Skip to content

Commit aa5190d

Browse files
Trond MyklebustTrond Myklebust
authored andcommitted
NFSv4: Kill nfs4_async_handle_error() abuses by NFSv4.1
Signed-off-by: Trond Myklebust <[email protected]>
1 parent d185a33 commit aa5190d

File tree

1 file changed

+41
-37
lines changed

1 file changed

+41
-37
lines changed

fs/nfs/nfs4proc.c

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3457,9 +3457,11 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen
34573457
}
34583458

34593459
static int
3460-
_nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, struct nfs_client *clp, struct nfs4_state *state)
3460+
nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, struct nfs4_state *state)
34613461
{
3462-
if (!clp || task->tk_status >= 0)
3462+
struct nfs_client *clp = server->nfs_client;
3463+
3464+
if (task->tk_status >= 0)
34633465
return 0;
34643466
switch(task->tk_status) {
34653467
case -NFS4ERR_ADMIN_REVOKED:
@@ -3491,8 +3493,7 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
34913493
return -EAGAIN;
34923494
#endif /* CONFIG_NFS_V4_1 */
34933495
case -NFS4ERR_DELAY:
3494-
if (server)
3495-
nfs_inc_server_stats(server, NFSIOS_DELAY);
3496+
nfs_inc_server_stats(server, NFSIOS_DELAY);
34963497
case -NFS4ERR_GRACE:
34973498
case -EKEYEXPIRED:
34983499
rpc_delay(task, NFS4_POLL_RETRY_MAX);
@@ -3513,12 +3514,6 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
35133514
return -EAGAIN;
35143515
}
35153516

3516-
static int
3517-
nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, struct nfs4_state *state)
3518-
{
3519-
return _nfs4_async_handle_error(task, server, server->nfs_client, state);
3520-
}
3521-
35223517
int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
35233518
unsigned short port, struct rpc_cred *cred,
35243519
struct nfs4_setclientid_res *res)
@@ -5088,6 +5083,19 @@ static void nfs41_sequence_release(void *data)
50885083
kfree(calldata);
50895084
}
50905085

5086+
static int nfs41_sequence_handle_errors(struct rpc_task *task, struct nfs_client *clp)
5087+
{
5088+
switch(task->tk_status) {
5089+
case -NFS4ERR_DELAY:
5090+
case -EKEYEXPIRED:
5091+
rpc_delay(task, NFS4_POLL_RETRY_MAX);
5092+
return -EAGAIN;
5093+
default:
5094+
nfs4_schedule_state_recovery(clp);
5095+
}
5096+
return 0;
5097+
}
5098+
50915099
static void nfs41_sequence_call_done(struct rpc_task *task, void *data)
50925100
{
50935101
struct nfs4_sequence_data *calldata = data;
@@ -5100,9 +5108,8 @@ static void nfs41_sequence_call_done(struct rpc_task *task, void *data)
51005108
if (atomic_read(&clp->cl_count) == 1)
51015109
goto out;
51025110

5103-
if (_nfs4_async_handle_error(task, NULL, clp, NULL)
5104-
== -EAGAIN) {
5105-
nfs_restart_rpc(task, clp);
5111+
if (nfs41_sequence_handle_errors(task, clp) == -EAGAIN) {
5112+
rpc_restart_call_prepare(task);
51065113
return;
51075114
}
51085115
}
@@ -5175,6 +5182,23 @@ static void nfs4_reclaim_complete_prepare(struct rpc_task *task, void *data)
51755182
rpc_call_start(task);
51765183
}
51775184

5185+
static int nfs41_reclaim_complete_handle_errors(struct rpc_task *task, struct nfs_client *clp)
5186+
{
5187+
switch(task->tk_status) {
5188+
case 0:
5189+
case -NFS4ERR_COMPLETE_ALREADY:
5190+
case -NFS4ERR_WRONG_CRED: /* What to do here? */
5191+
break;
5192+
case -NFS4ERR_DELAY:
5193+
case -EKEYEXPIRED:
5194+
rpc_delay(task, NFS4_POLL_RETRY_MAX);
5195+
return -EAGAIN;
5196+
default:
5197+
nfs4_schedule_state_recovery(clp);
5198+
}
5199+
return 0;
5200+
}
5201+
51785202
static void nfs4_reclaim_complete_done(struct rpc_task *task, void *data)
51795203
{
51805204
struct nfs4_reclaim_complete_data *calldata = data;
@@ -5183,31 +5207,11 @@ static void nfs4_reclaim_complete_done(struct rpc_task *task, void *data)
51835207

51845208
dprintk("--> %s\n", __func__);
51855209
nfs41_sequence_done(res);
5186-
switch (task->tk_status) {
5187-
case 0:
5188-
case -NFS4ERR_COMPLETE_ALREADY:
5189-
break;
5190-
case -NFS4ERR_BADSESSION:
5191-
case -NFS4ERR_DEADSESSION:
5192-
/*
5193-
* Handle the session error, but do not retry the operation, as
5194-
* we have no way of telling whether the clientid had to be
5195-
* reset before we got our reply. If reset, a new wave of
5196-
* reclaim operations will follow, containing their own reclaim
5197-
* complete. We don't want our retry to get on the way of
5198-
* recovery by incorrectly indicating to the server that we're
5199-
* done reclaiming state since the process had to be restarted.
5200-
*/
5201-
_nfs4_async_handle_error(task, NULL, clp, NULL);
5202-
break;
5203-
default:
5204-
if (_nfs4_async_handle_error(
5205-
task, NULL, clp, NULL) == -EAGAIN) {
5206-
rpc_restart_call_prepare(task);
5207-
return;
5208-
}
5209-
}
52105210

5211+
if (nfs41_reclaim_complete_handle_errors(task, clp) == -EAGAIN) {
5212+
rpc_restart_call_prepare(task);
5213+
return;
5214+
}
52115215
dprintk("<-- %s\n", __func__);
52125216
}
52135217

0 commit comments

Comments
 (0)