]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
xfs: metadir experiments
authorChristoph Hellwig <hch@lst.de>
Wed, 6 Dec 2023 07:49:06 +0000 (08:49 +0100)
committerChristoph Hellwig <hch@lst.de>
Wed, 6 Dec 2023 07:49:06 +0000 (08:49 +0100)
Source kernel commit: 7cab757b951ad07d87ccca49b4c296e503b70cd5

This is a mesh up of a few changes:

- add new fields for the new features instead of somewhat confusingly
overloading the old RT inode fields.
- don't actually use the metadir under the hood for the RT and quota
inodes.  It might or might not make sense to migrate everything to
the metadir, but doing it under the hood seems very confusing.
- cache the inodes for metadir subdirectories and make all operations
relative to the parent directory, similar to how the VFS works.
This actually simplifies a surprisingly large amount of code

If we go down this way it will need to be broken up and folded into
the original patches.

Note that this currently breaks compiling the metapth scrub code.

Signed-off-by: Christoph Hellwig <hch@lst.de>
12 files changed:
libxfs/xfs_format.h
libxfs/xfs_fs.h
libxfs/xfs_imeta.c
libxfs/xfs_imeta.h
libxfs/xfs_rtrefcount_btree.c
libxfs/xfs_rtrefcount_btree.h
libxfs/xfs_rtrmap_btree.c
libxfs/xfs_rtrmap_btree.h
libxfs/xfs_sb.c
libxfs/xfs_trans_resv.c
libxfs/xfs_trans_resv.h
libxfs/xfs_types.c

index 3cf57744189ecb4608fe1746e857348bd12c631f..3c08081437502ce4d713cb3e24f598d0e1872ec6 100644 (file)
@@ -174,23 +174,9 @@ typedef struct xfs_sb {
        xfs_lsn_t       sb_lsn;         /* last write sequence */
        uuid_t          sb_meta_uuid;   /* metadata file system unique id */
 
-       /* Fields beyond here do not match xfs_dsb.  Be very careful! */
-
-       /*
-        * Metadata Directory Inode.  On disk this lives in the sb_rbmino slot,
-        * but we continue to use the in-core superblock to cache the classic
-        * inodes (rt bitmap; rt summary; user, group, and project quotas) so
-        * we cache the metadir inode value here too.
-        */
-       xfs_ino_t       sb_metadirino;
-
-       /*
-        * Realtime group geometry information.  On disk these fields live in
-        * the rsumino slot, but we cache them separately in the in-core super
-        * for easy access.
-        */
-       xfs_rgblock_t   sb_rgblocks;    /* size of a realtime group */
+       xfs_ino_t       sb_metadirino;  /* metadata root directory inode */
        xfs_rgnumber_t  sb_rgcount;     /* number of realtime groups */
+       xfs_rgblock_t   sb_rgblocks;    /* size of a realtime group */
 
        /* must be padded to 64 bit alignment */
 } xfs_sb_t;
