- Deal with wedges and the new disk geometry structures, instead of using

struct disklabel.

Functionality lost:
  1. struct disklabel used to be updated to contain bsize, fsize, cpg.
     This information was used to locate the alternative superblock in
     the filesystem if the primary superblock was corrupted. We need
     to find a new place to store this information if we need this
     functionality.
  2. On vax SMD drives that contained bad sector lists, the newfs program
     knew how to get the offset and skip to the correct location in order
     to place the label.
This commit is contained in:
christos 2006-08-26 22:03:47 +00:00
parent 09e8908e10
commit 5a70d8a008
6 changed files with 91 additions and 241 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.32 2006/08/17 22:21:27 christos Exp $
# $NetBSD: Makefile,v 1.33 2006/08/26 22:03:47 christos Exp $
# @(#)Makefile 8.2 (Berkeley) 4/27/95
.include <bsd.own.mk>
@ -7,7 +7,7 @@ PROG= fsck_ffs
MAN= fsck_ffs.8
SRCS= dir.c inode.c main.c pass1.c pass1b.c pass2.c pass3.c pass4.c \
pass5.c fsutil.c setup.c utilities.c ffs_bswap.c ffs_subr.c \
ffs_tables.c ffs_appleufs.c
ffs_tables.c ffs_appleufs.c partutil.c
FSCK= ${NETBSDSRCDIR}/sbin/fsck
CPPFLAGS+=-I${FSCK}
@ -19,6 +19,9 @@ SRCS+= progress.c
.PATH: ${NETBSDSRCDIR}/sys/ufs/ffs ${FSCK}
LDADD+=-lutil
DPADD+=${LIBUTIL}
.if ${HAVE_GCC} == 4
COPTS.ffs_appleufs.c+= -Wno-pointer-sign
.endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: setup.c,v 1.79 2006/03/17 15:53:46 rumble Exp $ */
/* $NetBSD: setup.c,v 1.80 2006/08/26 22:03:47 christos Exp $ */
/*
* Copyright (c) 1980, 1986, 1993
@ -34,7 +34,7 @@
#if 0
static char sccsid[] = "@(#)setup.c 8.10 (Berkeley) 5/9/95";
#else
__RCSID("$NetBSD: setup.c,v 1.79 2006/03/17 15:53:46 rumble Exp $");
__RCSID("$NetBSD: setup.c,v 1.80 2006/08/26 22:03:47 christos Exp $");
#endif
#endif /* not lint */
@ -42,9 +42,8 @@ __RCSID("$NetBSD: setup.c,v 1.79 2006/03/17 15:53:46 rumble Exp $");
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#define FSTYPENAMES
#include <sys/disklabel.h>
#include <sys/file.h>
#include <sys/disk.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h>
@ -62,13 +61,12 @@ __RCSID("$NetBSD: setup.c,v 1.79 2006/03/17 15:53:46 rumble Exp $");
#include "fsck.h"
#include "extern.h"
#include "fsutil.h"
#include "partutil.h"
#define POWEROF2(num) (((num) & ((num) - 1)) == 0)
static void badsb(int, const char *);
static int calcsb(const char *, int, struct fs *);
static struct disklabel *getdisklabel(const char *, int);
static struct partition *getdisklabelpart(const char *, struct disklabel *);
static int readsb(int);
static int readappleufs(void);
@ -84,7 +82,8 @@ setup(const char *dev)
{
long cg, size, asked, i, j;
long bmapsize;
struct disklabel *lp = NULL;
struct disk_geom geo;
struct dkwedge_info dkw;
off_t sizepb;
struct stat statb;
struct fs proto;
@ -128,8 +127,8 @@ setup(const char *dev)
if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL ||
sblock == NULL || altsblock == NULL)
errx(EEXIT, "cannot allocate space for superblock");
if (!forceimage && (lp = getdisklabel(NULL, fsreadfd)) != NULL)
dev_bsize = secsize = lp->d_secsize;
if (!forceimage && getdiskinfo(dev, fsreadfd, NULL, &geo, &dkw) != -1)
dev_bsize = secsize = geo.dg_secsize;
else
dev_bsize = secsize = DEV_BSIZE;
/*
@ -471,17 +470,12 @@ setup(const char *dev)
else
usedsoftdep = 0;
{
struct partition *pp = 0;
if (!forceimage && lp)
pp = getdisklabelpart(dev,lp);
if (pp && (pp->p_fstype == FS_APPLEUFS)) {
if (!forceimage && dkw.dkw_parent[0])
if (strcmp(dkw.dkw_ptype, DKW_PTYPE_APPLEUFS) == 0)
isappleufs = 1;
}
}
if (readappleufs()) {
if (readappleufs())
isappleufs = 1;
}
dirblksiz = DIRBLKSIZ;
if (isappleufs)
@ -750,7 +744,9 @@ readsb(int listerr)
}
badsb(listerr,
"VALUES IN SUPER BLOCK DISAGREE WITH THOSE IN FIRST ALTERNATE");
/*
return (0);
*/
}
out:
@ -929,90 +925,41 @@ badsb(int listerr, const char *s)
static int
calcsb(const char *dev, int devfd, struct fs *fs)
{
struct disklabel *lp;
struct partition *pp;
struct dkwedge_info dkw;
struct disk_geom geo;
int i, nspf;
lp = getdisklabel(dev, devfd);
pp = getdisklabelpart(dev,lp);
if (pp == 0) {
if (getdiskinfo(dev, fsreadfd, NULL, &geo, &dkw) == -1)
pfatal("%s: CANNOT FIGURE OUT FILE SYSTEM PARTITION\n", dev);
if (dkw.dkw_parent[0] == '\0') {
pfatal("%s: CANNOT FIGURE OUT FILE SYSTEM PARTITION\n", dev);
return (0);
}
if ((pp->p_fstype != FS_BSDFFS) && (pp->p_fstype != FS_APPLEUFS)) {
if (strcmp(dkw.dkw_ptype, DKW_PTYPE_FFS) &&
strcmp(dkw.dkw_ptype, DKW_PTYPE_APPLEUFS)) {
pfatal("%s: NOT LABELED AS A BSD FILE SYSTEM (%s)\n",
dev, pp->p_fstype < FSMAXTYPES ?
fstypenames[pp->p_fstype] : "unknown");
dev, dkw.dkw_ptype);
return (0);
}
/* avoid divide by 0 */
if (pp->p_fsize == 0 || pp->p_frag == 0 || pp->p_cpg == 0) {
pfatal("%s: LABEL DOES NOT CONTAIN FILE SYSTEM PARAMETERS\n", dev);
return (0);
}
memset(fs, 0, sizeof(struct fs));
fs->fs_fsize = pp->p_fsize;
fs->fs_frag = pp->p_frag;
fs->fs_size = pp->p_size;
fs->fs_sblkno = roundup(
howmany(lp->d_bbsize + lp->d_sbsize, fs->fs_fsize),
fs->fs_frag);
nspf = fs->fs_fsize / lp->d_secsize;
memcpy(fs, &sblk.b_un.b_fs, sizeof(struct fs));
nspf = fs->fs_fsize / geo.dg_secsize;
fs->fs_old_nspf = nspf;
for (fs->fs_fsbtodb = 0, i = nspf; i > 1; i >>= 1)
fs->fs_fsbtodb++;
dev_bsize = lp->d_secsize;
dev_bsize = geo.dg_secsize;
if (fs->fs_magic == FS_UFS2_MAGIC) {
fs->fs_fpg = pp->p_cpg;
fs->fs_ncg = howmany(fs->fs_size, fs->fs_fpg);
} else /* if (fs->fs_magic == FS_UFS1_MAGIC) */ {
fs->fs_old_cpg = pp->p_cpg;
fs->fs_old_cgmask = 0xffffffff;
for (i = lp->d_ntracks; i > 1; i >>= 1)
for (i = geo.dg_ntracks; i > 1; i >>= 1)
fs->fs_old_cgmask <<= 1;
if (!POWEROF2(lp->d_ntracks))
if (!POWEROF2(geo.dg_ntracks))
fs->fs_old_cgmask <<= 1;
fs->fs_old_cgoffset = roundup(
howmany(lp->d_nsectors, nspf), fs->fs_frag);
fs->fs_fpg = (fs->fs_old_cpg * lp->d_secpercyl) / nspf;
fs->fs_ncg = howmany(fs->fs_size / lp->d_secpercyl,
howmany(geo.dg_nsectors, nspf), fs->fs_frag);
fs->fs_fpg = (fs->fs_old_cpg * geo.dg_secpercyl) / nspf;
fs->fs_ncg = howmany(fs->fs_size / geo.dg_secpercyl,
fs->fs_old_cpg);
}
return (1);
}
static struct disklabel *
getdisklabel(const char *s, int fd)
{
static struct disklabel lab;
if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) {
if (s == NULL)
return ((struct disklabel *)NULL);
pwarn("ioctl (GCINFO): %s\n", strerror(errno));
errx(EEXIT, "%s: can't read disk label", s);
}
return (&lab);
}
static struct partition *
getdisklabelpart(const char *dev, struct disklabel *lp)
{
char *cp;
int c;
cp = strchr(dev, '\0');
if (cp == dev)
return NULL;
c = (unsigned char)cp[-1];
if (isdigit(c))
/* eg "wd0", return info for first partition */
return &lp->d_partitions[0];
if (c >= 'a' && c <= 'p')
/* eg "wd0f", return info for specified partition */
return &lp->d_partitions[c - 'a'];
return NULL;
}

