summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2020-10-25 17:16:03 -0700
committerDarrick J. Wong <darrick.wong@oracle.com>2020-10-26 18:32:30 -0700
commit6ef0e4f57e2d258304d5cb0a28309568055588ee (patch)
treeb1b25686dc6959e3a43c59d92c144369fccf7d82
parentbc96e0eabdb435b1b15f8f5b216db0fc1206cf06 (diff)
xfs: load metadata directory root at mount time
Load the metadata directory root inode into memory at mount time and release it at unmount time. We also make sure that the obsolete inode pointers in the superblock are not logged or read from the superblock. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
-rw-r--r--fs/xfs/libxfs/xfs_sb.c31
-rw-r--r--fs/xfs/libxfs/xfs_types.c2
-rw-r--r--fs/xfs/xfs_mount.c20
-rw-r--r--fs/xfs/xfs_mount.h1
4 files changed, 51 insertions, 3 deletions
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index b9473717d9a0..c33b75cec84a 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -552,6 +552,25 @@ __xfs_sb_from_disk(
/* Convert on-disk flags to in-memory flags? */
if (convert_xquota)
xfs_sb_quota_from_disk(to);
+
+ if (xfs_sb_version_hasmetadir(to)) {
+ /*
+ * 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;
+ }
}
void
@@ -693,6 +712,18 @@ xfs_sb_to_disk(
if (xfs_sb_version_hasmetauuid(from))
uuid_copy(&to->sb_meta_uuid, &from->sb_meta_uuid);
}
+
+ if (xfs_sb_version_hasmetadir(from)) {
+ /*
+ * 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);
+ }
}
/*
diff --git a/fs/xfs/libxfs/xfs_types.c b/fs/xfs/libxfs/xfs_types.c
index 94ae0002a5e1..1e4bab40f7dd 100644
--- a/fs/xfs/libxfs/xfs_types.c
+++ b/fs/xfs/libxfs/xfs_types.c
@@ -157,7 +157,7 @@ xfs_verify_dir_ino(
struct xfs_mount *mp,
xfs_ino_t ino)
{
- if (xfs_internal_inum(mp, ino))
+ if (!xfs_sb_version_hasmetadir(&mp->m_sb) && xfs_internal_inum(mp, ino))
return false;
return xfs_verify_ino(mp, ino);
}
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 3a154ad62e7d..223126c4f0cb 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -641,6 +641,16 @@ xfs_mountfs_imeta(
{
int error;
+ /* Load the metadata directory inode into memory. */
+ if (xfs_sb_version_hasmetadir(&mp->m_sb)) {
+ error = xfs_imeta_iget(mp, mp->m_sb.sb_metadirino,
+ XFS_DIR3_FT_DIR, &mp->m_metadirip);
+ if (error) {
+ xfs_warn(mp, "Failed metadir ino init: %d", error);
+ return error;
+ }
+ }
+
error = xfs_imeta_mount(mp);
if (error) {
xfs_warn(mp, "Failed to load metadata inode info, error %d",
@@ -872,7 +882,7 @@ xfs_mountfs(
error = xfs_mountfs_imeta(mp);
if (error)
- goto out_log_dealloc;
+ goto out_free_metadir;
/*
* Get and sanity-check the root inode.
@@ -884,7 +894,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);
@@ -1028,6 +1038,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_imeta_irele(mp->m_metadirip);
/*
* Shut down all pending inode inactivation work, which will also
* cancel all delayed reclaim work and reclaim the inodes directly.
@@ -1091,6 +1104,9 @@ xfs_unmountfs(
xfs_rtunmount_inodes(mp);
xfs_irele(mp->m_rootip);
+ if (mp->m_metadirip)
+ xfs_imeta_irele(mp->m_metadirip);
+
/*
* We can potentially deadlock here if we have an inode cluster
* that has been freed has its buffer still pinned in memory because
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 67189ddef472..be355c5a1414 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -77,6 +77,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 */
xfs_buftarg_t *m_ddev_targp; /* saves taking the address */
xfs_buftarg_t *m_logdev_targp;/* ptr to log device */