diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2018-03-30 11:22:59 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2018-03-30 11:22:59 +0000 |
commit | 09e4ce793930863061c4d5837d185e3f9d6be73d (patch) | |
tree | ea81b58b1a24c4999e70bb90861adebfe8e02207 | |
parent | 1c5e10d02e032d6f0b41776342585c86c7bb091d (diff) |
Unlock the NET_LOCK() before calling vn_lock(9) to avoid a lock ordering
issues with upcoming NFSnode's locks.
ok visa@
-rw-r--r-- | sys/uvm/uvm_vnode.c | 29 |
1 files changed, 16 insertions, 13 deletions
diff --git a/sys/uvm/uvm_vnode.c b/sys/uvm/uvm_vnode.c index 918e3abd883..cc1a566a5ce 100644 --- a/sys/uvm/uvm_vnode.c +++ b/sys/uvm/uvm_vnode.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_vnode.c,v 1.99 2018/03/08 22:04:18 bluhm Exp $ */ +/* $OpenBSD: uvm_vnode.c,v 1.100 2018/03/30 11:22:58 mpi Exp $ */ /* $NetBSD: uvm_vnode.c,v 1.36 2000/11/24 20:34:01 chs Exp $ */ /* @@ -1105,6 +1105,7 @@ uvn_io(struct uvm_vnode *uvn, vm_page_t *pps, int npages, int flags, int rw) off_t file_offset; int waitf, result, mapinflags; size_t got, wanted; + int netunlocked = 0; /* init values */ waitf = (flags & PGO_SYNCIO) ? M_WAITOK : M_NOWAIT; @@ -1163,6 +1164,15 @@ uvn_io(struct uvm_vnode *uvn, vm_page_t *pps, int npages, int flags, int rw) uio.uio_resid = wanted; uio.uio_procp = curproc; + /* + * This process may already have the NET_LOCK(), if we + * faulted in copyin() or copyout() in the network stack. + */ + if (rw_status(&netlock) == RW_WRITE) { + NET_UNLOCK(); + netunlocked = 1; + } + /* do the I/O! (XXX: curproc?) */ /* * This process may already have this vnode locked, if we faulted in @@ -1178,15 +1188,6 @@ uvn_io(struct uvm_vnode *uvn, vm_page_t *pps, int npages, int flags, int rw) result = vn_lock(vn, LK_EXCLUSIVE | LK_RECURSEFAIL, curproc); if (result == 0) { - int netlocked = (rw_status(&netlock) == RW_WRITE); - - /* - * This process may already have the NET_LOCK(), if we - * faulted in copyin() or copyout() in the network stack. - */ - if (netlocked) - NET_UNLOCK(); - /* NOTE: vnode now locked! */ if (rw == UIO_READ) result = VOP_READ(vn, &uio, 0, curproc->p_ucred); @@ -1195,13 +1196,15 @@ uvn_io(struct uvm_vnode *uvn, vm_page_t *pps, int npages, int flags, int rw) (flags & PGO_PDFREECLUST) ? IO_NOCACHE : 0, curproc->p_ucred); - if (netlocked) - NET_LOCK(); - if ((uvn->u_flags & UVM_VNODE_VNISLOCKED) == 0) VOP_UNLOCK(vn, curproc); + } + if (netunlocked) + NET_LOCK(); + + /* NOTE: vnode now unlocked (unless vnislocked) */ /* * result == unix style errno (0 == OK!) |