aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2013-05-03 16:22:55 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-05-06 17:24:27 -0400
commitc8b2d0bfd3370a5e19e64ddb23f8bc1276410b6c (patch)
tree18a26f03ce32f7707d335c2b25187c6d61c91fda /fs/nfs
parent7c1d5fae4a87d3cf3e9ffd68bcdbaf6529013009 (diff)
NFSv4.1: Ensure that we free the lock stateid on the server
This ensures that the server doesn't need to keep huge numbers of lock stateids waiting around for the final CLOSE. See section 8.2.4 in RFC5661. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4_fs.h3
-rw-r--r--fs/nfs/nfs4proc.c17
-rw-r--r--fs/nfs/nfs4state.c11
3 files changed, 24 insertions, 7 deletions
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 553a83cc4106..a1dd768d0a35 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -47,6 +47,8 @@ struct nfs4_minor_version_ops {
47 const nfs4_stateid *); 47 const nfs4_stateid *);
48 int (*find_root_sec)(struct nfs_server *, struct nfs_fh *, 48 int (*find_root_sec)(struct nfs_server *, struct nfs_fh *,
49 struct nfs_fsinfo *); 49 struct nfs_fsinfo *);
50 int (*free_lock_state)(struct nfs_server *,
51 struct nfs4_lock_state *);
50 const struct nfs4_state_recovery_ops *reboot_recovery_ops; 52 const struct nfs4_state_recovery_ops *reboot_recovery_ops;
51 const struct nfs4_state_recovery_ops *nograce_recovery_ops; 53 const struct nfs4_state_recovery_ops *nograce_recovery_ops;
52 const struct nfs4_state_maintenance_ops *state_renewal_ops; 54 const struct nfs4_state_maintenance_ops *state_renewal_ops;
@@ -234,7 +236,6 @@ extern int nfs4_proc_fs_locations(struct rpc_clnt *, struct inode *, const struc
234extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *, struct qstr *, 236extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *, struct qstr *,
235 struct nfs_fh *, struct nfs_fattr *); 237 struct nfs_fh *, struct nfs_fattr *);
236extern int nfs4_proc_secinfo(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *); 238extern int nfs4_proc_secinfo(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *);
237extern int nfs4_release_lockowner(struct nfs4_lock_state *);
238extern const struct xattr_handler *nfs4_xattr_handlers[]; 239extern const struct xattr_handler *nfs4_xattr_handlers[];
239extern int nfs4_set_rw_stateid(nfs4_stateid *stateid, 240extern int nfs4_set_rw_stateid(nfs4_stateid *stateid,
240 const struct nfs_open_context *ctx, 241 const struct nfs_open_context *ctx,
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 1f3c6118c8ce..8fbc10054115 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5238,9 +5238,8 @@ static const struct rpc_call_ops nfs4_release_lockowner_ops = {
5238 .rpc_release = nfs4_release_lockowner_release, 5238 .rpc_release = nfs4_release_lockowner_release,
5239}; 5239};
5240 5240
5241int nfs4_release_lockowner(struct nfs4_lock_state *lsp) 5241static int nfs4_release_lockowner(struct nfs_server *server, struct nfs4_lock_state *lsp)
5242{ 5242{
5243 struct nfs_server *server = lsp->ls_state->owner->so_server;
5244 struct nfs_release_lockowner_data *data; 5243 struct nfs_release_lockowner_data *data;
5245 struct rpc_message msg = { 5244 struct rpc_message msg = {
5246 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RELEASE_LOCKOWNER], 5245 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RELEASE_LOCKOWNER],
@@ -6879,6 +6878,18 @@ static int nfs41_free_stateid(struct nfs_server *server, nfs4_stateid *stateid)
6879 return ret; 6878 return ret;
6880} 6879}
6881 6880
6881static int nfs41_free_lock_state(struct nfs_server *server, struct nfs4_lock_state *lsp)
6882{
6883 struct rpc_task *task;
6884
6885 task = _nfs41_free_stateid(server, &lsp->ls_stateid, false);
6886 nfs4_free_lock_state(server, lsp);
6887 if (IS_ERR(task))
6888 return PTR_ERR(task);
6889 rpc_put_task(task);
6890 return 0;
6891}
6892
6882static bool nfs41_match_stateid(const nfs4_stateid *s1, 6893static bool nfs41_match_stateid(const nfs4_stateid *s1,
6883 const nfs4_stateid *s2) 6894 const nfs4_stateid *s2)
6884{ 6895{
@@ -6968,6 +6979,7 @@ static const struct nfs4_minor_version_ops nfs_v4_0_minor_ops = {
6968 .call_sync = _nfs4_call_sync, 6979 .call_sync = _nfs4_call_sync,
6969 .match_stateid = nfs4_match_stateid, 6980 .match_stateid = nfs4_match_stateid,
6970 .find_root_sec = nfs4_find_root_sec, 6981 .find_root_sec = nfs4_find_root_sec,
6982 .free_lock_state = nfs4_release_lockowner,
6971 .reboot_recovery_ops = &nfs40_reboot_recovery_ops, 6983 .reboot_recovery_ops = &nfs40_reboot_recovery_ops,
6972 .nograce_recovery_ops = &nfs40_nograce_recovery_ops, 6984 .nograce_recovery_ops = &nfs40_nograce_recovery_ops,
6973 .state_renewal_ops = &nfs40_state_renewal_ops, 6985 .state_renewal_ops = &nfs40_state_renewal_ops,
@@ -6985,6 +6997,7 @@ static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = {
6985 .call_sync = nfs4_call_sync_sequence, 6997 .call_sync = nfs4_call_sync_sequence,
6986 .match_stateid = nfs41_match_stateid, 6998 .match_stateid = nfs41_match_stateid,
6987 .find_root_sec = nfs41_find_root_sec, 6999 .find_root_sec = nfs41_find_root_sec,
7000 .free_lock_state = nfs41_free_lock_state,
6988 .reboot_recovery_ops = &nfs41_reboot_recovery_ops, 7001 .reboot_recovery_ops = &nfs41_reboot_recovery_ops,
6989 .nograce_recovery_ops = &nfs41_nograce_recovery_ops, 7002 .nograce_recovery_ops = &nfs41_nograce_recovery_ops,
6990 .state_renewal_ops = &nfs41_state_renewal_ops, 7003 .state_renewal_ops = &nfs41_state_renewal_ops,
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 0b32f9483b7a..300d17d85c0e 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -921,6 +921,7 @@ static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_
921 */ 921 */
922void nfs4_put_lock_state(struct nfs4_lock_state *lsp) 922void nfs4_put_lock_state(struct nfs4_lock_state *lsp)
923{ 923{
924 struct nfs_server *server;
924 struct nfs4_state *state; 925 struct nfs4_state *state;
925 926
926 if (lsp == NULL) 927 if (lsp == NULL)
@@ -932,11 +933,13 @@ void nfs4_put_lock_state(struct nfs4_lock_state *lsp)
932 if (list_empty(&state->lock_states)) 933 if (list_empty(&state->lock_states))
933 clear_bit(LK_STATE_IN_USE, &state->flags); 934 clear_bit(LK_STATE_IN_USE, &state->flags);
934 spin_unlock(&state->state_lock); 935 spin_unlock(&state->state_lock);
936 server = state->owner->so_server;
935 if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags)) { 937 if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags)) {
936 if (nfs4_release_lockowner(lsp) == 0) 938 struct nfs_client *clp = server->nfs_client;
937 return; 939
938 } 940 clp->cl_mvops->free_lock_state(server, lsp);
939 nfs4_free_lock_state(lsp->ls_state->owner->so_server, lsp); 941 } else
942 nfs4_free_lock_state(server, lsp);
940} 943}
941 944
942static void nfs4_fl_copy_lock(struct file_lock *dst, struct file_lock *src) 945static void nfs4_fl_copy_lock(struct file_lock *dst, struct file_lock *src)