When a device containing mounted UFS filesystem disappears, the type

of devvp becomes VBAD, which UFS incorrectly interprets as snapshot
vnode, which in turns causes panic.  Fix it by replacing '!= VCHR'
with '== VREG'.

With this fix in place, you should no longer be able to panic the system
by removing a device with an UFS filesystem mounted from it - assuming
you don't use softupdates.

Reviewed by:	kib
Tested by:	pho
Approved by:	rwatson (mentor)
Sponsored by:	FreeBSD Foundation
This commit is contained in:
Edward Tomasz Napierala 2009-02-06 17:14:07 +00:00
parent 14fdb5561d
commit 8a3f2c376a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=188240

View file

@ -1858,7 +1858,7 @@ ffs_blkfree(ump, fs, devvp, bno, size, inum)
struct cdev *dev;
cg = dtog(fs, bno);
if (devvp->v_type != VCHR) {
if (devvp->v_type == VREG) {
/* devvp is a snapshot */
dev = VTOI(devvp)->i_devvp->v_rdev;
cgblkno = fragstoblks(fs, cgtod(fs, cg));
@ -1903,7 +1903,7 @@ ffs_blkfree(ump, fs, devvp, bno, size, inum)
if (size == fs->fs_bsize) {
fragno = fragstoblks(fs, cgbno);
if (!ffs_isfreeblock(fs, blksfree, fragno)) {
if (devvp->v_type != VCHR) {
if (devvp->v_type == VREG) {
UFS_UNLOCK(ump);
/* devvp is a snapshot */
brelse(bp);
@ -2056,7 +2056,7 @@ ffs_freefile(ump, fs, devvp, ino, mode)
struct cdev *dev;
cg = ino_to_cg(fs, ino);
if (devvp->v_type != VCHR) {
if (devvp->v_type == VREG) {
/* devvp is a snapshot */
dev = VTOI(devvp)->i_devvp->v_rdev;
cgbno = fragstoblks(fs, cgtod(fs, cg));
@ -2122,7 +2122,7 @@ ffs_checkfreefile(fs, devvp, ino)
u_int8_t *inosused;
cg = ino_to_cg(fs, ino);
if (devvp->v_type != VCHR) {
if (devvp->v_type == VREG) {
/* devvp is a snapshot */
cgbno = fragstoblks(fs, cgtod(fs, cg));
} else {