diff options
author | Andy Adamson <andros@netapp.com> | 2014-01-29 11:34:38 -0500 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2014-01-29 11:54:55 -0500 |
commit | f9c96fcc501a43dbc292b17fc0ded4b54e63b79d (patch) | |
tree | 50feb8393e5fa42095511a1417dbe56def085569 /fs/nfs | |
parent | 4db72b40fdbc706f8957e9773ae73b1574b8c694 (diff) |
NFSv4.1 free slot before resending I/O to MDS
Fix a dynamic session slot leak where a slot is preallocated and I/O is
resent through the MDS.
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/nfs4_fs.h | 1 | ||||
-rw-r--r-- | fs/nfs/nfs4filelayout.c | 10 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 3 |
3 files changed, 11 insertions, 3 deletions
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 5609edc742a0..a5b27c2d9689 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
@@ -270,6 +270,7 @@ static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *ser | |||
270 | extern int nfs41_setup_sequence(struct nfs4_session *session, | 270 | extern int nfs41_setup_sequence(struct nfs4_session *session, |
271 | struct nfs4_sequence_args *args, struct nfs4_sequence_res *res, | 271 | struct nfs4_sequence_args *args, struct nfs4_sequence_res *res, |
272 | struct rpc_task *task); | 272 | struct rpc_task *task); |
273 | extern int nfs41_sequence_done(struct rpc_task *, struct nfs4_sequence_res *); | ||
273 | extern int nfs4_proc_create_session(struct nfs_client *, struct rpc_cred *); | 274 | extern int nfs4_proc_create_session(struct nfs_client *, struct rpc_cred *); |
274 | extern int nfs4_proc_destroy_session(struct nfs4_session *, struct rpc_cred *); | 275 | extern int nfs4_proc_destroy_session(struct nfs4_session *, struct rpc_cred *); |
275 | extern int nfs4_proc_get_lease_time(struct nfs_client *clp, | 276 | extern int nfs4_proc_get_lease_time(struct nfs_client *clp, |
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c index 03fd8be8c0c5..20a56fa271bd 100644 --- a/fs/nfs/nfs4filelayout.c +++ b/fs/nfs/nfs4filelayout.c | |||
@@ -335,8 +335,11 @@ static void filelayout_read_call_done(struct rpc_task *task, void *data) | |||
335 | dprintk("--> %s task->tk_status %d\n", __func__, task->tk_status); | 335 | dprintk("--> %s task->tk_status %d\n", __func__, task->tk_status); |
336 | 336 | ||
337 | if (test_bit(NFS_IOHDR_REDO, &rdata->header->flags) && | 337 | if (test_bit(NFS_IOHDR_REDO, &rdata->header->flags) && |
338 | task->tk_status == 0) | 338 | task->tk_status == 0) { |
339 | if (rdata->res.seq_res.sr_slot != NULL) | ||
340 | nfs41_sequence_done(task, &rdata->res.seq_res); | ||
339 | return; | 341 | return; |
342 | } | ||
340 | 343 | ||
341 | /* Note this may cause RPC to be resent */ | 344 | /* Note this may cause RPC to be resent */ |
342 | rdata->header->mds_ops->rpc_call_done(task, data); | 345 | rdata->header->mds_ops->rpc_call_done(task, data); |
@@ -442,8 +445,11 @@ static void filelayout_write_call_done(struct rpc_task *task, void *data) | |||
442 | struct nfs_write_data *wdata = data; | 445 | struct nfs_write_data *wdata = data; |
443 | 446 | ||
444 | if (test_bit(NFS_IOHDR_REDO, &wdata->header->flags) && | 447 | if (test_bit(NFS_IOHDR_REDO, &wdata->header->flags) && |
445 | task->tk_status == 0) | 448 | task->tk_status == 0) { |
449 | if (wdata->res.seq_res.sr_slot != NULL) | ||
450 | nfs41_sequence_done(task, &wdata->res.seq_res); | ||
446 | return; | 451 | return; |
452 | } | ||
447 | 453 | ||
448 | /* Note this may cause RPC to be resent */ | 454 | /* Note this may cause RPC to be resent */ |
449 | wdata->header->mds_ops->rpc_call_done(task, data); | 455 | wdata->header->mds_ops->rpc_call_done(task, data); |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index ed10d0d4f860..ae00c3ed733f 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -592,7 +592,7 @@ out_unlock: | |||
592 | nfs41_server_notify_highest_slotid_update(session->clp); | 592 | nfs41_server_notify_highest_slotid_update(session->clp); |
593 | } | 593 | } |
594 | 594 | ||
595 | static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) | 595 | int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) |
596 | { | 596 | { |
597 | struct nfs4_session *session; | 597 | struct nfs4_session *session; |
598 | struct nfs4_slot *slot; | 598 | struct nfs4_slot *slot; |
@@ -692,6 +692,7 @@ out_retry: | |||
692 | rpc_delay(task, NFS4_POLL_RETRY_MAX); | 692 | rpc_delay(task, NFS4_POLL_RETRY_MAX); |
693 | return 0; | 693 | return 0; |
694 | } | 694 | } |
695 | EXPORT_SYMBOL_GPL(nfs41_sequence_done); | ||
695 | 696 | ||
696 | static int nfs4_sequence_done(struct rpc_task *task, | 697 | static int nfs4_sequence_done(struct rpc_task *task, |
697 | struct nfs4_sequence_res *res) | 698 | struct nfs4_sequence_res *res) |