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.
This commit is contained in:
mlelstv 2014-08-09 10:33:46 +00:00
parent c07b99a1a9
commit 2d1e5095e8
2 changed files with 59 additions and 6 deletions

View File

@ -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 at once.
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 ,

View File

@ -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, 1993\
#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);
}