diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-12-05 19:32:19 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-12-05 19:32:19 -0500 |
commit | d61e612a728fb9bf848c4383f8f6645e822d5b57 (patch) | |
tree | b4024efc797fa3b992b042f484574c1d43893a61 /fs/nfs/nfs4proc.c | |
parent | f26468fb9384e73fb357d2e84d3e9c88c7d1129d (diff) |
NFSv41: Clean up slot table management
We no longer need to maintain a distinction between nfs41_sequence_done and
nfs41_sequence_free_slot.
This fixes a number of slot table leakages in the NFSv4.1 code.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 65 |
1 files changed, 15 insertions, 50 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index be96d28baccf..c06a2bade59e 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -341,15 +341,11 @@ nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid) | |||
341 | free_slotid, tbl->highest_used_slotid); | 341 | free_slotid, tbl->highest_used_slotid); |
342 | } | 342 | } |
343 | 343 | ||
344 | void nfs41_sequence_free_slot(const struct nfs_client *clp, | 344 | static void nfs41_sequence_free_slot(const struct nfs_client *clp, |
345 | struct nfs4_sequence_res *res) | 345 | struct nfs4_sequence_res *res) |
346 | { | 346 | { |
347 | struct nfs4_slot_table *tbl; | 347 | struct nfs4_slot_table *tbl; |
348 | 348 | ||
349 | if (!nfs4_has_session(clp)) { | ||
350 | dprintk("%s: No session\n", __func__); | ||
351 | return; | ||
352 | } | ||
353 | tbl = &clp->cl_session->fc_slot_table; | 349 | tbl = &clp->cl_session->fc_slot_table; |
354 | if (res->sr_slotid == NFS4_MAX_SLOT_TABLE) { | 350 | if (res->sr_slotid == NFS4_MAX_SLOT_TABLE) { |
355 | /* just wake up the next guy waiting since | 351 | /* just wake up the next guy waiting since |
@@ -407,7 +403,6 @@ static void nfs41_sequence_done(struct nfs_client *clp, | |||
407 | spin_unlock(&clp->cl_lock); | 403 | spin_unlock(&clp->cl_lock); |
408 | /* Check sequence flags */ | 404 | /* Check sequence flags */ |
409 | nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags); | 405 | nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags); |
410 | return; | ||
411 | } | 406 | } |
412 | out: | 407 | out: |
413 | /* The session may be reset by one of the error handlers. */ | 408 | /* The session may be reset by one of the error handlers. */ |
@@ -556,7 +551,6 @@ static void nfs41_call_sync_done(struct rpc_task *task, void *calldata) | |||
556 | struct nfs41_call_sync_data *data = calldata; | 551 | struct nfs41_call_sync_data *data = calldata; |
557 | 552 | ||
558 | nfs41_sequence_done(data->clp, data->seq_res, task->tk_status); | 553 | nfs41_sequence_done(data->clp, data->seq_res, task->tk_status); |
559 | nfs41_sequence_free_slot(data->clp, data->seq_res); | ||
560 | } | 554 | } |
561 | 555 | ||
562 | struct rpc_call_ops nfs41_call_sync_ops = { | 556 | struct rpc_call_ops nfs41_call_sync_ops = { |
@@ -632,12 +626,10 @@ static void nfs4_sequence_done(const struct nfs_server *server, | |||
632 | #endif /* CONFIG_NFS_V4_1 */ | 626 | #endif /* CONFIG_NFS_V4_1 */ |
633 | } | 627 | } |
634 | 628 | ||
635 | void nfs4_restart_rpc(struct rpc_task *task, const struct nfs_client *clp, | 629 | void nfs4_restart_rpc(struct rpc_task *task, const struct nfs_client *clp) |
636 | struct nfs4_sequence_res *res) | ||
637 | { | 630 | { |
638 | #ifdef CONFIG_NFS_V4_1 | 631 | #ifdef CONFIG_NFS_V4_1 |
639 | if (nfs4_has_session(clp)) { | 632 | if (nfs4_has_session(clp)) { |
640 | nfs41_sequence_free_slot(clp, res); | ||
641 | rpc_restart_call_prepare(task); | 633 | rpc_restart_call_prepare(task); |
642 | return; | 634 | return; |
643 | } | 635 | } |
@@ -645,15 +637,6 @@ void nfs4_restart_rpc(struct rpc_task *task, const struct nfs_client *clp, | |||
645 | rpc_restart_call(task); | 637 | rpc_restart_call(task); |
646 | } | 638 | } |
647 | 639 | ||
648 | /* no restart, therefore free slot here */ | ||
649 | static void nfs4_sequence_done_free_slot(const struct nfs_server *server, | ||
650 | struct nfs4_sequence_res *res, | ||
651 | int rpc_status) | ||
652 | { | ||
653 | nfs4_sequence_done(server, res, rpc_status); | ||
654 | nfs4_sequence_free_slot(server->nfs_client, res); | ||
655 | } | ||
656 | |||
657 | static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo) | 640 | static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo) |
658 | { | 641 | { |
659 | struct nfs_inode *nfsi = NFS_I(dir); | 642 | struct nfs_inode *nfsi = NFS_I(dir); |
@@ -1350,8 +1333,8 @@ static void nfs4_open_done(struct rpc_task *task, void *calldata) | |||
1350 | 1333 | ||
1351 | data->rpc_status = task->tk_status; | 1334 | data->rpc_status = task->tk_status; |
1352 | 1335 | ||
1353 | nfs4_sequence_done_free_slot(data->o_arg.server, &data->o_res.seq_res, | 1336 | nfs4_sequence_done(data->o_arg.server, &data->o_res.seq_res, |
1354 | task->tk_status); | 1337 | task->tk_status); |
1355 | 1338 | ||
1356 | if (RPC_ASSASSINATED(task)) | 1339 | if (RPC_ASSASSINATED(task)) |
1357 | return; | 1340 | return; |
@@ -1757,12 +1740,10 @@ static void nfs4_close_done(struct rpc_task *task, void *data) | |||
1757 | break; | 1740 | break; |
1758 | default: | 1741 | default: |
1759 | if (nfs4_async_handle_error(task, server, state) == -EAGAIN) { | 1742 | if (nfs4_async_handle_error(task, server, state) == -EAGAIN) { |
1760 | nfs4_restart_rpc(task, server->nfs_client, | 1743 | nfs4_restart_rpc(task, server->nfs_client); |
1761 | &calldata->res.seq_res); | ||
1762 | return; | 1744 | return; |
1763 | } | 1745 | } |
1764 | } | 1746 | } |
1765 | nfs4_sequence_free_slot(server->nfs_client, &calldata->res.seq_res); | ||
1766 | nfs_refresh_inode(calldata->inode, calldata->res.fattr); | 1747 | nfs_refresh_inode(calldata->inode, calldata->res.fattr); |
1767 | } | 1748 | } |
1768 | 1749 | ||
@@ -2553,7 +2534,6 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir) | |||
2553 | nfs4_sequence_done(res->server, &res->seq_res, task->tk_status); | 2534 | nfs4_sequence_done(res->server, &res->seq_res, task->tk_status); |
2554 | if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN) | 2535 | if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN) |
2555 | return 0; | 2536 | return 0; |
2556 | nfs4_sequence_free_slot(res->server->nfs_client, &res->seq_res); | ||
2557 | update_changeattr(dir, &res->cinfo); | 2537 | update_changeattr(dir, &res->cinfo); |
2558 | nfs_post_op_update_inode(dir, &res->dir_attr); | 2538 | nfs_post_op_update_inode(dir, &res->dir_attr); |
2559 | return 1; | 2539 | return 1; |
@@ -2992,20 +2972,16 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data) | |||
2992 | 2972 | ||
2993 | dprintk("--> %s\n", __func__); | 2973 | dprintk("--> %s\n", __func__); |
2994 | 2974 | ||
2995 | /* nfs4_sequence_free_slot called in the read rpc_call_done */ | ||
2996 | nfs4_sequence_done(server, &data->res.seq_res, task->tk_status); | 2975 | nfs4_sequence_done(server, &data->res.seq_res, task->tk_status); |
2997 | 2976 | ||
2998 | if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) { | 2977 | if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) { |
2999 | nfs4_restart_rpc(task, server->nfs_client, &data->res.seq_res); | 2978 | nfs4_restart_rpc(task, server->nfs_client); |
3000 | return -EAGAIN; | 2979 | return -EAGAIN; |
3001 | } | 2980 | } |
3002 | 2981 | ||
3003 | nfs_invalidate_atime(data->inode); | 2982 | nfs_invalidate_atime(data->inode); |
3004 | if (task->tk_status > 0) | 2983 | if (task->tk_status > 0) |
3005 | renew_lease(server, data->timestamp); | 2984 | renew_lease(server, data->timestamp); |
3006 | else if (task->tk_status < 0) | ||
3007 | nfs4_sequence_free_slot(server->nfs_client, &data->res.seq_res); | ||
3008 | |||
3009 | return 0; | 2985 | return 0; |
3010 | } | 2986 | } |
3011 | 2987 | ||
@@ -3019,13 +2995,11 @@ static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data) | |||
3019 | { | 2995 | { |
3020 | struct inode *inode = data->inode; | 2996 | struct inode *inode = data->inode; |
3021 | 2997 | ||
3022 | /* slot is freed in nfs_writeback_done */ | ||
3023 | nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res, | 2998 | nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res, |
3024 | task->tk_status); | 2999 | task->tk_status); |
3025 | 3000 | ||
3026 | if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) { | 3001 | if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) { |
3027 | nfs4_restart_rpc(task, NFS_SERVER(inode)->nfs_client, | 3002 | nfs4_restart_rpc(task, NFS_SERVER(inode)->nfs_client); |
3028 | &data->res.seq_res); | ||
3029 | return -EAGAIN; | 3003 | return -EAGAIN; |
3030 | } | 3004 | } |
3031 | if (task->tk_status >= 0) { | 3005 | if (task->tk_status >= 0) { |
@@ -3053,12 +3027,9 @@ static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data) | |||
3053 | nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res, | 3027 | nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res, |
3054 | task->tk_status); | 3028 | task->tk_status); |
3055 | if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) { | 3029 | if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) { |
3056 | nfs4_restart_rpc(task, NFS_SERVER(inode)->nfs_client, | 3030 | nfs4_restart_rpc(task, NFS_SERVER(inode)->nfs_client); |
3057 | &data->res.seq_res); | ||
3058 | return -EAGAIN; | 3031 | return -EAGAIN; |
3059 | } | 3032 | } |
3060 | nfs4_sequence_free_slot(NFS_SERVER(inode)->nfs_client, | ||
3061 | &data->res.seq_res); | ||
3062 | nfs_refresh_inode(inode, data->res.fattr); | 3033 | nfs_refresh_inode(inode, data->res.fattr); |
3063 | return 0; | 3034 | return 0; |
3064 | } | 3035 | } |
@@ -3509,8 +3480,8 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata) | |||
3509 | { | 3480 | { |
3510 | struct nfs4_delegreturndata *data = calldata; | 3481 | struct nfs4_delegreturndata *data = calldata; |
3511 | 3482 | ||
3512 | nfs4_sequence_done_free_slot(data->res.server, &data->res.seq_res, | 3483 | nfs4_sequence_done(data->res.server, &data->res.seq_res, |
3513 | task->tk_status); | 3484 | task->tk_status); |
3514 | 3485 | ||
3515 | data->rpc_status = task->tk_status; | 3486 | data->rpc_status = task->tk_status; |
3516 | if (data->rpc_status == 0) | 3487 | if (data->rpc_status == 0) |
@@ -3768,11 +3739,8 @@ static void nfs4_locku_done(struct rpc_task *task, void *data) | |||
3768 | default: | 3739 | default: |
3769 | if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN) | 3740 | if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN) |
3770 | nfs4_restart_rpc(task, | 3741 | nfs4_restart_rpc(task, |
3771 | calldata->server->nfs_client, | 3742 | calldata->server->nfs_client); |
3772 | &calldata->res.seq_res); | ||
3773 | } | 3743 | } |
3774 | nfs4_sequence_free_slot(calldata->server->nfs_client, | ||
3775 | &calldata->res.seq_res); | ||
3776 | } | 3744 | } |
3777 | 3745 | ||
3778 | static void nfs4_locku_prepare(struct rpc_task *task, void *data) | 3746 | static void nfs4_locku_prepare(struct rpc_task *task, void *data) |
@@ -3954,8 +3922,8 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata) | |||
3954 | 3922 | ||
3955 | dprintk("%s: begin!\n", __func__); | 3923 | dprintk("%s: begin!\n", __func__); |
3956 | 3924 | ||
3957 | nfs4_sequence_done_free_slot(data->server, &data->res.seq_res, | 3925 | nfs4_sequence_done(data->server, &data->res.seq_res, |
3958 | task->tk_status); | 3926 | task->tk_status); |
3959 | 3927 | ||
3960 | data->rpc_status = task->tk_status; | 3928 | data->rpc_status = task->tk_status; |
3961 | if (RPC_ASSASSINATED(task)) | 3929 | if (RPC_ASSASSINATED(task)) |
@@ -4425,10 +4393,9 @@ static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata) | |||
4425 | dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status); | 4393 | dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status); |
4426 | rpc_delay(task, NFS4_POLL_RETRY_MIN); | 4394 | rpc_delay(task, NFS4_POLL_RETRY_MIN); |
4427 | task->tk_status = 0; | 4395 | task->tk_status = 0; |
4428 | rpc_restart_call(task); | 4396 | nfs4_restart_rpc(task, data->clp); |
4429 | return; | 4397 | return; |
4430 | } | 4398 | } |
4431 | nfs41_sequence_free_slot(data->clp, &data->res->lr_seq_res); | ||
4432 | dprintk("<-- %s\n", __func__); | 4399 | dprintk("<-- %s\n", __func__); |
4433 | } | 4400 | } |
4434 | 4401 | ||
@@ -4900,11 +4867,10 @@ void nfs41_sequence_call_done(struct rpc_task *task, void *data) | |||
4900 | 4867 | ||
4901 | if (_nfs4_async_handle_error(task, NULL, clp, NULL) | 4868 | if (_nfs4_async_handle_error(task, NULL, clp, NULL) |
4902 | == -EAGAIN) { | 4869 | == -EAGAIN) { |
4903 | nfs4_restart_rpc(task, clp, task->tk_msg.rpc_resp); | 4870 | nfs4_restart_rpc(task, clp); |
4904 | return; | 4871 | return; |
4905 | } | 4872 | } |
4906 | } | 4873 | } |
4907 | nfs41_sequence_free_slot(clp, task->tk_msg.rpc_resp); | ||
4908 | dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred); | 4874 | dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred); |
4909 | 4875 | ||
4910 | kfree(task->tk_msg.rpc_argp); | 4876 | kfree(task->tk_msg.rpc_argp); |
@@ -5008,7 +4974,6 @@ static void nfs4_reclaim_complete_done(struct rpc_task *task, void *data) | |||
5008 | return; | 4974 | return; |
5009 | } | 4975 | } |
5010 | } | 4976 | } |
5011 | nfs41_sequence_free_slot(clp, res); | ||
5012 | 4977 | ||
5013 | dprintk("<-- %s\n", __func__); | 4978 | dprintk("<-- %s\n", __func__); |
5014 | } | 4979 | } |