Date: Sat, 1 Sep 2007 11:48:03 +0400 From: Yar Tikhiy <yar@comp.chem.msu.su> To: fs@freebsd.org Subject: New option for newfs(3) to make life with GEOM easier Message-ID: <20070901074803.GM85633@comp.chem.msu.su>
next in thread | raw e-mail | index | archive | help
Hi all, With some geom(4) modules saving their metadata in the last sectors of block devices such as disks and partitions, it can be convenient to reserve space at the end of the device when creating a new file system in it. Now newfs(8) allows for specification of file system size, which can be used for the purpose, but additional calculations by hand are needed. OTOH, with the below patch, newfs(8) will grow a new option to specify the reserved space size directly and in a error-free way. The idea and implementation are by Dmitry Morozovsky and yours truly. Any comments or objections? Thanks! -- Yar --- //depot/vendor/freebsd/src/sbin/newfs/mkfs.c 2006/10/31 22:39:49 +++ //depot/user/yar/hack/sbin/newfs/mkfs.c 2007/08/31 09:06:24 @@ -107,7 +107,7 @@ int fragsperinode, optimalfpg, origdensity, minfpg, lastminfpg; long i, j, cylno, csfrags; time_t utime; - quad_t sizepb; + off_t sizepb; int width; char tmpbuf[100]; /* XXX this will break in about 2,500 years */ union { --- //depot/vendor/freebsd/src/sbin/newfs/newfs.8 2006/10/31 22:39:49 +++ //depot/user/yar/hack/sbin/newfs/newfs.8 2007/08/31 11:55:35 @@ -52,6 +52,7 @@ .Op Fl i Ar bytes .Op Fl m Ar free-space .Op Fl o Ar optimization +.Op Fl r Ar reserved .Op Fl s Ar size .Ar special .Sh DESCRIPTION @@ -196,14 +197,30 @@ See .Xr tunefs 8 for more details on how to set this option. +.It Fl r Ar reserved +The size, in sectors, of reserved space +at the end of the partition specified in +.Ar special . +This space will not be occupied by the file system; +it can be used by other consumers such as +.Xr geom 4 . +Defaults to 0. .It Fl s Ar size The size of the file system in sectors. This value defaults to the size of the raw partition specified in .Ar special -(in other words, -.Nm -will use the entire partition for the file system). +less the +.Ar reserved +space at its end (see +.Fl r ) . +A +.Ar size +of 0 can also be used to choose the default value. +A valid +.Ar size +value cannot be larger than the default one, +which means that the file system cannot extend into the reserved space. .El .Pp The following options override the standard sizes for the disk geometry. @@ -237,6 +254,7 @@ on file systems that contain many small files. .Sh SEE ALSO .Xr fdformat 1 , +.Xr geom 4 , .Xr disktab 5 , .Xr fs 5 , .Xr bsdlabel 8 , --- //depot/vendor/freebsd/src/sbin/newfs/newfs.c 2007/03/03 00:43:12 +++ //depot/user/yar/hack/sbin/newfs/newfs.c 2007/08/31 11:55:35 @@ -120,7 +120,7 @@ int Jflag; /* enable gjournal for file system */ int lflag; /* enable multilabel for file system */ int nflag; /* do not create .snap directory */ -quad_t fssize; /* file system size */ +off_t fssize; /* file system size */ int sectorsize; /* bytes/sector */ int realsectorsize; /* bytes/sector in hardware */ int fsize = 0; /* fragment size */ @@ -141,6 +141,7 @@ static char *disktype; static int unlabeled; +static void getfssize(off_t *, const char *p, off_t, off_t); static struct disklabel *getdisklabel(char *s); static void rewritelabel(char *s, struct disklabel *lp); static void usage(void); @@ -154,10 +155,11 @@ struct stat st; char *cp, *special; int ch, i; - off_t mediasize; + off_t mediasize, reserved; + reserved = 0; while ((ch = getopt(argc, argv, - "EJL:NO:RS:T:Ua:b:c:d:e:f:g:h:i:lm:no:s:")) != -1) + "EJL:NO:RS:T:Ua:b:c:d:e:f:g:h:i:lm:no:r:s:")) != -1) switch (ch) { case 'E': Eflag++; @@ -262,11 +264,15 @@ "%s: unknown optimization preference: use `space' or `time'", optarg); break; + case 'r': + reserved = strtoimax(optarg, &cp, 0); + if (*cp || reserved < 0) + errx(1, "%s: bad reserved size", optarg); + break; case 's': - errno = 0; - fssize = strtoimax(optarg, NULL, 0); - if (errno != 0) - err(1, "%s: bad file system size", optarg); + fssize = strtoimax(optarg, &cp, 0); + if (*cp || fssize < 0) + errx(1, "%s: bad file system size", optarg); break; case '?': default: @@ -302,13 +308,8 @@ if (sectorsize == 0) ioctl(disk.d_fd, DIOCGSECTORSIZE, §orsize); - if (sectorsize && !ioctl(disk.d_fd, DIOCGMEDIASIZE, &mediasize)) { - if (fssize == 0) - fssize = mediasize / sectorsize; - else if (fssize > mediasize / sectorsize) - errx(1, "%s: maximum file system size is %jd", - special, (intmax_t)(mediasize / sectorsize)); - } + if (sectorsize && !ioctl(disk.d_fd, DIOCGMEDIASIZE, &mediasize)) + getfssize(&fssize, special, mediasize / sectorsize, reserved); pp = NULL; lp = getdisklabel(special); if (lp != NULL) { @@ -328,11 +329,7 @@ if (pp->p_fstype == FS_BOOT) errx(1, "%s: `%c' partition overlaps boot program", special, *cp); - if (fssize == 0) - fssize = pp->p_size; - if (fssize > pp->p_size) - errx(1, - "%s: maximum file system size %d", special, pp->p_size); + getfssize(&fssize, special, pp->p_size, reserved); if (sectorsize == 0) sectorsize = lp->d_secsize; if (fsize == 0) @@ -385,6 +382,23 @@ exit(0); } +void +getfssize(off_t *fsz, const char *s, off_t disksize, off_t reserved) +{ + off_t available; + + available = disksize - reserved; + if (available <= 0) + errx(1, "%s: reserved size must be less " + "than partition size %jd", + s, (intmax_t)disksize); + if (*fsz == 0) + *fsz = available; + else if (*fsz > available) + errx(1, "%s: maximum file system size is %jd", + s, (intmax_t)available); +} + struct disklabel * getdisklabel(char *s) { @@ -443,6 +457,7 @@ fprintf(stderr, "\t-n do not create .snap directory\n"); fprintf(stderr, "\t-m minimum free space %%\n"); fprintf(stderr, "\t-o optimization preference (`space' or `time')\n"); - fprintf(stderr, "\t-s file systemsize (sectors)\n"); + fprintf(stderr, "\t-r reserved sectors at the end of device\n"); + fprintf(stderr, "\t-s file system size (sectors)\n"); exit(1); } --- //depot/vendor/freebsd/src/sbin/newfs/newfs.h 2006/10/31 22:39:49 +++ //depot/user/yar/hack/sbin/newfs/newfs.h 2007/08/31 09:06:24 @@ -52,7 +52,7 @@ extern int Jflag; /* enable gjournal for file system */ extern int lflag; /* enable multilabel MAC for file system */ extern int nflag; /* do not create .snap directory */ -extern quad_t fssize; /* file system size */ +extern off_t fssize; /* file system size */ extern int sectorsize; /* bytes/sector */ extern int realsectorsize; /* bytes/sector in hardware*/ extern int fsize; /* fragment size */ ----- End -----
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070901074803.GM85633>