--- nlm/nlm_prot_impl.c.sav 2011-12-05 10:59:00.000000000 -0500 +++ nlm/nlm_prot_impl.c 2011-12-05 20:09:03.000000000 -0500 @@ -1774,7 +1774,7 @@ struct vfs_state { static int nlm_get_vfs_state(struct nlm_host *host, struct svc_req *rqstp, - fhandle_t *fhp, struct vfs_state *vs) + fhandle_t *fhp, struct vfs_state *vs, bool_t exclusive) { int error, exflags; struct ucred *cred = NULL, *credanon; @@ -1816,6 +1816,8 @@ nlm_get_vfs_state(struct nlm_host *host, * Check cred. */ error = VOP_ACCESS(vs->vs_vp, VWRITE, cred, curthread); + if (error != 0 && !exclusive) + error = VOP_ACCESS(vs->vs_vp, VREAD, cred, curthread); if (error) goto out; @@ -1896,7 +1898,7 @@ nlm_do_test(nlm4_testargs *argp, nlm4_te goto out; } - error = nlm_get_vfs_state(host, rqstp, &fh, &vs); + error = nlm_get_vfs_state(host, rqstp, &fh, &vs, argp->exclusive); if (error) { result->stat.stat = nlm_convert_error(error); goto out; @@ -2001,7 +2003,7 @@ nlm_do_lock(nlm4_lockargs *argp, nlm4_re goto out; } - error = nlm_get_vfs_state(host, rqstp, &fh, &vs); + error = nlm_get_vfs_state(host, rqstp, &fh, &vs, argp->exclusive); if (error) { result->stat.stat = nlm_convert_error(error); goto out; @@ -2180,7 +2182,7 @@ nlm_do_cancel(nlm4_cancargs *argp, nlm4_ goto out; } - error = nlm_get_vfs_state(host, rqstp, &fh, &vs); + error = nlm_get_vfs_state(host, rqstp, &fh, &vs, argp->exclusive); if (error) { result->stat.stat = nlm_convert_error(error); goto out; @@ -2269,7 +2271,11 @@ nlm_do_unlock(nlm4_unlockargs *argp, nlm goto out; } - error = nlm_get_vfs_state(host, rqstp, &fh, &vs); + /* + * Specify FALSE so that it will try the case where there is + * VREAD access, when VWRITE access is denied. + */ + error = nlm_get_vfs_state(host, rqstp, &fh, &vs, FALSE); if (error) { result->stat.stat = nlm_convert_error(error); goto out;