View File

@ -1,17 +1,18 @@
# $NetBSD: Makefile,v 1.30 2006/05/11 23:16:29 mrg Exp $
# $NetBSD: Makefile,v 1.31 2006/08/26 22:03:47 christos Exp $
# @(#)Makefile 8.2 (Berkeley) 3/27/94
.include <bsd.own.mk>
PROG= newfs
SRCS= dkcksum.c newfs.c mkfs.c ffs_bswap.c ffs_appleufs.c
SRCS= dkcksum.c newfs.c mkfs.c ffs_bswap.c ffs_appleufs.c partutil.c
MAN= newfs.8 mount_mfs.8
DISKLABEL=${NETBSDSRCDIR}/sbin/disklabel
CPPFLAGS+=-DMFS -I${.CURDIR} -I${DISKLABEL}
FSCK=${NETBSDSRCDIR}/sbin/fsck
CPPFLAGS+=-DMFS -I${.CURDIR} -I${DISKLABEL} -I${FSCK}
DPADD+= ${LIBUTIL}
LDADD+= -lutil
.PATH: ${DISKLABEL} ${NETBSDSRCDIR}/sys/ufs/ffs
.PATH: ${DISKLABEL} ${NETBSDSRCDIR}/sys/ufs/ffs ${FSCK}
LINKS= ${BINDIR}/newfs ${BINDIR}/mount_mfs
MLINKS= mount_mfs.8 mfs.8

