@@ -520,6 +520,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
@@ -661,6 +680,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);
+ }
}
/*
@@ -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);
}
@@ -645,6 +645,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",
@@ -876,7 +886,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.
@@ -888,7 +898,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);
@@ -1032,6 +1042,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.
@@ -1095,6 +1108,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
@@ -120,6 +120,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; /* metadata inode 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 */