XFS_IMETA_DEFINE_PATH(XFS_IMETA_GRPQUOTA, grpquota_path);
XFS_IMETA_DEFINE_PATH(XFS_IMETA_PRJQUOTA, prjquota_path);
-const struct xfs_imeta_path XFS_IMETA_METADIR = {
- .im_depth = 0,
- .im_ftype = XFS_DIR3_FT_DIR,
-};
-
-/* Are these two paths equal? */
-STATIC bool
-xfs_imeta_path_compare(
- const struct xfs_imeta_path *a,
- const struct xfs_imeta_path *b)
-{
- unsigned int i;
-
- if (a == b)
- return true;
-
- if (a->im_depth != b->im_depth)
- return false;
-
- for (i = 0; i < a->im_depth; i++)
- if (a->im_path[i] != b->im_path[i] &&
- strcmp(a->im_path[i], b->im_path[i]))
- return false;
-
- return true;
-}
-
/* Is this path ok? */
static inline bool
xfs_imeta_path_check(
return path->im_depth <= XFS_IMETA_MAX_DEPTH;
}
-/* Functions for storing and retrieving superblock inode values. */
-
-/* Mapping of metadata inode paths to in-core superblock values. */
-static const struct xfs_imeta_sbmap {
- const struct xfs_imeta_path *path;
- unsigned int offset;
-} xfs_imeta_sbmaps[] = {
- {
- .path = &XFS_IMETA_RTBITMAP,
- .offset = offsetof(struct xfs_sb, sb_rbmino),
- },
- {
- .path = &XFS_IMETA_RTSUMMARY,
- .offset = offsetof(struct xfs_sb, sb_rsumino),
- },
- {
- .path = &XFS_IMETA_USRQUOTA,
- .offset = offsetof(struct xfs_sb, sb_uquotino),
- },
- {
- .path = &XFS_IMETA_GRPQUOTA,
- .offset = offsetof(struct xfs_sb, sb_gquotino),
- },
- {
- .path = &XFS_IMETA_PRJQUOTA,
- .offset = offsetof(struct xfs_sb, sb_pquotino),
- },
- {
- .path = &XFS_IMETA_METADIR,
- .offset = offsetof(struct xfs_sb, sb_metadirino),
- },
- { NULL, 0 },
-};
-
-/* Return a pointer to the in-core superblock inode value. */
-static inline xfs_ino_t *
-xfs_imeta_sbmap_to_inop(
- struct xfs_mount *mp,
- const struct xfs_imeta_sbmap *map)
-{
- return (xfs_ino_t *)(((char *)&mp->m_sb) + map->offset);
-}
-
-/* Compute location of metadata inode pointer in the in-core superblock */
-static inline xfs_ino_t *
-xfs_imeta_path_to_sb_inop(
- struct xfs_mount *mp,
- const struct xfs_imeta_path *path)
-{
- const struct xfs_imeta_sbmap *p;
-
- for (p = xfs_imeta_sbmaps; p->path; p++)
- if (xfs_imeta_path_compare(p->path, path))
- return xfs_imeta_sbmap_to_inop(mp, p);
-
- return NULL;
-}
-
/* Functions for storing and retrieving metadata directory inode values. */
static inline void
int error;
/* metadir ino is recorded in superblock */
- if (xfs_imeta_path_compare(path, &XFS_IMETA_METADIR))
+ if (path->im_depth == 0)
return tp->t_mountp->m_sb.sb_metadirino;
- ASSERT(path->im_depth > 0);
-
/* Find the parent of the last path component. */
error = xfs_imeta_dir_parent(tp, path, &dp);
if (error)
return error;
}
-/*
- * Load all the metadata inode pointers that are cached in the in-core
- * superblock but live somewhere in the metadata directory tree.
- */
-STATIC int
-xfs_imeta_dir_mount(
- struct xfs_trans *tp)
-{
- struct xfs_mount *mp = tp->t_mountp;
- const struct xfs_imeta_sbmap *p;
- xfs_ino_t *sb_inop;
- int err2;
- int error = 0;
-
- for (p = xfs_imeta_sbmaps; p->path && p->path->im_depth > 0; p++) {
- if (p->path == &XFS_IMETA_METADIR)
- continue;
- sb_inop = xfs_imeta_sbmap_to_inop(mp, p);
- err2 = xfs_imeta_dir_lookup_int(tp, p->path, sb_inop);
- if (err2 == -ENOENT) {
- *sb_inop = NULLFSINO;
- continue;
- }
- if (!error && err2)
- error = err2;
- }
-
- return error;
-}
-
/* Set up an inode to be recognized as a metadata directory inode. */
void
xfs_imeta_set_iflag(
.ppargs = upd->ppargs,
};
struct xfs_mount *mp = upd->mp;
- xfs_ino_t *sb_inop;
xfs_ino_t ino;
unsigned int resblks;
int error;
/* Metadir files are not accounted to quota. */
trace_xfs_imeta_dir_create(upd);
-
- /* Update the in-core superblock value if there is one. */
- sb_inop = xfs_imeta_path_to_sb_inop(mp, upd->path);
- if (sb_inop)
- *sb_inop = ino;
return 0;
}
.ppargs = upd->ppargs,
};
struct xfs_mount *mp = upd->mp;
- xfs_ino_t *sb_inop;
xfs_ino_t ino;
unsigned int resblks;
int error;
xfs_assert_ilocked(upd->ip, XFS_ILOCK_EXCL);
/* Metadata directory root cannot be linked. */
- if (xfs_imeta_path_compare(upd->path, &XFS_IMETA_METADIR)) {
- ASSERT(0);
- xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
- return -EFSCORRUPTED;
- }
-
ASSERT(upd->path->im_depth > 0);
/* Look up the name in the current directory. */
return error;
trace_xfs_imeta_dir_link(upd);
-
- /* Update the in-core superblock value if there is one. */
- sb_inop = xfs_imeta_path_to_sb_inop(mp, upd->path);
- if (sb_inop)
- *sb_inop = upd->ip->i_ino;
return 0;
}
return xfs_imeta_dir_link(upd);
}
-/*
- * Ensure that the in-core superblock has all the values that it should.
- * Caller should pass in an empty transaction to avoid livelocking on btree
- * cycles.
- */
-int
-xfs_imeta_mount(
- struct xfs_trans *tp)
-{
- if (xfs_has_metadir(tp->t_mountp))
- return xfs_imeta_dir_mount(tp);
-
- return 0;
-}
-
/* Create a path to a file within the metadata directory tree. */
int
xfs_imeta_create_file_path(