#define XFS_FEAT_NREXT64 (1ULL << 26) /* large extent counters */
#define XFS_FEAT_EXCHANGE_RANGE (1ULL << 27) /* exchange range */
#define XFS_FEAT_METADIR (1ULL << 28) /* metadata directory tree */
-#define XFS_FEAT_RTGROUPS (1ULL << 29) /* realtime groups */
-#define XFS_FEAT_RTSB (1ULL << 30) /* realtime superblock */
#define __XFS_HAS_FEAT(name, NAME) \
static inline bool xfs_has_ ## name (struct xfs_mount *mp) \
__XFS_HAS_FEAT(large_extent_counts, NREXT64)
__XFS_HAS_FEAT(exchange_range, EXCHANGE_RANGE)
__XFS_HAS_FEAT(metadir, METADIR)
-__XFS_HAS_FEAT(rtgroups, RTGROUPS)
-__XFS_HAS_FEAT(rtsb, RTSB)
+
+static inline bool xfs_has_rtgroups(struct xfs_mount *mp)
+{
+ /* all metadir file systems using rtgroups */
+ return xfs_has_metadir(mp);
+}
+
+static inline bool xfs_has_rtsb(struct xfs_mount *mp)
+{
+ return xfs_has_metadir(mp) && xfs_has_realtime(mp);
+}
static inline bool xfs_has_rtrmapbt(struct xfs_mount *mp)
{
- return xfs_has_rtgroups(mp) && xfs_has_realtime(mp) &&
+ return xfs_has_metadir(mp) && xfs_has_realtime(mp) &&
xfs_has_rmapbt(mp);
}
R_FILE,
R_NAME,
R_NOALIGN,
- R_RTGROUPS,
R_RGCOUNT,
R_RGSIZE,
- R_RTSB,
R_MAX_OPTS,
};
[R_FILE] = "file",
[R_NAME] = "name",
[R_NOALIGN] = "noalign",
- [R_RTGROUPS] = "rtgroups",
[R_RGCOUNT] = "rgcount",
[R_RGSIZE] = "rgsize",
- [R_RTSB] = "rtsb",
[R_MAX_OPTS] = NULL,
},
.subopt_params = {
.defaultval = 1,
.conflicts = { { NULL, LAST_CONFLICT } },
},
- { .index = R_RTGROUPS,
- .conflicts = { { NULL, LAST_CONFLICT } },
- .minval = 0,
- .maxval = 1,
- .defaultval = 1,
- },
{ .index = R_RGCOUNT,
.conflicts = { { &dopts, R_RGSIZE },
{ NULL, LAST_CONFLICT } },
.maxval = (unsigned long long)XFS_MAX_RGBLOCKS << XFS_MAX_BLOCKSIZE_LOG,
.defaultval = SUBOPT_NEEDS_VAL,
},
- { .index = R_RTSB,
- .conflicts = { { NULL, LAST_CONFLICT } },
- .minval = 0,
- .maxval = 1,
- .defaultval = 1,
- },
},
};
bool nortalign;
bool nrext64;
bool exchrange; /* XFS_SB_FEAT_INCOMPAT_EXCHRANGE */
- bool rtgroups; /* XFS_SB_FEAT_INCOMPAT_RTGROUPS */
- bool rtsb; /* XFS_SB_FEAT_RO_COMPAT_RTSB */
};
struct cli_params {
/* no-op info only */ [-N]\n\
/* prototype file */ [-p fname]\n\
/* quiet */ [-q]\n\
-/* realtime subvol */ [-r extsize=num,size=num,rtdev=xxx,rtgroups=0|1,\n\
- rgcount=n,rgsize=n,rtsb=0|1]\n\
+/* realtime subvol */ [-r extsize=num,size=num,rtdev=xxx,rgcount=n,\n\
+ rgsize=n]\n\
/* sectorsize */ [-s size=num]\n\
/* version */ [-V]\n\
devicename\n\
case R_NOALIGN:
cli->sb_feat.nortalign = getnum(value, opts, subopt);
break;
- case R_RTGROUPS:
- cli->sb_feat.rtgroups = getnum(value, opts, subopt);
- break;
case R_RGCOUNT:
cli->rgcount = getnum(value, opts, subopt);
break;
case R_RGSIZE:
cli->rgsize = getstr(value, opts, subopt);
break;
- case R_RTSB:
- cli->sb_feat.rtsb = getnum(value, opts, subopt);
- break;
default:
return -EINVAL;
}
}
if (cli->xi->rt.name) {
- if (cli->rtextsize && cli->sb_feat.reflink) {
+ if (cli->rtextsize && cli->sb_feat.metadir) {
if (cli_opt_set(&mopts, M_REFLINK)) {
fprintf(stderr,
_("reflink not supported on realtime devices with rt extent size specified\n"));
}
cli->sb_feat.reflink = false;
}
- if (!cli->sb_feat.rtgroups && cli->sb_feat.reflink) {
+ if (!cli->sb_feat.metadir && cli->sb_feat.reflink) {
if (cli_opt_set(&mopts, M_REFLINK) &&
- cli_opt_set(&ropts, R_RTGROUPS)) {
+ cli_opt_set(&ropts, M_METADIR)) {
fprintf(stderr,
-_("reflink not supported on realtime devices without rtgroups feature\n"));
+_("reflink not supported on realtime devices without metadir feature\n"));
usage();
} else if (cli_opt_set(&mopts, M_REFLINK)) {
- cli->sb_feat.rtgroups = true;
+ cli->sb_feat.metadir = true;
} else {
cli->sb_feat.reflink = false;
}
}
- if (!cli->sb_feat.rtgroups && cli->sb_feat.rmapbt) {
+ if (!cli->sb_feat.metadir && cli->sb_feat.rmapbt) {
if (cli_opt_set(&mopts, M_RMAPBT) &&
- cli_opt_set(&ropts, R_RTGROUPS)) {
+ cli_opt_set(&ropts, M_METADIR)) {
fprintf(stderr,
-_("rmapbt not supported on realtime devices without rtgroups feature\n"));
+_("rmapbt not supported on realtime devices without metadir feature\n"));
usage();
} else if (cli_opt_set(&mopts, M_RMAPBT)) {
- cli->sb_feat.rtgroups = true;
+ cli->sb_feat.metadir = true;
} else {
cli->sb_feat.rmapbt = false;
}
usage();
}
- if (cli->sb_feat.rtgroups && !cli->sb_feat.metadir) {
- if (cli_opt_set(&mopts, M_METADIR)) {
- fprintf(stderr,
-_("realtime groups not supported without metadata directory support\n"));
- usage();
- }
- cli->sb_feat.metadir = true;
- }
-
/*
* Turn on exchange-range if parent pointers are enabled and the caller
* did not provide an explicit exchange-range parameter so that users
}
/*
- * Exchange-range will be needed for space reorganization on
- * filesystems with realtime rmap or realtime reflink enabled.
+ * Exchange-range will be needed for space reorganization on filesystems
+ * with realtime rmap or realtime reflink enabled, and there is no good
+ * reason to ever disable it on a file system with new enough features.
*/
- if (cli->sb_feat.rtgroups && !cli->sb_feat.exchrange) {
+ if (cli->sb_feat.metadir && !cli->sb_feat.exchrange) {
if (cli_opt_set(&iopts, I_EXCHANGE)) {
fprintf(stderr,
-_("realtime groups not supported without exchange-range support\n"));
+_("metadir not supported without exchange-range support\n"));
usage();
}
cli->sb_feat.exchrange = true;
}
- /*
- * Turn on realtime superblocks if realtime groups are enabled and the
- * caller did not provide an explicit rtsb parameter so that users
- * can take advantage of labelled rt volumes. It's not required for
- * correct operation, but it costs us nothing to enable it.
- */
- if (cli->sb_feat.rtgroups && !cli->sb_feat.rtsb &&
- !cli_opt_set(&ropts, R_RTSB)) {
- cli->sb_feat.rtsb = true;
- }
-
- /* Realtime superblocks require realtime groups. */
- if (cli->sb_feat.rtsb && !cli->sb_feat.rtgroups) {
- if (cli_opt_set(&ropts, R_RTSB)) {
- fprintf(stderr,
-_("realtime superblock not supported without realtime group support\n"));
- usage();
- }
- cli->sb_feat.rtsb = true;
- }
-
/*
* Copy features across to config structure now.
*/
struct mkfs_params *cfg,
struct cli_params *cli)
{
- if (!cli->sb_feat.rtgroups) {
+ if (!cli->sb_feat.metadir) {
cfg->rgcount = 0;
cfg->rgsize = 0;
return;
*/
sbp->sb_versionnum |= XFS_SB_VERSION_ATTRBIT;
}
- if (fp->metadir)
+ if (fp->metadir) {
sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_METADIR;
- if (fp->rtsb)
- sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_RTSB;
- if (fp->rtgroups) {
- sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_RTGROUPS;
sbp->sb_rgcount = cfg->rgcount;
sbp->sb_rgextents = cfg->rgsize / cfg->rtextblocks;
}
*
* size is the size of data which is valid for this sb.
*/
- if (xfs_sb_version_hasrtgroups(sb))
+ if (xfs_sb_version_hasmetadir(sb))
size = offsetofend(struct xfs_dsb, sb_rgextents);
- else if (xfs_sb_version_hasmetadir(sb))
- size = offsetofend(struct xfs_dsb, sb_metadirino);
else if (xfs_sb_version_hasmetauuid(sb))
size = offsetofend(struct xfs_dsb, sb_meta_uuid);
else if (xfs_sb_version_hascrc(sb))
bool add_rmapbt; /* add reverse mapping btrees */
bool add_parent; /* add parent pointers */
bool add_metadir; /* add metadata directory tree */
-bool add_rtsb; /* add realtime superblock */
-bool add_rtgroups; /* add realtime allocation groups */
/* misc status variables */
extern bool add_rmapbt; /* add reverse mapping btrees */
extern bool add_parent; /* add parent pointers */
extern bool add_metadir; /* add metadata directory tree */
-extern bool add_rtsb; /* add realtime superblock */
-extern bool add_rtgroups; /* add realtime allocation groups */
/* misc status variables */
doomed_gquotino = mp->m_sb.sb_gquotino;
doomed_pquotino = mp->m_sb.sb_pquotino;
- new_sb->sb_rbmino = new_sb->sb_metadirino + 1;
- new_sb->sb_rsumino = new_sb->sb_rbmino + 1;
+ new_sb->sb_rbmino = NULLFSINO;
+ new_sb->sb_rsumino = NULLFSINO;
new_sb->sb_uquotino = NULLFSINO;
new_sb->sb_gquotino = NULLFSINO;
new_sb->sb_pquotino = NULLFSINO;
+ new_sb->sb_rgextents = 0;
+ new_sb->sb_rgcount = 0;
/* Indicate that we need a rebuild. */
need_metadir_inode = 1;
return true;
}
-static bool
-set_rtsb(
- struct xfs_mount *mp,
- struct xfs_sb *new_sb)
-{
- if (xfs_has_rtsb(mp)) {
- printf(_("Filesystem already supports realtime superblock.\n"));
- exit(0);
- }
-
- if (!xfs_has_rtgroups(mp) && !add_rtgroups) {
- printf(
- _("Realtime superblock feature only supported if realtime groups are enabled.\n"));
- exit(0);
- }
-
- if (!xfs_has_crc(mp)) {
- printf(
- _("Realtime superblock only supported on V5 filesystems.\n"));
- exit(0);
- }
-
- if (xfs_has_realtime(mp)) {
- printf(
- _("Realtime superblock feature cannot be added to existing realtime volumes.\n"));
- exit(0);
- }
-
- printf(_("Adding realtime superblock to filesystem.\n"));
- new_sb->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_RTSB;
- new_sb->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR;
- return true;
-}
-
-static bool
-set_rtgroups(
- struct xfs_mount *mp,
- struct xfs_sb *new_sb)
-{
- if (xfs_has_rtgroups(mp)) {
- printf(_("Filesystem already supports realtime groups.\n"));
- exit(0);
- }
-
- if (!xfs_has_metadir(mp) && !add_metadir) {
- printf(
- _("Realtime allocation group feature only supported if metadir is enabled.\n"));
- exit(0);
- }
-
- if (!xfs_has_crc(mp)) {
- printf(
- _("Realtime allocation groups only supported on V5 filesystems.\n"));
- exit(0);
- }
-
- if (xfs_has_realtime(mp)) {
- printf(
- _("Realtime allocation group feature cannot be added to existing realtime volumes.\n"));
- exit(0);
- }
-
- printf(_("Adding realtime groups to filesystem.\n"));
- new_sb->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_RTGROUPS;
- new_sb->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR;
- new_sb->sb_rgcount = 0;
- /*
- * The allocation group size is 1TB, rounded down to the nearest rt
- * extent.
- */
- new_sb->sb_rgextents = xfs_blen_to_rtbxlen(mp,
- XFS_B_TO_FSBT(mp, 1ULL << 40));
- return true;
-}
-
struct check_state {
struct xfs_sb sb;
uint64_t features;
dirty |= set_parent(mp, &new_sb);
if (add_metadir)
dirty |= set_metadir(mp, &new_sb);
- if (add_rtsb)
- dirty |= set_rtsb(mp, &new_sb);
- if (add_rtgroups)
- dirty |= set_rtgroups(mp, &new_sb);
if (!dirty)
return;
{
uint64_t groups;
- if (!(sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_METADIR))
- return XR_BAD_RT_GEO_DATA;
+ if (sbp->sb_rextents == 0)
+ return 0;
if (sbp->sb_rextsize == 0)
return XR_BAD_RT_GEO_DATA;
if (sb->sb_blocklog + sb->sb_dirblklog > XFS_MAX_BLOCKSIZE_LOG)
return XR_BAD_DIR_SIZE_DATA;
- if (sb->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_RTGROUPS) {
+ if (xfs_sb_version_hasmetadir(sb)) {
int err = verify_sb_rtgroups(sb);
if (err)
return err;
CONVERT_RMAPBT,
CONVERT_PARENT,
CONVERT_METADIR,
- CONVERT_RTSB,
- CONVERT_RTGROUPS,
C_MAX_OPTS,
};
[CONVERT_RMAPBT] = "rmapbt",
[CONVERT_PARENT] = "parent",
[CONVERT_METADIR] = "metadir",
- [CONVERT_RTSB] = "rtsb",
- [CONVERT_RTGROUPS] = "rtgroups",
[C_MAX_OPTS] = NULL,
};
_("-c metadir only supports upgrades\n"));
add_metadir = true;
break;
- case CONVERT_RTSB:
- if (!val)
- do_abort(
- _("-c rtsb requires a parameter\n"));
- if (strtol(val, NULL, 0) != 1)
- do_abort(
- _("-c rtsb only supports upgrades\n"));
- add_rtsb = true;
- break;
- case CONVERT_RTGROUPS:
- if (!val)
- do_abort(
- _("-c rtgroups requires a parameter\n"));
- if (strtol(val, NULL, 0) != 1)
- do_abort(
- _("-c rtgroups only supports upgrades\n"));
- add_rtgroups = true;
- break;
default:
unknown('c', val);
break;