]> www.infradead.org Git - users/hch/xfs.git/commitdiff
xfs: load metadata directory root at mount time
authorDarrick J. Wong <djwong@kernel.org>
Wed, 7 Aug 2024 22:54:10 +0000 (15:54 -0700)
committerChristoph Hellwig <hch@lst.de>
Sun, 22 Sep 2024 06:07:16 +0000 (08:07 +0200)
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>
Reviewed-by: Christoph Hellwig <hch@lst.de>
fs/xfs/xfs_mount.c
fs/xfs/xfs_mount.h

index 6671ee3849c239887b6d37b74a58c9d2721954bf..70bcc72d3155216b7faae329611b9fede16c2c81 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,22 @@ 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)
+{
+       int                     error;
+
+       /* Load the metadata directory root inode into memory. */
+       error = xfs_metafile_iget(mp, mp->m_sb.sb_metadirino, XFS_METAFILE_DIR,
+                       &mp->m_metadirip);
+       if (error)
+               xfs_warn(mp, "Failed to load metadir root directory, error %d",
+                               error);
+       return error;
+}
+
 /* Compute maximum possible height for per-AG btree types for this fs. */
 static inline void
 xfs_agbtree_compute_maxlevels(
@@ -862,6 +879,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 +895,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 +1037,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 +1061,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 +1112,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 934ad49214c20f784c635c247608b1f1210185a0..92f376d5c2a86335e6554e95a1443646f747fc61 100644 (file)
@@ -97,6 +97,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 */