Commit cc77b152 authored by Miklos Szeredi's avatar Miklos Szeredi Committed by Linus Torvalds

lockd: dont return EAGAIN for a permanent error

Fix nlm_fopen() to return NLM_FAILED (or NLM_LCK_DENIED_NOLOCKS) instead
of NLM_LCK_DENIED.  The latter means the lock request failed because of a
conflicting lock (i.e.  a temporary error), which is wrong in this case.

Also fix the client to return ENOLCK instead of EAGAIN if a blocking lock
request returns with NLM_LOCK_DENIED.
Signed-off-by: default avatarMiklos Szeredi <mszeredi@suse.cz>
Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Matthew Wilcox <matthew@wil.cx>
Cc: David Teigland <teigland@redhat.com>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent b81f3ea9
...@@ -582,6 +582,14 @@ again: ...@@ -582,6 +582,14 @@ again:
} }
if (status < 0) if (status < 0)
goto out_unlock; goto out_unlock;
/*
* EAGAIN doesn't make sense for sleeping locks, and in some
* cases NLM_LCK_DENIED is returned for a permanent error. So
* turn it into an ENOLCK.
*/
if (resp->status == nlm_lck_denied && (fl_flags & FL_SLEEP))
status = -ENOLCK;
else
status = nlm_stat_to_errno(resp->status); status = nlm_stat_to_errno(resp->status);
out_unblock: out_unblock:
nlmclnt_finish_block(block); nlmclnt_finish_block(block);
......
...@@ -19,6 +19,13 @@ ...@@ -19,6 +19,13 @@
#define NFSDDBG_FACILITY NFSDDBG_LOCKD #define NFSDDBG_FACILITY NFSDDBG_LOCKD
#ifdef CONFIG_LOCKD_V4
#define nlm_stale_fh nlm4_stale_fh
#define nlm_failed nlm4_failed
#else
#define nlm_stale_fh nlm_lck_denied_nolocks
#define nlm_failed nlm_lck_denied_nolocks
#endif
/* /*
* Note: we hold the dentry use count while the file is open. * Note: we hold the dentry use count while the file is open.
*/ */
...@@ -47,12 +54,10 @@ nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp) ...@@ -47,12 +54,10 @@ nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp)
return 0; return 0;
case nfserr_dropit: case nfserr_dropit:
return nlm_drop_reply; return nlm_drop_reply;
#ifdef CONFIG_LOCKD_V4
case nfserr_stale: case nfserr_stale:
return nlm4_stale_fh; return nlm_stale_fh;
#endif
default: default:
return nlm_lck_denied; return nlm_failed;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment