summaryrefslogtreecommitdiffstats
path: root/sbin/newfs
diff options
context:
space:
mode:
authoryar <yar@FreeBSD.org>2007-11-28 07:29:10 +0000
committeryar <yar@FreeBSD.org>2007-11-28 07:29:10 +0000
commit13b1c70facfd50df5e26ab1d2cb15ec557a2c480 (patch)
tree87013b76681a13ea5066cc3256a664fd1b2e4efe /sbin/newfs
parent2562874cb6c7148dd0a0e252035eeb28cc19eb23 (diff)
downloadFreeBSD-src-13b1c70facfd50df5e26ab1d2cb15ec557a2c480.zip
FreeBSD-src-13b1c70facfd50df5e26ab1d2cb15ec557a2c480.tar.gz
MFp4:
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)
Diffstat (limited to 'sbin/newfs')
-rw-r--r--sbin/newfs/newfs.824
-rw-r--r--sbin/newfs/newfs.c55
-rw-r--r--sbin/newfs/newfs.h2
3 files changed, 59 insertions, 22 deletions
diff --git a/sbin/newfs/newfs.8 b/sbin/newfs/newfs.8
index 8be6d35..875f915 100644
--- a/sbin/newfs/newfs.8
+++ b/sbin/newfs/newfs.8
@@ -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 ,
diff --git a/sbin/newfs/newfs.c b/sbin/newfs/newfs.c
index 41823cb..532e066 100644
--- a/sbin/newfs/newfs.c
+++ b/sbin/newfs/newfs.c
@@ -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);
}
diff --git a/sbin/newfs/newfs.h b/sbin/newfs/newfs.h
index 55f920f..19e383a 100644
--- a/sbin/newfs/newfs.h
+++ b/sbin/newfs/newfs.h
@@ -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 */
OpenPOWER on IntegriCloud