Add a new option to newfs(8), -r, to specify reserved space at the
end of the device.  It can be useful, e.g., when the device is to
become a member of a gmirror array later w/o losing the file system
on it.

Document the new option in the manpage.

While I'm here, improve error handling for -s option, which is
syntactically similar to -r; and document the fact that -s0 selects
the default fs size explicitly, which can be useful, e.g., in a
menu-based wrapper around newfs(8) requiring some value be entered
for the fs size.

Also fix a small typo in the help line for -s (missing space).

Idea and initial implementation by:	marck
Discussed on:				-fs
Critical review by:			bde
Tested with:				cmp(1)
This commit is contained in:
Yaroslav Tykhiy 2007-11-28 07:29:10 +00:00
parent 573c6b82df
commit 35956d32df
3 changed files with 59 additions and 22 deletions

View File

@ -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 @@ the default is to optimize for
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 @@ This large fragment size may lead to much wasted space
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 ,

View File

@ -120,7 +120,7 @@ int Eflag = 0; /* exit in middle of newfs for testing */
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 */
intmax_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 device[MAXPATHLEN];
static char *disktype;
static int unlabeled;
static void getfssize(intmax_t *, const char *p, intmax_t, intmax_t);
static struct disklabel *getdisklabel(char *s);
static void rewritelabel(char *s, struct disklabel *lp);
static void usage(void);
@ -153,11 +154,13 @@ main(int argc, char *argv[])
struct partition oldpartition;
struct stat st;
char *cp, *special;
intmax_t reserved;
int ch, i;
off_t mediasize;
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 +265,19 @@ main(int argc, char *argv[])
"%s: unknown optimization preference: use `space' or `time'",
optarg);
break;
case 'r':
errno = 0;
reserved = strtoimax(optarg, &cp, 0);
if (errno != 0 || cp == optarg ||
*cp != '\0' || 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 (errno != 0 || cp == optarg ||
*cp != '\0' || fssize < 0)
errx(1, "%s: bad file system size", optarg);
break;
case '?':
default:
@ -302,13 +313,8 @@ main(int argc, char *argv[])
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 +334,7 @@ main(int argc, char *argv[])
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 +387,22 @@ main(int argc, char *argv[])
exit(0);
}
void
getfssize(intmax_t *fsz, const char *s, intmax_t disksize, intmax_t reserved)
{
intmax_t available;
available = disksize - reserved;
if (available <= 0)
errx(1, "%s: reserved not less than device size %jd",
s, disksize);
if (*fsz == 0)
*fsz = available;
else if (*fsz > available)
errx(1, "%s: maximum file system size is %jd",
s, available);
}
struct disklabel *
getdisklabel(char *s)
{
@ -443,6 +461,7 @@ usage()
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);
}

View File

@ -52,7 +52,7 @@ extern int Eflag; /* exit as if error, for testing */
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 intmax_t fssize; /* file system size */
extern int sectorsize; /* bytes/sector */
extern int realsectorsize; /* bytes/sector in hardware*/
extern int fsize; /* fragment size */