Create a realtime rmapbt inode if we format the fs with realtime and rmap. Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx> --- libxfs/libxfs_api_defs.h | 1 + mkfs/proto.c | 51 +++++++++++++++++++++++++++++++--------------- mkfs/xfs_mkfs.c | 19 +++++++++++------ 3 files changed, 47 insertions(+), 24 deletions(-) diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h index 44b9065..e567076 100644 --- a/libxfs/libxfs_api_defs.h +++ b/libxfs/libxfs_api_defs.h @@ -145,5 +145,6 @@ #define xfs_rtrmapbt_maxrecs libxfs_rtrmapbt_maxrecs #define xfs_rtrmapbt_init_cursor libxfs_rtrmapbt_init_cursor #define xfs_rmap_map_extent libxfs_rmap_map_extent +#define xfs_btree_compute_maxlevels libxfs_btree_compute_maxlevels #endif /* __LIBXFS_API_DEFS_H__ */ diff --git a/mkfs/proto.c b/mkfs/proto.c index 1de77f8..bf31483 100644 --- a/mkfs/proto.c +++ b/mkfs/proto.c @@ -626,24 +626,25 @@ parse_proto( */ static void rtinit( - xfs_mount_t *mp) + struct xfs_mount *mp) { - xfs_fileoff_t bno; - xfs_fileoff_t ebno; - xfs_bmbt_irec_t *ep; - int error; - xfs_fsblock_t first; + xfs_fileoff_t bno; + xfs_fileoff_t ebno; + struct xfs_bmbt_irec *ep; + int error; + xfs_fsblock_t first; struct xfs_defer_ops dfops; - int i; - xfs_bmbt_irec_t map[XFS_BMAP_MAX_NMAP]; - xfs_extlen_t nsumblocks; - int nmap; - xfs_inode_t *rbmip; - xfs_inode_t *rsumip; - xfs_trans_t *tp; - struct cred creds; - struct fsxattr fsxattrs; - struct xfs_trans_res tres = {0}; + int i; + struct xfs_bmbt_irec map[XFS_BMAP_MAX_NMAP]; + xfs_extlen_t nsumblocks; + int nmap; + struct xfs_inode *rbmip; + struct xfs_inode *rsumip; + struct xfs_inode *rrmapip; + struct xfs_trans *tp; + struct cred creds; + struct fsxattr fsxattrs; + struct xfs_trans_res tres = {0}; /* * First, allocate the inodes. @@ -680,8 +681,24 @@ rtinit( rsumip->i_d.di_size = mp->m_rsumsize; libxfs_trans_log_inode(tp, rsumip, XFS_ILOG_CORE); libxfs_log_sb(tp); - libxfs_trans_commit(tp); mp->m_rsumip = rsumip; + + /* If we have rmap and a realtime device, create a rtrmapbt inode. */ + if (xfs_sb_version_hasrmapbt(&mp->m_sb) && mp->m_sb.sb_rblocks > 0) { + error = -libxfs_inode_alloc(&tp, NULL, S_IFREG, 1, 0, + &creds, &fsxattrs, &rrmapip); + if (error) { + fail(_("Realtime rmap inode allocation failed"), error); + } + mp->m_sb.sb_rrmapino = rrmapip->i_ino; + rrmapip->i_d.di_size = 0; + rrmapip->i_d.di_format = XFS_DINODE_FMT_RMAP; + libxfs_trans_log_inode(tp, rrmapip, XFS_ILOG_CORE); + libxfs_log_sb(tp); + mp->m_rrmapip = rrmapip; + } + libxfs_trans_commit(tp); + /* * Next, give the bitmap file some zero-filled blocks. */ diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index fc565c0..e7bc044 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -2141,13 +2141,6 @@ _("reflink not supported without CRC support\n")); } - if (sb_feat.rmapbt && xi.rtname) { - fprintf(stderr, -_("rmapbt not supported with realtime devices\n")); - usage(); - sb_feat.rmapbt = false; - } - if (nsflag || nlflag) { if (dirblocksize < blocksize || dirblocksize > XFS_MAX_BLOCKSIZE) { @@ -2908,6 +2901,18 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), exit(1); } + /* The realtime rmapbt mustn't grow taller than max btree height. */ + if (xfs_sb_version_hasrtrmapbt(&mp->m_sb) && + libxfs_btree_compute_maxlevels(mp, mp->m_rtrmap_mnr, + mp->m_sb.sb_rblocks) > XFS_BTREE_MAXLEVELS) { + fprintf(stderr, +_("%s: max realtime rmapbt height (%d) exceeds configured maximum (%d)\n"), + progname, libxfs_btree_compute_maxlevels(mp, + mp->m_rtrmap_mnr, mp->m_sb.sb_rblocks), + XFS_BTREE_MAXLEVELS); + exit(1); + } + /* * XXX: this code is effectively shared with the kernel growfs code. * These initialisations should be pulled into libxfs to keep the _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs