aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2009-12-05 19:32:19 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2009-12-05 19:32:19 -0500
commitd61e612a728fb9bf848c4383f8f6645e822d5b57 (patch)
treeb4024efc797fa3b992b042f484574c1d43893a61 /fs/nfs
parentf26468fb9384e73fb357d2e84d3e9c88c7d1129d (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')
-rw-r--r--fs/nfs/internal.h17
-rw-r--r--fs/nfs/nfs4proc.c65
-rw-r--r--fs/nfs/read.c13
-rw-r--r--fs/nfs/unlink.c4
-rw-r--r--fs/nfs/write.c4
5 files changed, 21 insertions, 82 deletions
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 83a9284b83c7..b1a020c11724 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -197,8 +197,7 @@ extern const u32 nfs41_maxwrite_overhead;
197#endif 197#endif
198 198
199/* nfs4proc.c */ 199/* nfs4proc.c */
200extern void nfs4_restart_rpc(struct rpc_task *, const struct nfs_client *, 200extern void nfs4_restart_rpc(struct rpc_task *, const struct nfs_client *);
201 struct nfs4_sequence_res *);
202#ifdef CONFIG_NFS_V4 201#ifdef CONFIG_NFS_V4
203extern struct rpc_procinfo nfs4_procedures[]; 202extern struct rpc_procinfo nfs4_procedures[];
204#endif 203#endif
@@ -275,20 +274,6 @@ extern int _nfs4_call_sync_session(struct nfs_server *server,
275 struct nfs4_sequence_res *res, 274 struct nfs4_sequence_res *res,
276 int cache_reply); 275 int cache_reply);
277 276
278#ifdef CONFIG_NFS_V4_1
279extern void nfs41_sequence_free_slot(const struct nfs_client *,
280 struct nfs4_sequence_res *res);
281#endif /* CONFIG_NFS_V4_1 */
282
283static inline void nfs4_sequence_free_slot(const struct nfs_client *clp,
284 struct nfs4_sequence_res *res)
285{
286#ifdef CONFIG_NFS_V4_1
287 if (nfs4_has_session(clp))
288 nfs41_sequence_free_slot(clp, res);
289#endif /* CONFIG_NFS_V4_1 */
290}
291
292/* 277/*
293 * Determine the device name as a string 278 * Determine the device name as a string
294 */ 279 */
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
344void nfs41_sequence_free_slot(const struct nfs_client *clp, 344static 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 }
412out: 407out:
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
562struct rpc_call_ops nfs41_call_sync_ops = { 556struct 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
635void nfs4_restart_rpc(struct rpc_task *task, const struct nfs_client *clp, 629void 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 */
649static 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
657static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo) 640static 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
3778static void nfs4_locku_prepare(struct rpc_task *task, void *data) 3746static 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}
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 3e04fb9ea644..d319bfbe5137 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -356,26 +356,19 @@ static void nfs_readpage_retry(struct rpc_task *task, struct nfs_read_data *data
356 struct nfs_readres *resp = &data->res; 356 struct nfs_readres *resp = &data->res;
357 357
358 if (resp->eof || resp->count == argp->count) 358 if (resp->eof || resp->count == argp->count)
359 goto out; 359 return;
360 360
361 /* This is a short read! */ 361 /* This is a short read! */
362 nfs_inc_stats(data->inode, NFSIOS_SHORTREAD); 362 nfs_inc_stats(data->inode, NFSIOS_SHORTREAD);
363 /* Has the server at least made some progress? */ 363 /* Has the server at least made some progress? */
364 if (resp->count == 0) 364 if (resp->count == 0)
365 goto out; 365 return;
366 366
367 /* Yes, so retry the read at the end of the data */ 367 /* Yes, so retry the read at the end of the data */
368 argp->offset += resp->count; 368 argp->offset += resp->count;
369 argp->pgbase += resp->count; 369 argp->pgbase += resp->count;
370 argp->count -= resp->count; 370 argp->count -= resp->count;
371 nfs4_restart_rpc(task, NFS_SERVER(data->inode)->nfs_client, 371 nfs4_restart_rpc(task, NFS_SERVER(data->inode)->nfs_client);
372 &data->res.seq_res);
373 return;
374out:
375 nfs4_sequence_free_slot(NFS_SERVER(data->inode)->nfs_client,
376 &data->res.seq_res);
377 return;
378
379} 372}
380 373
381/* 374/*
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index 52f7bdb12c83..1064c91ae810 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -81,11 +81,9 @@ static void nfs_async_unlink_done(struct rpc_task *task, void *calldata)
81{ 81{
82 struct nfs_unlinkdata *data = calldata; 82 struct nfs_unlinkdata *data = calldata;
83 struct inode *dir = data->dir; 83 struct inode *dir = data->dir;
84 struct nfs_removeres *res = task->tk_msg.rpc_resp;
85 84
86 if (!NFS_PROTO(dir)->unlink_done(task, dir)) 85 if (!NFS_PROTO(dir)->unlink_done(task, dir))
87 nfs4_restart_rpc(task, NFS_SERVER(dir)->nfs_client, 86 nfs4_restart_rpc(task, NFS_SERVER(dir)->nfs_client);
88 &res->seq_res);
89} 87}
90 88
91/** 89/**
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 556668ff0224..d546c607de08 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1216,8 +1216,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1216 */ 1216 */
1217 argp->stable = NFS_FILE_SYNC; 1217 argp->stable = NFS_FILE_SYNC;
1218 } 1218 }
1219 nfs4_restart_rpc(task, server->nfs_client, 1219 nfs4_restart_rpc(task, server->nfs_client);
1220 &data->res.seq_res);
1221 return -EAGAIN; 1220 return -EAGAIN;
1222 } 1221 }
1223 if (time_before(complain, jiffies)) { 1222 if (time_before(complain, jiffies)) {
@@ -1229,7 +1228,6 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1229 /* Can't do anything about it except throw an error. */ 1228 /* Can't do anything about it except throw an error. */
1230 task->tk_status = -EIO; 1229 task->tk_status = -EIO;
1231 } 1230 }
1232 nfs4_sequence_free_slot(server->nfs_client, &data->res.seq_res);
1233 return 0; 1231 return 0;
1234} 1232}
1235 1233