int64_t logagno;
int loginternal;
int lsunit;
+ int has_warranty;
/* parameters where 0 is not a valid value */
int64_t agcount;
}
}
+/* Complain if this filesystem is not a supported configuration. */
+static void
+validate_warranty(
+ struct xfs_mount *mp,
+ struct cli_params *cli)
+{
+ /* Undocumented option to enable unsupported tiny filesystems. */
+ if (!cli->has_warranty) {
+ printf(
+ _("Filesystems formatted with --yes-i-know-what-i-am-doing are not supported!!\n"));
+ return;
+ }
+
+ /*
+ * fstests has a large number of tests that create tiny filesystems to
+ * perform specific regression and resource depletion tests in a
+ * controlled environment. Avoid breaking fstests by allowing
+ * unsupported configurations if TEST_DIR, TEST_DEV, and QA_CHECK_FS
+ * are all set.
+ */
+ if (getenv("TEST_DIR") && getenv("TEST_DEV") && getenv("QA_CHECK_FS"))
+ return;
+
+ /*
+ * We don't support filesystems smaller than 300MB anymore. Tiny
+ * filesystems have never been XFS' design target. This limit has been
+ * carefully calculated to prevent formatting with a log smaller than
+ * the "realistic" size.
+ *
+ * If the realistic log size is 64MB, there are four AGs, and the log
+ * AG should be at least 1/8 free after formatting, this gives us:
+ *
+ * 64MB * (8 / 7) * 4 = 293MB
+ */
+ if (mp->m_sb.sb_dblocks < MEGABYTES(300, mp->m_sb.sb_blocklog)) {
+ fprintf(stderr,
+ _("Filesystem must be larger than 300MB.\n"));
+ usage();
+ }
+
+ /*
+ * For best performance, we don't allow unrealistically small logs.
+ * See the comment for XFS_MIN_REALISTIC_LOG_BLOCKS.
+ */
+ if (mp->m_sb.sb_logblocks <
+ XFS_MIN_REALISTIC_LOG_BLOCKS(mp->m_sb.sb_blocklog)) {
+ fprintf(stderr,
+ _("Log size must be at least 64MB.\n"));
+ usage();
+ }
+
+ /*
+ * Filesystems should not have fewer than two AGs, because we need to
+ * have redundant superblocks.
+ */
+ if (mp->m_sb.sb_agcount < 2) {
+ fprintf(stderr,
+ _("Filesystem must have redundant superblocks!\n"));
+ usage();
+ }
+}
+
/*
* Validate the configured stripe geometry, or is none is specified, pull
* the configuration from the underlying device.
struct cli_params cli = {
.xi = &xi,
.loginternal = 1,
+ .has_warranty = 1,
};
struct mkfs_params cfg = {};
+ struct option long_options[] = {
+ {
+ .name = "yes-i-know-what-i-am-doing",
+ .has_arg = no_argument,
+ .flag = &cli.has_warranty,
+ .val = 0,
+ },
+ {NULL, 0, NULL, 0 },
+ };
+ int option_index = 0;
+
/* build time defaults */
struct mkfs_default_params dft = {
.source = _("package build definitions"),
memcpy(&cli.sb_feat, &dft.sb_feat, sizeof(cli.sb_feat));
memcpy(&cli.fsx, &dft.fsx, sizeof(cli.fsx));
- while ((c = getopt(argc, argv, "b:c:d:i:l:L:m:n:KNp:qr:s:CfV")) != EOF) {
+ while ((c = getopt_long(argc, argv, "b:c:d:i:l:L:m:n:KNp:qr:s:CfV",
+ long_options, &option_index)) != EOF) {
switch (c) {
+ case 0:
+ break;
case 'C':
case 'f':
force_overwrite = 1;
validate_extsize_hint(mp, &cli);
validate_cowextsize_hint(mp, &cli);
+ validate_warranty(mp, &cli);
+
/* Print the intended geometry of the fs. */
if (!quiet || dry_run) {
struct xfs_fsop_geom geo;