diff options
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r-- | fs/nfsd/nfs4state.c | 136 |
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 |
720 | nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | 687 | nfsd4_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 |
867 | nfsd4_setclientid_confirm(struct svc_rqst *rqstp, | 811 | nfsd4_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 { |