All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Sandeen <sandeen@sandeen.net>
To: Jeff Mahoney <jeffm@suse.com>,
	"linux-xfs@vger.kernel.org" <linux-xfs@vger.kernel.org>,
	Dave Chinner <david@fromorbit.com>
Subject: [PATCH 2/1] mkfs: factor stripe geom validator & use for cli + device
Date: Mon, 30 Jul 2018 21:57:36 -0500	[thread overview]
Message-ID: <b250d549-68aa-74da-0767-bc5c1d49a9f9@sandeen.net> (raw)
In-Reply-To: <6f62dbc6-f516-e8b5-1f08-6be227a61219@suse.com>

Factor the dsunit-vs-dwidth-vs-blocksize checks into a helper.

If they fail on user-specified values, exit with usage().

If they fail on values from the device, warn about it and set
them to zero so they'll be ignored.

This also ensures that we won't complain if user-specified values
don't match bogus device-provided geometry.

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---

NB: this does undo Jeff's "try to make the best of it" approach
which set swidth=sunit, but I feel like we get burned whenever
we try to second-guess broken hardware anyway.  Thoughts?

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 8f0bd89..4f05354 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -2196,6 +2196,37 @@ validate_rtextsize(
 	ASSERT(cfg->rtextblocks);
 }
 
+static bool
+validate_stripe_factors(
+	int			blocksize,
+	int			dsunit,
+	int			dswidth,
+	bool			devicevals)
+{
+	/* Can't have one without the other, and dswidth must be multiple */
+	if ((dsunit && !dswidth) || (!dsunit && dswidth) ||
+	    (dsunit && (dswidth % dsunit != 0))) {
+		if (devicevals)
+			fprintf(stderr, _("Validating device geometry:\n"));
+		fprintf(stderr,
+_("Data stripe width (%d) must be a multiple of the data stripe unit (%d)\n"),
+			BBTOB(dswidth), BBTOB(dsunit));
+		return false;
+	}
+
+	/* Check that the stripe config is a multiple of block size */
+	if ((BBTOB(dsunit) % blocksize) ||
+	    (BBTOB(dswidth) % blocksize)) {
+		if (devicevals)
+			fprintf(stderr, _("Validating device geometry:\n"));
+		fprintf(stderr,
+_("Stripe unit(%d) or stripe width(%d) is not a multiple of the block size(%d)\n"),
+			BBTOB(dsunit), BBTOB(dswidth), blocksize);
+		return false;
+	}
+	return true;
+}
+
 /*
  * Validate the configured stripe geometry, or is none is specified, pull
  * the configuration from the underlying device.
@@ -2215,7 +2246,6 @@ calc_stripe_factors(
 	int		dsu = 0;
 	int		dsw = 0;
 	int		lsu = 0;
-	bool		use_dev = false;
 
 	if (cli_opt_set(&dopts, D_SUNIT))
 		dsunit = cli->dsunit;
@@ -2259,13 +2289,9 @@ _("data stripe width (%lld) is too large of a multiple of the data stripe unit (
 		dswidth = big_dswidth;
 	}
 
-	if ((dsunit && !dswidth) || (!dsunit && dswidth) ||
-	    (dsunit && (dswidth % dsunit != 0))) {
-		fprintf(stderr,
-_("data stripe width (%d) must be a multiple of the data stripe unit (%d)\n"),
-			dswidth, dsunit);
+	/* Validate the user-supplied stripe geometry */
+	if (!validate_stripe_factors(cfg->blocksize, dsunit, dswidth, false))
 		usage();
-	}
 
 	/* If sunit & swidth were manually specified as 0, same as noalign */
 	if ((cli_opt_set(&dopts, D_SUNIT) || cli_opt_set(&dopts, D_SU)) &&
@@ -2279,22 +2305,16 @@ _("data stripe width (%d) must be a multiple of the data stripe unit (%d)\n"),
 		goto check_lsunit;
 	}
 
-	/* if no stripe config set, use the device default */
-	if (!dsunit) {
-		/* Watch out for nonsense from device */
-		if (ft->dsunit && ft->dswidth == 0) {
-			fprintf(stderr,
-_("%s: Volume reports stripe unit of %d bytes but stripe width of 0.\n"),
-				progname, ft->dsunit << 9);
-			fprintf(stderr,
-_("Using stripe width of %d bytes, which may not be optimal.\n"),
-				ft->dsunit << 9);
-			ft->dswidth = ft->dsunit;
-		}
-		dsunit = ft->dsunit;
-		dswidth = ft->dswidth;
-		use_dev = true;
-	} else {
+	/* Validate the device-reported stripe geometry */
+	if (!validate_stripe_factors(cfg->blocksize, ft->dsunit, ft->dswidth, true)) {
+		fprintf(stderr,
+_("Device-reported stripe geometry failed checks, ignoring\n"));
+		ft->dsunit = 0;
+		ft->dswidth = 0;
+	}
+
+	/* If user specified geometry, check against device values */
+	if (dsunit) {
 		/* check and warn if user-specified alignment is sub-optimal */
 		if (ft->dsunit && ft->dsunit != dsunit) {
 			fprintf(stderr,
@@ -2306,28 +2326,10 @@ _("%s: Specified data stripe unit %d is not the same as the volume stripe unit %
 _("%s: Specified data stripe width %d is not the same as the volume stripe width %d\n"),
 				progname, dswidth, ft->dswidth);
 		}
-	}
-
-	/*
-	 * now we have our stripe config, check it's a multiple of block
-	 * size.
-	 */
-	if ((BBTOB(dsunit) % cfg->blocksize) ||
-	    (BBTOB(dswidth) % cfg->blocksize)) {
-		/*
-		 * If we are using device defaults, just clear them and we're
-		 * good to go. Otherwise bail out with an error.
-		 */
-		if (!use_dev) {
-			fprintf(stderr,
-_("%s: Stripe unit(%d) or stripe width(%d) is not a multiple of the block size(%d)\n"),
-				progname, BBTOB(dsunit), BBTOB(dswidth),
-				cfg->blocksize);
-			exit(1);
-		}
-		dsunit = 0;
-		dswidth = 0;
-		cfg->sb_feat.nodalign = true;
+	} else {
+		/* Use the device-reported geometry */
+		dsunit = ft->dsunit;
+		dswidth = ft->dswidth;
 	}
 
 	/* convert from 512 byte blocks to fs blocksize */



      parent reply	other threads:[~2018-07-31  4:35 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-19 21:23 [PATCH] mkfs: avoid divide-by-zero when hardware reports optimal i/o size as 0 Jeff Mahoney
2018-07-20 15:55 ` Carlos Maiolino
2018-07-20 16:19   ` Darrick J. Wong
2018-07-23 12:21     ` Carlos Maiolino
2018-07-20 18:08   ` Jeff Mahoney
2018-07-31  2:10 ` Eric Sandeen
2018-07-31  2:14   ` Eric Sandeen
2018-07-31  2:57 ` Eric Sandeen [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b250d549-68aa-74da-0767-bc5c1d49a9f9@sandeen.net \
    --to=sandeen@sandeen.net \
    --cc=david@fromorbit.com \
    --cc=jeffm@suse.com \
    --cc=linux-xfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.