]> www.infradead.org Git - users/hch/xfs.git/commitdiff
xfs: load metadata directory root at mount time
authorDarrick J. Wong <djwong@kernel.org>
Wed, 29 May 2024 04:10:56 +0000 (21:10 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Thu, 1 Aug 2024 00:10:01 +0000 (17:10 -0700)
Load the metadata directory root inode into memory at mount time and
release it at unmount time.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
fs/xfs/xfs_mount.c
fs/xfs/xfs_mount.h

index 09eef1721ef4f4f81454229aca90db235d5c1fec..ec9f4911a0e0bcd88718312168975f1586ee685b 100644 (file)
@@ -35,6 +35,7 @@
 #include "xfs_trace.h"
 #include "xfs_ag.h"
 #include "xfs_rtbitmap.h"
+#include "xfs_metafile.h"
 #include "scrub/stats.h"
 
 static DEFINE_MUTEX(xfs_uuid_table_mutex);
@@ -616,6 +617,32 @@ xfs_mount_setup_inode_geom(
        xfs_ialloc_setup_geometry(mp);
 }
 
+/* Mount the metadata directory tree root. */
+STATIC int
+xfs_mount_setup_metadir(
+       struct xfs_mount        *mp)
+{
+       struct xfs_trans        *tp;
+       int                     error;
+
+       error = xfs_trans_alloc_empty(mp, &tp);
+       if (error)
+               return error;
+
+       /* Load the metadata directory root inode into memory. */
+       error = xfs_metafile_iget(tp, mp->m_sb.sb_metadirino, S_IFDIR,
+                       &mp->m_metadirip);
+       if (error) {
+               xfs_warn(mp, "Failed to load metadir root directory, error %d",
+                               error);
+               goto err_cancel;
+       }
+
+err_cancel:
+       xfs_trans_cancel(tp);
+       return error;
+}
+
 /* Compute maximum possible height for per-AG btree types for this fs. */
 static inline void
 xfs_agbtree_compute_maxlevels(
@@ -862,6 +889,12 @@ xfs_mountfs(
                mp->m_features |= XFS_FEAT_ATTR2;
        }
 
+       if (xfs_has_metadir(mp)) {
+               error = xfs_mount_setup_metadir(mp);
+               if (error)
+                       goto out_free_metadir;
+       }
+
        /*
         * Get and sanity-check the root inode.
         * Save the pointer to it in the mount structure.
@@ -872,7 +905,7 @@ xfs_mountfs(
                xfs_warn(mp,
                        "Failed to read root inode 0x%llx, error %d",
                        sbp->sb_rootino, -error);
-               goto out_log_dealloc;
+               goto out_free_metadir;
        }
 
        ASSERT(rip != NULL);
@@ -1014,6 +1047,9 @@ xfs_mountfs(
        xfs_irele(rip);
        /* Clean out dquots that might be in memory after quotacheck. */
        xfs_qm_unmount(mp);
+ out_free_metadir:
+       if (mp->m_metadirip)
+               xfs_irele(mp->m_metadirip);
 
        /*
         * Inactivate all inodes that might still be in memory after a log
@@ -1035,7 +1071,6 @@ xfs_mountfs(
         * quota inodes.
         */
        xfs_unmount_flush_inodes(mp);
- out_log_dealloc:
        xfs_log_mount_cancel(mp);
  out_inodegc_shrinker:
        shrinker_free(mp->m_inodegc_shrinker);
@@ -1087,6 +1122,8 @@ xfs_unmountfs(
        xfs_qm_unmount_quotas(mp);
        xfs_rtunmount_inodes(mp);
        xfs_irele(mp->m_rootip);
+       if (mp->m_metadirip)
+               xfs_irele(mp->m_metadirip);
 
        xfs_unmount_flush_inodes(mp);
 
index d404ce122f238503a353cff91032c127df9b8924..6251ebced3062237d4940064983aaaf2229436f5 100644 (file)
@@ -93,6 +93,7 @@ typedef struct xfs_mount {
        struct xfs_inode        *m_rbmip;       /* pointer to bitmap inode */
        struct xfs_inode        *m_rsumip;      /* pointer to summary inode */
        struct xfs_inode        *m_rootip;      /* pointer to root directory */
+       struct xfs_inode        *m_metadirip;   /* ptr to metadata directory */
        struct xfs_quotainfo    *m_quotainfo;   /* disk quota information */
        struct xfs_buftarg      *m_ddev_targp;  /* data device */
        struct xfs_buftarg      *m_logdev_targp;/* log device */