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.
This commit is contained in:
christos 2017-04-14 15:39:29 +00:00
parent d962cd4d88
commit 64f54f261d
1 changed files with 53 additions and 48 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: mkfs_msdos.c,v 1.12 2017/02/16 22:42:25 christos Exp $ */
/* $NetBSD: mkfs_msdos.c,v 1.13 2017/04/14 15:39:29 christos Exp $ */
/*
* Copyright (c) 1998 Robert Nordier
@ -37,7 +37,7 @@
static const char rcsid[] =
"$FreeBSD: src/sbin/newfs_msdos/newfs_msdos.c,v 1.15 2000/10/10 01:49:37 wollman Exp $";
#else
__RCSID("$NetBSD: mkfs_msdos.c,v 1.12 2017/02/16 22:42:25 christos Exp $");
__RCSID("$NetBSD: mkfs_msdos.c,v 1.13 2017/04/14 15:39:29 christos Exp $");
#endif
#endif /* not lint */
@ -235,7 +235,7 @@ static int got_siginfo = 0; /* received a SIGINFO */
static int check_mounted(const char *, mode_t);
#endif
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 int ckgeom(const char *, u_int, const char *);
static int oklabel(const char *);
@ -331,7 +331,7 @@ mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op)
if (!(o.floppy || (o.drive_heads && o.sectors_per_track &&
o.bytes_per_sector && o.size && o.hidden_sectors_set))) {
if (getbpbinfo(fd, fname, dtype, o.hidden_sectors_set, &bpb,
o.create_size != 0) == -1)
o.create_size) == -1)
return -1;
bpb.bsec -= (o.offset / bpb.bps);
if (bpb.spc == 0) { /* set defaults */
@ -817,7 +817,7 @@ getstdfmt(const char *fmt, struct bpb *bpb)
*/
static int
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;
int part;
@ -835,26 +835,31 @@ getbpbinfo(int fd, const char *fname, const char *dtype, int iflag,
#ifndef MAKEFS
int maxpartitions = getmaxpartitions();
struct disk_geom geo;
struct dkwedge_info dkw;
// XXX: Does not work with wedges
if (s2 && *s2 >= 'a' && *s2 <= 'a' + maxpartitions - 1) {
part = *s2++ - 'a';
}
#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) {
sector_size = geo.dg_secsize = 512;
nsectors = geo.dg_nsectors = 63;
ntracks = geo.dg_ntracks = 255;
if (!(((part != -1) && ((!iflag && part != -1) || !bpb->bsec)) ||
!bpb->bps || !bpb->spt || !bpb->hds)) {
return 0;
}
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;
} else
#endif
@ -865,39 +870,39 @@ getbpbinfo(int fd, const char *fname, const char *dtype, int iflag,
warnx("Can't get disk size for `%s'", fname);
return -1;
}
/* create a fake geometry for a file image */
sector_size = 512;
nsectors = 63;
ntracks = 255;
size = st.st_size / sector_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;
} else {
size = create_size / sector_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;
}