aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libufs/libufs.h6
-rw-r--r--lib/libufs/sblock.c2
-rw-r--r--sbin/dump/main.c2
-rw-r--r--sbin/fsck_ffs/setup.c2
-rw-r--r--sbin/fsirand/fsirand.c2
-rw-r--r--sbin/growfs/growfs.c2
-rw-r--r--sbin/quotacheck/quotacheck.c2
-rw-r--r--stand/libsa/ufs.c8
-rw-r--r--sys/geom/journal/g_journal_ufs.c2
-rw-r--r--sys/geom/label/g_label_ufs.c2
-rw-r--r--sys/ufs/ffs/ffs_extern.h6
-rw-r--r--sys/ufs/ffs/ffs_subr.c35
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c7
-rw-r--r--usr.sbin/fstyp/ufs.c2
-rw-r--r--usr.sbin/quot/quot.c2
15 files changed, 60 insertions, 22 deletions
diff --git a/lib/libufs/libufs.h b/lib/libufs/libufs.h
index dbd378949877..9d1e7355c2f7 100644
--- a/lib/libufs/libufs.h
+++ b/lib/libufs/libufs.h
@@ -118,6 +118,12 @@ int ffs_sbput(void *, struct fs *, off_t,
int (*)(void *, off_t, void *, int));
/*
+ * Request standard superblock location in ffs_sbget
+ */
+#define STDSB -1 /* Fail if check-hash is bad */
+#define STDSB_NOHASHFAIL -2 /* Ignore check-hash failure */
+
+/*
* block.c
*/
ssize_t bread(struct uufsd *, ufs2_daddr_t, void *, size_t);
diff --git a/lib/libufs/sblock.c b/lib/libufs/sblock.c
index 29ff258b6ebf..53c8d44f6d65 100644
--- a/lib/libufs/sblock.c
+++ b/lib/libufs/sblock.c
@@ -54,7 +54,7 @@ sbread(struct uufsd *disk)
ERROR(disk, NULL);
- if ((errno = sbget(disk->d_fd, &fs, -1)) != 0) {
+ if ((errno = sbget(disk->d_fd, &fs, STDSB)) != 0) {
switch (errno) {
case EIO:
ERROR(disk, "non-existent or truncated superblock");
diff --git a/sbin/dump/main.c b/sbin/dump/main.c
index 7301ca318d80..135b4fcfb64c 100644
--- a/sbin/dump/main.c
+++ b/sbin/dump/main.c
@@ -433,7 +433,7 @@ main(int argc, char *argv[])
msgtail("to %s\n", tape);
sync();
- if ((ret = sbget(diskfd, &sblock, -1)) != 0) {
+ if ((ret = sbget(diskfd, &sblock, STDSB)) != 0) {
switch (ret) {
case ENOENT:
warn("Cannot find file system superblock");
diff --git a/sbin/fsck_ffs/setup.c b/sbin/fsck_ffs/setup.c
index 82a970e12858..8599f6cde739 100644
--- a/sbin/fsck_ffs/setup.c
+++ b/sbin/fsck_ffs/setup.c
@@ -327,7 +327,7 @@ readsb(int listerr)
int bad, ret;
struct fs *fs;
- super = bflag ? bflag * dev_bsize : -1;
+ super = bflag ? bflag * dev_bsize : STDSB;
readcnt[sblk.b_type]++;
if ((ret = sbget(fsreadfd, &fs, super)) != 0) {
switch (ret) {
diff --git a/sbin/fsirand/fsirand.c b/sbin/fsirand/fsirand.c
index f5e26571f903..8675f7c3fd33 100644
--- a/sbin/fsirand/fsirand.c
+++ b/sbin/fsirand/fsirand.c
@@ -126,7 +126,7 @@ fsirand(char *device)
dp2 = NULL;
/* Read in master superblock */
- if ((ret = sbget(devfd, &sblock, -1)) != 0) {
+ if ((ret = sbget(devfd, &sblock, STDSB)) != 0) {
switch (ret) {
case ENOENT:
warn("Cannot find file system superblock");
diff --git a/sbin/growfs/growfs.c b/sbin/growfs/growfs.c
index b75f377841ef..967cda3330d0 100644
--- a/sbin/growfs/growfs.c
+++ b/sbin/growfs/growfs.c
@@ -1449,7 +1449,7 @@ main(int argc, char **argv)
/*
* Read the current superblock, and take a backup.
*/
- if ((ret = sbget(fsi, &fs, -1)) != 0) {
+ if ((ret = sbget(fsi, &fs, STDSB)) != 0) {
switch (ret) {
case ENOENT:
errx(1, "superblock not recognized");
diff --git a/sbin/quotacheck/quotacheck.c b/sbin/quotacheck/quotacheck.c
index 3b192a7a9585..9a01be11d9d0 100644
--- a/sbin/quotacheck/quotacheck.c
+++ b/sbin/quotacheck/quotacheck.c
@@ -321,7 +321,7 @@ chkquota(char *specname, struct quotafile *qfu, struct quotafile *qfg)
}
}
sync();
- if ((ret = sbget(fi, &fs, -1)) != 0) {
+ if ((ret = sbget(fi, &fs, STDSB)) != 0) {
switch (ret) {
case ENOENT:
warn("Cannot find file system superblock");
diff --git a/stand/libsa/ufs.c b/stand/libsa/ufs.c
index 204bc969f968..317d6e9fdb1c 100644
--- a/stand/libsa/ufs.c
+++ b/stand/libsa/ufs.c
@@ -140,6 +140,11 @@ static int ufs_use_sa_read(void *, off_t, void **, int);
/* from ffs_subr.c */
int ffs_sbget(void *, struct fs **, off_t, char *,
int (*)(void *, off_t, void **, int));
+/*
+ * Request standard superblock location in ffs_sbget
+ */
+#define STDSB -1 /* Fail if check-hash is bad */
+#define STDSB_NOHASHFAIL -2 /* Ignore check-hash failure */
/*
* Read a new inode into a file structure.
@@ -519,7 +524,8 @@ ufs_open(upath, f)
/* read super block */
twiddle(1);
- if ((rc = ffs_sbget(f, &fs, -1, "stand", ufs_use_sa_read)) != 0)
+ if ((rc = ffs_sbget(f, &fs, STDSB_NOHASHFAIL, "stand",
+ ufs_use_sa_read)) != 0)
goto out;
fp->f_fs = fs;
/*
diff --git a/sys/geom/journal/g_journal_ufs.c b/sys/geom/journal/g_journal_ufs.c
index de0dbd83d48b..028c68079482 100644
--- a/sys/geom/journal/g_journal_ufs.c
+++ b/sys/geom/journal/g_journal_ufs.c
@@ -72,7 +72,7 @@ g_journal_ufs_dirty(struct g_consumer *cp)
fs = NULL;
if (SBLOCKSIZE % cp->provider->sectorsize != 0 ||
- ffs_sbget(cp, &fs, -1, M_GEOM, g_use_g_read_data) != 0) {
+ ffs_sbget(cp, &fs, STDSB, M_GEOM, g_use_g_read_data) != 0) {
GJ_DEBUG(0, "Cannot find superblock to mark file system %s "
"as dirty.", cp->provider->name);
KASSERT(fs == NULL,
diff --git a/sys/geom/label/g_label_ufs.c b/sys/geom/label/g_label_ufs.c
index b247eaad827d..4c4d43cad0f7 100644
--- a/sys/geom/label/g_label_ufs.c
+++ b/sys/geom/label/g_label_ufs.c
@@ -77,7 +77,7 @@ g_label_ufs_taste_common(struct g_consumer *cp, char *label, size_t size, int wh
fs = NULL;
if (SBLOCKSIZE % pp->sectorsize != 0 ||
- ffs_sbget(cp, &fs, -1, M_GEOM, g_use_g_read_data) != 0) {
+ ffs_sbget(cp, &fs, STDSB, M_GEOM, g_use_g_read_data) != 0) {
KASSERT(fs == NULL,
("g_label_ufs_taste_common: non-NULL fs %p\n", fs));
return;
diff --git a/sys/ufs/ffs/ffs_extern.h b/sys/ufs/ffs/ffs_extern.h
index d3f6cb597b9a..16f517d5f12e 100644
--- a/sys/ufs/ffs/ffs_extern.h
+++ b/sys/ufs/ffs/ffs_extern.h
@@ -126,6 +126,12 @@ void process_deferred_inactive(struct mount *mp);
#define FFSR_UNSUSPEND 0x0002
/*
+ * Request standard superblock location in ffs_sbget
+ */
+#define STDSB -1 /* Fail if check-hash is bad */
+#define STDSB_NOHASHFAIL -2 /* Ignore check-hash failure */
+
+/*
* Definitions for TRIM interface
*
* Special keys and recommended hash table size
diff --git a/sys/ufs/ffs/ffs_subr.c b/sys/ufs/ffs/ffs_subr.c
index e4dbd730b186..64354bbd5383 100644
--- a/sys/ufs/ffs/ffs_subr.c
+++ b/sys/ufs/ffs/ffs_subr.c
@@ -51,6 +51,11 @@ struct malloc_type;
#define UFS_MALLOC(size, type, flags) malloc(size)
#define UFS_FREE(ptr, type) free(ptr)
#define UFS_TIME time(NULL)
+/*
+ * Request standard superblock location in ffs_sbget
+ */
+#define STDSB -1 /* Fail if check-hash is bad */
+#define STDSB_NOHASHFAIL -2 /* Ignore check-hash failure */
#else /* _KERNEL */
#include <sys/systm.h>
@@ -139,14 +144,14 @@ ffs_load_inode(struct buf *bp, struct inode *ip, struct fs *fs, ino_t ino)
ip->i_gid = dip2->di_gid;
return (0);
}
-#endif /* KERNEL */
+#endif /* _KERNEL */
/*
* These are the low-level functions that actually read and write
* the superblock and its associated data.
*/
static off_t sblock_try[] = SBLOCKSEARCH;
-static int readsuper(void *, struct fs **, off_t, int,
+static int readsuper(void *, struct fs **, off_t, int, int,
int (*)(void *, off_t, void **, int));
/*
@@ -177,21 +182,25 @@ ffs_sbget(void *devfd, struct fs **fsp, off_t altsblock,
int i, error, size, blks;
uint8_t *space;
int32_t *lp;
+ int chkhash;
char *buf;
fs = NULL;
*fsp = NULL;
- if (altsblock != -1) {
- if ((error = readsuper(devfd, &fs, altsblock, 1,
+ chkhash = 1;
+ if (altsblock >= 0) {
+ if ((error = readsuper(devfd, &fs, altsblock, 1, chkhash,
readfunc)) != 0) {
if (fs != NULL)
UFS_FREE(fs, filltype);
return (error);
}
} else {
+ if (altsblock == STDSB_NOHASHFAIL)
+ chkhash = 0;
for (i = 0; sblock_try[i] != -1; i++) {
if ((error = readsuper(devfd, &fs, sblock_try[i], 0,
- readfunc)) == 0)
+ chkhash, readfunc)) == 0)
break;
if (fs != NULL) {
UFS_FREE(fs, filltype);
@@ -255,7 +264,7 @@ ffs_sbget(void *devfd, struct fs **fsp, off_t altsblock,
*/
static int
readsuper(void *devfd, struct fs **fsp, off_t sblockloc, int isaltsblk,
- int (*readfunc)(void *devfd, off_t loc, void **bufp, int size))
+ int chkhash, int (*readfunc)(void *devfd, off_t loc, void **bufp, int size))
{
struct fs *fs;
int error, res;
@@ -285,8 +294,9 @@ readsuper(void *devfd, struct fs **fsp, off_t sblockloc, int isaltsblk,
if (fs->fs_ckhash != (ckhash = ffs_calc_sbhash(fs))) {
#ifdef _KERNEL
res = uprintf("Superblock check-hash failed: recorded "
- "check-hash 0x%x != computed check-hash 0x%x\n",
- fs->fs_ckhash, ckhash);
+ "check-hash 0x%x != computed check-hash 0x%x%s\n",
+ fs->fs_ckhash, ckhash,
+ chkhash == 0 ? " (Ignored)" : "");
#else
res = 0;
#endif
@@ -297,7 +307,14 @@ readsuper(void *devfd, struct fs **fsp, off_t sblockloc, int isaltsblk,
if (res == 0)
printf("Superblock check-hash failed: recorded "
"check-hash 0x%x != computed check-hash "
- "0x%x\n", fs->fs_ckhash, ckhash);
+ "0x%x%s\n", fs->fs_ckhash, ckhash,
+ chkhash == 0 ? " (Ignored)" : "");
+ if (chkhash == 0) {
+ fs->fs_flags |= FS_NEEDSFSCK;
+ fs->fs_fmod = 1;
+ return (0);
+ }
+ fs->fs_fmod = 0;
return (EINVAL);
}
/* Have to set for old filesystems that predate this field */
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 9670d6217e86..7cb81cfa450a 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -774,6 +774,7 @@ ffs_mountfs(devvp, mp, td)
struct g_consumer *cp;
struct mount *nmp;
int candelete;
+ off_t loc;
fs = NULL;
ump = NULL;
@@ -810,9 +811,11 @@ ffs_mountfs(devvp, mp, td)
goto out;
}
/* fetch the superblock and summary information */
- if ((error = ffs_sbget(devvp, &fs, -1, M_UFSMNT, ffs_use_bread)) != 0)
+ loc = STDSB;
+ if ((mp->mnt_flag & MNT_ROOTFS) != 0)
+ loc = STDSB_NOHASHFAIL;
+ if ((error = ffs_sbget(devvp, &fs, loc, M_UFSMNT, ffs_use_bread)) != 0)
goto out;
- fs->fs_fmod = 0;
/* none of these types of check-hashes are maintained by this kernel */
fs->fs_metackhash &= ~(CK_INODE | CK_INDIR | CK_DIR);
/* no support for any undefined flags */
diff --git a/usr.sbin/fstyp/ufs.c b/usr.sbin/fstyp/ufs.c
index 340119dada4c..4002fc89c9ee 100644
--- a/usr.sbin/fstyp/ufs.c
+++ b/usr.sbin/fstyp/ufs.c
@@ -50,7 +50,7 @@ fstyp_ufs(FILE *fp, char *label, size_t labelsize)
{
struct fs *fs;
- switch (sbget(fileno(fp), &fs, -1)) {
+ switch (sbget(fileno(fp), &fs, STDSB)) {
case 0:
strlcpy(label, fs->fs_volname, labelsize);
return (0);
diff --git a/usr.sbin/quot/quot.c b/usr.sbin/quot/quot.c
index 348946ff7dbb..18b1e398ec09 100644
--- a/usr.sbin/quot/quot.c
+++ b/usr.sbin/quot/quot.c
@@ -550,7 +550,7 @@ quot(char *name, char *mp)
close(fd);
return;
}
- switch (sbget(fd, &fs, -1)) {
+ switch (sbget(fd, &fs, STDSB)) {
case 0:
break;
case ENOENT: