summaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c182
1 files changed, 91 insertions, 91 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 0e5ff69455c7..ff5bddc49a2a 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -78,7 +78,6 @@ struct nfs4_opendata;
78static int _nfs4_proc_open(struct nfs4_opendata *data); 78static int _nfs4_proc_open(struct nfs4_opendata *data);
79static int _nfs4_recover_proc_open(struct nfs4_opendata *data); 79static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
80static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); 80static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
81static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *, long *);
82static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr); 81static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
83static int nfs4_proc_getattr(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *, struct nfs4_label *label); 82static int nfs4_proc_getattr(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *, struct nfs4_label *label);
84static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label); 83static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label);
@@ -239,6 +238,7 @@ const u32 nfs4_fsinfo_bitmap[3] = { FATTR4_WORD0_MAXFILESIZE
239 FATTR4_WORD1_TIME_DELTA 238 FATTR4_WORD1_TIME_DELTA
240 | FATTR4_WORD1_FS_LAYOUT_TYPES, 239 | FATTR4_WORD1_FS_LAYOUT_TYPES,
241 FATTR4_WORD2_LAYOUT_BLKSIZE 240 FATTR4_WORD2_LAYOUT_BLKSIZE
241 | FATTR4_WORD2_CLONE_BLKSIZE
242}; 242};
243 243
244const u32 nfs4_fs_locations_bitmap[3] = { 244const u32 nfs4_fs_locations_bitmap[3] = {
@@ -344,13 +344,16 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
344/* This is the error handling routine for processes that are allowed 344/* This is the error handling routine for processes that are allowed
345 * to sleep. 345 * to sleep.
346 */ 346 */
347int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception) 347static int nfs4_do_handle_exception(struct nfs_server *server,
348 int errorcode, struct nfs4_exception *exception)
348{ 349{
349 struct nfs_client *clp = server->nfs_client; 350 struct nfs_client *clp = server->nfs_client;
350 struct nfs4_state *state = exception->state; 351 struct nfs4_state *state = exception->state;
351 struct inode *inode = exception->inode; 352 struct inode *inode = exception->inode;
352 int ret = errorcode; 353 int ret = errorcode;
353 354
355 exception->delay = 0;
356 exception->recovering = 0;
354 exception->retry = 0; 357 exception->retry = 0;
355 switch(errorcode) { 358 switch(errorcode) {
356 case 0: 359 case 0:
@@ -359,11 +362,9 @@ int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_
359 case -NFS4ERR_DELEG_REVOKED: 362 case -NFS4ERR_DELEG_REVOKED:
360 case -NFS4ERR_ADMIN_REVOKED: 363 case -NFS4ERR_ADMIN_REVOKED:
361 case -NFS4ERR_BAD_STATEID: 364 case -NFS4ERR_BAD_STATEID:
362 if (inode && nfs4_have_delegation(inode, FMODE_READ)) { 365 if (inode && nfs_async_inode_return_delegation(inode,
363 nfs4_inode_return_delegation(inode); 366 NULL) == 0)
364 exception->retry = 1; 367 goto wait_on_recovery;
365 return 0;
366 }
367 if (state == NULL) 368 if (state == NULL)
368 break; 369 break;
369 ret = nfs4_schedule_stateid_recovery(server, state); 370 ret = nfs4_schedule_stateid_recovery(server, state);
@@ -409,11 +410,12 @@ int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_
409 ret = -EBUSY; 410 ret = -EBUSY;
410 break; 411 break;
411 } 412 }
412 case -NFS4ERR_GRACE:
413 case -NFS4ERR_DELAY: 413 case -NFS4ERR_DELAY:
414 ret = nfs4_delay(server->client, &exception->timeout); 414 nfs_inc_server_stats(server, NFSIOS_DELAY);
415 if (ret != 0) 415 case -NFS4ERR_GRACE:
416 break; 416 exception->delay = 1;
417 return 0;
418
417 case -NFS4ERR_RETRY_UNCACHED_REP: 419 case -NFS4ERR_RETRY_UNCACHED_REP:
418 case -NFS4ERR_OLD_STATEID: 420 case -NFS4ERR_OLD_STATEID:
419 exception->retry = 1; 421 exception->retry = 1;
@@ -434,14 +436,85 @@ int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_
434 /* We failed to handle the error */ 436 /* We failed to handle the error */
435 return nfs4_map_errors(ret); 437 return nfs4_map_errors(ret);
436wait_on_recovery: 438wait_on_recovery:
437 ret = nfs4_wait_clnt_recover(clp); 439 exception->recovering = 1;
440 return 0;
441}
442
443/* This is the error handling routine for processes that are allowed
444 * to sleep.
445 */
446int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
447{
448 struct nfs_client *clp = server->nfs_client;
449 int ret;
450
451 ret = nfs4_do_handle_exception(server, errorcode, exception);
452 if (exception->delay) {
453 ret = nfs4_delay(server->client, &exception->timeout);
454 goto out_retry;
455 }
456 if (exception->recovering) {
457 ret = nfs4_wait_clnt_recover(clp);
458 if (test_bit(NFS_MIG_FAILED, &server->mig_status))
459 return -EIO;
460 goto out_retry;
461 }
462 return ret;
463out_retry:
464 if (ret == 0)
465 exception->retry = 1;
466 return ret;
467}
468
469static int
470nfs4_async_handle_exception(struct rpc_task *task, struct nfs_server *server,
471 int errorcode, struct nfs4_exception *exception)
472{
473 struct nfs_client *clp = server->nfs_client;
474 int ret;
475
476 ret = nfs4_do_handle_exception(server, errorcode, exception);
477 if (exception->delay) {
478 rpc_delay(task, nfs4_update_delay(&exception->timeout));
479 goto out_retry;
480 }
481 if (exception->recovering) {
482 rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);
483 if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)
484 rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
485 goto out_retry;
486 }
438 if (test_bit(NFS_MIG_FAILED, &server->mig_status)) 487 if (test_bit(NFS_MIG_FAILED, &server->mig_status))
439 return -EIO; 488 ret = -EIO;
489 return ret;
490out_retry:
440 if (ret == 0) 491 if (ret == 0)
441 exception->retry = 1; 492 exception->retry = 1;
442 return ret; 493 return ret;
443} 494}
444 495
496static int
497nfs4_async_handle_error(struct rpc_task *task, struct nfs_server *server,
498 struct nfs4_state *state, long *timeout)
499{
500 struct nfs4_exception exception = {
501 .state = state,
502 };
503
504 if (task->tk_status >= 0)
505 return 0;
506 if (timeout)
507 exception.timeout = *timeout;
508 task->tk_status = nfs4_async_handle_exception(task, server,
509 task->tk_status,
510 &exception);
511 if (exception.delay && timeout)
512 *timeout = exception.timeout;
513 if (exception.retry)
514 return -EAGAIN;
515 return 0;
516}
517
445/* 518/*
446 * Return 'true' if 'clp' is using an rpc_client that is integrity protected 519 * Return 'true' if 'clp' is using an rpc_client that is integrity protected
447 * or 'false' otherwise. 520 * or 'false' otherwise.
@@ -4530,7 +4603,7 @@ static inline int nfs4_server_supports_acls(struct nfs_server *server)
4530#define NFS4ACL_MAXPAGES DIV_ROUND_UP(XATTR_SIZE_MAX, PAGE_SIZE) 4603#define NFS4ACL_MAXPAGES DIV_ROUND_UP(XATTR_SIZE_MAX, PAGE_SIZE)
4531 4604
4532static int buf_to_pages_noslab(const void *buf, size_t buflen, 4605static int buf_to_pages_noslab(const void *buf, size_t buflen,
4533 struct page **pages, unsigned int *pgbase) 4606 struct page **pages)
4534{ 4607{
4535 struct page *newpage, **spages; 4608 struct page *newpage, **spages;
4536 int rc = 0; 4609 int rc = 0;
@@ -4674,7 +4747,6 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
4674 goto out_free; 4747 goto out_free;
4675 4748
4676 args.acl_len = npages * PAGE_SIZE; 4749 args.acl_len = npages * PAGE_SIZE;
4677 args.acl_pgbase = 0;
4678 4750
4679 dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n", 4751 dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n",
4680 __func__, buf, buflen, npages, args.acl_len); 4752 __func__, buf, buflen, npages, args.acl_len);
@@ -4766,7 +4838,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
4766 return -EOPNOTSUPP; 4838 return -EOPNOTSUPP;
4767 if (npages > ARRAY_SIZE(pages)) 4839 if (npages > ARRAY_SIZE(pages))
4768 return -ERANGE; 4840 return -ERANGE;
4769 i = buf_to_pages_noslab(buf, buflen, arg.acl_pages, &arg.acl_pgbase); 4841 i = buf_to_pages_noslab(buf, buflen, arg.acl_pages);
4770 if (i < 0) 4842 if (i < 0)
4771 return i; 4843 return i;
4772 nfs4_inode_return_delegation(inode); 4844 nfs4_inode_return_delegation(inode);
@@ -4955,79 +5027,6 @@ out:
4955#endif /* CONFIG_NFS_V4_SECURITY_LABEL */ 5027#endif /* CONFIG_NFS_V4_SECURITY_LABEL */
4956 5028
4957 5029
4958static int
4959nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
4960 struct nfs4_state *state, long *timeout)
4961{
4962 struct nfs_client *clp = server->nfs_client;
4963
4964 if (task->tk_status >= 0)
4965 return 0;
4966 switch(task->tk_status) {
4967 case -NFS4ERR_DELEG_REVOKED:
4968 case -NFS4ERR_ADMIN_REVOKED:
4969 case -NFS4ERR_BAD_STATEID:
4970 case -NFS4ERR_OPENMODE:
4971 if (state == NULL)
4972 break;
4973 if (nfs4_schedule_stateid_recovery(server, state) < 0)
4974 goto recovery_failed;
4975 goto wait_on_recovery;
4976 case -NFS4ERR_EXPIRED:
4977 if (state != NULL) {
4978 if (nfs4_schedule_stateid_recovery(server, state) < 0)
4979 goto recovery_failed;
4980 }
4981 case -NFS4ERR_STALE_STATEID:
4982 case -NFS4ERR_STALE_CLIENTID:
4983 nfs4_schedule_lease_recovery(clp);
4984 goto wait_on_recovery;
4985 case -NFS4ERR_MOVED:
4986 if (nfs4_schedule_migration_recovery(server) < 0)
4987 goto recovery_failed;
4988 goto wait_on_recovery;
4989 case -NFS4ERR_LEASE_MOVED:
4990 nfs4_schedule_lease_moved_recovery(clp);
4991 goto wait_on_recovery;
4992#if defined(CONFIG_NFS_V4_1)
4993 case -NFS4ERR_BADSESSION:
4994 case -NFS4ERR_BADSLOT:
4995 case -NFS4ERR_BAD_HIGH_SLOT:
4996 case -NFS4ERR_DEADSESSION:
4997 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
4998 case -NFS4ERR_SEQ_FALSE_RETRY:
4999 case -NFS4ERR_SEQ_MISORDERED:
5000 dprintk("%s ERROR %d, Reset session\n", __func__,
5001 task->tk_status);
5002 nfs4_schedule_session_recovery(clp->cl_session, task->tk_status);
5003 goto wait_on_recovery;
5004#endif /* CONFIG_NFS_V4_1 */
5005 case -NFS4ERR_DELAY:
5006 nfs_inc_server_stats(server, NFSIOS_DELAY);
5007 rpc_delay(task, nfs4_update_delay(timeout));
5008 goto restart_call;
5009 case -NFS4ERR_GRACE:
5010 rpc_delay(task, NFS4_POLL_RETRY_MAX);
5011 case -NFS4ERR_RETRY_UNCACHED_REP:
5012 case -NFS4ERR_OLD_STATEID:
5013 goto restart_call;
5014 }
5015 task->tk_status = nfs4_map_errors(task->tk_status);
5016 return 0;
5017recovery_failed:
5018 task->tk_status = -EIO;
5019 return 0;
5020wait_on_recovery:
5021 rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);
5022 if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)
5023 rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
5024 if (test_bit(NFS_MIG_FAILED, &server->mig_status))
5025 goto recovery_failed;
5026restart_call:
5027 task->tk_status = 0;
5028 return -EAGAIN;
5029}
5030
5031static void nfs4_init_boot_verifier(const struct nfs_client *clp, 5030static void nfs4_init_boot_verifier(const struct nfs_client *clp,
5032 nfs4_verifier *bootverf) 5031 nfs4_verifier *bootverf)
5033{ 5032{
@@ -5522,7 +5521,7 @@ struct nfs4_unlockdata {
5522 struct nfs4_lock_state *lsp; 5521 struct nfs4_lock_state *lsp;
5523 struct nfs_open_context *ctx; 5522 struct nfs_open_context *ctx;
5524 struct file_lock fl; 5523 struct file_lock fl;
5525 const struct nfs_server *server; 5524 struct nfs_server *server;
5526 unsigned long timestamp; 5525 unsigned long timestamp;
5527}; 5526};
5528 5527
@@ -8718,7 +8717,8 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = {
8718 | NFS_CAP_ALLOCATE 8717 | NFS_CAP_ALLOCATE
8719 | NFS_CAP_DEALLOCATE 8718 | NFS_CAP_DEALLOCATE
8720 | NFS_CAP_SEEK 8719 | NFS_CAP_SEEK
8721 | NFS_CAP_LAYOUTSTATS, 8720 | NFS_CAP_LAYOUTSTATS
8721 | NFS_CAP_CLONE,
8722 .init_client = nfs41_init_client, 8722 .init_client = nfs41_init_client,
8723 .shutdown_client = nfs41_shutdown_client, 8723 .shutdown_client = nfs41_shutdown_client,
8724 .match_stateid = nfs41_match_stateid, 8724 .match_stateid = nfs41_match_stateid,