svn commit: r363313 - stable/12/sbin/newfs_msdos

Xin LI delphij at FreeBSD.org
Sat Jul 18 23:05:17 UTC 2020


Author: delphij
Date: Sat Jul 18 23:05:16 2020
New Revision: 363313
URL: https://svnweb.freebsd.org/changeset/base/363313

Log:
  MFC r362936: Gather writes to larger chunks (MAXPHYS) instead of issuing
  them in sectors.

Modified:
  stable/12/sbin/newfs_msdos/mkfs_msdos.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sbin/newfs_msdos/mkfs_msdos.c
==============================================================================
--- stable/12/sbin/newfs_msdos/mkfs_msdos.c	Sat Jul 18 20:17:40 2020	(r363312)
+++ stable/12/sbin/newfs_msdos/mkfs_msdos.c	Sat Jul 18 23:05:16 2020	(r363313)
@@ -59,6 +59,7 @@ static const char rcsid[] =
 
 #define	DOSMAGIC  0xaa55	/* DOS magic number */
 #define	MINBPS	  512		/* minimum bytes per sector */
+#define	MAXBPS    4096		/* maximum bytes per sector */
 #define	MAXSPC	  128		/* maximum sectors per cluster */
 #define	MAXNFT	  16		/* maximum number of FATs */
 #define	DEFBLK	  4096		/* default block size */
@@ -72,6 +73,25 @@ static const char rcsid[] =
 #define	MAXCLS16  0xfff4U	/* maximum FAT16 clusters */
 #define	MAXCLS32  0xffffff4U	/* maximum FAT32 clusters */
 
+#ifndef	CTASSERT
+#define	CTASSERT(x)		_CTASSERT(x, __LINE__)
+#define	_CTASSERT(x, y)		__CTASSERT(x, y)
+#define	__CTASSERT(x, y)	typedef char __assert_ ## y [(x) ? 1 : -1]
+#endif
+
+/*
+ * For better performance, we want to write larger chunks instead of
+ * individual sectors (the size can only be 512, 1024, 2048 or 4096
+ * bytes). Assert that MAXPHYS can always hold an integer number of
+ * sectors by asserting that both are power of two numbers and the
+ * MAXPHYS is greater than MAXBPS.
+ */
+CTASSERT(powerof2(MAXPHYS));
+CTASSERT(powerof2(MAXBPS));
+CTASSERT(MAXPHYS > MAXBPS);
+
+const static ssize_t chunksize = MAXPHYS;
+
 #define	mincls(fat)  ((fat) == 12 ? MINCLS12 :	\
 		      (fat) == 16 ? MINCLS16 :	\
 				    MINCLS32)
@@ -238,6 +258,7 @@ mkfs_msdos(const char *fname, const char *dtype, const
     struct bsx *bsx;
     struct de *de;
     u_int8_t *img;
+    u_int8_t *physbuf, *physbuf_end;
     const char *bname;
     ssize_t n;
     time_t now;
@@ -247,7 +268,7 @@ mkfs_msdos(const char *fname, const char *dtype, const
     int fd, fd1, rv;
     struct msdos_options o = *op;
 
-    img = NULL;
+    physbuf = NULL;
     rv = -1;
     fd = fd1 = -1;
 
@@ -332,15 +353,13 @@ mkfs_msdos(const char *fname, const char *dtype, const
 		bpb.bpbSecPerClust = 64;		/* otherwise 32k */
 	}
     }
-    if (!powerof2(bpb.bpbBytesPerSec)) {
-	warnx("bytes/sector (%u) is not a power of 2", bpb.bpbBytesPerSec);
+    if (bpb.bpbBytesPerSec < MINBPS ||
+        bpb.bpbBytesPerSec > MAXBPS ||
+	!powerof2(bpb.bpbBytesPerSec)) {
+	warnx("Invalid bytes/sector (%u): must be 512, 1024, 2048 or 4096",
+	    bpb.bpbBytesPerSec);
 	goto done;
     }
-    if (bpb.bpbBytesPerSec < MINBPS) {
-	warnx("bytes/sector (%u) is too small; minimum is %u",
-	     bpb.bpbBytesPerSec, MINBPS);
-	goto done;
-    }
 
     if (o.volume_label && !oklabel(o.volume_label)) {
 	warnx("%s: bad volume label", o.volume_label);
@@ -610,11 +629,14 @@ mkfs_msdos(const char *fname, const char *dtype, const
 	    tm = localtime(&now);
 	}
 
-
-	if (!(img = malloc(bpb.bpbBytesPerSec))) {
+	physbuf = malloc(chunksize);
+	if (physbuf == NULL) {
 	    warn(NULL);
 	    goto done;
 	}
+	physbuf_end = physbuf + chunksize;
+	img = physbuf;
+
 	dir = bpb.bpbResSectors + (bpb.bpbFATsecs ? bpb.bpbFATsecs :
 				   bpb.bpbBigFATsecs) * bpb.bpbFATs;
 	memset(&si_sa, 0, sizeof(si_sa));
@@ -737,19 +759,37 @@ mkfs_msdos(const char *fname, const char *dtype, const
 		    (u_int)tm->tm_mday;
 		mk2(de->deMDate, x);
 	    }
-	    if ((n = write(fd, img, bpb.bpbBytesPerSec)) == -1) {
-		warn("%s", fname);
-		goto done;
+	    /*
+	     * Issue a write of chunksize once we have collected
+	     * enough sectors.
+	     */
+	    img += bpb.bpbBytesPerSec;
+	    if (img >= physbuf_end) {
+		n = write(fd, physbuf, chunksize);
+		if (n != chunksize) {
+		    warnx("%s: can't write sector %u", fname, lsn);
+		    goto done;
+		}
+		img = physbuf;
 	    }
-	    if ((unsigned)n != bpb.bpbBytesPerSec) {
-		warnx("%s: can't write sector %u", fname, lsn);
-		goto done;
-	    }
 	}
+	/*
+	 * Write remaining sectors, if the last write didn't end
+	 * up filling a whole chunk.
+	 */
+	if (img != physbuf) {
+		ssize_t tailsize = img - physbuf;
+
+		n = write(fd, physbuf, tailsize);
+		if (n != tailsize) {
+		    warnx("%s: can't write sector %u", fname, lsn);
+		    goto done;
+		}
+	}
     }
     rv = 0;
 done:
-    free(img);
+    free(physbuf);
     if (fd != -1)
 	    close(fd);
     if (fd1 != -1)


More information about the svn-src-all mailing list