aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-09-09 12:19:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-09 12:19:15 -0400
commitbf97293eb878df3792d9de7213bd7b82135aea77 (patch)
tree16cb367bd78095b9eb8a54c800fcddfcccb618c7 /fs/nfs/nfs4proc.c
parent16d70e15295953b19ecf59e943723a181782b856 (diff)
parentb1b3e136948a2bf4915326acb0d825d7d180753f (diff)
Merge tag 'nfs-for-3.12-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client updates from Trond Myklebust: "Highlights include: - Fix NFSv4 recovery so that it doesn't recover lost locks in cases such as lease loss due to a network partition, where doing so may result in data corruption. Add a kernel parameter to control choice of legacy behaviour or not. - Performance improvements when 2 processes are writing to the same file. - Flush data to disk when an RPCSEC_GSS session timeout is imminent. - Implement NFSv4.1 SP4_MACH_CRED state protection to prevent other NFS clients from being able to manipulate our lease and file locking state. - Allow sharing of RPCSEC_GSS caches between different rpc clients. - Fix the broken NFSv4 security auto-negotiation between client and server. - Fix rmdir() to wait for outstanding sillyrename unlinks to complete - Add a tracepoint framework for debugging NFSv4 state recovery issues. - Add tracing to the generic NFS layer. - Add tracing for the SUNRPC socket connection state. - Clean up the rpc_pipefs mount/umount event management. - Merge more patches from Chuck in preparation for NFSv4 migration support" * tag 'nfs-for-3.12-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (107 commits) NFSv4: use mach cred for SECINFO_NO_NAME w/ integrity NFS: nfs_compare_super shouldn't check the auth flavour unless 'sec=' was set NFSv4: Allow security autonegotiation for submounts NFSv4: Disallow security negotiation for lookups when 'sec=' is specified NFSv4: Fix security auto-negotiation NFS: Clean up nfs_parse_security_flavors() NFS: Clean up the auth flavour array mess NFSv4.1 Use MDS auth flavor for data server connection NFS: Don't check lock owner compatability unless file is locked (part 2) NFS: Don't check lock owner compatibility in writes unless file is locked nfs4: Map NFS4ERR_WRONG_CRED to EPERM nfs4.1: Add SP4_MACH_CRED write and commit support nfs4.1: Add SP4_MACH_CRED stateid support nfs4.1: Add SP4_MACH_CRED secinfo support nfs4.1: Add SP4_MACH_CRED cleanup support nfs4.1: Add state protection handler nfs4.1: Minimal SP4_MACH_CRED implementation SUNRPC: Replace pointer values with task->tk_pid and rpc_clnt->cl_clid SUNRPC: Add an identifier for struct rpc_clnt SUNRPC: Ensure rpc_task->tk_pid is available for tracepoints ...
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c793
1 files changed, 618 insertions, 175 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 108a774095f7..39b6cf2d1683 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -66,6 +66,8 @@
66#include "nfs4session.h" 66#include "nfs4session.h"
67#include "fscache.h" 67#include "fscache.h"
68 68
69#include "nfs4trace.h"
70
69#define NFSDBG_FACILITY NFSDBG_PROC 71#define NFSDBG_FACILITY NFSDBG_PROC
70 72
71#define NFS4_POLL_RETRY_MIN (HZ/10) 73#define NFS4_POLL_RETRY_MIN (HZ/10)
@@ -150,6 +152,7 @@ static int nfs4_map_errors(int err)
150 case -NFS4ERR_RECALLCONFLICT: 152 case -NFS4ERR_RECALLCONFLICT:
151 return -EREMOTEIO; 153 return -EREMOTEIO;
152 case -NFS4ERR_WRONGSEC: 154 case -NFS4ERR_WRONGSEC:
155 case -NFS4ERR_WRONG_CRED:
153 return -EPERM; 156 return -EPERM;
154 case -NFS4ERR_BADOWNER: 157 case -NFS4ERR_BADOWNER:
155 case -NFS4ERR_BADNAME: 158 case -NFS4ERR_BADNAME:
@@ -433,6 +436,20 @@ wait_on_recovery:
433 return ret; 436 return ret;
434} 437}
435 438
439/*
440 * Return 'true' if 'clp' is using an rpc_client that is integrity protected
441 * or 'false' otherwise.
442 */
443static bool _nfs4_is_integrity_protected(struct nfs_client *clp)
444{
445 rpc_authflavor_t flavor = clp->cl_rpcclient->cl_auth->au_flavor;
446
447 if (flavor == RPC_AUTH_GSS_KRB5I ||
448 flavor == RPC_AUTH_GSS_KRB5P)
449 return true;
450
451 return false;
452}
436 453
437static void do_renew_lease(struct nfs_client *clp, unsigned long timestamp) 454static void do_renew_lease(struct nfs_client *clp, unsigned long timestamp)
438{ 455{
@@ -447,6 +464,88 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestamp
447 do_renew_lease(server->nfs_client, timestamp); 464 do_renew_lease(server->nfs_client, timestamp);
448} 465}
449 466
467struct nfs4_call_sync_data {
468 const struct nfs_server *seq_server;
469 struct nfs4_sequence_args *seq_args;
470 struct nfs4_sequence_res *seq_res;
471};
472
473static void nfs4_init_sequence(struct nfs4_sequence_args *args,
474 struct nfs4_sequence_res *res, int cache_reply)
475{
476 args->sa_slot = NULL;
477 args->sa_cache_this = cache_reply;
478 args->sa_privileged = 0;
479
480 res->sr_slot = NULL;
481}
482
483static void nfs4_set_sequence_privileged(struct nfs4_sequence_args *args)
484{
485 args->sa_privileged = 1;
486}
487
488static int nfs40_setup_sequence(const struct nfs_server *server,
489 struct nfs4_sequence_args *args,
490 struct nfs4_sequence_res *res,
491 struct rpc_task *task)
492{
493 struct nfs4_slot_table *tbl = server->nfs_client->cl_slot_tbl;
494 struct nfs4_slot *slot;
495
496 /* slot already allocated? */
497 if (res->sr_slot != NULL)
498 goto out_start;
499
500 spin_lock(&tbl->slot_tbl_lock);
501 if (nfs4_slot_tbl_draining(tbl) && !args->sa_privileged)
502 goto out_sleep;
503
504 slot = nfs4_alloc_slot(tbl);
505 if (IS_ERR(slot)) {
506 if (slot == ERR_PTR(-ENOMEM))
507 task->tk_timeout = HZ >> 2;
508 goto out_sleep;
509 }
510 spin_unlock(&tbl->slot_tbl_lock);
511
512 args->sa_slot = slot;
513 res->sr_slot = slot;
514
515out_start:
516 rpc_call_start(task);
517 return 0;
518
519out_sleep:
520 if (args->sa_privileged)
521 rpc_sleep_on_priority(&tbl->slot_tbl_waitq, task,
522 NULL, RPC_PRIORITY_PRIVILEGED);
523 else
524 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
525 spin_unlock(&tbl->slot_tbl_lock);
526 return -EAGAIN;
527}
528
529static int nfs40_sequence_done(struct rpc_task *task,
530 struct nfs4_sequence_res *res)
531{
532 struct nfs4_slot *slot = res->sr_slot;
533 struct nfs4_slot_table *tbl;
534
535 if (!RPC_WAS_SENT(task))
536 goto out;
537
538 tbl = slot->table;
539 spin_lock(&tbl->slot_tbl_lock);
540 if (!nfs41_wake_and_assign_slot(tbl, slot))
541 nfs4_free_slot(tbl, slot);
542 spin_unlock(&tbl->slot_tbl_lock);
543
544 res->sr_slot = NULL;
545out:
546 return 1;
547}
548
450#if defined(CONFIG_NFS_V4_1) 549#if defined(CONFIG_NFS_V4_1)
451 550
452static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res) 551static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
@@ -506,6 +605,7 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *
506 interrupted = true; 605 interrupted = true;
507 } 606 }
508 607
608 trace_nfs4_sequence_done(session, res);
509 /* Check the SEQUENCE operation status */ 609 /* Check the SEQUENCE operation status */
510 switch (res->sr_status) { 610 switch (res->sr_status) {
511 case 0: 611 case 0:
@@ -591,25 +691,11 @@ static int nfs4_sequence_done(struct rpc_task *task,
591{ 691{
592 if (res->sr_slot == NULL) 692 if (res->sr_slot == NULL)
593 return 1; 693 return 1;
694 if (!res->sr_slot->table->session)
695 return nfs40_sequence_done(task, res);
594 return nfs41_sequence_done(task, res); 696 return nfs41_sequence_done(task, res);
595} 697}
596 698
597static void nfs41_init_sequence(struct nfs4_sequence_args *args,
598 struct nfs4_sequence_res *res, int cache_reply)
599{
600 args->sa_slot = NULL;
601 args->sa_cache_this = 0;
602 args->sa_privileged = 0;
603 if (cache_reply)
604 args->sa_cache_this = 1;
605 res->sr_slot = NULL;
606}
607
608static void nfs4_set_sequence_privileged(struct nfs4_sequence_args *args)
609{
610 args->sa_privileged = 1;
611}
612
613int nfs41_setup_sequence(struct nfs4_session *session, 699int nfs41_setup_sequence(struct nfs4_session *session,
614 struct nfs4_sequence_args *args, 700 struct nfs4_sequence_args *args,
615 struct nfs4_sequence_res *res, 701 struct nfs4_sequence_res *res,
@@ -647,7 +733,7 @@ int nfs41_setup_sequence(struct nfs4_session *session,
647 733
648 args->sa_slot = slot; 734 args->sa_slot = slot;
649 735
650 dprintk("<-- %s slotid=%d seqid=%d\n", __func__, 736 dprintk("<-- %s slotid=%u seqid=%u\n", __func__,
651 slot->slot_nr, slot->seq_nr); 737 slot->slot_nr, slot->seq_nr);
652 738
653 res->sr_slot = slot; 739 res->sr_slot = slot;
@@ -658,6 +744,7 @@ int nfs41_setup_sequence(struct nfs4_session *session,
658 * set to 1 if an rpc level failure occurs. 744 * set to 1 if an rpc level failure occurs.
659 */ 745 */
660 res->sr_status = 1; 746 res->sr_status = 1;
747 trace_nfs4_setup_sequence(session, args);
661out_success: 748out_success:
662 rpc_call_start(task); 749 rpc_call_start(task);
663 return 0; 750 return 0;
@@ -673,38 +760,30 @@ out_sleep:
673} 760}
674EXPORT_SYMBOL_GPL(nfs41_setup_sequence); 761EXPORT_SYMBOL_GPL(nfs41_setup_sequence);
675 762
676int nfs4_setup_sequence(const struct nfs_server *server, 763static int nfs4_setup_sequence(const struct nfs_server *server,
677 struct nfs4_sequence_args *args, 764 struct nfs4_sequence_args *args,
678 struct nfs4_sequence_res *res, 765 struct nfs4_sequence_res *res,
679 struct rpc_task *task) 766 struct rpc_task *task)
680{ 767{
681 struct nfs4_session *session = nfs4_get_session(server); 768 struct nfs4_session *session = nfs4_get_session(server);
682 int ret = 0; 769 int ret = 0;
683 770
684 if (session == NULL) { 771 if (!session)
685 rpc_call_start(task); 772 return nfs40_setup_sequence(server, args, res, task);
686 goto out;
687 }
688 773
689 dprintk("--> %s clp %p session %p sr_slot %d\n", 774 dprintk("--> %s clp %p session %p sr_slot %u\n",
690 __func__, session->clp, session, res->sr_slot ? 775 __func__, session->clp, session, res->sr_slot ?
691 res->sr_slot->slot_nr : -1); 776 res->sr_slot->slot_nr : NFS4_NO_SLOT);
692 777
693 ret = nfs41_setup_sequence(session, args, res, task); 778 ret = nfs41_setup_sequence(session, args, res, task);
694out: 779
695 dprintk("<-- %s status=%d\n", __func__, ret); 780 dprintk("<-- %s status=%d\n", __func__, ret);
696 return ret; 781 return ret;
697} 782}
698 783
699struct nfs41_call_sync_data {
700 const struct nfs_server *seq_server;
701 struct nfs4_sequence_args *seq_args;
702 struct nfs4_sequence_res *seq_res;
703};
704
705static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata) 784static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
706{ 785{
707 struct nfs41_call_sync_data *data = calldata; 786 struct nfs4_call_sync_data *data = calldata;
708 struct nfs4_session *session = nfs4_get_session(data->seq_server); 787 struct nfs4_session *session = nfs4_get_session(data->seq_server);
709 788
710 dprintk("--> %s data->seq_server %p\n", __func__, data->seq_server); 789 dprintk("--> %s data->seq_server %p\n", __func__, data->seq_server);
@@ -714,7 +793,7 @@ static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
714 793
715static void nfs41_call_sync_done(struct rpc_task *task, void *calldata) 794static void nfs41_call_sync_done(struct rpc_task *task, void *calldata)
716{ 795{
717 struct nfs41_call_sync_data *data = calldata; 796 struct nfs4_call_sync_data *data = calldata;
718 797
719 nfs41_sequence_done(task, data->seq_res); 798 nfs41_sequence_done(task, data->seq_res);
720} 799}
@@ -724,6 +803,42 @@ static const struct rpc_call_ops nfs41_call_sync_ops = {
724 .rpc_call_done = nfs41_call_sync_done, 803 .rpc_call_done = nfs41_call_sync_done,
725}; 804};
726 805
806#else /* !CONFIG_NFS_V4_1 */
807
808static int nfs4_setup_sequence(const struct nfs_server *server,
809 struct nfs4_sequence_args *args,
810 struct nfs4_sequence_res *res,
811 struct rpc_task *task)
812{
813 return nfs40_setup_sequence(server, args, res, task);
814}
815
816static int nfs4_sequence_done(struct rpc_task *task,
817 struct nfs4_sequence_res *res)
818{
819 return nfs40_sequence_done(task, res);
820}
821
822#endif /* !CONFIG_NFS_V4_1 */
823
824static void nfs40_call_sync_prepare(struct rpc_task *task, void *calldata)
825{
826 struct nfs4_call_sync_data *data = calldata;
827 nfs4_setup_sequence(data->seq_server,
828 data->seq_args, data->seq_res, task);
829}
830
831static void nfs40_call_sync_done(struct rpc_task *task, void *calldata)
832{
833 struct nfs4_call_sync_data *data = calldata;
834 nfs4_sequence_done(task, data->seq_res);
835}
836
837static const struct rpc_call_ops nfs40_call_sync_ops = {
838 .rpc_call_prepare = nfs40_call_sync_prepare,
839 .rpc_call_done = nfs40_call_sync_done,
840};
841
727static int nfs4_call_sync_sequence(struct rpc_clnt *clnt, 842static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
728 struct nfs_server *server, 843 struct nfs_server *server,
729 struct rpc_message *msg, 844 struct rpc_message *msg,
@@ -732,7 +847,8 @@ static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
732{ 847{
733 int ret; 848 int ret;
734 struct rpc_task *task; 849 struct rpc_task *task;
735 struct nfs41_call_sync_data data = { 850 struct nfs_client *clp = server->nfs_client;
851 struct nfs4_call_sync_data data = {
736 .seq_server = server, 852 .seq_server = server,
737 .seq_args = args, 853 .seq_args = args,
738 .seq_res = res, 854 .seq_res = res,
@@ -740,7 +856,7 @@ static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
740 struct rpc_task_setup task_setup = { 856 struct rpc_task_setup task_setup = {
741 .rpc_client = clnt, 857 .rpc_client = clnt,
742 .rpc_message = msg, 858 .rpc_message = msg,
743 .callback_ops = &nfs41_call_sync_ops, 859 .callback_ops = clp->cl_mvops->call_sync_ops,
744 .callback_data = &data 860 .callback_data = &data
745 }; 861 };
746 862
@@ -754,35 +870,6 @@ static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
754 return ret; 870 return ret;
755} 871}
756 872
757#else
758static
759void nfs41_init_sequence(struct nfs4_sequence_args *args,
760 struct nfs4_sequence_res *res, int cache_reply)
761{
762}
763
764static void nfs4_set_sequence_privileged(struct nfs4_sequence_args *args)
765{
766}
767
768
769static int nfs4_sequence_done(struct rpc_task *task,
770 struct nfs4_sequence_res *res)
771{
772 return 1;
773}
774#endif /* CONFIG_NFS_V4_1 */
775
776static
777int _nfs4_call_sync(struct rpc_clnt *clnt,
778 struct nfs_server *server,
779 struct rpc_message *msg,
780 struct nfs4_sequence_args *args,
781 struct nfs4_sequence_res *res)
782{
783 return rpc_call_sync(clnt, msg, 0);
784}
785
786static 873static
787int nfs4_call_sync(struct rpc_clnt *clnt, 874int nfs4_call_sync(struct rpc_clnt *clnt,
788 struct nfs_server *server, 875 struct nfs_server *server,
@@ -791,9 +878,8 @@ int nfs4_call_sync(struct rpc_clnt *clnt,
791 struct nfs4_sequence_res *res, 878 struct nfs4_sequence_res *res,
792 int cache_reply) 879 int cache_reply)
793{ 880{
794 nfs41_init_sequence(args, res, cache_reply); 881 nfs4_init_sequence(args, res, cache_reply);
795 return server->nfs_client->cl_mvops->call_sync(clnt, server, msg, 882 return nfs4_call_sync_sequence(clnt, server, msg, args, res);
796 args, res);
797} 883}
798 884
799static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo) 885static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
@@ -933,7 +1019,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
933 p->o_arg.fh = NFS_FH(dentry->d_inode); 1019 p->o_arg.fh = NFS_FH(dentry->d_inode);
934 } 1020 }
935 if (attrs != NULL && attrs->ia_valid != 0) { 1021 if (attrs != NULL && attrs->ia_valid != 0) {
936 __be32 verf[2]; 1022 __u32 verf[2];
937 1023
938 p->o_arg.u.attrs = &p->attrs; 1024 p->o_arg.u.attrs = &p->attrs;
939 memcpy(&p->attrs, attrs, sizeof(p->attrs)); 1025 memcpy(&p->attrs, attrs, sizeof(p->attrs));
@@ -1103,7 +1189,7 @@ static int update_open_stateid(struct nfs4_state *state, nfs4_stateid *open_stat
1103 goto no_delegation; 1189 goto no_delegation;
1104 1190
1105 spin_lock(&deleg_cur->lock); 1191 spin_lock(&deleg_cur->lock);
1106 if (nfsi->delegation != deleg_cur || 1192 if (rcu_dereference(nfsi->delegation) != deleg_cur ||
1107 test_bit(NFS_DELEGATION_RETURNING, &deleg_cur->flags) || 1193 test_bit(NFS_DELEGATION_RETURNING, &deleg_cur->flags) ||
1108 (deleg_cur->type & fmode) != fmode) 1194 (deleg_cur->type & fmode) != fmode)
1109 goto no_delegation_unlock; 1195 goto no_delegation_unlock;
@@ -1440,6 +1526,7 @@ static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state
1440 int err; 1526 int err;
1441 do { 1527 do {
1442 err = _nfs4_do_open_reclaim(ctx, state); 1528 err = _nfs4_do_open_reclaim(ctx, state);
1529 trace_nfs4_open_reclaim(ctx, 0, err);
1443 if (nfs4_clear_cap_atomic_open_v1(server, err, &exception)) 1530 if (nfs4_clear_cap_atomic_open_v1(server, err, &exception))
1444 continue; 1531 continue;
1445 if (err != -NFS4ERR_DELAY) 1532 if (err != -NFS4ERR_DELAY)
@@ -1524,10 +1611,20 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state
1524 return nfs4_handle_delegation_recall_error(server, state, stateid, err); 1611 return nfs4_handle_delegation_recall_error(server, state, stateid, err);
1525} 1612}
1526 1613
1614static void nfs4_open_confirm_prepare(struct rpc_task *task, void *calldata)
1615{
1616 struct nfs4_opendata *data = calldata;
1617
1618 nfs40_setup_sequence(data->o_arg.server, &data->o_arg.seq_args,
1619 &data->o_res.seq_res, task);
1620}
1621
1527static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata) 1622static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata)
1528{ 1623{
1529 struct nfs4_opendata *data = calldata; 1624 struct nfs4_opendata *data = calldata;
1530 1625
1626 nfs40_sequence_done(task, &data->o_res.seq_res);
1627
1531 data->rpc_status = task->tk_status; 1628 data->rpc_status = task->tk_status;
1532 if (data->rpc_status == 0) { 1629 if (data->rpc_status == 0) {
1533 nfs4_stateid_copy(&data->o_res.stateid, &data->c_res.stateid); 1630 nfs4_stateid_copy(&data->o_res.stateid, &data->c_res.stateid);
@@ -1556,6 +1653,7 @@ out_free:
1556} 1653}
1557 1654
1558static const struct rpc_call_ops nfs4_open_confirm_ops = { 1655static const struct rpc_call_ops nfs4_open_confirm_ops = {
1656 .rpc_call_prepare = nfs4_open_confirm_prepare,
1559 .rpc_call_done = nfs4_open_confirm_done, 1657 .rpc_call_done = nfs4_open_confirm_done,
1560 .rpc_release = nfs4_open_confirm_release, 1658 .rpc_release = nfs4_open_confirm_release,
1561}; 1659};
@@ -1583,6 +1681,7 @@ static int _nfs4_proc_open_confirm(struct nfs4_opendata *data)
1583 }; 1681 };
1584 int status; 1682 int status;
1585 1683
1684 nfs4_init_sequence(&data->o_arg.seq_args, &data->o_res.seq_res, 1);
1586 kref_get(&data->kref); 1685 kref_get(&data->kref);
1587 data->rpc_done = 0; 1686 data->rpc_done = 0;
1588 data->rpc_status = 0; 1687 data->rpc_status = 0;
@@ -1742,7 +1841,7 @@ static int nfs4_run_open_task(struct nfs4_opendata *data, int isrecover)
1742 }; 1841 };
1743 int status; 1842 int status;
1744 1843
1745 nfs41_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1); 1844 nfs4_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1);
1746 kref_get(&data->kref); 1845 kref_get(&data->kref);
1747 data->rpc_done = 0; 1846 data->rpc_done = 0;
1748 data->rpc_status = 0; 1847 data->rpc_status = 0;
@@ -1895,6 +1994,7 @@ static int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state
1895 1994
1896 do { 1995 do {
1897 err = _nfs4_open_expired(ctx, state); 1996 err = _nfs4_open_expired(ctx, state);
1997 trace_nfs4_open_expired(ctx, 0, err);
1898 if (nfs4_clear_cap_atomic_open_v1(server, err, &exception)) 1998 if (nfs4_clear_cap_atomic_open_v1(server, err, &exception))
1899 continue; 1999 continue;
1900 switch (err) { 2000 switch (err) {
@@ -1944,6 +2044,7 @@ static void nfs41_clear_delegation_stateid(struct nfs4_state *state)
1944 cred = get_rpccred(delegation->cred); 2044 cred = get_rpccred(delegation->cred);
1945 rcu_read_unlock(); 2045 rcu_read_unlock();
1946 status = nfs41_test_stateid(server, stateid, cred); 2046 status = nfs41_test_stateid(server, stateid, cred);
2047 trace_nfs4_test_delegation_stateid(state, NULL, status);
1947 } else 2048 } else
1948 rcu_read_unlock(); 2049 rcu_read_unlock();
1949 2050
@@ -1986,6 +2087,7 @@ static int nfs41_check_open_stateid(struct nfs4_state *state)
1986 return -NFS4ERR_BAD_STATEID; 2087 return -NFS4ERR_BAD_STATEID;
1987 2088
1988 status = nfs41_test_stateid(server, stateid, cred); 2089 status = nfs41_test_stateid(server, stateid, cred);
2090 trace_nfs4_test_open_stateid(state, NULL, status);
1989 if (status != NFS_OK) { 2091 if (status != NFS_OK) {
1990 /* Free the stateid unless the server explicitly 2092 /* Free the stateid unless the server explicitly
1991 * informs us the stateid is unrecognized. */ 2093 * informs us the stateid is unrecognized. */
@@ -2197,6 +2299,7 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir,
2197 do { 2299 do {
2198 status = _nfs4_do_open(dir, ctx, flags, sattr, label); 2300 status = _nfs4_do_open(dir, ctx, flags, sattr, label);
2199 res = ctx->state; 2301 res = ctx->state;
2302 trace_nfs4_open_file(ctx, flags, status);
2200 if (status == 0) 2303 if (status == 0)
2201 break; 2304 break;
2202 /* NOTE: BAD_SEQID means the server and client disagree about the 2305 /* NOTE: BAD_SEQID means the server and client disagree about the
@@ -2310,6 +2413,7 @@ static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
2310 int err; 2413 int err;
2311 do { 2414 do {
2312 err = _nfs4_do_setattr(inode, cred, fattr, sattr, state, ilabel, olabel); 2415 err = _nfs4_do_setattr(inode, cred, fattr, sattr, state, ilabel, olabel);
2416 trace_nfs4_setattr(inode, err);
2313 switch (err) { 2417 switch (err) {
2314 case -NFS4ERR_OPENMODE: 2418 case -NFS4ERR_OPENMODE:
2315 if (!(sattr->ia_valid & ATTR_SIZE)) { 2419 if (!(sattr->ia_valid & ATTR_SIZE)) {
@@ -2387,6 +2491,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
2387 dprintk("%s: begin!\n", __func__); 2491 dprintk("%s: begin!\n", __func__);
2388 if (!nfs4_sequence_done(task, &calldata->res.seq_res)) 2492 if (!nfs4_sequence_done(task, &calldata->res.seq_res))
2389 return; 2493 return;
2494 trace_nfs4_close(state, &calldata->arg, &calldata->res, task->tk_status);
2390 /* hmm. we are done with the inode, and in the process of freeing 2495 /* hmm. we are done with the inode, and in the process of freeing
2391 * the state_owner. we keep this around to process errors 2496 * the state_owner. we keep this around to process errors
2392 */ 2497 */
@@ -2511,10 +2616,13 @@ int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait)
2511 }; 2616 };
2512 int status = -ENOMEM; 2617 int status = -ENOMEM;
2513 2618
2619 nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_CLEANUP,
2620 &task_setup_data.rpc_client, &msg);
2621
2514 calldata = kzalloc(sizeof(*calldata), gfp_mask); 2622 calldata = kzalloc(sizeof(*calldata), gfp_mask);
2515 if (calldata == NULL) 2623 if (calldata == NULL)
2516 goto out; 2624 goto out;
2517 nfs41_init_sequence(&calldata->arg.seq_args, &calldata->res.seq_res, 1); 2625 nfs4_init_sequence(&calldata->arg.seq_args, &calldata->res.seq_res, 1);
2518 calldata->inode = state->inode; 2626 calldata->inode = state->inode;
2519 calldata->state = state; 2627 calldata->state = state;
2520 calldata->arg.fh = NFS_FH(state->inode); 2628 calldata->arg.fh = NFS_FH(state->inode);
@@ -2690,6 +2798,7 @@ static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
2690 int err; 2798 int err;
2691 do { 2799 do {
2692 err = _nfs4_lookup_root(server, fhandle, info); 2800 err = _nfs4_lookup_root(server, fhandle, info);
2801 trace_nfs4_lookup_root(server, fhandle, info->fattr, err);
2693 switch (err) { 2802 switch (err) {
2694 case 0: 2803 case 0:
2695 case -NFS4ERR_WRONGSEC: 2804 case -NFS4ERR_WRONGSEC:
@@ -2705,10 +2814,13 @@ out:
2705static int nfs4_lookup_root_sec(struct nfs_server *server, struct nfs_fh *fhandle, 2814static int nfs4_lookup_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
2706 struct nfs_fsinfo *info, rpc_authflavor_t flavor) 2815 struct nfs_fsinfo *info, rpc_authflavor_t flavor)
2707{ 2816{
2817 struct rpc_auth_create_args auth_args = {
2818 .pseudoflavor = flavor,
2819 };
2708 struct rpc_auth *auth; 2820 struct rpc_auth *auth;
2709 int ret; 2821 int ret;
2710 2822
2711 auth = rpcauth_create(flavor, server->client); 2823 auth = rpcauth_create(&auth_args, server->client);
2712 if (IS_ERR(auth)) { 2824 if (IS_ERR(auth)) {
2713 ret = -EACCES; 2825 ret = -EACCES;
2714 goto out; 2826 goto out;
@@ -2772,18 +2884,27 @@ static int nfs4_do_find_root_sec(struct nfs_server *server,
2772 * @server: initialized nfs_server handle 2884 * @server: initialized nfs_server handle
2773 * @fhandle: we fill in the pseudo-fs root file handle 2885 * @fhandle: we fill in the pseudo-fs root file handle
2774 * @info: we fill in an FSINFO struct 2886 * @info: we fill in an FSINFO struct
2887 * @auth_probe: probe the auth flavours
2775 * 2888 *
2776 * Returns zero on success, or a negative errno. 2889 * Returns zero on success, or a negative errno.
2777 */ 2890 */
2778int nfs4_proc_get_rootfh(struct nfs_server *server, struct nfs_fh *fhandle, 2891int nfs4_proc_get_rootfh(struct nfs_server *server, struct nfs_fh *fhandle,
2779 struct nfs_fsinfo *info) 2892 struct nfs_fsinfo *info,
2893 bool auth_probe)
2780{ 2894{
2781 int status; 2895 int status;
2782 2896
2783 status = nfs4_lookup_root(server, fhandle, info); 2897 switch (auth_probe) {
2784 if ((status == -NFS4ERR_WRONGSEC) && 2898 case false:
2785 !(server->flags & NFS_MOUNT_SECFLAVOUR)) 2899 status = nfs4_lookup_root(server, fhandle, info);
2900 if (status != -NFS4ERR_WRONGSEC)
2901 break;
2902 /* Did user force a 'sec=' mount option? */
2903 if (server->flags & NFS_MOUNT_SECFLAVOUR)
2904 break;
2905 default:
2786 status = nfs4_do_find_root_sec(server, fhandle, info); 2906 status = nfs4_do_find_root_sec(server, fhandle, info);
2907 }
2787 2908
2788 if (status == 0) 2909 if (status == 0)
2789 status = nfs4_server_capabilities(server, fhandle); 2910 status = nfs4_server_capabilities(server, fhandle);
@@ -2899,8 +3020,9 @@ static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
2899 struct nfs4_exception exception = { }; 3020 struct nfs4_exception exception = { };
2900 int err; 3021 int err;
2901 do { 3022 do {
2902 err = nfs4_handle_exception(server, 3023 err = _nfs4_proc_getattr(server, fhandle, fattr, label);
2903 _nfs4_proc_getattr(server, fhandle, fattr, label), 3024 trace_nfs4_getattr(server, fhandle, fattr, err);
3025 err = nfs4_handle_exception(server, err,
2904 &exception); 3026 &exception);
2905 } while (exception.retry); 3027 } while (exception.retry);
2906 return err; 3028 return err;
@@ -2940,10 +3062,10 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
2940 3062
2941 /* Deal with open(O_TRUNC) */ 3063 /* Deal with open(O_TRUNC) */
2942 if (sattr->ia_valid & ATTR_OPEN) 3064 if (sattr->ia_valid & ATTR_OPEN)
2943 sattr->ia_valid &= ~(ATTR_MTIME|ATTR_CTIME|ATTR_OPEN); 3065 sattr->ia_valid &= ~(ATTR_MTIME|ATTR_CTIME);
2944 3066
2945 /* Optimization: if the end result is no change, don't RPC */ 3067 /* Optimization: if the end result is no change, don't RPC */
2946 if ((sattr->ia_valid & ~(ATTR_FILE)) == 0) 3068 if ((sattr->ia_valid & ~(ATTR_FILE|ATTR_OPEN)) == 0)
2947 return 0; 3069 return 0;
2948 3070
2949 /* Search for an existing open(O_WRITE) file */ 3071 /* Search for an existing open(O_WRITE) file */
@@ -3020,6 +3142,7 @@ static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir,
3020 int err; 3142 int err;
3021 do { 3143 do {
3022 err = _nfs4_proc_lookup(client, dir, name, fhandle, fattr, label); 3144 err = _nfs4_proc_lookup(client, dir, name, fhandle, fattr, label);
3145 trace_nfs4_lookup(dir, name, err);
3023 switch (err) { 3146 switch (err) {
3024 case -NFS4ERR_BADNAME: 3147 case -NFS4ERR_BADNAME:
3025 err = -ENOENT; 3148 err = -ENOENT;
@@ -3031,7 +3154,9 @@ static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir,
3031 err = -EPERM; 3154 err = -EPERM;
3032 if (client != *clnt) 3155 if (client != *clnt)
3033 goto out; 3156 goto out;
3034 3157 /* No security negotiation if the user specified 'sec=' */
3158 if (NFS_SERVER(dir)->flags & NFS_MOUNT_SECFLAVOUR)
3159 goto out;
3035 client = nfs4_create_sec_client(client, dir, name); 3160 client = nfs4_create_sec_client(client, dir, name);
3036 if (IS_ERR(client)) 3161 if (IS_ERR(client))
3037 return PTR_ERR(client); 3162 return PTR_ERR(client);
@@ -3134,8 +3259,9 @@ static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
3134 struct nfs4_exception exception = { }; 3259 struct nfs4_exception exception = { };
3135 int err; 3260 int err;
3136 do { 3261 do {
3137 err = nfs4_handle_exception(NFS_SERVER(inode), 3262 err = _nfs4_proc_access(inode, entry);
3138 _nfs4_proc_access(inode, entry), 3263 trace_nfs4_access(inode, err);
3264 err = nfs4_handle_exception(NFS_SERVER(inode), err,
3139 &exception); 3265 &exception);
3140 } while (exception.retry); 3266 } while (exception.retry);
3141 return err; 3267 return err;
@@ -3188,8 +3314,9 @@ static int nfs4_proc_readlink(struct inode *inode, struct page *page,
3188 struct nfs4_exception exception = { }; 3314 struct nfs4_exception exception = { };
3189 int err; 3315 int err;
3190 do { 3316 do {
3191 err = nfs4_handle_exception(NFS_SERVER(inode), 3317 err = _nfs4_proc_readlink(inode, page, pgbase, pglen);
3192 _nfs4_proc_readlink(inode, page, pgbase, pglen), 3318 trace_nfs4_readlink(inode, err);
3319 err = nfs4_handle_exception(NFS_SERVER(inode), err,
3193 &exception); 3320 &exception);
3194 } while (exception.retry); 3321 } while (exception.retry);
3195 return err; 3322 return err;
@@ -3253,8 +3380,9 @@ static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
3253 struct nfs4_exception exception = { }; 3380 struct nfs4_exception exception = { };
3254 int err; 3381 int err;
3255 do { 3382 do {
3256 err = nfs4_handle_exception(NFS_SERVER(dir), 3383 err = _nfs4_proc_remove(dir, name);
3257 _nfs4_proc_remove(dir, name), 3384 trace_nfs4_remove(dir, name, err);
3385 err = nfs4_handle_exception(NFS_SERVER(dir), err,
3258 &exception); 3386 &exception);
3259 } while (exception.retry); 3387 } while (exception.retry);
3260 return err; 3388 return err;
@@ -3268,7 +3396,7 @@ static void nfs4_proc_unlink_setup(struct rpc_message *msg, struct inode *dir)
3268 3396
3269 res->server = server; 3397 res->server = server;
3270 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE]; 3398 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE];
3271 nfs41_init_sequence(&args->seq_args, &res->seq_res, 1); 3399 nfs4_init_sequence(&args->seq_args, &res->seq_res, 1);
3272 3400
3273 nfs_fattr_init(res->dir_attr); 3401 nfs_fattr_init(res->dir_attr);
3274} 3402}
@@ -3283,7 +3411,8 @@ static void nfs4_proc_unlink_rpc_prepare(struct rpc_task *task, struct nfs_unlin
3283 3411
3284static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir) 3412static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
3285{ 3413{
3286 struct nfs_removeres *res = task->tk_msg.rpc_resp; 3414 struct nfs_unlinkdata *data = task->tk_calldata;
3415 struct nfs_removeres *res = &data->res;
3287 3416
3288 if (!nfs4_sequence_done(task, &res->seq_res)) 3417 if (!nfs4_sequence_done(task, &res->seq_res))
3289 return 0; 3418 return 0;
@@ -3301,7 +3430,7 @@ static void nfs4_proc_rename_setup(struct rpc_message *msg, struct inode *dir)
3301 3430
3302 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME]; 3431 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME];
3303 res->server = server; 3432 res->server = server;
3304 nfs41_init_sequence(&arg->seq_args, &res->seq_res, 1); 3433 nfs4_init_sequence(&arg->seq_args, &res->seq_res, 1);
3305} 3434}
3306 3435
3307static void nfs4_proc_rename_rpc_prepare(struct rpc_task *task, struct nfs_renamedata *data) 3436static void nfs4_proc_rename_rpc_prepare(struct rpc_task *task, struct nfs_renamedata *data)
@@ -3315,7 +3444,8 @@ static void nfs4_proc_rename_rpc_prepare(struct rpc_task *task, struct nfs_renam
3315static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir, 3444static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
3316 struct inode *new_dir) 3445 struct inode *new_dir)
3317{ 3446{
3318 struct nfs_renameres *res = task->tk_msg.rpc_resp; 3447 struct nfs_renamedata *data = task->tk_calldata;
3448 struct nfs_renameres *res = &data->res;
3319 3449
3320 if (!nfs4_sequence_done(task, &res->seq_res)) 3450 if (!nfs4_sequence_done(task, &res->seq_res))
3321 return 0; 3451 return 0;
@@ -3361,9 +3491,10 @@ static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
3361 struct nfs4_exception exception = { }; 3491 struct nfs4_exception exception = { };
3362 int err; 3492 int err;
3363 do { 3493 do {
3364 err = nfs4_handle_exception(NFS_SERVER(old_dir), 3494 err = _nfs4_proc_rename(old_dir, old_name,
3365 _nfs4_proc_rename(old_dir, old_name, 3495 new_dir, new_name);
3366 new_dir, new_name), 3496 trace_nfs4_rename(old_dir, old_name, new_dir, new_name, err);
3497 err = nfs4_handle_exception(NFS_SERVER(old_dir), err,
3367 &exception); 3498 &exception);
3368 } while (exception.retry); 3499 } while (exception.retry);
3369 return err; 3500 return err;
@@ -3525,9 +3656,9 @@ static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
3525 label = nfs4_label_init_security(dir, dentry, sattr, &l); 3656 label = nfs4_label_init_security(dir, dentry, sattr, &l);
3526 3657
3527 do { 3658 do {
3528 err = nfs4_handle_exception(NFS_SERVER(dir), 3659 err = _nfs4_proc_symlink(dir, dentry, page, len, sattr, label);
3529 _nfs4_proc_symlink(dir, dentry, page, 3660 trace_nfs4_symlink(dir, &dentry->d_name, err);
3530 len, sattr, label), 3661 err = nfs4_handle_exception(NFS_SERVER(dir), err,
3531 &exception); 3662 &exception);
3532 } while (exception.retry); 3663 } while (exception.retry);
3533 3664
@@ -3564,8 +3695,9 @@ static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
3564 3695
3565 sattr->ia_mode &= ~current_umask(); 3696 sattr->ia_mode &= ~current_umask();
3566 do { 3697 do {
3567 err = nfs4_handle_exception(NFS_SERVER(dir), 3698 err = _nfs4_proc_mkdir(dir, dentry, sattr, label);
3568 _nfs4_proc_mkdir(dir, dentry, sattr, label), 3699 trace_nfs4_mkdir(dir, &dentry->d_name, err);
3700 err = nfs4_handle_exception(NFS_SERVER(dir), err,
3569 &exception); 3701 &exception);
3570 } while (exception.retry); 3702 } while (exception.retry);
3571 nfs4_label_release_security(label); 3703 nfs4_label_release_security(label);
@@ -3618,9 +3750,10 @@ static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
3618 struct nfs4_exception exception = { }; 3750 struct nfs4_exception exception = { };
3619 int err; 3751 int err;
3620 do { 3752 do {
3621 err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode), 3753 err = _nfs4_proc_readdir(dentry, cred, cookie,
3622 _nfs4_proc_readdir(dentry, cred, cookie, 3754 pages, count, plus);
3623 pages, count, plus), 3755 trace_nfs4_readdir(dentry->d_inode, err);
3756 err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode), err,
3624 &exception); 3757 &exception);
3625 } while (exception.retry); 3758 } while (exception.retry);
3626 return err; 3759 return err;
@@ -3672,8 +3805,9 @@ static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
3672 3805
3673 sattr->ia_mode &= ~current_umask(); 3806 sattr->ia_mode &= ~current_umask();
3674 do { 3807 do {
3675 err = nfs4_handle_exception(NFS_SERVER(dir), 3808 err = _nfs4_proc_mknod(dir, dentry, sattr, label, rdev);
3676 _nfs4_proc_mknod(dir, dentry, sattr, label, rdev), 3809 trace_nfs4_mknod(dir, &dentry->d_name, err);
3810 err = nfs4_handle_exception(NFS_SERVER(dir), err,
3677 &exception); 3811 &exception);
3678 } while (exception.retry); 3812 } while (exception.retry);
3679 3813
@@ -3741,6 +3875,7 @@ static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, str
3741 3875
3742 do { 3876 do {
3743 err = _nfs4_do_fsinfo(server, fhandle, fsinfo); 3877 err = _nfs4_do_fsinfo(server, fhandle, fsinfo);
3878 trace_nfs4_fsinfo(server, fhandle, fsinfo->fattr, err);
3744 if (err == 0) { 3879 if (err == 0) {
3745 struct nfs_client *clp = server->nfs_client; 3880 struct nfs_client *clp = server->nfs_client;
3746 3881
@@ -3859,6 +3994,7 @@ static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_read_data *data)
3859{ 3994{
3860 struct nfs_server *server = NFS_SERVER(data->header->inode); 3995 struct nfs_server *server = NFS_SERVER(data->header->inode);
3861 3996
3997 trace_nfs4_read(data, task->tk_status);
3862 if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) { 3998 if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) {
3863 rpc_restart_call_prepare(task); 3999 rpc_restart_call_prepare(task);
3864 return -EAGAIN; 4000 return -EAGAIN;
@@ -3902,24 +4038,29 @@ static void nfs4_proc_read_setup(struct nfs_read_data *data, struct rpc_message
3902 data->timestamp = jiffies; 4038 data->timestamp = jiffies;
3903 data->read_done_cb = nfs4_read_done_cb; 4039 data->read_done_cb = nfs4_read_done_cb;
3904 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ]; 4040 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ];
3905 nfs41_init_sequence(&data->args.seq_args, &data->res.seq_res, 0); 4041 nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 0);
3906} 4042}
3907 4043
3908static void nfs4_proc_read_rpc_prepare(struct rpc_task *task, struct nfs_read_data *data) 4044static int nfs4_proc_read_rpc_prepare(struct rpc_task *task, struct nfs_read_data *data)
3909{ 4045{
3910 if (nfs4_setup_sequence(NFS_SERVER(data->header->inode), 4046 if (nfs4_setup_sequence(NFS_SERVER(data->header->inode),
3911 &data->args.seq_args, 4047 &data->args.seq_args,
3912 &data->res.seq_res, 4048 &data->res.seq_res,
3913 task)) 4049 task))
3914 return; 4050 return 0;
3915 nfs4_set_rw_stateid(&data->args.stateid, data->args.context, 4051 if (nfs4_set_rw_stateid(&data->args.stateid, data->args.context,
3916 data->args.lock_context, FMODE_READ); 4052 data->args.lock_context, FMODE_READ) == -EIO)
4053 return -EIO;
4054 if (unlikely(test_bit(NFS_CONTEXT_BAD, &data->args.context->flags)))
4055 return -EIO;
4056 return 0;
3917} 4057}
3918 4058
3919static int nfs4_write_done_cb(struct rpc_task *task, struct nfs_write_data *data) 4059static int nfs4_write_done_cb(struct rpc_task *task, struct nfs_write_data *data)
3920{ 4060{
3921 struct inode *inode = data->header->inode; 4061 struct inode *inode = data->header->inode;
3922 4062
4063 trace_nfs4_write(data, task->tk_status);
3923 if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) { 4064 if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) {
3924 rpc_restart_call_prepare(task); 4065 rpc_restart_call_prepare(task);
3925 return -EAGAIN; 4066 return -EAGAIN;
@@ -3985,18 +4126,22 @@ static void nfs4_proc_write_setup(struct nfs_write_data *data, struct rpc_messag
3985 data->timestamp = jiffies; 4126 data->timestamp = jiffies;
3986 4127
3987 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE]; 4128 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE];
3988 nfs41_init_sequence(&data->args.seq_args, &data->res.seq_res, 1); 4129 nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1);
3989} 4130}
3990 4131
3991static void nfs4_proc_write_rpc_prepare(struct rpc_task *task, struct nfs_write_data *data) 4132static int nfs4_proc_write_rpc_prepare(struct rpc_task *task, struct nfs_write_data *data)
3992{ 4133{
3993 if (nfs4_setup_sequence(NFS_SERVER(data->header->inode), 4134 if (nfs4_setup_sequence(NFS_SERVER(data->header->inode),
3994 &data->args.seq_args, 4135 &data->args.seq_args,
3995 &data->res.seq_res, 4136 &data->res.seq_res,
3996 task)) 4137 task))
3997 return; 4138 return 0;
3998 nfs4_set_rw_stateid(&data->args.stateid, data->args.context, 4139 if (nfs4_set_rw_stateid(&data->args.stateid, data->args.context,
3999 data->args.lock_context, FMODE_WRITE); 4140 data->args.lock_context, FMODE_WRITE) == -EIO)
4141 return -EIO;
4142 if (unlikely(test_bit(NFS_CONTEXT_BAD, &data->args.context->flags)))
4143 return -EIO;
4144 return 0;
4000} 4145}
4001 4146
4002static void nfs4_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data) 4147static void nfs4_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data)
@@ -4011,6 +4156,7 @@ static int nfs4_commit_done_cb(struct rpc_task *task, struct nfs_commit_data *da
4011{ 4156{
4012 struct inode *inode = data->inode; 4157 struct inode *inode = data->inode;
4013 4158
4159 trace_nfs4_commit(data, task->tk_status);
4014 if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) { 4160 if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) {
4015 rpc_restart_call_prepare(task); 4161 rpc_restart_call_prepare(task);
4016 return -EAGAIN; 4162 return -EAGAIN;
@@ -4033,7 +4179,7 @@ static void nfs4_proc_commit_setup(struct nfs_commit_data *data, struct rpc_mess
4033 data->commit_done_cb = nfs4_commit_done_cb; 4179 data->commit_done_cb = nfs4_commit_done_cb;
4034 data->res.server = server; 4180 data->res.server = server;
4035 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT]; 4181 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT];
4036 nfs41_init_sequence(&data->args.seq_args, &data->res.seq_res, 1); 4182 nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1);
4037} 4183}
4038 4184
4039struct nfs4_renewdata { 4185struct nfs4_renewdata {
@@ -4062,6 +4208,7 @@ static void nfs4_renew_done(struct rpc_task *task, void *calldata)
4062 struct nfs_client *clp = data->client; 4208 struct nfs_client *clp = data->client;
4063 unsigned long timestamp = data->timestamp; 4209 unsigned long timestamp = data->timestamp;
4064 4210
4211 trace_nfs4_renew_async(clp, task->tk_status);
4065 if (task->tk_status < 0) { 4212 if (task->tk_status < 0) {
4066 /* Unless we're shutting down, schedule state recovery! */ 4213 /* Unless we're shutting down, schedule state recovery! */
4067 if (test_bit(NFS_CS_RENEWD, &clp->cl_res_state) == 0) 4214 if (test_bit(NFS_CS_RENEWD, &clp->cl_res_state) == 0)
@@ -4319,6 +4466,7 @@ static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bufl
4319 ssize_t ret; 4466 ssize_t ret;
4320 do { 4467 do {
4321 ret = __nfs4_get_acl_uncached(inode, buf, buflen); 4468 ret = __nfs4_get_acl_uncached(inode, buf, buflen);
4469 trace_nfs4_get_acl(inode, ret);
4322 if (ret >= 0) 4470 if (ret >= 0)
4323 break; 4471 break;
4324 ret = nfs4_handle_exception(NFS_SERVER(inode), ret, &exception); 4472 ret = nfs4_handle_exception(NFS_SERVER(inode), ret, &exception);
@@ -4398,8 +4546,9 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen
4398 struct nfs4_exception exception = { }; 4546 struct nfs4_exception exception = { };
4399 int err; 4547 int err;
4400 do { 4548 do {
4401 err = nfs4_handle_exception(NFS_SERVER(inode), 4549 err = __nfs4_proc_set_acl(inode, buf, buflen);
4402 __nfs4_proc_set_acl(inode, buf, buflen), 4550 trace_nfs4_set_acl(inode, err);
4551 err = nfs4_handle_exception(NFS_SERVER(inode), err,
4403 &exception); 4552 &exception);
4404 } while (exception.retry); 4553 } while (exception.retry);
4405 return err; 4554 return err;
@@ -4452,8 +4601,9 @@ static int nfs4_get_security_label(struct inode *inode, void *buf,
4452 return -EOPNOTSUPP; 4601 return -EOPNOTSUPP;
4453 4602
4454 do { 4603 do {
4455 err = nfs4_handle_exception(NFS_SERVER(inode), 4604 err = _nfs4_get_security_label(inode, buf, buflen);
4456 _nfs4_get_security_label(inode, buf, buflen), 4605 trace_nfs4_get_security_label(inode, err);
4606 err = nfs4_handle_exception(NFS_SERVER(inode), err,
4457 &exception); 4607 &exception);
4458 } while (exception.retry); 4608 } while (exception.retry);
4459 return err; 4609 return err;
@@ -4505,9 +4655,10 @@ static int nfs4_do_set_security_label(struct inode *inode,
4505 int err; 4655 int err;
4506 4656
4507 do { 4657 do {
4508 err = nfs4_handle_exception(NFS_SERVER(inode), 4658 err = _nfs4_do_set_security_label(inode, ilabel,
4509 _nfs4_do_set_security_label(inode, ilabel, 4659 fattr, olabel);
4510 fattr, olabel), 4660 trace_nfs4_set_security_label(inode, err);
4661 err = nfs4_handle_exception(NFS_SERVER(inode), err,
4511 &exception); 4662 &exception);
4512 } while (exception.retry); 4663 } while (exception.retry);
4513 return err; 4664 return err;
@@ -4630,11 +4781,11 @@ static void nfs4_init_boot_verifier(const struct nfs_client *clp,
4630 /* An impossible timestamp guarantees this value 4781 /* An impossible timestamp guarantees this value
4631 * will never match a generated boot time. */ 4782 * will never match a generated boot time. */
4632 verf[0] = 0; 4783 verf[0] = 0;
4633 verf[1] = (__be32)(NSEC_PER_SEC + 1); 4784 verf[1] = cpu_to_be32(NSEC_PER_SEC + 1);
4634 } else { 4785 } else {
4635 struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id); 4786 struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id);
4636 verf[0] = (__be32)nn->boot_time.tv_sec; 4787 verf[0] = cpu_to_be32(nn->boot_time.tv_sec);
4637 verf[1] = (__be32)nn->boot_time.tv_nsec; 4788 verf[1] = cpu_to_be32(nn->boot_time.tv_nsec);
4638 } 4789 }
4639 memcpy(bootverf->data, verf, sizeof(bootverf->data)); 4790 memcpy(bootverf->data, verf, sizeof(bootverf->data));
4640} 4791}
@@ -4660,10 +4811,14 @@ static unsigned int
4660nfs4_init_uniform_client_string(const struct nfs_client *clp, 4811nfs4_init_uniform_client_string(const struct nfs_client *clp,
4661 char *buf, size_t len) 4812 char *buf, size_t len)
4662{ 4813{
4663 char *nodename = clp->cl_rpcclient->cl_nodename; 4814 const char *nodename = clp->cl_rpcclient->cl_nodename;
4664 4815
4665 if (nfs4_client_id_uniquifier[0] != '\0') 4816 if (nfs4_client_id_uniquifier[0] != '\0')
4666 nodename = nfs4_client_id_uniquifier; 4817 return scnprintf(buf, len, "Linux NFSv%u.%u %s/%s",
4818 clp->rpc_ops->version,
4819 clp->cl_minorversion,
4820 nfs4_client_id_uniquifier,
4821 nodename);
4667 return scnprintf(buf, len, "Linux NFSv%u.%u %s", 4822 return scnprintf(buf, len, "Linux NFSv%u.%u %s",
4668 clp->rpc_ops->version, clp->cl_minorversion, 4823 clp->rpc_ops->version, clp->cl_minorversion,
4669 nodename); 4824 nodename);
@@ -4724,6 +4879,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
4724 clp->cl_rpcclient->cl_auth->au_ops->au_name, 4879 clp->cl_rpcclient->cl_auth->au_ops->au_name,
4725 setclientid.sc_name_len, setclientid.sc_name); 4880 setclientid.sc_name_len, setclientid.sc_name);
4726 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 4881 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
4882 trace_nfs4_setclientid(clp, status);
4727 dprintk("NFS reply setclientid: %d\n", status); 4883 dprintk("NFS reply setclientid: %d\n", status);
4728 return status; 4884 return status;
4729} 4885}
@@ -4751,6 +4907,7 @@ int nfs4_proc_setclientid_confirm(struct nfs_client *clp,
4751 clp->cl_rpcclient->cl_auth->au_ops->au_name, 4907 clp->cl_rpcclient->cl_auth->au_ops->au_name,
4752 clp->cl_clientid); 4908 clp->cl_clientid);
4753 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 4909 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
4910 trace_nfs4_setclientid_confirm(clp, status);
4754 dprintk("NFS reply setclientid_confirm: %d\n", status); 4911 dprintk("NFS reply setclientid_confirm: %d\n", status);
4755 return status; 4912 return status;
4756} 4913}
@@ -4772,6 +4929,7 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
4772 if (!nfs4_sequence_done(task, &data->res.seq_res)) 4929 if (!nfs4_sequence_done(task, &data->res.seq_res))
4773 return; 4930 return;
4774 4931
4932 trace_nfs4_delegreturn_exit(&data->args, &data->res, task->tk_status);
4775 switch (task->tk_status) { 4933 switch (task->tk_status) {
4776 case -NFS4ERR_STALE_STATEID: 4934 case -NFS4ERR_STALE_STATEID:
4777 case -NFS4ERR_EXPIRED: 4935 case -NFS4ERR_EXPIRED:
@@ -4793,7 +4951,6 @@ static void nfs4_delegreturn_release(void *calldata)
4793 kfree(calldata); 4951 kfree(calldata);
4794} 4952}
4795 4953
4796#if defined(CONFIG_NFS_V4_1)
4797static void nfs4_delegreturn_prepare(struct rpc_task *task, void *data) 4954static void nfs4_delegreturn_prepare(struct rpc_task *task, void *data)
4798{ 4955{
4799 struct nfs4_delegreturndata *d_data; 4956 struct nfs4_delegreturndata *d_data;
@@ -4805,12 +4962,9 @@ static void nfs4_delegreturn_prepare(struct rpc_task *task, void *data)
4805 &d_data->res.seq_res, 4962 &d_data->res.seq_res,
4806 task); 4963 task);
4807} 4964}
4808#endif /* CONFIG_NFS_V4_1 */
4809 4965
4810static const struct rpc_call_ops nfs4_delegreturn_ops = { 4966static const struct rpc_call_ops nfs4_delegreturn_ops = {
4811#if defined(CONFIG_NFS_V4_1)
4812 .rpc_call_prepare = nfs4_delegreturn_prepare, 4967 .rpc_call_prepare = nfs4_delegreturn_prepare,
4813#endif /* CONFIG_NFS_V4_1 */
4814 .rpc_call_done = nfs4_delegreturn_done, 4968 .rpc_call_done = nfs4_delegreturn_done,
4815 .rpc_release = nfs4_delegreturn_release, 4969 .rpc_release = nfs4_delegreturn_release,
4816}; 4970};
@@ -4835,7 +4989,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
4835 data = kzalloc(sizeof(*data), GFP_NOFS); 4989 data = kzalloc(sizeof(*data), GFP_NOFS);
4836 if (data == NULL) 4990 if (data == NULL)
4837 return -ENOMEM; 4991 return -ENOMEM;
4838 nfs41_init_sequence(&data->args.seq_args, &data->res.seq_res, 1); 4992 nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1);
4839 data->args.fhandle = &data->fh; 4993 data->args.fhandle = &data->fh;
4840 data->args.stateid = &data->stateid; 4994 data->args.stateid = &data->stateid;
4841 data->args.bitmask = server->cache_consistency_bitmask; 4995 data->args.bitmask = server->cache_consistency_bitmask;
@@ -4875,6 +5029,7 @@ int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4
4875 int err; 5029 int err;
4876 do { 5030 do {
4877 err = _nfs4_proc_delegreturn(inode, cred, stateid, issync); 5031 err = _nfs4_proc_delegreturn(inode, cred, stateid, issync);
5032 trace_nfs4_delegreturn(inode, err);
4878 switch (err) { 5033 switch (err) {
4879 case -NFS4ERR_STALE_STATEID: 5034 case -NFS4ERR_STALE_STATEID:
4880 case -NFS4ERR_EXPIRED: 5035 case -NFS4ERR_EXPIRED:
@@ -4949,8 +5104,9 @@ static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *
4949 int err; 5104 int err;
4950 5105
4951 do { 5106 do {
4952 err = nfs4_handle_exception(NFS_SERVER(state->inode), 5107 err = _nfs4_proc_getlk(state, cmd, request);
4953 _nfs4_proc_getlk(state, cmd, request), 5108 trace_nfs4_get_lock(request, state, cmd, err);
5109 err = nfs4_handle_exception(NFS_SERVER(state->inode), err,
4954 &exception); 5110 &exception);
4955 } while (exception.retry); 5111 } while (exception.retry);
4956 return err; 5112 return err;
@@ -5087,6 +5243,9 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl,
5087 .flags = RPC_TASK_ASYNC, 5243 .flags = RPC_TASK_ASYNC,
5088 }; 5244 };
5089 5245
5246 nfs4_state_protect(NFS_SERVER(lsp->ls_state->inode)->nfs_client,
5247 NFS_SP4_MACH_CRED_CLEANUP, &task_setup_data.rpc_client, &msg);
5248
5090 /* Ensure this is an unlock - when canceling a lock, the 5249 /* Ensure this is an unlock - when canceling a lock, the
5091 * canceled lock is passed in, and it won't be an unlock. 5250 * canceled lock is passed in, and it won't be an unlock.
5092 */ 5251 */
@@ -5098,7 +5257,7 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl,
5098 return ERR_PTR(-ENOMEM); 5257 return ERR_PTR(-ENOMEM);
5099 } 5258 }
5100 5259
5101 nfs41_init_sequence(&data->arg.seq_args, &data->res.seq_res, 1); 5260 nfs4_init_sequence(&data->arg.seq_args, &data->res.seq_res, 1);
5102 msg.rpc_argp = &data->arg; 5261 msg.rpc_argp = &data->arg;
5103 msg.rpc_resp = &data->res; 5262 msg.rpc_resp = &data->res;
5104 task_setup_data.callback_data = data; 5263 task_setup_data.callback_data = data;
@@ -5148,6 +5307,7 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *
5148 rpc_put_task(task); 5307 rpc_put_task(task);
5149out: 5308out:
5150 request->fl_flags = fl_flags; 5309 request->fl_flags = fl_flags;
5310 trace_nfs4_unlock(request, state, F_SETLK, status);
5151 return status; 5311 return status;
5152} 5312}
5153 5313
@@ -5333,7 +5493,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
5333 return -ENOMEM; 5493 return -ENOMEM;
5334 if (IS_SETLKW(cmd)) 5494 if (IS_SETLKW(cmd))
5335 data->arg.block = 1; 5495 data->arg.block = 1;
5336 nfs41_init_sequence(&data->arg.seq_args, &data->res.seq_res, 1); 5496 nfs4_init_sequence(&data->arg.seq_args, &data->res.seq_res, 1);
5337 msg.rpc_argp = &data->arg; 5497 msg.rpc_argp = &data->arg;
5338 msg.rpc_resp = &data->res; 5498 msg.rpc_resp = &data->res;
5339 task_setup_data.callback_data = data; 5499 task_setup_data.callback_data = data;
@@ -5371,6 +5531,7 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request
5371 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) 5531 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
5372 return 0; 5532 return 0;
5373 err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_RECLAIM); 5533 err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_RECLAIM);
5534 trace_nfs4_lock_reclaim(request, state, F_SETLK, err);
5374 if (err != -NFS4ERR_DELAY) 5535 if (err != -NFS4ERR_DELAY)
5375 break; 5536 break;
5376 nfs4_handle_exception(server, err, &exception); 5537 nfs4_handle_exception(server, err, &exception);
@@ -5389,10 +5550,15 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
5389 err = nfs4_set_lock_state(state, request); 5550 err = nfs4_set_lock_state(state, request);
5390 if (err != 0) 5551 if (err != 0)
5391 return err; 5552 return err;
5553 if (!recover_lost_locks) {
5554 set_bit(NFS_LOCK_LOST, &request->fl_u.nfs4_fl.owner->ls_flags);
5555 return 0;
5556 }
5392 do { 5557 do {
5393 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) 5558 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
5394 return 0; 5559 return 0;
5395 err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_EXPIRED); 5560 err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_EXPIRED);
5561 trace_nfs4_lock_expired(request, state, F_SETLK, err);
5396 switch (err) { 5562 switch (err) {
5397 default: 5563 default:
5398 goto out; 5564 goto out;
@@ -5428,6 +5594,7 @@ static int nfs41_check_expired_locks(struct nfs4_state *state)
5428 status = nfs41_test_stateid(server, 5594 status = nfs41_test_stateid(server,
5429 &lsp->ls_stateid, 5595 &lsp->ls_stateid,
5430 cred); 5596 cred);
5597 trace_nfs4_test_lock_stateid(state, lsp, status);
5431 if (status != NFS_OK) { 5598 if (status != NFS_OK) {
5432 /* Free the stateid unless the server 5599 /* Free the stateid unless the server
5433 * informs us the stateid is unrecognized. */ 5600 * informs us the stateid is unrecognized. */
@@ -5515,6 +5682,7 @@ static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *
5515 5682
5516 do { 5683 do {
5517 err = _nfs4_proc_setlk(state, cmd, request); 5684 err = _nfs4_proc_setlk(state, cmd, request);
5685 trace_nfs4_set_lock(request, state, cmd, err);
5518 if (err == -NFS4ERR_DENIED) 5686 if (err == -NFS4ERR_DENIED)
5519 err = -EAGAIN; 5687 err = -EAGAIN;
5520 err = nfs4_handle_exception(NFS_SERVER(state->inode), 5688 err = nfs4_handle_exception(NFS_SERVER(state->inode),
@@ -5597,8 +5765,23 @@ struct nfs_release_lockowner_data {
5597 struct nfs4_lock_state *lsp; 5765 struct nfs4_lock_state *lsp;
5598 struct nfs_server *server; 5766 struct nfs_server *server;
5599 struct nfs_release_lockowner_args args; 5767 struct nfs_release_lockowner_args args;
5768 struct nfs4_sequence_args seq_args;
5769 struct nfs4_sequence_res seq_res;
5600}; 5770};
5601 5771
5772static void nfs4_release_lockowner_prepare(struct rpc_task *task, void *calldata)
5773{
5774 struct nfs_release_lockowner_data *data = calldata;
5775 nfs40_setup_sequence(data->server,
5776 &data->seq_args, &data->seq_res, task);
5777}
5778
5779static void nfs4_release_lockowner_done(struct rpc_task *task, void *calldata)
5780{
5781 struct nfs_release_lockowner_data *data = calldata;
5782 nfs40_sequence_done(task, &data->seq_res);
5783}
5784
5602static void nfs4_release_lockowner_release(void *calldata) 5785static void nfs4_release_lockowner_release(void *calldata)
5603{ 5786{
5604 struct nfs_release_lockowner_data *data = calldata; 5787 struct nfs_release_lockowner_data *data = calldata;
@@ -5607,6 +5790,8 @@ static void nfs4_release_lockowner_release(void *calldata)
5607} 5790}
5608 5791
5609static const struct rpc_call_ops nfs4_release_lockowner_ops = { 5792static const struct rpc_call_ops nfs4_release_lockowner_ops = {
5793 .rpc_call_prepare = nfs4_release_lockowner_prepare,
5794 .rpc_call_done = nfs4_release_lockowner_done,
5610 .rpc_release = nfs4_release_lockowner_release, 5795 .rpc_release = nfs4_release_lockowner_release,
5611}; 5796};
5612 5797
@@ -5619,14 +5804,17 @@ static int nfs4_release_lockowner(struct nfs_server *server, struct nfs4_lock_st
5619 5804
5620 if (server->nfs_client->cl_mvops->minor_version != 0) 5805 if (server->nfs_client->cl_mvops->minor_version != 0)
5621 return -EINVAL; 5806 return -EINVAL;
5807
5622 data = kmalloc(sizeof(*data), GFP_NOFS); 5808 data = kmalloc(sizeof(*data), GFP_NOFS);
5623 if (!data) 5809 if (!data)
5624 return -ENOMEM; 5810 return -ENOMEM;
5811 nfs4_init_sequence(&data->seq_args, &data->seq_res, 0);
5625 data->lsp = lsp; 5812 data->lsp = lsp;
5626 data->server = server; 5813 data->server = server;
5627 data->args.lock_owner.clientid = server->nfs_client->cl_clientid; 5814 data->args.lock_owner.clientid = server->nfs_client->cl_clientid;
5628 data->args.lock_owner.id = lsp->ls_seqid.owner_id; 5815 data->args.lock_owner.id = lsp->ls_seqid.owner_id;
5629 data->args.lock_owner.s_dev = server->s_dev; 5816 data->args.lock_owner.s_dev = server->s_dev;
5817
5630 msg.rpc_argp = &data->args; 5818 msg.rpc_argp = &data->args;
5631 rpc_call_async(server->client, &msg, 0, &nfs4_release_lockowner_ops, data); 5819 rpc_call_async(server->client, &msg, 0, &nfs4_release_lockowner_ops, data);
5632 return 0; 5820 return 0;
@@ -5781,14 +5969,23 @@ int nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir,
5781 struct nfs4_exception exception = { }; 5969 struct nfs4_exception exception = { };
5782 int err; 5970 int err;
5783 do { 5971 do {
5784 err = nfs4_handle_exception(NFS_SERVER(dir), 5972 err = _nfs4_proc_fs_locations(client, dir, name,
5785 _nfs4_proc_fs_locations(client, dir, name, fs_locations, page), 5973 fs_locations, page);
5974 trace_nfs4_get_fs_locations(dir, name, err);
5975 err = nfs4_handle_exception(NFS_SERVER(dir), err,
5786 &exception); 5976 &exception);
5787 } while (exception.retry); 5977 } while (exception.retry);
5788 return err; 5978 return err;
5789} 5979}
5790 5980
5791static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct nfs4_secinfo_flavors *flavors) 5981/**
5982 * If 'use_integrity' is true and the state managment nfs_client
5983 * cl_rpcclient is using krb5i/p, use the integrity protected cl_rpcclient
5984 * and the machine credential as per RFC3530bis and RFC5661 Security
5985 * Considerations sections. Otherwise, just use the user cred with the
5986 * filesystem's rpc_client.
5987 */
5988static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct nfs4_secinfo_flavors *flavors, bool use_integrity)
5792{ 5989{
5793 int status; 5990 int status;
5794 struct nfs4_secinfo_arg args = { 5991 struct nfs4_secinfo_arg args = {
@@ -5803,10 +6000,25 @@ static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct
5803 .rpc_argp = &args, 6000 .rpc_argp = &args,
5804 .rpc_resp = &res, 6001 .rpc_resp = &res,
5805 }; 6002 };
6003 struct rpc_clnt *clnt = NFS_SERVER(dir)->client;
6004
6005 if (use_integrity) {
6006 clnt = NFS_SERVER(dir)->nfs_client->cl_rpcclient;
6007 msg.rpc_cred = nfs4_get_clid_cred(NFS_SERVER(dir)->nfs_client);
6008 }
5806 6009
5807 dprintk("NFS call secinfo %s\n", name->name); 6010 dprintk("NFS call secinfo %s\n", name->name);
5808 status = nfs4_call_sync(NFS_SERVER(dir)->client, NFS_SERVER(dir), &msg, &args.seq_args, &res.seq_res, 0); 6011
6012 nfs4_state_protect(NFS_SERVER(dir)->nfs_client,
6013 NFS_SP4_MACH_CRED_SECINFO, &clnt, &msg);
6014
6015 status = nfs4_call_sync(clnt, NFS_SERVER(dir), &msg, &args.seq_args,
6016 &res.seq_res, 0);
5809 dprintk("NFS reply secinfo: %d\n", status); 6017 dprintk("NFS reply secinfo: %d\n", status);
6018
6019 if (msg.rpc_cred)
6020 put_rpccred(msg.rpc_cred);
6021
5810 return status; 6022 return status;
5811} 6023}
5812 6024
@@ -5816,8 +6028,23 @@ int nfs4_proc_secinfo(struct inode *dir, const struct qstr *name,
5816 struct nfs4_exception exception = { }; 6028 struct nfs4_exception exception = { };
5817 int err; 6029 int err;
5818 do { 6030 do {
5819 err = nfs4_handle_exception(NFS_SERVER(dir), 6031 err = -NFS4ERR_WRONGSEC;
5820 _nfs4_proc_secinfo(dir, name, flavors), 6032
6033 /* try to use integrity protection with machine cred */
6034 if (_nfs4_is_integrity_protected(NFS_SERVER(dir)->nfs_client))
6035 err = _nfs4_proc_secinfo(dir, name, flavors, true);
6036
6037 /*
6038 * if unable to use integrity protection, or SECINFO with
6039 * integrity protection returns NFS4ERR_WRONGSEC (which is
6040 * disallowed by spec, but exists in deployed servers) use
6041 * the current filesystem's rpc_client and the user cred.
6042 */
6043 if (err == -NFS4ERR_WRONGSEC)
6044 err = _nfs4_proc_secinfo(dir, name, flavors, false);
6045
6046 trace_nfs4_secinfo(dir, name, err);
6047 err = nfs4_handle_exception(NFS_SERVER(dir), err,
5821 &exception); 6048 &exception);
5822 } while (exception.retry); 6049 } while (exception.retry);
5823 return err; 6050 return err;
@@ -5881,6 +6108,7 @@ int nfs4_proc_bind_conn_to_session(struct nfs_client *clp, struct rpc_cred *cred
5881 } 6108 }
5882 6109
5883 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 6110 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
6111 trace_nfs4_bind_conn_to_session(clp, status);
5884 if (status == 0) { 6112 if (status == 0) {
5885 if (memcmp(res.session->sess_id.data, 6113 if (memcmp(res.session->sess_id.data,
5886 clp->cl_session->sess_id.data, NFS4_MAX_SESSIONID_LEN)) { 6114 clp->cl_session->sess_id.data, NFS4_MAX_SESSIONID_LEN)) {
@@ -5909,16 +6137,124 @@ out:
5909} 6137}
5910 6138
5911/* 6139/*
5912 * nfs4_proc_exchange_id() 6140 * Minimum set of SP4_MACH_CRED operations from RFC 5661 in the enforce map
6141 * and operations we'd like to see to enable certain features in the allow map
6142 */
6143static const struct nfs41_state_protection nfs4_sp4_mach_cred_request = {
6144 .how = SP4_MACH_CRED,
6145 .enforce.u.words = {
6146 [1] = 1 << (OP_BIND_CONN_TO_SESSION - 32) |
6147 1 << (OP_EXCHANGE_ID - 32) |
6148 1 << (OP_CREATE_SESSION - 32) |
6149 1 << (OP_DESTROY_SESSION - 32) |
6150 1 << (OP_DESTROY_CLIENTID - 32)
6151 },
6152 .allow.u.words = {
6153 [0] = 1 << (OP_CLOSE) |
6154 1 << (OP_LOCKU),
6155 [1] = 1 << (OP_SECINFO - 32) |
6156 1 << (OP_SECINFO_NO_NAME - 32) |
6157 1 << (OP_TEST_STATEID - 32) |
6158 1 << (OP_FREE_STATEID - 32)
6159 }
6160};
6161
6162/*
6163 * Select the state protection mode for client `clp' given the server results
6164 * from exchange_id in `sp'.
5913 * 6165 *
5914 * Returns zero, a negative errno, or a negative NFS4ERR status code. 6166 * Returns 0 on success, negative errno otherwise.
6167 */
6168static int nfs4_sp4_select_mode(struct nfs_client *clp,
6169 struct nfs41_state_protection *sp)
6170{
6171 static const u32 supported_enforce[NFS4_OP_MAP_NUM_WORDS] = {
6172 [1] = 1 << (OP_BIND_CONN_TO_SESSION - 32) |
6173 1 << (OP_EXCHANGE_ID - 32) |
6174 1 << (OP_CREATE_SESSION - 32) |
6175 1 << (OP_DESTROY_SESSION - 32) |
6176 1 << (OP_DESTROY_CLIENTID - 32)
6177 };
6178 unsigned int i;
6179
6180 if (sp->how == SP4_MACH_CRED) {
6181 /* Print state protect result */
6182 dfprintk(MOUNT, "Server SP4_MACH_CRED support:\n");
6183 for (i = 0; i <= LAST_NFS4_OP; i++) {
6184 if (test_bit(i, sp->enforce.u.longs))
6185 dfprintk(MOUNT, " enforce op %d\n", i);
6186 if (test_bit(i, sp->allow.u.longs))
6187 dfprintk(MOUNT, " allow op %d\n", i);
6188 }
6189
6190 /* make sure nothing is on enforce list that isn't supported */
6191 for (i = 0; i < NFS4_OP_MAP_NUM_WORDS; i++) {
6192 if (sp->enforce.u.words[i] & ~supported_enforce[i]) {
6193 dfprintk(MOUNT, "sp4_mach_cred: disabled\n");
6194 return -EINVAL;
6195 }
6196 }
6197
6198 /*
6199 * Minimal mode - state operations are allowed to use machine
6200 * credential. Note this already happens by default, so the
6201 * client doesn't have to do anything more than the negotiation.
6202 *
6203 * NOTE: we don't care if EXCHANGE_ID is in the list -
6204 * we're already using the machine cred for exchange_id
6205 * and will never use a different cred.
6206 */
6207 if (test_bit(OP_BIND_CONN_TO_SESSION, sp->enforce.u.longs) &&
6208 test_bit(OP_CREATE_SESSION, sp->enforce.u.longs) &&
6209 test_bit(OP_DESTROY_SESSION, sp->enforce.u.longs) &&
6210 test_bit(OP_DESTROY_CLIENTID, sp->enforce.u.longs)) {
6211 dfprintk(MOUNT, "sp4_mach_cred:\n");
6212 dfprintk(MOUNT, " minimal mode enabled\n");
6213 set_bit(NFS_SP4_MACH_CRED_MINIMAL, &clp->cl_sp4_flags);
6214 } else {
6215 dfprintk(MOUNT, "sp4_mach_cred: disabled\n");
6216 return -EINVAL;
6217 }
6218
6219 if (test_bit(OP_CLOSE, sp->allow.u.longs) &&
6220 test_bit(OP_LOCKU, sp->allow.u.longs)) {
6221 dfprintk(MOUNT, " cleanup mode enabled\n");
6222 set_bit(NFS_SP4_MACH_CRED_CLEANUP, &clp->cl_sp4_flags);
6223 }
6224
6225 if (test_bit(OP_SECINFO, sp->allow.u.longs) &&
6226 test_bit(OP_SECINFO_NO_NAME, sp->allow.u.longs)) {
6227 dfprintk(MOUNT, " secinfo mode enabled\n");
6228 set_bit(NFS_SP4_MACH_CRED_SECINFO, &clp->cl_sp4_flags);
6229 }
6230
6231 if (test_bit(OP_TEST_STATEID, sp->allow.u.longs) &&
6232 test_bit(OP_FREE_STATEID, sp->allow.u.longs)) {
6233 dfprintk(MOUNT, " stateid mode enabled\n");
6234 set_bit(NFS_SP4_MACH_CRED_STATEID, &clp->cl_sp4_flags);
6235 }
6236
6237 if (test_bit(OP_WRITE, sp->allow.u.longs)) {
6238 dfprintk(MOUNT, " write mode enabled\n");
6239 set_bit(NFS_SP4_MACH_CRED_WRITE, &clp->cl_sp4_flags);
6240 }
6241
6242 if (test_bit(OP_COMMIT, sp->allow.u.longs)) {
6243 dfprintk(MOUNT, " commit mode enabled\n");
6244 set_bit(NFS_SP4_MACH_CRED_COMMIT, &clp->cl_sp4_flags);
6245 }
6246 }
6247
6248 return 0;
6249}
6250
6251/*
6252 * _nfs4_proc_exchange_id()
5915 * 6253 *
5916 * Since the clientid has expired, all compounds using sessions 6254 * Wrapper for EXCHANGE_ID operation.
5917 * associated with the stale clientid will be returning
5918 * NFS4ERR_BADSESSION in the sequence operation, and will therefore
5919 * be in some phase of session reset.
5920 */ 6255 */
5921int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred) 6256static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
6257 u32 sp4_how)
5922{ 6258{
5923 nfs4_verifier verifier; 6259 nfs4_verifier verifier;
5924 struct nfs41_exchange_id_args args = { 6260 struct nfs41_exchange_id_args args = {
@@ -5965,10 +6301,30 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
5965 goto out_server_scope; 6301 goto out_server_scope;
5966 } 6302 }
5967 6303
6304 switch (sp4_how) {
6305 case SP4_NONE:
6306 args.state_protect.how = SP4_NONE;
6307 break;
6308
6309 case SP4_MACH_CRED:
6310 args.state_protect = nfs4_sp4_mach_cred_request;
6311 break;
6312
6313 default:
6314 /* unsupported! */
6315 WARN_ON_ONCE(1);
6316 status = -EINVAL;
6317 goto out_server_scope;
6318 }
6319
5968 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 6320 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
6321 trace_nfs4_exchange_id(clp, status);
5969 if (status == 0) 6322 if (status == 0)
5970 status = nfs4_check_cl_exchange_flags(res.flags); 6323 status = nfs4_check_cl_exchange_flags(res.flags);
5971 6324
6325 if (status == 0)
6326 status = nfs4_sp4_select_mode(clp, &res.state_protect);
6327
5972 if (status == 0) { 6328 if (status == 0) {
5973 clp->cl_clientid = res.clientid; 6329 clp->cl_clientid = res.clientid;
5974 clp->cl_exchange_flags = (res.flags & ~EXCHGID4_FLAG_CONFIRMED_R); 6330 clp->cl_exchange_flags = (res.flags & ~EXCHGID4_FLAG_CONFIRMED_R);
@@ -6015,6 +6371,35 @@ out:
6015 return status; 6371 return status;
6016} 6372}
6017 6373
6374/*
6375 * nfs4_proc_exchange_id()
6376 *
6377 * Returns zero, a negative errno, or a negative NFS4ERR status code.
6378 *
6379 * Since the clientid has expired, all compounds using sessions
6380 * associated with the stale clientid will be returning
6381 * NFS4ERR_BADSESSION in the sequence operation, and will therefore
6382 * be in some phase of session reset.
6383 *
6384 * Will attempt to negotiate SP4_MACH_CRED if krb5i / krb5p auth is used.
6385 */
6386int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
6387{
6388 rpc_authflavor_t authflavor = clp->cl_rpcclient->cl_auth->au_flavor;
6389 int status;
6390
6391 /* try SP4_MACH_CRED if krb5i/p */
6392 if (authflavor == RPC_AUTH_GSS_KRB5I ||
6393 authflavor == RPC_AUTH_GSS_KRB5P) {
6394 status = _nfs4_proc_exchange_id(clp, cred, SP4_MACH_CRED);
6395 if (!status)
6396 return 0;
6397 }
6398
6399 /* try SP4_NONE */
6400 return _nfs4_proc_exchange_id(clp, cred, SP4_NONE);
6401}
6402
6018static int _nfs4_proc_destroy_clientid(struct nfs_client *clp, 6403static int _nfs4_proc_destroy_clientid(struct nfs_client *clp,
6019 struct rpc_cred *cred) 6404 struct rpc_cred *cred)
6020{ 6405{
@@ -6026,6 +6411,7 @@ static int _nfs4_proc_destroy_clientid(struct nfs_client *clp,
6026 int status; 6411 int status;
6027 6412
6028 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 6413 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
6414 trace_nfs4_destroy_clientid(clp, status);
6029 if (status) 6415 if (status)
6030 dprintk("NFS: Got error %d from the server %s on " 6416 dprintk("NFS: Got error %d from the server %s on "
6031 "DESTROY_CLIENTID.", status, clp->cl_hostname); 6417 "DESTROY_CLIENTID.", status, clp->cl_hostname);
@@ -6063,7 +6449,7 @@ int nfs4_destroy_clientid(struct nfs_client *clp)
6063 goto out; 6449 goto out;
6064 if (clp->cl_preserve_clid) 6450 if (clp->cl_preserve_clid)
6065 goto out; 6451 goto out;
6066 cred = nfs4_get_exchange_id_cred(clp); 6452 cred = nfs4_get_clid_cred(clp);
6067 ret = nfs4_proc_destroy_clientid(clp, cred); 6453 ret = nfs4_proc_destroy_clientid(clp, cred);
6068 if (cred) 6454 if (cred)
6069 put_rpccred(cred); 6455 put_rpccred(cred);
@@ -6155,7 +6541,7 @@ int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
6155 }; 6541 };
6156 int status; 6542 int status;
6157 6543
6158 nfs41_init_sequence(&args.la_seq_args, &res.lr_seq_res, 0); 6544 nfs4_init_sequence(&args.la_seq_args, &res.lr_seq_res, 0);
6159 nfs4_set_sequence_privileged(&args.la_seq_args); 6545 nfs4_set_sequence_privileged(&args.la_seq_args);
6160 dprintk("--> %s\n", __func__); 6546 dprintk("--> %s\n", __func__);
6161 task = rpc_run_task(&task_setup); 6547 task = rpc_run_task(&task_setup);
@@ -6289,6 +6675,7 @@ static int _nfs4_proc_create_session(struct nfs_client *clp,
6289 args.flags = (SESSION4_PERSIST | SESSION4_BACK_CHAN); 6675 args.flags = (SESSION4_PERSIST | SESSION4_BACK_CHAN);
6290 6676
6291 status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 6677 status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
6678 trace_nfs4_create_session(clp, status);
6292 6679
6293 if (!status) { 6680 if (!status) {
6294 /* Verify the session's negotiated channel_attrs values */ 6681 /* Verify the session's negotiated channel_attrs values */
@@ -6352,6 +6739,7 @@ int nfs4_proc_destroy_session(struct nfs4_session *session,
6352 return status; 6739 return status;
6353 6740
6354 status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 6741 status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
6742 trace_nfs4_destroy_session(session->clp, status);
6355 6743
6356 if (status) 6744 if (status)
6357 dprintk("NFS: Got error %d from the server on DESTROY_SESSION. " 6745 dprintk("NFS: Got error %d from the server on DESTROY_SESSION. "
@@ -6401,6 +6789,7 @@ static void nfs41_sequence_call_done(struct rpc_task *task, void *data)
6401 if (!nfs41_sequence_done(task, task->tk_msg.rpc_resp)) 6789 if (!nfs41_sequence_done(task, task->tk_msg.rpc_resp))
6402 return; 6790 return;
6403 6791
6792 trace_nfs4_sequence(clp, task->tk_status);
6404 if (task->tk_status < 0) { 6793 if (task->tk_status < 0) {
6405 dprintk("%s ERROR %d\n", __func__, task->tk_status); 6794 dprintk("%s ERROR %d\n", __func__, task->tk_status);
6406 if (atomic_read(&clp->cl_count) == 1) 6795 if (atomic_read(&clp->cl_count) == 1)
@@ -6458,7 +6847,7 @@ static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp,
6458 nfs_put_client(clp); 6847 nfs_put_client(clp);
6459 return ERR_PTR(-ENOMEM); 6848 return ERR_PTR(-ENOMEM);
6460 } 6849 }
6461 nfs41_init_sequence(&calldata->args, &calldata->res, 0); 6850 nfs4_init_sequence(&calldata->args, &calldata->res, 0);
6462 if (is_privileged) 6851 if (is_privileged)
6463 nfs4_set_sequence_privileged(&calldata->args); 6852 nfs4_set_sequence_privileged(&calldata->args);
6464 msg.rpc_argp = &calldata->args; 6853 msg.rpc_argp = &calldata->args;
@@ -6553,6 +6942,7 @@ static void nfs4_reclaim_complete_done(struct rpc_task *task, void *data)
6553 if (!nfs41_sequence_done(task, res)) 6942 if (!nfs41_sequence_done(task, res))
6554 return; 6943 return;
6555 6944
6945 trace_nfs4_reclaim_complete(clp, task->tk_status);
6556 if (nfs41_reclaim_complete_handle_errors(task, clp) == -EAGAIN) { 6946 if (nfs41_reclaim_complete_handle_errors(task, clp) == -EAGAIN) {
6557 rpc_restart_call_prepare(task); 6947 rpc_restart_call_prepare(task);
6558 return; 6948 return;
@@ -6600,7 +6990,7 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp,
6600 calldata->clp = clp; 6990 calldata->clp = clp;
6601 calldata->arg.one_fs = 0; 6991 calldata->arg.one_fs = 0;
6602 6992
6603 nfs41_init_sequence(&calldata->arg.seq_args, &calldata->res.seq_res, 0); 6993 nfs4_init_sequence(&calldata->arg.seq_args, &calldata->res.seq_res, 0);
6604 nfs4_set_sequence_privileged(&calldata->arg.seq_args); 6994 nfs4_set_sequence_privileged(&calldata->arg.seq_args);
6605 msg.rpc_argp = &calldata->arg; 6995 msg.rpc_argp = &calldata->arg;
6606 msg.rpc_resp = &calldata->res; 6996 msg.rpc_resp = &calldata->res;
@@ -6791,7 +7181,7 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
6791 7181
6792 lgp->res.layoutp = &lgp->args.layout; 7182 lgp->res.layoutp = &lgp->args.layout;
6793 lgp->res.seq_res.sr_slot = NULL; 7183 lgp->res.seq_res.sr_slot = NULL;
6794 nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0); 7184 nfs4_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0);
6795 7185
6796 /* nfs4_layoutget_release calls pnfs_put_layout_hdr */ 7186 /* nfs4_layoutget_release calls pnfs_put_layout_hdr */
6797 pnfs_get_layout_hdr(NFS_I(inode)->layout); 7187 pnfs_get_layout_hdr(NFS_I(inode)->layout);
@@ -6802,6 +7192,10 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
6802 status = nfs4_wait_for_completion_rpc_task(task); 7192 status = nfs4_wait_for_completion_rpc_task(task);
6803 if (status == 0) 7193 if (status == 0)
6804 status = task->tk_status; 7194 status = task->tk_status;
7195 trace_nfs4_layoutget(lgp->args.ctx,
7196 &lgp->args.range,
7197 &lgp->res.range,
7198 status);
6805 /* if layoutp->len is 0, nfs4_layoutget_prepare called rpc_exit */ 7199 /* if layoutp->len is 0, nfs4_layoutget_prepare called rpc_exit */
6806 if (status == 0 && lgp->res.layoutp->len) 7200 if (status == 0 && lgp->res.layoutp->len)
6807 lseg = pnfs_layout_process(lgp); 7201 lseg = pnfs_layout_process(lgp);
@@ -6874,7 +7268,7 @@ int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp)
6874 .rpc_cred = lrp->cred, 7268 .rpc_cred = lrp->cred,
6875 }; 7269 };
6876 struct rpc_task_setup task_setup_data = { 7270 struct rpc_task_setup task_setup_data = {
6877 .rpc_client = lrp->clp->cl_rpcclient, 7271 .rpc_client = NFS_SERVER(lrp->args.inode)->client,
6878 .rpc_message = &msg, 7272 .rpc_message = &msg,
6879 .callback_ops = &nfs4_layoutreturn_call_ops, 7273 .callback_ops = &nfs4_layoutreturn_call_ops,
6880 .callback_data = lrp, 7274 .callback_data = lrp,
@@ -6882,11 +7276,12 @@ int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp)
6882 int status; 7276 int status;
6883 7277
6884 dprintk("--> %s\n", __func__); 7278 dprintk("--> %s\n", __func__);
6885 nfs41_init_sequence(&lrp->args.seq_args, &lrp->res.seq_res, 1); 7279 nfs4_init_sequence(&lrp->args.seq_args, &lrp->res.seq_res, 1);
6886 task = rpc_run_task(&task_setup_data); 7280 task = rpc_run_task(&task_setup_data);
6887 if (IS_ERR(task)) 7281 if (IS_ERR(task))
6888 return PTR_ERR(task); 7282 return PTR_ERR(task);
6889 status = task->tk_status; 7283 status = task->tk_status;
7284 trace_nfs4_layoutreturn(lrp->args.inode, status);
6890 dprintk("<-- %s status=%d\n", __func__, status); 7285 dprintk("<-- %s status=%d\n", __func__, status);
6891 rpc_put_task(task); 7286 rpc_put_task(task);
6892 return status; 7287 return status;
@@ -7063,7 +7458,7 @@ nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data, bool sync)
7063 data->args.lastbytewritten, 7458 data->args.lastbytewritten,
7064 data->args.inode->i_ino); 7459 data->args.inode->i_ino);
7065 7460
7066 nfs41_init_sequence(&data->args.seq_args, &data->res.seq_res, 1); 7461 nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1);
7067 task = rpc_run_task(&task_setup_data); 7462 task = rpc_run_task(&task_setup_data);
7068 if (IS_ERR(task)) 7463 if (IS_ERR(task))
7069 return PTR_ERR(task); 7464 return PTR_ERR(task);
@@ -7073,15 +7468,21 @@ nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data, bool sync)
7073 if (status != 0) 7468 if (status != 0)
7074 goto out; 7469 goto out;
7075 status = task->tk_status; 7470 status = task->tk_status;
7471 trace_nfs4_layoutcommit(data->args.inode, status);
7076out: 7472out:
7077 dprintk("%s: status %d\n", __func__, status); 7473 dprintk("%s: status %d\n", __func__, status);
7078 rpc_put_task(task); 7474 rpc_put_task(task);
7079 return status; 7475 return status;
7080} 7476}
7081 7477
7478/**
7479 * Use the state managment nfs_client cl_rpcclient, which uses krb5i (if
7480 * possible) as per RFC3530bis and RFC5661 Security Considerations sections
7481 */
7082static int 7482static int
7083_nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle, 7483_nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
7084 struct nfs_fsinfo *info, struct nfs4_secinfo_flavors *flavors) 7484 struct nfs_fsinfo *info,
7485 struct nfs4_secinfo_flavors *flavors, bool use_integrity)
7085{ 7486{
7086 struct nfs41_secinfo_no_name_args args = { 7487 struct nfs41_secinfo_no_name_args args = {
7087 .style = SECINFO_STYLE_CURRENT_FH, 7488 .style = SECINFO_STYLE_CURRENT_FH,
@@ -7094,7 +7495,23 @@ _nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
7094 .rpc_argp = &args, 7495 .rpc_argp = &args,
7095 .rpc_resp = &res, 7496 .rpc_resp = &res,
7096 }; 7497 };
7097 return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0); 7498 struct rpc_clnt *clnt = server->client;
7499 int status;
7500
7501 if (use_integrity) {
7502 clnt = server->nfs_client->cl_rpcclient;
7503 msg.rpc_cred = nfs4_get_clid_cred(server->nfs_client);
7504 }
7505
7506 dprintk("--> %s\n", __func__);
7507 status = nfs4_call_sync(clnt, server, &msg, &args.seq_args,
7508 &res.seq_res, 0);
7509 dprintk("<-- %s status=%d\n", __func__, status);
7510
7511 if (msg.rpc_cred)
7512 put_rpccred(msg.rpc_cred);
7513
7514 return status;
7098} 7515}
7099 7516
7100static int 7517static int
@@ -7104,7 +7521,24 @@ nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
7104 struct nfs4_exception exception = { }; 7521 struct nfs4_exception exception = { };
7105 int err; 7522 int err;
7106 do { 7523 do {
7107 err = _nfs41_proc_secinfo_no_name(server, fhandle, info, flavors); 7524 /* first try using integrity protection */
7525 err = -NFS4ERR_WRONGSEC;
7526
7527 /* try to use integrity protection with machine cred */
7528 if (_nfs4_is_integrity_protected(server->nfs_client))
7529 err = _nfs41_proc_secinfo_no_name(server, fhandle, info,
7530 flavors, true);
7531
7532 /*
7533 * if unable to use integrity protection, or SECINFO with
7534 * integrity protection returns NFS4ERR_WRONGSEC (which is
7535 * disallowed by spec, but exists in deployed servers) use
7536 * the current filesystem's rpc_client and the user cred.
7537 */
7538 if (err == -NFS4ERR_WRONGSEC)
7539 err = _nfs41_proc_secinfo_no_name(server, fhandle, info,
7540 flavors, false);
7541
7108 switch (err) { 7542 switch (err) {
7109 case 0: 7543 case 0:
7110 case -NFS4ERR_WRONGSEC: 7544 case -NFS4ERR_WRONGSEC:
@@ -7174,11 +7608,15 @@ static int _nfs41_test_stateid(struct nfs_server *server,
7174 .rpc_resp = &res, 7608 .rpc_resp = &res,
7175 .rpc_cred = cred, 7609 .rpc_cred = cred,
7176 }; 7610 };
7611 struct rpc_clnt *rpc_client = server->client;
7612
7613 nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_STATEID,
7614 &rpc_client, &msg);
7177 7615
7178 dprintk("NFS call test_stateid %p\n", stateid); 7616 dprintk("NFS call test_stateid %p\n", stateid);
7179 nfs41_init_sequence(&args.seq_args, &res.seq_res, 0); 7617 nfs4_init_sequence(&args.seq_args, &res.seq_res, 0);
7180 nfs4_set_sequence_privileged(&args.seq_args); 7618 nfs4_set_sequence_privileged(&args.seq_args);
7181 status = nfs4_call_sync_sequence(server->client, server, &msg, 7619 status = nfs4_call_sync_sequence(rpc_client, server, &msg,
7182 &args.seq_args, &res.seq_res); 7620 &args.seq_args, &res.seq_res);
7183 if (status != NFS_OK) { 7621 if (status != NFS_OK) {
7184 dprintk("NFS reply test_stateid: failed, %d\n", status); 7622 dprintk("NFS reply test_stateid: failed, %d\n", status);
@@ -7247,7 +7685,7 @@ static void nfs41_free_stateid_release(void *calldata)
7247 kfree(calldata); 7685 kfree(calldata);
7248} 7686}
7249 7687
7250const struct rpc_call_ops nfs41_free_stateid_ops = { 7688static const struct rpc_call_ops nfs41_free_stateid_ops = {
7251 .rpc_call_prepare = nfs41_free_stateid_prepare, 7689 .rpc_call_prepare = nfs41_free_stateid_prepare,
7252 .rpc_call_done = nfs41_free_stateid_done, 7690 .rpc_call_done = nfs41_free_stateid_done,
7253 .rpc_release = nfs41_free_stateid_release, 7691 .rpc_release = nfs41_free_stateid_release,
@@ -7270,6 +7708,9 @@ static struct rpc_task *_nfs41_free_stateid(struct nfs_server *server,
7270 }; 7708 };
7271 struct nfs_free_stateid_data *data; 7709 struct nfs_free_stateid_data *data;
7272 7710
7711 nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_STATEID,
7712 &task_setup.rpc_client, &msg);
7713
7273 dprintk("NFS call free_stateid %p\n", stateid); 7714 dprintk("NFS call free_stateid %p\n", stateid);
7274 data = kmalloc(sizeof(*data), GFP_NOFS); 7715 data = kmalloc(sizeof(*data), GFP_NOFS);
7275 if (!data) 7716 if (!data)
@@ -7281,7 +7722,7 @@ static struct rpc_task *_nfs41_free_stateid(struct nfs_server *server,
7281 7722
7282 msg.rpc_argp = &data->args; 7723 msg.rpc_argp = &data->args;
7283 msg.rpc_resp = &data->res; 7724 msg.rpc_resp = &data->res;
7284 nfs41_init_sequence(&data->args.seq_args, &data->res.seq_res, 0); 7725 nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 0);
7285 if (privileged) 7726 if (privileged)
7286 nfs4_set_sequence_privileged(&data->args.seq_args); 7727 nfs4_set_sequence_privileged(&data->args.seq_args);
7287 7728
@@ -7357,7 +7798,6 @@ static const struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = {
7357 .recover_open = nfs4_open_reclaim, 7798 .recover_open = nfs4_open_reclaim,
7358 .recover_lock = nfs4_lock_reclaim, 7799 .recover_lock = nfs4_lock_reclaim,
7359 .establish_clid = nfs4_init_clientid, 7800 .establish_clid = nfs4_init_clientid,
7360 .get_clid_cred = nfs4_get_setclientid_cred,
7361 .detect_trunking = nfs40_discover_server_trunking, 7801 .detect_trunking = nfs40_discover_server_trunking,
7362}; 7802};
7363 7803
@@ -7368,7 +7808,6 @@ static const struct nfs4_state_recovery_ops nfs41_reboot_recovery_ops = {
7368 .recover_open = nfs4_open_reclaim, 7808 .recover_open = nfs4_open_reclaim,
7369 .recover_lock = nfs4_lock_reclaim, 7809 .recover_lock = nfs4_lock_reclaim,
7370 .establish_clid = nfs41_init_clientid, 7810 .establish_clid = nfs41_init_clientid,
7371 .get_clid_cred = nfs4_get_exchange_id_cred,
7372 .reclaim_complete = nfs41_proc_reclaim_complete, 7811 .reclaim_complete = nfs41_proc_reclaim_complete,
7373 .detect_trunking = nfs41_discover_server_trunking, 7812 .detect_trunking = nfs41_discover_server_trunking,
7374}; 7813};
@@ -7380,7 +7819,6 @@ static const struct nfs4_state_recovery_ops nfs40_nograce_recovery_ops = {
7380 .recover_open = nfs4_open_expired, 7819 .recover_open = nfs4_open_expired,
7381 .recover_lock = nfs4_lock_expired, 7820 .recover_lock = nfs4_lock_expired,
7382 .establish_clid = nfs4_init_clientid, 7821 .establish_clid = nfs4_init_clientid,
7383 .get_clid_cred = nfs4_get_setclientid_cred,
7384}; 7822};
7385 7823
7386#if defined(CONFIG_NFS_V4_1) 7824#if defined(CONFIG_NFS_V4_1)
@@ -7390,7 +7828,6 @@ static const struct nfs4_state_recovery_ops nfs41_nograce_recovery_ops = {
7390 .recover_open = nfs41_open_expired, 7828 .recover_open = nfs41_open_expired,
7391 .recover_lock = nfs41_lock_expired, 7829 .recover_lock = nfs41_lock_expired,
7392 .establish_clid = nfs41_init_clientid, 7830 .establish_clid = nfs41_init_clientid,
7393 .get_clid_cred = nfs4_get_exchange_id_cred,
7394}; 7831};
7395#endif /* CONFIG_NFS_V4_1 */ 7832#endif /* CONFIG_NFS_V4_1 */
7396 7833
@@ -7414,10 +7851,12 @@ static const struct nfs4_minor_version_ops nfs_v4_0_minor_ops = {
7414 | NFS_CAP_ATOMIC_OPEN 7851 | NFS_CAP_ATOMIC_OPEN
7415 | NFS_CAP_CHANGE_ATTR 7852 | NFS_CAP_CHANGE_ATTR
7416 | NFS_CAP_POSIX_LOCK, 7853 | NFS_CAP_POSIX_LOCK,
7417 .call_sync = _nfs4_call_sync, 7854 .init_client = nfs40_init_client,
7855 .shutdown_client = nfs40_shutdown_client,
7418 .match_stateid = nfs4_match_stateid, 7856 .match_stateid = nfs4_match_stateid,
7419 .find_root_sec = nfs4_find_root_sec, 7857 .find_root_sec = nfs4_find_root_sec,
7420 .free_lock_state = nfs4_release_lockowner, 7858 .free_lock_state = nfs4_release_lockowner,
7859 .call_sync_ops = &nfs40_call_sync_ops,
7421 .reboot_recovery_ops = &nfs40_reboot_recovery_ops, 7860 .reboot_recovery_ops = &nfs40_reboot_recovery_ops,
7422 .nograce_recovery_ops = &nfs40_nograce_recovery_ops, 7861 .nograce_recovery_ops = &nfs40_nograce_recovery_ops,
7423 .state_renewal_ops = &nfs40_state_renewal_ops, 7862 .state_renewal_ops = &nfs40_state_renewal_ops,
@@ -7432,10 +7871,12 @@ static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = {
7432 | NFS_CAP_POSIX_LOCK 7871 | NFS_CAP_POSIX_LOCK
7433 | NFS_CAP_STATEID_NFSV41 7872 | NFS_CAP_STATEID_NFSV41
7434 | NFS_CAP_ATOMIC_OPEN_V1, 7873 | NFS_CAP_ATOMIC_OPEN_V1,
7435 .call_sync = nfs4_call_sync_sequence, 7874 .init_client = nfs41_init_client,
7875 .shutdown_client = nfs41_shutdown_client,
7436 .match_stateid = nfs41_match_stateid, 7876 .match_stateid = nfs41_match_stateid,
7437 .find_root_sec = nfs41_find_root_sec, 7877 .find_root_sec = nfs41_find_root_sec,
7438 .free_lock_state = nfs41_free_lock_state, 7878 .free_lock_state = nfs41_free_lock_state,
7879 .call_sync_ops = &nfs41_call_sync_ops,
7439 .reboot_recovery_ops = &nfs41_reboot_recovery_ops, 7880 .reboot_recovery_ops = &nfs41_reboot_recovery_ops,
7440 .nograce_recovery_ops = &nfs41_nograce_recovery_ops, 7881 .nograce_recovery_ops = &nfs41_nograce_recovery_ops,
7441 .state_renewal_ops = &nfs41_state_renewal_ops, 7882 .state_renewal_ops = &nfs41_state_renewal_ops,
@@ -7451,10 +7892,12 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = {
7451 | NFS_CAP_POSIX_LOCK 7892 | NFS_CAP_POSIX_LOCK
7452 | NFS_CAP_STATEID_NFSV41 7893 | NFS_CAP_STATEID_NFSV41
7453 | NFS_CAP_ATOMIC_OPEN_V1, 7894 | NFS_CAP_ATOMIC_OPEN_V1,
7454 .call_sync = nfs4_call_sync_sequence, 7895 .init_client = nfs41_init_client,
7896 .shutdown_client = nfs41_shutdown_client,
7455 .match_stateid = nfs41_match_stateid, 7897 .match_stateid = nfs41_match_stateid,
7456 .find_root_sec = nfs41_find_root_sec, 7898 .find_root_sec = nfs41_find_root_sec,
7457 .free_lock_state = nfs41_free_lock_state, 7899 .free_lock_state = nfs41_free_lock_state,
7900 .call_sync_ops = &nfs41_call_sync_ops,
7458 .reboot_recovery_ops = &nfs41_reboot_recovery_ops, 7901 .reboot_recovery_ops = &nfs41_reboot_recovery_ops,
7459 .nograce_recovery_ops = &nfs41_nograce_recovery_ops, 7902 .nograce_recovery_ops = &nfs41_nograce_recovery_ops,
7460 .state_renewal_ops = &nfs41_state_renewal_ops, 7903 .state_renewal_ops = &nfs41_state_renewal_ops,
@@ -7471,7 +7914,7 @@ const struct nfs4_minor_version_ops *nfs_v4_minor_ops[] = {
7471#endif 7914#endif
7472}; 7915};
7473 7916
7474const struct inode_operations nfs4_dir_inode_operations = { 7917static const struct inode_operations nfs4_dir_inode_operations = {
7475 .create = nfs_create, 7918 .create = nfs_create,
7476 .lookup = nfs_lookup, 7919 .lookup = nfs_lookup,
7477 .atomic_open = nfs_atomic_open, 7920 .atomic_open = nfs_atomic_open,