When the MNTK_EXTENDED_SHARED mount option was added, some filesystems were
changed to defer the setting of VN_LOCK_ASHARE() (which clears LK_NOSHARE in the vnode lock's flags) until after they had determined if the vnode was a FIFO. This occurs after the vnode has been inserted a VFS hash or some similar table, so it is possible for another thread to find this vnode via vget() on an i-node number and block on the vnode lock. If the lockmgr interlock (vnode interlock for vnode locks) is not held when clearing the LK_NOSHARE flag, then the lk_flags field can be clobbered. As a result the thread blocked on the vnode lock may never get woken up. Fix this by holding the vnode interlock while modifying the lock flags in this case. MFC after: 3 days
This commit is contained in:
parent
12c5cab23e
commit
dbfcf8cfea
@ -566,8 +566,11 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz)
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (vp->v_type != VFIFO)
|
||||
if (vp->v_type != VFIFO) {
|
||||
VI_LOCK(vp);
|
||||
VN_LOCK_ASHARE(vp);
|
||||
VI_UNLOCK(vp);
|
||||
}
|
||||
|
||||
mutex_enter(&zfsvfs->z_znodes_lock);
|
||||
list_insert_tail(&zfsvfs->z_all_znodes, zp);
|
||||
|
@ -814,7 +814,9 @@ cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir)
|
||||
vp->v_op = &cd9660_fifoops;
|
||||
break;
|
||||
default:
|
||||
VI_LOCK(vp);
|
||||
VN_LOCK_ASHARE(vp);
|
||||
VI_UNLOCK(vp);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -710,8 +710,11 @@ udf_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp)
|
||||
break;
|
||||
}
|
||||
|
||||
if (vp->v_type != VFIFO)
|
||||
if (vp->v_type != VFIFO) {
|
||||
VI_LOCK(vp);
|
||||
VN_LOCK_ASHARE(vp);
|
||||
VI_UNLOCK(vp);
|
||||
}
|
||||
|
||||
if (ino == udf_getid(&udfmp->root_icb))
|
||||
vp->v_vflag |= VV_ROOT;
|
||||
|
@ -1577,7 +1577,9 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags)
|
||||
*/
|
||||
if (vp->v_type != VFIFO) {
|
||||
/* FFS supports shared locking for all files except fifos. */
|
||||
VI_LOCK(vp);
|
||||
VN_LOCK_ASHARE(vp);
|
||||
VI_UNLOCK(vp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user