summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2020-02-19 17:02:54 -0800
committerDarrick J. Wong <darrick.wong@oracle.com>2020-06-01 21:16:45 -0700
commit30943144c77b2bfc0c3452b1ecf1a24014e909f4 (patch)
treed99a42eac93a3b803e52645336a5385fbe4cd3e0 /fs
parent4b9c7054f8bc76adc127ce9812a0b1bb23213163 (diff)
xfs: dynamically create the realtime rmapbt inode when attaching rtdev
If the administrator asks us to add a realtime volume to an existing rmap filesystem, we must allocate and attach the rtrmapbt inode to the system prior to enabling the rt volume. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_rtalloc.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 976a7b017c82..000073e2fcc0 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -22,6 +22,7 @@
#include "xfs_da_format.h"
#include "xfs_imeta.h"
#include "xfs_error.h"
+#include "xfs_rtrmap_btree.h"
/*
* Read and return the summary information for a given extent size,
@@ -874,6 +875,60 @@ xfs_alloc_rsum_cache(
* Visible (exported) functions.
*/
+
+/* Add a realtime rmap btree inode. */
+STATIC int
+xfs_growfs_rt_rmap(
+ struct xfs_mount *mp)
+{
+ struct xfs_imeta_end ic;
+ struct xfs_inode *ip = NULL;
+ struct xfs_trans *tp;
+ int error;
+
+ if (!xfs_sb_version_hasrmapbt(&mp->m_sb) || mp->m_rrmapip != NULL)
+ return 0;
+
+ /* rtrmapbt requires metadir */
+ if (!xfs_sb_version_hasmetadir(&mp->m_sb))
+ return -EINVAL;
+
+ /* Ensure the path to the rtrmapbt inode exists. */
+ error = xfs_imeta_ensure_dirpath(mp, &XFS_IMETA_RTRMAPBT);
+ if (error)
+ return error;
+
+ /* Create the rtrmapbt inode. */
+ error = xfs_trans_alloc(mp, &M_RES(mp)->tr_imeta_create,
+ xfs_imeta_create_space_res(mp), 0, 0, &tp);
+ if (error)
+ return error;
+
+ error = xfs_rtrmapbt_create(&tp, &ic, &ip);
+ if (error)
+ goto out_cancel;
+
+ error = xfs_trans_commit(tp);
+ xfs_finish_inode_setup(ip);
+ xfs_imeta_end_update(mp, &ic, error);
+ if (error) {
+ xfs_irele(ip);
+ return error;
+ }
+
+ mp->m_rrmapip = ip;
+ return 0;
+
+out_cancel:
+ xfs_trans_cancel(tp);
+ xfs_imeta_end_update(mp, &ic, error);
+ if (ip) {
+ xfs_finish_inode_setup(ip);
+ xfs_irele(ip);
+ }
+ return error;
+}
+
/*
* Grow the realtime area of the filesystem.
*/
@@ -955,6 +1010,9 @@ xfs_growfs_rt(
error = xfs_growfs_rt_alloc(mp, rsumblocks, nrsumblocks, mp->m_rsumip);
if (error)
return error;
+ error = xfs_growfs_rt_rmap(mp);
+ if (error)
+ return error;
rsum_cache = mp->m_rsum_cache;
if (nrbmblocks != sbp->sb_rbmblocks)