aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c91
1 files changed, 52 insertions, 39 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 1ff76acc7e9..0a07e353a96 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -51,7 +51,6 @@
51#include <linux/sunrpc/bc_xprt.h> 51#include <linux/sunrpc/bc_xprt.h>
52#include <linux/xattr.h> 52#include <linux/xattr.h>
53#include <linux/utsname.h> 53#include <linux/utsname.h>
54#include <linux/mm.h>
55 54
56#include "nfs4_fs.h" 55#include "nfs4_fs.h"
57#include "delegation.h" 56#include "delegation.h"
@@ -257,12 +256,13 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
257 case -NFS4ERR_OPENMODE: 256 case -NFS4ERR_OPENMODE:
258 if (state == NULL) 257 if (state == NULL)
259 break; 258 break;
260 nfs4_state_mark_reclaim_nograce(clp, state); 259 nfs4_schedule_stateid_recovery(server, state);
261 goto do_state_recovery; 260 goto wait_on_recovery;
262 case -NFS4ERR_STALE_STATEID: 261 case -NFS4ERR_STALE_STATEID:
263 case -NFS4ERR_STALE_CLIENTID: 262 case -NFS4ERR_STALE_CLIENTID:
264 case -NFS4ERR_EXPIRED: 263 case -NFS4ERR_EXPIRED:
265 goto do_state_recovery; 264 nfs4_schedule_lease_recovery(clp);
265 goto wait_on_recovery;
266#if defined(CONFIG_NFS_V4_1) 266#if defined(CONFIG_NFS_V4_1)
267 case -NFS4ERR_BADSESSION: 267 case -NFS4ERR_BADSESSION:
268 case -NFS4ERR_BADSLOT: 268 case -NFS4ERR_BADSLOT:
@@ -273,7 +273,7 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
273 case -NFS4ERR_SEQ_MISORDERED: 273 case -NFS4ERR_SEQ_MISORDERED:
274 dprintk("%s ERROR: %d Reset session\n", __func__, 274 dprintk("%s ERROR: %d Reset session\n", __func__,
275 errorcode); 275 errorcode);
276 nfs4_schedule_state_recovery(clp); 276 nfs4_schedule_session_recovery(clp->cl_session);
277 exception->retry = 1; 277 exception->retry = 1;
278 break; 278 break;
279#endif /* defined(CONFIG_NFS_V4_1) */ 279#endif /* defined(CONFIG_NFS_V4_1) */
@@ -296,8 +296,7 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
296 } 296 }
297 /* We failed to handle the error */ 297 /* We failed to handle the error */
298 return nfs4_map_errors(ret); 298 return nfs4_map_errors(ret);
299do_state_recovery: 299wait_on_recovery:
300 nfs4_schedule_state_recovery(clp);
301 ret = nfs4_wait_clnt_recover(clp); 300 ret = nfs4_wait_clnt_recover(clp);
302 if (ret == 0) 301 if (ret == 0)
303 exception->retry = 1; 302 exception->retry = 1;
@@ -436,8 +435,8 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *
436 clp = res->sr_session->clp; 435 clp = res->sr_session->clp;
437 do_renew_lease(clp, timestamp); 436 do_renew_lease(clp, timestamp);
438 /* Check sequence flags */ 437 /* Check sequence flags */
439 if (atomic_read(&clp->cl_count) > 1) 438 if (res->sr_status_flags != 0)
440 nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags); 439 nfs4_schedule_lease_recovery(clp);
441 break; 440 break;
442 case -NFS4ERR_DELAY: 441 case -NFS4ERR_DELAY:
443 /* The server detected a resend of the RPC call and 442 /* The server detected a resend of the RPC call and
@@ -1256,14 +1255,13 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state
1256 case -NFS4ERR_BAD_HIGH_SLOT: 1255 case -NFS4ERR_BAD_HIGH_SLOT:
1257 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: 1256 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
1258 case -NFS4ERR_DEADSESSION: 1257 case -NFS4ERR_DEADSESSION:
1259 nfs4_schedule_state_recovery( 1258 nfs4_schedule_session_recovery(server->nfs_client->cl_session);
1260 server->nfs_client);
1261 goto out; 1259 goto out;
1262 case -NFS4ERR_STALE_CLIENTID: 1260 case -NFS4ERR_STALE_CLIENTID:
1263 case -NFS4ERR_STALE_STATEID: 1261 case -NFS4ERR_STALE_STATEID:
1264 case -NFS4ERR_EXPIRED: 1262 case -NFS4ERR_EXPIRED:
1265 /* Don't recall a delegation if it was lost */ 1263 /* Don't recall a delegation if it was lost */
1266 nfs4_schedule_state_recovery(server->nfs_client); 1264 nfs4_schedule_lease_recovery(server->nfs_client);
1267 goto out; 1265 goto out;
1268 case -ERESTARTSYS: 1266 case -ERESTARTSYS:
1269 /* 1267 /*
@@ -1272,7 +1270,7 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state
1272 */ 1270 */
1273 case -NFS4ERR_ADMIN_REVOKED: 1271 case -NFS4ERR_ADMIN_REVOKED:
1274 case -NFS4ERR_BAD_STATEID: 1272 case -NFS4ERR_BAD_STATEID:
1275 nfs4_state_mark_reclaim_nograce(server->nfs_client, state); 1273 nfs4_schedule_stateid_recovery(server, state);
1276 case -EKEYEXPIRED: 1274 case -EKEYEXPIRED:
1277 /* 1275 /*
1278 * User RPCSEC_GSS context has expired. 1276 * User RPCSEC_GSS context has expired.
@@ -1588,7 +1586,7 @@ static int nfs4_recover_expired_lease(struct nfs_server *server)
1588 if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) && 1586 if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) &&
1589 !test_bit(NFS4CLNT_CHECK_LEASE,&clp->cl_state)) 1587 !test_bit(NFS4CLNT_CHECK_LEASE,&clp->cl_state))
1590 break; 1588 break;
1591 nfs4_schedule_state_recovery(clp); 1589 nfs4_schedule_state_manager(clp);
1592 ret = -EIO; 1590 ret = -EIO;
1593 } 1591 }
1594 return ret; 1592 return ret;
@@ -3179,7 +3177,7 @@ static void nfs4_renew_done(struct rpc_task *task, void *calldata)
3179 if (task->tk_status < 0) { 3177 if (task->tk_status < 0) {
3180 /* Unless we're shutting down, schedule state recovery! */ 3178 /* Unless we're shutting down, schedule state recovery! */
3181 if (test_bit(NFS_CS_RENEWD, &clp->cl_res_state) != 0) 3179 if (test_bit(NFS_CS_RENEWD, &clp->cl_res_state) != 0)
3182 nfs4_schedule_state_recovery(clp); 3180 nfs4_schedule_lease_recovery(clp);
3183 return; 3181 return;
3184 } 3182 }
3185 do_renew_lease(clp, timestamp); 3183 do_renew_lease(clp, timestamp);
@@ -3262,7 +3260,7 @@ static int buf_to_pages_noslab(const void *buf, size_t buflen,
3262 spages = pages; 3260 spages = pages;
3263 3261
3264 do { 3262 do {
3265 len = min(PAGE_CACHE_SIZE, buflen); 3263 len = min_t(size_t, PAGE_CACHE_SIZE, buflen);
3266 newpage = alloc_page(GFP_KERNEL); 3264 newpage = alloc_page(GFP_KERNEL);
3267 3265
3268 if (newpage == NULL) 3266 if (newpage == NULL)
@@ -3504,12 +3502,13 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
3504 case -NFS4ERR_OPENMODE: 3502 case -NFS4ERR_OPENMODE:
3505 if (state == NULL) 3503 if (state == NULL)
3506 break; 3504 break;
3507 nfs4_state_mark_reclaim_nograce(clp, state); 3505 nfs4_schedule_stateid_recovery(server, state);
3508 goto do_state_recovery; 3506 goto wait_on_recovery;
3509 case -NFS4ERR_STALE_STATEID: 3507 case -NFS4ERR_STALE_STATEID:
3510 case -NFS4ERR_STALE_CLIENTID: 3508 case -NFS4ERR_STALE_CLIENTID:
3511 case -NFS4ERR_EXPIRED: 3509 case -NFS4ERR_EXPIRED:
3512 goto do_state_recovery; 3510 nfs4_schedule_lease_recovery(clp);
3511 goto wait_on_recovery;
3513#if defined(CONFIG_NFS_V4_1) 3512#if defined(CONFIG_NFS_V4_1)
3514 case -NFS4ERR_BADSESSION: 3513 case -NFS4ERR_BADSESSION:
3515 case -NFS4ERR_BADSLOT: 3514 case -NFS4ERR_BADSLOT:
@@ -3520,7 +3519,7 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
3520 case -NFS4ERR_SEQ_MISORDERED: 3519 case -NFS4ERR_SEQ_MISORDERED:
3521 dprintk("%s ERROR %d, Reset session\n", __func__, 3520 dprintk("%s ERROR %d, Reset session\n", __func__,
3522 task->tk_status); 3521 task->tk_status);
3523 nfs4_schedule_state_recovery(clp); 3522 nfs4_schedule_session_recovery(clp->cl_session);
3524 task->tk_status = 0; 3523 task->tk_status = 0;
3525 return -EAGAIN; 3524 return -EAGAIN;
3526#endif /* CONFIG_NFS_V4_1 */ 3525#endif /* CONFIG_NFS_V4_1 */
@@ -3537,9 +3536,8 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
3537 } 3536 }
3538 task->tk_status = nfs4_map_errors(task->tk_status); 3537 task->tk_status = nfs4_map_errors(task->tk_status);
3539 return 0; 3538 return 0;
3540do_state_recovery: 3539wait_on_recovery:
3541 rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); 3540 rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);
3542 nfs4_schedule_state_recovery(clp);
3543 if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0) 3541 if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)
3544 rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task); 3542 rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
3545 task->tk_status = 0; 3543 task->tk_status = 0;
@@ -4150,7 +4148,7 @@ static void nfs4_lock_release(void *calldata)
4150 task = nfs4_do_unlck(&data->fl, data->ctx, data->lsp, 4148 task = nfs4_do_unlck(&data->fl, data->ctx, data->lsp,
4151 data->arg.lock_seqid); 4149 data->arg.lock_seqid);
4152 if (!IS_ERR(task)) 4150 if (!IS_ERR(task))
4153 rpc_put_task(task); 4151 rpc_put_task_async(task);
4154 dprintk("%s: cancelling lock!\n", __func__); 4152 dprintk("%s: cancelling lock!\n", __func__);
4155 } else 4153 } else
4156 nfs_free_seqid(data->arg.lock_seqid); 4154 nfs_free_seqid(data->arg.lock_seqid);
@@ -4174,23 +4172,18 @@ static const struct rpc_call_ops nfs4_recover_lock_ops = {
4174 4172
4175static void nfs4_handle_setlk_error(struct nfs_server *server, struct nfs4_lock_state *lsp, int new_lock_owner, int error) 4173static void nfs4_handle_setlk_error(struct nfs_server *server, struct nfs4_lock_state *lsp, int new_lock_owner, int error)
4176{ 4174{
4177 struct nfs_client *clp = server->nfs_client;
4178 struct nfs4_state *state = lsp->ls_state;
4179
4180 switch (error) { 4175 switch (error) {
4181 case -NFS4ERR_ADMIN_REVOKED: 4176 case -NFS4ERR_ADMIN_REVOKED:
4182 case -NFS4ERR_BAD_STATEID: 4177 case -NFS4ERR_BAD_STATEID:
4183 case -NFS4ERR_EXPIRED: 4178 lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED;
4184 if (new_lock_owner != 0 || 4179 if (new_lock_owner != 0 ||
4185 (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) 4180 (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0)
4186 nfs4_state_mark_reclaim_nograce(clp, state); 4181 nfs4_schedule_stateid_recovery(server, lsp->ls_state);
4187 lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED;
4188 break; 4182 break;
4189 case -NFS4ERR_STALE_STATEID: 4183 case -NFS4ERR_STALE_STATEID:
4190 if (new_lock_owner != 0 ||
4191 (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0)
4192 nfs4_state_mark_reclaim_reboot(clp, state);
4193 lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED; 4184 lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED;
4185 case -NFS4ERR_EXPIRED:
4186 nfs4_schedule_lease_recovery(server->nfs_client);
4194 }; 4187 };
4195} 4188}
4196 4189
@@ -4406,12 +4399,14 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
4406 case -NFS4ERR_EXPIRED: 4399 case -NFS4ERR_EXPIRED:
4407 case -NFS4ERR_STALE_CLIENTID: 4400 case -NFS4ERR_STALE_CLIENTID:
4408 case -NFS4ERR_STALE_STATEID: 4401 case -NFS4ERR_STALE_STATEID:
4402 nfs4_schedule_lease_recovery(server->nfs_client);
4403 goto out;
4409 case -NFS4ERR_BADSESSION: 4404 case -NFS4ERR_BADSESSION:
4410 case -NFS4ERR_BADSLOT: 4405 case -NFS4ERR_BADSLOT:
4411 case -NFS4ERR_BAD_HIGH_SLOT: 4406 case -NFS4ERR_BAD_HIGH_SLOT:
4412 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: 4407 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
4413 case -NFS4ERR_DEADSESSION: 4408 case -NFS4ERR_DEADSESSION:
4414 nfs4_schedule_state_recovery(server->nfs_client); 4409 nfs4_schedule_session_recovery(server->nfs_client->cl_session);
4415 goto out; 4410 goto out;
4416 case -ERESTARTSYS: 4411 case -ERESTARTSYS:
4417 /* 4412 /*
@@ -4421,7 +4416,7 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
4421 case -NFS4ERR_ADMIN_REVOKED: 4416 case -NFS4ERR_ADMIN_REVOKED:
4422 case -NFS4ERR_BAD_STATEID: 4417 case -NFS4ERR_BAD_STATEID:
4423 case -NFS4ERR_OPENMODE: 4418 case -NFS4ERR_OPENMODE:
4424 nfs4_state_mark_reclaim_nograce(server->nfs_client, state); 4419 nfs4_schedule_stateid_recovery(server, state);
4425 err = 0; 4420 err = 0;
4426 goto out; 4421 goto out;
4427 case -EKEYEXPIRED: 4422 case -EKEYEXPIRED:
@@ -5028,10 +5023,20 @@ int nfs4_proc_create_session(struct nfs_client *clp)
5028 int status; 5023 int status;
5029 unsigned *ptr; 5024 unsigned *ptr;
5030 struct nfs4_session *session = clp->cl_session; 5025 struct nfs4_session *session = clp->cl_session;
5026 long timeout = 0;
5027 int err;
5031 5028
5032 dprintk("--> %s clp=%p session=%p\n", __func__, clp, session); 5029 dprintk("--> %s clp=%p session=%p\n", __func__, clp, session);
5033 5030
5034 status = _nfs4_proc_create_session(clp); 5031 do {
5032 status = _nfs4_proc_create_session(clp);
5033 if (status == -NFS4ERR_DELAY) {
5034 err = nfs4_delay(clp->cl_rpcclient, &timeout);
5035 if (err)
5036 status = err;
5037 }
5038 } while (status == -NFS4ERR_DELAY);
5039
5035 if (status) 5040 if (status)
5036 goto out; 5041 goto out;
5037 5042
@@ -5140,7 +5145,7 @@ static int nfs41_sequence_handle_errors(struct rpc_task *task, struct nfs_client
5140 rpc_delay(task, NFS4_POLL_RETRY_MAX); 5145 rpc_delay(task, NFS4_POLL_RETRY_MAX);
5141 return -EAGAIN; 5146 return -EAGAIN;
5142 default: 5147 default:
5143 nfs4_schedule_state_recovery(clp); 5148 nfs4_schedule_lease_recovery(clp);
5144 } 5149 }
5145 return 0; 5150 return 0;
5146} 5151}
@@ -5227,7 +5232,7 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp, struct rpc_cred *cr
5227 if (IS_ERR(task)) 5232 if (IS_ERR(task))
5228 ret = PTR_ERR(task); 5233 ret = PTR_ERR(task);
5229 else 5234 else
5230 rpc_put_task(task); 5235 rpc_put_task_async(task);
5231 dprintk("<-- %s status=%d\n", __func__, ret); 5236 dprintk("<-- %s status=%d\n", __func__, ret);
5232 return ret; 5237 return ret;
5233} 5238}
@@ -5243,8 +5248,13 @@ static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred)
5243 goto out; 5248 goto out;
5244 } 5249 }
5245 ret = rpc_wait_for_completion_task(task); 5250 ret = rpc_wait_for_completion_task(task);
5246 if (!ret) 5251 if (!ret) {
5252 struct nfs4_sequence_res *res = task->tk_msg.rpc_resp;
5253
5254 if (task->tk_status == 0)
5255 nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags);
5247 ret = task->tk_status; 5256 ret = task->tk_status;
5257 }
5248 rpc_put_task(task); 5258 rpc_put_task(task);
5249out: 5259out:
5250 dprintk("<-- %s status=%d\n", __func__, ret); 5260 dprintk("<-- %s status=%d\n", __func__, ret);
@@ -5281,7 +5291,7 @@ static int nfs41_reclaim_complete_handle_errors(struct rpc_task *task, struct nf
5281 rpc_delay(task, NFS4_POLL_RETRY_MAX); 5291 rpc_delay(task, NFS4_POLL_RETRY_MAX);
5282 return -EAGAIN; 5292 return -EAGAIN;
5283 default: 5293 default:
5284 nfs4_schedule_state_recovery(clp); 5294 nfs4_schedule_lease_recovery(clp);
5285 } 5295 }
5286 return 0; 5296 return 0;
5287} 5297}
@@ -5349,6 +5359,9 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp)
5349 status = PTR_ERR(task); 5359 status = PTR_ERR(task);
5350 goto out; 5360 goto out;
5351 } 5361 }
5362 status = nfs4_wait_for_completion_rpc_task(task);
5363 if (status == 0)
5364 status = task->tk_status;
5352 rpc_put_task(task); 5365 rpc_put_task(task);
5353 return 0; 5366 return 0;
5354out: 5367out: