Module Name:    src
Committed By:   mlelstv
Date:           Sat Aug  9 10:33:46 UTC 2014

Modified Files:
        src/sbin/tunefs: tunefs.8 tunefs.c

Log Message:
add -S option to adjust the superblock for different sector sizes. While
the kernel ignores this information, userland tools rely on it.

This is needed when moving images between devices of different sector size.


To generate a diff of this commit:
cvs rdiff -u -r1.42 -r1.43 src/sbin/tunefs/tunefs.8
cvs rdiff -u -r1.47 -r1.48 src/sbin/tunefs/tunefs.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sbin/tunefs/tunefs.8
diff -u src/sbin/tunefs/tunefs.8:1.42 src/sbin/tunefs/tunefs.8:1.43
--- src/sbin/tunefs/tunefs.8:1.42	Mon Dec  3 12:28:06 2012
+++ src/sbin/tunefs/tunefs.8	Sat Aug  9 10:33:46 2014
@@ -1,4 +1,4 @@
-.\"	$NetBSD: tunefs.8,v 1.42 2012/12/03 12:28:06 wiz Exp $
+.\"	$NetBSD: tunefs.8,v 1.43 2014/08/09 10:33:46 mlelstv Exp $
 .\"
 .\" Copyright (c) 1983, 1991, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -45,6 +45,7 @@
 .Op Fl m Ar minfree
 .Op Fl o Ar optimize_preference
 .Op Fl q Ar quota
+.Op Fl S Ar sectorsize
 .Ar special | Ar filesys
 .Sh DESCRIPTION
 .Nm
@@ -152,6 +153,18 @@ can be used to enable/disable all types 
 After enabling a quota,
 .Xr fsck_ffs 8
 has to be run to compute the correct quota values.
+.Pp
+.It Fl S Ar sectorsize
+changes the fsbtodb value in the superblock to reflect a particular
+physical sector size. This value is ignored by the NetBSD kernel but
+needed by tools like
+.Xr fsck_ffs  8
+to access disk blocks correctly. The minimum value is DEV_BSIZE (512).
+.Pp
+Changing the fsbtodb value becomes necessary when a filesystem image
+is created for one sector size and then transferred to a device with
+a different sector size and should be applied also to the alternate
+superblocks.
 .El
 .Sh SEE ALSO
 .Xr wapbl 4 ,

Index: src/sbin/tunefs/tunefs.c
diff -u src/sbin/tunefs/tunefs.c:1.47 src/sbin/tunefs/tunefs.c:1.48
--- src/sbin/tunefs/tunefs.c:1.47	Sat Apr 26 13:23:49 2014
+++ src/sbin/tunefs/tunefs.c	Sat Aug  9 10:33:46 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: tunefs.c,v 1.47 2014/04/26 13:23:49 martin Exp $	*/
+/*	$NetBSD: tunefs.c,v 1.48 2014/08/09 10:33:46 mlelstv Exp $	*/
 
 /*
  * Copyright (c) 1983, 1993
@@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 19
 #if 0
 static char sccsid[] = "@(#)tunefs.c	8.3 (Berkeley) 5/3/95";
 #else
-__RCSID("$NetBSD: tunefs.c,v 1.47 2014/04/26 13:23:49 martin Exp $");
+__RCSID("$NetBSD: tunefs.c,v 1.48 2014/08/09 10:33:46 mlelstv Exp $");
 #endif
 #endif /* not lint */
 
@@ -102,18 +102,20 @@ main(int argc, char *argv[])
 	int		i, ch, Aflag, Fflag, Nflag, openflags;
 	const char	*special, *chg[2];
 	char		device[MAXPATHLEN];
-	int		maxbpg, minfree, optim;
+	int		maxbpg, minfree, optim, secsize;
 	int		avgfilesize, avgfpdir;
 	long long	logfilesize;
+	int		secshift, fsbtodb;
 
 	Aflag = Fflag = Nflag = 0;
-	maxbpg = minfree = optim = -1;
+	maxbpg = minfree = optim = secsize = -1;
 	avgfilesize = avgfpdir = -1;
 	logfilesize = -1;
+	secshift = 0;
 	chg[FS_OPTSPACE] = "space";
 	chg[FS_OPTTIME] = "time";
 
-	while ((ch = getopt(argc, argv, "AFNe:g:h:l:m:o:q:")) != -1) {
+	while ((ch = getopt(argc, argv, "AFNe:g:h:l:m:o:q:S:")) != -1) {
 		switch (ch) {
 
 		case 'A':
@@ -177,6 +179,13 @@ main(int argc, char *argv[])
 			else
 			    errx(11, "invalid quota type %s", optarg);
 			break;
+		case 'S':
+			secsize = strsuftoll("physical sector size",
+			    optarg, 0, INT_MAX);
+			secshift = ffs(secsize) - 1;
+			if (secsize != 0 && 1 << secshift != secsize)
+				errx(12, "sector size %d is not a power of two", secsize);
+			break;
 		default:
 			usage();
 		}
@@ -241,6 +250,30 @@ main(int argc, char *argv[])
 				warnx(OPTWARN, "space", "<", MINFREE);
 		}
 	}
+	if (secsize != -1) {
+		if (secsize == 0) {
+			secsize = sblock.fs_fsize / FFS_FSBTODB(&sblock, 1);
+			secshift = ffs(secsize) - 1;
+		}
+
+		if (secshift < DEV_BSHIFT)
+			warnx("sector size must be at least %d", DEV_BSIZE);
+		else if (secshift > sblock.fs_fshift)
+			warnx("sector size %d cannot be larger than fragment size %d",
+				secsize, sblock.fs_fsize);
+		else {
+			fsbtodb = sblock.fs_fshift - secshift;
+			if (fsbtodb == sblock.fs_fsbtodb) {
+				warnx("sector size remains unchanged as %d",
+					sblock.fs_fsize / FFS_FSBTODB(&sblock, 1));
+			} else {
+				warnx("sector size changed from %d to %d",
+					sblock.fs_fsize / FFS_FSBTODB(&sblock, 1),
+					secsize);
+				sblock.fs_fsbtodb = fsbtodb;
+			}
+		}
+	}
 	CHANGEVAL(sblock.fs_avgfilesize, avgfilesize,
 	    "average file size", "");
 	CHANGEVAL(sblock.fs_avgfpdir, avgfpdir,
@@ -328,7 +361,13 @@ main(int argc, char *argv[])
 	memcpy(&buf, (char *)&sblock, SBLOCKSIZE);
 	if (needswap)
 		ffs_sb_swap((struct fs*)&buf, (struct fs*)&buf);
+
+	/* write superblock to original coordinates (use old dev_bsize!) */
 	bwrite(sblockloc, buf.data, SBLOCKSIZE, special);
+
+	/* correct dev_bsize from possibly changed superblock data */
+	dev_bsize = sblock.fs_fsize / FFS_FSBTODB(&sblock, 1);
+
 	if (Aflag)
 		for (i = 0; i < sblock.fs_ncg; i++)
 			bwrite(FFS_FSBTODB(&sblock, cgsblock(&sblock, i)),
@@ -479,6 +518,7 @@ usage(void)
 	fprintf(stderr, "\t-m minimum percentage of free space\n");
 	fprintf(stderr, "\t-o optimization preference (`space' or `time')\n");
 	fprintf(stderr, "\t-q quota type (`[no]user' or `[no]group')\n");
+	fprintf(stderr, "\t-S sector size\n");
 	exit(2);
 }
 

Reply via email to