View File

@ -1,4 +1,4 @@
/* $NetBSD: extern.h,v 1.12 2006/01/15 19:49:25 dsl Exp $ */
/* $NetBSD: extern.h,v 1.13 2006/08/26 22:03:47 christos Exp $ */
/*
* Copyright (c) 1997 Christos Zoulas. All rights reserved.
@ -30,7 +30,7 @@
*/
/* prototypes */
void mkfs(struct partition *, const char *, int, int, mode_t, uid_t, gid_t);
void mkfs(const char *, int, int, mode_t, uid_t, gid_t);
/* * variables set up by front end. */
extern int mfs; /* run as the memory based filesystem */

View File

@ -1,4 +1,4 @@
/* $NetBSD: mkfs.c,v 1.100 2006/01/21 12:32:14 simonb Exp $ */
/* $NetBSD: mkfs.c,v 1.101 2006/08/26 22:03:47 christos Exp $ */
/*
* Copyright (c) 1980, 1989, 1993
@ -73,7 +73,7 @@
#if 0
static char sccsid[] = "@(#)mkfs.c 8.11 (Berkeley) 5/3/95";
#else
__RCSID("$NetBSD: mkfs.c,v 1.100 2006/01/21 12:32:14 simonb Exp $");
__RCSID("$NetBSD: mkfs.c,v 1.101 2006/08/26 22:03:47 christos Exp $");
#endif
#endif /* not lint */
@ -159,7 +159,7 @@ int iobuf_memsize; /* Actual buffer size */
int fsi, fso;
void
mkfs(struct partition *pp, const char *fsys, int fi, int fo,
mkfs(const char *fsys, int fi, int fo,
mode_t mfsmode, uid_t mfsuid, gid_t mfsgid)
{
uint fragsperinodeblk, ncg;
@ -726,20 +726,6 @@ mkfs(struct partition *pp, const char *fsys, int fi, int fo,
/* mfs doesn't need these permanently allocated */
munmap(iobuf, iobuf_memsize);
munmap(fscs_0, 2 * sblock.fs_fsize);
/*
* Update information about this partion in pack
* label, to that it may be updated on disk.
*/
if (pp == NULL)
return;
if (isappleufs)
pp->p_fstype = FS_APPLEUFS;
else
pp->p_fstype = FS_BSDFFS;
pp->p_fsize = sblock.fs_fsize;
pp->p_frag = sblock.fs_frag;
pp->p_cpg = sblock.fs_fpg;
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: newfs.c,v 1.91 2006/05/04 19:46:10 christos Exp $ */
/* $NetBSD: newfs.c,v 1.92 2006/08/26 22:03:47 christos Exp $ */
/*
* Copyright (c) 1983, 1989, 1993, 1994
@ -78,7 +78,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 1989, 1993, 1994\n\
#if 0
static char sccsid[] = "@(#)newfs.c 8.13 (Berkeley) 5/1/95";
#else
__RCSID("$NetBSD: newfs.c,v 1.91 2006/05/04 19:46:10 christos Exp $");
__RCSID("$NetBSD: newfs.c,v 1.92 2006/08/26 22:03:47 christos Exp $");
#endif
#endif /* not lint */
@ -88,6 +88,7 @@ __RCSID("$NetBSD: newfs.c,v 1.91 2006/05/04 19:46:10 christos Exp $");
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/disklabel.h>
#include <sys/disk.h>
#include <sys/file.h>
#include <sys/mount.h>
#include <sys/sysctl.h>
@ -118,6 +119,7 @@ __RCSID("$NetBSD: newfs.c,v 1.91 2006/05/04 19:46:10 christos Exp $");
#include "mntopts.h"
#include "dkcksum.h"
#include "extern.h"
#include "partutil.h"
struct mntopt mopts[] = {
MOPT_STDOPTS,
@ -128,16 +130,19 @@ struct mntopt mopts[] = {
{ NULL },
};
static struct disklabel *getdisklabel(char *, int);
static void rewritelabel(char *, int, struct disklabel *);
static gid_t mfs_group(const char *);
static uid_t mfs_user(const char *);
static int64_t strsuftoi64(const char *, const char *, int64_t, int64_t, int *);
static void usage(void);
int main(int, char *[]);
static void usage(void) __attribute__((__noreturn__));
#define COMPAT /* allow non-labeled disks */
#ifdef COMPAT
const char lmsg[] = "%s: can't read disk label; disk type must be specified";
#else
const char lmsg[] = "%s: can't read disk label";
#endif
/*
* The following two constants set the default block and fragment sizes.
* Both constants must be a power of 2 and meet the following constraints:
@ -206,10 +211,8 @@ int mntflags = 0; /* flags to be passed to mount */
u_long memleft; /* virtual memory available */
caddr_t membase; /* start address of memory based filesystem */
int needswap; /* Filesystem not in native byte order */
#ifdef COMPAT
char *disktype;
char *disktype = NULL;
int unlabeled;
#endif
char *appleufs_volname = 0; /* Apple UFS volume name */
int isappleufs = 0;
@ -218,13 +221,11 @@ char device[MAXPATHLEN];
int
main(int argc, char *argv[])
{
struct partition *pp = NULL;
struct disklabel *lp = NULL;
struct partition oldpartition;
struct disk_geom geo;
struct dkwedge_info dkw;
struct statvfs *mp;
struct stat sb;
int ch, fsi, fso, len, n, Fflag, Iflag, Zflag;
uint ptn = 0; /* gcc -Wuninitialised */
char *cp, *s1, *s2, *special;
const char *opstring;
int byte_sized = 0;
@ -417,7 +418,6 @@ main(int argc, char *argv[])
if (argc != 2 && (mfs || argc != 1))
usage();
memset(&oldpartition, 0, sizeof oldpartition);
memset(&sb, 0, sizeof sb);
special = argv[0];
if (Fflag || mfs) {
@ -490,34 +490,39 @@ main(int argc, char *argv[])
if (disktype == NULL)
disktype = argv[1];
#endif
lp = getdisklabel(special, fsi);
if (getdiskinfo(special, fsi, disktype, &geo, &dkw) == -1)
errx(1, lmsg, special);
unlabeled = disktype != NULL;
if (sectorsize == 0) {
sectorsize = lp->d_secsize;
sectorsize = geo.dg_secsize;
if (sectorsize <= 0)
errx(1, "no default sector size");
}
ptn = strchr(special, '\0')[-1] - 'a';
if (ptn < lp->d_npartitions && ptn == DISKPART(sb.st_rdev)) {
/* Assume partition really does match the label */
pp = &lp->d_partitions[ptn];
oldpartition = *pp;
if (pp->p_size == 0)
errx(1, "`%c' partition is unavailable",
'a' + ptn);
if (pp->p_fstype == FS_APPLEUFS)
if (dkw.dkw_parent[0]) {
if (dkw.dkw_size == 0)
errx(1, "%s partition is unavailable", special);
if (strcmp(dkw.dkw_ptype, DKW_PTYPE_APPLEUFS) == 0)
isappleufs = 1;
if (!Iflag) {
static const char m[] =
"%s partition type is not `%s'";
if (isappleufs) {
if (pp->p_fstype != FS_APPLEUFS)
errx(1, "`%c' partition type is not `Apple UFS'", 'a' + ptn);
if (strcmp(dkw.dkw_ptype,
DKW_PTYPE_APPLEUFS))
errx(1, m,
special, "Apple UFS");
} else {
if (pp->p_fstype != FS_BSDFFS)
errx(1, "`%c' partition type is not `4.2BSD'", 'a' + ptn);
if (strcmp(dkw.dkw_ptype,
DKW_PTYPE_FFS))
errx(1, m, special, "4.2BSD");
}
}
}
} /* !Fflag && !mfs */
} /* !Fflag && !mfs */
}
if (byte_sized)
fssize /= sectorsize;
@ -525,15 +530,15 @@ main(int argc, char *argv[])
if (sb.st_size != 0)
fssize += sb.st_size / sectorsize;
else
fssize += oldpartition.p_size;
fssize += dkw.dkw_size;
if (fssize <= 0)
errx(1, "Unable to determine file system size");
}
if (pp != NULL && fssize > pp->p_size)
if (dkw.dkw_parent[0] && fssize > dkw.dkw_size)
errx(1, "size %" PRIu64 " exceeds maximum file system size on "
"`%s' of %u sectors",
fssize, special, pp->p_size);
"`%s' of %" PRIu64 " sectors",
fssize, special, dkw.dkw_size);
/* XXXLUKEM: only ftruncate() regular files ? (dsl: or at all?) */
if (Fflag && fso != -1
@ -572,8 +577,6 @@ main(int argc, char *argv[])
/* Sort out fragment and block sizes */
if (fsize == 0) {
fsize = bsize / DFL_FRAG_BLK;
if (fsize == 0)
fsize = oldpartition.p_fsize;
if (fsize <= 0) {
if (isappleufs) {
fsize = APPLEUFS_DFL_FRAGSIZE;
@ -589,14 +592,11 @@ main(int argc, char *argv[])
}
}
}
if (bsize == 0) {
bsize = oldpartition.p_frag * oldpartition.p_fsize;
if (bsize <= 0) {
if (isappleufs)
bsize = APPLEUFS_DFL_BLKSIZE;
else
bsize = DFL_FRAG_BLK * fsize;
}
if (bsize <= 0) {
if (isappleufs)
bsize = APPLEUFS_DFL_BLKSIZE;
else
bsize = DFL_FRAG_BLK * fsize;
}
if (isappleufs && (fsize < APPLEUFS_DFL_FRAGSIZE)) {
@ -629,10 +629,7 @@ main(int argc, char *argv[])
else
maxbpg = MAXBLKPG_UFS2(bsize);
}
mkfs(pp, special, fsi, fso, mfsmode, mfsuid, mfsgid);
if (!Nflag && pp != NULL
&& memcmp(pp, &oldpartition, sizeof(oldpartition)))
rewritelabel(special, fso, lp);
mkfs(special, fsi, fso, mfsmode, mfsuid, mfsgid);
if (fsi != -1 && fsi != fso)
close(fsi);
if (fso != -1)
@ -702,90 +699,6 @@ main(int argc, char *argv[])
exit(0);
}
#ifdef COMPAT
const char lmsg[] = "%s: can't read disk label; disk type must be specified";
#else
const char lmsg[] = "%s: can't read disk label";
#endif
static struct disklabel *
getdisklabel(char *s, int fd)
{
static struct disklabel lab;
#ifdef COMPAT
if (disktype) {
struct disklabel *lp;
unlabeled++;
lp = getdiskbyname(disktype);
if (lp == NULL)
errx(1, "%s: unknown disk type", disktype);
return (lp);
}
#endif
if (ioctl(fd, DIOCGDINFO, &lab) < 0) {
warn("ioctl (GDINFO)");
errx(1, lmsg, s);
}
return (&lab);
}
static void
rewritelabel(char *s, int fd, struct disklabel *lp)
{
#ifdef COMPAT
if (unlabeled)
return;
#endif
lp->d_checksum = 0;
lp->d_checksum = dkcksum(lp);
if (ioctl(fd, DIOCWDINFO, (char *)lp) < 0) {
if (errno == ESRCH)
return;
warn("ioctl (WDINFO)");
errx(1, "%s: can't rewrite disk label", s);
}
#if __vax__
if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) {
int i;
int cfd;
daddr_t alt;
off_t loff;
char specname[64];
char blk[1024];
char *cp;
/*
* Make name for 'c' partition.
*/
strlcpy(specname, s, sizeof(specname));
cp = specname + strlen(specname) - 1;
if (!isdigit((unsigned char)*cp))
*cp = 'c';
cfd = open(specname, O_WRONLY);
if (cfd < 0)
err(1, "%s: open", specname);
if ((loff = getlabeloffset()) < 0)
err(1, "getlabeloffset()");
memset(blk, 0, sizeof(blk));
*(struct disklabel *)(blk + loff) = *lp;
alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors;
for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) {
off_t offset;
offset = alt + i;
offset *= lp->d_secsize;
if (lseek(cfd, offset, SEEK_SET) == -1)
err(1, "lseek to badsector area: ");
if (write(cfd, blk, lp->d_secsize) < lp->d_secsize)
warn("alternate label %d write", i/2);
}
close(cfd);
}
#endif
}
static gid_t
mfs_group(const char *gname)
{