aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4state.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r--fs/nfsd/nfs4state.c136
1 files changed, 40 insertions, 96 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 9d81c7117ae6..242fee7c1018 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -683,39 +683,6 @@ out_err:
683 return; 683 return;
684} 684}
685 685
686/*
687 * RFC 3010 has a complex implmentation description of processing a
688 * SETCLIENTID request consisting of 5 bullets, labeled as
689 * CASE0 - CASE4 below.
690 *
691 * NOTES:
692 * callback information will be processed in a future patch
693 *
694 * an unconfirmed record is added when:
695 * NORMAL (part of CASE 4): there is no confirmed nor unconfirmed record.
696 * CASE 1: confirmed record found with matching name, principal,
697 * verifier, and clientid.
698 * CASE 2: confirmed record found with matching name, principal,
699 * and there is no unconfirmed record with matching
700 * name and principal
701 *
702 * an unconfirmed record is replaced when:
703 * CASE 3: confirmed record found with matching name, principal,
704 * and an unconfirmed record is found with matching
705 * name, principal, and with clientid and
706 * confirm that does not match the confirmed record.
707 * CASE 4: there is no confirmed record with matching name and
708 * principal. there is an unconfirmed record with
709 * matching name, principal.
710 *
711 * an unconfirmed record is deleted when:
712 * CASE 1: an unconfirmed record that matches input name, verifier,
713 * and confirmed clientid.
714 * CASE 4: any unconfirmed records with matching name and principal
715 * that exist after an unconfirmed record has been replaced
716 * as described above.
717 *
718 */
719__be32 686__be32
720nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 687nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
721 struct nfsd4_setclientid *setclid) 688 struct nfsd4_setclientid *setclid)
@@ -748,11 +715,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
748 nfs4_lock_state(); 715 nfs4_lock_state();
749 conf = find_confirmed_client_by_str(dname, strhashval); 716 conf = find_confirmed_client_by_str(dname, strhashval);
750 if (conf) { 717 if (conf) {
751 /* 718 /* RFC 3530 14.2.33 CASE 0: */
752 * CASE 0:
753 * clname match, confirmed, different principal
754 * or different ip_address
755 */
756 status = nfserr_clid_inuse; 719 status = nfserr_clid_inuse;
757 if (!same_creds(&conf->cl_cred, &rqstp->rq_cred) 720 if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)
758 || conf->cl_addr != sin->sin_addr.s_addr) { 721 || conf->cl_addr != sin->sin_addr.s_addr) {
@@ -761,12 +724,17 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
761 goto out; 724 goto out;
762 } 725 }
763 } 726 }
727 /*
728 * section 14.2.33 of RFC 3530 (under the heading "IMPLEMENTATION")
729 * has a description of SETCLIENTID request processing consisting
730 * of 5 bullet points, labeled as CASE0 - CASE4 below.
731 */
764 unconf = find_unconfirmed_client_by_str(dname, strhashval); 732 unconf = find_unconfirmed_client_by_str(dname, strhashval);
765 status = nfserr_resource; 733 status = nfserr_resource;
766 if (!conf) { 734 if (!conf) {
767 /* 735 /*
768 * CASE 4: 736 * RFC 3530 14.2.33 CASE 4:
769 * placed first, because it is the normal case. 737 * placed first, because it is the normal case
770 */ 738 */
771 if (unconf) 739 if (unconf)
772 expire_client(unconf); 740 expire_client(unconf);
@@ -776,17 +744,8 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
776 gen_clid(new); 744 gen_clid(new);
777 } else if (same_verf(&conf->cl_verifier, &clverifier)) { 745 } else if (same_verf(&conf->cl_verifier, &clverifier)) {
778 /* 746 /*
779 * CASE 1: 747 * RFC 3530 14.2.33 CASE 1:
780 * cl_name match, confirmed, principal match 748 * probable callback update
781 * verifier match: probable callback update
782 *
783 * remove any unconfirmed nfs4_client with
784 * matching cl_name, cl_verifier, and cl_clientid
785 *
786 * create and insert an unconfirmed nfs4_client with same
787 * cl_name, cl_verifier, and cl_clientid as existing
788 * nfs4_client, but with the new callback info and a
789 * new cl_confirm
790 */ 749 */
791 if (unconf) { 750 if (unconf) {
792 /* Note this is removing unconfirmed {*x***}, 751 /* Note this is removing unconfirmed {*x***},
@@ -802,32 +761,19 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
802 copy_clid(new, conf); 761 copy_clid(new, conf);
803 } else if (!unconf) { 762 } else if (!unconf) {
804 /* 763 /*
805 * CASE 2: 764 * RFC 3530 14.2.33 CASE 2:
806 * clname match, confirmed, principal match 765 * probable client reboot; state will be removed if
807 * verfier does not match 766 * confirmed.
808 * no unconfirmed. create a new unconfirmed nfs4_client
809 * using input clverifier, clname, and callback info
810 * and generate a new cl_clientid and cl_confirm.
811 */ 767 */
812 new = create_client(clname, dname); 768 new = create_client(clname, dname);
813 if (new == NULL) 769 if (new == NULL)
814 goto out; 770 goto out;
815 gen_clid(new); 771 gen_clid(new);
816 } else if (!same_verf(&conf->cl_confirm, &unconf->cl_confirm)) { 772 } else if (!same_verf(&conf->cl_confirm, &unconf->cl_confirm)) {
817 /* 773 /*
818 * CASE3: 774 * RFC 3530 14.2.33 CASE 3:
819 * confirmed found (name, principal match) 775 * probable client reboot; state will be removed if
820 * confirmed verifier does not match input clverifier 776 * confirmed.
821 *
822 * unconfirmed found (name match)
823 * confirmed->cl_confirm != unconfirmed->cl_confirm
824 *
825 * remove unconfirmed.
826 *
827 * create an unconfirmed nfs4_client
828 * with same cl_name as existing confirmed nfs4_client,
829 * but with new callback info, new cl_clientid,
830 * new cl_verifier and a new cl_confirm
831 */ 777 */
832 expire_client(unconf); 778 expire_client(unconf);
833 new = create_client(clname, dname); 779 new = create_client(clname, dname);
@@ -857,11 +803,9 @@ out:
857 803
858 804
859/* 805/*
860 * RFC 3010 has a complex implmentation description of processing a 806 * Section 14.2.34 of RFC 3530 (under the heading "IMPLEMENTATION") has
861 * SETCLIENTID_CONFIRM request consisting of 4 bullets describing 807 * a description of SETCLIENTID_CONFIRM request processing consisting of 4
862 * processing on a DRC miss, labeled as CASE1 - CASE4 below. 808 * bullets, labeled as CASE1 - CASE4 below.
863 *
864 * NOTE: callback information will be processed here in a future patch
865 */ 809 */
866__be32 810__be32
867nfsd4_setclientid_confirm(struct svc_rqst *rqstp, 811nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
@@ -892,16 +836,20 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
892 if (unconf && unconf->cl_addr != sin->sin_addr.s_addr) 836 if (unconf && unconf->cl_addr != sin->sin_addr.s_addr)
893 goto out; 837 goto out;
894 838
839 /*
840 * section 14.2.34 of RFC 3530 has a description of
841 * SETCLIENTID_CONFIRM request processing consisting
842 * of 4 bullet points, labeled as CASE1 - CASE4 below.
843 */
895 if ((conf && unconf) && 844 if ((conf && unconf) &&
896 (same_verf(&unconf->cl_confirm, &confirm)) && 845 (same_verf(&unconf->cl_confirm, &confirm)) &&
897 (same_verf(&conf->cl_verifier, &unconf->cl_verifier)) && 846 (same_verf(&conf->cl_verifier, &unconf->cl_verifier)) &&
898 (same_name(conf->cl_recdir,unconf->cl_recdir)) && 847 (same_name(conf->cl_recdir,unconf->cl_recdir)) &&
899 (!same_verf(&conf->cl_confirm, &unconf->cl_confirm))) { 848 (!same_verf(&conf->cl_confirm, &unconf->cl_confirm))) {
900 /* CASE 1: 849 /*
901 * unconf record that matches input clientid and input confirm. 850 * RFC 3530 14.2.34 CASE 1:
902 * conf record that matches input clientid. 851 * callback update
903 * conf and unconf records match names, verifiers 852 */
904 */
905 if (!same_creds(&conf->cl_cred, &unconf->cl_cred)) 853 if (!same_creds(&conf->cl_cred, &unconf->cl_cred))
906 status = nfserr_clid_inuse; 854 status = nfserr_clid_inuse;
907 else { 855 else {
@@ -918,11 +866,10 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
918 ((conf && unconf) && 866 ((conf && unconf) &&
919 (!same_verf(&conf->cl_verifier, &unconf->cl_verifier) || 867 (!same_verf(&conf->cl_verifier, &unconf->cl_verifier) ||
920 !same_name(conf->cl_recdir, unconf->cl_recdir)))) { 868 !same_name(conf->cl_recdir, unconf->cl_recdir)))) {
921 /* CASE 2: 869 /*
922 * conf record that matches input clientid. 870 * RFC 3530 14.2.34 CASE 2:
923 * if unconf record matches input clientid, then 871 * probable retransmitted request; play it safe and
924 * unconf->cl_name or unconf->cl_verifier don't match the 872 * do nothing.
925 * conf record.
926 */ 873 */
927 if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) 874 if (!same_creds(&conf->cl_cred, &rqstp->rq_cred))
928 status = nfserr_clid_inuse; 875 status = nfserr_clid_inuse;
@@ -930,10 +877,9 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
930 status = nfs_ok; 877 status = nfs_ok;
931 } else if (!conf && unconf 878 } else if (!conf && unconf
932 && same_verf(&unconf->cl_confirm, &confirm)) { 879 && same_verf(&unconf->cl_confirm, &confirm)) {
933 /* CASE 3: 880 /*
934 * conf record not found. 881 * RFC 3530 14.2.34 CASE 3:
935 * unconf record found. 882 * Normal case; new or rebooted client:
936 * unconf->cl_confirm matches input confirm
937 */ 883 */
938 if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred)) { 884 if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred)) {
939 status = nfserr_clid_inuse; 885 status = nfserr_clid_inuse;
@@ -954,11 +900,9 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
954 } else if ((!conf || (conf && !same_verf(&conf->cl_confirm, &confirm))) 900 } else if ((!conf || (conf && !same_verf(&conf->cl_confirm, &confirm)))
955 && (!unconf || (unconf && !same_verf(&unconf->cl_confirm, 901 && (!unconf || (unconf && !same_verf(&unconf->cl_confirm,
956 &confirm)))) { 902 &confirm)))) {
957 /* CASE 4: 903 /*
958 * conf record not found, or if conf, conf->cl_confirm does not 904 * RFC 3530 14.2.34 CASE 4:
959 * match input confirm. 905 * Client probably hasn't noticed that we rebooted yet.
960 * unconf record not found, or if unconf, unconf->cl_confirm
961 * does not match input confirm.
962 */ 906 */
963 status = nfserr_stale_clientid; 907 status = nfserr_stale_clientid;
964 } else { 908 } else {