sbin/newfs_msdos: sync with NetBSD-8

Allow 0 timestamp.
Grammar fixes.
Use the create_size if given to compute the real size instead of stat'ing
the file again, which might have been larger to start with.
Document history.

closes #274

Change-Id: Ibf881f22f351c7a17488b24a05c2110be1d65ae0
This commit is contained in:
Sevan Janiyan 2018-11-04 14:48:36 +00:00 committed by Lionel Sambuc
parent 609f541dd3
commit 25d017aa13
4 changed files with 138 additions and 75 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: mkfs_msdos.c,v 1.9 2014/01/05 12:52:39 martin Exp $ */ /* $NetBSD: mkfs_msdos.c,v 1.13 2017/04/14 15:39:29 christos Exp $ */
/* /*
* Copyright (c) 1998 Robert Nordier * Copyright (c) 1998 Robert Nordier
@ -37,7 +37,7 @@
static const char rcsid[] = static const char rcsid[] =
"$FreeBSD: src/sbin/newfs_msdos/newfs_msdos.c,v 1.15 2000/10/10 01:49:37 wollman Exp $"; "$FreeBSD: src/sbin/newfs_msdos/newfs_msdos.c,v 1.15 2000/10/10 01:49:37 wollman Exp $";
#else #else
__RCSID("$NetBSD: mkfs_msdos.c,v 1.9 2014/01/05 12:52:39 martin Exp $"); __RCSID("$NetBSD: mkfs_msdos.c,v 1.13 2017/04/14 15:39:29 christos Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
@ -235,7 +235,7 @@ static int got_siginfo = 0; /* received a SIGINFO */
static int check_mounted(const char *, mode_t); static int check_mounted(const char *, mode_t);
#endif #endif
static int getstdfmt(const char *, struct bpb *); static int getstdfmt(const char *, struct bpb *);
static int getbpbinfo(int, const char *, const char *, int, struct bpb *, int); static int getbpbinfo(int, const char *, const char *, int, struct bpb *, off_t);
static void print_bpb(struct bpb *); static void print_bpb(struct bpb *);
static int ckgeom(const char *, u_int, const char *); static int ckgeom(const char *, u_int, const char *);
static int oklabel(const char *); static int oklabel(const char *);
@ -331,20 +331,30 @@ mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op)
if (!(o.floppy || (o.drive_heads && o.sectors_per_track && if (!(o.floppy || (o.drive_heads && o.sectors_per_track &&
o.bytes_per_sector && o.size && o.hidden_sectors_set))) { o.bytes_per_sector && o.size && o.hidden_sectors_set))) {
if (getbpbinfo(fd, fname, dtype, o.hidden_sectors_set, &bpb, if (getbpbinfo(fd, fname, dtype, o.hidden_sectors_set, &bpb,
o.create_size != 0) == -1) o.create_size) == -1)
return -1; return -1;
bpb.bsec -= (o.offset / bpb.bps); bpb.bsec -= (o.offset / bpb.bps);
if (bpb.spc == 0) { /* set defaults */ if (bpb.spc == 0) { /* set defaults */
if (bpb.bsec <= 6000) /* about 3MB -> 512 bytes */ /* minimum cluster size */
bpb.spc = 1; switch (o.fat_type) {
else if (bpb.bsec <= (1<<17)) /* 64M -> 4k */ case 12:
bpb.spc = 8; bpb.spc = 1; /* use 512 bytes */
else if (bpb.bsec <= (1<<19)) /* 256M -> 8k */ x = 2; /* up to 2MB */
bpb.spc = 16; break;
else if (bpb.bsec <= (1<<21)) /* 1G -> 16k */ case 16:
bpb.spc = 32; bpb.spc = 1; /* use 512 bytes */
else x = 32; /* up to 32MB */
bpb.spc = 64; /* otherwise 32k */ break;
default:
bpb.spc = 8; /* use 4k */
x = 8192; /* up to 8GB */
break;
}
x1 = howmany(bpb.bsec, (1048576 / 512)); /* -> MB */
while (bpb.spc < 128 && x < x1) {
x *= 2;
bpb.spc *= 2;
}
} }
} }
@ -611,9 +621,15 @@ mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op)
printf("MBR type: %d\n", ch); printf("MBR type: %d\n", ch);
print_bpb(&bpb); print_bpb(&bpb);
if (!o.no_create) { if (!o.no_create) {
gettimeofday(&tv, NULL); if (o.timestamp_set) {
now = tv.tv_sec; tv.tv_sec = now = o.timestamp;
tm = localtime(&now); tv.tv_usec = 0;
tm = gmtime(&now);
} else {
gettimeofday(&tv, NULL);
now = tv.tv_sec;
tm = localtime(&now);
}
if (!(img = malloc(bpb.bps))) if (!(img = malloc(bpb.bps)))
err(1, NULL); err(1, NULL);
dir = bpb.res + (bpb.spf ? bpb.spf : bpb.bspf) * bpb.nft; dir = bpb.res + (bpb.spf ? bpb.spf : bpb.bspf) * bpb.nft;
@ -801,7 +817,7 @@ getstdfmt(const char *fmt, struct bpb *bpb)
*/ */
static int static int
getbpbinfo(int fd, const char *fname, const char *dtype, int iflag, getbpbinfo(int fd, const char *fname, const char *dtype, int iflag,
struct bpb *bpb, int create) struct bpb *bpb, off_t create_size)
{ {
const char *s1, *s2; const char *s1, *s2;
int part; int part;
@ -819,26 +835,31 @@ getbpbinfo(int fd, const char *fname, const char *dtype, int iflag,
#ifndef MAKEFS #ifndef MAKEFS
int maxpartitions = getmaxpartitions(); int maxpartitions = getmaxpartitions();
struct disk_geom geo;
struct dkwedge_info dkw;
// XXX: Does not work with wedges // XXX: Does not work with wedges
if (s2 && *s2 >= 'a' && *s2 <= 'a' + maxpartitions - 1) { if (s2 && *s2 >= 'a' && *s2 <= 'a' + maxpartitions - 1) {
part = *s2++ - 'a'; part = *s2++ - 'a';
} }
#endif #endif
if (((part != -1) && ((!iflag && part != -1) || !bpb->bsec)) ||
!bpb->bps || !bpb->spt || !bpb->hds) {
u_int sector_size;
u_int nsectors;
u_int ntracks;
u_int size;
#ifndef MAKEFS
struct disk_geom geo;
struct dkwedge_info dkw;
if (!create && getdiskinfo(fname, fd, NULL, &geo, &dkw) != -1) { if (!(((part != -1) && ((!iflag && part != -1) || !bpb->bsec)) ||
sector_size = geo.dg_secsize = 512; !bpb->bps || !bpb->spt || !bpb->hds)) {
nsectors = geo.dg_nsectors = 63; return 0;
ntracks = geo.dg_ntracks = 255; }
u_int sector_size = 512;
u_int nsectors = 63;
u_int ntracks = 255;
u_int size;
if (create_size == 0) {
#ifndef MAKEFS
if (getdiskinfo(fname, fd, NULL, &geo, &dkw) != -1) {
sector_size = geo.dg_secsize;
nsectors = geo.dg_nsectors;
ntracks = geo.dg_ntracks;
size = dkw.dkw_size; size = dkw.dkw_size;
} else } else
#endif #endif
@ -849,39 +870,39 @@ getbpbinfo(int fd, const char *fname, const char *dtype, int iflag,
warnx("Can't get disk size for `%s'", fname); warnx("Can't get disk size for `%s'", fname);
return -1; return -1;
} }
/* create a fake geometry for a file image */
sector_size = 512;
nsectors = 63;
ntracks = 255;
size = st.st_size / sector_size; size = st.st_size / sector_size;
} }
if (!bpb->bps) { } else {
if (ckgeom(fname, sector_size, "bytes/sector") == -1) size = create_size / sector_size;
return -1;
bpb->bps = sector_size;
}
if (nsectors > 63) {
/*
* The kernel doesn't accept BPB with spt > 63.
* (see sys/fs/msdosfs/msdosfs_vfsops.c:msdosfs_mountfs())
* If values taken from disklabel don't match these
* restrictions, use popular BIOS default values instead.
*/
nsectors = 63;
}
if (!bpb->spt) {
if (ckgeom(fname, nsectors, "sectors/track") == -1)
return -1;
bpb->spt = nsectors;
}
if (!bpb->hds)
if (ckgeom(fname, ntracks, "drive heads") == -1)
return -1;
bpb->hds = ntracks;
if (!bpb->bsec)
bpb->bsec = size;
} }
if (!bpb->bps) {
if (ckgeom(fname, sector_size, "bytes/sector") == -1)
return -1;
bpb->bps = sector_size;
}
if (nsectors > 63) {
/*
* The kernel doesn't accept BPB with spt > 63.
* (see sys/fs/msdosfs/msdosfs_vfsops.c:msdosfs_mountfs())
* If values taken from disklabel don't match these
* restrictions, use popular BIOS default values instead.
*/
nsectors = 63;
}
if (!bpb->spt) {
if (ckgeom(fname, nsectors, "sectors/track") == -1)
return -1;
bpb->spt = nsectors;
}
if (!bpb->hds)
if (ckgeom(fname, ntracks, "drive heads") == -1)
return -1;
bpb->hds = ntracks;
if (!bpb->bsec)
bpb->bsec = size;
return 0; return 0;
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: mkfs_msdos.h,v 1.2 2013/01/23 15:29:15 christos Exp $ */ /* $NetBSD: mkfs_msdos.h,v 1.6 2017/02/17 09:29:35 wiz Exp $ */
/*- /*-
* Copyright (c) 2013 The NetBSD Foundation, Inc. * Copyright (c) 2013 The NetBSD Foundation, Inc.
@ -15,9 +15,6 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@ -41,7 +38,7 @@ AOPT('C', off_t, create_size, 0, "Create file") \
AOPT('F', uint8_t, fat_type, 12, "FAT type (12, 16, or 32)") \ AOPT('F', uint8_t, fat_type, 12, "FAT type (12, 16, or 32)") \
AOPT('I', uint32_t, volume_id, 0, "Volume ID") \ AOPT('I', uint32_t, volume_id, 0, "Volume ID") \
AOPT('L', char *, volume_label, -1, "Volume Label") \ AOPT('L', char *, volume_label, -1, "Volume Label") \
AOPT('N', bool, no_create, -2, "Don't create filesystem, print params only") \ AOPT('N', bool, no_create, -2, "Don't create file system, print params only") \
AOPT('O', char *, OEM_string, -1, "OEM string") \ AOPT('O', char *, OEM_string, -1, "OEM string") \
AOPT('S', uint16_t, bytes_per_sector, 1, "Bytes per sector") \ AOPT('S', uint16_t, bytes_per_sector, 1, "Bytes per sector") \
AOPT('a', uint32_t, sectors_per_fat, 1, "Sectors per FAT") \ AOPT('a', uint32_t, sectors_per_fat, 1, "Sectors per FAT") \
@ -63,6 +60,8 @@ struct msdos_options {
#define AOPT(_opt, _type, _name, _min, _desc) _type _name; #define AOPT(_opt, _type, _name, _min, _desc) _type _name;
ALLOPTS ALLOPTS
#undef AOPT #undef AOPT
time_t timestamp;
uint32_t timestamp_set:1;
uint32_t volume_id_set:1; uint32_t volume_id_set:1;
uint32_t media_descriptor_set:1; uint32_t media_descriptor_set:1;
uint32_t hidden_sectors_set:1; uint32_t hidden_sectors_set:1;

View File

@ -1,4 +1,4 @@
.\" $NetBSD: newfs_msdos.8,v 1.20 2014/04/24 23:49:40 christos Exp $ .\" $NetBSD: newfs_msdos.8,v 1.23 2017/02/17 09:29:35 wiz Exp $
.\" .\"
.\" Copyright (c) 1998 Robert Nordier .\" Copyright (c) 1998 Robert Nordier
.\" All rights reserved. .\" All rights reserved.
@ -27,7 +27,7 @@
.\" .\"
.\" From: $FreeBSD: src/sbin/newfs_msdos/newfs_msdos.8,v 1.13 2001/08/14 10:01:48 ru Exp $ .\" From: $FreeBSD: src/sbin/newfs_msdos/newfs_msdos.8,v 1.13 2001/08/14 10:01:48 ru Exp $
.\" .\"
.Dd April 24, 2014 .Dd February 16, 2017
.Dt NEWFS_MSDOS 8 .Dt NEWFS_MSDOS 8
.Os .Os
.Sh NAME .Sh NAME
@ -57,6 +57,7 @@
.Op Fl o Ar hidden .Op Fl o Ar hidden
.Op Fl r Ar reserved .Op Fl r Ar reserved
.Op Fl s Ar total .Op Fl s Ar total
.Op Fl T Ar timestamp
.Op Fl u Ar track-size .Op Fl u Ar track-size
.Ar special .Ar special
.Op Ar disktype .Op Ar disktype
@ -74,9 +75,9 @@ to determine geometry, if required.
The options are as follow: The options are as follow:
.Bl -tag -width indent .Bl -tag -width indent
.It Fl N .It Fl N
Don't create a file system: just print out parameters. Do not create a file system: just print out parameters.
.It Fl @ Ar offset .It Fl @ Ar offset
Build the filesystem at the specified offset in bytes in the device or file. Build the file system at the specified offset in bytes in the device or file.
A suffix s, k, m, g (lower or upper case) A suffix s, k, m, g (lower or upper case)
appended to the offset specifies that the appended to the offset specifies that the
number is in sectors, kilobytes, megabytes or gigabytes, respectively. number is in sectors, kilobytes, megabytes or gigabytes, respectively.
@ -120,7 +121,7 @@ Sectors per cluster.
Acceptable values are powers of 2 in the range 1 through 128. Acceptable values are powers of 2 in the range 1 through 128.
If the block or cluster size are not specified, the code If the block or cluster size are not specified, the code
uses a cluster between 512 bytes and 32K depending on uses a cluster between 512 bytes and 32K depending on
the filesystem size. the file system size.
.It Fl e Ar dirents .It Fl e Ar dirents
Number of root directory entries (FAT12 and FAT16 only). Number of root directory entries (FAT12 and FAT16 only).
.It Fl f Ar format .It Fl f Ar format
@ -147,6 +148,13 @@ Number of hidden sectors.
Number of reserved sectors. Number of reserved sectors.
.It Fl s Ar total .It Fl s Ar total
File system size. File system size.
.It Fl T At timestamp
Specify a timestamp to be used for file system creation so that
it can be consistent for reproducible builds.
The timestamp can be a pathname, where the timestamps are derived from
that file, a parseable date for parsedate(3) (this option is not
yet available in the tools build), or an integer value interpreted
as the number of seconds from the Epoch.
.It Fl u Ar track-size .It Fl u Ar track-size
Number of sectors per track. Number of sectors per track.
.El .El
@ -174,7 +182,7 @@ option.
When the geometry is not available, it is assumed to be When the geometry is not available, it is assumed to be
63 sectors, 255 heads. 63 sectors, 255 heads.
The size is then rounded to become The size is then rounded to become
a multiple of the track size and avoid complaints by some filesystem code. a multiple of the track size and avoid complaints by some file system code.
.Pp .Pp
FAT file system parameters occupy a "Boot Sector BPB (BIOS Parameter FAT file system parameters occupy a "Boot Sector BPB (BIOS Parameter
Block)" in the first of the "reserved" sectors which precede the actual Block)" in the first of the "reserved" sectors which precede the actual
@ -233,6 +241,10 @@ Exit status is 0 on success and 1 on error.
.Xr fdisk 8 , .Xr fdisk 8 ,
.Xr newfs 8 .Xr newfs 8
.Sh HISTORY .Sh HISTORY
A
.Nm
utility appeared in
.Fx 3.0 .
The The
.Nm .Nm
command first appeared in command first appeared in

View File

@ -1,4 +1,4 @@
/* $NetBSD: newfs_msdos.c,v 1.43 2015/04/23 13:27:14 abs Exp $ */ /* $NetBSD: newfs_msdos.c,v 1.45 2017/02/16 22:42:25 christos Exp $ */
/* /*
* Copyright (c) 1998 Robert Nordier * Copyright (c) 1998 Robert Nordier
@ -33,11 +33,12 @@
static const char rcsid[] = static const char rcsid[] =
"$FreeBSD: src/sbin/newfs_msdos/newfs_msdos.c,v 1.15 2000/10/10 01:49:37 wollman Exp $"; "$FreeBSD: src/sbin/newfs_msdos/newfs_msdos.c,v 1.15 2000/10/10 01:49:37 wollman Exp $";
#else #else
__RCSID("$NetBSD: newfs_msdos.c,v 1.43 2015/04/23 13:27:14 abs Exp $"); __RCSID("$NetBSD: newfs_msdos.c,v 1.45 2017/02/16 22:42:25 christos Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/stat.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <err.h> #include <err.h>
@ -45,6 +46,7 @@ __RCSID("$NetBSD: newfs_msdos.c,v 1.43 2015/04/23 13:27:14 abs Exp $");
#include <unistd.h> #include <unistd.h>
#include <paths.h> #include <paths.h>
#include <errno.h> #include <errno.h>
#include <util.h>
#include "mkfs_msdos.h" #include "mkfs_msdos.h"
@ -57,13 +59,38 @@ __dead static void usage(void);
static u_int argtou(const char *, u_int, u_int, const char *); static u_int argtou(const char *, u_int, u_int, const char *);
static off_t argtooff(const char *, const char *); static off_t argtooff(const char *, const char *);
static time_t
get_tstamp(const char *b)
{
struct stat st;
char *eb;
long long l;
#ifndef HAVE_NBTOOL_CONFIG_H
time_t when;
#endif
if (stat(b, &st) != -1)
return (time_t)st.st_mtime;
#ifndef HAVE_NBTOOL_CONFIG_H
errno = 0;
if ((when = parsedate(b, NULL, NULL)) != -1 || errno == 0)
return when;
#endif
errno = 0;
l = strtoll(b, &eb, 0);
if (b == eb || *eb || errno)
errx(EXIT_FAILURE, "Can't parse timestamp `%s'", b);
return (time_t)l;
}
/* /*
* Construct a FAT12, FAT16, or FAT32 file system. * Construct a FAT12, FAT16, or FAT32 file system.
*/ */
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
static const char opts[] = "@:NB:C:F:I:L:O:S:a:b:c:e:f:h:i:k:m:n:o:r:s:u:"; static const char opts[] = "@:NB:C:F:I:L:O:S:a:b:c:e:f:h:i:k:m:n:o:r:s:T:u:";
struct msdos_options o; struct msdos_options o;
char *fname, *dtype; char *fname, *dtype;
char buf[MAXPATHLEN]; char buf[MAXPATHLEN];
@ -142,6 +169,10 @@ main(int argc, char *argv[])
case 's': case 's':
o.size = argto4(optarg, 1, "file system size"); o.size = argto4(optarg, 1, "file system size");
break; break;
case 'T':
o.timestamp_set = 1;
o.timestamp = get_tstamp(optarg);
break;
case 'u': case 'u':
o.sectors_per_track = argto2(optarg, 1, "sectors/track"); o.sectors_per_track = argto2(optarg, 1, "sectors/track");
break; break;