MFC: Always use an exclusive lock on the leaf vnode during an open() when
shared lookups are enabled. This closes a few races including a race where concurrent opens of a fifo could result in different v_fifoinfo structures in different threads.
This commit is contained in:
parent
1db2bde192
commit
9ad5f6f445
@ -215,6 +215,7 @@ devfs_allocv(struct devfs_dirent *de, struct mount *mp, struct vnode **vpp, stru
|
||||
VI_LOCK(vp);
|
||||
dev_lock();
|
||||
dev_refl(dev);
|
||||
/* XXX: v_rdev should be protect by vnode lock */
|
||||
vp->v_rdev = dev;
|
||||
KASSERT(vp->v_usecount == 1,
|
||||
("%s %d (%d)\n", __func__, __LINE__, vp->v_usecount));
|
||||
|
@ -179,7 +179,7 @@ fifo_open(ap)
|
||||
struct file *fp;
|
||||
int error;
|
||||
|
||||
ASSERT_VOP_LOCKED(vp, "fifo_open");
|
||||
ASSERT_VOP_ELOCKED(vp, "fifo_open");
|
||||
if (ap->a_fdidx < 0)
|
||||
return (EINVAL);
|
||||
if ((fip = vp->v_fifoinfo) == NULL) {
|
||||
|
@ -349,7 +349,7 @@ uipc_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
goto error;
|
||||
}
|
||||
vp = nd.ni_vp;
|
||||
ASSERT_VOP_LOCKED(vp, "uipc_bind");
|
||||
ASSERT_VOP_ELOCKED(vp, "uipc_bind");
|
||||
soun = (struct sockaddr_un *)sodupsockaddr(nam, M_WAITOK);
|
||||
UNP_LOCK();
|
||||
vp->v_socket = unp->unp_socket;
|
||||
|
@ -179,7 +179,7 @@ vn_open_cred(ndp, flagp, cmode, cred, fdidx)
|
||||
ndp->ni_cnd.cn_nameiop = LOOKUP;
|
||||
ndp->ni_cnd.cn_flags = ISOPEN |
|
||||
((fmode & O_NOFOLLOW) ? NOFOLLOW : FOLLOW) |
|
||||
LOCKSHARED | LOCKLEAF | MPSAFE | AUDITVNODE1;
|
||||
LOCKLEAF | MPSAFE | AUDITVNODE1;
|
||||
if ((error = namei(ndp)) != 0)
|
||||
return (error);
|
||||
ndp->ni_cnd.cn_flags &= ~MPSAFE;
|
||||
@ -229,7 +229,7 @@ vn_open_cred(ndp, flagp, cmode, cred, fdidx)
|
||||
if (fmode & FWRITE)
|
||||
vp->v_writecount++;
|
||||
*flagp = fmode;
|
||||
ASSERT_VOP_LOCKED(vp, "vn_open_cred");
|
||||
ASSERT_VOP_ELOCKED(vp, "vn_open_cred");
|
||||
if (fdidx == -1)
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
return (0);
|
||||
|
@ -172,7 +172,7 @@ vnode_destroy_vobject(struct vnode *vp)
|
||||
obj = vp->v_object;
|
||||
if (obj == NULL)
|
||||
return;
|
||||
ASSERT_VOP_LOCKED(vp, "vnode_destroy_vobject");
|
||||
ASSERT_VOP_ELOCKED(vp, "vnode_destroy_vobject");
|
||||
VM_OBJECT_LOCK(obj);
|
||||
if (obj->ref_count == 0) {
|
||||
/*
|
||||
@ -219,7 +219,7 @@ vnode_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot,
|
||||
|
||||
vp = (struct vnode *) handle;
|
||||
|
||||
ASSERT_VOP_LOCKED(vp, "vnode_pager_alloc");
|
||||
ASSERT_VOP_ELOCKED(vp, "vnode_pager_alloc");
|
||||
|
||||
/*
|
||||
* If the object is being terminated, wait for it to
|
||||
@ -277,7 +277,7 @@ vnode_pager_dealloc(object)
|
||||
vm_object_clear_flag(object, OBJ_DISCONNECTWNT);
|
||||
wakeup(object);
|
||||
}
|
||||
ASSERT_VOP_LOCKED(vp, "vnode_pager_dealloc");
|
||||
ASSERT_VOP_ELOCKED(vp, "vnode_pager_dealloc");
|
||||
vp->v_object = NULL;
|
||||
vp->v_vflag &= ~VV_TEXT;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user