summaryrefslogtreecommitdiff
path: root/fs/nfsd/state.h
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2016-09-16 23:28:24 +0300
committerJ. Bruce Fields <bfields@redhat.com>2016-09-26 22:20:36 +0300
commit76d348fadff52e8ad10e7f587a4560df79a5fefe (patch)
tree24b7a65f5fac106041d8bed8459b2a9a5f64bc79 /fs/nfsd/state.h
parenta188620ebd294b18d8da93f4b2a307d484e7bd27 (diff)
downloadlinux-76d348fadff52e8ad10e7f587a4560df79a5fefe.tar.xz
nfsd: have nfsd4_lock use blocking locks for v4.1+ locks
Create a new per-lockowner+per-inode structure that contains a file_lock. Have nfsd4_lock add this structure to the lockowner's list prior to setting the lock. Then call the vfs and request a blocking lock (by setting FL_SLEEP). If we get anything besides FILE_LOCK_DEFERRED back, then we dequeue the block structure and free it. When the next lock request comes in, we'll look for an existing block for the same filehandle and dequeue and reuse it if there is one. When the lock comes free (a'la an lm_notify call), we dequeue it from the lockowner's list and kick off a CB_NOTIFY_LOCK callback to inform the client that it should retry the lock request. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/state.h')
-rw-r--r--fs/nfsd/state.h12
1 files changed, 9 insertions, 3 deletions
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index 88d029dd13aa..e45c183a8bf7 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -440,11 +440,11 @@ struct nfs4_openowner {
/*
* Represents a generic "lockowner". Similar to an openowner. References to it
* are held by the lock stateids that are created on its behalf. This object is
- * a superset of the nfs4_stateowner struct (or would be if it needed any extra
- * fields).
+ * a superset of the nfs4_stateowner struct.
*/
struct nfs4_lockowner {
- struct nfs4_stateowner lo_owner; /* must be first element */
+ struct nfs4_stateowner lo_owner; /* must be first element */
+ struct list_head lo_blocked; /* blocked file_locks */
};
static inline struct nfs4_openowner * openowner(struct nfs4_stateowner *so)
@@ -580,7 +580,13 @@ static inline bool nfsd4_stateid_generation_after(stateid_t *a, stateid_t *b)
return (s32)(a->si_generation - b->si_generation) > 0;
}
+/*
+ * When a client tries to get a lock on a file, we set one of these objects
+ * on the blocking lock. When the lock becomes free, we can then issue a
+ * CB_NOTIFY_LOCK to the server.
+ */
struct nfsd4_blocked_lock {
+ struct list_head nbl_list;
struct file_lock nbl_lock;
struct knfsd_fh nbl_fh;
struct nfsd4_callback nbl_cb;