svn commit: r305977 - in head/sys/ufs: ffs ufs
Konstantin Belousov
kib at FreeBSD.org
Mon Sep 19 15:58:34 UTC 2016
Author: kib
Date: Mon Sep 19 15:58:33 2016
New Revision: 305977
URL: https://svnweb.freebsd.org/changeset/base/305977
Log:
Be more strict when selecting between snapshot/regular mount.
Reclaimed vnode type is VBAD, so succesful comparision like
devvp->v_type != VREG does not imply that the devvp references
snapshot, it might be due to a reclaimed vnode. Explicitely check the
vnode type.
In the the most important case of ffs_blkfree(), the devfs vnode is
locked and its type is stable. In other cases, if the vnode is
reclaimed right after the check, hopefully the buffer methods return
right error codes.
Reviewed by: mckusick
Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks
Modified:
head/sys/ufs/ffs/ffs_alloc.c
head/sys/ufs/ufs/ufs_gjournal.c
Modified: head/sys/ufs/ffs/ffs_alloc.c
==============================================================================
--- head/sys/ufs/ffs/ffs_alloc.c Mon Sep 19 15:39:24 2016 (r305976)
+++ head/sys/ufs/ffs/ffs_alloc.c Mon Sep 19 15:58:33 2016 (r305977)
@@ -2171,12 +2171,13 @@ ffs_blkfree_cg(ump, fs, devvp, bno, size
MPASS(devvp->v_mount->mnt_data == ump);
dev = ump->um_devvp->v_rdev;
cgblkno = fragstoblks(fs, cgtod(fs, cg));
- } else {
+ } else if (devvp->v_type == VCHR) {
/* devvp is a normal disk device */
dev = devvp->v_rdev;
cgblkno = fsbtodb(fs, cgtod(fs, cg));
ASSERT_VOP_LOCKED(devvp, "ffs_blkfree_cg");
- }
+ } else
+ return;
#ifdef INVARIANTS
if ((u_int)size > fs->fs_bsize || fragoff(fs, size) != 0 ||
fragnum(fs, bno) + numfrags(fs, size) > fs->fs_frag) {
@@ -2270,7 +2271,7 @@ ffs_blkfree_cg(ump, fs, devvp, bno, size
ACTIVECLEAR(fs, cg);
UFS_UNLOCK(ump);
mp = UFSTOVFS(ump);
- if (MOUNTEDSOFTDEP(mp) && devvp->v_type != VREG)
+ if (MOUNTEDSOFTDEP(mp) && devvp->v_type == VCHR)
softdep_setup_blkfree(UFSTOVFS(ump), bp, bno,
numfrags(fs, size), dephd);
bdwrite(bp);
@@ -2335,7 +2336,7 @@ ffs_blkfree(ump, fs, devvp, bno, size, i
* it has a snapshot(s) associated with it, and one of the
* snapshots wants to claim the block.
*/
- if (devvp->v_type != VREG &&
+ if (devvp->v_type == VCHR &&
(devvp->v_vflag & VV_COPYONWRITE) &&
ffs_snapblkfree(fs, devvp, bno, size, inum, vtype, dephd)) {
return;
@@ -2480,10 +2481,13 @@ ffs_freefile(ump, fs, devvp, ino, mode,
MPASS(devvp->v_mount->mnt_data == ump);
dev = ump->um_devvp->v_rdev;
cgbno = fragstoblks(fs, cgtod(fs, cg));
- } else {
+ } else if (devvp->v_type == VCHR) {
/* devvp is a normal disk device */
dev = devvp->v_rdev;
cgbno = fsbtodb(fs, cgtod(fs, cg));
+ } else {
+ bp = NULL;
+ return (0);
}
if (ino >= fs->fs_ipg * fs->fs_ncg)
panic("ffs_freefile: range: dev = %s, ino = %ju, fs = %s",
@@ -2522,7 +2526,7 @@ ffs_freefile(ump, fs, devvp, ino, mode,
fs->fs_fmod = 1;
ACTIVECLEAR(fs, cg);
UFS_UNLOCK(ump);
- if (MOUNTEDSOFTDEP(UFSTOVFS(ump)) && devvp->v_type != VREG)
+ if (MOUNTEDSOFTDEP(UFSTOVFS(ump)) && devvp->v_type == VCHR)
softdep_setup_inofree(UFSTOVFS(ump), bp,
ino + cg * fs->fs_ipg, wkhd);
bdwrite(bp);
@@ -2549,9 +2553,11 @@ ffs_checkfreefile(fs, devvp, ino)
if (devvp->v_type == VREG) {
/* devvp is a snapshot */
cgbno = fragstoblks(fs, cgtod(fs, cg));
- } else {
+ } else if (devvp->v_type == VCHR) {
/* devvp is a normal disk device */
cgbno = fsbtodb(fs, cgtod(fs, cg));
+ } else {
+ return (1);
}
if (ino >= fs->fs_ipg * fs->fs_ncg)
return (1);
Modified: head/sys/ufs/ufs/ufs_gjournal.c
==============================================================================
--- head/sys/ufs/ufs/ufs_gjournal.c Mon Sep 19 15:39:24 2016 (r305976)
+++ head/sys/ufs/ufs/ufs_gjournal.c Mon Sep 19 15:58:33 2016 (r305977)
@@ -71,14 +71,17 @@ ufs_gjournal_modref(struct vnode *vp, in
ino = ip->i_number;
cg = ino_to_cg(fs, ino);
- if (devvp->v_type != VCHR) {
+ if (devvp->v_type == VREG) {
/* devvp is a snapshot */
dev = VFSTOUFS(devvp->v_mount)->um_devvp->v_rdev;
cgbno = fragstoblks(fs, cgtod(fs, cg));
- } else {
+ } else if (devvp->v_type == VCHR) {
/* devvp is a normal disk device */
dev = devvp->v_rdev;
cgbno = fsbtodb(fs, cgtod(fs, cg));
+ } else {
+ bp = NULL;
+ return (EIO);
}
if ((u_int)ino >= fs->fs_ipg * fs->fs_ncg)
panic("ufs_gjournal_modref: range: dev = %s, ino = %lu, fs = %s",
More information about the svn-src-all
mailing list