diff options
author | jeff <jeff@FreeBSD.org> | 2005-03-13 12:04:12 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2005-03-13 12:04:12 +0000 |
commit | 6d607052330e66dc1e260e8f180de926262e8041 (patch) | |
tree | 46902fafd3cddf062e4a953287a3aef7082658b8 /sys | |
parent | cebf929bc833e9802f4f5142935c8f5355502a26 (diff) | |
download | FreeBSD-src-6d607052330e66dc1e260e8f180de926262e8041.zip FreeBSD-src-6d607052330e66dc1e260e8f180de926262e8041.tar.gz |
- It is not legal to access v_data without the vnode lock or interlock
held. Grab the vnode interlock if LK_INTERLOCK has not been passed in
so that we can inspect v_data in ffs_lock().
Sponsored by: Isilon Systems, Inc.
Diffstat (limited to 'sys')
-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; |