From: Darrick J. Wong <djwong@kernel.org> Date: Wed, 3 Jul 2024 21:22:36 +0000 (-0700) Subject: mkfs: enable reflink on the realtime device X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Fxfs-realtime-refcount-rebase;p=users%2Fhch%2Fxfsprogs.git mkfs: enable reflink on the realtime device Allow the creation of filesystems with both reflink and realtime volumes enabled. For now we don't support a realtime extent size > 1. Signed-off-by: Darrick J. Wong <djwong@kernel.org> --- diff --git a/libxfs/init.c b/libxfs/init.c index 5e248de68..e3e7cd12b 100644 --- a/libxfs/init.c +++ b/libxfs/init.c @@ -300,9 +300,9 @@ rtmount_init( if (mp->m_sb.sb_rblocks == 0) return 0; - if (xfs_has_reflink(mp)) { + if (xfs_has_reflink(mp) && mp->m_sb.sb_rextsize > 1) { fprintf(stderr, - _("%s: Reflink not compatible with realtime device. Please try a newer xfsprogs.\n"), + _("%s: Reflink not compatible with realtime extent size > 1. Please try a newer xfsprogs.\n"), progname); return -1; } diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index 17f99efdd..fc2fd4bc6 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -2553,12 +2553,36 @@ _("inode btree counters not supported without finobt support\n")); } if (cli->xi->rt.name) { - if (cli->sb_feat.reflink && cli_opt_set(&mopts, M_REFLINK)) { - fprintf(stderr, -_("reflink not supported with realtime devices\n")); - usage(); + if (cli->rtextsize && cli->sb_feat.reflink) { + if (cli_opt_set(&mopts, M_REFLINK)) { + fprintf(stderr, +_("reflink not supported on realtime devices with rt extent size specified\n")); + usage(); + } + cli->sb_feat.reflink = false; + } + if (cli->blocksize < XFS_MIN_RTEXTSIZE && cli->sb_feat.reflink) { + if (cli_opt_set(&mopts, M_REFLINK)) { + fprintf(stderr, +_("reflink not supported on realtime devices with blocksize %d < %d\n"), + cli->blocksize, + XFS_MIN_RTEXTSIZE); + usage(); + } + cli->sb_feat.reflink = false; + } + if (!cli->sb_feat.rtgroups && cli->sb_feat.reflink) { + if (cli_opt_set(&mopts, M_REFLINK) && + cli_opt_set(&ropts, R_RTGROUPS)) { + fprintf(stderr, +_("reflink not supported on realtime devices without rtgroups feature\n")); + usage(); + } else if (cli_opt_set(&mopts, M_REFLINK)) { + cli->sb_feat.rtgroups = true; + } else { + cli->sb_feat.reflink = false; + } } - cli->sb_feat.reflink = false; if (!cli->sb_feat.rtgroups && cli->sb_feat.rmapbt) { if (cli_opt_set(&mopts, M_RMAPBT) && @@ -2771,6 +2795,19 @@ validate_rtextsize( usage(); } cfg->rtextblocks = (xfs_extlen_t)(rtextbytes >> cfg->blocklog); + } else if (cli->sb_feat.reflink && cli->xi->rt.name) { + /* + * reflink doesn't support rt extent size > 1FSB yet, so set + * an extent size of 1FSB. Make sure we still satisfy the + * minimum rt extent size. + */ + if (cfg->blocksize < XFS_MIN_RTEXTSIZE) { + fprintf(stderr, + _("reflink not supported on rt volume with blocksize %d\n"), + cfg->blocksize); + usage(); + } + cfg->rtextblocks = 1; } else { /* * If realtime extsize has not been specified by the user, @@ -2802,6 +2839,12 @@ validate_rtextsize( } } ASSERT(cfg->rtextblocks); + + if (cli->sb_feat.reflink && cfg->rtblocks > 0 && cfg->rtextblocks > 1) { + fprintf(stderr, +_("reflink not supported on realtime with extent sizes > 1\n")); + usage(); + } } /* Validate the incoming extsize hint. */ @@ -4887,11 +4930,18 @@ check_rt_meta_prealloc( rtg->rtg_inodes[XFS_RTG_RMAP], ask); if (error) prealloc_fail(mp, error, ask, _("realtime rmap btree")); + + ask = libxfs_rtrefcountbt_calc_reserves(mp); + error = -libxfs_metafile_resv_init( + rtg->rtg_inodes[XFS_RTG_REFCOUNT], ask); + if (error) + prealloc_fail(mp, error, ask, _("realtime refcount btree")); } /* Unreserve the realtime metadata reservations. */ for_each_rtgroup(mp, rgno, rtg) { libxfs_metafile_resv_free(rtg->rtg_inodes[XFS_RTG_RMAP]); + libxfs_metafile_resv_free(rtg->rtg_inodes[XFS_RTG_REFCOUNT]); } /* Unreserve the per-AG reservations. */