diff options
Diffstat (limited to 'sys/nfsclient')
-rw-r--r-- | sys/nfsclient/nfs_lock.c | 26 | ||||
-rw-r--r-- | sys/nfsclient/nfs_vnops.c | 42 | ||||
-rw-r--r-- | sys/nfsclient/nfsnode.h | 1 |
3 files changed, 41 insertions, 28 deletions
diff --git a/sys/nfsclient/nfs_lock.c b/sys/nfsclient/nfs_lock.c index bdb20d8..bf52706 100644 --- a/sys/nfsclient/nfs_lock.c +++ b/sys/nfsclient/nfs_lock.c @@ -226,6 +226,9 @@ MODULE_VERSION(nfslock, 1); /* * nfs_advlock -- * NFS advisory byte-level locks. + * + * The vnode shall be (shared) locked on the entry, it is + * unconditionally unlocked after. */ int nfs_dolock(struct vop_advlock_args *ap) @@ -243,6 +246,15 @@ nfs_dolock(struct vop_advlock_args *ap) vp = ap->a_vp; fl = ap->a_fl; + ASSERT_VOP_LOCKED(vp, "nfs_dolock"); + + bcopy(VFSTONFS(vp->v_mount)->nm_nam, &msg.lm_addr, + min(sizeof msg.lm_addr, VFSTONFS(vp->v_mount)->nm_nam->sa_len)); + msg.lm_fh_len = NFS_ISV3(vp) ? VTONFS(vp)->n_fhsize : NFSX_V2FH; + bcopy(VTONFS(vp)->n_fhp, msg.lm_fh, msg.lm_fh_len); + msg.lm_nfsv3 = NFS_ISV3(vp); + VOP_UNLOCK(vp, 0); + /* * the NLM protocol doesn't allow the server to return an error * on ranges, so we do it. @@ -263,6 +275,8 @@ nfs_dolock(struct vop_advlock_args *ap) */ msg.lm_version = LOCKD_MSG_VERSION; msg.lm_msg_ident.pid = p->p_pid; + + mtx_lock(&Giant); /* * if there is no nfsowner table yet, allocate one. */ @@ -278,21 +292,16 @@ nfs_dolock(struct vop_advlock_args *ap) msg.lm_fl = *fl; msg.lm_wait = ap->a_flags & F_WAIT; msg.lm_getlk = ap->a_op == F_GETLK; - bcopy(VFSTONFS(vp->v_mount)->nm_nam, &msg.lm_addr, - min(sizeof msg.lm_addr, VFSTONFS(vp->v_mount)->nm_nam->sa_len)); - msg.lm_fh_len = NFS_ISV3(vp) ? VTONFS(vp)->n_fhsize : NFSX_V2FH; - bcopy(VTONFS(vp)->n_fhp, msg.lm_fh, msg.lm_fh_len); - msg.lm_nfsv3 = NFS_ISV3(vp); cru2x(td->td_ucred, &msg.lm_cred); for (;;) { error = nfslock_send(&msg); if (error) - return (error); + goto out; /* Unlocks succeed immediately. */ if (fl->l_type == F_UNLCK) - return (error); + goto out; /* * Retry after 20 seconds if we haven't gotten a response yet. @@ -333,7 +342,8 @@ nfs_dolock(struct vop_advlock_args *ap) error = p->p_nlminfo->retcode; break; } - + out: + mtx_unlock(&Giant); return (error); } diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index 14a50c1..8b4b1e1 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -3038,18 +3038,19 @@ done: static int nfs_advlock(struct vop_advlock_args *ap) { + struct vnode *vp = ap->a_vp; + u_quad_t size; int error; - - mtx_lock(&Giant); - if ((VFSTONFS(ap->a_vp->v_mount)->nm_flag & NFSMNT_NOLOCKD) != 0) { - struct nfsnode *np = VTONFS(ap->a_vp); - error = lf_advlock(ap, &(np->n_lockf), np->n_size); - goto out; - } - error = nfs_dolock(ap); -out: - mtx_unlock(&Giant); + error = vn_lock(vp, LK_SHARED); + if (error) + return (error); + if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NOLOCKD) != 0) { + size = VTONFS(vp)->n_size; + VOP_UNLOCK(vp, 0); + error = lf_advlock(ap, &(vp->v_lockf), size); + } else + error = nfs_dolock(ap); return (error); } @@ -3059,18 +3060,21 @@ out: static int nfs_advlockasync(struct vop_advlockasync_args *ap) { + struct vnode *vp = ap->a_vp; + u_quad_t size; int error; - mtx_lock(&Giant); - if ((VFSTONFS(ap->a_vp->v_mount)->nm_flag & NFSMNT_NOLOCKD) != 0) { - struct nfsnode *np = VTONFS(ap->a_vp); - - error = lf_advlockasync(ap, &(np->n_lockf), np->n_size); - goto out; + error = vn_lock(vp, LK_SHARED); + if (error) + return (error); + if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NOLOCKD) != 0) { + size = VTONFS(vp)->n_size; + VOP_UNLOCK(vp, 0); + error = lf_advlockasync(ap, &(vp->v_lockf), size); + } else { + VOP_UNLOCK(vp, 0); + error = EOPNOTSUPP; } - error = EOPNOTSUPP; -out: - mtx_unlock(&Giant); return (error); } diff --git a/sys/nfsclient/nfsnode.h b/sys/nfsclient/nfsnode.h index 7f05fa4..f227361 100644 --- a/sys/nfsclient/nfsnode.h +++ b/sys/nfsclient/nfsnode.h @@ -113,7 +113,6 @@ struct nfsnode { nfsfh_t *n_fhp; /* NFS File Handle */ struct vnode *n_vnode; /* associated vnode */ struct vnode *n_dvp; /* parent vnode */ - struct lockf *n_lockf; /* Locking record of file */ int n_error; /* Save write error value */ union { struct timespec nf_atim; /* Special file times */ |