aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/lockd/clntlock.c3
-rw-r--r--fs/lockd/clntproc.c3
-rw-r--r--fs/nfs/callback.c3
-rw-r--r--fs/nfs/callback_proc.c2
-rw-r--r--fs/nfs/client.c2
-rw-r--r--fs/nfs/delegation.c121
-rw-r--r--fs/nfs/delegation.h5
-rw-r--r--fs/nfs/dir.c2
-rw-r--r--fs/nfs/file.c9
-rw-r--r--fs/nfs/inode.c8
-rw-r--r--fs/nfs/internal.h7
-rw-r--r--fs/nfs/nfs4_fs.h16
-rw-r--r--fs/nfs/nfs4client.c30
-rw-r--r--fs/nfs/nfs4filelayout.c34
-rw-r--r--fs/nfs/nfs4namespace.c43
-rw-r--r--fs/nfs/nfs4proc.c557
-rw-r--r--fs/nfs/nfs4state.c141
-rw-r--r--fs/nfs/nfs4super.c2
-rw-r--r--fs/nfs/nfs4xdr.c176
-rw-r--r--fs/nfs/pagelist.c53
-rw-r--r--fs/nfs/pnfs.c2
-rw-r--r--fs/nfs/read.c2
-rw-r--r--fs/nfs/super.c80
-rw-r--r--fs/nfs/write.c2
-rw-r--r--fs/nfsd/nfs4xdr.c24
-rw-r--r--include/linux/nfs_fs.h8
-rw-r--r--include/linux/nfs_fs_sb.h3
-rw-r--r--include/linux/nfs_xdr.h27
-rw-r--r--include/linux/sunrpc/auth.h9
-rw-r--r--include/linux/sunrpc/clnt.h1
-rw-r--r--include/linux/sunrpc/gss_api.h30
-rw-r--r--include/linux/sunrpc/xprt.h5
-rw-r--r--net/sunrpc/Kconfig2
-rw-r--r--net/sunrpc/auth.c75
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c3
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_mech.c6
-rw-r--r--net/sunrpc/auth_gss/gss_mech_switch.c119
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c4
-rw-r--r--net/sunrpc/clnt.c43
-rw-r--r--net/sunrpc/xprt.c61
-rw-r--r--net/sunrpc/xprtsock.c14
41 files changed, 1174 insertions, 563 deletions
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c
index 0796c45d0d4d..01bfe7662751 100644
--- a/fs/lockd/clntlock.c
+++ b/fs/lockd/clntlock.c
@@ -144,6 +144,9 @@ int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout)
144 timeout); 144 timeout);
145 if (ret < 0) 145 if (ret < 0)
146 return -ERESTARTSYS; 146 return -ERESTARTSYS;
147 /* Reset the lock status after a server reboot so we resend */
148 if (block->b_status == nlm_lck_denied_grace_period)
149 block->b_status = nlm_lck_blocked;
147 req->a_res.status = block->b_status; 150 req->a_res.status = block->b_status;
148 return 0; 151 return 0;
149} 152}
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index 7e529c3c45c0..9760ecb9b60f 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -550,9 +550,6 @@ again:
550 status = nlmclnt_block(block, req, NLMCLNT_POLL_TIMEOUT); 550 status = nlmclnt_block(block, req, NLMCLNT_POLL_TIMEOUT);
551 if (status < 0) 551 if (status < 0)
552 break; 552 break;
553 /* Resend the blocking lock request after a server reboot */
554 if (resp->status == nlm_lck_denied_grace_period)
555 continue;
556 if (resp->status != nlm_lck_blocked) 553 if (resp->status != nlm_lck_blocked)
557 break; 554 break;
558 } 555 }
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index 5088b57b078a..cff089a412c7 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -125,6 +125,9 @@ nfs41_callback_svc(void *vrqstp)
125 set_freezable(); 125 set_freezable();
126 126
127 while (!kthread_should_stop()) { 127 while (!kthread_should_stop()) {
128 if (try_to_freeze())
129 continue;
130
128 prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_INTERRUPTIBLE); 131 prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_INTERRUPTIBLE);
129 spin_lock_bh(&serv->sv_cb_lock); 132 spin_lock_bh(&serv->sv_cb_lock);
130 if (!list_empty(&serv->sv_cb_list)) { 133 if (!list_empty(&serv->sv_cb_list)) {
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index 2960512792c2..a13d26ede254 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -500,7 +500,7 @@ __be32 nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy,
500 &args->craa_type_mask)) 500 &args->craa_type_mask))
501 pnfs_recall_all_layouts(cps->clp); 501 pnfs_recall_all_layouts(cps->clp);
502 if (flags) 502 if (flags)
503 nfs_expire_all_delegation_types(cps->clp, flags); 503 nfs_expire_unused_delegation_types(cps->clp, flags);
504out: 504out:
505 dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); 505 dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
506 return status; 506 return status;
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 84d8eae203a7..c513b0cc835f 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -593,6 +593,8 @@ int nfs_create_rpc_client(struct nfs_client *clp,
593 args.flags |= RPC_CLNT_CREATE_DISCRTRY; 593 args.flags |= RPC_CLNT_CREATE_DISCRTRY;
594 if (test_bit(NFS_CS_NORESVPORT, &clp->cl_flags)) 594 if (test_bit(NFS_CS_NORESVPORT, &clp->cl_flags))
595 args.flags |= RPC_CLNT_CREATE_NONPRIVPORT; 595 args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
596 if (test_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags))
597 args.flags |= RPC_CLNT_CREATE_INFINITE_SLOTS;
596 598
597 if (!IS_ERR(clp->cl_rpcclient)) 599 if (!IS_ERR(clp->cl_rpcclient))
598 return 0; 600 return 0;
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 6390a4b5fee7..57db3244f4d9 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -64,17 +64,15 @@ int nfs4_have_delegation(struct inode *inode, fmode_t flags)
64 return ret; 64 return ret;
65} 65}
66 66
67static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state) 67static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
68{ 68{
69 struct inode *inode = state->inode; 69 struct inode *inode = state->inode;
70 struct file_lock *fl; 70 struct file_lock *fl;
71 int status = 0; 71 int status = 0;
72 72
73 if (inode->i_flock == NULL) 73 if (inode->i_flock == NULL)
74 return 0;
75
76 if (inode->i_flock == NULL)
77 goto out; 74 goto out;
75
78 /* Protect inode->i_flock using the file locks lock */ 76 /* Protect inode->i_flock using the file locks lock */
79 lock_flocks(); 77 lock_flocks();
80 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { 78 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
@@ -83,7 +81,7 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_
83 if (nfs_file_open_context(fl->fl_file) != ctx) 81 if (nfs_file_open_context(fl->fl_file) != ctx)
84 continue; 82 continue;
85 unlock_flocks(); 83 unlock_flocks();
86 status = nfs4_lock_delegation_recall(state, fl); 84 status = nfs4_lock_delegation_recall(fl, state, stateid);
87 if (status < 0) 85 if (status < 0)
88 goto out; 86 goto out;
89 lock_flocks(); 87 lock_flocks();
@@ -120,7 +118,7 @@ again:
120 seq = raw_seqcount_begin(&sp->so_reclaim_seqcount); 118 seq = raw_seqcount_begin(&sp->so_reclaim_seqcount);
121 err = nfs4_open_delegation_recall(ctx, state, stateid); 119 err = nfs4_open_delegation_recall(ctx, state, stateid);
122 if (!err) 120 if (!err)
123 err = nfs_delegation_claim_locks(ctx, state); 121 err = nfs_delegation_claim_locks(ctx, state, stateid);
124 if (!err && read_seqcount_retry(&sp->so_reclaim_seqcount, seq)) 122 if (!err && read_seqcount_retry(&sp->so_reclaim_seqcount, seq))
125 err = -EAGAIN; 123 err = -EAGAIN;
126 mutex_unlock(&sp->so_delegreturn_mutex); 124 mutex_unlock(&sp->so_delegreturn_mutex);
@@ -389,6 +387,24 @@ out:
389 return err; 387 return err;
390} 388}
391 389
390static bool nfs_delegation_need_return(struct nfs_delegation *delegation)
391{
392 bool ret = false;
393
394 if (test_and_clear_bit(NFS_DELEGATION_RETURN, &delegation->flags))
395 ret = true;
396 if (test_and_clear_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags) && !ret) {
397 struct inode *inode;
398
399 spin_lock(&delegation->lock);
400 inode = delegation->inode;
401 if (inode && list_empty(&NFS_I(inode)->open_files))
402 ret = true;
403 spin_unlock(&delegation->lock);
404 }
405 return ret;
406}
407
392/** 408/**
393 * nfs_client_return_marked_delegations - return previously marked delegations 409 * nfs_client_return_marked_delegations - return previously marked delegations
394 * @clp: nfs_client to process 410 * @clp: nfs_client to process
@@ -411,8 +427,7 @@ restart:
411 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) { 427 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
412 list_for_each_entry_rcu(delegation, &server->delegations, 428 list_for_each_entry_rcu(delegation, &server->delegations,
413 super_list) { 429 super_list) {
414 if (!test_and_clear_bit(NFS_DELEGATION_RETURN, 430 if (!nfs_delegation_need_return(delegation))
415 &delegation->flags))
416 continue; 431 continue;
417 inode = nfs_delegation_grab_inode(delegation); 432 inode = nfs_delegation_grab_inode(delegation);
418 if (inode == NULL) 433 if (inode == NULL)
@@ -471,6 +486,13 @@ int nfs4_inode_return_delegation(struct inode *inode)
471 return err; 486 return err;
472} 487}
473 488
489static void nfs_mark_return_if_closed_delegation(struct nfs_server *server,
490 struct nfs_delegation *delegation)
491{
492 set_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
493 set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state);
494}
495
474static void nfs_mark_return_delegation(struct nfs_server *server, 496static void nfs_mark_return_delegation(struct nfs_server *server,
475 struct nfs_delegation *delegation) 497 struct nfs_delegation *delegation)
476{ 498{
@@ -478,6 +500,45 @@ static void nfs_mark_return_delegation(struct nfs_server *server,
478 set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state); 500 set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state);
479} 501}
480 502
503static bool nfs_server_mark_return_all_delegations(struct nfs_server *server)
504{
505 struct nfs_delegation *delegation;
506 bool ret = false;
507
508 list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
509 nfs_mark_return_delegation(server, delegation);
510 ret = true;
511 }
512 return ret;
513}
514
515static void nfs_client_mark_return_all_delegations(struct nfs_client *clp)
516{
517 struct nfs_server *server;
518
519 rcu_read_lock();
520 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
521 nfs_server_mark_return_all_delegations(server);
522 rcu_read_unlock();
523}
524
525static void nfs_delegation_run_state_manager(struct nfs_client *clp)
526{
527 if (test_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state))
528 nfs4_schedule_state_manager(clp);
529}
530
531/**
532 * nfs_expire_all_delegations
533 * @clp: client to process
534 *
535 */
536void nfs_expire_all_delegations(struct nfs_client *clp)
537{
538 nfs_client_mark_return_all_delegations(clp);
539 nfs_delegation_run_state_manager(clp);
540}
541
481/** 542/**
482 * nfs_super_return_all_delegations - return delegations for one superblock 543 * nfs_super_return_all_delegations - return delegations for one superblock
483 * @sb: sb to process 544 * @sb: sb to process
@@ -486,24 +547,22 @@ static void nfs_mark_return_delegation(struct nfs_server *server,
486void nfs_server_return_all_delegations(struct nfs_server *server) 547void nfs_server_return_all_delegations(struct nfs_server *server)
487{ 548{
488 struct nfs_client *clp = server->nfs_client; 549 struct nfs_client *clp = server->nfs_client;
489 struct nfs_delegation *delegation; 550 bool need_wait;
490 551
491 if (clp == NULL) 552 if (clp == NULL)
492 return; 553 return;
493 554
494 rcu_read_lock(); 555 rcu_read_lock();
495 list_for_each_entry_rcu(delegation, &server->delegations, super_list) { 556 need_wait = nfs_server_mark_return_all_delegations(server);
496 spin_lock(&delegation->lock);
497 set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
498 spin_unlock(&delegation->lock);
499 }
500 rcu_read_unlock(); 557 rcu_read_unlock();
501 558
502 if (nfs_client_return_marked_delegations(clp) != 0) 559 if (need_wait) {
503 nfs4_schedule_state_manager(clp); 560 nfs4_schedule_state_manager(clp);
561 nfs4_wait_clnt_recover(clp);
562 }
504} 563}
505 564
506static void nfs_mark_return_all_delegation_types(struct nfs_server *server, 565static void nfs_mark_return_unused_delegation_types(struct nfs_server *server,
507 fmode_t flags) 566 fmode_t flags)
508{ 567{
509 struct nfs_delegation *delegation; 568 struct nfs_delegation *delegation;
@@ -512,27 +571,21 @@ static void nfs_mark_return_all_delegation_types(struct nfs_server *server,
512 if ((delegation->type == (FMODE_READ|FMODE_WRITE)) && !(flags & FMODE_WRITE)) 571 if ((delegation->type == (FMODE_READ|FMODE_WRITE)) && !(flags & FMODE_WRITE))
513 continue; 572 continue;
514 if (delegation->type & flags) 573 if (delegation->type & flags)
515 nfs_mark_return_delegation(server, delegation); 574 nfs_mark_return_if_closed_delegation(server, delegation);
516 } 575 }
517} 576}
518 577
519static void nfs_client_mark_return_all_delegation_types(struct nfs_client *clp, 578static void nfs_client_mark_return_unused_delegation_types(struct nfs_client *clp,
520 fmode_t flags) 579 fmode_t flags)
521{ 580{
522 struct nfs_server *server; 581 struct nfs_server *server;
523 582
524 rcu_read_lock(); 583 rcu_read_lock();
525 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) 584 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
526 nfs_mark_return_all_delegation_types(server, flags); 585 nfs_mark_return_unused_delegation_types(server, flags);
527 rcu_read_unlock(); 586 rcu_read_unlock();
528} 587}
529 588
530static void nfs_delegation_run_state_manager(struct nfs_client *clp)
531{
532 if (test_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state))
533 nfs4_schedule_state_manager(clp);
534}
535
536void nfs_remove_bad_delegation(struct inode *inode) 589void nfs_remove_bad_delegation(struct inode *inode)
537{ 590{
538 struct nfs_delegation *delegation; 591 struct nfs_delegation *delegation;
@@ -546,27 +599,17 @@ void nfs_remove_bad_delegation(struct inode *inode)
546EXPORT_SYMBOL_GPL(nfs_remove_bad_delegation); 599EXPORT_SYMBOL_GPL(nfs_remove_bad_delegation);
547 600
548/** 601/**
549 * nfs_expire_all_delegation_types 602 * nfs_expire_unused_delegation_types
550 * @clp: client to process 603 * @clp: client to process
551 * @flags: delegation types to expire 604 * @flags: delegation types to expire
552 * 605 *
553 */ 606 */
554void nfs_expire_all_delegation_types(struct nfs_client *clp, fmode_t flags) 607void nfs_expire_unused_delegation_types(struct nfs_client *clp, fmode_t flags)
555{ 608{
556 nfs_client_mark_return_all_delegation_types(clp, flags); 609 nfs_client_mark_return_unused_delegation_types(clp, flags);
557 nfs_delegation_run_state_manager(clp); 610 nfs_delegation_run_state_manager(clp);
558} 611}
559 612
560/**
561 * nfs_expire_all_delegations
562 * @clp: client to process
563 *
564 */
565void nfs_expire_all_delegations(struct nfs_client *clp)
566{
567 nfs_expire_all_delegation_types(clp, FMODE_READ|FMODE_WRITE);
568}
569
570static void nfs_mark_return_unreferenced_delegations(struct nfs_server *server) 613static void nfs_mark_return_unreferenced_delegations(struct nfs_server *server)
571{ 614{
572 struct nfs_delegation *delegation; 615 struct nfs_delegation *delegation;
@@ -574,7 +617,7 @@ static void nfs_mark_return_unreferenced_delegations(struct nfs_server *server)
574 list_for_each_entry_rcu(delegation, &server->delegations, super_list) { 617 list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
575 if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags)) 618 if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags))
576 continue; 619 continue;
577 nfs_mark_return_delegation(server, delegation); 620 nfs_mark_return_if_closed_delegation(server, delegation);
578 } 621 }
579} 622}
580 623
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
index d54d4fca6793..9a79c7a99d6d 100644
--- a/fs/nfs/delegation.h
+++ b/fs/nfs/delegation.h
@@ -28,6 +28,7 @@ struct nfs_delegation {
28enum { 28enum {
29 NFS_DELEGATION_NEED_RECLAIM = 0, 29 NFS_DELEGATION_NEED_RECLAIM = 0,
30 NFS_DELEGATION_RETURN, 30 NFS_DELEGATION_RETURN,
31 NFS_DELEGATION_RETURN_IF_CLOSED,
31 NFS_DELEGATION_REFERENCED, 32 NFS_DELEGATION_REFERENCED,
32 NFS_DELEGATION_RETURNING, 33 NFS_DELEGATION_RETURNING,
33}; 34};
@@ -41,7 +42,7 @@ void nfs_inode_return_delegation_noreclaim(struct inode *inode);
41struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle); 42struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle);
42void nfs_server_return_all_delegations(struct nfs_server *); 43void nfs_server_return_all_delegations(struct nfs_server *);
43void nfs_expire_all_delegations(struct nfs_client *clp); 44void nfs_expire_all_delegations(struct nfs_client *clp);
44void nfs_expire_all_delegation_types(struct nfs_client *clp, fmode_t flags); 45void nfs_expire_unused_delegation_types(struct nfs_client *clp, fmode_t flags);
45void nfs_expire_unreferenced_delegations(struct nfs_client *clp); 46void nfs_expire_unreferenced_delegations(struct nfs_client *clp);
46int nfs_client_return_marked_delegations(struct nfs_client *clp); 47int nfs_client_return_marked_delegations(struct nfs_client *clp);
47int nfs_delegations_present(struct nfs_client *clp); 48int nfs_delegations_present(struct nfs_client *clp);
@@ -53,7 +54,7 @@ void nfs_delegation_reap_unclaimed(struct nfs_client *clp);
53/* NFSv4 delegation-related procedures */ 54/* NFSv4 delegation-related procedures */
54int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync); 55int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync);
55int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid); 56int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid);
56int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl); 57int nfs4_lock_delegation_recall(struct file_lock *fl, struct nfs4_state *state, const nfs4_stateid *stateid);
57bool nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode, fmode_t flags); 58bool nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode, fmode_t flags);
58 59
59void nfs_mark_delegation_referenced(struct nfs_delegation *delegation); 60void nfs_mark_delegation_referenced(struct nfs_delegation *delegation);
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index f23f455be42b..e093e73178b7 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1486,6 +1486,8 @@ static int nfs4_lookup_revalidate(struct dentry *dentry, unsigned int flags)
1486 goto no_open; 1486 goto no_open;
1487 if (d_mountpoint(dentry)) 1487 if (d_mountpoint(dentry))
1488 goto no_open; 1488 goto no_open;
1489 if (NFS_SB(dentry->d_sb)->caps & NFS_CAP_ATOMIC_OPEN_V1)
1490 goto no_open;
1489 1491
1490 inode = dentry->d_inode; 1492 inode = dentry->d_inode;
1491 parent = dget_parent(dentry); 1493 parent = dget_parent(dentry);
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 29f4a48a0ee6..a87a44f84113 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -744,6 +744,7 @@ static int
744do_unlk(struct file *filp, int cmd, struct file_lock *fl, int is_local) 744do_unlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
745{ 745{
746 struct inode *inode = filp->f_mapping->host; 746 struct inode *inode = filp->f_mapping->host;
747 struct nfs_lock_context *l_ctx;
747 int status; 748 int status;
748 749
749 /* 750 /*
@@ -752,6 +753,14 @@ do_unlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
752 */ 753 */
753 nfs_sync_mapping(filp->f_mapping); 754 nfs_sync_mapping(filp->f_mapping);
754 755
756 l_ctx = nfs_get_lock_context(nfs_file_open_context(filp));
757 if (!IS_ERR(l_ctx)) {
758 status = nfs_iocounter_wait(&l_ctx->io_count);
759 nfs_put_lock_context(l_ctx);
760 if (status < 0)
761 return status;
762 }
763
755 /* NOTE: special case 764 /* NOTE: special case
756 * If we're signalled while cleaning up locks on process exit, we 765 * If we're signalled while cleaning up locks on process exit, we
757 * still need to complete the unlock. 766 * still need to complete the unlock.
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 1f941674b089..c1c7a9d78722 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -561,20 +561,22 @@ static void nfs_init_lock_context(struct nfs_lock_context *l_ctx)
561 l_ctx->lockowner.l_owner = current->files; 561 l_ctx->lockowner.l_owner = current->files;
562 l_ctx->lockowner.l_pid = current->tgid; 562 l_ctx->lockowner.l_pid = current->tgid;
563 INIT_LIST_HEAD(&l_ctx->list); 563 INIT_LIST_HEAD(&l_ctx->list);
564 nfs_iocounter_init(&l_ctx->io_count);
564} 565}
565 566
566static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context *ctx) 567static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context *ctx)
567{ 568{
568 struct nfs_lock_context *pos; 569 struct nfs_lock_context *head = &ctx->lock_context;
570 struct nfs_lock_context *pos = head;
569 571
570 list_for_each_entry(pos, &ctx->lock_context.list, list) { 572 do {
571 if (pos->lockowner.l_owner != current->files) 573 if (pos->lockowner.l_owner != current->files)
572 continue; 574 continue;
573 if (pos->lockowner.l_pid != current->tgid) 575 if (pos->lockowner.l_pid != current->tgid)
574 continue; 576 continue;
575 atomic_inc(&pos->count); 577 atomic_inc(&pos->count);
576 return pos; 578 return pos;
577 } 579 } while ((pos = list_entry(pos->list.next, typeof(*pos), list)) != head);
578 return NULL; 580 return NULL;
579} 581}
580 582
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 541c9ebdbc5a..91e59a39fc08 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -229,6 +229,13 @@ extern void nfs_pgheader_init(struct nfs_pageio_descriptor *desc,
229 struct nfs_pgio_header *hdr, 229 struct nfs_pgio_header *hdr,
230 void (*release)(struct nfs_pgio_header *hdr)); 230 void (*release)(struct nfs_pgio_header *hdr));
231void nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos); 231void nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos);
232int nfs_iocounter_wait(struct nfs_io_counter *c);
233
234static inline void nfs_iocounter_init(struct nfs_io_counter *c)
235{
236 c->flags = 0;
237 atomic_set(&c->io_count, 0);
238}
232 239
233/* nfs2xdr.c */ 240/* nfs2xdr.c */
234extern struct rpc_procinfo nfs_procedures[]; 241extern struct rpc_procinfo nfs_procedures[];
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 944c9a5c1039..553a83cc4106 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -36,6 +36,7 @@ enum nfs4_client_state {
36 36
37struct nfs4_minor_version_ops { 37struct nfs4_minor_version_ops {
38 u32 minor_version; 38 u32 minor_version;
39 unsigned init_caps;
39 40
40 int (*call_sync)(struct rpc_clnt *clnt, 41 int (*call_sync)(struct rpc_clnt *clnt,
41 struct nfs_server *server, 42 struct nfs_server *server,
@@ -143,12 +144,14 @@ struct nfs4_lock_state {
143enum { 144enum {
144 LK_STATE_IN_USE, 145 LK_STATE_IN_USE,
145 NFS_DELEGATED_STATE, /* Current stateid is delegation */ 146 NFS_DELEGATED_STATE, /* Current stateid is delegation */
147 NFS_OPEN_STATE, /* OPEN stateid is set */
146 NFS_O_RDONLY_STATE, /* OPEN stateid has read-only state */ 148 NFS_O_RDONLY_STATE, /* OPEN stateid has read-only state */
147 NFS_O_WRONLY_STATE, /* OPEN stateid has write-only state */ 149 NFS_O_WRONLY_STATE, /* OPEN stateid has write-only state */
148 NFS_O_RDWR_STATE, /* OPEN stateid has read/write state */ 150 NFS_O_RDWR_STATE, /* OPEN stateid has read/write state */
149 NFS_STATE_RECLAIM_REBOOT, /* OPEN stateid server rebooted */ 151 NFS_STATE_RECLAIM_REBOOT, /* OPEN stateid server rebooted */
150 NFS_STATE_RECLAIM_NOGRACE, /* OPEN stateid needs to recover state */ 152 NFS_STATE_RECLAIM_NOGRACE, /* OPEN stateid needs to recover state */
151 NFS_STATE_POSIX_LOCKS, /* Posix locks are supported */ 153 NFS_STATE_POSIX_LOCKS, /* Posix locks are supported */
154 NFS_STATE_RECOVERY_FAILED, /* OPEN stateid state recovery failed */
152}; 155};
153 156
154struct nfs4_state { 157struct nfs4_state {
@@ -233,6 +236,10 @@ extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *, struct qstr
233extern int nfs4_proc_secinfo(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *); 236extern int nfs4_proc_secinfo(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *);
234extern int nfs4_release_lockowner(struct nfs4_lock_state *); 237extern int nfs4_release_lockowner(struct nfs4_lock_state *);
235extern const struct xattr_handler *nfs4_xattr_handlers[]; 238extern const struct xattr_handler *nfs4_xattr_handlers[];
239extern int nfs4_set_rw_stateid(nfs4_stateid *stateid,
240 const struct nfs_open_context *ctx,
241 const struct nfs_lock_context *l_ctx,
242 fmode_t fmode);
236 243
237#if defined(CONFIG_NFS_V4_1) 244#if defined(CONFIG_NFS_V4_1)
238static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *server) 245static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *server)
@@ -347,13 +354,13 @@ extern int nfs4_wait_clnt_recover(struct nfs_client *clp);
347extern int nfs4_client_recover_expired_lease(struct nfs_client *clp); 354extern int nfs4_client_recover_expired_lease(struct nfs_client *clp);
348extern void nfs4_schedule_state_manager(struct nfs_client *); 355extern void nfs4_schedule_state_manager(struct nfs_client *);
349extern void nfs4_schedule_path_down_recovery(struct nfs_client *clp); 356extern void nfs4_schedule_path_down_recovery(struct nfs_client *clp);
350extern void nfs4_schedule_stateid_recovery(const struct nfs_server *, struct nfs4_state *); 357extern int nfs4_schedule_stateid_recovery(const struct nfs_server *, struct nfs4_state *);
351extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags); 358extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags);
352extern void nfs41_handle_server_scope(struct nfs_client *, 359extern void nfs41_handle_server_scope(struct nfs_client *,
353 struct nfs41_server_scope **); 360 struct nfs41_server_scope **);
354extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); 361extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
355extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl); 362extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
356extern void nfs4_select_rw_stateid(nfs4_stateid *, struct nfs4_state *, 363extern int nfs4_select_rw_stateid(nfs4_stateid *, struct nfs4_state *,
357 fmode_t, const struct nfs_lockowner *); 364 fmode_t, const struct nfs_lockowner *);
358 365
359extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask); 366extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask);
@@ -412,6 +419,11 @@ static inline bool nfs4_stateid_match(const nfs4_stateid *dst, const nfs4_statei
412 return memcmp(dst, src, sizeof(*dst)) == 0; 419 return memcmp(dst, src, sizeof(*dst)) == 0;
413} 420}
414 421
422static inline bool nfs4_valid_open_stateid(const struct nfs4_state *state)
423{
424 return test_bit(NFS_STATE_RECOVERY_FAILED, &state->flags) == 0;
425}
426
415#else 427#else
416 428
417#define nfs4_close_state(a, b) do { } while (0) 429#define nfs4_close_state(a, b) do { } while (0)
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 66b6664dcd4c..947b0c908aa9 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -198,8 +198,12 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp,
198 /* Check NFS protocol revision and initialize RPC op vector */ 198 /* Check NFS protocol revision and initialize RPC op vector */
199 clp->rpc_ops = &nfs_v4_clientops; 199 clp->rpc_ops = &nfs_v4_clientops;
200 200
201 if (clp->cl_minorversion != 0)
202 __set_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags);
201 __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags); 203 __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags);
202 error = nfs_create_rpc_client(clp, timeparms, authflavour); 204 error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_GSS_KRB5I);
205 if (error == -EINVAL)
206 error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_NULL);
203 if (error < 0) 207 if (error < 0)
204 goto error; 208 goto error;
205 209
@@ -730,6 +734,19 @@ static int nfs4_server_common_setup(struct nfs_server *server,
730 if (error < 0) 734 if (error < 0)
731 goto out; 735 goto out;
732 736
737 /* Set the basic capabilities */
738 server->caps |= server->nfs_client->cl_mvops->init_caps;
739 if (server->flags & NFS_MOUNT_NORDIRPLUS)
740 server->caps &= ~NFS_CAP_READDIRPLUS;
741 /*
742 * Don't use NFS uid/gid mapping if we're using AUTH_SYS or lower
743 * authentication.
744 */
745 if (nfs4_disable_idmapping &&
746 server->client->cl_auth->au_flavor == RPC_AUTH_UNIX)
747 server->caps |= NFS_CAP_UIDGID_NOMAP;
748
749
733 /* Probe the root fh to retrieve its FSID and filehandle */ 750 /* Probe the root fh to retrieve its FSID and filehandle */
734 error = nfs4_get_rootfh(server, mntfh); 751 error = nfs4_get_rootfh(server, mntfh);
735 if (error < 0) 752 if (error < 0)
@@ -773,9 +790,6 @@ static int nfs4_init_server(struct nfs_server *server,
773 790
774 /* Initialise the client representation from the mount data */ 791 /* Initialise the client representation from the mount data */
775 server->flags = data->flags; 792 server->flags = data->flags;
776 server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR|NFS_CAP_POSIX_LOCK;
777 if (!(data->flags & NFS_MOUNT_NORDIRPLUS))
778 server->caps |= NFS_CAP_READDIRPLUS;
779 server->options = data->options; 793 server->options = data->options;
780 794
781 /* Get a client record */ 795 /* Get a client record */
@@ -792,13 +806,6 @@ static int nfs4_init_server(struct nfs_server *server,
792 if (error < 0) 806 if (error < 0)
793 goto error; 807 goto error;
794 808
795 /*
796 * Don't use NFS uid/gid mapping if we're using AUTH_SYS or lower
797 * authentication.
798 */
799 if (nfs4_disable_idmapping && data->auth_flavors[0] == RPC_AUTH_UNIX)
800 server->caps |= NFS_CAP_UIDGID_NOMAP;
801
802 if (data->rsize) 809 if (data->rsize)
803 server->rsize = nfs_block_size(data->rsize, NULL); 810 server->rsize = nfs_block_size(data->rsize, NULL);
804 if (data->wsize) 811 if (data->wsize)
@@ -876,7 +883,6 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
876 883
877 /* Initialise the client representation from the parent server */ 884 /* Initialise the client representation from the parent server */
878 nfs_server_copy_userdata(server, parent_server); 885 nfs_server_copy_userdata(server, parent_server);
879 server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR;
880 886
881 /* Get a client representation. 887 /* Get a client representation.
882 * Note: NFSv4 always uses TCP, */ 888 * Note: NFSv4 always uses TCP, */
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 4fb234d3aefb..22d10623f5ee 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -158,11 +158,14 @@ static int filelayout_async_handle_error(struct rpc_task *task,
158 case -NFS4ERR_OPENMODE: 158 case -NFS4ERR_OPENMODE:
159 if (state == NULL) 159 if (state == NULL)
160 break; 160 break;
161 nfs4_schedule_stateid_recovery(mds_server, state); 161 if (nfs4_schedule_stateid_recovery(mds_server, state) < 0)
162 goto out_bad_stateid;
162 goto wait_on_recovery; 163 goto wait_on_recovery;
163 case -NFS4ERR_EXPIRED: 164 case -NFS4ERR_EXPIRED:
164 if (state != NULL) 165 if (state != NULL) {
165 nfs4_schedule_stateid_recovery(mds_server, state); 166 if (nfs4_schedule_stateid_recovery(mds_server, state) < 0)
167 goto out_bad_stateid;
168 }
166 nfs4_schedule_lease_recovery(mds_client); 169 nfs4_schedule_lease_recovery(mds_client);
167 goto wait_on_recovery; 170 goto wait_on_recovery;
168 /* DS session errors */ 171 /* DS session errors */
@@ -226,6 +229,9 @@ reset:
226out: 229out:
227 task->tk_status = 0; 230 task->tk_status = 0;
228 return -EAGAIN; 231 return -EAGAIN;
232out_bad_stateid:
233 task->tk_status = -EIO;
234 return 0;
229wait_on_recovery: 235wait_on_recovery:
230 rpc_sleep_on(&mds_client->cl_rpcwaitq, task, NULL); 236 rpc_sleep_on(&mds_client->cl_rpcwaitq, task, NULL);
231 if (test_bit(NFS4CLNT_MANAGER_RUNNING, &mds_client->cl_state) == 0) 237 if (test_bit(NFS4CLNT_MANAGER_RUNNING, &mds_client->cl_state) == 0)
@@ -299,6 +305,10 @@ static void filelayout_read_prepare(struct rpc_task *task, void *data)
299{ 305{
300 struct nfs_read_data *rdata = data; 306 struct nfs_read_data *rdata = data;
301 307
308 if (unlikely(test_bit(NFS_CONTEXT_BAD, &rdata->args.context->flags))) {
309 rpc_exit(task, -EIO);
310 return;
311 }
302 if (filelayout_reset_to_mds(rdata->header->lseg)) { 312 if (filelayout_reset_to_mds(rdata->header->lseg)) {
303 dprintk("%s task %u reset io to MDS\n", __func__, task->tk_pid); 313 dprintk("%s task %u reset io to MDS\n", __func__, task->tk_pid);
304 filelayout_reset_read(rdata); 314 filelayout_reset_read(rdata);
@@ -307,10 +317,13 @@ static void filelayout_read_prepare(struct rpc_task *task, void *data)
307 } 317 }
308 rdata->read_done_cb = filelayout_read_done_cb; 318 rdata->read_done_cb = filelayout_read_done_cb;
309 319
310 nfs41_setup_sequence(rdata->ds_clp->cl_session, 320 if (nfs41_setup_sequence(rdata->ds_clp->cl_session,
311 &rdata->args.seq_args, 321 &rdata->args.seq_args,
312 &rdata->res.seq_res, 322 &rdata->res.seq_res,
313 task); 323 task))
324 return;
325 nfs4_set_rw_stateid(&rdata->args.stateid, rdata->args.context,
326 rdata->args.lock_context, FMODE_READ);
314} 327}
315 328
316static void filelayout_read_call_done(struct rpc_task *task, void *data) 329static void filelayout_read_call_done(struct rpc_task *task, void *data)
@@ -401,16 +414,23 @@ static void filelayout_write_prepare(struct rpc_task *task, void *data)
401{ 414{
402 struct nfs_write_data *wdata = data; 415 struct nfs_write_data *wdata = data;
403 416
417 if (unlikely(test_bit(NFS_CONTEXT_BAD, &wdata->args.context->flags))) {
418 rpc_exit(task, -EIO);
419 return;
420 }
404 if (filelayout_reset_to_mds(wdata->header->lseg)) { 421 if (filelayout_reset_to_mds(wdata->header->lseg)) {
405 dprintk("%s task %u reset io to MDS\n", __func__, task->tk_pid); 422 dprintk("%s task %u reset io to MDS\n", __func__, task->tk_pid);
406 filelayout_reset_write(wdata); 423 filelayout_reset_write(wdata);
407 rpc_exit(task, 0); 424 rpc_exit(task, 0);
408 return; 425 return;
409 } 426 }
410 nfs41_setup_sequence(wdata->ds_clp->cl_session, 427 if (nfs41_setup_sequence(wdata->ds_clp->cl_session,
411 &wdata->args.seq_args, 428 &wdata->args.seq_args,
412 &wdata->res.seq_res, 429 &wdata->res.seq_res,
413 task); 430 task))
431 return;
432 nfs4_set_rw_stateid(&wdata->args.stateid, wdata->args.context,
433 wdata->args.lock_context, FMODE_WRITE);
414} 434}
415 435
416static void filelayout_write_call_done(struct rpc_task *task, void *data) 436static void filelayout_write_call_done(struct rpc_task *task, void *data)
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index 0dd766079e1c..cdb0b41a4810 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -134,33 +134,38 @@ static size_t nfs_parse_server_name(char *string, size_t len,
134 return ret; 134 return ret;
135} 135}
136 136
137/**
138 * nfs_find_best_sec - Find a security mechanism supported locally
139 * @flavors: List of security tuples returned by SECINFO procedure
140 *
141 * Return the pseudoflavor of the first security mechanism in
142 * "flavors" that is locally supported. Return RPC_AUTH_UNIX if
143 * no matching flavor is found in the array. The "flavors" array
144 * is searched in the order returned from the server, per RFC 3530
145 * recommendation.
146 */
137rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors) 147rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors)
138{ 148{
139 struct gss_api_mech *mech; 149 rpc_authflavor_t pseudoflavor;
140 struct xdr_netobj oid; 150 struct nfs4_secinfo4 *secinfo;
141 int i; 151 unsigned int i;
142 rpc_authflavor_t pseudoflavor = RPC_AUTH_UNIX;
143 152
144 for (i = 0; i < flavors->num_flavors; i++) { 153 for (i = 0; i < flavors->num_flavors; i++) {
145 struct nfs4_secinfo_flavor *flavor; 154 secinfo = &flavors->flavors[i];
146 flavor = &flavors->flavors[i]; 155
147 156 switch (secinfo->flavor) {
148 if (flavor->flavor == RPC_AUTH_NULL || flavor->flavor == RPC_AUTH_UNIX) { 157 case RPC_AUTH_NULL:
149 pseudoflavor = flavor->flavor; 158 case RPC_AUTH_UNIX:
150 break; 159 case RPC_AUTH_GSS:
151 } else if (flavor->flavor == RPC_AUTH_GSS) { 160 pseudoflavor = rpcauth_get_pseudoflavor(secinfo->flavor,
152 oid.len = flavor->gss.sec_oid4.len; 161 &secinfo->flavor_info);
153 oid.data = flavor->gss.sec_oid4.data; 162 if (pseudoflavor != RPC_AUTH_MAXFLAVOR)
154 mech = gss_mech_get_by_OID(&oid); 163 return pseudoflavor;
155 if (!mech)
156 continue;
157 pseudoflavor = gss_svc_to_pseudoflavor(mech, flavor->gss.service);
158 gss_mech_put(mech);
159 break; 164 break;
160 } 165 }
161 } 166 }
162 167
163 return pseudoflavor; 168 return RPC_AUTH_UNIX;
164} 169}
165 170
166static rpc_authflavor_t nfs4_negotiate_security(struct inode *inode, struct qstr *name) 171static rpc_authflavor_t nfs4_negotiate_security(struct inode *inode, struct qstr *name)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 0ad025eb523b..9da4bd55eb30 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -107,6 +107,8 @@ static int nfs4_map_errors(int err)
107 return -EPROTONOSUPPORT; 107 return -EPROTONOSUPPORT;
108 case -NFS4ERR_ACCESS: 108 case -NFS4ERR_ACCESS:
109 return -EACCES; 109 return -EACCES;
110 case -NFS4ERR_FILE_OPEN:
111 return -EBUSY;
110 default: 112 default:
111 dprintk("%s could not handle NFSv4 error %d\n", 113 dprintk("%s could not handle NFSv4 error %d\n",
112 __func__, -err); 114 __func__, -err);
@@ -295,19 +297,30 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc
295 } 297 }
296 if (state == NULL) 298 if (state == NULL)
297 break; 299 break;
298 nfs4_schedule_stateid_recovery(server, state); 300 ret = nfs4_schedule_stateid_recovery(server, state);
301 if (ret < 0)
302 break;
299 goto wait_on_recovery; 303 goto wait_on_recovery;
300 case -NFS4ERR_DELEG_REVOKED: 304 case -NFS4ERR_DELEG_REVOKED:
301 case -NFS4ERR_ADMIN_REVOKED: 305 case -NFS4ERR_ADMIN_REVOKED:
302 case -NFS4ERR_BAD_STATEID: 306 case -NFS4ERR_BAD_STATEID:
307 if (inode != NULL && nfs4_have_delegation(inode, FMODE_READ)) {
308 nfs_remove_bad_delegation(inode);
309 exception->retry = 1;
310 break;
311 }
303 if (state == NULL) 312 if (state == NULL)
304 break; 313 break;
305 nfs_remove_bad_delegation(state->inode); 314 ret = nfs4_schedule_stateid_recovery(server, state);
306 nfs4_schedule_stateid_recovery(server, state); 315 if (ret < 0)
316 break;
307 goto wait_on_recovery; 317 goto wait_on_recovery;
308 case -NFS4ERR_EXPIRED: 318 case -NFS4ERR_EXPIRED:
309 if (state != NULL) 319 if (state != NULL) {
310 nfs4_schedule_stateid_recovery(server, state); 320 ret = nfs4_schedule_stateid_recovery(server, state);
321 if (ret < 0)
322 break;
323 }
311 case -NFS4ERR_STALE_STATEID: 324 case -NFS4ERR_STALE_STATEID:
312 case -NFS4ERR_STALE_CLIENTID: 325 case -NFS4ERR_STALE_CLIENTID:
313 nfs4_schedule_lease_recovery(clp); 326 nfs4_schedule_lease_recovery(clp);
@@ -756,10 +769,40 @@ struct nfs4_opendata {
756 struct iattr attrs; 769 struct iattr attrs;
757 unsigned long timestamp; 770 unsigned long timestamp;
758 unsigned int rpc_done : 1; 771 unsigned int rpc_done : 1;
772 unsigned int is_recover : 1;
759 int rpc_status; 773 int rpc_status;
760 int cancelled; 774 int cancelled;
761}; 775};
762 776
777static bool nfs4_clear_cap_atomic_open_v1(struct nfs_server *server,
778 int err, struct nfs4_exception *exception)
779{
780 if (err != -EINVAL)
781 return false;
782 if (!(server->caps & NFS_CAP_ATOMIC_OPEN_V1))
783 return false;
784 server->caps &= ~NFS_CAP_ATOMIC_OPEN_V1;
785 exception->retry = 1;
786 return true;
787}
788
789static enum open_claim_type4
790nfs4_map_atomic_open_claim(struct nfs_server *server,
791 enum open_claim_type4 claim)
792{
793 if (server->caps & NFS_CAP_ATOMIC_OPEN_V1)
794 return claim;
795 switch (claim) {
796 default:
797 return claim;
798 case NFS4_OPEN_CLAIM_FH:
799 return NFS4_OPEN_CLAIM_NULL;
800 case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
801 return NFS4_OPEN_CLAIM_DELEGATE_CUR;
802 case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
803 return NFS4_OPEN_CLAIM_DELEGATE_PREV;
804 }
805}
763 806
764static void nfs4_init_opendata_res(struct nfs4_opendata *p) 807static void nfs4_init_opendata_res(struct nfs4_opendata *p)
765{ 808{
@@ -775,6 +818,7 @@ static void nfs4_init_opendata_res(struct nfs4_opendata *p)
775static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, 818static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
776 struct nfs4_state_owner *sp, fmode_t fmode, int flags, 819 struct nfs4_state_owner *sp, fmode_t fmode, int flags,
777 const struct iattr *attrs, 820 const struct iattr *attrs,
821 enum open_claim_type4 claim,
778 gfp_t gfp_mask) 822 gfp_t gfp_mask)
779{ 823{
780 struct dentry *parent = dget_parent(dentry); 824 struct dentry *parent = dget_parent(dentry);
@@ -793,7 +837,6 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
793 p->dir = parent; 837 p->dir = parent;
794 p->owner = sp; 838 p->owner = sp;
795 atomic_inc(&sp->so_count); 839 atomic_inc(&sp->so_count);
796 p->o_arg.fh = NFS_FH(dir);
797 p->o_arg.open_flags = flags; 840 p->o_arg.open_flags = flags;
798 p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE); 841 p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE);
799 /* don't put an ACCESS op in OPEN compound if O_EXCL, because ACCESS 842 /* don't put an ACCESS op in OPEN compound if O_EXCL, because ACCESS
@@ -811,7 +854,19 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
811 p->o_arg.server = server; 854 p->o_arg.server = server;
812 p->o_arg.bitmask = server->attr_bitmask; 855 p->o_arg.bitmask = server->attr_bitmask;
813 p->o_arg.open_bitmap = &nfs4_fattr_bitmap[0]; 856 p->o_arg.open_bitmap = &nfs4_fattr_bitmap[0];
814 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL; 857 p->o_arg.claim = nfs4_map_atomic_open_claim(server, claim);
858 switch (p->o_arg.claim) {
859 case NFS4_OPEN_CLAIM_NULL:
860 case NFS4_OPEN_CLAIM_DELEGATE_CUR:
861 case NFS4_OPEN_CLAIM_DELEGATE_PREV:
862 p->o_arg.fh = NFS_FH(dir);
863 break;
864 case NFS4_OPEN_CLAIM_PREVIOUS:
865 case NFS4_OPEN_CLAIM_FH:
866 case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
867 case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
868 p->o_arg.fh = NFS_FH(dentry->d_inode);
869 }
815 if (attrs != NULL && attrs->ia_valid != 0) { 870 if (attrs != NULL && attrs->ia_valid != 0) {
816 __be32 verf[2]; 871 __be32 verf[2];
817 872
@@ -924,6 +979,7 @@ static void nfs_set_open_stateid_locked(struct nfs4_state *state, nfs4_stateid *
924 if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0) 979 if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0)
925 nfs4_stateid_copy(&state->stateid, stateid); 980 nfs4_stateid_copy(&state->stateid, stateid);
926 nfs4_stateid_copy(&state->open_stateid, stateid); 981 nfs4_stateid_copy(&state->open_stateid, stateid);
982 set_bit(NFS_OPEN_STATE, &state->flags);
927 switch (fmode) { 983 switch (fmode) {
928 case FMODE_READ: 984 case FMODE_READ:
929 set_bit(NFS_O_RDONLY_STATE, &state->flags); 985 set_bit(NFS_O_RDONLY_STATE, &state->flags);
@@ -1047,9 +1103,11 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
1047 nfs4_stateid_copy(&stateid, &delegation->stateid); 1103 nfs4_stateid_copy(&stateid, &delegation->stateid);
1048 rcu_read_unlock(); 1104 rcu_read_unlock();
1049 nfs_release_seqid(opendata->o_arg.seqid); 1105 nfs_release_seqid(opendata->o_arg.seqid);
1050 ret = nfs_may_open(state->inode, state->owner->so_cred, open_mode); 1106 if (!opendata->is_recover) {
1051 if (ret != 0) 1107 ret = nfs_may_open(state->inode, state->owner->so_cred, open_mode);
1052 goto out; 1108 if (ret != 0)
1109 goto out;
1110 }
1053 ret = -EAGAIN; 1111 ret = -EAGAIN;
1054 1112
1055 /* Try to update the stateid using the delegation */ 1113 /* Try to update the stateid using the delegation */
@@ -1194,11 +1252,13 @@ static struct nfs_open_context *nfs4_state_find_open_context(struct nfs4_state *
1194 return ERR_PTR(-ENOENT); 1252 return ERR_PTR(-ENOENT);
1195} 1253}
1196 1254
1197static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context *ctx, struct nfs4_state *state) 1255static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context *ctx,
1256 struct nfs4_state *state, enum open_claim_type4 claim)
1198{ 1257{
1199 struct nfs4_opendata *opendata; 1258 struct nfs4_opendata *opendata;
1200 1259
1201 opendata = nfs4_opendata_alloc(ctx->dentry, state->owner, 0, 0, NULL, GFP_NOFS); 1260 opendata = nfs4_opendata_alloc(ctx->dentry, state->owner, 0, 0,
1261 NULL, claim, GFP_NOFS);
1202 if (opendata == NULL) 1262 if (opendata == NULL)
1203 return ERR_PTR(-ENOMEM); 1263 return ERR_PTR(-ENOMEM);
1204 opendata->state = state; 1264 opendata->state = state;
@@ -1234,6 +1294,7 @@ static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *
1234 1294
1235 /* memory barrier prior to reading state->n_* */ 1295 /* memory barrier prior to reading state->n_* */
1236 clear_bit(NFS_DELEGATED_STATE, &state->flags); 1296 clear_bit(NFS_DELEGATED_STATE, &state->flags);
1297 clear_bit(NFS_OPEN_STATE, &state->flags);
1237 smp_rmb(); 1298 smp_rmb();
1238 if (state->n_rdwr != 0) { 1299 if (state->n_rdwr != 0) {
1239 clear_bit(NFS_O_RDWR_STATE, &state->flags); 1300 clear_bit(NFS_O_RDWR_STATE, &state->flags);
@@ -1284,11 +1345,10 @@ static int _nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state
1284 fmode_t delegation_type = 0; 1345 fmode_t delegation_type = 0;
1285 int status; 1346 int status;
1286 1347
1287 opendata = nfs4_open_recoverdata_alloc(ctx, state); 1348 opendata = nfs4_open_recoverdata_alloc(ctx, state,
1349 NFS4_OPEN_CLAIM_PREVIOUS);
1288 if (IS_ERR(opendata)) 1350 if (IS_ERR(opendata))
1289 return PTR_ERR(opendata); 1351 return PTR_ERR(opendata);
1290 opendata->o_arg.claim = NFS4_OPEN_CLAIM_PREVIOUS;
1291 opendata->o_arg.fh = NFS_FH(state->inode);
1292 rcu_read_lock(); 1352 rcu_read_lock();
1293 delegation = rcu_dereference(NFS_I(state->inode)->delegation); 1353 delegation = rcu_dereference(NFS_I(state->inode)->delegation);
1294 if (delegation != NULL && test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags) != 0) 1354 if (delegation != NULL && test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags) != 0)
@@ -1307,6 +1367,8 @@ static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state
1307 int err; 1367 int err;
1308 do { 1368 do {
1309 err = _nfs4_do_open_reclaim(ctx, state); 1369 err = _nfs4_do_open_reclaim(ctx, state);
1370 if (nfs4_clear_cap_atomic_open_v1(server, err, &exception))
1371 continue;
1310 if (err != -NFS4ERR_DELAY) 1372 if (err != -NFS4ERR_DELAY)
1311 break; 1373 break;
1312 nfs4_handle_exception(server, err, &exception); 1374 nfs4_handle_exception(server, err, &exception);
@@ -1321,71 +1383,72 @@ static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *sta
1321 1383
1322 ctx = nfs4_state_find_open_context(state); 1384 ctx = nfs4_state_find_open_context(state);
1323 if (IS_ERR(ctx)) 1385 if (IS_ERR(ctx))
1324 return PTR_ERR(ctx); 1386 return -EAGAIN;
1325 ret = nfs4_do_open_reclaim(ctx, state); 1387 ret = nfs4_do_open_reclaim(ctx, state);
1326 put_nfs_open_context(ctx); 1388 put_nfs_open_context(ctx);
1327 return ret; 1389 return ret;
1328} 1390}
1329 1391
1330static int _nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid) 1392static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct nfs4_state *state, const nfs4_stateid *stateid, int err)
1331{ 1393{
1332 struct nfs4_opendata *opendata; 1394 switch (err) {
1333 int ret; 1395 default:
1334 1396 printk(KERN_ERR "NFS: %s: unhandled error "
1335 opendata = nfs4_open_recoverdata_alloc(ctx, state); 1397 "%d.\n", __func__, err);
1336 if (IS_ERR(opendata)) 1398 case 0:
1337 return PTR_ERR(opendata); 1399 case -ENOENT:
1338 opendata->o_arg.claim = NFS4_OPEN_CLAIM_DELEGATE_CUR; 1400 case -ESTALE:
1339 nfs4_stateid_copy(&opendata->o_arg.u.delegation, stateid); 1401 break;
1340 ret = nfs4_open_recover(opendata, state); 1402 case -NFS4ERR_BADSESSION:
1341 nfs4_opendata_put(opendata); 1403 case -NFS4ERR_BADSLOT:
1342 return ret; 1404 case -NFS4ERR_BAD_HIGH_SLOT:
1405 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
1406 case -NFS4ERR_DEADSESSION:
1407 set_bit(NFS_DELEGATED_STATE, &state->flags);
1408 nfs4_schedule_session_recovery(server->nfs_client->cl_session, err);
1409 return -EAGAIN;
1410 case -NFS4ERR_STALE_CLIENTID:
1411 case -NFS4ERR_STALE_STATEID:
1412 set_bit(NFS_DELEGATED_STATE, &state->flags);
1413 case -NFS4ERR_EXPIRED:
1414 /* Don't recall a delegation if it was lost */
1415 nfs4_schedule_lease_recovery(server->nfs_client);
1416 return -EAGAIN;
1417 case -NFS4ERR_DELEG_REVOKED:
1418 case -NFS4ERR_ADMIN_REVOKED:
1419 case -NFS4ERR_BAD_STATEID:
1420 case -NFS4ERR_OPENMODE:
1421 nfs_inode_find_state_and_recover(state->inode,
1422 stateid);
1423 nfs4_schedule_stateid_recovery(server, state);
1424 return 0;
1425 case -NFS4ERR_DELAY:
1426 case -NFS4ERR_GRACE:
1427 set_bit(NFS_DELEGATED_STATE, &state->flags);
1428 ssleep(1);
1429 return -EAGAIN;
1430 case -ENOMEM:
1431 case -NFS4ERR_DENIED:
1432 /* kill_proc(fl->fl_pid, SIGLOST, 1); */
1433 return 0;
1434 }
1435 return err;
1343} 1436}
1344 1437
1345int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid) 1438int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
1346{ 1439{
1347 struct nfs4_exception exception = { };
1348 struct nfs_server *server = NFS_SERVER(state->inode); 1440 struct nfs_server *server = NFS_SERVER(state->inode);
1441 struct nfs4_opendata *opendata;
1349 int err; 1442 int err;
1350 do { 1443
1351 err = _nfs4_open_delegation_recall(ctx, state, stateid); 1444 opendata = nfs4_open_recoverdata_alloc(ctx, state,
1352 switch (err) { 1445 NFS4_OPEN_CLAIM_DELEG_CUR_FH);
1353 case 0: 1446 if (IS_ERR(opendata))
1354 case -ENOENT: 1447 return PTR_ERR(opendata);
1355 case -ESTALE: 1448 nfs4_stateid_copy(&opendata->o_arg.u.delegation, stateid);
1356 goto out; 1449 err = nfs4_open_recover(opendata, state);
1357 case -NFS4ERR_BADSESSION: 1450 nfs4_opendata_put(opendata);
1358 case -NFS4ERR_BADSLOT: 1451 return nfs4_handle_delegation_recall_error(server, state, stateid, err);
1359 case -NFS4ERR_BAD_HIGH_SLOT:
1360 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
1361 case -NFS4ERR_DEADSESSION:
1362 set_bit(NFS_DELEGATED_STATE, &state->flags);
1363 nfs4_schedule_session_recovery(server->nfs_client->cl_session, err);
1364 err = -EAGAIN;
1365 goto out;
1366 case -NFS4ERR_STALE_CLIENTID:
1367 case -NFS4ERR_STALE_STATEID:
1368 set_bit(NFS_DELEGATED_STATE, &state->flags);
1369 case -NFS4ERR_EXPIRED:
1370 /* Don't recall a delegation if it was lost */
1371 nfs4_schedule_lease_recovery(server->nfs_client);
1372 err = -EAGAIN;
1373 goto out;
1374 case -NFS4ERR_DELEG_REVOKED:
1375 case -NFS4ERR_ADMIN_REVOKED:
1376 case -NFS4ERR_BAD_STATEID:
1377 nfs_inode_find_state_and_recover(state->inode,
1378 stateid);
1379 nfs4_schedule_stateid_recovery(server, state);
1380 case -ENOMEM:
1381 err = 0;
1382 goto out;
1383 }
1384 set_bit(NFS_DELEGATED_STATE, &state->flags);
1385 err = nfs4_handle_exception(server, err, &exception);
1386 } while (exception.retry);
1387out:
1388 return err;
1389} 1452}
1390 1453
1391static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata) 1454static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata)
@@ -1468,6 +1531,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
1468{ 1531{
1469 struct nfs4_opendata *data = calldata; 1532 struct nfs4_opendata *data = calldata;
1470 struct nfs4_state_owner *sp = data->owner; 1533 struct nfs4_state_owner *sp = data->owner;
1534 struct nfs_client *clp = sp->so_server->nfs_client;
1471 1535
1472 if (nfs_wait_on_sequence(data->o_arg.seqid, task) != 0) 1536 if (nfs_wait_on_sequence(data->o_arg.seqid, task) != 0)
1473 goto out_wait; 1537 goto out_wait;
@@ -1483,15 +1547,20 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
1483 rcu_read_lock(); 1547 rcu_read_lock();
1484 delegation = rcu_dereference(NFS_I(data->state->inode)->delegation); 1548 delegation = rcu_dereference(NFS_I(data->state->inode)->delegation);
1485 if (data->o_arg.claim != NFS4_OPEN_CLAIM_DELEGATE_CUR && 1549 if (data->o_arg.claim != NFS4_OPEN_CLAIM_DELEGATE_CUR &&
1550 data->o_arg.claim != NFS4_OPEN_CLAIM_DELEG_CUR_FH &&
1486 can_open_delegated(delegation, data->o_arg.fmode)) 1551 can_open_delegated(delegation, data->o_arg.fmode))
1487 goto unlock_no_action; 1552 goto unlock_no_action;
1488 rcu_read_unlock(); 1553 rcu_read_unlock();
1489 } 1554 }
1490 /* Update client id. */ 1555 /* Update client id. */
1491 data->o_arg.clientid = sp->so_server->nfs_client->cl_clientid; 1556 data->o_arg.clientid = clp->cl_clientid;
1492 if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) { 1557 switch (data->o_arg.claim) {
1493 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR]; 1558 case NFS4_OPEN_CLAIM_PREVIOUS:
1559 case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
1560 case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
1494 data->o_arg.open_bitmap = &nfs4_open_noattr_bitmap[0]; 1561 data->o_arg.open_bitmap = &nfs4_open_noattr_bitmap[0];
1562 case NFS4_OPEN_CLAIM_FH:
1563 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR];
1495 nfs_copy_fh(&data->o_res.fh, data->o_arg.fh); 1564 nfs_copy_fh(&data->o_res.fh, data->o_arg.fh);
1496 } 1565 }
1497 data->timestamp = jiffies; 1566 data->timestamp = jiffies;
@@ -1500,6 +1569,16 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
1500 &data->o_res.seq_res, 1569 &data->o_res.seq_res,
1501 task) != 0) 1570 task) != 0)
1502 nfs_release_seqid(data->o_arg.seqid); 1571 nfs_release_seqid(data->o_arg.seqid);
1572
1573 /* Set the create mode (note dependency on the session type) */
1574 data->o_arg.createmode = NFS4_CREATE_UNCHECKED;
1575 if (data->o_arg.open_flags & O_EXCL) {
1576 data->o_arg.createmode = NFS4_CREATE_EXCLUSIVE;
1577 if (nfs4_has_persistent_session(clp))
1578 data->o_arg.createmode = NFS4_CREATE_GUARDED;
1579 else if (clp->cl_mvops->minor_version > 0)
1580 data->o_arg.createmode = NFS4_CREATE_EXCLUSIVE4_1;
1581 }
1503 return; 1582 return;
1504unlock_no_action: 1583unlock_no_action:
1505 rcu_read_unlock(); 1584 rcu_read_unlock();
@@ -1595,8 +1674,11 @@ static int nfs4_run_open_task(struct nfs4_opendata *data, int isrecover)
1595 data->rpc_done = 0; 1674 data->rpc_done = 0;
1596 data->rpc_status = 0; 1675 data->rpc_status = 0;
1597 data->cancelled = 0; 1676 data->cancelled = 0;
1598 if (isrecover) 1677 data->is_recover = 0;
1678 if (isrecover) {
1599 nfs4_set_sequence_privileged(&o_arg->seq_args); 1679 nfs4_set_sequence_privileged(&o_arg->seq_args);
1680 data->is_recover = 1;
1681 }
1600 task = rpc_run_task(&task_setup_data); 1682 task = rpc_run_task(&task_setup_data);
1601 if (IS_ERR(task)) 1683 if (IS_ERR(task))
1602 return PTR_ERR(task); 1684 return PTR_ERR(task);
@@ -1721,7 +1803,8 @@ static int _nfs4_open_expired(struct nfs_open_context *ctx, struct nfs4_state *s
1721 struct nfs4_opendata *opendata; 1803 struct nfs4_opendata *opendata;
1722 int ret; 1804 int ret;
1723 1805
1724 opendata = nfs4_open_recoverdata_alloc(ctx, state); 1806 opendata = nfs4_open_recoverdata_alloc(ctx, state,
1807 NFS4_OPEN_CLAIM_FH);
1725 if (IS_ERR(opendata)) 1808 if (IS_ERR(opendata))
1726 return PTR_ERR(opendata); 1809 return PTR_ERR(opendata);
1727 ret = nfs4_open_recover(opendata, state); 1810 ret = nfs4_open_recover(opendata, state);
@@ -1739,6 +1822,8 @@ static int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state
1739 1822
1740 do { 1823 do {
1741 err = _nfs4_open_expired(ctx, state); 1824 err = _nfs4_open_expired(ctx, state);
1825 if (nfs4_clear_cap_atomic_open_v1(server, err, &exception))
1826 continue;
1742 switch (err) { 1827 switch (err) {
1743 default: 1828 default:
1744 goto out; 1829 goto out;
@@ -1759,7 +1844,7 @@ static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *sta
1759 1844
1760 ctx = nfs4_state_find_open_context(state); 1845 ctx = nfs4_state_find_open_context(state);
1761 if (IS_ERR(ctx)) 1846 if (IS_ERR(ctx))
1762 return PTR_ERR(ctx); 1847 return -EAGAIN;
1763 ret = nfs4_do_open_expired(ctx, state); 1848 ret = nfs4_do_open_expired(ctx, state);
1764 put_nfs_open_context(ctx); 1849 put_nfs_open_context(ctx);
1765 return ret; 1850 return ret;
@@ -1821,6 +1906,7 @@ static int nfs41_check_open_stateid(struct nfs4_state *state)
1821 clear_bit(NFS_O_RDONLY_STATE, &state->flags); 1906 clear_bit(NFS_O_RDONLY_STATE, &state->flags);
1822 clear_bit(NFS_O_WRONLY_STATE, &state->flags); 1907 clear_bit(NFS_O_WRONLY_STATE, &state->flags);
1823 clear_bit(NFS_O_RDWR_STATE, &state->flags); 1908 clear_bit(NFS_O_RDWR_STATE, &state->flags);
1909 clear_bit(NFS_OPEN_STATE, &state->flags);
1824 } 1910 }
1825 return status; 1911 return status;
1826} 1912}
@@ -1881,10 +1967,8 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
1881 if (ret != 0) 1967 if (ret != 0)
1882 goto out; 1968 goto out;
1883 1969
1884 if (read_seqcount_retry(&sp->so_reclaim_seqcount, seq)) { 1970 if (read_seqcount_retry(&sp->so_reclaim_seqcount, seq))
1885 nfs4_schedule_stateid_recovery(server, state); 1971 nfs4_schedule_stateid_recovery(server, state);
1886 nfs4_wait_clnt_recover(server->nfs_client);
1887 }
1888 *res = state; 1972 *res = state;
1889out: 1973out:
1890 return ret; 1974 return ret;
@@ -1906,6 +1990,7 @@ static int _nfs4_do_open(struct inode *dir,
1906 struct nfs4_state *state = NULL; 1990 struct nfs4_state *state = NULL;
1907 struct nfs_server *server = NFS_SERVER(dir); 1991 struct nfs_server *server = NFS_SERVER(dir);
1908 struct nfs4_opendata *opendata; 1992 struct nfs4_opendata *opendata;
1993 enum open_claim_type4 claim = NFS4_OPEN_CLAIM_NULL;
1909 int status; 1994 int status;
1910 1995
1911 /* Protect against reboot recovery conflicts */ 1996 /* Protect against reboot recovery conflicts */
@@ -1921,7 +2006,10 @@ static int _nfs4_do_open(struct inode *dir,
1921 if (dentry->d_inode != NULL) 2006 if (dentry->d_inode != NULL)
1922 nfs4_return_incompatible_delegation(dentry->d_inode, fmode); 2007 nfs4_return_incompatible_delegation(dentry->d_inode, fmode);
1923 status = -ENOMEM; 2008 status = -ENOMEM;
1924 opendata = nfs4_opendata_alloc(dentry, sp, fmode, flags, sattr, GFP_KERNEL); 2009 if (dentry->d_inode)
2010 claim = NFS4_OPEN_CLAIM_FH;
2011 opendata = nfs4_opendata_alloc(dentry, sp, fmode, flags, sattr,
2012 claim, GFP_KERNEL);
1925 if (opendata == NULL) 2013 if (opendata == NULL)
1926 goto err_put_state_owner; 2014 goto err_put_state_owner;
1927 2015
@@ -1938,7 +2026,8 @@ static int _nfs4_do_open(struct inode *dir,
1938 if (status != 0) 2026 if (status != 0)
1939 goto err_opendata_put; 2027 goto err_opendata_put;
1940 2028
1941 if (opendata->o_arg.open_flags & O_EXCL) { 2029 if ((opendata->o_arg.open_flags & O_EXCL) &&
2030 (opendata->o_arg.createmode != NFS4_CREATE_GUARDED)) {
1942 nfs4_exclusive_attrset(opendata, sattr); 2031 nfs4_exclusive_attrset(opendata, sattr);
1943 2032
1944 nfs_fattr_init(opendata->o_res.f_attr); 2033 nfs_fattr_init(opendata->o_res.f_attr);
@@ -1979,6 +2068,7 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir,
1979 struct rpc_cred *cred, 2068 struct rpc_cred *cred,
1980 struct nfs4_threshold **ctx_th) 2069 struct nfs4_threshold **ctx_th)
1981{ 2070{
2071 struct nfs_server *server = NFS_SERVER(dir);
1982 struct nfs4_exception exception = { }; 2072 struct nfs4_exception exception = { };
1983 struct nfs4_state *res; 2073 struct nfs4_state *res;
1984 int status; 2074 int status;
@@ -2022,7 +2112,9 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir,
2022 exception.retry = 1; 2112 exception.retry = 1;
2023 continue; 2113 continue;
2024 } 2114 }
2025 res = ERR_PTR(nfs4_handle_exception(NFS_SERVER(dir), 2115 if (nfs4_clear_cap_atomic_open_v1(server, status, &exception))
2116 continue;
2117 res = ERR_PTR(nfs4_handle_exception(server,
2026 status, &exception)); 2118 status, &exception));
2027 } while (exception.retry); 2119 } while (exception.retry);
2028 return res; 2120 return res;
@@ -2050,20 +2142,25 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
2050 .rpc_cred = cred, 2142 .rpc_cred = cred,
2051 }; 2143 };
2052 unsigned long timestamp = jiffies; 2144 unsigned long timestamp = jiffies;
2145 fmode_t fmode;
2146 bool truncate;
2053 int status; 2147 int status;
2054 2148
2055 nfs_fattr_init(fattr); 2149 nfs_fattr_init(fattr);
2056 2150
2057 if (state != NULL) { 2151 /* Servers should only apply open mode checks for file size changes */
2152 truncate = (sattr->ia_valid & ATTR_SIZE) ? true : false;
2153 fmode = truncate ? FMODE_WRITE : FMODE_READ;
2154
2155 if (nfs4_copy_delegation_stateid(&arg.stateid, inode, fmode)) {
2156 /* Use that stateid */
2157 } else if (truncate && state != NULL && nfs4_valid_open_stateid(state)) {
2058 struct nfs_lockowner lockowner = { 2158 struct nfs_lockowner lockowner = {
2059 .l_owner = current->files, 2159 .l_owner = current->files,
2060 .l_pid = current->tgid, 2160 .l_pid = current->tgid,
2061 }; 2161 };
2062 nfs4_select_rw_stateid(&arg.stateid, state, FMODE_WRITE, 2162 nfs4_select_rw_stateid(&arg.stateid, state, FMODE_WRITE,
2063 &lockowner); 2163 &lockowner);
2064 } else if (nfs4_copy_delegation_stateid(&arg.stateid, inode,
2065 FMODE_WRITE)) {
2066 /* Use that stateid */
2067 } else 2164 } else
2068 nfs4_stateid_copy(&arg.stateid, &zero_stateid); 2165 nfs4_stateid_copy(&arg.stateid, &zero_stateid);
2069 2166
@@ -2087,6 +2184,13 @@ static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
2087 err = _nfs4_do_setattr(inode, cred, fattr, sattr, state); 2184 err = _nfs4_do_setattr(inode, cred, fattr, sattr, state);
2088 switch (err) { 2185 switch (err) {
2089 case -NFS4ERR_OPENMODE: 2186 case -NFS4ERR_OPENMODE:
2187 if (!(sattr->ia_valid & ATTR_SIZE)) {
2188 pr_warn_once("NFSv4: server %s is incorrectly "
2189 "applying open mode checks to "
2190 "a SETATTR that is not "
2191 "changing file size.\n",
2192 server->nfs_client->cl_hostname);
2193 }
2090 if (state && !(state->state & FMODE_WRITE)) { 2194 if (state && !(state->state & FMODE_WRITE)) {
2091 err = -EBADF; 2195 err = -EBADF;
2092 if (sattr->ia_valid & ATTR_OPEN) 2196 if (sattr->ia_valid & ATTR_OPEN)
@@ -2130,11 +2234,19 @@ static void nfs4_close_clear_stateid_flags(struct nfs4_state *state,
2130 fmode_t fmode) 2234 fmode_t fmode)
2131{ 2235{
2132 spin_lock(&state->owner->so_lock); 2236 spin_lock(&state->owner->so_lock);
2133 if (!(fmode & FMODE_READ)) 2237 clear_bit(NFS_O_RDWR_STATE, &state->flags);
2238 switch (fmode & (FMODE_READ|FMODE_WRITE)) {
2239 case FMODE_WRITE:
2134 clear_bit(NFS_O_RDONLY_STATE, &state->flags); 2240 clear_bit(NFS_O_RDONLY_STATE, &state->flags);
2135 if (!(fmode & FMODE_WRITE)) 2241 break;
2242 case FMODE_READ:
2136 clear_bit(NFS_O_WRONLY_STATE, &state->flags); 2243 clear_bit(NFS_O_WRONLY_STATE, &state->flags);
2137 clear_bit(NFS_O_RDWR_STATE, &state->flags); 2244 break;
2245 case 0:
2246 clear_bit(NFS_O_RDONLY_STATE, &state->flags);
2247 clear_bit(NFS_O_WRONLY_STATE, &state->flags);
2248 clear_bit(NFS_OPEN_STATE, &state->flags);
2249 }
2138 spin_unlock(&state->owner->so_lock); 2250 spin_unlock(&state->owner->so_lock);
2139} 2251}
2140 2252
@@ -2202,6 +2314,8 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
2202 calldata->arg.fmode &= ~FMODE_WRITE; 2314 calldata->arg.fmode &= ~FMODE_WRITE;
2203 } 2315 }
2204 } 2316 }
2317 if (!nfs4_valid_open_stateid(state))
2318 call_close = 0;
2205 spin_unlock(&state->owner->so_lock); 2319 spin_unlock(&state->owner->so_lock);
2206 2320
2207 if (!call_close) { 2321 if (!call_close) {
@@ -2212,8 +2326,10 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
2212 if (calldata->arg.fmode == 0) { 2326 if (calldata->arg.fmode == 0) {
2213 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE]; 2327 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE];
2214 if (calldata->roc && 2328 if (calldata->roc &&
2215 pnfs_roc_drain(inode, &calldata->roc_barrier, task)) 2329 pnfs_roc_drain(inode, &calldata->roc_barrier, task)) {
2330 nfs_release_seqid(calldata->arg.seqid);
2216 goto out_wait; 2331 goto out_wait;
2332 }
2217 } 2333 }
2218 2334
2219 nfs_fattr_init(calldata->res.fattr); 2335 nfs_fattr_init(calldata->res.fattr);
@@ -2444,7 +2560,7 @@ static int nfs4_lookup_root_sec(struct nfs_server *server, struct nfs_fh *fhandl
2444 2560
2445 auth = rpcauth_create(flavor, server->client); 2561 auth = rpcauth_create(flavor, server->client);
2446 if (IS_ERR(auth)) { 2562 if (IS_ERR(auth)) {
2447 ret = -EIO; 2563 ret = -EACCES;
2448 goto out; 2564 goto out;
2449 } 2565 }
2450 ret = nfs4_lookup_root(server, fhandle, info); 2566 ret = nfs4_lookup_root(server, fhandle, info);
@@ -2452,27 +2568,36 @@ out:
2452 return ret; 2568 return ret;
2453} 2569}
2454 2570
2571/*
2572 * Retry pseudoroot lookup with various security flavors. We do this when:
2573 *
2574 * NFSv4.0: the PUTROOTFH operation returns NFS4ERR_WRONGSEC
2575 * NFSv4.1: the server does not support the SECINFO_NO_NAME operation
2576 *
2577 * Returns zero on success, or a negative NFS4ERR value, or a
2578 * negative errno value.
2579 */
2455static int nfs4_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle, 2580static int nfs4_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
2456 struct nfs_fsinfo *info) 2581 struct nfs_fsinfo *info)
2457{ 2582{
2458 int i, len, status = 0; 2583 /* Per 3530bis 15.33.5 */
2459 rpc_authflavor_t flav_array[NFS_MAX_SECFLAVORS]; 2584 static const rpc_authflavor_t flav_array[] = {
2460 2585 RPC_AUTH_GSS_KRB5P,
2461 len = rpcauth_list_flavors(flav_array, ARRAY_SIZE(flav_array)); 2586 RPC_AUTH_GSS_KRB5I,
2462 if (len < 0) 2587 RPC_AUTH_GSS_KRB5,
2463 return len; 2588 RPC_AUTH_UNIX, /* courtesy */
2464 2589 RPC_AUTH_NULL,
2465 for (i = 0; i < len; i++) { 2590 };
2466 /* AUTH_UNIX is the default flavor if none was specified, 2591 int status = -EPERM;
2467 * thus has already been tried. */ 2592 size_t i;
2468 if (flav_array[i] == RPC_AUTH_UNIX)
2469 continue;
2470 2593
2594 for (i = 0; i < ARRAY_SIZE(flav_array); i++) {
2471 status = nfs4_lookup_root_sec(server, fhandle, info, flav_array[i]); 2595 status = nfs4_lookup_root_sec(server, fhandle, info, flav_array[i]);
2472 if (status == -NFS4ERR_WRONGSEC || status == -EACCES) 2596 if (status == -NFS4ERR_WRONGSEC || status == -EACCES)
2473 continue; 2597 continue;
2474 break; 2598 break;
2475 } 2599 }
2600
2476 /* 2601 /*
2477 * -EACCESS could mean that the user doesn't have correct permissions 2602 * -EACCESS could mean that the user doesn't have correct permissions
2478 * to access the mount. It could also mean that we tried to mount 2603 * to access the mount. It could also mean that we tried to mount
@@ -2485,24 +2610,36 @@ static int nfs4_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
2485 return status; 2610 return status;
2486} 2611}
2487 2612
2488/* 2613static int nfs4_do_find_root_sec(struct nfs_server *server,
2489 * get the file handle for the "/" directory on the server 2614 struct nfs_fh *fhandle, struct nfs_fsinfo *info)
2615{
2616 int mv = server->nfs_client->cl_minorversion;
2617 return nfs_v4_minor_ops[mv]->find_root_sec(server, fhandle, info);
2618}
2619
2620/**
2621 * nfs4_proc_get_rootfh - get file handle for server's pseudoroot
2622 * @server: initialized nfs_server handle
2623 * @fhandle: we fill in the pseudo-fs root file handle
2624 * @info: we fill in an FSINFO struct
2625 *
2626 * Returns zero on success, or a negative errno.
2490 */ 2627 */
2491int nfs4_proc_get_rootfh(struct nfs_server *server, struct nfs_fh *fhandle, 2628int nfs4_proc_get_rootfh(struct nfs_server *server, struct nfs_fh *fhandle,
2492 struct nfs_fsinfo *info) 2629 struct nfs_fsinfo *info)
2493{ 2630{
2494 int minor_version = server->nfs_client->cl_minorversion; 2631 int status;
2495 int status = nfs4_lookup_root(server, fhandle, info); 2632
2496 if ((status == -NFS4ERR_WRONGSEC) && !(server->flags & NFS_MOUNT_SECFLAVOUR)) 2633 status = nfs4_lookup_root(server, fhandle, info);
2497 /* 2634 if ((status == -NFS4ERR_WRONGSEC) &&
2498 * A status of -NFS4ERR_WRONGSEC will be mapped to -EPERM 2635 !(server->flags & NFS_MOUNT_SECFLAVOUR))
2499 * by nfs4_map_errors() as this function exits. 2636 status = nfs4_do_find_root_sec(server, fhandle, info);
2500 */ 2637
2501 status = nfs_v4_minor_ops[minor_version]->find_root_sec(server, fhandle, info);
2502 if (status == 0) 2638 if (status == 0)
2503 status = nfs4_server_capabilities(server, fhandle); 2639 status = nfs4_server_capabilities(server, fhandle);
2504 if (status == 0) 2640 if (status == 0)
2505 status = nfs4_do_fsinfo(server, fhandle, info); 2641 status = nfs4_do_fsinfo(server, fhandle, info);
2642
2506 return nfs4_map_errors(status); 2643 return nfs4_map_errors(status);
2507} 2644}
2508 2645
@@ -3381,12 +3518,21 @@ static int _nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
3381static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo) 3518static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
3382{ 3519{
3383 struct nfs4_exception exception = { }; 3520 struct nfs4_exception exception = { };
3521 unsigned long now = jiffies;
3384 int err; 3522 int err;
3385 3523
3386 do { 3524 do {
3387 err = nfs4_handle_exception(server, 3525 err = _nfs4_do_fsinfo(server, fhandle, fsinfo);
3388 _nfs4_do_fsinfo(server, fhandle, fsinfo), 3526 if (err == 0) {
3389 &exception); 3527 struct nfs_client *clp = server->nfs_client;
3528
3529 spin_lock(&clp->cl_lock);
3530 clp->cl_lease_time = fsinfo->lease_time * HZ;
3531 clp->cl_last_renewal = now;
3532 spin_unlock(&clp->cl_lock);
3533 break;
3534 }
3535 err = nfs4_handle_exception(server, err, &exception);
3390 } while (exception.retry); 3536 } while (exception.retry);
3391 return err; 3537 return err;
3392} 3538}
@@ -3446,6 +3592,46 @@ static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
3446 return err; 3592 return err;
3447} 3593}
3448 3594
3595int nfs4_set_rw_stateid(nfs4_stateid *stateid,
3596 const struct nfs_open_context *ctx,
3597 const struct nfs_lock_context *l_ctx,
3598 fmode_t fmode)
3599{
3600 const struct nfs_lockowner *lockowner = NULL;
3601
3602 if (l_ctx != NULL)
3603 lockowner = &l_ctx->lockowner;
3604 return nfs4_select_rw_stateid(stateid, ctx->state, fmode, lockowner);
3605}
3606EXPORT_SYMBOL_GPL(nfs4_set_rw_stateid);
3607
3608static bool nfs4_stateid_is_current(nfs4_stateid *stateid,
3609 const struct nfs_open_context *ctx,
3610 const struct nfs_lock_context *l_ctx,
3611 fmode_t fmode)
3612{
3613 nfs4_stateid current_stateid;
3614
3615 if (nfs4_set_rw_stateid(&current_stateid, ctx, l_ctx, fmode))
3616 return false;
3617 return nfs4_stateid_match(stateid, &current_stateid);
3618}
3619
3620static bool nfs4_error_stateid_expired(int err)
3621{
3622 switch (err) {
3623 case -NFS4ERR_DELEG_REVOKED:
3624 case -NFS4ERR_ADMIN_REVOKED:
3625 case -NFS4ERR_BAD_STATEID:
3626 case -NFS4ERR_STALE_STATEID:
3627 case -NFS4ERR_OLD_STATEID:
3628 case -NFS4ERR_OPENMODE:
3629 case -NFS4ERR_EXPIRED:
3630 return true;
3631 }
3632 return false;
3633}
3634
3449void __nfs4_read_done_cb(struct nfs_read_data *data) 3635void __nfs4_read_done_cb(struct nfs_read_data *data)
3450{ 3636{
3451 nfs_invalidate_atime(data->header->inode); 3637 nfs_invalidate_atime(data->header->inode);
@@ -3466,6 +3652,20 @@ static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_read_data *data)
3466 return 0; 3652 return 0;
3467} 3653}
3468 3654
3655static bool nfs4_read_stateid_changed(struct rpc_task *task,
3656 struct nfs_readargs *args)
3657{
3658
3659 if (!nfs4_error_stateid_expired(task->tk_status) ||
3660 nfs4_stateid_is_current(&args->stateid,
3661 args->context,
3662 args->lock_context,
3663 FMODE_READ))
3664 return false;
3665 rpc_restart_call_prepare(task);
3666 return true;
3667}
3668
3469static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data) 3669static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data)
3470{ 3670{
3471 3671
@@ -3473,7 +3673,8 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data)
3473 3673
3474 if (!nfs4_sequence_done(task, &data->res.seq_res)) 3674 if (!nfs4_sequence_done(task, &data->res.seq_res))
3475 return -EAGAIN; 3675 return -EAGAIN;
3476 3676 if (nfs4_read_stateid_changed(task, &data->args))
3677 return -EAGAIN;
3477 return data->read_done_cb ? data->read_done_cb(task, data) : 3678 return data->read_done_cb ? data->read_done_cb(task, data) :
3478 nfs4_read_done_cb(task, data); 3679 nfs4_read_done_cb(task, data);
3479} 3680}
@@ -3488,10 +3689,13 @@ static void nfs4_proc_read_setup(struct nfs_read_data *data, struct rpc_message
3488 3689
3489static void nfs4_proc_read_rpc_prepare(struct rpc_task *task, struct nfs_read_data *data) 3690static void nfs4_proc_read_rpc_prepare(struct rpc_task *task, struct nfs_read_data *data)
3490{ 3691{
3491 nfs4_setup_sequence(NFS_SERVER(data->header->inode), 3692 if (nfs4_setup_sequence(NFS_SERVER(data->header->inode),
3492 &data->args.seq_args, 3693 &data->args.seq_args,
3493 &data->res.seq_res, 3694 &data->res.seq_res,
3494 task); 3695 task))
3696 return;
3697 nfs4_set_rw_stateid(&data->args.stateid, data->args.context,
3698 data->args.lock_context, FMODE_READ);
3495} 3699}
3496 3700
3497static int nfs4_write_done_cb(struct rpc_task *task, struct nfs_write_data *data) 3701static int nfs4_write_done_cb(struct rpc_task *task, struct nfs_write_data *data)
@@ -3509,10 +3713,26 @@ static int nfs4_write_done_cb(struct rpc_task *task, struct nfs_write_data *data
3509 return 0; 3713 return 0;
3510} 3714}
3511 3715
3716static bool nfs4_write_stateid_changed(struct rpc_task *task,
3717 struct nfs_writeargs *args)
3718{
3719
3720 if (!nfs4_error_stateid_expired(task->tk_status) ||
3721 nfs4_stateid_is_current(&args->stateid,
3722 args->context,
3723 args->lock_context,
3724 FMODE_WRITE))
3725 return false;
3726 rpc_restart_call_prepare(task);
3727 return true;
3728}
3729
3512static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data) 3730static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
3513{ 3731{
3514 if (!nfs4_sequence_done(task, &data->res.seq_res)) 3732 if (!nfs4_sequence_done(task, &data->res.seq_res))
3515 return -EAGAIN; 3733 return -EAGAIN;
3734 if (nfs4_write_stateid_changed(task, &data->args))
3735 return -EAGAIN;
3516 return data->write_done_cb ? data->write_done_cb(task, data) : 3736 return data->write_done_cb ? data->write_done_cb(task, data) :
3517 nfs4_write_done_cb(task, data); 3737 nfs4_write_done_cb(task, data);
3518} 3738}
@@ -3552,10 +3772,13 @@ static void nfs4_proc_write_setup(struct nfs_write_data *data, struct rpc_messag
3552 3772
3553static void nfs4_proc_write_rpc_prepare(struct rpc_task *task, struct nfs_write_data *data) 3773static void nfs4_proc_write_rpc_prepare(struct rpc_task *task, struct nfs_write_data *data)
3554{ 3774{
3555 nfs4_setup_sequence(NFS_SERVER(data->header->inode), 3775 if (nfs4_setup_sequence(NFS_SERVER(data->header->inode),
3556 &data->args.seq_args, 3776 &data->args.seq_args,
3557 &data->res.seq_res, 3777 &data->res.seq_res,
3558 task); 3778 task))
3779 return;
3780 nfs4_set_rw_stateid(&data->args.stateid, data->args.context,
3781 data->args.lock_context, FMODE_WRITE);
3559} 3782}
3560 3783
3561static void nfs4_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data) 3784static void nfs4_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data)
@@ -3657,7 +3880,7 @@ static int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred,
3657 return -ENOMEM; 3880 return -ENOMEM;
3658 data->client = clp; 3881 data->client = clp;
3659 data->timestamp = jiffies; 3882 data->timestamp = jiffies;
3660 return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT, 3883 return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT,
3661 &nfs4_renew_ops, data); 3884 &nfs4_renew_ops, data);
3662} 3885}
3663 3886
@@ -3671,7 +3894,7 @@ static int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred)
3671 unsigned long now = jiffies; 3894 unsigned long now = jiffies;
3672 int status; 3895 int status;
3673 3896
3674 status = rpc_call_sync(clp->cl_rpcclient, &msg, 0); 3897 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
3675 if (status < 0) 3898 if (status < 0)
3676 return status; 3899 return status;
3677 do_renew_lease(clp, now); 3900 do_renew_lease(clp, now);
@@ -3981,11 +4204,14 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
3981 case -NFS4ERR_OPENMODE: 4204 case -NFS4ERR_OPENMODE:
3982 if (state == NULL) 4205 if (state == NULL)
3983 break; 4206 break;
3984 nfs4_schedule_stateid_recovery(server, state); 4207 if (nfs4_schedule_stateid_recovery(server, state) < 0)
4208 goto stateid_invalid;
3985 goto wait_on_recovery; 4209 goto wait_on_recovery;
3986 case -NFS4ERR_EXPIRED: 4210 case -NFS4ERR_EXPIRED:
3987 if (state != NULL) 4211 if (state != NULL) {
3988 nfs4_schedule_stateid_recovery(server, state); 4212 if (nfs4_schedule_stateid_recovery(server, state) < 0)
4213 goto stateid_invalid;
4214 }
3989 case -NFS4ERR_STALE_STATEID: 4215 case -NFS4ERR_STALE_STATEID:
3990 case -NFS4ERR_STALE_CLIENTID: 4216 case -NFS4ERR_STALE_CLIENTID:
3991 nfs4_schedule_lease_recovery(clp); 4217 nfs4_schedule_lease_recovery(clp);
@@ -4017,6 +4243,9 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
4017 } 4243 }
4018 task->tk_status = nfs4_map_errors(task->tk_status); 4244 task->tk_status = nfs4_map_errors(task->tk_status);
4019 return 0; 4245 return 0;
4246stateid_invalid:
4247 task->tk_status = -EIO;
4248 return 0;
4020wait_on_recovery: 4249wait_on_recovery:
4021 rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); 4250 rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);
4022 if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0) 4251 if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)
@@ -4144,27 +4373,17 @@ int nfs4_proc_setclientid_confirm(struct nfs_client *clp,
4144 struct nfs4_setclientid_res *arg, 4373 struct nfs4_setclientid_res *arg,
4145 struct rpc_cred *cred) 4374 struct rpc_cred *cred)
4146{ 4375{
4147 struct nfs_fsinfo fsinfo;
4148 struct rpc_message msg = { 4376 struct rpc_message msg = {
4149 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM], 4377 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM],
4150 .rpc_argp = arg, 4378 .rpc_argp = arg,
4151 .rpc_resp = &fsinfo,
4152 .rpc_cred = cred, 4379 .rpc_cred = cred,
4153 }; 4380 };
4154 unsigned long now;
4155 int status; 4381 int status;
4156 4382
4157 dprintk("NFS call setclientid_confirm auth=%s, (client ID %llx)\n", 4383 dprintk("NFS call setclientid_confirm auth=%s, (client ID %llx)\n",
4158 clp->cl_rpcclient->cl_auth->au_ops->au_name, 4384 clp->cl_rpcclient->cl_auth->au_ops->au_name,
4159 clp->cl_clientid); 4385 clp->cl_clientid);
4160 now = jiffies;
4161 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 4386 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
4162 if (status == 0) {
4163 spin_lock(&clp->cl_lock);
4164 clp->cl_lease_time = fsinfo.lease_time * HZ;
4165 clp->cl_last_renewal = now;
4166 spin_unlock(&clp->cl_lock);
4167 }
4168 dprintk("NFS reply setclientid_confirm: %d\n", status); 4387 dprintk("NFS reply setclientid_confirm: %d\n", status);
4169 return status; 4388 return status;
4170} 4389}
@@ -4628,17 +4847,23 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
4628 if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0) { 4847 if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0) {
4629 goto out_release_lock_seqid; 4848 goto out_release_lock_seqid;
4630 } 4849 }
4631 data->arg.open_stateid = &state->stateid; 4850 data->arg.open_stateid = &state->open_stateid;
4632 data->arg.new_lock_owner = 1; 4851 data->arg.new_lock_owner = 1;
4633 data->res.open_seqid = data->arg.open_seqid; 4852 data->res.open_seqid = data->arg.open_seqid;
4634 } else 4853 } else
4635 data->arg.new_lock_owner = 0; 4854 data->arg.new_lock_owner = 0;
4855 if (!nfs4_valid_open_stateid(state)) {
4856 data->rpc_status = -EBADF;
4857 task->tk_action = NULL;
4858 goto out_release_open_seqid;
4859 }
4636 data->timestamp = jiffies; 4860 data->timestamp = jiffies;
4637 if (nfs4_setup_sequence(data->server, 4861 if (nfs4_setup_sequence(data->server,
4638 &data->arg.seq_args, 4862 &data->arg.seq_args,
4639 &data->res.seq_res, 4863 &data->res.seq_res,
4640 task) == 0) 4864 task) == 0)
4641 return; 4865 return;
4866out_release_open_seqid:
4642 nfs_release_seqid(data->arg.open_seqid); 4867 nfs_release_seqid(data->arg.open_seqid);
4643out_release_lock_seqid: 4868out_release_lock_seqid:
4644 nfs_release_seqid(data->arg.lock_seqid); 4869 nfs_release_seqid(data->arg.lock_seqid);
@@ -4984,58 +5209,16 @@ nfs4_proc_lock(struct file *filp, int cmd, struct file_lock *request)
4984 return status; 5209 return status;
4985} 5210}
4986 5211
4987int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl) 5212int nfs4_lock_delegation_recall(struct file_lock *fl, struct nfs4_state *state, const nfs4_stateid *stateid)
4988{ 5213{
4989 struct nfs_server *server = NFS_SERVER(state->inode); 5214 struct nfs_server *server = NFS_SERVER(state->inode);
4990 struct nfs4_exception exception = { };
4991 int err; 5215 int err;
4992 5216
4993 err = nfs4_set_lock_state(state, fl); 5217 err = nfs4_set_lock_state(state, fl);
4994 if (err != 0) 5218 if (err != 0)
4995 goto out; 5219 return err;
4996 do { 5220 err = _nfs4_do_setlk(state, F_SETLK, fl, NFS_LOCK_NEW);
4997 err = _nfs4_do_setlk(state, F_SETLK, fl, NFS_LOCK_NEW); 5221 return nfs4_handle_delegation_recall_error(server, state, stateid, err);
4998 switch (err) {
4999 default:
5000 printk(KERN_ERR "NFS: %s: unhandled error "
5001 "%d.\n", __func__, err);
5002 case 0:
5003 case -ESTALE:
5004 goto out;
5005 case -NFS4ERR_STALE_CLIENTID:
5006 case -NFS4ERR_STALE_STATEID:
5007 set_bit(NFS_DELEGATED_STATE, &state->flags);
5008 case -NFS4ERR_EXPIRED:
5009 nfs4_schedule_lease_recovery(server->nfs_client);
5010 err = -EAGAIN;
5011 goto out;
5012 case -NFS4ERR_BADSESSION:
5013 case -NFS4ERR_BADSLOT:
5014 case -NFS4ERR_BAD_HIGH_SLOT:
5015 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
5016 case -NFS4ERR_DEADSESSION:
5017 set_bit(NFS_DELEGATED_STATE, &state->flags);
5018 nfs4_schedule_session_recovery(server->nfs_client->cl_session, err);
5019 err = -EAGAIN;
5020 goto out;
5021 case -NFS4ERR_DELEG_REVOKED:
5022 case -NFS4ERR_ADMIN_REVOKED:
5023 case -NFS4ERR_BAD_STATEID:
5024 case -NFS4ERR_OPENMODE:
5025 nfs4_schedule_stateid_recovery(server, state);
5026 err = 0;
5027 goto out;
5028 case -ENOMEM:
5029 case -NFS4ERR_DENIED:
5030 /* kill_proc(fl->fl_pid, SIGLOST, 1); */
5031 err = 0;
5032 goto out;
5033 }
5034 set_bit(NFS_DELEGATED_STATE, &state->flags);
5035 err = nfs4_handle_exception(server, err, &exception);
5036 } while (exception.retry);
5037out:
5038 return err;
5039} 5222}
5040 5223
5041struct nfs_release_lockowner_data { 5224struct nfs_release_lockowner_data {
@@ -5849,7 +6032,7 @@ static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp,
5849 .rpc_client = clp->cl_rpcclient, 6032 .rpc_client = clp->cl_rpcclient,
5850 .rpc_message = &msg, 6033 .rpc_message = &msg,
5851 .callback_ops = &nfs41_sequence_ops, 6034 .callback_ops = &nfs41_sequence_ops,
5852 .flags = RPC_TASK_ASYNC | RPC_TASK_SOFT, 6035 .flags = RPC_TASK_ASYNC | RPC_TASK_TIMEOUT,
5853 }; 6036 };
5854 6037
5855 if (!atomic_inc_not_zero(&clp->cl_count)) 6038 if (!atomic_inc_not_zero(&clp->cl_count))
@@ -6726,6 +6909,10 @@ static const struct nfs4_state_maintenance_ops nfs41_state_renewal_ops = {
6726 6909
6727static const struct nfs4_minor_version_ops nfs_v4_0_minor_ops = { 6910static const struct nfs4_minor_version_ops nfs_v4_0_minor_ops = {
6728 .minor_version = 0, 6911 .minor_version = 0,
6912 .init_caps = NFS_CAP_READDIRPLUS
6913 | NFS_CAP_ATOMIC_OPEN
6914 | NFS_CAP_CHANGE_ATTR
6915 | NFS_CAP_POSIX_LOCK,
6729 .call_sync = _nfs4_call_sync, 6916 .call_sync = _nfs4_call_sync,
6730 .match_stateid = nfs4_match_stateid, 6917 .match_stateid = nfs4_match_stateid,
6731 .find_root_sec = nfs4_find_root_sec, 6918 .find_root_sec = nfs4_find_root_sec,
@@ -6737,6 +6924,12 @@ static const struct nfs4_minor_version_ops nfs_v4_0_minor_ops = {
6737#if defined(CONFIG_NFS_V4_1) 6924#if defined(CONFIG_NFS_V4_1)
6738static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = { 6925static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = {
6739 .minor_version = 1, 6926 .minor_version = 1,
6927 .init_caps = NFS_CAP_READDIRPLUS
6928 | NFS_CAP_ATOMIC_OPEN
6929 | NFS_CAP_CHANGE_ATTR
6930 | NFS_CAP_POSIX_LOCK
6931 | NFS_CAP_STATEID_NFSV41
6932 | NFS_CAP_ATOMIC_OPEN_V1,
6740 .call_sync = nfs4_call_sync_sequence, 6933 .call_sync = nfs4_call_sync_sequence,
6741 .match_stateid = nfs41_match_stateid, 6934 .match_stateid = nfs41_match_stateid,
6742 .find_root_sec = nfs41_find_root_sec, 6935 .find_root_sec = nfs41_find_root_sec,
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index d41a3518509f..0b32f9483b7a 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -154,18 +154,6 @@ struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp)
154 return cred; 154 return cred;
155} 155}
156 156
157static void nfs4_clear_machine_cred(struct nfs_client *clp)
158{
159 struct rpc_cred *cred;
160
161 spin_lock(&clp->cl_lock);
162 cred = clp->cl_machine_cred;
163 clp->cl_machine_cred = NULL;
164 spin_unlock(&clp->cl_lock);
165 if (cred != NULL)
166 put_rpccred(cred);
167}
168
169static struct rpc_cred * 157static struct rpc_cred *
170nfs4_get_renew_cred_server_locked(struct nfs_server *server) 158nfs4_get_renew_cred_server_locked(struct nfs_server *server)
171{ 159{
@@ -699,6 +687,8 @@ __nfs4_find_state_byowner(struct inode *inode, struct nfs4_state_owner *owner)
699 list_for_each_entry(state, &nfsi->open_states, inode_states) { 687 list_for_each_entry(state, &nfsi->open_states, inode_states) {
700 if (state->owner != owner) 688 if (state->owner != owner)
701 continue; 689 continue;
690 if (!nfs4_valid_open_stateid(state))
691 continue;
702 if (atomic_inc_not_zero(&state->count)) 692 if (atomic_inc_not_zero(&state->count))
703 return state; 693 return state;
704 } 694 }
@@ -987,13 +977,14 @@ int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl)
987 return 0; 977 return 0;
988} 978}
989 979
990static bool nfs4_copy_lock_stateid(nfs4_stateid *dst, struct nfs4_state *state, 980static int nfs4_copy_lock_stateid(nfs4_stateid *dst,
981 struct nfs4_state *state,
991 const struct nfs_lockowner *lockowner) 982 const struct nfs_lockowner *lockowner)
992{ 983{
993 struct nfs4_lock_state *lsp; 984 struct nfs4_lock_state *lsp;
994 fl_owner_t fl_owner; 985 fl_owner_t fl_owner;
995 pid_t fl_pid; 986 pid_t fl_pid;
996 bool ret = false; 987 int ret = -ENOENT;
997 988
998 989
999 if (lockowner == NULL) 990 if (lockowner == NULL)
@@ -1008,7 +999,10 @@ static bool nfs4_copy_lock_stateid(nfs4_stateid *dst, struct nfs4_state *state,
1008 lsp = __nfs4_find_lock_state(state, fl_owner, fl_pid, NFS4_ANY_LOCK_TYPE); 999 lsp = __nfs4_find_lock_state(state, fl_owner, fl_pid, NFS4_ANY_LOCK_TYPE);
1009 if (lsp != NULL && test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags) != 0) { 1000 if (lsp != NULL && test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags) != 0) {
1010 nfs4_stateid_copy(dst, &lsp->ls_stateid); 1001 nfs4_stateid_copy(dst, &lsp->ls_stateid);
1011 ret = true; 1002 ret = 0;
1003 smp_rmb();
1004 if (!list_empty(&lsp->ls_seqid.list))
1005 ret = -EWOULDBLOCK;
1012 } 1006 }
1013 spin_unlock(&state->state_lock); 1007 spin_unlock(&state->state_lock);
1014 nfs4_put_lock_state(lsp); 1008 nfs4_put_lock_state(lsp);
@@ -1016,28 +1010,44 @@ out:
1016 return ret; 1010 return ret;
1017} 1011}
1018 1012
1019static void nfs4_copy_open_stateid(nfs4_stateid *dst, struct nfs4_state *state) 1013static int nfs4_copy_open_stateid(nfs4_stateid *dst, struct nfs4_state *state)
1020{ 1014{
1015 const nfs4_stateid *src;
1016 int ret;
1021 int seq; 1017 int seq;
1022 1018
1023 do { 1019 do {
1020 src = &zero_stateid;
1024 seq = read_seqbegin(&state->seqlock); 1021 seq = read_seqbegin(&state->seqlock);
1025 nfs4_stateid_copy(dst, &state->stateid); 1022 if (test_bit(NFS_OPEN_STATE, &state->flags))
1023 src = &state->open_stateid;
1024 nfs4_stateid_copy(dst, src);
1025 ret = 0;
1026 smp_rmb();
1027 if (!list_empty(&state->owner->so_seqid.list))
1028 ret = -EWOULDBLOCK;
1026 } while (read_seqretry(&state->seqlock, seq)); 1029 } while (read_seqretry(&state->seqlock, seq));
1030 return ret;
1027} 1031}
1028 1032
1029/* 1033/*
1030 * Byte-range lock aware utility to initialize the stateid of read/write 1034 * Byte-range lock aware utility to initialize the stateid of read/write
1031 * requests. 1035 * requests.
1032 */ 1036 */
1033void nfs4_select_rw_stateid(nfs4_stateid *dst, struct nfs4_state *state, 1037int nfs4_select_rw_stateid(nfs4_stateid *dst, struct nfs4_state *state,
1034 fmode_t fmode, const struct nfs_lockowner *lockowner) 1038 fmode_t fmode, const struct nfs_lockowner *lockowner)
1035{ 1039{
1040 int ret = 0;
1036 if (nfs4_copy_delegation_stateid(dst, state->inode, fmode)) 1041 if (nfs4_copy_delegation_stateid(dst, state->inode, fmode))
1037 return; 1042 goto out;
1038 if (nfs4_copy_lock_stateid(dst, state, lockowner)) 1043 ret = nfs4_copy_lock_stateid(dst, state, lockowner);
1039 return; 1044 if (ret != -ENOENT)
1040 nfs4_copy_open_stateid(dst, state); 1045 goto out;
1046 ret = nfs4_copy_open_stateid(dst, state);
1047out:
1048 if (nfs_server_capable(state->inode, NFS_CAP_STATEID_NFSV41))
1049 dst->seqid = 0;
1050 return ret;
1041} 1051}
1042 1052
1043struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask) 1053struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask)
@@ -1286,14 +1296,17 @@ static int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_s
1286 return 1; 1296 return 1;
1287} 1297}
1288 1298
1289void nfs4_schedule_stateid_recovery(const struct nfs_server *server, struct nfs4_state *state) 1299int nfs4_schedule_stateid_recovery(const struct nfs_server *server, struct nfs4_state *state)
1290{ 1300{
1291 struct nfs_client *clp = server->nfs_client; 1301 struct nfs_client *clp = server->nfs_client;
1292 1302
1303 if (!nfs4_valid_open_stateid(state))
1304 return -EBADF;
1293 nfs4_state_mark_reclaim_nograce(clp, state); 1305 nfs4_state_mark_reclaim_nograce(clp, state);
1294 dprintk("%s: scheduling stateid recovery for server %s\n", __func__, 1306 dprintk("%s: scheduling stateid recovery for server %s\n", __func__,
1295 clp->cl_hostname); 1307 clp->cl_hostname);
1296 nfs4_schedule_state_manager(clp); 1308 nfs4_schedule_state_manager(clp);
1309 return 0;
1297} 1310}
1298EXPORT_SYMBOL_GPL(nfs4_schedule_stateid_recovery); 1311EXPORT_SYMBOL_GPL(nfs4_schedule_stateid_recovery);
1299 1312
@@ -1323,6 +1336,27 @@ void nfs_inode_find_state_and_recover(struct inode *inode,
1323 nfs4_schedule_state_manager(clp); 1336 nfs4_schedule_state_manager(clp);
1324} 1337}
1325 1338
1339static void nfs4_state_mark_open_context_bad(struct nfs4_state *state)
1340{
1341 struct inode *inode = state->inode;
1342 struct nfs_inode *nfsi = NFS_I(inode);
1343 struct nfs_open_context *ctx;
1344
1345 spin_lock(&inode->i_lock);
1346 list_for_each_entry(ctx, &nfsi->open_files, list) {
1347 if (ctx->state != state)
1348 continue;
1349 set_bit(NFS_CONTEXT_BAD, &ctx->flags);
1350 }
1351 spin_unlock(&inode->i_lock);
1352}
1353
1354static void nfs4_state_mark_recovery_failed(struct nfs4_state *state, int error)
1355{
1356 set_bit(NFS_STATE_RECOVERY_FAILED, &state->flags);
1357 nfs4_state_mark_open_context_bad(state);
1358}
1359
1326 1360
1327static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_recovery_ops *ops) 1361static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_recovery_ops *ops)
1328{ 1362{
@@ -1398,6 +1432,8 @@ restart:
1398 list_for_each_entry(state, &sp->so_states, open_states) { 1432 list_for_each_entry(state, &sp->so_states, open_states) {
1399 if (!test_and_clear_bit(ops->state_flag_bit, &state->flags)) 1433 if (!test_and_clear_bit(ops->state_flag_bit, &state->flags))
1400 continue; 1434 continue;
1435 if (!nfs4_valid_open_stateid(state))
1436 continue;
1401 if (state->state == 0) 1437 if (state->state == 0)
1402 continue; 1438 continue;
1403 atomic_inc(&state->count); 1439 atomic_inc(&state->count);
@@ -1430,11 +1466,10 @@ restart:
1430 * Open state on this file cannot be recovered 1466 * Open state on this file cannot be recovered
1431 * All we can do is revert to using the zero stateid. 1467 * All we can do is revert to using the zero stateid.
1432 */ 1468 */
1433 memset(&state->stateid, 0, 1469 nfs4_state_mark_recovery_failed(state, status);
1434 sizeof(state->stateid));
1435 /* Mark the file as being 'closed' */
1436 state->state = 0;
1437 break; 1470 break;
1471 case -EAGAIN:
1472 ssleep(1);
1438 case -NFS4ERR_ADMIN_REVOKED: 1473 case -NFS4ERR_ADMIN_REVOKED:
1439 case -NFS4ERR_STALE_STATEID: 1474 case -NFS4ERR_STALE_STATEID:
1440 case -NFS4ERR_BAD_STATEID: 1475 case -NFS4ERR_BAD_STATEID:
@@ -1696,6 +1731,10 @@ static int nfs4_check_lease(struct nfs_client *clp)
1696 } 1731 }
1697 status = ops->renew_lease(clp, cred); 1732 status = ops->renew_lease(clp, cred);
1698 put_rpccred(cred); 1733 put_rpccred(cred);
1734 if (status == -ETIMEDOUT) {
1735 set_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state);
1736 return 0;
1737 }
1699out: 1738out:
1700 return nfs4_recovery_handle_error(clp, status); 1739 return nfs4_recovery_handle_error(clp, status);
1701} 1740}
@@ -1725,10 +1764,6 @@ static int nfs4_handle_reclaim_lease_error(struct nfs_client *clp, int status)
1725 clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); 1764 clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
1726 return -EPERM; 1765 return -EPERM;
1727 case -EACCES: 1766 case -EACCES:
1728 if (clp->cl_machine_cred == NULL)
1729 return -EACCES;
1730 /* Handle case where the user hasn't set up machine creds */
1731 nfs4_clear_machine_cred(clp);
1732 case -NFS4ERR_DELAY: 1767 case -NFS4ERR_DELAY:
1733 case -ETIMEDOUT: 1768 case -ETIMEDOUT:
1734 case -EAGAIN: 1769 case -EAGAIN:
@@ -1823,31 +1858,18 @@ int nfs4_discover_server_trunking(struct nfs_client *clp,
1823{ 1858{
1824 const struct nfs4_state_recovery_ops *ops = 1859 const struct nfs4_state_recovery_ops *ops =
1825 clp->cl_mvops->reboot_recovery_ops; 1860 clp->cl_mvops->reboot_recovery_ops;
1826 rpc_authflavor_t *flavors, flav, save;
1827 struct rpc_clnt *clnt; 1861 struct rpc_clnt *clnt;
1828 struct rpc_cred *cred; 1862 struct rpc_cred *cred;
1829 int i, len, status; 1863 int i, status;
1830 1864
1831 dprintk("NFS: %s: testing '%s'\n", __func__, clp->cl_hostname); 1865 dprintk("NFS: %s: testing '%s'\n", __func__, clp->cl_hostname);
1832 1866
1833 len = NFS_MAX_SECFLAVORS;
1834 flavors = kcalloc(len, sizeof(*flavors), GFP_KERNEL);
1835 if (flavors == NULL) {
1836 status = -ENOMEM;
1837 goto out;
1838 }
1839 len = rpcauth_list_flavors(flavors, len);
1840 if (len < 0) {
1841 status = len;
1842 goto out_free;
1843 }
1844 clnt = clp->cl_rpcclient; 1867 clnt = clp->cl_rpcclient;
1845 save = clnt->cl_auth->au_flavor;
1846 i = 0; 1868 i = 0;
1847 1869
1848 mutex_lock(&nfs_clid_init_mutex); 1870 mutex_lock(&nfs_clid_init_mutex);
1849 status = -ENOENT;
1850again: 1871again:
1872 status = -ENOENT;
1851 cred = ops->get_clid_cred(clp); 1873 cred = ops->get_clid_cred(clp);
1852 if (cred == NULL) 1874 if (cred == NULL)
1853 goto out_unlock; 1875 goto out_unlock;
@@ -1857,12 +1879,6 @@ again:
1857 switch (status) { 1879 switch (status) {
1858 case 0: 1880 case 0:
1859 break; 1881 break;
1860
1861 case -EACCES:
1862 if (clp->cl_machine_cred == NULL)
1863 break;
1864 /* Handle case where the user hasn't set up machine creds */
1865 nfs4_clear_machine_cred(clp);
1866 case -NFS4ERR_DELAY: 1882 case -NFS4ERR_DELAY:
1867 case -ETIMEDOUT: 1883 case -ETIMEDOUT:
1868 case -EAGAIN: 1884 case -EAGAIN:
@@ -1871,17 +1887,12 @@ again:
1871 dprintk("NFS: %s after status %d, retrying\n", 1887 dprintk("NFS: %s after status %d, retrying\n",
1872 __func__, status); 1888 __func__, status);
1873 goto again; 1889 goto again;
1874 1890 case -EACCES:
1891 if (i++)
1892 break;
1875 case -NFS4ERR_CLID_INUSE: 1893 case -NFS4ERR_CLID_INUSE:
1876 case -NFS4ERR_WRONGSEC: 1894 case -NFS4ERR_WRONGSEC:
1877 status = -EPERM; 1895 clnt = rpc_clone_client_set_auth(clnt, RPC_AUTH_UNIX);
1878 if (i >= len)
1879 break;
1880
1881 flav = flavors[i++];
1882 if (flav == save)
1883 flav = flavors[i++];
1884 clnt = rpc_clone_client_set_auth(clnt, flav);
1885 if (IS_ERR(clnt)) { 1896 if (IS_ERR(clnt)) {
1886 status = PTR_ERR(clnt); 1897 status = PTR_ERR(clnt);
1887 break; 1898 break;
@@ -1903,13 +1914,15 @@ again:
1903 case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery 1914 case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery
1904 * in nfs4_exchange_id */ 1915 * in nfs4_exchange_id */
1905 status = -EKEYEXPIRED; 1916 status = -EKEYEXPIRED;
1917 break;
1918 default:
1919 pr_warn("NFS: %s unhandled error %d. Exiting with error EIO\n",
1920 __func__, status);
1921 status = -EIO;
1906 } 1922 }
1907 1923
1908out_unlock: 1924out_unlock:
1909 mutex_unlock(&nfs_clid_init_mutex); 1925 mutex_unlock(&nfs_clid_init_mutex);
1910out_free:
1911 kfree(flavors);
1912out:
1913 dprintk("NFS: %s: status = %d\n", __func__, status); 1926 dprintk("NFS: %s: status = %d\n", __func__, status);
1914 return status; 1927 return status;
1915} 1928}
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c
index 569b166cc050..a5e1a3026d48 100644
--- a/fs/nfs/nfs4super.c
+++ b/fs/nfs/nfs4super.c
@@ -252,6 +252,8 @@ struct dentry *nfs4_try_mount(int flags, const char *dev_name,
252 252
253 dfprintk(MOUNT, "--> nfs4_try_mount()\n"); 253 dfprintk(MOUNT, "--> nfs4_try_mount()\n");
254 254
255 if (data->auth_flavors[0] == RPC_AUTH_MAXFLAVOR)
256 data->auth_flavors[0] = RPC_AUTH_UNIX;
255 export_path = data->nfs_server.export_path; 257 export_path = data->nfs_server.export_path;
256 data->nfs_server.export_path = "/"; 258 data->nfs_server.export_path = "/";
257 root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, mount_info, 259 root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, mount_info,
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index e3edda554ac7..3c79c5878c6d 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -530,14 +530,10 @@ static int nfs4_stat_to_errno(int);
530 decode_setclientid_maxsz) 530 decode_setclientid_maxsz)
531#define NFS4_enc_setclientid_confirm_sz \ 531#define NFS4_enc_setclientid_confirm_sz \
532 (compound_encode_hdr_maxsz + \ 532 (compound_encode_hdr_maxsz + \
533 encode_setclientid_confirm_maxsz + \ 533 encode_setclientid_confirm_maxsz)
534 encode_putrootfh_maxsz + \
535 encode_fsinfo_maxsz)
536#define NFS4_dec_setclientid_confirm_sz \ 534#define NFS4_dec_setclientid_confirm_sz \
537 (compound_decode_hdr_maxsz + \ 535 (compound_decode_hdr_maxsz + \
538 decode_setclientid_confirm_maxsz + \ 536 decode_setclientid_confirm_maxsz)
539 decode_putrootfh_maxsz + \
540 decode_fsinfo_maxsz)
541#define NFS4_enc_lock_sz (compound_encode_hdr_maxsz + \ 537#define NFS4_enc_lock_sz (compound_encode_hdr_maxsz + \
542 encode_sequence_maxsz + \ 538 encode_sequence_maxsz + \
543 encode_putfh_maxsz + \ 539 encode_putfh_maxsz + \
@@ -1058,8 +1054,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const
1058 if (iap->ia_valid & ATTR_ATIME_SET) { 1054 if (iap->ia_valid & ATTR_ATIME_SET) {
1059 bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET; 1055 bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET;
1060 *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME); 1056 *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);
1061 *p++ = cpu_to_be32(0); 1057 p = xdr_encode_hyper(p, (s64)iap->ia_atime.tv_sec);
1062 *p++ = cpu_to_be32(iap->ia_atime.tv_sec);
1063 *p++ = cpu_to_be32(iap->ia_atime.tv_nsec); 1058 *p++ = cpu_to_be32(iap->ia_atime.tv_nsec);
1064 } 1059 }
1065 else if (iap->ia_valid & ATTR_ATIME) { 1060 else if (iap->ia_valid & ATTR_ATIME) {
@@ -1069,8 +1064,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const
1069 if (iap->ia_valid & ATTR_MTIME_SET) { 1064 if (iap->ia_valid & ATTR_MTIME_SET) {
1070 bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET; 1065 bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET;
1071 *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME); 1066 *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);
1072 *p++ = cpu_to_be32(0); 1067 p = xdr_encode_hyper(p, (s64)iap->ia_mtime.tv_sec);
1073 *p++ = cpu_to_be32(iap->ia_mtime.tv_sec);
1074 *p++ = cpu_to_be32(iap->ia_mtime.tv_nsec); 1068 *p++ = cpu_to_be32(iap->ia_mtime.tv_nsec);
1075 } 1069 }
1076 else if (iap->ia_valid & ATTR_MTIME) { 1070 else if (iap->ia_valid & ATTR_MTIME) {
@@ -1366,33 +1360,28 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena
1366 1360
1367static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg) 1361static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg)
1368{ 1362{
1363 struct iattr dummy;
1369 __be32 *p; 1364 __be32 *p;
1370 struct nfs_client *clp;
1371 1365
1372 p = reserve_space(xdr, 4); 1366 p = reserve_space(xdr, 4);
1373 switch(arg->open_flags & O_EXCL) { 1367 switch(arg->createmode) {
1374 case 0: 1368 case NFS4_CREATE_UNCHECKED:
1375 *p = cpu_to_be32(NFS4_CREATE_UNCHECKED); 1369 *p = cpu_to_be32(NFS4_CREATE_UNCHECKED);
1376 encode_attrs(xdr, arg->u.attrs, arg->server); 1370 encode_attrs(xdr, arg->u.attrs, arg->server);
1377 break; 1371 break;
1378 default: 1372 case NFS4_CREATE_GUARDED:
1379 clp = arg->server->nfs_client; 1373 *p = cpu_to_be32(NFS4_CREATE_GUARDED);
1380 if (clp->cl_mvops->minor_version > 0) { 1374 encode_attrs(xdr, arg->u.attrs, arg->server);
1381 if (nfs4_has_persistent_session(clp)) { 1375 break;
1382 *p = cpu_to_be32(NFS4_CREATE_GUARDED); 1376 case NFS4_CREATE_EXCLUSIVE:
1383 encode_attrs(xdr, arg->u.attrs, arg->server); 1377 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE);
1384 } else { 1378 encode_nfs4_verifier(xdr, &arg->u.verifier);
1385 struct iattr dummy; 1379 break;
1386 1380 case NFS4_CREATE_EXCLUSIVE4_1:
1387 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1); 1381 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1);
1388 encode_nfs4_verifier(xdr, &arg->u.verifier); 1382 encode_nfs4_verifier(xdr, &arg->u.verifier);
1389 dummy.ia_valid = 0; 1383 dummy.ia_valid = 0;
1390 encode_attrs(xdr, &dummy, arg->server); 1384 encode_attrs(xdr, &dummy, arg->server);
1391 }
1392 } else {
1393 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE);
1394 encode_nfs4_verifier(xdr, &arg->u.verifier);
1395 }
1396 } 1385 }
1397} 1386}
1398 1387
@@ -1459,6 +1448,23 @@ static inline void encode_claim_delegate_cur(struct xdr_stream *xdr, const struc
1459 encode_string(xdr, name->len, name->name); 1448 encode_string(xdr, name->len, name->name);
1460} 1449}
1461 1450
1451static inline void encode_claim_fh(struct xdr_stream *xdr)
1452{
1453 __be32 *p;
1454
1455 p = reserve_space(xdr, 4);
1456 *p = cpu_to_be32(NFS4_OPEN_CLAIM_FH);
1457}
1458
1459static inline void encode_claim_delegate_cur_fh(struct xdr_stream *xdr, const nfs4_stateid *stateid)
1460{
1461 __be32 *p;
1462
1463 p = reserve_space(xdr, 4);
1464 *p = cpu_to_be32(NFS4_OPEN_CLAIM_DELEG_CUR_FH);
1465 encode_nfs4_stateid(xdr, stateid);
1466}
1467
1462static void encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg, struct compound_hdr *hdr) 1468static void encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg, struct compound_hdr *hdr)
1463{ 1469{
1464 encode_op_hdr(xdr, OP_OPEN, decode_open_maxsz, hdr); 1470 encode_op_hdr(xdr, OP_OPEN, decode_open_maxsz, hdr);
@@ -1474,6 +1480,12 @@ static void encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg,
1474 case NFS4_OPEN_CLAIM_DELEGATE_CUR: 1480 case NFS4_OPEN_CLAIM_DELEGATE_CUR:
1475 encode_claim_delegate_cur(xdr, arg->name, &arg->u.delegation); 1481 encode_claim_delegate_cur(xdr, arg->name, &arg->u.delegation);
1476 break; 1482 break;
1483 case NFS4_OPEN_CLAIM_FH:
1484 encode_claim_fh(xdr);
1485 break;
1486 case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
1487 encode_claim_delegate_cur_fh(xdr, &arg->u.delegation);
1488 break;
1477 default: 1489 default:
1478 BUG(); 1490 BUG();
1479 } 1491 }
@@ -1506,35 +1518,12 @@ static void encode_putrootfh(struct xdr_stream *xdr, struct compound_hdr *hdr)
1506 encode_op_hdr(xdr, OP_PUTROOTFH, decode_putrootfh_maxsz, hdr); 1518 encode_op_hdr(xdr, OP_PUTROOTFH, decode_putrootfh_maxsz, hdr);
1507} 1519}
1508 1520
1509static void encode_open_stateid(struct xdr_stream *xdr,
1510 const struct nfs_open_context *ctx,
1511 const struct nfs_lock_context *l_ctx,
1512 fmode_t fmode,
1513 int zero_seqid)
1514{
1515 nfs4_stateid stateid;
1516
1517 if (ctx->state != NULL) {
1518 const struct nfs_lockowner *lockowner = NULL;
1519
1520 if (l_ctx != NULL)
1521 lockowner = &l_ctx->lockowner;
1522 nfs4_select_rw_stateid(&stateid, ctx->state,
1523 fmode, lockowner);
1524 if (zero_seqid)
1525 stateid.seqid = 0;
1526 encode_nfs4_stateid(xdr, &stateid);
1527 } else
1528 encode_nfs4_stateid(xdr, &zero_stateid);
1529}
1530
1531static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args, struct compound_hdr *hdr) 1521static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args, struct compound_hdr *hdr)
1532{ 1522{
1533 __be32 *p; 1523 __be32 *p;
1534 1524
1535 encode_op_hdr(xdr, OP_READ, decode_read_maxsz, hdr); 1525 encode_op_hdr(xdr, OP_READ, decode_read_maxsz, hdr);
1536 encode_open_stateid(xdr, args->context, args->lock_context, 1526 encode_nfs4_stateid(xdr, &args->stateid);
1537 FMODE_READ, hdr->minorversion);
1538 1527
1539 p = reserve_space(xdr, 12); 1528 p = reserve_space(xdr, 12);
1540 p = xdr_encode_hyper(p, args->offset); 1529 p = xdr_encode_hyper(p, args->offset);
@@ -1670,8 +1659,7 @@ static void encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *arg
1670 __be32 *p; 1659 __be32 *p;
1671 1660
1672 encode_op_hdr(xdr, OP_WRITE, decode_write_maxsz, hdr); 1661 encode_op_hdr(xdr, OP_WRITE, decode_write_maxsz, hdr);
1673 encode_open_stateid(xdr, args->context, args->lock_context, 1662 encode_nfs4_stateid(xdr, &args->stateid);
1674 FMODE_WRITE, hdr->minorversion);
1675 1663
1676 p = reserve_space(xdr, 16); 1664 p = reserve_space(xdr, 16);
1677 p = xdr_encode_hyper(p, args->offset); 1665 p = xdr_encode_hyper(p, args->offset);
@@ -2609,12 +2597,9 @@ static void nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req,
2609 struct compound_hdr hdr = { 2597 struct compound_hdr hdr = {
2610 .nops = 0, 2598 .nops = 0,
2611 }; 2599 };
2612 const u32 lease_bitmap[3] = { FATTR4_WORD0_LEASE_TIME };
2613 2600
2614 encode_compound_hdr(xdr, req, &hdr); 2601 encode_compound_hdr(xdr, req, &hdr);
2615 encode_setclientid_confirm(xdr, arg, &hdr); 2602 encode_setclientid_confirm(xdr, arg, &hdr);
2616 encode_putrootfh(xdr, &hdr);
2617 encode_fsinfo(xdr, lease_bitmap, &hdr);
2618 encode_nops(&hdr); 2603 encode_nops(&hdr);
2619} 2604}
2620 2605
@@ -3497,8 +3482,11 @@ static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path)
3497 if (n == 0) 3482 if (n == 0)
3498 goto root_path; 3483 goto root_path;
3499 dprintk("pathname4: "); 3484 dprintk("pathname4: ");
3500 path->ncomponents = 0; 3485 if (n > NFS4_PATHNAME_MAXCOMPONENTS) {
3501 while (path->ncomponents < n) { 3486 dprintk("cannot parse %d components in path\n", n);
3487 goto out_eio;
3488 }
3489 for (path->ncomponents = 0; path->ncomponents < n; path->ncomponents++) {
3502 struct nfs4_string *component = &path->components[path->ncomponents]; 3490 struct nfs4_string *component = &path->components[path->ncomponents];
3503 status = decode_opaque_inline(xdr, &component->len, &component->data); 3491 status = decode_opaque_inline(xdr, &component->len, &component->data);
3504 if (unlikely(status != 0)) 3492 if (unlikely(status != 0))
@@ -3507,12 +3495,6 @@ static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path)
3507 pr_cont("%s%.*s ", 3495 pr_cont("%s%.*s ",
3508 (path->ncomponents != n ? "/ " : ""), 3496 (path->ncomponents != n ? "/ " : ""),
3509 component->len, component->data); 3497 component->len, component->data);
3510 if (path->ncomponents < NFS4_PATHNAME_MAXCOMPONENTS)
3511 path->ncomponents++;
3512 else {
3513 dprintk("cannot parse %d components in path\n", n);
3514 goto out_eio;
3515 }
3516 } 3498 }
3517out: 3499out:
3518 return status; 3500 return status;
@@ -3557,27 +3539,23 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st
3557 n = be32_to_cpup(p); 3539 n = be32_to_cpup(p);
3558 if (n <= 0) 3540 if (n <= 0)
3559 goto out_eio; 3541 goto out_eio;
3560 res->nlocations = 0; 3542 for (res->nlocations = 0; res->nlocations < n; res->nlocations++) {
3561 while (res->nlocations < n) {
3562 u32 m; 3543 u32 m;
3563 struct nfs4_fs_location *loc = &res->locations[res->nlocations]; 3544 struct nfs4_fs_location *loc;
3564 3545
3546 if (res->nlocations == NFS4_FS_LOCATIONS_MAXENTRIES)
3547 break;
3548 loc = &res->locations[res->nlocations];
3565 p = xdr_inline_decode(xdr, 4); 3549 p = xdr_inline_decode(xdr, 4);
3566 if (unlikely(!p)) 3550 if (unlikely(!p))
3567 goto out_overflow; 3551 goto out_overflow;
3568 m = be32_to_cpup(p); 3552 m = be32_to_cpup(p);
3569 3553
3570 loc->nservers = 0;
3571 dprintk("%s: servers:\n", __func__); 3554 dprintk("%s: servers:\n", __func__);
3572 while (loc->nservers < m) { 3555 for (loc->nservers = 0; loc->nservers < m; loc->nservers++) {
3573 struct nfs4_string *server = &loc->servers[loc->nservers]; 3556 struct nfs4_string *server;
3574 status = decode_opaque_inline(xdr, &server->len, &server->data); 3557
3575 if (unlikely(status != 0)) 3558 if (loc->nservers == NFS4_FS_LOCATION_MAXSERVERS) {
3576 goto out_eio;
3577 dprintk("%s ", server->data);
3578 if (loc->nservers < NFS4_FS_LOCATION_MAXSERVERS)
3579 loc->nservers++;
3580 else {
3581 unsigned int i; 3559 unsigned int i;
3582 dprintk("%s: using first %u of %u servers " 3560 dprintk("%s: using first %u of %u servers "
3583 "returned for location %u\n", 3561 "returned for location %u\n",
@@ -3591,13 +3569,17 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st
3591 if (unlikely(status != 0)) 3569 if (unlikely(status != 0))
3592 goto out_eio; 3570 goto out_eio;
3593 } 3571 }
3572 break;
3594 } 3573 }
3574 server = &loc->servers[loc->nservers];
3575 status = decode_opaque_inline(xdr, &server->len, &server->data);
3576 if (unlikely(status != 0))
3577 goto out_eio;
3578 dprintk("%s ", server->data);
3595 } 3579 }
3596 status = decode_pathname(xdr, &loc->rootpath); 3580 status = decode_pathname(xdr, &loc->rootpath);
3597 if (unlikely(status != 0)) 3581 if (unlikely(status != 0))
3598 goto out_eio; 3582 goto out_eio;
3599 if (res->nlocations < NFS4_FS_LOCATIONS_MAXENTRIES)
3600 res->nlocations++;
3601 } 3583 }
3602 if (res->nlocations != 0) 3584 if (res->nlocations != 0)
3603 status = NFS_ATTR_FATTR_V4_LOCATIONS; 3585 status = NFS_ATTR_FATTR_V4_LOCATIONS;
@@ -5209,27 +5191,30 @@ static int decode_delegreturn(struct xdr_stream *xdr)
5209 return decode_op_hdr(xdr, OP_DELEGRETURN); 5191 return decode_op_hdr(xdr, OP_DELEGRETURN);
5210} 5192}
5211 5193
5212static int decode_secinfo_gss(struct xdr_stream *xdr, struct nfs4_secinfo_flavor *flavor) 5194static int decode_secinfo_gss(struct xdr_stream *xdr,
5195 struct nfs4_secinfo4 *flavor)
5213{ 5196{
5197 u32 oid_len;
5214 __be32 *p; 5198 __be32 *p;
5215 5199
5216 p = xdr_inline_decode(xdr, 4); 5200 p = xdr_inline_decode(xdr, 4);
5217 if (unlikely(!p)) 5201 if (unlikely(!p))
5218 goto out_overflow; 5202 goto out_overflow;
5219 flavor->gss.sec_oid4.len = be32_to_cpup(p); 5203 oid_len = be32_to_cpup(p);
5220 if (flavor->gss.sec_oid4.len > GSS_OID_MAX_LEN) 5204 if (oid_len > GSS_OID_MAX_LEN)
5221 goto out_err; 5205 goto out_err;
5222 5206
5223 p = xdr_inline_decode(xdr, flavor->gss.sec_oid4.len); 5207 p = xdr_inline_decode(xdr, oid_len);
5224 if (unlikely(!p)) 5208 if (unlikely(!p))
5225 goto out_overflow; 5209 goto out_overflow;
5226 memcpy(flavor->gss.sec_oid4.data, p, flavor->gss.sec_oid4.len); 5210 memcpy(flavor->flavor_info.oid.data, p, oid_len);
5211 flavor->flavor_info.oid.len = oid_len;
5227 5212
5228 p = xdr_inline_decode(xdr, 8); 5213 p = xdr_inline_decode(xdr, 8);
5229 if (unlikely(!p)) 5214 if (unlikely(!p))
5230 goto out_overflow; 5215 goto out_overflow;
5231 flavor->gss.qop4 = be32_to_cpup(p++); 5216 flavor->flavor_info.qop = be32_to_cpup(p++);
5232 flavor->gss.service = be32_to_cpup(p); 5217 flavor->flavor_info.service = be32_to_cpup(p);
5233 5218
5234 return 0; 5219 return 0;
5235 5220
@@ -5242,10 +5227,10 @@ out_err:
5242 5227
5243static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) 5228static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res *res)
5244{ 5229{
5245 struct nfs4_secinfo_flavor *sec_flavor; 5230 struct nfs4_secinfo4 *sec_flavor;
5231 unsigned int i, num_flavors;
5246 int status; 5232 int status;
5247 __be32 *p; 5233 __be32 *p;
5248 int i, num_flavors;
5249 5234
5250 p = xdr_inline_decode(xdr, 4); 5235 p = xdr_inline_decode(xdr, 4);
5251 if (unlikely(!p)) 5236 if (unlikely(!p))
@@ -6648,8 +6633,7 @@ static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req,
6648 * Decode SETCLIENTID_CONFIRM response 6633 * Decode SETCLIENTID_CONFIRM response
6649 */ 6634 */
6650static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, 6635static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req,
6651 struct xdr_stream *xdr, 6636 struct xdr_stream *xdr)
6652 struct nfs_fsinfo *fsinfo)
6653{ 6637{
6654 struct compound_hdr hdr; 6638 struct compound_hdr hdr;
6655 int status; 6639 int status;
@@ -6657,10 +6641,6 @@ static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req,
6657 status = decode_compound_hdr(xdr, &hdr); 6641 status = decode_compound_hdr(xdr, &hdr);
6658 if (!status) 6642 if (!status)
6659 status = decode_setclientid_confirm(xdr); 6643 status = decode_setclientid_confirm(xdr);
6660 if (!status)
6661 status = decode_putrootfh(xdr);
6662 if (!status)
6663 status = decode_fsinfo(xdr, fsinfo);
6664 return status; 6644 return status;
6665} 6645}
6666 6646
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index e56e846e9d2d..29cfb7ade121 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -84,6 +84,55 @@ nfs_page_free(struct nfs_page *p)
84 kmem_cache_free(nfs_page_cachep, p); 84 kmem_cache_free(nfs_page_cachep, p);
85} 85}
86 86
87static void
88nfs_iocounter_inc(struct nfs_io_counter *c)
89{
90 atomic_inc(&c->io_count);
91}
92
93static void
94nfs_iocounter_dec(struct nfs_io_counter *c)
95{
96 if (atomic_dec_and_test(&c->io_count)) {
97 clear_bit(NFS_IO_INPROGRESS, &c->flags);
98 smp_mb__after_clear_bit();
99 wake_up_bit(&c->flags, NFS_IO_INPROGRESS);
100 }
101}
102
103static int
104__nfs_iocounter_wait(struct nfs_io_counter *c)
105{
106 wait_queue_head_t *wq = bit_waitqueue(&c->flags, NFS_IO_INPROGRESS);
107 DEFINE_WAIT_BIT(q, &c->flags, NFS_IO_INPROGRESS);
108 int ret = 0;
109
110 do {
111 prepare_to_wait(wq, &q.wait, TASK_KILLABLE);
112 set_bit(NFS_IO_INPROGRESS, &c->flags);
113 if (atomic_read(&c->io_count) == 0)
114 break;
115 ret = nfs_wait_bit_killable(&c->flags);
116 } while (atomic_read(&c->io_count) != 0);
117 finish_wait(wq, &q.wait);
118 return ret;
119}
120
121/**
122 * nfs_iocounter_wait - wait for i/o to complete
123 * @c: nfs_io_counter to use
124 *
125 * returns -ERESTARTSYS if interrupted by a fatal signal.
126 * Otherwise returns 0 once the io_count hits 0.
127 */
128int
129nfs_iocounter_wait(struct nfs_io_counter *c)
130{
131 if (atomic_read(&c->io_count) == 0)
132 return 0;
133 return __nfs_iocounter_wait(c);
134}
135
87/** 136/**
88 * nfs_create_request - Create an NFS read/write request. 137 * nfs_create_request - Create an NFS read/write request.
89 * @ctx: open context to use 138 * @ctx: open context to use
@@ -104,6 +153,8 @@ nfs_create_request(struct nfs_open_context *ctx, struct inode *inode,
104 struct nfs_page *req; 153 struct nfs_page *req;
105 struct nfs_lock_context *l_ctx; 154 struct nfs_lock_context *l_ctx;
106 155
156 if (test_bit(NFS_CONTEXT_BAD, &ctx->flags))
157 return ERR_PTR(-EBADF);
107 /* try to allocate the request struct */ 158 /* try to allocate the request struct */
108 req = nfs_page_alloc(); 159 req = nfs_page_alloc();
109 if (req == NULL) 160 if (req == NULL)
@@ -116,6 +167,7 @@ nfs_create_request(struct nfs_open_context *ctx, struct inode *inode,
116 return ERR_CAST(l_ctx); 167 return ERR_CAST(l_ctx);
117 } 168 }
118 req->wb_lock_context = l_ctx; 169 req->wb_lock_context = l_ctx;
170 nfs_iocounter_inc(&l_ctx->io_count);
119 171
120 /* Initialize the request struct. Initially, we assume a 172 /* Initialize the request struct. Initially, we assume a
121 * long write-back delay. This will be adjusted in 173 * long write-back delay. This will be adjusted in
@@ -175,6 +227,7 @@ static void nfs_clear_request(struct nfs_page *req)
175 req->wb_page = NULL; 227 req->wb_page = NULL;
176 } 228 }
177 if (l_ctx != NULL) { 229 if (l_ctx != NULL) {
230 nfs_iocounter_dec(&l_ctx->io_count);
178 nfs_put_lock_context(l_ctx); 231 nfs_put_lock_context(l_ctx);
179 req->wb_lock_context = NULL; 232 req->wb_lock_context = NULL;
180 } 233 }
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 4bdffe0ba025..c5bd758e5637 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -718,6 +718,8 @@ pnfs_choose_layoutget_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo,
718 spin_lock(&lo->plh_inode->i_lock); 718 spin_lock(&lo->plh_inode->i_lock);
719 if (pnfs_layoutgets_blocked(lo, 1)) { 719 if (pnfs_layoutgets_blocked(lo, 1)) {
720 status = -EAGAIN; 720 status = -EAGAIN;
721 } else if (!nfs4_valid_open_stateid(open_state)) {
722 status = -EBADF;
721 } else if (list_empty(&lo->plh_segs)) { 723 } else if (list_empty(&lo->plh_segs)) {
722 int seq; 724 int seq;
723 725
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index a5e5d9899d56..70a26c651f09 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -514,6 +514,8 @@ void nfs_read_prepare(struct rpc_task *task, void *calldata)
514{ 514{
515 struct nfs_read_data *data = calldata; 515 struct nfs_read_data *data = calldata;
516 NFS_PROTO(data->header->inode)->read_rpc_prepare(task, data); 516 NFS_PROTO(data->header->inode)->read_rpc_prepare(task, data);
517 if (unlikely(test_bit(NFS_CONTEXT_BAD, &data->args.context->flags)))
518 rpc_exit(task, -EIO);
517} 519}
518 520
519static const struct rpc_call_ops nfs_read_common_ops = { 521static const struct rpc_call_ops nfs_read_common_ops = {
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 2f8a29db0f1b..eb494f6a4c6b 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -920,7 +920,7 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void)
920 data->mount_server.port = NFS_UNSPEC_PORT; 920 data->mount_server.port = NFS_UNSPEC_PORT;
921 data->nfs_server.port = NFS_UNSPEC_PORT; 921 data->nfs_server.port = NFS_UNSPEC_PORT;
922 data->nfs_server.protocol = XPRT_TRANSPORT_TCP; 922 data->nfs_server.protocol = XPRT_TRANSPORT_TCP;
923 data->auth_flavors[0] = RPC_AUTH_UNIX; 923 data->auth_flavors[0] = RPC_AUTH_MAXFLAVOR;
924 data->auth_flavor_len = 1; 924 data->auth_flavor_len = 1;
925 data->minorversion = 0; 925 data->minorversion = 0;
926 data->need_mount = true; 926 data->need_mount = true;
@@ -1608,49 +1608,57 @@ out_security_failure:
1608} 1608}
1609 1609
1610/* 1610/*
1611 * Match the requested auth flavors with the list returned by 1611 * Select a security flavor for this mount. The selected flavor
1612 * the server. Returns zero and sets the mount's authentication 1612 * is planted in args->auth_flavors[0].
1613 * flavor on success; returns -EACCES if server does not support
1614 * the requested flavor.
1615 */ 1613 */
1616static int nfs_walk_authlist(struct nfs_parsed_mount_data *args, 1614static void nfs_select_flavor(struct nfs_parsed_mount_data *args,
1617 struct nfs_mount_request *request) 1615 struct nfs_mount_request *request)
1618{ 1616{
1619 unsigned int i, j, server_authlist_len = *(request->auth_flav_len); 1617 unsigned int i, count = *(request->auth_flav_len);
1618 rpc_authflavor_t flavor;
1619
1620 if (args->auth_flavors[0] != RPC_AUTH_MAXFLAVOR)
1621 goto out;
1622
1623 /*
1624 * The NFSv2 MNT operation does not return a flavor list.
1625 */
1626 if (args->mount_server.version != NFS_MNT3_VERSION)
1627 goto out_default;
1620 1628
1621 /* 1629 /*
1622 * Certain releases of Linux's mountd return an empty 1630 * Certain releases of Linux's mountd return an empty
1623 * flavor list. To prevent behavioral regression with 1631 * flavor list in some cases.
1624 * these servers (ie. rejecting mounts that used to
1625 * succeed), revert to pre-2.6.32 behavior (no checking)
1626 * if the returned flavor list is empty.
1627 */ 1632 */
1628 if (server_authlist_len == 0) 1633 if (count == 0)
1629 return 0; 1634 goto out_default;
1630 1635
1631 /* 1636 /*
1632 * We avoid sophisticated negotiating here, as there are
1633 * plenty of cases where we can get it wrong, providing
1634 * either too little or too much security.
1635 *
1636 * RFC 2623, section 2.7 suggests we SHOULD prefer the 1637 * RFC 2623, section 2.7 suggests we SHOULD prefer the
1637 * flavor listed first. However, some servers list 1638 * flavor listed first. However, some servers list
1638 * AUTH_NULL first. Our caller plants AUTH_SYS, the 1639 * AUTH_NULL first. Avoid ever choosing AUTH_NULL.
1639 * preferred default, in args->auth_flavors[0] if user
1640 * didn't specify sec= mount option.
1641 */ 1640 */
1642 for (i = 0; i < args->auth_flavor_len; i++) 1641 for (i = 0; i < count; i++) {
1643 for (j = 0; j < server_authlist_len; j++) 1642 struct rpcsec_gss_info info;
1644 if (args->auth_flavors[i] == request->auth_flavs[j]) { 1643
1645 dfprintk(MOUNT, "NFS: using auth flavor %d\n", 1644 flavor = request->auth_flavs[i];
1646 request->auth_flavs[j]); 1645 switch (flavor) {
1647 args->auth_flavors[0] = request->auth_flavs[j]; 1646 case RPC_AUTH_UNIX:
1648 return 0; 1647 goto out_set;
1649 } 1648 case RPC_AUTH_NULL:
1649 continue;
1650 default:
1651 if (rpcauth_get_gssinfo(flavor, &info) == 0)
1652 goto out_set;
1653 }
1654 }
1650 1655
1651 dfprintk(MOUNT, "NFS: server does not support requested auth flavor\n"); 1656out_default:
1652 nfs_umount(request); 1657 flavor = RPC_AUTH_UNIX;
1653 return -EACCES; 1658out_set:
1659 args->auth_flavors[0] = flavor;
1660out:
1661 dfprintk(MOUNT, "NFS: using auth flavor %d\n", args->auth_flavors[0]);
1654} 1662}
1655 1663
1656/* 1664/*
@@ -1713,12 +1721,8 @@ static int nfs_request_mount(struct nfs_parsed_mount_data *args,
1713 return status; 1721 return status;
1714 } 1722 }
1715 1723
1716 /* 1724 nfs_select_flavor(args, &request);
1717 * MNTv1 (NFSv2) does not support auth flavor negotiation. 1725 return 0;
1718 */
1719 if (args->mount_server.version != NFS_MNT3_VERSION)
1720 return 0;
1721 return nfs_walk_authlist(args, &request);
1722} 1726}
1723 1727
1724struct dentry *nfs_try_mount(int flags, const char *dev_name, 1728struct dentry *nfs_try_mount(int flags, const char *dev_name,
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index c483cc50b82e..a2c7c28049d5 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1251,6 +1251,8 @@ void nfs_write_prepare(struct rpc_task *task, void *calldata)
1251{ 1251{
1252 struct nfs_write_data *data = calldata; 1252 struct nfs_write_data *data = calldata;
1253 NFS_PROTO(data->header->inode)->write_rpc_prepare(task, data); 1253 NFS_PROTO(data->header->inode)->write_rpc_prepare(task, data);
1254 if (unlikely(test_bit(NFS_CONTEXT_BAD, &data->args.context->flags)))
1255 rpc_exit(task, -EIO);
1254} 1256}
1255 1257
1256void nfs_commit_prepare(struct rpc_task *task, void *calldata) 1258void nfs_commit_prepare(struct rpc_task *task, void *calldata)
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index a2720071f282..2502951714b1 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -3138,10 +3138,9 @@ nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
3138 3138
3139static __be32 3139static __be32
3140nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp, 3140nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
3141 __be32 nfserr,struct svc_export *exp) 3141 __be32 nfserr, struct svc_export *exp)
3142{ 3142{
3143 int i = 0; 3143 u32 i, nflavs;
3144 u32 nflavs;
3145 struct exp_flavor_info *flavs; 3144 struct exp_flavor_info *flavs;
3146 struct exp_flavor_info def_flavs[2]; 3145 struct exp_flavor_info def_flavs[2];
3147 __be32 *p; 3146 __be32 *p;
@@ -3172,30 +3171,29 @@ nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
3172 WRITE32(nflavs); 3171 WRITE32(nflavs);
3173 ADJUST_ARGS(); 3172 ADJUST_ARGS();
3174 for (i = 0; i < nflavs; i++) { 3173 for (i = 0; i < nflavs; i++) {
3175 u32 flav = flavs[i].pseudoflavor; 3174 struct rpcsec_gss_info info;
3176 struct gss_api_mech *gm = gss_mech_get_by_pseudoflavor(flav);
3177 3175
3178 if (gm) { 3176 if (rpcauth_get_gssinfo(flavs[i].pseudoflavor, &info) == 0) {
3179 RESERVE_SPACE(4); 3177 RESERVE_SPACE(4);
3180 WRITE32(RPC_AUTH_GSS); 3178 WRITE32(RPC_AUTH_GSS);
3181 ADJUST_ARGS(); 3179 ADJUST_ARGS();
3182 RESERVE_SPACE(4 + gm->gm_oid.len); 3180 RESERVE_SPACE(4 + info.oid.len);
3183 WRITE32(gm->gm_oid.len); 3181 WRITE32(info.oid.len);
3184 WRITEMEM(gm->gm_oid.data, gm->gm_oid.len); 3182 WRITEMEM(info.oid.data, info.oid.len);
3185 ADJUST_ARGS(); 3183 ADJUST_ARGS();
3186 RESERVE_SPACE(4); 3184 RESERVE_SPACE(4);
3187 WRITE32(0); /* qop */ 3185 WRITE32(info.qop);
3188 ADJUST_ARGS(); 3186 ADJUST_ARGS();
3189 RESERVE_SPACE(4); 3187 RESERVE_SPACE(4);
3190 WRITE32(gss_pseudoflavor_to_service(gm, flav)); 3188 WRITE32(info.service);
3191 ADJUST_ARGS(); 3189 ADJUST_ARGS();
3192 gss_mech_put(gm);
3193 } else { 3190 } else {
3194 RESERVE_SPACE(4); 3191 RESERVE_SPACE(4);
3195 WRITE32(flav); 3192 WRITE32(flavs[i].pseudoflavor);
3196 ADJUST_ARGS(); 3193 ADJUST_ARGS();
3197 } 3194 }
3198 } 3195 }
3196
3199out: 3197out:
3200 if (exp) 3198 if (exp)
3201 exp_put(exp); 3199 exp_put(exp);
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 1cc25682b20b..fc01d5cb4cf1 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -59,11 +59,18 @@ struct nfs_lockowner {
59 pid_t l_pid; 59 pid_t l_pid;
60}; 60};
61 61
62#define NFS_IO_INPROGRESS 0
63struct nfs_io_counter {
64 unsigned long flags;
65 atomic_t io_count;
66};
67
62struct nfs_lock_context { 68struct nfs_lock_context {
63 atomic_t count; 69 atomic_t count;
64 struct list_head list; 70 struct list_head list;
65 struct nfs_open_context *open_context; 71 struct nfs_open_context *open_context;
66 struct nfs_lockowner lockowner; 72 struct nfs_lockowner lockowner;
73 struct nfs_io_counter io_count;
67}; 74};
68 75
69struct nfs4_state; 76struct nfs4_state;
@@ -77,6 +84,7 @@ struct nfs_open_context {
77 unsigned long flags; 84 unsigned long flags;
78#define NFS_CONTEXT_ERROR_WRITE (0) 85#define NFS_CONTEXT_ERROR_WRITE (0)
79#define NFS_CONTEXT_RESEND_WRITES (1) 86#define NFS_CONTEXT_RESEND_WRITES (1)
87#define NFS_CONTEXT_BAD (2)
80 int error; 88 int error;
81 89
82 struct list_head list; 90 struct list_head list;
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 6c6ed153a9b4..3b7fa2abecca 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -40,6 +40,7 @@ struct nfs_client {
40#define NFS_CS_NORESVPORT 0 /* - use ephemeral src port */ 40#define NFS_CS_NORESVPORT 0 /* - use ephemeral src port */
41#define NFS_CS_DISCRTRY 1 /* - disconnect on RPC retry */ 41#define NFS_CS_DISCRTRY 1 /* - disconnect on RPC retry */
42#define NFS_CS_MIGRATION 2 /* - transparent state migr */ 42#define NFS_CS_MIGRATION 2 /* - transparent state migr */
43#define NFS_CS_INFINITE_SLOTS 3 /* - don't limit TCP slots */
43 struct sockaddr_storage cl_addr; /* server identifier */ 44 struct sockaddr_storage cl_addr; /* server identifier */
44 size_t cl_addrlen; 45 size_t cl_addrlen;
45 char * cl_hostname; /* hostname of server */ 46 char * cl_hostname; /* hostname of server */
@@ -197,5 +198,7 @@ struct nfs_server {
197#define NFS_CAP_MTIME (1U << 13) 198#define NFS_CAP_MTIME (1U << 13)
198#define NFS_CAP_POSIX_LOCK (1U << 14) 199#define NFS_CAP_POSIX_LOCK (1U << 14)
199#define NFS_CAP_UIDGID_NOMAP (1U << 15) 200#define NFS_CAP_UIDGID_NOMAP (1U << 15)
201#define NFS_CAP_STATEID_NFSV41 (1U << 16)
202#define NFS_CAP_ATOMIC_OPEN_V1 (1U << 17)
200 203
201#endif 204#endif
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 4b993d358dad..766c5bc9d441 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -14,9 +14,6 @@
14#define NFS_DEF_FILE_IO_SIZE (4096U) 14#define NFS_DEF_FILE_IO_SIZE (4096U)
15#define NFS_MIN_FILE_IO_SIZE (1024U) 15#define NFS_MIN_FILE_IO_SIZE (1024U)
16 16
17/* Forward declaration for NFS v3 */
18struct nfs4_secinfo_flavors;
19
20struct nfs4_string { 17struct nfs4_string {
21 unsigned int len; 18 unsigned int len;
22 char *data; 19 char *data;
@@ -349,6 +346,7 @@ struct nfs_openargs {
349 const u32 * bitmask; 346 const u32 * bitmask;
350 const u32 * open_bitmap; 347 const u32 * open_bitmap;
351 __u32 claim; 348 __u32 claim;
349 enum createmode4 createmode;
352}; 350};
353 351
354struct nfs_openres { 352struct nfs_openres {
@@ -486,6 +484,7 @@ struct nfs_readargs {
486 struct nfs_fh * fh; 484 struct nfs_fh * fh;
487 struct nfs_open_context *context; 485 struct nfs_open_context *context;
488 struct nfs_lock_context *lock_context; 486 struct nfs_lock_context *lock_context;
487 nfs4_stateid stateid;
489 __u64 offset; 488 __u64 offset;
490 __u32 count; 489 __u32 count;
491 unsigned int pgbase; 490 unsigned int pgbase;
@@ -507,6 +506,7 @@ struct nfs_writeargs {
507 struct nfs_fh * fh; 506 struct nfs_fh * fh;
508 struct nfs_open_context *context; 507 struct nfs_open_context *context;
509 struct nfs_lock_context *lock_context; 508 struct nfs_lock_context *lock_context;
509 nfs4_stateid stateid;
510 __u64 offset; 510 __u64 offset;
511 __u32 count; 511 __u32 count;
512 enum nfs3_stable_how stable; 512 enum nfs3_stable_how stable;
@@ -1050,25 +1050,14 @@ struct nfs4_fs_locations_res {
1050 struct nfs4_fs_locations *fs_locations; 1050 struct nfs4_fs_locations *fs_locations;
1051}; 1051};
1052 1052
1053struct nfs4_secinfo_oid { 1053struct nfs4_secinfo4 {
1054 unsigned int len; 1054 u32 flavor;
1055 char data[GSS_OID_MAX_LEN]; 1055 struct rpcsec_gss_info flavor_info;
1056};
1057
1058struct nfs4_secinfo_gss {
1059 struct nfs4_secinfo_oid sec_oid4;
1060 unsigned int qop4;
1061 unsigned int service;
1062};
1063
1064struct nfs4_secinfo_flavor {
1065 unsigned int flavor;
1066 struct nfs4_secinfo_gss gss;
1067}; 1056};
1068 1057
1069struct nfs4_secinfo_flavors { 1058struct nfs4_secinfo_flavors {
1070 unsigned int num_flavors; 1059 unsigned int num_flavors;
1071 struct nfs4_secinfo_flavor flavors[0]; 1060 struct nfs4_secinfo4 flavors[0];
1072}; 1061};
1073 1062
1074struct nfs4_secinfo_arg { 1063struct nfs4_secinfo_arg {
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index 58fda1c3c783..0dd00f4f6810 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -22,6 +22,8 @@
22/* size of the nodename buffer */ 22/* size of the nodename buffer */
23#define UNX_MAXNODENAME 32 23#define UNX_MAXNODENAME 32
24 24
25struct rpcsec_gss_info;
26
25/* Work around the lack of a VFS credential */ 27/* Work around the lack of a VFS credential */
26struct auth_cred { 28struct auth_cred {
27 kuid_t uid; 29 kuid_t uid;
@@ -103,6 +105,9 @@ struct rpc_authops {
103 int (*pipes_create)(struct rpc_auth *); 105 int (*pipes_create)(struct rpc_auth *);
104 void (*pipes_destroy)(struct rpc_auth *); 106 void (*pipes_destroy)(struct rpc_auth *);
105 int (*list_pseudoflavors)(rpc_authflavor_t *, int); 107 int (*list_pseudoflavors)(rpc_authflavor_t *, int);
108 rpc_authflavor_t (*info2flavor)(struct rpcsec_gss_info *);
109 int (*flavor2info)(rpc_authflavor_t,
110 struct rpcsec_gss_info *);
106}; 111};
107 112
108struct rpc_credops { 113struct rpc_credops {
@@ -137,6 +142,10 @@ int rpcauth_register(const struct rpc_authops *);
137int rpcauth_unregister(const struct rpc_authops *); 142int rpcauth_unregister(const struct rpc_authops *);
138struct rpc_auth * rpcauth_create(rpc_authflavor_t, struct rpc_clnt *); 143struct rpc_auth * rpcauth_create(rpc_authflavor_t, struct rpc_clnt *);
139void rpcauth_release(struct rpc_auth *); 144void rpcauth_release(struct rpc_auth *);
145rpc_authflavor_t rpcauth_get_pseudoflavor(rpc_authflavor_t,
146 struct rpcsec_gss_info *);
147int rpcauth_get_gssinfo(rpc_authflavor_t,
148 struct rpcsec_gss_info *);
140int rpcauth_list_flavors(rpc_authflavor_t *, int); 149int rpcauth_list_flavors(rpc_authflavor_t *, int);
141struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int); 150struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int);
142void rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *); 151void rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *);
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 2cf4ffaa3cd4..e7d492ce7c18 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -124,6 +124,7 @@ struct rpc_create_args {
124#define RPC_CLNT_CREATE_NOPING (1UL << 4) 124#define RPC_CLNT_CREATE_NOPING (1UL << 4)
125#define RPC_CLNT_CREATE_DISCRTRY (1UL << 5) 125#define RPC_CLNT_CREATE_DISCRTRY (1UL << 5)
126#define RPC_CLNT_CREATE_QUIET (1UL << 6) 126#define RPC_CLNT_CREATE_QUIET (1UL << 6)
127#define RPC_CLNT_CREATE_INFINITE_SLOTS (1UL << 7)
127 128
128struct rpc_clnt *rpc_create(struct rpc_create_args *args); 129struct rpc_clnt *rpc_create(struct rpc_create_args *args);
129struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *, 130struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *,
diff --git a/include/linux/sunrpc/gss_api.h b/include/linux/sunrpc/gss_api.h
index a19e2547ae6a..f32b7a47e13f 100644
--- a/include/linux/sunrpc/gss_api.h
+++ b/include/linux/sunrpc/gss_api.h
@@ -25,10 +25,21 @@ struct gss_ctx {
25 25
26#define GSS_C_NO_BUFFER ((struct xdr_netobj) 0) 26#define GSS_C_NO_BUFFER ((struct xdr_netobj) 0)
27#define GSS_C_NO_CONTEXT ((struct gss_ctx *) 0) 27#define GSS_C_NO_CONTEXT ((struct gss_ctx *) 0)
28#define GSS_C_NULL_OID ((struct xdr_netobj) 0) 28#define GSS_C_QOP_DEFAULT (0)
29 29
30/*XXX arbitrary length - is this set somewhere? */ 30/*XXX arbitrary length - is this set somewhere? */
31#define GSS_OID_MAX_LEN 32 31#define GSS_OID_MAX_LEN 32
32struct rpcsec_gss_oid {
33 unsigned int len;
34 u8 data[GSS_OID_MAX_LEN];
35};
36
37/* From RFC 3530 */
38struct rpcsec_gss_info {
39 struct rpcsec_gss_oid oid;
40 u32 qop;
41 u32 service;
42};
32 43
33/* gss-api prototypes; note that these are somewhat simplified versions of 44/* gss-api prototypes; note that these are somewhat simplified versions of
34 * the prototypes specified in RFC 2744. */ 45 * the prototypes specified in RFC 2744. */
@@ -58,12 +69,14 @@ u32 gss_unwrap(
58u32 gss_delete_sec_context( 69u32 gss_delete_sec_context(
59 struct gss_ctx **ctx_id); 70 struct gss_ctx **ctx_id);
60 71
61u32 gss_svc_to_pseudoflavor(struct gss_api_mech *, u32 service); 72rpc_authflavor_t gss_svc_to_pseudoflavor(struct gss_api_mech *, u32 qop,
73 u32 service);
62u32 gss_pseudoflavor_to_service(struct gss_api_mech *, u32 pseudoflavor); 74u32 gss_pseudoflavor_to_service(struct gss_api_mech *, u32 pseudoflavor);
63char *gss_service_to_auth_domain_name(struct gss_api_mech *, u32 service); 75char *gss_service_to_auth_domain_name(struct gss_api_mech *, u32 service);
64 76
65struct pf_desc { 77struct pf_desc {
66 u32 pseudoflavor; 78 u32 pseudoflavor;
79 u32 qop;
67 u32 service; 80 u32 service;
68 char *name; 81 char *name;
69 char *auth_domain_name; 82 char *auth_domain_name;
@@ -76,7 +89,7 @@ struct pf_desc {
76struct gss_api_mech { 89struct gss_api_mech {
77 struct list_head gm_list; 90 struct list_head gm_list;
78 struct module *gm_owner; 91 struct module *gm_owner;
79 struct xdr_netobj gm_oid; 92 struct rpcsec_gss_oid gm_oid;
80 char *gm_name; 93 char *gm_name;
81 const struct gss_api_ops *gm_ops; 94 const struct gss_api_ops *gm_ops;
82 /* pseudoflavors supported by this mechanism: */ 95 /* pseudoflavors supported by this mechanism: */
@@ -117,9 +130,11 @@ struct gss_api_ops {
117int gss_mech_register(struct gss_api_mech *); 130int gss_mech_register(struct gss_api_mech *);
118void gss_mech_unregister(struct gss_api_mech *); 131void gss_mech_unregister(struct gss_api_mech *);
119 132
120/* returns a mechanism descriptor given an OID, and increments the mechanism's 133/* Given a GSS security tuple, look up a pseudoflavor */
121 * reference count. */ 134rpc_authflavor_t gss_mech_info2flavor(struct rpcsec_gss_info *);
122struct gss_api_mech * gss_mech_get_by_OID(struct xdr_netobj *); 135
136/* Given a pseudoflavor, look up a GSS security tuple */
137int gss_mech_flavor2info(rpc_authflavor_t, struct rpcsec_gss_info *);
123 138
124/* Returns a reference to a mechanism, given a name like "krb5" etc. */ 139/* Returns a reference to a mechanism, given a name like "krb5" etc. */
125struct gss_api_mech *gss_mech_get_by_name(const char *); 140struct gss_api_mech *gss_mech_get_by_name(const char *);
@@ -130,9 +145,6 @@ struct gss_api_mech *gss_mech_get_by_pseudoflavor(u32);
130/* Fill in an array with a list of supported pseudoflavors */ 145/* Fill in an array with a list of supported pseudoflavors */
131int gss_mech_list_pseudoflavors(rpc_authflavor_t *, int); 146int gss_mech_list_pseudoflavors(rpc_authflavor_t *, int);
132 147
133/* Just increments the mechanism's reference count and returns its input: */
134struct gss_api_mech * gss_mech_get(struct gss_api_mech *);
135
136/* For every successful gss_mech_get or gss_mech_get_by_* call there must be a 148/* For every successful gss_mech_get or gss_mech_get_by_* call there must be a
137 * corresponding call to gss_mech_put. */ 149 * corresponding call to gss_mech_put. */
138void gss_mech_put(struct gss_api_mech *); 150void gss_mech_put(struct gss_api_mech *);
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index 30834be03011..ff5392421cb2 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -255,6 +255,8 @@ static inline int bc_prealloc(struct rpc_rqst *req)
255} 255}
256#endif /* CONFIG_SUNRPC_BACKCHANNEL */ 256#endif /* CONFIG_SUNRPC_BACKCHANNEL */
257 257
258#define XPRT_CREATE_INFINITE_SLOTS (1U)
259
258struct xprt_create { 260struct xprt_create {
259 int ident; /* XPRT_TRANSPORT identifier */ 261 int ident; /* XPRT_TRANSPORT identifier */
260 struct net * net; 262 struct net * net;
@@ -263,6 +265,7 @@ struct xprt_create {
263 size_t addrlen; 265 size_t addrlen;
264 const char *servername; 266 const char *servername;
265 struct svc_xprt *bc_xprt; /* NFSv4.1 backchannel */ 267 struct svc_xprt *bc_xprt; /* NFSv4.1 backchannel */
268 unsigned int flags;
266}; 269};
267 270
268struct xprt_class { 271struct xprt_class {
@@ -279,6 +282,7 @@ struct xprt_class {
279struct rpc_xprt *xprt_create_transport(struct xprt_create *args); 282struct rpc_xprt *xprt_create_transport(struct xprt_create *args);
280void xprt_connect(struct rpc_task *task); 283void xprt_connect(struct rpc_task *task);
281void xprt_reserve(struct rpc_task *task); 284void xprt_reserve(struct rpc_task *task);
285void xprt_retry_reserve(struct rpc_task *task);
282int xprt_reserve_xprt(struct rpc_xprt *xprt, struct rpc_task *task); 286int xprt_reserve_xprt(struct rpc_xprt *xprt, struct rpc_task *task);
283int xprt_reserve_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task); 287int xprt_reserve_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task);
284void xprt_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task); 288void xprt_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task);
@@ -334,6 +338,7 @@ int xs_swapper(struct rpc_xprt *xprt, int enable);
334#define XPRT_CLOSING (6) 338#define XPRT_CLOSING (6)
335#define XPRT_CONNECTION_ABORT (7) 339#define XPRT_CONNECTION_ABORT (7)
336#define XPRT_CONNECTION_CLOSE (8) 340#define XPRT_CONNECTION_CLOSE (8)
341#define XPRT_CONGESTED (9)
337 342
338static inline void xprt_set_connected(struct rpc_xprt *xprt) 343static inline void xprt_set_connected(struct rpc_xprt *xprt)
339{ 344{
diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig
index 516fe2caac2c..241b54f30204 100644
--- a/net/sunrpc/Kconfig
+++ b/net/sunrpc/Kconfig
@@ -3,6 +3,7 @@ config SUNRPC
3 3
4config SUNRPC_GSS 4config SUNRPC_GSS
5 tristate 5 tristate
6 select OID_REGISTRY
6 7
7config SUNRPC_BACKCHANNEL 8config SUNRPC_BACKCHANNEL
8 bool 9 bool
@@ -24,7 +25,6 @@ config SUNRPC_XPRT_RDMA
24config SUNRPC_SWAP 25config SUNRPC_SWAP
25 bool 26 bool
26 depends on SUNRPC 27 depends on SUNRPC
27 select NETVM
28 28
29config RPCSEC_GSS_KRB5 29config RPCSEC_GSS_KRB5
30 tristate "Secure RPC: Kerberos V mechanism" 30 tristate "Secure RPC: Kerberos V mechanism"
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index f5294047df77..ed2fdd210c0b 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -82,7 +82,7 @@ MODULE_PARM_DESC(auth_hashtable_size, "RPC credential cache hashtable size");
82 82
83static u32 83static u32
84pseudoflavor_to_flavor(u32 flavor) { 84pseudoflavor_to_flavor(u32 flavor) {
85 if (flavor >= RPC_AUTH_MAXFLAVOR) 85 if (flavor > RPC_AUTH_MAXFLAVOR)
86 return RPC_AUTH_GSS; 86 return RPC_AUTH_GSS;
87 return flavor; 87 return flavor;
88} 88}
@@ -124,6 +124,79 @@ rpcauth_unregister(const struct rpc_authops *ops)
124EXPORT_SYMBOL_GPL(rpcauth_unregister); 124EXPORT_SYMBOL_GPL(rpcauth_unregister);
125 125
126/** 126/**
127 * rpcauth_get_pseudoflavor - check if security flavor is supported
128 * @flavor: a security flavor
129 * @info: a GSS mech OID, quality of protection, and service value
130 *
131 * Verifies that an appropriate kernel module is available or already loaded.
132 * Returns an equivalent pseudoflavor, or RPC_AUTH_MAXFLAVOR if "flavor" is
133 * not supported locally.
134 */
135rpc_authflavor_t
136rpcauth_get_pseudoflavor(rpc_authflavor_t flavor, struct rpcsec_gss_info *info)
137{
138 const struct rpc_authops *ops;
139 rpc_authflavor_t pseudoflavor;
140
141 ops = auth_flavors[flavor];
142 if (ops == NULL)
143 request_module("rpc-auth-%u", flavor);
144 spin_lock(&rpc_authflavor_lock);
145 ops = auth_flavors[flavor];
146 if (ops == NULL || !try_module_get(ops->owner)) {
147 spin_unlock(&rpc_authflavor_lock);
148 return RPC_AUTH_MAXFLAVOR;
149 }
150 spin_unlock(&rpc_authflavor_lock);
151
152 pseudoflavor = flavor;
153 if (ops->info2flavor != NULL)
154 pseudoflavor = ops->info2flavor(info);
155
156 module_put(ops->owner);
157 return pseudoflavor;
158}
159EXPORT_SYMBOL_GPL(rpcauth_get_pseudoflavor);
160
161/**
162 * rpcauth_get_gssinfo - find GSS tuple matching a GSS pseudoflavor
163 * @pseudoflavor: GSS pseudoflavor to match
164 * @info: rpcsec_gss_info structure to fill in
165 *
166 * Returns zero and fills in "info" if pseudoflavor matches a
167 * supported mechanism.
168 */
169int
170rpcauth_get_gssinfo(rpc_authflavor_t pseudoflavor, struct rpcsec_gss_info *info)
171{
172 rpc_authflavor_t flavor = pseudoflavor_to_flavor(pseudoflavor);
173 const struct rpc_authops *ops;
174 int result;
175
176 if (flavor >= RPC_AUTH_MAXFLAVOR)
177 return -EINVAL;
178
179 ops = auth_flavors[flavor];
180 if (ops == NULL)
181 request_module("rpc-auth-%u", flavor);
182 spin_lock(&rpc_authflavor_lock);
183 ops = auth_flavors[flavor];
184 if (ops == NULL || !try_module_get(ops->owner)) {
185 spin_unlock(&rpc_authflavor_lock);
186 return -ENOENT;
187 }
188 spin_unlock(&rpc_authflavor_lock);
189
190 result = -ENOENT;
191 if (ops->flavor2info != NULL)
192 result = ops->flavor2info(pseudoflavor, info);
193
194 module_put(ops->owner);
195 return result;
196}
197EXPORT_SYMBOL_GPL(rpcauth_get_gssinfo);
198
199/**
127 * rpcauth_list_flavors - discover registered flavors and pseudoflavors 200 * rpcauth_list_flavors - discover registered flavors and pseudoflavors
128 * @array: array to fill in 201 * @array: array to fill in
129 * @size: size of "array" 202 * @size: size of "array"
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 5257d2982ba5..51415b07174e 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -1641,6 +1641,8 @@ static const struct rpc_authops authgss_ops = {
1641 .pipes_create = gss_pipes_dentries_create, 1641 .pipes_create = gss_pipes_dentries_create,
1642 .pipes_destroy = gss_pipes_dentries_destroy, 1642 .pipes_destroy = gss_pipes_dentries_destroy,
1643 .list_pseudoflavors = gss_mech_list_pseudoflavors, 1643 .list_pseudoflavors = gss_mech_list_pseudoflavors,
1644 .info2flavor = gss_mech_info2flavor,
1645 .flavor2info = gss_mech_flavor2info,
1644}; 1646};
1645 1647
1646static const struct rpc_credops gss_credops = { 1648static const struct rpc_credops gss_credops = {
@@ -1733,6 +1735,7 @@ static void __exit exit_rpcsec_gss(void)
1733 rcu_barrier(); /* Wait for completion of call_rcu()'s */ 1735 rcu_barrier(); /* Wait for completion of call_rcu()'s */
1734} 1736}
1735 1737
1738MODULE_ALIAS("rpc-auth-6");
1736MODULE_LICENSE("GPL"); 1739MODULE_LICENSE("GPL");
1737module_param_named(expired_cred_retry_delay, 1740module_param_named(expired_cred_retry_delay,
1738 gss_expired_cred_retry_delay, 1741 gss_expired_cred_retry_delay,
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
index d3611f11a8df..33255ff889c0 100644
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
@@ -729,16 +729,19 @@ static const struct gss_api_ops gss_kerberos_ops = {
729static struct pf_desc gss_kerberos_pfs[] = { 729static struct pf_desc gss_kerberos_pfs[] = {
730 [0] = { 730 [0] = {
731 .pseudoflavor = RPC_AUTH_GSS_KRB5, 731 .pseudoflavor = RPC_AUTH_GSS_KRB5,
732 .qop = GSS_C_QOP_DEFAULT,
732 .service = RPC_GSS_SVC_NONE, 733 .service = RPC_GSS_SVC_NONE,
733 .name = "krb5", 734 .name = "krb5",
734 }, 735 },
735 [1] = { 736 [1] = {
736 .pseudoflavor = RPC_AUTH_GSS_KRB5I, 737 .pseudoflavor = RPC_AUTH_GSS_KRB5I,
738 .qop = GSS_C_QOP_DEFAULT,
737 .service = RPC_GSS_SVC_INTEGRITY, 739 .service = RPC_GSS_SVC_INTEGRITY,
738 .name = "krb5i", 740 .name = "krb5i",
739 }, 741 },
740 [2] = { 742 [2] = {
741 .pseudoflavor = RPC_AUTH_GSS_KRB5P, 743 .pseudoflavor = RPC_AUTH_GSS_KRB5P,
744 .qop = GSS_C_QOP_DEFAULT,
742 .service = RPC_GSS_SVC_PRIVACY, 745 .service = RPC_GSS_SVC_PRIVACY,
743 .name = "krb5p", 746 .name = "krb5p",
744 }, 747 },
@@ -750,11 +753,12 @@ MODULE_ALIAS("rpc-auth-gss-krb5p");
750MODULE_ALIAS("rpc-auth-gss-390003"); 753MODULE_ALIAS("rpc-auth-gss-390003");
751MODULE_ALIAS("rpc-auth-gss-390004"); 754MODULE_ALIAS("rpc-auth-gss-390004");
752MODULE_ALIAS("rpc-auth-gss-390005"); 755MODULE_ALIAS("rpc-auth-gss-390005");
756MODULE_ALIAS("rpc-auth-gss-1.2.840.113554.1.2.2");
753 757
754static struct gss_api_mech gss_kerberos_mech = { 758static struct gss_api_mech gss_kerberos_mech = {
755 .gm_name = "krb5", 759 .gm_name = "krb5",
756 .gm_owner = THIS_MODULE, 760 .gm_owner = THIS_MODULE,
757 .gm_oid = {9, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"}, 761 .gm_oid = { 9, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" },
758 .gm_ops = &gss_kerberos_ops, 762 .gm_ops = &gss_kerberos_ops,
759 .gm_pf_num = ARRAY_SIZE(gss_kerberos_pfs), 763 .gm_pf_num = ARRAY_SIZE(gss_kerberos_pfs),
760 .gm_pfs = gss_kerberos_pfs, 764 .gm_pfs = gss_kerberos_pfs,
diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c
index f0f4eee63a35..79881d6e68a1 100644
--- a/net/sunrpc/auth_gss/gss_mech_switch.c
+++ b/net/sunrpc/auth_gss/gss_mech_switch.c
@@ -36,6 +36,7 @@
36#include <linux/types.h> 36#include <linux/types.h>
37#include <linux/slab.h> 37#include <linux/slab.h>
38#include <linux/module.h> 38#include <linux/module.h>
39#include <linux/oid_registry.h>
39#include <linux/sunrpc/msg_prot.h> 40#include <linux/sunrpc/msg_prot.h>
40#include <linux/sunrpc/gss_asn1.h> 41#include <linux/sunrpc/gss_asn1.h>
41#include <linux/sunrpc/auth_gss.h> 42#include <linux/sunrpc/auth_gss.h>
@@ -102,8 +103,13 @@ out:
102 return status; 103 return status;
103} 104}
104 105
105int 106/**
106gss_mech_register(struct gss_api_mech *gm) 107 * gss_mech_register - register a GSS mechanism
108 * @gm: GSS mechanism handle
109 *
110 * Returns zero if successful, or a negative errno.
111 */
112int gss_mech_register(struct gss_api_mech *gm)
107{ 113{
108 int status; 114 int status;
109 115
@@ -116,11 +122,14 @@ gss_mech_register(struct gss_api_mech *gm)
116 dprintk("RPC: registered gss mechanism %s\n", gm->gm_name); 122 dprintk("RPC: registered gss mechanism %s\n", gm->gm_name);
117 return 0; 123 return 0;
118} 124}
119
120EXPORT_SYMBOL_GPL(gss_mech_register); 125EXPORT_SYMBOL_GPL(gss_mech_register);
121 126
122void 127/**
123gss_mech_unregister(struct gss_api_mech *gm) 128 * gss_mech_unregister - release a GSS mechanism
129 * @gm: GSS mechanism handle
130 *
131 */
132void gss_mech_unregister(struct gss_api_mech *gm)
124{ 133{
125 spin_lock(&registered_mechs_lock); 134 spin_lock(&registered_mechs_lock);
126 list_del(&gm->gm_list); 135 list_del(&gm->gm_list);
@@ -128,18 +137,14 @@ gss_mech_unregister(struct gss_api_mech *gm)
128 dprintk("RPC: unregistered gss mechanism %s\n", gm->gm_name); 137 dprintk("RPC: unregistered gss mechanism %s\n", gm->gm_name);
129 gss_mech_free(gm); 138 gss_mech_free(gm);
130} 139}
131
132EXPORT_SYMBOL_GPL(gss_mech_unregister); 140EXPORT_SYMBOL_GPL(gss_mech_unregister);
133 141
134struct gss_api_mech * 142static struct gss_api_mech *gss_mech_get(struct gss_api_mech *gm)
135gss_mech_get(struct gss_api_mech *gm)
136{ 143{
137 __module_get(gm->gm_owner); 144 __module_get(gm->gm_owner);
138 return gm; 145 return gm;
139} 146}
140 147
141EXPORT_SYMBOL_GPL(gss_mech_get);
142
143static struct gss_api_mech * 148static struct gss_api_mech *
144_gss_mech_get_by_name(const char *name) 149_gss_mech_get_by_name(const char *name)
145{ 150{
@@ -169,12 +174,16 @@ struct gss_api_mech * gss_mech_get_by_name(const char *name)
169 } 174 }
170 return gm; 175 return gm;
171} 176}
172EXPORT_SYMBOL_GPL(gss_mech_get_by_name);
173 177
174struct gss_api_mech * 178static struct gss_api_mech *gss_mech_get_by_OID(struct rpcsec_gss_oid *obj)
175gss_mech_get_by_OID(struct xdr_netobj *obj)
176{ 179{
177 struct gss_api_mech *pos, *gm = NULL; 180 struct gss_api_mech *pos, *gm = NULL;
181 char buf[32];
182
183 if (sprint_oid(obj->data, obj->len, buf, sizeof(buf)) < 0)
184 return NULL;
185 dprintk("RPC: %s(%s)\n", __func__, buf);
186 request_module("rpc-auth-gss-%s", buf);
178 187
179 spin_lock(&registered_mechs_lock); 188 spin_lock(&registered_mechs_lock);
180 list_for_each_entry(pos, &registered_mechs, gm_list) { 189 list_for_each_entry(pos, &registered_mechs, gm_list) {
@@ -188,11 +197,8 @@ gss_mech_get_by_OID(struct xdr_netobj *obj)
188 } 197 }
189 spin_unlock(&registered_mechs_lock); 198 spin_unlock(&registered_mechs_lock);
190 return gm; 199 return gm;
191
192} 200}
193 201
194EXPORT_SYMBOL_GPL(gss_mech_get_by_OID);
195
196static inline int 202static inline int
197mech_supports_pseudoflavor(struct gss_api_mech *gm, u32 pseudoflavor) 203mech_supports_pseudoflavor(struct gss_api_mech *gm, u32 pseudoflavor)
198{ 204{
@@ -237,8 +243,6 @@ gss_mech_get_by_pseudoflavor(u32 pseudoflavor)
237 return gm; 243 return gm;
238} 244}
239 245
240EXPORT_SYMBOL_GPL(gss_mech_get_by_pseudoflavor);
241
242/** 246/**
243 * gss_mech_list_pseudoflavors - Discover registered GSS pseudoflavors 247 * gss_mech_list_pseudoflavors - Discover registered GSS pseudoflavors
244 * @array: array to fill in 248 * @array: array to fill in
@@ -268,19 +272,82 @@ int gss_mech_list_pseudoflavors(rpc_authflavor_t *array_ptr, int size)
268 return i; 272 return i;
269} 273}
270 274
271u32 275/**
272gss_svc_to_pseudoflavor(struct gss_api_mech *gm, u32 service) 276 * gss_svc_to_pseudoflavor - map a GSS service number to a pseudoflavor
277 * @gm: GSS mechanism handle
278 * @qop: GSS quality-of-protection value
279 * @service: GSS service value
280 *
281 * Returns a matching security flavor, or RPC_AUTH_MAXFLAVOR if none is found.
282 */
283rpc_authflavor_t gss_svc_to_pseudoflavor(struct gss_api_mech *gm, u32 qop,
284 u32 service)
273{ 285{
274 int i; 286 int i;
275 287
276 for (i = 0; i < gm->gm_pf_num; i++) { 288 for (i = 0; i < gm->gm_pf_num; i++) {
277 if (gm->gm_pfs[i].service == service) { 289 if (gm->gm_pfs[i].qop == qop &&
290 gm->gm_pfs[i].service == service) {
278 return gm->gm_pfs[i].pseudoflavor; 291 return gm->gm_pfs[i].pseudoflavor;
279 } 292 }
280 } 293 }
281 return RPC_AUTH_MAXFLAVOR; /* illegal value */ 294 return RPC_AUTH_MAXFLAVOR;
295}
296
297/**
298 * gss_mech_info2flavor - look up a pseudoflavor given a GSS tuple
299 * @info: a GSS mech OID, quality of protection, and service value
300 *
301 * Returns a matching pseudoflavor, or RPC_AUTH_MAXFLAVOR if the tuple is
302 * not supported.
303 */
304rpc_authflavor_t gss_mech_info2flavor(struct rpcsec_gss_info *info)
305{
306 rpc_authflavor_t pseudoflavor;
307 struct gss_api_mech *gm;
308
309 gm = gss_mech_get_by_OID(&info->oid);
310 if (gm == NULL)
311 return RPC_AUTH_MAXFLAVOR;
312
313 pseudoflavor = gss_svc_to_pseudoflavor(gm, info->qop, info->service);
314
315 gss_mech_put(gm);
316 return pseudoflavor;
317}
318
319/**
320 * gss_mech_flavor2info - look up a GSS tuple for a given pseudoflavor
321 * @pseudoflavor: GSS pseudoflavor to match
322 * @info: rpcsec_gss_info structure to fill in
323 *
324 * Returns zero and fills in "info" if pseudoflavor matches a
325 * supported mechanism. Otherwise a negative errno is returned.
326 */
327int gss_mech_flavor2info(rpc_authflavor_t pseudoflavor,
328 struct rpcsec_gss_info *info)
329{
330 struct gss_api_mech *gm;
331 int i;
332
333 gm = gss_mech_get_by_pseudoflavor(pseudoflavor);
334 if (gm == NULL)
335 return -ENOENT;
336
337 for (i = 0; i < gm->gm_pf_num; i++) {
338 if (gm->gm_pfs[i].pseudoflavor == pseudoflavor) {
339 memcpy(info->oid.data, gm->gm_oid.data, gm->gm_oid.len);
340 info->oid.len = gm->gm_oid.len;
341 info->qop = gm->gm_pfs[i].qop;
342 info->service = gm->gm_pfs[i].service;
343 gss_mech_put(gm);
344 return 0;
345 }
346 }
347
348 gss_mech_put(gm);
349 return -ENOENT;
282} 350}
283EXPORT_SYMBOL_GPL(gss_svc_to_pseudoflavor);
284 351
285u32 352u32
286gss_pseudoflavor_to_service(struct gss_api_mech *gm, u32 pseudoflavor) 353gss_pseudoflavor_to_service(struct gss_api_mech *gm, u32 pseudoflavor)
@@ -294,8 +361,6 @@ gss_pseudoflavor_to_service(struct gss_api_mech *gm, u32 pseudoflavor)
294 return 0; 361 return 0;
295} 362}
296 363
297EXPORT_SYMBOL_GPL(gss_pseudoflavor_to_service);
298
299char * 364char *
300gss_service_to_auth_domain_name(struct gss_api_mech *gm, u32 service) 365gss_service_to_auth_domain_name(struct gss_api_mech *gm, u32 service)
301{ 366{
@@ -308,8 +373,6 @@ gss_service_to_auth_domain_name(struct gss_api_mech *gm, u32 service)
308 return NULL; 373 return NULL;
309} 374}
310 375
311EXPORT_SYMBOL_GPL(gss_service_to_auth_domain_name);
312
313void 376void
314gss_mech_put(struct gss_api_mech * gm) 377gss_mech_put(struct gss_api_mech * gm)
315{ 378{
@@ -317,8 +380,6 @@ gss_mech_put(struct gss_api_mech * gm)
317 module_put(gm->gm_owner); 380 module_put(gm->gm_owner);
318} 381}
319 382
320EXPORT_SYMBOL_GPL(gss_mech_put);
321
322/* The mech could probably be determined from the token instead, but it's just 383/* The mech could probably be determined from the token instead, but it's just
323 * as easy for now to pass it in. */ 384 * as easy for now to pass it in. */
324int 385int
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 5ead60550895..c3ba570222dc 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -1220,7 +1220,9 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
1220 svcdata->rsci = rsci; 1220 svcdata->rsci = rsci;
1221 cache_get(&rsci->h); 1221 cache_get(&rsci->h);
1222 rqstp->rq_cred.cr_flavor = gss_svc_to_pseudoflavor( 1222 rqstp->rq_cred.cr_flavor = gss_svc_to_pseudoflavor(
1223 rsci->mechctx->mech_type, gc->gc_svc); 1223 rsci->mechctx->mech_type,
1224 GSS_C_QOP_DEFAULT,
1225 gc->gc_svc);
1224 ret = SVC_OK; 1226 ret = SVC_OK;
1225 goto out; 1227 goto out;
1226 } 1228 }
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index d5f35f15af98..d259fa966927 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -411,6 +411,8 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
411 }; 411 };
412 char servername[48]; 412 char servername[48];
413 413
414 if (args->flags & RPC_CLNT_CREATE_INFINITE_SLOTS)
415 xprtargs.flags |= XPRT_CREATE_INFINITE_SLOTS;
414 /* 416 /*
415 * If the caller chooses not to specify a hostname, whip 417 * If the caller chooses not to specify a hostname, whip
416 * up a string representation of the passed-in address. 418 * up a string representation of the passed-in address.
@@ -1301,6 +1303,8 @@ call_reserve(struct rpc_task *task)
1301 xprt_reserve(task); 1303 xprt_reserve(task);
1302} 1304}
1303 1305
1306static void call_retry_reserve(struct rpc_task *task);
1307
1304/* 1308/*
1305 * 1b. Grok the result of xprt_reserve() 1309 * 1b. Grok the result of xprt_reserve()
1306 */ 1310 */
@@ -1342,7 +1346,7 @@ call_reserveresult(struct rpc_task *task)
1342 case -ENOMEM: 1346 case -ENOMEM:
1343 rpc_delay(task, HZ >> 2); 1347 rpc_delay(task, HZ >> 2);
1344 case -EAGAIN: /* woken up; retry */ 1348 case -EAGAIN: /* woken up; retry */
1345 task->tk_action = call_reserve; 1349 task->tk_action = call_retry_reserve;
1346 return; 1350 return;
1347 case -EIO: /* probably a shutdown */ 1351 case -EIO: /* probably a shutdown */
1348 break; 1352 break;
@@ -1355,6 +1359,19 @@ call_reserveresult(struct rpc_task *task)
1355} 1359}
1356 1360
1357/* 1361/*
1362 * 1c. Retry reserving an RPC call slot
1363 */
1364static void
1365call_retry_reserve(struct rpc_task *task)
1366{
1367 dprint_status(task);
1368
1369 task->tk_status = 0;
1370 task->tk_action = call_reserveresult;
1371 xprt_retry_reserve(task);
1372}
1373
1374/*
1358 * 2. Bind and/or refresh the credentials 1375 * 2. Bind and/or refresh the credentials
1359 */ 1376 */
1360static void 1377static void
@@ -1639,22 +1656,26 @@ call_connect_status(struct rpc_task *task)
1639 1656
1640 dprint_status(task); 1657 dprint_status(task);
1641 1658
1642 task->tk_status = 0;
1643 if (status >= 0 || status == -EAGAIN) {
1644 clnt->cl_stats->netreconn++;
1645 task->tk_action = call_transmit;
1646 return;
1647 }
1648
1649 trace_rpc_connect_status(task, status); 1659 trace_rpc_connect_status(task, status);
1650 switch (status) { 1660 switch (status) {
1651 /* if soft mounted, test if we've timed out */ 1661 /* if soft mounted, test if we've timed out */
1652 case -ETIMEDOUT: 1662 case -ETIMEDOUT:
1653 task->tk_action = call_timeout; 1663 task->tk_action = call_timeout;
1654 break; 1664 return;
1655 default: 1665 case -ECONNREFUSED:
1656 rpc_exit(task, -EIO); 1666 case -ECONNRESET:
1667 case -ENETUNREACH:
1668 if (RPC_IS_SOFTCONN(task))
1669 break;
1670 /* retry with existing socket, after a delay */
1671 case 0:
1672 case -EAGAIN:
1673 task->tk_status = 0;
1674 clnt->cl_stats->netreconn++;
1675 task->tk_action = call_transmit;
1676 return;
1657 } 1677 }
1678 rpc_exit(task, status);
1658} 1679}
1659 1680
1660/* 1681/*
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index b7478d5e7ffd..745fca3cfd36 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -948,6 +948,34 @@ void xprt_transmit(struct rpc_task *task)
948 spin_unlock_bh(&xprt->transport_lock); 948 spin_unlock_bh(&xprt->transport_lock);
949} 949}
950 950
951static void xprt_add_backlog(struct rpc_xprt *xprt, struct rpc_task *task)
952{
953 set_bit(XPRT_CONGESTED, &xprt->state);
954 rpc_sleep_on(&xprt->backlog, task, NULL);
955}
956
957static void xprt_wake_up_backlog(struct rpc_xprt *xprt)
958{
959 if (rpc_wake_up_next(&xprt->backlog) == NULL)
960 clear_bit(XPRT_CONGESTED, &xprt->state);
961}
962
963static bool xprt_throttle_congested(struct rpc_xprt *xprt, struct rpc_task *task)
964{
965 bool ret = false;
966
967 if (!test_bit(XPRT_CONGESTED, &xprt->state))
968 goto out;
969 spin_lock(&xprt->reserve_lock);
970 if (test_bit(XPRT_CONGESTED, &xprt->state)) {
971 rpc_sleep_on(&xprt->backlog, task, NULL);
972 ret = true;
973 }
974 spin_unlock(&xprt->reserve_lock);
975out:
976 return ret;
977}
978
951static struct rpc_rqst *xprt_dynamic_alloc_slot(struct rpc_xprt *xprt, gfp_t gfp_flags) 979static struct rpc_rqst *xprt_dynamic_alloc_slot(struct rpc_xprt *xprt, gfp_t gfp_flags)
952{ 980{
953 struct rpc_rqst *req = ERR_PTR(-EAGAIN); 981 struct rpc_rqst *req = ERR_PTR(-EAGAIN);
@@ -992,7 +1020,7 @@ void xprt_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task)
992 task->tk_status = -ENOMEM; 1020 task->tk_status = -ENOMEM;
993 break; 1021 break;
994 case -EAGAIN: 1022 case -EAGAIN:
995 rpc_sleep_on(&xprt->backlog, task, NULL); 1023 xprt_add_backlog(xprt, task);
996 dprintk("RPC: waiting for request slot\n"); 1024 dprintk("RPC: waiting for request slot\n");
997 default: 1025 default:
998 task->tk_status = -EAGAIN; 1026 task->tk_status = -EAGAIN;
@@ -1028,7 +1056,7 @@ static void xprt_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req)
1028 memset(req, 0, sizeof(*req)); /* mark unused */ 1056 memset(req, 0, sizeof(*req)); /* mark unused */
1029 list_add(&req->rq_list, &xprt->free); 1057 list_add(&req->rq_list, &xprt->free);
1030 } 1058 }
1031 rpc_wake_up_next(&xprt->backlog); 1059 xprt_wake_up_backlog(xprt);
1032 spin_unlock(&xprt->reserve_lock); 1060 spin_unlock(&xprt->reserve_lock);
1033} 1061}
1034 1062
@@ -1092,7 +1120,8 @@ EXPORT_SYMBOL_GPL(xprt_free);
1092 * xprt_reserve - allocate an RPC request slot 1120 * xprt_reserve - allocate an RPC request slot
1093 * @task: RPC task requesting a slot allocation 1121 * @task: RPC task requesting a slot allocation
1094 * 1122 *
1095 * If no more slots are available, place the task on the transport's 1123 * If the transport is marked as being congested, or if no more
1124 * slots are available, place the task on the transport's
1096 * backlog queue. 1125 * backlog queue.
1097 */ 1126 */
1098void xprt_reserve(struct rpc_task *task) 1127void xprt_reserve(struct rpc_task *task)
@@ -1107,6 +1136,32 @@ void xprt_reserve(struct rpc_task *task)
1107 task->tk_status = -EAGAIN; 1136 task->tk_status = -EAGAIN;
1108 rcu_read_lock(); 1137 rcu_read_lock();
1109 xprt = rcu_dereference(task->tk_client->cl_xprt); 1138 xprt = rcu_dereference(task->tk_client->cl_xprt);
1139 if (!xprt_throttle_congested(xprt, task))
1140 xprt->ops->alloc_slot(xprt, task);
1141 rcu_read_unlock();
1142}
1143
1144/**
1145 * xprt_retry_reserve - allocate an RPC request slot
1146 * @task: RPC task requesting a slot allocation
1147 *
1148 * If no more slots are available, place the task on the transport's
1149 * backlog queue.
1150 * Note that the only difference with xprt_reserve is that we now
1151 * ignore the value of the XPRT_CONGESTED flag.
1152 */
1153void xprt_retry_reserve(struct rpc_task *task)
1154{
1155 struct rpc_xprt *xprt;
1156
1157 task->tk_status = 0;
1158 if (task->tk_rqstp != NULL)
1159 return;
1160
1161 task->tk_timeout = 0;
1162 task->tk_status = -EAGAIN;
1163 rcu_read_lock();
1164 xprt = rcu_dereference(task->tk_client->cl_xprt);
1110 xprt->ops->alloc_slot(xprt, task); 1165 xprt->ops->alloc_slot(xprt, task);
1111 rcu_read_unlock(); 1166 rcu_read_unlock();
1112} 1167}
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 3d02130828da..9c2825827dec 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2207,10 +2207,6 @@ static void xs_tcp_setup_socket(struct work_struct *work)
2207 */ 2207 */
2208 xs_tcp_force_close(xprt); 2208 xs_tcp_force_close(xprt);
2209 break; 2209 break;
2210 case -ECONNREFUSED:
2211 case -ECONNRESET:
2212 case -ENETUNREACH:
2213 /* retry with existing socket, after a delay */
2214 case 0: 2210 case 0:
2215 case -EINPROGRESS: 2211 case -EINPROGRESS:
2216 case -EALREADY: 2212 case -EALREADY:
@@ -2221,6 +2217,10 @@ static void xs_tcp_setup_socket(struct work_struct *work)
2221 /* Happens, for instance, if the user specified a link 2217 /* Happens, for instance, if the user specified a link
2222 * local IPv6 address without a scope-id. 2218 * local IPv6 address without a scope-id.
2223 */ 2219 */
2220 case -ECONNREFUSED:
2221 case -ECONNRESET:
2222 case -ENETUNREACH:
2223 /* retry with existing socket, after a delay */
2224 goto out; 2224 goto out;
2225 } 2225 }
2226out_eagain: 2226out_eagain:
@@ -2767,9 +2767,13 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args)
2767 struct rpc_xprt *xprt; 2767 struct rpc_xprt *xprt;
2768 struct sock_xprt *transport; 2768 struct sock_xprt *transport;
2769 struct rpc_xprt *ret; 2769 struct rpc_xprt *ret;
2770 unsigned int max_slot_table_size = xprt_max_tcp_slot_table_entries;
2771
2772 if (args->flags & XPRT_CREATE_INFINITE_SLOTS)
2773 max_slot_table_size = RPC_MAX_SLOT_TABLE_LIMIT;
2770 2774
2771 xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries, 2775 xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries,
2772 xprt_max_tcp_slot_table_entries); 2776 max_slot_table_size);
2773 if (IS_ERR(xprt)) 2777 if (IS_ERR(xprt))
2774 return xprt; 2778 return xprt;
2775 transport = container_of(xprt, struct sock_xprt, xprt); 2779 transport = container_of(xprt, struct sock_xprt, xprt);