@@ -208,25 +194,8 @@ struct xfs_dsb {
        uuid_t          sb_uuid;        /* user-visible file system unique id */
        __be64          sb_logstart;    /* starting block of log if internal */
        __be64          sb_rootino;     /* root inode number */
-       /*
-        * bitmap inode for realtime extents.
-        *
-        * The metadata directory feature uses the sb_rbmino field to point to
-        * the root of the metadata directory tree.  All other sb inode
-        * pointers are no longer used.
-        */
-       __be64          sb_rbmino;
-       /*
-        * rtgroups requires metadir, so we reuse the rsumino space to hold
-        * the rg block count and shift values.
-        */
-       union {
-               __be64  sb_rsumino;     /* summary inode for rt bitmap */
-               struct {
-                       __be32  sb_rgcount;     /* # of realtime groups */
-                       __be32  sb_rgblocks;    /* rtblocks per group */
-               };
-       };
+       __be64          sb_rbmino;      /* rt bitmap inode */
+       __be64          sb_rsumino;     /* summary inode for rt bitmap */
        __be32          sb_rextsize;    /* realtime extent size, blocks */
        __be32          sb_agblocks;    /* size of an allocation group */
        __be32          sb_agcount;     /* number of allocation groups */
@@ -294,6 +263,10 @@ struct xfs_dsb {
        __be64          sb_lsn;         /* last write sequence */
        uuid_t          sb_meta_uuid;   /* metadata file system unique id */
 
+       __be64          sb_metadirino;  /* metadata root directory inode */
+       __be32          sb_rgcount;     /* # of realtime groups */
+       __be32          sb_rgblocks;    /* rtblocks per group */
+
        /* must be padded to 64 bit alignment */
 };
 
index 4159e96d01ae6195afe269fdcc95ddb95d8f22f6..4d76e82cf71fefbbf536e39eabc0d0b8cfe7eed0 100644 (file)
@@ -799,12 +799,9 @@ struct xfs_scrub_metadata {
 /*
  * i: sm_ino values for XFS_SCRUB_TYPE_METAPATH to select a metadata file for
  * path checking.
+ *
+ * XXX: renumber
  */
-#define XFS_SCRUB_METAPATH_RTBITMAP    0
-#define XFS_SCRUB_METAPATH_RTSUMMARY   1
-#define XFS_SCRUB_METAPATH_USRQUOTA    2
-#define XFS_SCRUB_METAPATH_GRPQUOTA    3
-#define XFS_SCRUB_METAPATH_PRJQUOTA    4
 #define XFS_SCRUB_METAPATH_RTRMAPBT    5
 #define XFS_SCRUB_METAPATH_RTREFCBT    6
 
index 78a944ab483cf6640022bb7f092388b7bfb341fa..a59373bb7e5307de142834254693aad525445807 100644 (file)
@@ -40,7 +40,7 @@
  *
  * For the five existing metadata inodes (real time bitmap & summary; and the
  * user, group, and quotas) we'll continue to maintain the in-core superblock
- * inodes for reads and only require xfs_imeta_create and xfs_imeta_unlink to
+ * inodes for reads and only require xfs_imeta_dir_create to
  * persist changes.  New metadata inode types must only use the xfs_imeta_*
  * functions.
  *
  * to user space.
  */
 
-/* Static metadata inode paths */
-static const unsigned char *rtbitmap_path[]    = {"realtime", "bitmap"};
-static const unsigned char *rtsummary_path[]   = {"realtime", "summary"};
-static const unsigned char *usrquota_path[]    = {"quota", "user"};
-static const unsigned char *grpquota_path[]    = {"quota", "group"};
-static const unsigned char *prjquota_path[]    = {"quota", "project"};
-
-XFS_IMETA_DEFINE_PATH(XFS_IMETA_RTBITMAP,      rtbitmap_path);
-XFS_IMETA_DEFINE_PATH(XFS_IMETA_RTSUMMARY,     rtsummary_path);
-XFS_IMETA_DEFINE_PATH(XFS_IMETA_USRQUOTA,      usrquota_path);
-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(
-       const struct xfs_imeta_path     *path)
-{
-       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;
-}
-
-/* Look up a superblock metadata inode by its path. */
-STATIC int
-xfs_imeta_sb_lookup(
-       struct xfs_mount                *mp,
-       const struct xfs_imeta_path     *path,
-       xfs_ino_t                       *inop)
-{
-       xfs_ino_t                       *sb_inop;
-
-       sb_inop = xfs_imeta_path_to_sb_inop(mp, path);
-       if (!sb_inop)
-               return -EINVAL;
-
-       trace_xfs_imeta_sb_lookup(mp, sb_inop);
-       *inop = *sb_inop;
-       return 0;
-}
-
 /* Update inode pointers in the superblock. */
 static inline void
 xfs_imeta_log_sb(
@@ -208,38 +84,43 @@ xfs_imeta_log_sb(
  * Create a new metadata inode and set a superblock pointer to this new inode.
  * The superblock field must not already be pointing to an inode.
  */
-STATIC int
+int
 xfs_imeta_sb_create(
-       struct xfs_imeta_update         *upd,
-       umode_t                         mode)
+       struct xfs_trans                **tpp,
+       xfs_ino_t                       *sb_inop,
+       umode_t                         mode,
+       struct xfs_inode                **ipp)
 {
+       struct xfs_mount                *mp = (*tpp)->t_mountp;
        struct xfs_icreate_args         args = {
                .nlink                  = S_ISDIR(mode) ? 2 : 1,
        };
-       struct xfs_mount                *mp = upd->mp;
-       xfs_ino_t                       *sb_inop;
        xfs_ino_t                       ino;
        int                             error;
 
        /* Files rooted in the superblock do not have parents. */
        xfs_icreate_args_rootfile(&args, mp, mode, false);
 
-       /* Reject if the sb already points to some inode. */
-       sb_inop = xfs_imeta_path_to_sb_inop(mp, upd->path);
-       if (!sb_inop)
-               return -EINVAL;
-
+       /* Reject if the sb already points to an inode. */
        if (*sb_inop != NULLFSINO)
                return -EEXIST;
 
        /* Create a new inode and set the sb pointer. */
-       error = xfs_dialloc(&upd->tp, NULL, mode, &ino);
+       error = xfs_dialloc(tpp, NULL, mode, &ino);
        if (error)
                return error;
-       error = xfs_icreate(upd->tp, ino, &args, &upd->ip);
+       error = xfs_icreate(*tpp, ino, &args, ipp);
        if (error)
                return error;
-       upd->ip_locked = true;
+
+       if (S_ISDIR(mode)) {
+               ASSERT(sb_inop == &mp->m_sb.sb_metadirino);
+
+               xfs_imeta_set_iflag(*tpp, *ipp);
+               error = xfs_dir_init(*tpp, *ipp, *ipp);
+               if (error)
+                       return error;
+       }
 
        /*
         * If we ever need the ability to create rt metadata files on a
@@ -250,85 +131,23 @@ xfs_imeta_sb_create(
 
        /* Update superblock pointer. */
        *sb_inop = ino;
-       xfs_imeta_log_sb(upd->tp);
-
-       trace_xfs_imeta_sb_create(upd);
-       return 0;
-}
-
-/*
- * Clear the given inode pointer from the superblock and drop the link count
- * of the metadata inode.
- */
-STATIC int
-xfs_imeta_sb_unlink(
-       struct xfs_imeta_update         *upd)
-{
-       struct xfs_mount                *mp = upd->mp;
-       xfs_ino_t                       *sb_inop;
+       xfs_imeta_log_sb(*tpp);
 
-       ASSERT(xfs_isilocked(upd->ip, XFS_ILOCK_EXCL));
-
-       sb_inop = xfs_imeta_path_to_sb_inop(mp, upd->path);
-       if (!sb_inop)
-               return -EINVAL;
-
-       /* Reject if the sb doesn't point to the inode that was passed in. */
-       if (*sb_inop != upd->ip->i_ino)
-               return -ENOENT;
-
-       trace_xfs_imeta_sb_unlink(upd);
-
-       *sb_inop = NULLFSINO;
-       xfs_imeta_log_sb(upd->tp);
-       return xfs_droplink(upd->tp, upd->ip);
-}
-
-/* Set the given inode pointer in the superblock. */
-STATIC int
-xfs_imeta_sb_link(
-       struct xfs_imeta_update         *upd)
-{
-       struct xfs_mount                *mp = upd->mp;
-       xfs_ino_t                       *sb_inop;
-
-       ASSERT(xfs_isilocked(upd->ip, XFS_ILOCK_EXCL));
-
-       sb_inop = xfs_imeta_path_to_sb_inop(mp, upd->path);
-       if (!sb_inop)
-               return -EINVAL;
-       if (*sb_inop != NULLFSINO)
-               return -EEXIST;
-
-       trace_xfs_imeta_sb_link(upd);
-
-       xfs_bumplink(upd->tp, upd->ip);
-       xfs_imeta_log_sb(upd->tp);
-
-       *sb_inop = upd->ip->i_ino;
+       trace_xfs_imeta_sb_create(mp, sb_inop);
        return 0;
 }
 
 /* Functions for storing and retrieving metadata directory inode values. */
 
-static inline void
-xfs_imeta_set_xname(
-       struct xfs_name                 *xname,
-       const struct xfs_imeta_path     *path,
-       unsigned int                    path_idx,
-       unsigned char                   ftype)
-{
-       xname->name = (const unsigned char *)path->im_path[path_idx];
-       xname->len = strlen(path->im_path[path_idx]);
-       xname->type = ftype;
-}
-
 /*
- * Look up the inode number and filetype for an exact name in a directory.
+ * Given a parent directory @dp and a metadata inode path component @name,
+ * Look up the inode number in the directory, returning it in @ino.
+ * @xname.type must match the directory entry's ftype.
+ *
  * Caller must hold ILOCK_EXCL.
  */
 static inline int
-xfs_imeta_dir_lookup(
+xfs_imeta_dir_lookup_locked(
        struct xfs_trans        *tp,
        struct xfs_inode        *dp,
        struct xfs_name         *xname,
@@ -351,6 +170,11 @@ xfs_imeta_dir_lookup(
        if (xfs_is_shutdown(dp->i_mount))
                return -EIO;
 
+       if (!S_ISDIR(VFS_I(dp)->i_mode)) {
+               xfs_fs_mark_sick(dp->i_mount, XFS_SICK_FS_METADIR);
+               return -EFSCORRUPTED;
+       }
+
        if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
                error = xfs_dir2_sf_lookup(&args);
                goto out_unlock;
@@ -388,40 +212,13 @@ out_unlock:
                return error;
 
        *ino = args.inumber;
-       xname->type = args.filetype;
-       return 0;
-}
 
-/*
- * Given a parent directory @dp and a metadata inode path component @xname,
- * Look up the inode number in the directory, returning it in @ino.
- * @xname.type must match the directory entry's ftype.
- *
- * Caller must hold ILOCK_EXCL.
- */
-static inline int
-xfs_imeta_dir_lookup_component(
-       struct xfs_trans        *tp,
-       struct xfs_inode        *dp,
-       struct xfs_name         *xname,
-       xfs_ino_t               *ino)
-{
-       int                     type_wanted = xname->type;
-       int                     error;
-
-       if (!S_ISDIR(VFS_I(dp)->i_mode)) {
-               xfs_fs_mark_sick(dp->i_mount, XFS_SICK_FS_METADIR);
-               return -EFSCORRUPTED;
-       }
-
-       error = xfs_imeta_dir_lookup(tp, dp, xname, ino);
-       if (error)
-               return error;
        if (!xfs_verify_ino(dp->i_mount, *ino)) {
                xfs_fs_mark_sick(dp->i_mount, XFS_SICK_FS_METADIR);
                return -EFSCORRUPTED;
        }
-       if (type_wanted != XFS_DIR3_FT_UNKNOWN && xname->type != type_wanted) {
+       if (xname->type != XFS_DIR3_FT_UNKNOWN &&
+           args.filetype != xname->type) {
                xfs_fs_mark_sick(dp->i_mount, XFS_SICK_FS_METADIR);
                return -EFSCORRUPTED;
        }
@@ -430,150 +227,40 @@ xfs_imeta_dir_lookup_component(
        return 0;
 }
 
-/*
- * Traverse a metadata directory tree path, returning the inode corresponding
- * to the parent of the last path component.  If any of the path components do
- * not exist, return -ENOENT.  Caller must supply a transaction to avoid
- * livelocks on btree cycles.
- *
- * @dp is returned without any locks held.
- */
-int
-xfs_imeta_dir_parent(
-       struct xfs_trans                *tp,
-       const struct xfs_imeta_path     *path,
-       struct xfs_inode                **dpp)
-{
-       struct xfs_name                 xname;
-       struct xfs_mount                *mp = tp->t_mountp;
-       struct xfs_inode                *dp = NULL;
-       xfs_ino_t                       ino;
-       unsigned int                    i;
-       int                             error;
-
-       /* Caller wanted the root, we're done! */
-       if (path->im_depth == 0)
-               goto out;
-
-       /* No metadata directory means no parent. */
-       if (mp->m_metadirip == NULL)
-               return -ENOENT;
-
-       /* Grab a new reference to the metadir root dir. */
-       error = xfs_imeta_iget(tp, mp->m_metadirip->i_ino, XFS_DIR3_FT_DIR,
-                       &dp);
-       if (error)
-               return error;
-
-       for (i = 0; i < path->im_depth - 1; i++) {
-               struct xfs_inode        *ip = NULL;
-
-               xfs_ilock(dp, XFS_ILOCK_EXCL);
-
-               /* Look up the name in the current directory. */
-               xfs_imeta_set_xname(&xname, path, i, XFS_DIR3_FT_DIR);
-               error = xfs_imeta_dir_lookup_component(tp, dp, &xname, &ino);
-               if (error)
-                       goto out_rele;
-
-               /*
-                * Grab the child inode while we still have the parent
-                * directory locked.
-                */
-               error = xfs_imeta_iget(tp, ino, XFS_DIR3_FT_DIR, &ip);
-               if (error)
-                       goto out_rele;
-
-               xfs_iunlock(dp, XFS_ILOCK_EXCL);
-               xfs_imeta_irele(dp);
-               dp = ip;
-       }
-
-out:
-       *dpp = dp;
-       return 0;
-
-out_rele:
-       xfs_iunlock(dp, XFS_ILOCK_EXCL);
-       xfs_imeta_irele(dp);
-       return error;
-}
-
 /*
  * Look up a metadata inode from the metadata directory.  If the last path
  * component doesn't exist, return NULLFSINO.  If any other part of the path
  * does not exist, return -ENOENT so we can distinguish the two.
  */
-STATIC int
-xfs_imeta_dir_lookup_int(
+int
+xfs_imeta_dir_lookup(
        struct xfs_trans                *tp,
-       const struct xfs_imeta_path     *path,
-       xfs_ino_t                       *inop)
+       struct xfs_inode                *dp,
+       const char                      *name,
+       uint8_t                         ftype,
+       struct xfs_inode                **ipp)
 {
-       struct xfs_name                 xname;
-       struct xfs_inode                *dp = NULL;
-       xfs_ino_t                       ino;
+       struct xfs_mount                *mp = tp->t_mountp;
+       struct xfs_name                 xname = {
+               .name   = (const unsigned char *)name,
+               .len    = strlen(name),
+               .type   = ftype,
+       };
        int                             error;
+       xfs_ino_t                       ino;
 
-       /* metadir ino is recorded in superblock */
-       if (xfs_imeta_path_compare(path, &XFS_IMETA_METADIR))
-               return xfs_imeta_sb_lookup(tp->t_mountp, path, inop);
-
-       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;
+       ASSERT(xfs_has_metadir(mp));
 
        xfs_ilock(dp, XFS_ILOCK_EXCL);
-
-       /* Look up the name in the current directory. */
-       xfs_imeta_set_xname(&xname, path, path->im_depth - 1, path->im_ftype);
-       error = xfs_imeta_dir_lookup_component(tp, dp, &xname, &ino);
-       switch (error) {
-       case 0:
-               *inop = ino;
-               break;
-       case -ENOENT:
-               *inop = NULLFSINO;
-               error = 0;
-               break;
-       }
-
+       error = xfs_imeta_dir_lookup_locked(tp, dp, &xname, &ino);
        xfs_iunlock(dp, XFS_ILOCK_EXCL);
-       xfs_imeta_irele(dp);
-       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;
-       }
+       if (error)
+               return error;
 
-       return error;
+       if (!xfs_verify_ino(mp, ino))
+               return -EFSCORRUPTED;
+       return xfs_imeta_iget(tp, ino, ftype, ipp);
 }
 
 /* Set up an inode to be recognized as a metadata directory inode. */
@@ -609,12 +296,23 @@ xfs_imeta_clear_iflag(
        ip->i_diflags2 &= ~XFS_DIFLAG2_METADIR;
        xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
 }
+
 /*
- * Create a new metadata inode accessible via the given metadata directory path.
- * Callers must ensure that the directory entry does not already exist; a new
- * one will be created.
+ * Create a metadata inode with the given @mode, and insert it into the
+ * metadata directory tree at the given @path.  The path (up to the final
+ * component) must already exist.
+ *
+ * The new metadata inode will be attached to the update structure @upd->ip,
+ * with the ILOCK held until the caller releases it.  @ipp is set to upd->ip
+ * as a convenience for callers.
+ *
+ * Callers must ensure that the root dquots are allocated, if applicable.
+ *
+ * NOTE: This function may return a new inode to the caller even if it returns
+ * a negative error code.  If an inode is passed back, the caller must finish
+ * setting up the inode before releasing it.
  */
-STATIC int
+int
 xfs_imeta_dir_create(
        struct xfs_imeta_update         *upd,
        umode_t                         mode)
@@ -623,54 +321,37 @@ xfs_imeta_dir_create(
                .pip                    = upd->dp,
                .nlink                  = S_ISDIR(mode) ? 2 : 1,
        };
-       struct xfs_name                 xname;
+       struct xfs_name                 xname = {
+               .name   = (const unsigned char *)upd->name,
+               .len    = strlen(upd->name),
+               .type   = XFS_DIR3_FT_UNKNOWN,
+       };
        struct xfs_dir_update           du = {
                .dp                     = upd->dp,
                .name                   = &xname,
                .ppargs                 = upd->ppargs,
        };
-       struct xfs_mount                *mp = upd->mp;
-       xfs_ino_t                       *sb_inop;
+       struct xfs_mount                *mp = upd->dp->i_mount;
        xfs_ino_t                       ino;
        unsigned int                    resblks;
        int                             error;
 
+       ASSERT(xfs_has_metadir(mp));
        ASSERT(xfs_isilocked(upd->dp, XFS_ILOCK_EXCL));
 
-       /* metadir ino is recorded in superblock; only mkfs gets to do this */
-       if (xfs_imeta_path_compare(upd->path, &XFS_IMETA_METADIR)) {
-               error = xfs_imeta_sb_create(upd, mode);
-               if (error)
-                       return error;
-
-               /* Set the metadata iflag, initialize directory. */
-               xfs_imeta_set_iflag(upd->tp, upd->ip);
-               return xfs_dir_init(upd->tp, upd->ip, upd->ip);
-       }
-
-       ASSERT(upd->path->im_depth > 0);
-
        xfs_icreate_args_rootfile(&args, mp, mode, xfs_has_parent(mp));
 
        /* Check that the name does not already exist in the directory. */
-       xfs_imeta_set_xname(&xname, upd->path, upd->path->im_depth - 1,
-                       XFS_DIR3_FT_UNKNOWN);
-       error = xfs_imeta_dir_lookup_component(upd->tp, upd->dp, &xname, &ino);
+       error = xfs_imeta_dir_lookup_locked(upd->tp, upd->dp, &xname, &ino);
        switch (error) {
        case -ENOENT:
                break;
        case 0:
-               error = -EEXIST;
-               fallthrough;
+               return -EEXIST;
        default:
                return error;
        }
 
-       /*
-        * A newly created regular or special file just has one directory
-        * entry pointing to them, but a directory also the "." entry
-        * pointing to itself.
-        */
        error = xfs_dialloc(&upd->tp, upd->dp, mode, &ino);
        if (error)
                return error;
@@ -679,7 +360,6 @@ xfs_imeta_dir_create(
                return error;
        du.ip = upd->ip;
        xfs_imeta_set_iflag(upd->tp, upd->ip);
-       upd->ip_locked = true;
 
        /*
         * Join the directory inode to the transaction.  We do not do it
@@ -704,380 +384,9 @@ xfs_imeta_dir_create(
 
        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;
 }
 
-/*
- * Remove the given entry from the metadata directory and drop the link count
- * of the metadata inode.
- */
-STATIC int
-xfs_imeta_dir_unlink(
-       struct xfs_imeta_update         *upd)
-{
-       struct xfs_name                 xname;
-       struct xfs_dir_update           du = {
-               .dp                     = upd->dp,
-               .name                   = &xname,
-               .ip                     = upd->ip,
-               .ppargs                 = upd->ppargs,
-       };
-       struct xfs_mount                *mp = upd->mp;
-       xfs_ino_t                       *sb_inop;
-       xfs_ino_t                       ino;
-       unsigned int                    resblks;
-       int                             error;
-
-       ASSERT(xfs_isilocked(upd->dp, XFS_ILOCK_EXCL));
-       ASSERT(xfs_isilocked(upd->ip, XFS_ILOCK_EXCL));
-
-       /* Metadata directory root cannot be unlinked. */
-       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. */
-       xfs_imeta_set_xname(&xname, upd->path, upd->path->im_depth - 1,
-                       xfs_mode_to_ftype(VFS_I(upd->ip)->i_mode));
-       error = xfs_imeta_dir_lookup_component(upd->tp, upd->dp, &xname, &ino);
-       switch (error) {
-       case 0:
-               if (ino != upd->ip->i_ino)
-                       error = -ENOENT;
-               break;
-       case -ENOENT:
-               xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
-               error = -EFSCORRUPTED;
-               break;
-       }
-       if (error)
-               return error;
-
-       resblks = xfs_remove_space_res(mp, xname.len);
-       error = xfs_dir_remove_child(upd->tp, resblks, &du);
-       if (error)
-               return error;
-
-       trace_xfs_imeta_dir_unlink(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 = NULLFSINO;
-       return 0;
-}
-
-/* Set the given path in the metadata directory to point to an inode. */
-STATIC int
-xfs_imeta_dir_link(
-       struct xfs_imeta_update         *upd)
-{
-       struct xfs_name                 xname;
-       struct xfs_dir_update           du = {
-               .dp                     = upd->dp,
-               .name                   = &xname,
-               .ip                     = upd->ip,
-               .ppargs                 = upd->ppargs,
-       };
-       struct xfs_mount                *mp = upd->mp;
-       xfs_ino_t                       *sb_inop;
-       xfs_ino_t                       ino;
-       unsigned int                    resblks;
-       int                             error;
-
-       ASSERT(xfs_isilocked(upd->dp, XFS_ILOCK_EXCL));
-       ASSERT(xfs_isilocked(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. */
-       xfs_imeta_set_xname(&xname, upd->path, upd->path->im_depth - 1,
-                       xfs_mode_to_ftype(VFS_I(upd->ip)->i_mode));
-       error = xfs_imeta_dir_lookup_component(upd->tp, upd->dp, &xname, &ino);
-       switch (error) {
-       case -ENOENT:
-               break;
-       case 0:
-               error = -EEXIST;
-               fallthrough;
-       default:
-               return error;
-       }
-
-       resblks = xfs_link_space_res(mp, xname.len);
-       error = xfs_dir_add_child(upd->tp, resblks, &du);
-       if (error)
-               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;
-}
-
-/* General functions for managing metadata inode pointers */
-
-/*
- * Is this metadata inode pointer ok?  We allow the fields to be set to
- * NULLFSINO if the metadata structure isn't present, and we don't allow
- * obviously incorrect inode pointers.
- */
-static inline bool
-xfs_imeta_verify(
-       struct xfs_mount        *mp,
-       xfs_ino_t               ino)
-{
-       if (ino == NULLFSINO)
-               return true;
-       return xfs_verify_ino(mp, ino);
-}
-
-/* Look up a metadata inode by its path. */
-int
-xfs_imeta_lookup(
-       struct xfs_trans                *tp,
-       const struct xfs_imeta_path     *path,
-       xfs_ino_t                       *inop)
-{
-       struct xfs_mount                *mp = tp->t_mountp;
-       xfs_ino_t                       ino;
-       int                             error;
-
-       ASSERT(xfs_imeta_path_check(path));
-
-       if (xfs_has_metadir(mp)) {
-               error = xfs_imeta_dir_lookup_int(tp, path, &ino);
-               if (error == -ENOENT) {
-                       xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
-                       return -EFSCORRUPTED;
-               }
-       } else {
-               error = xfs_imeta_sb_lookup(mp, path, &ino);
-       }
-       if (error)
-               return error;
-
-       if (!xfs_imeta_verify(mp, ino)) {
-               xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
-               return -EFSCORRUPTED;
-       }
-
-       *inop = ino;
-       return 0;
-}
-
-/*
- * Create a metadata inode with the given @mode, and insert it into the
- * metadata directory tree at the given @path.  The path (up to the final
- * component) must already exist.
- *
- * The new metadata inode will be attached to the update structure @upd->ip,
- * with the ILOCK held until the caller releases it.  @ipp is set to upd->ip
- * as a convenience for callers.
- *
- * Callers must ensure that the root dquots are allocated, if applicable.
- *
- * NOTE: This function may return a new inode to the caller even if it returns
- * a negative error code.  If an inode is passed back, the caller must finish
- * setting up the inode before releasing it.
- */
-int
-xfs_imeta_create(
-       struct xfs_imeta_update         *upd,
-       umode_t                         mode,
-       struct xfs_inode                **ipp)
-{
-       struct xfs_mount                *mp = upd->mp;
-       int                             error;
-
-       ASSERT(xfs_imeta_path_check(upd->path));
-
-       *ipp = NULL;
-
-       if (xfs_has_metadir(mp))
-               error = xfs_imeta_dir_create(upd, mode);
-       else
-               error = xfs_imeta_sb_create(upd, mode);
-       *ipp = upd->ip;
-       return error;
-}
-
-/* Free a file from the metadata directory tree. */
-STATIC int
-xfs_imeta_ifree(
-       struct xfs_trans        *tp,
-       struct xfs_inode        *ip)
-{
-       struct xfs_mount        *mp = ip->i_mount;
-       struct xfs_perag        *pag;
-       struct xfs_icluster     xic = { 0 };
-       int                     error;
-
-       ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
-       ASSERT(VFS_I(ip)->i_nlink == 0);
-       ASSERT(ip->i_df.if_nextents == 0);
-       ASSERT(ip->i_disk_size == 0 || !S_ISREG(VFS_I(ip)->i_mode));
-       ASSERT(ip->i_nblocks == 0);
-
-       pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
-
-       error = xfs_dir_ifree(tp, pag, ip, &xic);
-       if (error)
-               goto out;
-
-       /* Metadata files do not support ownership changes or DMAPI. */
-
-       if (xic.deleted)
-               error = xfs_ifree_cluster(tp, pag, ip, &xic);
-out:
-       xfs_perag_put(pag);
-       return error;
-}
-
-/*
- * Unlink a metadata inode @upd->ip from the metadata directory given by @path.
- * The path must already exist.
- */
-int
-xfs_imeta_unlink(
-       struct xfs_imeta_update         *upd)
-{
-       int                             error;
-
-       ASSERT(xfs_imeta_path_check(upd->path));
-       ASSERT(xfs_imeta_verify(upd->mp, upd->ip->i_ino));
-
-       if (xfs_has_metadir(upd->mp))
-               error = xfs_imeta_dir_unlink(upd);
-       else
-               error = xfs_imeta_sb_unlink(upd);
-       if (error)
-               return error;
-
-       /*
-        * Metadata files require explicit resource cleanup.  In other words,
-        * the inactivation system will not touch these files, so we must free
-        * the ondisk inode by ourselves if warranted.
-        */
-       if (VFS_I(upd->ip)->i_nlink > 0)
-               return 0;
-
-       return xfs_imeta_ifree(upd->tp, upd->ip);
-}
-
-/*
- * Link the metadata directory given by @path to the inode @upd->ip.
- * The path (up to the final component) must already exist, but the final
- * component must not already exist.
- */
-int
-xfs_imeta_link(
-       struct xfs_imeta_update         *upd)
-{
-       ASSERT(xfs_imeta_path_check(upd->path));
-
-       if (xfs_has_metadir(upd->mp))
-               return xfs_imeta_dir_link(upd);
-       return xfs_imeta_sb_link(upd);
-}
-
-/* Does this inode number refer to a static metadata inode? */
-bool
-xfs_is_static_meta_ino(
-       struct xfs_mount                *mp,
-       xfs_ino_t                       ino)
-{
-       const struct xfs_imeta_sbmap    *p;
-
-       if (ino == NULLFSINO)
-               return false;
-
-       for (p = xfs_imeta_sbmaps; p->path; p++)
-               if (ino == *xfs_imeta_sbmap_to_inop(mp, p))
-                       return true;
-
-       return false;
-}
-
-/*
- * 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(
-       struct xfs_mount        *mp,
-       unsigned int            nr_components,
-       struct xfs_imeta_path   **pathp)
-{
-       struct xfs_imeta_path   *p;
-       unsigned char           **components;
-
-       p = kzalloc(sizeof(struct xfs_imeta_path), GFP_KERNEL);
-       if (!p)
-               return -ENOMEM;
-
-       components = kvcalloc(nr_components, sizeof(unsigned char *),
-                       GFP_KERNEL);
-       if (!components) {
-               kfree(p);
-               return -ENOMEM;
-       }
-
-       p->im_depth = nr_components;
-       p->im_path = (const unsigned char **)components;
-       p->im_ftype = XFS_DIR3_FT_REG_FILE;
-       *pathp = p;
-       return 0;
-}
-
-/* Free a metadata directory tree path. */
-void
-xfs_imeta_free_path(
-       const struct xfs_imeta_path     *path)
-{
-       unsigned int                    i;
-
-       if (path->im_flags & XFS_IMETA_PATH_STATIC)
-               return;
-
-       for (i = 0; i < path->im_depth; i++) {
-               if ((path->im_dynamicmask & (1ULL << i)) && path->im_path[i])
-                       kfree(path->im_path[i]);
-       }
-       kfree(path->im_path);
-       kfree(path);
-}
-
 /*
  * Is the amount of space that could be allocated towards a given metadata
  * file at or beneath a certain threshold?
index 9caf6aa59ac4c027662938a104f8488db1f438e0..a968d91d91ac06d2e153a09364b52301f0dffb3f 100644 (file)
 #ifndef __XFS_IMETA_H__
 #define __XFS_IMETA_H__
 
-/* How deep can we nest metadata dirs? */
-#define XFS_IMETA_MAX_DEPTH    64
-
-/* Form an imeta path from a simple array of strings. */
-#define XFS_IMETA_DEFINE_PATH(name, path) \
-const struct xfs_imeta_path name = { \
-       .im_path = (path), \
-       .im_ftype = XFS_DIR3_FT_REG_FILE, \
-       .im_depth = ARRAY_SIZE(path), \
-       .im_flags = XFS_IMETA_PATH_STATIC, \
-       .im_dynamicmask = 0, \
-}
-
-/* Key for looking up metadata inodes. */
-struct xfs_imeta_path {
-       /* Array of string pointers. */
-       const unsigned char     **im_path;
-
-       /* Each bit corresponds to an element of im_path needing to be freed */
-       unsigned long long      im_dynamicmask;
-
-       /* XFS_IMETA_* path flags */
-       uint16_t                im_flags;
-
-       /* Number of strings in path. */
-       uint8_t                 im_depth;
-
-       /* Expected file type. */
-       uint8_t                 im_ftype;
-};
-
-/* Path is statically allocated. */
-#define XFS_IMETA_PATH_STATIC  (1U << 0)
-
 /* Cleanup widget for metadata inode creation and deletion. */
 struct xfs_imeta_update {
-       struct xfs_mount        *mp;
        struct xfs_trans        *tp;
 
-       const struct xfs_imeta_path *path;
+       /* Parent directory */
+       struct xfs_inode        *dp;
+
+       /* Name in the parent directory */
+       const char              *name;
 
        /* Parent pointer update context */
        struct xfs_parent_args  *ppargs;
 
-       /* Parent directory */
-       struct xfs_inode        *dp;
-
        /* Metadata inode */
        struct xfs_inode        *ip;
-
-       unsigned int            dp_locked:1;
-       unsigned int            ip_locked:1;
 };
 
-/* Grab the last path component, mostly for tracing. */
-static inline const unsigned char *
-xfs_imeta_lastpath(
-       const struct xfs_imeta_update   *upd)
-{
-       if (upd->path && upd->path->im_path && upd->path->im_depth > 0)
-               return upd->path->im_path[upd->path->im_depth - 1];
-       return "?";
-}
-
-/* Lookup keys for static metadata inodes. */
-extern const struct xfs_imeta_path XFS_IMETA_RTBITMAP;
-extern const struct xfs_imeta_path XFS_IMETA_RTSUMMARY;
-extern const struct xfs_imeta_path XFS_IMETA_USRQUOTA;
-extern const struct xfs_imeta_path XFS_IMETA_GRPQUOTA;
-extern const struct xfs_imeta_path XFS_IMETA_PRJQUOTA;
-extern const struct xfs_imeta_path XFS_IMETA_METADIR;
-
-int xfs_imeta_lookup(struct xfs_trans *tp, const struct xfs_imeta_path *path,
-               xfs_ino_t *ino);
-int xfs_imeta_dir_parent(struct xfs_trans *tp,
-               const struct xfs_imeta_path *path, struct xfs_inode **dpp);
-
-int xfs_imeta_create_file_path(struct xfs_mount *mp,
-               unsigned int nr_components, struct xfs_imeta_path **pathp);
-void xfs_imeta_free_path(const struct xfs_imeta_path *path);
-
 void xfs_imeta_set_iflag(struct xfs_trans *tp, struct xfs_inode *ip);
 void xfs_imeta_clear_iflag(struct xfs_trans *tp, struct xfs_inode *ip);
 
-int xfs_imeta_create(struct xfs_imeta_update *upd, umode_t mode,
-               struct xfs_inode **ipp);
-int xfs_imeta_unlink(struct xfs_imeta_update *upd);
-int xfs_imeta_link(struct xfs_imeta_update *upd);
+int xfs_imeta_dir_lookup(struct xfs_trans *tp, struct xfs_inode *dp,
+               const char *name, uint8_t ftype, struct xfs_inode **ipp);
+int xfs_imeta_dir_create(struct xfs_imeta_update *upd, umode_t mode);
 
-bool xfs_is_static_meta_ino(struct xfs_mount *mp, xfs_ino_t ino);
-int xfs_imeta_mount(struct xfs_trans *tp);
+int xfs_imeta_sb_create(struct xfs_trans **tpp, xfs_ino_t *sb_inop,
+               umode_t mode, struct xfs_inode **ipp);
 
 unsigned int xfs_imeta_create_space_res(struct xfs_mount *mp);
-unsigned int xfs_imeta_link_space_res(struct xfs_mount *mp);
-unsigned int xfs_imeta_unlink_space_res(struct xfs_mount *mp);
 
 /* Space reservations for metadata inodes. */
 struct xfs_alloc_arg;
index 899f37c0b6ca1f282801dd9cc91d29d3e9c03832..2b64fe4cc8dfb7c5edd8415da415c62826564e67 100644 (file)
@@ -561,33 +561,12 @@ xfs_rtrefcountbt_compute_maxlevels(
 
 #define XFS_RTREFC_NAMELEN             21
 
-/* Create the metadata directory path for an rtrefcount btree inode. */
-int
-xfs_rtrefcountbt_create_path(
-       struct xfs_mount        *mp,
-       xfs_rgnumber_t          rgno,
-       struct xfs_imeta_path   **pathp)
+/* create the directory entry name for an rtrefcount btree inode. */
+const char *
+xfs_rtrefcountbt_name(
+       xfs_rgnumber_t          rgno)
 {
-       struct xfs_imeta_path   *path;
-       unsigned char           *fname;
-       int                     error;
-
-       error = xfs_imeta_create_file_path(mp, 2, &path);
-       if (error)
-               return error;
-
-       fname = kmalloc(XFS_RTREFC_NAMELEN, GFP_KERNEL);
-       if (!fname) {
-               xfs_imeta_free_path(path);
-               return -ENOMEM;
-       }
-
-       snprintf(fname, XFS_RTREFC_NAMELEN, "%u.refcount", rgno);
-       path->im_path[0] = "realtime";
-       path->im_path[1] = fname;
-       path->im_dynamicmask = 0x2;
-       *pathp = path;
-       return 0;
+       return kasprintf(GFP_KERNEL, "%u.refcount", rgno);
 }
 
 /* Calculate the rtrefcount btree size for some records. */
@@ -772,19 +751,18 @@ xfs_iflush_rtrefcount(
  * Create a realtime refcount btree inode.
  *
  * Regardless of the return value, the caller must clean up @upd.  If a new
- * inode is returned through *ipp, the caller must finish setting up the incore
- * inode and release it.
+ * inode is returned through upd.ip, the caller must finish setting up the
+ * incore inode and release it.
  */
 int
 xfs_rtrefcountbt_create(
-       struct xfs_imeta_update *upd,
-       struct xfs_inode        **ipp)
+       struct xfs_imeta_update *upd)
 {
-       struct xfs_mount        *mp = upd->mp;
+       struct xfs_mount        *mp = upd->dp->i_mount;
        struct xfs_ifork        *ifp;
        int                     error;
 
-       error = xfs_imeta_create(upd, S_IFREG, ipp);
+       error = xfs_imeta_dir_create(upd, S_IFREG);
        if (error)
                return error;
 
index f5c7fb09e309e83d205bf1b864183e2e17bd04b9..39a5c6800a2d0aabe390e2d4c09a491488298c5a 100644 (file)
@@ -11,7 +11,6 @@ struct xfs_btree_cur;
 struct xfs_mount;
 struct xbtree_ifakeroot;
 struct xfs_rtgroup;
-struct xfs_imeta_path;
 
 /* refcounts only exist on crc enabled filesystems */
 #define XFS_RTREFCOUNT_BLOCK_LEN       XFS_BTREE_LBLOCK_CRC_LEN
@@ -69,9 +68,7 @@ xfs_rtrefcount_ptr_addr(
 unsigned int xfs_rtrefcountbt_maxlevels_ondisk(void);
 int __init xfs_rtrefcountbt_init_cur_cache(void);
 void xfs_rtrefcountbt_destroy_cur_cache(void);
-
-int xfs_rtrefcountbt_create_path(struct xfs_mount *mp, xfs_rgnumber_t rgno,
-               struct xfs_imeta_path **pathp);
+const char *xfs_rtrefcountbt_name(xfs_rgnumber_t rgno);
 
 xfs_filblks_t xfs_rtrefcountbt_calc_reserves(struct xfs_mount *mp);
 unsigned long long xfs_rtrefcountbt_calc_size(struct xfs_mount *mp,
@@ -190,7 +187,6 @@ void xfs_iflush_rtrefcount(struct xfs_inode *ip, struct xfs_dinode *dip);
 
 struct xfs_imeta_update;
 
-int xfs_rtrefcountbt_create(struct xfs_imeta_update *upd,
-               struct xfs_inode **ipp);
+int xfs_rtrefcountbt_create(struct xfs_imeta_update *upd);
 
 #endif /* __XFS_RTREFCOUNT_BTREE_H__ */
index a1371be54544f800649f3fbf3f7b5f92a1f5d237..c86f4314e3a15e5fc8048eac31c17769cd93d7b8 100644 (file)
@@ -818,35 +818,12 @@ xfs_rtrmapbt_compute_maxlevels(
        mp->m_rtrmap_maxlevels = min(d_maxlevels, r_maxlevels) + 1;
 }
 
-#define XFS_RTRMAP_NAMELEN             17
-
 /* Create the metadata directory path for an rtrmap btree inode. */
-int
-xfs_rtrmapbt_create_path(
-       struct xfs_mount        *mp,
-       xfs_rgnumber_t          rgno,
-       struct xfs_imeta_path   **pathp)
+const char *
+xfs_rtrmapbt_name(
+       xfs_rgnumber_t          rgno)
 {
-       struct xfs_imeta_path   *path;
-       unsigned char           *fname;
-       int                     error;
-
-       error = xfs_imeta_create_file_path(mp, 2, &path);
-       if (error)
-               return error;
-
-       fname = kmalloc(XFS_RTRMAP_NAMELEN, GFP_KERNEL);
-       if (!fname) {
-               xfs_imeta_free_path(path);
-               return -ENOMEM;
-       }
-
-       snprintf(fname, XFS_RTRMAP_NAMELEN, "%u.rmap", rgno);
-       path->im_path[0] = "realtime";
-       path->im_path[1] = fname;
-       path->im_dynamicmask = 0x2;
-       *pathp = path;
-       return 0;
+       return kasprintf(GFP_KERNEL, "%u.rmap", rgno);
 }
 
 /* Calculate the rtrmap btree size for some records. */
@@ -1021,19 +998,18 @@ xfs_iflush_rtrmap(
  * Create a realtime rmap btree inode.
  *
  * Regardless of the return value, the caller must clean up @upd.  If a new
- * inode is returned through @*ipp, the caller must finish setting up the incore
- * inode and release it.
+ * inode is returned through upd.ip, the caller must finish setting up the
+ * incore inode and release it.
  */
 int
 xfs_rtrmapbt_create(
-       struct xfs_imeta_update *upd,
-       struct xfs_inode        **ipp)
+       struct xfs_imeta_update *upd)
 {
-       struct xfs_mount        *mp = upd->mp;
+       struct xfs_mount        *mp = upd->dp->i_mount;
        struct xfs_ifork        *ifp;
        int                     error;
 
-       error = xfs_imeta_create(upd, S_IFREG, ipp);
+       error = xfs_imeta_dir_create(upd, S_IFREG);
        if (error)
                return error;
 
index 59f6a4bf9dac6791053f4e277abb3a4290807653..037aac6d0d21a136d05e09c102041b7bf2cfcffc 100644 (file)
@@ -11,7 +11,6 @@ struct xfs_btree_cur;
 struct xfs_mount;
 struct xbtree_ifakeroot;
 struct xfs_rtgroup;
-struct xfs_imeta_path;
 
 /* rmaps only exist on crc enabled filesystems */
 #define XFS_RTRMAP_BLOCK_LEN   XFS_BTREE_LBLOCK_CRC_LEN
@@ -81,9 +80,7 @@ unsigned int xfs_rtrmapbt_maxlevels_ondisk(void);
 
 int __init xfs_rtrmapbt_init_cur_cache(void);
 void xfs_rtrmapbt_destroy_cur_cache(void);
-
-int xfs_rtrmapbt_create_path(struct xfs_mount *mp, xfs_rgnumber_t rgno,
-               struct xfs_imeta_path **pathp);
+const char *xfs_rtrmapbt_name(xfs_rgnumber_t rgno);
 
 xfs_filblks_t xfs_rtrmapbt_calc_reserves(struct xfs_mount *mp);
 
@@ -200,7 +197,7 @@ void xfs_iflush_rtrmap(struct xfs_inode *ip, struct xfs_dinode *dip);
 
 struct xfs_imeta_update;
 
-int xfs_rtrmapbt_create(struct xfs_imeta_update *upd, struct xfs_inode **ipp);
+int xfs_rtrmapbt_create(struct xfs_imeta_update *upd);
 
 unsigned long long xfs_rtrmapbt_calc_size(struct xfs_mount *mp,
                unsigned long long len);
index 3c108106351d603849d2e1d2c5ad454a06d6037f..230524beae277936a3271f1acdd3d5bbb7c65ecf 100644 (file)
@@ -754,24 +754,10 @@ __xfs_sb_from_disk(
        if (convert_xquota)
                xfs_sb_quota_from_disk(to);
 
-       if (to->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_METADIR) {
-               /*
-                * Set metadirino here and null out the in-core fields for
-                * the other inodes because metadir initialization will load
-                * them later.
-                */
-               to->sb_metadirino = be64_to_cpu(from->sb_rbmino);
-               to->sb_rbmino = NULLFSINO;
-               to->sb_rsumino = NULLFSINO;
-
-               /*
-                * We don't have to worry about quota inode conversion here
-                * because metadir requires a v5 filesystem.
-                */
-               to->sb_uquotino = NULLFSINO;
-               to->sb_gquotino = NULLFSINO;
-               to->sb_pquotino = NULLFSINO;
-       }
+       if (to->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_METADIR)
+               to->sb_metadirino = be64_to_cpu(from->sb_metadirino);
+       else
+               to->sb_metadirino = NULLFSINO;
 
        if (to->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_RTGROUPS) {
                to->sb_rgcount = be32_to_cpu(from->sb_rgcount);
@@ -928,20 +914,10 @@ xfs_sb_to_disk(
        if (from->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_META_UUID)
                uuid_copy(&to->sb_meta_uuid, &from->sb_meta_uuid);
 
-       if (from->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_METADIR) {
-               /*
-                * Save metadirino here and null out the on-disk fields for
-                * the other inodes, at least until we reuse the fields.
-                */
-               to->sb_rbmino = cpu_to_be64(from->sb_metadirino);
-               to->sb_rsumino = cpu_to_be64(NULLFSINO);
-               to->sb_uquotino = cpu_to_be64(NULLFSINO);
-               to->sb_gquotino = cpu_to_be64(NULLFSINO);
-               to->sb_pquotino = cpu_to_be64(NULLFSINO);
-       }
+       if (from->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_METADIR)
+               to->sb_metadirino = cpu_to_be64(from->sb_metadirino);
 
        if (from->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_RTGROUPS) {
-               /* must come after setting to_rsumino */
                to->sb_rgcount = cpu_to_be32(from->sb_rgcount);
                to->sb_rgblocks = cpu_to_be32(from->sb_rgblocks);
        }
index 2fd942c42e771663a16f9ce40bbbd82138fedda9..44fe2d00d54d586b5d396ce295109ff96c60ff94 100644 (file)
@@ -1164,56 +1164,6 @@ xfs_calc_imeta_create_count(
        return resp->tr_create.tr_logcount;
 }
 
-/*
- * Metadata inode link needs enough space to add a file plus logging the
- * superblock.
- */
-static unsigned int
-xfs_calc_imeta_link_resv(
-       struct xfs_mount        *mp,
-       struct xfs_trans_resv   *resp)
-{
-       unsigned int            ret;
-
-       ret = xfs_calc_buf_res(1, mp->m_sb.sb_sectsize);
-       ret += resp->tr_link.tr_logres;
-       return ret;
-}
-
-/* Metadata inode linking needs enough rounds to remove a file. */
-static int
-xfs_calc_imeta_link_count(
-       struct xfs_mount        *mp,
-       struct xfs_trans_resv   *resp)
-{
-       return resp->tr_link.tr_logcount;
-}
-
-/*
- * Metadata inode unlink needs enough space to remove a file plus logging the
- * superblock.
- */
-static unsigned int
-xfs_calc_imeta_unlink_resv(
-       struct xfs_mount        *mp,
-       struct xfs_trans_resv   *resp)
-{
-       unsigned int            ret;
-
-       ret = xfs_calc_buf_res(1, mp->m_sb.sb_sectsize);
-       ret += resp->tr_remove.tr_logres;
-       return ret;
-}
-
-/* Metadata inode unlinking needs enough rounds to remove a file. */
-static int
-xfs_calc_imeta_unlink_count(
-       struct xfs_mount        *mp,
-       struct xfs_trans_resv   *resp)
-{
-       return resp->tr_remove.tr_logcount;
-}
-
 /*
  * Namespace reservations.
  *
@@ -1355,28 +1305,9 @@ xfs_trans_resv_calc(
        resp->tr_write.tr_logcount += logcount_adj;
        resp->tr_qm_dqalloc.tr_logcount += logcount_adj;
 
-       /* metadata inode creation and unlink */
-       if (xfs_has_metadir(mp)) {
-               resp->tr_imeta_create.tr_logres =
-                               xfs_calc_imeta_create_resv(mp, resp);
-               resp->tr_imeta_create.tr_logcount =
-                               xfs_calc_imeta_create_count(mp, resp);
-               resp->tr_imeta_create.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
-
-               resp->tr_imeta_link.tr_logres =
-                               xfs_calc_imeta_link_resv(mp, resp);
-               resp->tr_imeta_link.tr_logcount =
-                               xfs_calc_imeta_link_count(mp, resp);
-               resp->tr_imeta_link.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
-
-               resp->tr_imeta_unlink.tr_logres =
-                               xfs_calc_imeta_unlink_resv(mp, resp);
-               resp->tr_imeta_unlink.tr_logcount =
-                               xfs_calc_imeta_unlink_count(mp, resp);
-               resp->tr_imeta_unlink.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
-       } else {
-               resp->tr_imeta_create = resp->tr_create;
-               resp->tr_imeta_link = resp->tr_link;
-               resp->tr_imeta_unlink = resp->tr_remove;
-       }
+       /* metadata inode creation */
+       resp->tr_imeta_create.tr_logres = xfs_calc_imeta_create_resv(mp, resp);
+       resp->tr_imeta_create.tr_logcount =
+                       xfs_calc_imeta_create_count(mp, resp);
+       resp->tr_imeta_create.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
 }
index 6b851dfe1ac079742ed49a0e1adb57d1dd2bac48..a975b8d1310c2904a57772e21141b07ff4dfe597 100644 (file)
@@ -49,8 +49,6 @@ struct xfs_trans_resv {
        struct xfs_trans_res    tr_sb;          /* modify superblock */
        struct xfs_trans_res    tr_fsyncts;     /* update timestamps on fsync */
        struct xfs_trans_res    tr_imeta_create; /* create metadata inode */
-       struct xfs_trans_res    tr_imeta_link;  /* link metadata inode */
-       struct xfs_trans_res    tr_imeta_unlink; /* unlink metadata inode */
 };
 
 /* shorthand way of accessing reservation structure */
index 6488cda24e8670b9efb966c3c51e780367a1eea7..25aa8dac24a395d03eeb1b29c82561163b98d40d 100644 (file)
@@ -12,7 +12,6 @@
 #include "xfs_bit.h"
 #include "xfs_mount.h"
 #include "xfs_ag.h"
-#include "xfs_imeta.h"
 #include "xfs_rtbitmap.h"
 #include "xfs_rtgroup.h"
 
@@ -118,7 +117,9 @@ xfs_internal_inum(
        struct xfs_mount        *mp,
        xfs_ino_t               ino)
 {
-       return xfs_is_static_meta_ino(mp, ino);
+       return ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino ||
+               (xfs_has_quota(mp) &&
+                xfs_is_quota_inode(&mp->m_sb, ino));
 }
 
 /*
@@ -130,7 +131,7 @@ xfs_verify_dir_ino(
        struct xfs_mount        *mp,
        xfs_ino_t               ino)
 {
-       if (!xfs_has_metadir(mp) && xfs_internal_inum(mp, ino))
+       if (xfs_internal_inum(mp, ino))
                return false;
        return xfs_verify_ino(mp, ino);
 }