diff options
Diffstat (limited to 'sys/ufs')
-rw-r--r-- | sys/ufs/ffs/ffs_vnops.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c index 9b3a440..0362876 100644 --- a/sys/ufs/ffs/ffs_vnops.c +++ b/sys/ufs/ffs/ffs_vnops.c @@ -343,7 +343,17 @@ ffs_lock(ap) { struct vnode *vp = ap->a_vp; - if ((VTOI(vp)->i_flags & SF_SNAPSHOT) && + /* + * v_data could be NULL if a thread attempts to lock a + * vnode that is being recycled. Just hit the normal + * vnode lock in this case. Grab the interlock so we may + * safely inspect the vnode. + */ + if ((ap->a_flags & LK_INTERLOCK) == 0) { + VI_LOCK(vp); + ap->a_flags |= LK_INTERLOCK; + } + if (vp->v_data && (VTOI(vp)->i_flags & SF_SNAPSHOT) && ((ap->a_flags & LK_TYPE_MASK) == LK_SHARED)) { ap->a_flags &= ~LK_TYPE_MASK; ap->a_flags |= LK_EXCLUSIVE; |