Skip site navigation (1)Skip section navigation (2)
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, &sectorsize);
-	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>