1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-20 11:11:24 +00:00

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
This commit is contained in:
Konstantin Belousov 2016-09-19 15:58:33 +00:00
parent 5a3a700931
commit bf9c87c813
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=305977
2 changed files with 18 additions and 9 deletions

View File

@ -2171,12 +2171,13 @@ ffs_blkfree_cg(ump, fs, devvp, bno, size, inum, dephd)
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, inum, dephd)
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, inum, vtype, dephd)
* 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, wkhd)
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, wkhd)
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);

View File

@ -71,14 +71,17 @@ ufs_gjournal_modref(struct vnode *vp, int count)
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",