Test whether the filesystem is an LFS before trying to read the alternate
superblock (whose disk address is stored in the primary superblock). Also, refuse to mount a filesystem whose superblocks overlap or where the alt. superblock has a lower disk address than the primary superblock. Solves PR#10001.
This commit is contained in:
parent
22cfbf2cbb
commit
37f567639c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lfs_vfsops.c,v 1.49 2000/04/23 21:10:27 perseant Exp $ */
|
||||
/* $NetBSD: lfs_vfsops.c,v 1.50 2000/04/29 00:23:00 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
@ -366,6 +366,7 @@ lfs_mountfs(devvp, mp, p)
|
||||
|
||||
/* Don't free random space on error. */
|
||||
bp = NULL;
|
||||
abp = NULL;
|
||||
ump = NULL;
|
||||
|
||||
/* Read in the superblock. */
|
||||
@ -374,19 +375,6 @@ lfs_mountfs(devvp, mp, p)
|
||||
goto out;
|
||||
dfs = (struct dlfs *)bp->b_data;
|
||||
|
||||
/*
|
||||
* Check the second superblock to see which is newer; then mount
|
||||
* using the older of the two. This is necessary to ensure that
|
||||
* the filesystem is valid if it was not unmounted cleanly.
|
||||
*/
|
||||
error = bread(devvp, dfs->dlfs_sboffs[1], LFS_SBPAD, cred, &abp);
|
||||
if (error)
|
||||
goto out;
|
||||
adfs = (struct dlfs *)abp->b_data;
|
||||
|
||||
if (adfs->dlfs_tstamp < dfs->dlfs_tstamp) /* XXX KS - 1s resolution? */
|
||||
dfs = adfs;
|
||||
|
||||
/* Check the basics. */
|
||||
if (dfs->dlfs_magic != LFS_MAGIC || dfs->dlfs_bsize > MAXBSIZE ||
|
||||
dfs->dlfs_version > LFS_VERSION ||
|
||||
@ -395,6 +383,28 @@ lfs_mountfs(devvp, mp, p)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the second superblock to see which is newer; then mount
|
||||
* using the older of the two. This is necessary to ensure that
|
||||
* the filesystem is valid if it was not unmounted cleanly.
|
||||
*/
|
||||
if (dfs->dlfs_sboffs[1] &&
|
||||
dfs->dlfs_sboffs[1]-(LFS_LABELPAD/size) > LFS_SBPAD/size)
|
||||
{
|
||||
error = bread(devvp, dfs->dlfs_sboffs[1], LFS_SBPAD, cred, &abp);
|
||||
if (error)
|
||||
goto out;
|
||||
adfs = (struct dlfs *)abp->b_data;
|
||||
|
||||
if (adfs->dlfs_tstamp < dfs->dlfs_tstamp) /* XXX 1s? */
|
||||
dfs = adfs;
|
||||
} else {
|
||||
printf("lfs_mountfs: invalid alt superblock daddr=0x%x\n",
|
||||
dfs->dlfs_sboffs[1]);
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Allocate the mount structure, copy the superblock into it. */
|
||||
fs = malloc(sizeof(struct lfs), M_UFSMNT, M_WAITOK);
|
||||
memcpy(&fs->lfs_dlfs, dfs, sizeof(struct dlfs));
|
||||
|
Loading…
Reference in New Issue
Block a user