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:
parent
5a3a700931
commit
bf9c87c813
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=305977
@ -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);
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user