diff options
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r-- | fs/nfs/nfs4xdr.c | 1461 |
1 files changed, 868 insertions, 593 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 617273e7d47f..83ad47cbdd8a 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <linux/time.h> | 39 | #include <linux/time.h> |
40 | #include <linux/mm.h> | 40 | #include <linux/mm.h> |
41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
42 | #include <linux/utsname.h> | ||
43 | #include <linux/errno.h> | 42 | #include <linux/errno.h> |
44 | #include <linux/string.h> | 43 | #include <linux/string.h> |
45 | #include <linux/in.h> | 44 | #include <linux/in.h> |
@@ -702,29 +701,12 @@ struct compound_hdr { | |||
702 | u32 minorversion; | 701 | u32 minorversion; |
703 | }; | 702 | }; |
704 | 703 | ||
705 | /* | 704 | static __be32 *reserve_space(struct xdr_stream *xdr, size_t nbytes) |
706 | * START OF "GENERIC" ENCODE ROUTINES. | 705 | { |
707 | * These may look a little ugly since they are imported from a "generic" | 706 | __be32 *p = xdr_reserve_space(xdr, nbytes); |
708 | * set of XDR encode/decode routines which are intended to be shared by | 707 | BUG_ON(!p); |
709 | * all of our NFSv4 implementations (OpenBSD, MacOS X...). | 708 | return p; |
710 | * | 709 | } |
711 | * If the pain of reading these is too great, it should be a straightforward | ||
712 | * task to translate them into Linux-specific versions which are more | ||
713 | * consistent with the style used in NFSv2/v3... | ||
714 | */ | ||
715 | #define WRITE32(n) *p++ = htonl(n) | ||
716 | #define WRITE64(n) do { \ | ||
717 | *p++ = htonl((uint32_t)((n) >> 32)); \ | ||
718 | *p++ = htonl((uint32_t)(n)); \ | ||
719 | } while (0) | ||
720 | #define WRITEMEM(ptr,nbytes) do { \ | ||
721 | p = xdr_encode_opaque_fixed(p, ptr, nbytes); \ | ||
722 | } while (0) | ||
723 | |||
724 | #define RESERVE_SPACE(nbytes) do { \ | ||
725 | p = xdr_reserve_space(xdr, nbytes); \ | ||
726 | BUG_ON(!p); \ | ||
727 | } while (0) | ||
728 | 710 | ||
729 | static void encode_string(struct xdr_stream *xdr, unsigned int len, const char *str) | 711 | static void encode_string(struct xdr_stream *xdr, unsigned int len, const char *str) |
730 | { | 712 | { |
@@ -749,12 +731,11 @@ static void encode_compound_hdr(struct xdr_stream *xdr, | |||
749 | 731 | ||
750 | dprintk("encode_compound: tag=%.*s\n", (int)hdr->taglen, hdr->tag); | 732 | dprintk("encode_compound: tag=%.*s\n", (int)hdr->taglen, hdr->tag); |
751 | BUG_ON(hdr->taglen > NFS4_MAXTAGLEN); | 733 | BUG_ON(hdr->taglen > NFS4_MAXTAGLEN); |
752 | RESERVE_SPACE(12+(XDR_QUADLEN(hdr->taglen)<<2)); | 734 | p = reserve_space(xdr, 4 + hdr->taglen + 8); |
753 | WRITE32(hdr->taglen); | 735 | p = xdr_encode_opaque(p, hdr->tag, hdr->taglen); |
754 | WRITEMEM(hdr->tag, hdr->taglen); | 736 | *p++ = cpu_to_be32(hdr->minorversion); |
755 | WRITE32(hdr->minorversion); | ||
756 | hdr->nops_p = p; | 737 | hdr->nops_p = p; |
757 | WRITE32(hdr->nops); | 738 | *p = cpu_to_be32(hdr->nops); |
758 | } | 739 | } |
759 | 740 | ||
760 | static void encode_nops(struct compound_hdr *hdr) | 741 | static void encode_nops(struct compound_hdr *hdr) |
@@ -829,55 +810,53 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const | |||
829 | len += 16; | 810 | len += 16; |
830 | else if (iap->ia_valid & ATTR_MTIME) | 811 | else if (iap->ia_valid & ATTR_MTIME) |
831 | len += 4; | 812 | len += 4; |
832 | RESERVE_SPACE(len); | 813 | p = reserve_space(xdr, len); |
833 | 814 | ||
834 | /* | 815 | /* |
835 | * We write the bitmap length now, but leave the bitmap and the attribute | 816 | * We write the bitmap length now, but leave the bitmap and the attribute |
836 | * buffer length to be backfilled at the end of this routine. | 817 | * buffer length to be backfilled at the end of this routine. |
837 | */ | 818 | */ |
838 | WRITE32(2); | 819 | *p++ = cpu_to_be32(2); |
839 | q = p; | 820 | q = p; |
840 | p += 3; | 821 | p += 3; |
841 | 822 | ||
842 | if (iap->ia_valid & ATTR_SIZE) { | 823 | if (iap->ia_valid & ATTR_SIZE) { |
843 | bmval0 |= FATTR4_WORD0_SIZE; | 824 | bmval0 |= FATTR4_WORD0_SIZE; |
844 | WRITE64(iap->ia_size); | 825 | p = xdr_encode_hyper(p, iap->ia_size); |
845 | } | 826 | } |
846 | if (iap->ia_valid & ATTR_MODE) { | 827 | if (iap->ia_valid & ATTR_MODE) { |
847 | bmval1 |= FATTR4_WORD1_MODE; | 828 | bmval1 |= FATTR4_WORD1_MODE; |
848 | WRITE32(iap->ia_mode & S_IALLUGO); | 829 | *p++ = cpu_to_be32(iap->ia_mode & S_IALLUGO); |
849 | } | 830 | } |
850 | if (iap->ia_valid & ATTR_UID) { | 831 | if (iap->ia_valid & ATTR_UID) { |
851 | bmval1 |= FATTR4_WORD1_OWNER; | 832 | bmval1 |= FATTR4_WORD1_OWNER; |
852 | WRITE32(owner_namelen); | 833 | p = xdr_encode_opaque(p, owner_name, owner_namelen); |
853 | WRITEMEM(owner_name, owner_namelen); | ||
854 | } | 834 | } |
855 | if (iap->ia_valid & ATTR_GID) { | 835 | if (iap->ia_valid & ATTR_GID) { |
856 | bmval1 |= FATTR4_WORD1_OWNER_GROUP; | 836 | bmval1 |= FATTR4_WORD1_OWNER_GROUP; |
857 | WRITE32(owner_grouplen); | 837 | p = xdr_encode_opaque(p, owner_group, owner_grouplen); |
858 | WRITEMEM(owner_group, owner_grouplen); | ||
859 | } | 838 | } |
860 | if (iap->ia_valid & ATTR_ATIME_SET) { | 839 | if (iap->ia_valid & ATTR_ATIME_SET) { |
861 | bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET; | 840 | bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET; |
862 | WRITE32(NFS4_SET_TO_CLIENT_TIME); | 841 | *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME); |
863 | WRITE32(0); | 842 | *p++ = cpu_to_be32(0); |
864 | WRITE32(iap->ia_mtime.tv_sec); | 843 | *p++ = cpu_to_be32(iap->ia_mtime.tv_sec); |
865 | WRITE32(iap->ia_mtime.tv_nsec); | 844 | *p++ = cpu_to_be32(iap->ia_mtime.tv_nsec); |
866 | } | 845 | } |
867 | else if (iap->ia_valid & ATTR_ATIME) { | 846 | else if (iap->ia_valid & ATTR_ATIME) { |
868 | bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET; | 847 | bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET; |
869 | WRITE32(NFS4_SET_TO_SERVER_TIME); | 848 | *p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME); |
870 | } | 849 | } |
871 | if (iap->ia_valid & ATTR_MTIME_SET) { | 850 | if (iap->ia_valid & ATTR_MTIME_SET) { |
872 | bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET; | 851 | bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET; |
873 | WRITE32(NFS4_SET_TO_CLIENT_TIME); | 852 | *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME); |
874 | WRITE32(0); | 853 | *p++ = cpu_to_be32(0); |
875 | WRITE32(iap->ia_mtime.tv_sec); | 854 | *p++ = cpu_to_be32(iap->ia_mtime.tv_sec); |
876 | WRITE32(iap->ia_mtime.tv_nsec); | 855 | *p++ = cpu_to_be32(iap->ia_mtime.tv_nsec); |
877 | } | 856 | } |
878 | else if (iap->ia_valid & ATTR_MTIME) { | 857 | else if (iap->ia_valid & ATTR_MTIME) { |
879 | bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET; | 858 | bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET; |
880 | WRITE32(NFS4_SET_TO_SERVER_TIME); | 859 | *p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME); |
881 | } | 860 | } |
882 | 861 | ||
883 | /* | 862 | /* |
@@ -891,7 +870,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const | |||
891 | len = (char *)p - (char *)q - 12; | 870 | len = (char *)p - (char *)q - 12; |
892 | *q++ = htonl(bmval0); | 871 | *q++ = htonl(bmval0); |
893 | *q++ = htonl(bmval1); | 872 | *q++ = htonl(bmval1); |
894 | *q++ = htonl(len); | 873 | *q = htonl(len); |
895 | 874 | ||
896 | /* out: */ | 875 | /* out: */ |
897 | } | 876 | } |
@@ -900,9 +879,9 @@ static void encode_access(struct xdr_stream *xdr, u32 access, struct compound_hd | |||
900 | { | 879 | { |
901 | __be32 *p; | 880 | __be32 *p; |
902 | 881 | ||
903 | RESERVE_SPACE(8); | 882 | p = reserve_space(xdr, 8); |
904 | WRITE32(OP_ACCESS); | 883 | *p++ = cpu_to_be32(OP_ACCESS); |
905 | WRITE32(access); | 884 | *p = cpu_to_be32(access); |
906 | hdr->nops++; | 885 | hdr->nops++; |
907 | hdr->replen += decode_access_maxsz; | 886 | hdr->replen += decode_access_maxsz; |
908 | } | 887 | } |
@@ -911,10 +890,10 @@ static void encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg | |||
911 | { | 890 | { |
912 | __be32 *p; | 891 | __be32 *p; |
913 | 892 | ||
914 | RESERVE_SPACE(8+NFS4_STATEID_SIZE); | 893 | p = reserve_space(xdr, 8+NFS4_STATEID_SIZE); |
915 | WRITE32(OP_CLOSE); | 894 | *p++ = cpu_to_be32(OP_CLOSE); |
916 | WRITE32(arg->seqid->sequence->counter); | 895 | *p++ = cpu_to_be32(arg->seqid->sequence->counter); |
917 | WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE); | 896 | xdr_encode_opaque_fixed(p, arg->stateid->data, NFS4_STATEID_SIZE); |
918 | hdr->nops++; | 897 | hdr->nops++; |
919 | hdr->replen += decode_close_maxsz; | 898 | hdr->replen += decode_close_maxsz; |
920 | } | 899 | } |
@@ -923,10 +902,10 @@ static void encode_commit(struct xdr_stream *xdr, const struct nfs_writeargs *ar | |||
923 | { | 902 | { |
924 | __be32 *p; | 903 | __be32 *p; |
925 | 904 | ||
926 | RESERVE_SPACE(16); | 905 | p = reserve_space(xdr, 16); |
927 | WRITE32(OP_COMMIT); | 906 | *p++ = cpu_to_be32(OP_COMMIT); |
928 | WRITE64(args->offset); | 907 | p = xdr_encode_hyper(p, args->offset); |
929 | WRITE32(args->count); | 908 | *p = cpu_to_be32(args->count); |
930 | hdr->nops++; | 909 | hdr->nops++; |
931 | hdr->replen += decode_commit_maxsz; | 910 | hdr->replen += decode_commit_maxsz; |
932 | } | 911 | } |
@@ -935,30 +914,28 @@ static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg * | |||
935 | { | 914 | { |
936 | __be32 *p; | 915 | __be32 *p; |
937 | 916 | ||
938 | RESERVE_SPACE(8); | 917 | p = reserve_space(xdr, 8); |
939 | WRITE32(OP_CREATE); | 918 | *p++ = cpu_to_be32(OP_CREATE); |
940 | WRITE32(create->ftype); | 919 | *p = cpu_to_be32(create->ftype); |
941 | 920 | ||
942 | switch (create->ftype) { | 921 | switch (create->ftype) { |
943 | case NF4LNK: | 922 | case NF4LNK: |
944 | RESERVE_SPACE(4); | 923 | p = reserve_space(xdr, 4); |
945 | WRITE32(create->u.symlink.len); | 924 | *p = cpu_to_be32(create->u.symlink.len); |
946 | xdr_write_pages(xdr, create->u.symlink.pages, 0, create->u.symlink.len); | 925 | xdr_write_pages(xdr, create->u.symlink.pages, 0, create->u.symlink.len); |
947 | break; | 926 | break; |
948 | 927 | ||
949 | case NF4BLK: case NF4CHR: | 928 | case NF4BLK: case NF4CHR: |
950 | RESERVE_SPACE(8); | 929 | p = reserve_space(xdr, 8); |
951 | WRITE32(create->u.device.specdata1); | 930 | *p++ = cpu_to_be32(create->u.device.specdata1); |
952 | WRITE32(create->u.device.specdata2); | 931 | *p = cpu_to_be32(create->u.device.specdata2); |
953 | break; | 932 | break; |
954 | 933 | ||
955 | default: | 934 | default: |
956 | break; | 935 | break; |
957 | } | 936 | } |
958 | 937 | ||
959 | RESERVE_SPACE(4 + create->name->len); | 938 | encode_string(xdr, create->name->len, create->name->name); |
960 | WRITE32(create->name->len); | ||
961 | WRITEMEM(create->name->name, create->name->len); | ||
962 | hdr->nops++; | 939 | hdr->nops++; |
963 | hdr->replen += decode_create_maxsz; | 940 | hdr->replen += decode_create_maxsz; |
964 | 941 | ||
@@ -969,10 +946,10 @@ static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct c | |||
969 | { | 946 | { |
970 | __be32 *p; | 947 | __be32 *p; |
971 | 948 | ||
972 | RESERVE_SPACE(12); | 949 | p = reserve_space(xdr, 12); |
973 | WRITE32(OP_GETATTR); | 950 | *p++ = cpu_to_be32(OP_GETATTR); |
974 | WRITE32(1); | 951 | *p++ = cpu_to_be32(1); |
975 | WRITE32(bitmap); | 952 | *p = cpu_to_be32(bitmap); |
976 | hdr->nops++; | 953 | hdr->nops++; |
977 | hdr->replen += decode_getattr_maxsz; | 954 | hdr->replen += decode_getattr_maxsz; |
978 | } | 955 | } |
@@ -981,11 +958,11 @@ static void encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm | |||
981 | { | 958 | { |
982 | __be32 *p; | 959 | __be32 *p; |
983 | 960 | ||
984 | RESERVE_SPACE(16); | 961 | p = reserve_space(xdr, 16); |
985 | WRITE32(OP_GETATTR); | 962 | *p++ = cpu_to_be32(OP_GETATTR); |
986 | WRITE32(2); | 963 | *p++ = cpu_to_be32(2); |
987 | WRITE32(bm0); | 964 | *p++ = cpu_to_be32(bm0); |
988 | WRITE32(bm1); | 965 | *p = cpu_to_be32(bm1); |
989 | hdr->nops++; | 966 | hdr->nops++; |
990 | hdr->replen += decode_getattr_maxsz; | 967 | hdr->replen += decode_getattr_maxsz; |
991 | } | 968 | } |
@@ -1012,8 +989,8 @@ static void encode_getfh(struct xdr_stream *xdr, struct compound_hdr *hdr) | |||
1012 | { | 989 | { |
1013 | __be32 *p; | 990 | __be32 *p; |
1014 | 991 | ||
1015 | RESERVE_SPACE(4); | 992 | p = reserve_space(xdr, 4); |
1016 | WRITE32(OP_GETFH); | 993 | *p = cpu_to_be32(OP_GETFH); |
1017 | hdr->nops++; | 994 | hdr->nops++; |
1018 | hdr->replen += decode_getfh_maxsz; | 995 | hdr->replen += decode_getfh_maxsz; |
1019 | } | 996 | } |
@@ -1022,10 +999,9 @@ static void encode_link(struct xdr_stream *xdr, const struct qstr *name, struct | |||
1022 | { | 999 | { |
1023 | __be32 *p; | 1000 | __be32 *p; |
1024 | 1001 | ||
1025 | RESERVE_SPACE(8 + name->len); | 1002 | p = reserve_space(xdr, 8 + name->len); |
1026 | WRITE32(OP_LINK); | 1003 | *p++ = cpu_to_be32(OP_LINK); |
1027 | WRITE32(name->len); | 1004 | xdr_encode_opaque(p, name->name, name->len); |
1028 | WRITEMEM(name->name, name->len); | ||
1029 | hdr->nops++; | 1005 | hdr->nops++; |
1030 | hdr->replen += decode_link_maxsz; | 1006 | hdr->replen += decode_link_maxsz; |
1031 | } | 1007 | } |
@@ -1052,27 +1028,27 @@ static void encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args | |||
1052 | { | 1028 | { |
1053 | __be32 *p; | 1029 | __be32 *p; |
1054 | 1030 | ||
1055 | RESERVE_SPACE(32); | 1031 | p = reserve_space(xdr, 32); |
1056 | WRITE32(OP_LOCK); | 1032 | *p++ = cpu_to_be32(OP_LOCK); |
1057 | WRITE32(nfs4_lock_type(args->fl, args->block)); | 1033 | *p++ = cpu_to_be32(nfs4_lock_type(args->fl, args->block)); |
1058 | WRITE32(args->reclaim); | 1034 | *p++ = cpu_to_be32(args->reclaim); |
1059 | WRITE64(args->fl->fl_start); | 1035 | p = xdr_encode_hyper(p, args->fl->fl_start); |
1060 | WRITE64(nfs4_lock_length(args->fl)); | 1036 | p = xdr_encode_hyper(p, nfs4_lock_length(args->fl)); |
1061 | WRITE32(args->new_lock_owner); | 1037 | *p = cpu_to_be32(args->new_lock_owner); |
1062 | if (args->new_lock_owner){ | 1038 | if (args->new_lock_owner){ |
1063 | RESERVE_SPACE(4+NFS4_STATEID_SIZE+32); | 1039 | p = reserve_space(xdr, 4+NFS4_STATEID_SIZE+32); |
1064 | WRITE32(args->open_seqid->sequence->counter); | 1040 | *p++ = cpu_to_be32(args->open_seqid->sequence->counter); |
1065 | WRITEMEM(args->open_stateid->data, NFS4_STATEID_SIZE); | 1041 | p = xdr_encode_opaque_fixed(p, args->open_stateid->data, NFS4_STATEID_SIZE); |
1066 | WRITE32(args->lock_seqid->sequence->counter); | 1042 | *p++ = cpu_to_be32(args->lock_seqid->sequence->counter); |
1067 | WRITE64(args->lock_owner.clientid); | 1043 | p = xdr_encode_hyper(p, args->lock_owner.clientid); |
1068 | WRITE32(16); | 1044 | *p++ = cpu_to_be32(16); |
1069 | WRITEMEM("lock id:", 8); | 1045 | p = xdr_encode_opaque_fixed(p, "lock id:", 8); |
1070 | WRITE64(args->lock_owner.id); | 1046 | xdr_encode_hyper(p, args->lock_owner.id); |
1071 | } | 1047 | } |
1072 | else { | 1048 | else { |
1073 | RESERVE_SPACE(NFS4_STATEID_SIZE+4); | 1049 | p = reserve_space(xdr, NFS4_STATEID_SIZE+4); |
1074 | WRITEMEM(args->lock_stateid->data, NFS4_STATEID_SIZE); | 1050 | p = xdr_encode_opaque_fixed(p, args->lock_stateid->data, NFS4_STATEID_SIZE); |
1075 | WRITE32(args->lock_seqid->sequence->counter); | 1051 | *p = cpu_to_be32(args->lock_seqid->sequence->counter); |
1076 | } | 1052 | } |
1077 | hdr->nops++; | 1053 | hdr->nops++; |
1078 | hdr->replen += decode_lock_maxsz; | 1054 | hdr->replen += decode_lock_maxsz; |
@@ -1082,15 +1058,15 @@ static void encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *ar | |||
1082 | { | 1058 | { |
1083 | __be32 *p; | 1059 | __be32 *p; |
1084 | 1060 | ||
1085 | RESERVE_SPACE(52); | 1061 | p = reserve_space(xdr, 52); |
1086 | WRITE32(OP_LOCKT); | 1062 | *p++ = cpu_to_be32(OP_LOCKT); |
1087 | WRITE32(nfs4_lock_type(args->fl, 0)); | 1063 | *p++ = cpu_to_be32(nfs4_lock_type(args->fl, 0)); |
1088 | WRITE64(args->fl->fl_start); | 1064 | p = xdr_encode_hyper(p, args->fl->fl_start); |
1089 | WRITE64(nfs4_lock_length(args->fl)); | 1065 | p = xdr_encode_hyper(p, nfs4_lock_length(args->fl)); |
1090 | WRITE64(args->lock_owner.clientid); | 1066 | p = xdr_encode_hyper(p, args->lock_owner.clientid); |
1091 | WRITE32(16); | 1067 | *p++ = cpu_to_be32(16); |
1092 | WRITEMEM("lock id:", 8); | 1068 | p = xdr_encode_opaque_fixed(p, "lock id:", 8); |
1093 | WRITE64(args->lock_owner.id); | 1069 | xdr_encode_hyper(p, args->lock_owner.id); |
1094 | hdr->nops++; | 1070 | hdr->nops++; |
1095 | hdr->replen += decode_lockt_maxsz; | 1071 | hdr->replen += decode_lockt_maxsz; |
1096 | } | 1072 | } |
@@ -1099,13 +1075,13 @@ static void encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *ar | |||
1099 | { | 1075 | { |
1100 | __be32 *p; | 1076 | __be32 *p; |
1101 | 1077 | ||
1102 | RESERVE_SPACE(12+NFS4_STATEID_SIZE+16); | 1078 | p = reserve_space(xdr, 12+NFS4_STATEID_SIZE+16); |
1103 | WRITE32(OP_LOCKU); | 1079 | *p++ = cpu_to_be32(OP_LOCKU); |
1104 | WRITE32(nfs4_lock_type(args->fl, 0)); | 1080 | *p++ = cpu_to_be32(nfs4_lock_type(args->fl, 0)); |
1105 | WRITE32(args->seqid->sequence->counter); | 1081 | *p++ = cpu_to_be32(args->seqid->sequence->counter); |
1106 | WRITEMEM(args->stateid->data, NFS4_STATEID_SIZE); | 1082 | p = xdr_encode_opaque_fixed(p, args->stateid->data, NFS4_STATEID_SIZE); |
1107 | WRITE64(args->fl->fl_start); | 1083 | p = xdr_encode_hyper(p, args->fl->fl_start); |
1108 | WRITE64(nfs4_lock_length(args->fl)); | 1084 | xdr_encode_hyper(p, nfs4_lock_length(args->fl)); |
1109 | hdr->nops++; | 1085 | hdr->nops++; |
1110 | hdr->replen += decode_locku_maxsz; | 1086 | hdr->replen += decode_locku_maxsz; |
1111 | } | 1087 | } |
@@ -1115,10 +1091,9 @@ static void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struc | |||
1115 | int len = name->len; | 1091 | int len = name->len; |
1116 | __be32 *p; | 1092 | __be32 *p; |
1117 | 1093 | ||
1118 | RESERVE_SPACE(8 + len); | 1094 | p = reserve_space(xdr, 8 + len); |
1119 | WRITE32(OP_LOOKUP); | 1095 | *p++ = cpu_to_be32(OP_LOOKUP); |
1120 | WRITE32(len); | 1096 | xdr_encode_opaque(p, name->name, len); |
1121 | WRITEMEM(name->name, len); | ||
1122 | hdr->nops++; | 1097 | hdr->nops++; |
1123 | hdr->replen += decode_lookup_maxsz; | 1098 | hdr->replen += decode_lookup_maxsz; |
1124 | } | 1099 | } |
@@ -1127,21 +1102,21 @@ static void encode_share_access(struct xdr_stream *xdr, fmode_t fmode) | |||
1127 | { | 1102 | { |
1128 | __be32 *p; | 1103 | __be32 *p; |
1129 | 1104 | ||
1130 | RESERVE_SPACE(8); | 1105 | p = reserve_space(xdr, 8); |
1131 | switch (fmode & (FMODE_READ|FMODE_WRITE)) { | 1106 | switch (fmode & (FMODE_READ|FMODE_WRITE)) { |
1132 | case FMODE_READ: | 1107 | case FMODE_READ: |
1133 | WRITE32(NFS4_SHARE_ACCESS_READ); | 1108 | *p++ = cpu_to_be32(NFS4_SHARE_ACCESS_READ); |
1134 | break; | 1109 | break; |
1135 | case FMODE_WRITE: | 1110 | case FMODE_WRITE: |
1136 | WRITE32(NFS4_SHARE_ACCESS_WRITE); | 1111 | *p++ = cpu_to_be32(NFS4_SHARE_ACCESS_WRITE); |
1137 | break; | 1112 | break; |
1138 | case FMODE_READ|FMODE_WRITE: | 1113 | case FMODE_READ|FMODE_WRITE: |
1139 | WRITE32(NFS4_SHARE_ACCESS_BOTH); | 1114 | *p++ = cpu_to_be32(NFS4_SHARE_ACCESS_BOTH); |
1140 | break; | 1115 | break; |
1141 | default: | 1116 | default: |
1142 | WRITE32(0); | 1117 | *p++ = cpu_to_be32(0); |
1143 | } | 1118 | } |
1144 | WRITE32(0); /* for linux, share_deny = 0 always */ | 1119 | *p = cpu_to_be32(0); /* for linux, share_deny = 0 always */ |
1145 | } | 1120 | } |
1146 | 1121 | ||
1147 | static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_openargs *arg) | 1122 | static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_openargs *arg) |
@@ -1151,29 +1126,29 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena | |||
1151 | * opcode 4, seqid 4, share_access 4, share_deny 4, clientid 8, ownerlen 4, | 1126 | * opcode 4, seqid 4, share_access 4, share_deny 4, clientid 8, ownerlen 4, |
1152 | * owner 4 = 32 | 1127 | * owner 4 = 32 |
1153 | */ | 1128 | */ |
1154 | RESERVE_SPACE(8); | 1129 | p = reserve_space(xdr, 8); |
1155 | WRITE32(OP_OPEN); | 1130 | *p++ = cpu_to_be32(OP_OPEN); |
1156 | WRITE32(arg->seqid->sequence->counter); | 1131 | *p = cpu_to_be32(arg->seqid->sequence->counter); |
1157 | encode_share_access(xdr, arg->fmode); | 1132 | encode_share_access(xdr, arg->fmode); |
1158 | RESERVE_SPACE(28); | 1133 | p = reserve_space(xdr, 28); |
1159 | WRITE64(arg->clientid); | 1134 | p = xdr_encode_hyper(p, arg->clientid); |
1160 | WRITE32(16); | 1135 | *p++ = cpu_to_be32(16); |
1161 | WRITEMEM("open id:", 8); | 1136 | p = xdr_encode_opaque_fixed(p, "open id:", 8); |
1162 | WRITE64(arg->id); | 1137 | xdr_encode_hyper(p, arg->id); |
1163 | } | 1138 | } |
1164 | 1139 | ||
1165 | static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg) | 1140 | static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg) |
1166 | { | 1141 | { |
1167 | __be32 *p; | 1142 | __be32 *p; |
1168 | 1143 | ||
1169 | RESERVE_SPACE(4); | 1144 | p = reserve_space(xdr, 4); |
1170 | switch(arg->open_flags & O_EXCL) { | 1145 | switch(arg->open_flags & O_EXCL) { |
1171 | case 0: | 1146 | case 0: |
1172 | WRITE32(NFS4_CREATE_UNCHECKED); | 1147 | *p = cpu_to_be32(NFS4_CREATE_UNCHECKED); |
1173 | encode_attrs(xdr, arg->u.attrs, arg->server); | 1148 | encode_attrs(xdr, arg->u.attrs, arg->server); |
1174 | break; | 1149 | break; |
1175 | default: | 1150 | default: |
1176 | WRITE32(NFS4_CREATE_EXCLUSIVE); | 1151 | *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE); |
1177 | encode_nfs4_verifier(xdr, &arg->u.verifier); | 1152 | encode_nfs4_verifier(xdr, &arg->u.verifier); |
1178 | } | 1153 | } |
1179 | } | 1154 | } |
@@ -1182,14 +1157,14 @@ static void encode_opentype(struct xdr_stream *xdr, const struct nfs_openargs *a | |||
1182 | { | 1157 | { |
1183 | __be32 *p; | 1158 | __be32 *p; |
1184 | 1159 | ||
1185 | RESERVE_SPACE(4); | 1160 | p = reserve_space(xdr, 4); |
1186 | switch (arg->open_flags & O_CREAT) { | 1161 | switch (arg->open_flags & O_CREAT) { |
1187 | case 0: | 1162 | case 0: |
1188 | WRITE32(NFS4_OPEN_NOCREATE); | 1163 | *p = cpu_to_be32(NFS4_OPEN_NOCREATE); |
1189 | break; | 1164 | break; |
1190 | default: | 1165 | default: |
1191 | BUG_ON(arg->claim != NFS4_OPEN_CLAIM_NULL); | 1166 | BUG_ON(arg->claim != NFS4_OPEN_CLAIM_NULL); |
1192 | WRITE32(NFS4_OPEN_CREATE); | 1167 | *p = cpu_to_be32(NFS4_OPEN_CREATE); |
1193 | encode_createmode(xdr, arg); | 1168 | encode_createmode(xdr, arg); |
1194 | } | 1169 | } |
1195 | } | 1170 | } |
@@ -1198,16 +1173,16 @@ static inline void encode_delegation_type(struct xdr_stream *xdr, fmode_t delega | |||
1198 | { | 1173 | { |
1199 | __be32 *p; | 1174 | __be32 *p; |
1200 | 1175 | ||
1201 | RESERVE_SPACE(4); | 1176 | p = reserve_space(xdr, 4); |
1202 | switch (delegation_type) { | 1177 | switch (delegation_type) { |
1203 | case 0: | 1178 | case 0: |
1204 | WRITE32(NFS4_OPEN_DELEGATE_NONE); | 1179 | *p = cpu_to_be32(NFS4_OPEN_DELEGATE_NONE); |
1205 | break; | 1180 | break; |
1206 | case FMODE_READ: | 1181 | case FMODE_READ: |
1207 | WRITE32(NFS4_OPEN_DELEGATE_READ); | 1182 | *p = cpu_to_be32(NFS4_OPEN_DELEGATE_READ); |
1208 | break; | 1183 | break; |
1209 | case FMODE_WRITE|FMODE_READ: | 1184 | case FMODE_WRITE|FMODE_READ: |
1210 | WRITE32(NFS4_OPEN_DELEGATE_WRITE); | 1185 | *p = cpu_to_be32(NFS4_OPEN_DELEGATE_WRITE); |
1211 | break; | 1186 | break; |
1212 | default: | 1187 | default: |
1213 | BUG(); | 1188 | BUG(); |
@@ -1218,8 +1193,8 @@ static inline void encode_claim_null(struct xdr_stream *xdr, const struct qstr * | |||
1218 | { | 1193 | { |
1219 | __be32 *p; | 1194 | __be32 *p; |
1220 | 1195 | ||
1221 | RESERVE_SPACE(4); | 1196 | p = reserve_space(xdr, 4); |
1222 | WRITE32(NFS4_OPEN_CLAIM_NULL); | 1197 | *p = cpu_to_be32(NFS4_OPEN_CLAIM_NULL); |
1223 | encode_string(xdr, name->len, name->name); | 1198 | encode_string(xdr, name->len, name->name); |
1224 | } | 1199 | } |
1225 | 1200 | ||
@@ -1227,8 +1202,8 @@ static inline void encode_claim_previous(struct xdr_stream *xdr, fmode_t type) | |||
1227 | { | 1202 | { |
1228 | __be32 *p; | 1203 | __be32 *p; |
1229 | 1204 | ||
1230 | RESERVE_SPACE(4); | 1205 | p = reserve_space(xdr, 4); |
1231 | WRITE32(NFS4_OPEN_CLAIM_PREVIOUS); | 1206 | *p = cpu_to_be32(NFS4_OPEN_CLAIM_PREVIOUS); |
1232 | encode_delegation_type(xdr, type); | 1207 | encode_delegation_type(xdr, type); |
1233 | } | 1208 | } |
1234 | 1209 | ||
@@ -1236,9 +1211,9 @@ static inline void encode_claim_delegate_cur(struct xdr_stream *xdr, const struc | |||
1236 | { | 1211 | { |
1237 | __be32 *p; | 1212 | __be32 *p; |
1238 | 1213 | ||
1239 | RESERVE_SPACE(4+NFS4_STATEID_SIZE); | 1214 | p = reserve_space(xdr, 4+NFS4_STATEID_SIZE); |
1240 | WRITE32(NFS4_OPEN_CLAIM_DELEGATE_CUR); | 1215 | *p++ = cpu_to_be32(NFS4_OPEN_CLAIM_DELEGATE_CUR); |
1241 | WRITEMEM(stateid->data, NFS4_STATEID_SIZE); | 1216 | xdr_encode_opaque_fixed(p, stateid->data, NFS4_STATEID_SIZE); |
1242 | encode_string(xdr, name->len, name->name); | 1217 | encode_string(xdr, name->len, name->name); |
1243 | } | 1218 | } |
1244 | 1219 | ||
@@ -1267,10 +1242,10 @@ static void encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_co | |||
1267 | { | 1242 | { |
1268 | __be32 *p; | 1243 | __be32 *p; |
1269 | 1244 | ||
1270 | RESERVE_SPACE(4+NFS4_STATEID_SIZE+4); | 1245 | p = reserve_space(xdr, 4+NFS4_STATEID_SIZE+4); |
1271 | WRITE32(OP_OPEN_CONFIRM); | 1246 | *p++ = cpu_to_be32(OP_OPEN_CONFIRM); |
1272 | WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE); | 1247 | p = xdr_encode_opaque_fixed(p, arg->stateid->data, NFS4_STATEID_SIZE); |
1273 | WRITE32(arg->seqid->sequence->counter); | 1248 | *p = cpu_to_be32(arg->seqid->sequence->counter); |
1274 | hdr->nops++; | 1249 | hdr->nops++; |
1275 | hdr->replen += decode_open_confirm_maxsz; | 1250 | hdr->replen += decode_open_confirm_maxsz; |
1276 | } | 1251 | } |
@@ -1279,10 +1254,10 @@ static void encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_close | |||
1279 | { | 1254 | { |
1280 | __be32 *p; | 1255 | __be32 *p; |
1281 | 1256 | ||
1282 | RESERVE_SPACE(4+NFS4_STATEID_SIZE+4); | 1257 | p = reserve_space(xdr, 4+NFS4_STATEID_SIZE+4); |
1283 | WRITE32(OP_OPEN_DOWNGRADE); | 1258 | *p++ = cpu_to_be32(OP_OPEN_DOWNGRADE); |
1284 | WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE); | 1259 | p = xdr_encode_opaque_fixed(p, arg->stateid->data, NFS4_STATEID_SIZE); |
1285 | WRITE32(arg->seqid->sequence->counter); | 1260 | *p = cpu_to_be32(arg->seqid->sequence->counter); |
1286 | encode_share_access(xdr, arg->fmode); | 1261 | encode_share_access(xdr, arg->fmode); |
1287 | hdr->nops++; | 1262 | hdr->nops++; |
1288 | hdr->replen += decode_open_downgrade_maxsz; | 1263 | hdr->replen += decode_open_downgrade_maxsz; |
@@ -1294,10 +1269,9 @@ encode_putfh(struct xdr_stream *xdr, const struct nfs_fh *fh, struct compound_hd | |||
1294 | int len = fh->size; | 1269 | int len = fh->size; |
1295 | __be32 *p; | 1270 | __be32 *p; |
1296 | 1271 | ||
1297 | RESERVE_SPACE(8 + len); | 1272 | p = reserve_space(xdr, 8 + len); |
1298 | WRITE32(OP_PUTFH); | 1273 | *p++ = cpu_to_be32(OP_PUTFH); |
1299 | WRITE32(len); | 1274 | xdr_encode_opaque(p, fh->data, len); |
1300 | WRITEMEM(fh->data, len); | ||
1301 | hdr->nops++; | 1275 | hdr->nops++; |
1302 | hdr->replen += decode_putfh_maxsz; | 1276 | hdr->replen += decode_putfh_maxsz; |
1303 | } | 1277 | } |
@@ -1306,8 +1280,8 @@ static void encode_putrootfh(struct xdr_stream *xdr, struct compound_hdr *hdr) | |||
1306 | { | 1280 | { |
1307 | __be32 *p; | 1281 | __be32 *p; |
1308 | 1282 | ||
1309 | RESERVE_SPACE(4); | 1283 | p = reserve_space(xdr, 4); |
1310 | WRITE32(OP_PUTROOTFH); | 1284 | *p = cpu_to_be32(OP_PUTROOTFH); |
1311 | hdr->nops++; | 1285 | hdr->nops++; |
1312 | hdr->replen += decode_putrootfh_maxsz; | 1286 | hdr->replen += decode_putrootfh_maxsz; |
1313 | } | 1287 | } |
@@ -1317,26 +1291,26 @@ static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context | |||
1317 | nfs4_stateid stateid; | 1291 | nfs4_stateid stateid; |
1318 | __be32 *p; | 1292 | __be32 *p; |
1319 | 1293 | ||
1320 | RESERVE_SPACE(NFS4_STATEID_SIZE); | 1294 | p = reserve_space(xdr, NFS4_STATEID_SIZE); |
1321 | if (ctx->state != NULL) { | 1295 | if (ctx->state != NULL) { |
1322 | nfs4_copy_stateid(&stateid, ctx->state, ctx->lockowner); | 1296 | nfs4_copy_stateid(&stateid, ctx->state, ctx->lockowner); |
1323 | WRITEMEM(stateid.data, NFS4_STATEID_SIZE); | 1297 | xdr_encode_opaque_fixed(p, stateid.data, NFS4_STATEID_SIZE); |
1324 | } else | 1298 | } else |
1325 | WRITEMEM(zero_stateid.data, NFS4_STATEID_SIZE); | 1299 | xdr_encode_opaque_fixed(p, zero_stateid.data, NFS4_STATEID_SIZE); |
1326 | } | 1300 | } |
1327 | 1301 | ||
1328 | static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args, struct compound_hdr *hdr) | 1302 | static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args, struct compound_hdr *hdr) |
1329 | { | 1303 | { |
1330 | __be32 *p; | 1304 | __be32 *p; |
1331 | 1305 | ||
1332 | RESERVE_SPACE(4); | 1306 | p = reserve_space(xdr, 4); |
1333 | WRITE32(OP_READ); | 1307 | *p = cpu_to_be32(OP_READ); |
1334 | 1308 | ||
1335 | encode_stateid(xdr, args->context); | 1309 | encode_stateid(xdr, args->context); |
1336 | 1310 | ||
1337 | RESERVE_SPACE(12); | 1311 | p = reserve_space(xdr, 12); |
1338 | WRITE64(args->offset); | 1312 | p = xdr_encode_hyper(p, args->offset); |
1339 | WRITE32(args->count); | 1313 | *p = cpu_to_be32(args->count); |
1340 | hdr->nops++; | 1314 | hdr->nops++; |
1341 | hdr->replen += decode_read_maxsz; | 1315 | hdr->replen += decode_read_maxsz; |
1342 | } | 1316 | } |
@@ -1349,20 +1323,20 @@ static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg | |||
1349 | }; | 1323 | }; |
1350 | __be32 *p; | 1324 | __be32 *p; |
1351 | 1325 | ||
1352 | RESERVE_SPACE(12+NFS4_VERIFIER_SIZE+20); | 1326 | p = reserve_space(xdr, 12+NFS4_VERIFIER_SIZE+20); |
1353 | WRITE32(OP_READDIR); | 1327 | *p++ = cpu_to_be32(OP_READDIR); |
1354 | WRITE64(readdir->cookie); | 1328 | p = xdr_encode_hyper(p, readdir->cookie); |
1355 | WRITEMEM(readdir->verifier.data, NFS4_VERIFIER_SIZE); | 1329 | p = xdr_encode_opaque_fixed(p, readdir->verifier.data, NFS4_VERIFIER_SIZE); |
1356 | WRITE32(readdir->count >> 1); /* We're not doing readdirplus */ | 1330 | *p++ = cpu_to_be32(readdir->count >> 1); /* We're not doing readdirplus */ |
1357 | WRITE32(readdir->count); | 1331 | *p++ = cpu_to_be32(readdir->count); |
1358 | WRITE32(2); | 1332 | *p++ = cpu_to_be32(2); |
1359 | /* Switch to mounted_on_fileid if the server supports it */ | 1333 | /* Switch to mounted_on_fileid if the server supports it */ |
1360 | if (readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID) | 1334 | if (readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID) |
1361 | attrs[0] &= ~FATTR4_WORD0_FILEID; | 1335 | attrs[0] &= ~FATTR4_WORD0_FILEID; |
1362 | else | 1336 | else |
1363 | attrs[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; | 1337 | attrs[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; |
1364 | WRITE32(attrs[0] & readdir->bitmask[0]); | 1338 | *p++ = cpu_to_be32(attrs[0] & readdir->bitmask[0]); |
1365 | WRITE32(attrs[1] & readdir->bitmask[1]); | 1339 | *p = cpu_to_be32(attrs[1] & readdir->bitmask[1]); |
1366 | hdr->nops++; | 1340 | hdr->nops++; |
1367 | hdr->replen += decode_readdir_maxsz; | 1341 | hdr->replen += decode_readdir_maxsz; |
1368 | dprintk("%s: cookie = %Lu, verifier = %08x:%08x, bitmap = %08x:%08x\n", | 1342 | dprintk("%s: cookie = %Lu, verifier = %08x:%08x, bitmap = %08x:%08x\n", |
@@ -1378,8 +1352,8 @@ static void encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink * | |||
1378 | { | 1352 | { |
1379 | __be32 *p; | 1353 | __be32 *p; |
1380 | 1354 | ||
1381 | RESERVE_SPACE(4); | 1355 | p = reserve_space(xdr, 4); |
1382 | WRITE32(OP_READLINK); | 1356 | *p = cpu_to_be32(OP_READLINK); |
1383 | hdr->nops++; | 1357 | hdr->nops++; |
1384 | hdr->replen += decode_readlink_maxsz; | 1358 | hdr->replen += decode_readlink_maxsz; |
1385 | } | 1359 | } |
@@ -1388,10 +1362,9 @@ static void encode_remove(struct xdr_stream *xdr, const struct qstr *name, struc | |||
1388 | { | 1362 | { |
1389 | __be32 *p; | 1363 | __be32 *p; |
1390 | 1364 | ||
1391 | RESERVE_SPACE(8 + name->len); | 1365 | p = reserve_space(xdr, 8 + name->len); |
1392 | WRITE32(OP_REMOVE); | 1366 | *p++ = cpu_to_be32(OP_REMOVE); |
1393 | WRITE32(name->len); | 1367 | xdr_encode_opaque(p, name->name, name->len); |
1394 | WRITEMEM(name->name, name->len); | ||
1395 | hdr->nops++; | 1368 | hdr->nops++; |
1396 | hdr->replen += decode_remove_maxsz; | 1369 | hdr->replen += decode_remove_maxsz; |
1397 | } | 1370 | } |
@@ -1400,14 +1373,10 @@ static void encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, co | |||
1400 | { | 1373 | { |
1401 | __be32 *p; | 1374 | __be32 *p; |
1402 | 1375 | ||
1403 | RESERVE_SPACE(8 + oldname->len); | 1376 | p = reserve_space(xdr, 4); |
1404 | WRITE32(OP_RENAME); | 1377 | *p = cpu_to_be32(OP_RENAME); |
1405 | WRITE32(oldname->len); | 1378 | encode_string(xdr, oldname->len, oldname->name); |
1406 | WRITEMEM(oldname->name, oldname->len); | 1379 | encode_string(xdr, newname->len, newname->name); |
1407 | |||
1408 | RESERVE_SPACE(4 + newname->len); | ||
1409 | WRITE32(newname->len); | ||
1410 | WRITEMEM(newname->name, newname->len); | ||
1411 | hdr->nops++; | 1380 | hdr->nops++; |
1412 | hdr->replen += decode_rename_maxsz; | 1381 | hdr->replen += decode_rename_maxsz; |
1413 | } | 1382 | } |
@@ -1416,9 +1385,9 @@ static void encode_renew(struct xdr_stream *xdr, const struct nfs_client *client | |||
1416 | { | 1385 | { |
1417 | __be32 *p; | 1386 | __be32 *p; |
1418 | 1387 | ||
1419 | RESERVE_SPACE(12); | 1388 | p = reserve_space(xdr, 12); |
1420 | WRITE32(OP_RENEW); | 1389 | *p++ = cpu_to_be32(OP_RENEW); |
1421 | WRITE64(client_stateid->cl_clientid); | 1390 | xdr_encode_hyper(p, client_stateid->cl_clientid); |
1422 | hdr->nops++; | 1391 | hdr->nops++; |
1423 | hdr->replen += decode_renew_maxsz; | 1392 | hdr->replen += decode_renew_maxsz; |
1424 | } | 1393 | } |
@@ -1428,8 +1397,8 @@ encode_restorefh(struct xdr_stream *xdr, struct compound_hdr *hdr) | |||
1428 | { | 1397 | { |
1429 | __be32 *p; | 1398 | __be32 *p; |
1430 | 1399 | ||
1431 | RESERVE_SPACE(4); | 1400 | p = reserve_space(xdr, 4); |
1432 | WRITE32(OP_RESTOREFH); | 1401 | *p = cpu_to_be32(OP_RESTOREFH); |
1433 | hdr->nops++; | 1402 | hdr->nops++; |
1434 | hdr->replen += decode_restorefh_maxsz; | 1403 | hdr->replen += decode_restorefh_maxsz; |
1435 | } | 1404 | } |
@@ -1439,16 +1408,16 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compoun | |||
1439 | { | 1408 | { |
1440 | __be32 *p; | 1409 | __be32 *p; |
1441 | 1410 | ||
1442 | RESERVE_SPACE(4+NFS4_STATEID_SIZE); | 1411 | p = reserve_space(xdr, 4+NFS4_STATEID_SIZE); |
1443 | WRITE32(OP_SETATTR); | 1412 | *p++ = cpu_to_be32(OP_SETATTR); |
1444 | WRITEMEM(zero_stateid.data, NFS4_STATEID_SIZE); | 1413 | xdr_encode_opaque_fixed(p, zero_stateid.data, NFS4_STATEID_SIZE); |
1445 | RESERVE_SPACE(2*4); | 1414 | p = reserve_space(xdr, 2*4); |
1446 | WRITE32(1); | 1415 | *p++ = cpu_to_be32(1); |
1447 | WRITE32(FATTR4_WORD0_ACL); | 1416 | *p = cpu_to_be32(FATTR4_WORD0_ACL); |
1448 | if (arg->acl_len % 4) | 1417 | if (arg->acl_len % 4) |
1449 | return -EINVAL; | 1418 | return -EINVAL; |
1450 | RESERVE_SPACE(4); | 1419 | p = reserve_space(xdr, 4); |
1451 | WRITE32(arg->acl_len); | 1420 | *p = cpu_to_be32(arg->acl_len); |
1452 | xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len); | 1421 | xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len); |
1453 | hdr->nops++; | 1422 | hdr->nops++; |
1454 | hdr->replen += decode_setacl_maxsz; | 1423 | hdr->replen += decode_setacl_maxsz; |
@@ -1460,8 +1429,8 @@ encode_savefh(struct xdr_stream *xdr, struct compound_hdr *hdr) | |||
1460 | { | 1429 | { |
1461 | __be32 *p; | 1430 | __be32 *p; |
1462 | 1431 | ||
1463 | RESERVE_SPACE(4); | 1432 | p = reserve_space(xdr, 4); |
1464 | WRITE32(OP_SAVEFH); | 1433 | *p = cpu_to_be32(OP_SAVEFH); |
1465 | hdr->nops++; | 1434 | hdr->nops++; |
1466 | hdr->replen += decode_savefh_maxsz; | 1435 | hdr->replen += decode_savefh_maxsz; |
1467 | } | 1436 | } |
@@ -1470,9 +1439,9 @@ static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs | |||
1470 | { | 1439 | { |
1471 | __be32 *p; | 1440 | __be32 *p; |
1472 | 1441 | ||
1473 | RESERVE_SPACE(4+NFS4_STATEID_SIZE); | 1442 | p = reserve_space(xdr, 4+NFS4_STATEID_SIZE); |
1474 | WRITE32(OP_SETATTR); | 1443 | *p++ = cpu_to_be32(OP_SETATTR); |
1475 | WRITEMEM(arg->stateid.data, NFS4_STATEID_SIZE); | 1444 | xdr_encode_opaque_fixed(p, arg->stateid.data, NFS4_STATEID_SIZE); |
1476 | hdr->nops++; | 1445 | hdr->nops++; |
1477 | hdr->replen += decode_setattr_maxsz; | 1446 | hdr->replen += decode_setattr_maxsz; |
1478 | encode_attrs(xdr, arg->iap, server); | 1447 | encode_attrs(xdr, arg->iap, server); |
@@ -1482,17 +1451,17 @@ static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclie | |||
1482 | { | 1451 | { |
1483 | __be32 *p; | 1452 | __be32 *p; |
1484 | 1453 | ||
1485 | RESERVE_SPACE(4 + NFS4_VERIFIER_SIZE); | 1454 | p = reserve_space(xdr, 4 + NFS4_VERIFIER_SIZE); |
1486 | WRITE32(OP_SETCLIENTID); | 1455 | *p++ = cpu_to_be32(OP_SETCLIENTID); |
1487 | WRITEMEM(setclientid->sc_verifier->data, NFS4_VERIFIER_SIZE); | 1456 | xdr_encode_opaque_fixed(p, setclientid->sc_verifier->data, NFS4_VERIFIER_SIZE); |
1488 | 1457 | ||
1489 | encode_string(xdr, setclientid->sc_name_len, setclientid->sc_name); | 1458 | encode_string(xdr, setclientid->sc_name_len, setclientid->sc_name); |
1490 | RESERVE_SPACE(4); | 1459 | p = reserve_space(xdr, 4); |
1491 | WRITE32(setclientid->sc_prog); | 1460 | *p = cpu_to_be32(setclientid->sc_prog); |
1492 | encode_string(xdr, setclientid->sc_netid_len, setclientid->sc_netid); | 1461 | encode_string(xdr, setclientid->sc_netid_len, setclientid->sc_netid); |
1493 | encode_string(xdr, setclientid->sc_uaddr_len, setclientid->sc_uaddr); | 1462 | encode_string(xdr, setclientid->sc_uaddr_len, setclientid->sc_uaddr); |
1494 | RESERVE_SPACE(4); | 1463 | p = reserve_space(xdr, 4); |
1495 | WRITE32(setclientid->sc_cb_ident); | 1464 | *p = cpu_to_be32(setclientid->sc_cb_ident); |
1496 | hdr->nops++; | 1465 | hdr->nops++; |
1497 | hdr->replen += decode_setclientid_maxsz; | 1466 | hdr->replen += decode_setclientid_maxsz; |
1498 | } | 1467 | } |
@@ -1501,10 +1470,10 @@ static void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_ | |||
1501 | { | 1470 | { |
1502 | __be32 *p; | 1471 | __be32 *p; |
1503 | 1472 | ||
1504 | RESERVE_SPACE(12 + NFS4_VERIFIER_SIZE); | 1473 | p = reserve_space(xdr, 12 + NFS4_VERIFIER_SIZE); |
1505 | WRITE32(OP_SETCLIENTID_CONFIRM); | 1474 | *p++ = cpu_to_be32(OP_SETCLIENTID_CONFIRM); |
1506 | WRITE64(client_state->cl_clientid); | 1475 | p = xdr_encode_hyper(p, client_state->cl_clientid); |
1507 | WRITEMEM(client_state->cl_confirm.data, NFS4_VERIFIER_SIZE); | 1476 | xdr_encode_opaque_fixed(p, client_state->cl_confirm.data, NFS4_VERIFIER_SIZE); |
1508 | hdr->nops++; | 1477 | hdr->nops++; |
1509 | hdr->replen += decode_setclientid_confirm_maxsz; | 1478 | hdr->replen += decode_setclientid_confirm_maxsz; |
1510 | } | 1479 | } |
@@ -1513,15 +1482,15 @@ static void encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *arg | |||
1513 | { | 1482 | { |
1514 | __be32 *p; | 1483 | __be32 *p; |
1515 | 1484 | ||
1516 | RESERVE_SPACE(4); | 1485 | p = reserve_space(xdr, 4); |
1517 | WRITE32(OP_WRITE); | 1486 | *p = cpu_to_be32(OP_WRITE); |
1518 | 1487 | ||
1519 | encode_stateid(xdr, args->context); | 1488 | encode_stateid(xdr, args->context); |
1520 | 1489 | ||
1521 | RESERVE_SPACE(16); | 1490 | p = reserve_space(xdr, 16); |
1522 | WRITE64(args->offset); | 1491 | p = xdr_encode_hyper(p, args->offset); |
1523 | WRITE32(args->stable); | 1492 | *p++ = cpu_to_be32(args->stable); |
1524 | WRITE32(args->count); | 1493 | *p = cpu_to_be32(args->count); |
1525 | 1494 | ||
1526 | xdr_write_pages(xdr, args->pages, args->pgbase, args->count); | 1495 | xdr_write_pages(xdr, args->pages, args->pgbase, args->count); |
1527 | hdr->nops++; | 1496 | hdr->nops++; |
@@ -1532,10 +1501,10 @@ static void encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *state | |||
1532 | { | 1501 | { |
1533 | __be32 *p; | 1502 | __be32 *p; |
1534 | 1503 | ||
1535 | RESERVE_SPACE(4+NFS4_STATEID_SIZE); | 1504 | p = reserve_space(xdr, 4+NFS4_STATEID_SIZE); |
1536 | 1505 | ||
1537 | WRITE32(OP_DELEGRETURN); | 1506 | *p++ = cpu_to_be32(OP_DELEGRETURN); |
1538 | WRITEMEM(stateid->data, NFS4_STATEID_SIZE); | 1507 | xdr_encode_opaque_fixed(p, stateid->data, NFS4_STATEID_SIZE); |
1539 | hdr->nops++; | 1508 | hdr->nops++; |
1540 | hdr->replen += decode_delegreturn_maxsz; | 1509 | hdr->replen += decode_delegreturn_maxsz; |
1541 | } | 1510 | } |
@@ -1548,16 +1517,16 @@ static void encode_exchange_id(struct xdr_stream *xdr, | |||
1548 | { | 1517 | { |
1549 | __be32 *p; | 1518 | __be32 *p; |
1550 | 1519 | ||
1551 | RESERVE_SPACE(4 + sizeof(args->verifier->data)); | 1520 | p = reserve_space(xdr, 4 + sizeof(args->verifier->data)); |
1552 | WRITE32(OP_EXCHANGE_ID); | 1521 | *p++ = cpu_to_be32(OP_EXCHANGE_ID); |
1553 | WRITEMEM(args->verifier->data, sizeof(args->verifier->data)); | 1522 | xdr_encode_opaque_fixed(p, args->verifier->data, sizeof(args->verifier->data)); |
1554 | 1523 | ||
1555 | encode_string(xdr, args->id_len, args->id); | 1524 | encode_string(xdr, args->id_len, args->id); |
1556 | 1525 | ||
1557 | RESERVE_SPACE(12); | 1526 | p = reserve_space(xdr, 12); |
1558 | WRITE32(args->flags); | 1527 | *p++ = cpu_to_be32(args->flags); |
1559 | WRITE32(0); /* zero length state_protect4_a */ | 1528 | *p++ = cpu_to_be32(0); /* zero length state_protect4_a */ |
1560 | WRITE32(0); /* zero length implementation id array */ | 1529 | *p = cpu_to_be32(0); /* zero length implementation id array */ |
1561 | hdr->nops++; | 1530 | hdr->nops++; |
1562 | hdr->replen += decode_exchange_id_maxsz; | 1531 | hdr->replen += decode_exchange_id_maxsz; |
1563 | } | 1532 | } |
@@ -1571,55 +1540,43 @@ static void encode_create_session(struct xdr_stream *xdr, | |||
1571 | uint32_t len; | 1540 | uint32_t len; |
1572 | struct nfs_client *clp = args->client; | 1541 | struct nfs_client *clp = args->client; |
1573 | 1542 | ||
1574 | RESERVE_SPACE(4); | 1543 | len = scnprintf(machine_name, sizeof(machine_name), "%s", |
1575 | WRITE32(OP_CREATE_SESSION); | 1544 | clp->cl_ipaddr); |
1576 | |||
1577 | RESERVE_SPACE(8); | ||
1578 | WRITE64(clp->cl_ex_clid); | ||
1579 | 1545 | ||
1580 | RESERVE_SPACE(8); | 1546 | p = reserve_space(xdr, 20 + 2*28 + 20 + len + 12); |
1581 | WRITE32(clp->cl_seqid); /*Sequence id */ | 1547 | *p++ = cpu_to_be32(OP_CREATE_SESSION); |
1582 | WRITE32(args->flags); /*flags */ | 1548 | p = xdr_encode_hyper(p, clp->cl_ex_clid); |
1549 | *p++ = cpu_to_be32(clp->cl_seqid); /*Sequence id */ | ||
1550 | *p++ = cpu_to_be32(args->flags); /*flags */ | ||
1583 | 1551 | ||
1584 | RESERVE_SPACE(2*28); /* 2 channel_attrs */ | ||
1585 | /* Fore Channel */ | 1552 | /* Fore Channel */ |
1586 | WRITE32(args->fc_attrs.headerpadsz); /* header padding size */ | 1553 | *p++ = cpu_to_be32(args->fc_attrs.headerpadsz); /* header padding size */ |
1587 | WRITE32(args->fc_attrs.max_rqst_sz); /* max req size */ | 1554 | *p++ = cpu_to_be32(args->fc_attrs.max_rqst_sz); /* max req size */ |
1588 | WRITE32(args->fc_attrs.max_resp_sz); /* max resp size */ | 1555 | *p++ = cpu_to_be32(args->fc_attrs.max_resp_sz); /* max resp size */ |
1589 | WRITE32(args->fc_attrs.max_resp_sz_cached); /* Max resp sz cached */ | 1556 | *p++ = cpu_to_be32(args->fc_attrs.max_resp_sz_cached); /* Max resp sz cached */ |
1590 | WRITE32(args->fc_attrs.max_ops); /* max operations */ | 1557 | *p++ = cpu_to_be32(args->fc_attrs.max_ops); /* max operations */ |
1591 | WRITE32(args->fc_attrs.max_reqs); /* max requests */ | 1558 | *p++ = cpu_to_be32(args->fc_attrs.max_reqs); /* max requests */ |
1592 | WRITE32(0); /* rdmachannel_attrs */ | 1559 | *p++ = cpu_to_be32(0); /* rdmachannel_attrs */ |
1593 | 1560 | ||
1594 | /* Back Channel */ | 1561 | /* Back Channel */ |
1595 | WRITE32(args->fc_attrs.headerpadsz); /* header padding size */ | 1562 | *p++ = cpu_to_be32(args->fc_attrs.headerpadsz); /* header padding size */ |
1596 | WRITE32(args->bc_attrs.max_rqst_sz); /* max req size */ | 1563 | *p++ = cpu_to_be32(args->bc_attrs.max_rqst_sz); /* max req size */ |
1597 | WRITE32(args->bc_attrs.max_resp_sz); /* max resp size */ | 1564 | *p++ = cpu_to_be32(args->bc_attrs.max_resp_sz); /* max resp size */ |
1598 | WRITE32(args->bc_attrs.max_resp_sz_cached); /* Max resp sz cached */ | 1565 | *p++ = cpu_to_be32(args->bc_attrs.max_resp_sz_cached); /* Max resp sz cached */ |
1599 | WRITE32(args->bc_attrs.max_ops); /* max operations */ | 1566 | *p++ = cpu_to_be32(args->bc_attrs.max_ops); /* max operations */ |
1600 | WRITE32(args->bc_attrs.max_reqs); /* max requests */ | 1567 | *p++ = cpu_to_be32(args->bc_attrs.max_reqs); /* max requests */ |
1601 | WRITE32(0); /* rdmachannel_attrs */ | 1568 | *p++ = cpu_to_be32(0); /* rdmachannel_attrs */ |
1602 | 1569 | ||
1603 | RESERVE_SPACE(4); | 1570 | *p++ = cpu_to_be32(args->cb_program); /* cb_program */ |
1604 | WRITE32(args->cb_program); /* cb_program */ | 1571 | *p++ = cpu_to_be32(1); |
1605 | 1572 | *p++ = cpu_to_be32(RPC_AUTH_UNIX); /* auth_sys */ | |
1606 | RESERVE_SPACE(4); /* # of security flavors */ | ||
1607 | WRITE32(1); | ||
1608 | |||
1609 | RESERVE_SPACE(4); | ||
1610 | WRITE32(RPC_AUTH_UNIX); /* auth_sys */ | ||
1611 | 1573 | ||
1612 | /* authsys_parms rfc1831 */ | 1574 | /* authsys_parms rfc1831 */ |
1613 | RESERVE_SPACE(4); | 1575 | *p++ = cpu_to_be32((u32)clp->cl_boot_time.tv_nsec); /* stamp */ |
1614 | WRITE32((u32)clp->cl_boot_time.tv_nsec); /* stamp */ | 1576 | p = xdr_encode_opaque(p, machine_name, len); |
1615 | len = scnprintf(machine_name, sizeof(machine_name), "%s", | 1577 | *p++ = cpu_to_be32(0); /* UID */ |
1616 | clp->cl_ipaddr); | 1578 | *p++ = cpu_to_be32(0); /* GID */ |
1617 | RESERVE_SPACE(16 + len); | 1579 | *p = cpu_to_be32(0); /* No more gids */ |
1618 | WRITE32(len); | ||
1619 | WRITEMEM(machine_name, len); | ||
1620 | WRITE32(0); /* UID */ | ||
1621 | WRITE32(0); /* GID */ | ||
1622 | WRITE32(0); /* No more gids */ | ||
1623 | hdr->nops++; | 1580 | hdr->nops++; |
1624 | hdr->replen += decode_create_session_maxsz; | 1581 | hdr->replen += decode_create_session_maxsz; |
1625 | } | 1582 | } |
@@ -1629,9 +1586,9 @@ static void encode_destroy_session(struct xdr_stream *xdr, | |||
1629 | struct compound_hdr *hdr) | 1586 | struct compound_hdr *hdr) |
1630 | { | 1587 | { |
1631 | __be32 *p; | 1588 | __be32 *p; |
1632 | RESERVE_SPACE(4 + NFS4_MAX_SESSIONID_LEN); | 1589 | p = reserve_space(xdr, 4 + NFS4_MAX_SESSIONID_LEN); |
1633 | WRITE32(OP_DESTROY_SESSION); | 1590 | *p++ = cpu_to_be32(OP_DESTROY_SESSION); |
1634 | WRITEMEM(session->sess_id.data, NFS4_MAX_SESSIONID_LEN); | 1591 | xdr_encode_opaque_fixed(p, session->sess_id.data, NFS4_MAX_SESSIONID_LEN); |
1635 | hdr->nops++; | 1592 | hdr->nops++; |
1636 | hdr->replen += decode_destroy_session_maxsz; | 1593 | hdr->replen += decode_destroy_session_maxsz; |
1637 | } | 1594 | } |
@@ -1655,8 +1612,8 @@ static void encode_sequence(struct xdr_stream *xdr, | |||
1655 | WARN_ON(args->sa_slotid == NFS4_MAX_SLOT_TABLE); | 1612 | WARN_ON(args->sa_slotid == NFS4_MAX_SLOT_TABLE); |
1656 | slot = tp->slots + args->sa_slotid; | 1613 | slot = tp->slots + args->sa_slotid; |
1657 | 1614 | ||
1658 | RESERVE_SPACE(4); | 1615 | p = reserve_space(xdr, 4 + NFS4_MAX_SESSIONID_LEN + 16); |
1659 | WRITE32(OP_SEQUENCE); | 1616 | *p++ = cpu_to_be32(OP_SEQUENCE); |
1660 | 1617 | ||
1661 | /* | 1618 | /* |
1662 | * Sessionid + seqid + slotid + max slotid + cache_this | 1619 | * Sessionid + seqid + slotid + max slotid + cache_this |
@@ -1670,12 +1627,11 @@ static void encode_sequence(struct xdr_stream *xdr, | |||
1670 | ((u32 *)session->sess_id.data)[3], | 1627 | ((u32 *)session->sess_id.data)[3], |
1671 | slot->seq_nr, args->sa_slotid, | 1628 | slot->seq_nr, args->sa_slotid, |
1672 | tp->highest_used_slotid, args->sa_cache_this); | 1629 | tp->highest_used_slotid, args->sa_cache_this); |
1673 | RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 16); | 1630 | p = xdr_encode_opaque_fixed(p, session->sess_id.data, NFS4_MAX_SESSIONID_LEN); |
1674 | WRITEMEM(session->sess_id.data, NFS4_MAX_SESSIONID_LEN); | 1631 | *p++ = cpu_to_be32(slot->seq_nr); |
1675 | WRITE32(slot->seq_nr); | 1632 | *p++ = cpu_to_be32(args->sa_slotid); |
1676 | WRITE32(args->sa_slotid); | 1633 | *p++ = cpu_to_be32(tp->highest_used_slotid); |
1677 | WRITE32(tp->highest_used_slotid); | 1634 | *p = cpu_to_be32(args->sa_cache_this); |
1678 | WRITE32(args->sa_cache_this); | ||
1679 | hdr->nops++; | 1635 | hdr->nops++; |
1680 | hdr->replen += decode_sequence_maxsz; | 1636 | hdr->replen += decode_sequence_maxsz; |
1681 | #endif /* CONFIG_NFS_V4_1 */ | 1637 | #endif /* CONFIG_NFS_V4_1 */ |
@@ -2466,68 +2422,53 @@ static int nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req, uint32_t *p, | |||
2466 | } | 2422 | } |
2467 | #endif /* CONFIG_NFS_V4_1 */ | 2423 | #endif /* CONFIG_NFS_V4_1 */ |
2468 | 2424 | ||
2469 | /* | 2425 | static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) |
2470 | * START OF "GENERIC" DECODE ROUTINES. | 2426 | { |
2471 | * These may look a little ugly since they are imported from a "generic" | 2427 | dprintk("nfs: %s: prematurely hit end of receive buffer. " |
2472 | * set of XDR encode/decode routines which are intended to be shared by | 2428 | "Remaining buffer length is %tu words.\n", |
2473 | * all of our NFSv4 implementations (OpenBSD, MacOS X...). | 2429 | func, xdr->end - xdr->p); |
2474 | * | 2430 | } |
2475 | * If the pain of reading these is too great, it should be a straightforward | ||
2476 | * task to translate them into Linux-specific versions which are more | ||
2477 | * consistent with the style used in NFSv2/v3... | ||
2478 | */ | ||
2479 | #define READ32(x) (x) = ntohl(*p++) | ||
2480 | #define READ64(x) do { \ | ||
2481 | (x) = (u64)ntohl(*p++) << 32; \ | ||
2482 | (x) |= ntohl(*p++); \ | ||
2483 | } while (0) | ||
2484 | #define READTIME(x) do { \ | ||
2485 | p++; \ | ||
2486 | (x.tv_sec) = ntohl(*p++); \ | ||
2487 | (x.tv_nsec) = ntohl(*p++); \ | ||
2488 | } while (0) | ||
2489 | #define COPYMEM(x,nbytes) do { \ | ||
2490 | memcpy((x), p, nbytes); \ | ||
2491 | p += XDR_QUADLEN(nbytes); \ | ||
2492 | } while (0) | ||
2493 | |||
2494 | #define READ_BUF(nbytes) do { \ | ||
2495 | p = xdr_inline_decode(xdr, nbytes); \ | ||
2496 | if (unlikely(!p)) { \ | ||
2497 | dprintk("nfs: %s: prematurely hit end of receive" \ | ||
2498 | " buffer\n", __func__); \ | ||
2499 | dprintk("nfs: %s: xdr->p=%p, bytes=%u, xdr->end=%p\n", \ | ||
2500 | __func__, xdr->p, nbytes, xdr->end); \ | ||
2501 | return -EIO; \ | ||
2502 | } \ | ||
2503 | } while (0) | ||
2504 | 2431 | ||
2505 | static int decode_opaque_inline(struct xdr_stream *xdr, unsigned int *len, char **string) | 2432 | static int decode_opaque_inline(struct xdr_stream *xdr, unsigned int *len, char **string) |
2506 | { | 2433 | { |
2507 | __be32 *p; | 2434 | __be32 *p; |
2508 | 2435 | ||
2509 | READ_BUF(4); | 2436 | p = xdr_inline_decode(xdr, 4); |
2510 | READ32(*len); | 2437 | if (unlikely(!p)) |
2511 | READ_BUF(*len); | 2438 | goto out_overflow; |
2439 | *len = be32_to_cpup(p); | ||
2440 | p = xdr_inline_decode(xdr, *len); | ||
2441 | if (unlikely(!p)) | ||
2442 | goto out_overflow; | ||
2512 | *string = (char *)p; | 2443 | *string = (char *)p; |
2513 | return 0; | 2444 | return 0; |
2445 | out_overflow: | ||
2446 | print_overflow_msg(__func__, xdr); | ||
2447 | return -EIO; | ||
2514 | } | 2448 | } |
2515 | 2449 | ||
2516 | static int decode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr) | 2450 | static int decode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr) |
2517 | { | 2451 | { |
2518 | __be32 *p; | 2452 | __be32 *p; |
2519 | 2453 | ||
2520 | READ_BUF(8); | 2454 | p = xdr_inline_decode(xdr, 8); |
2521 | READ32(hdr->status); | 2455 | if (unlikely(!p)) |
2522 | READ32(hdr->taglen); | 2456 | goto out_overflow; |
2457 | hdr->status = be32_to_cpup(p++); | ||
2458 | hdr->taglen = be32_to_cpup(p); | ||
2523 | 2459 | ||
2524 | READ_BUF(hdr->taglen + 4); | 2460 | p = xdr_inline_decode(xdr, hdr->taglen + 4); |
2461 | if (unlikely(!p)) | ||
2462 | goto out_overflow; | ||
2525 | hdr->tag = (char *)p; | 2463 | hdr->tag = (char *)p; |
2526 | p += XDR_QUADLEN(hdr->taglen); | 2464 | p += XDR_QUADLEN(hdr->taglen); |
2527 | READ32(hdr->nops); | 2465 | hdr->nops = be32_to_cpup(p); |
2528 | if (unlikely(hdr->nops < 1)) | 2466 | if (unlikely(hdr->nops < 1)) |
2529 | return nfs4_stat_to_errno(hdr->status); | 2467 | return nfs4_stat_to_errno(hdr->status); |
2530 | return 0; | 2468 | return 0; |
2469 | out_overflow: | ||
2470 | print_overflow_msg(__func__, xdr); | ||
2471 | return -EIO; | ||
2531 | } | 2472 | } |
2532 | 2473 | ||
2533 | static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) | 2474 | static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) |
@@ -2536,18 +2477,23 @@ static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) | |||
2536 | uint32_t opnum; | 2477 | uint32_t opnum; |
2537 | int32_t nfserr; | 2478 | int32_t nfserr; |
2538 | 2479 | ||
2539 | READ_BUF(8); | 2480 | p = xdr_inline_decode(xdr, 8); |
2540 | READ32(opnum); | 2481 | if (unlikely(!p)) |
2482 | goto out_overflow; | ||
2483 | opnum = be32_to_cpup(p++); | ||
2541 | if (opnum != expected) { | 2484 | if (opnum != expected) { |
2542 | dprintk("nfs: Server returned operation" | 2485 | dprintk("nfs: Server returned operation" |
2543 | " %d but we issued a request for %d\n", | 2486 | " %d but we issued a request for %d\n", |
2544 | opnum, expected); | 2487 | opnum, expected); |
2545 | return -EIO; | 2488 | return -EIO; |
2546 | } | 2489 | } |
2547 | READ32(nfserr); | 2490 | nfserr = be32_to_cpup(p); |
2548 | if (nfserr != NFS_OK) | 2491 | if (nfserr != NFS_OK) |
2549 | return nfs4_stat_to_errno(nfserr); | 2492 | return nfs4_stat_to_errno(nfserr); |
2550 | return 0; | 2493 | return 0; |
2494 | out_overflow: | ||
2495 | print_overflow_msg(__func__, xdr); | ||
2496 | return -EIO; | ||
2551 | } | 2497 | } |
2552 | 2498 | ||
2553 | /* Dummy routine */ | 2499 | /* Dummy routine */ |
@@ -2557,8 +2503,11 @@ static int decode_ace(struct xdr_stream *xdr, void *ace, struct nfs_client *clp) | |||
2557 | unsigned int strlen; | 2503 | unsigned int strlen; |
2558 | char *str; | 2504 | char *str; |
2559 | 2505 | ||
2560 | READ_BUF(12); | 2506 | p = xdr_inline_decode(xdr, 12); |
2561 | return decode_opaque_inline(xdr, &strlen, &str); | 2507 | if (likely(p)) |
2508 | return decode_opaque_inline(xdr, &strlen, &str); | ||
2509 | print_overflow_msg(__func__, xdr); | ||
2510 | return -EIO; | ||
2562 | } | 2511 | } |
2563 | 2512 | ||
2564 | static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) | 2513 | static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) |
@@ -2566,27 +2515,39 @@ static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) | |||
2566 | uint32_t bmlen; | 2515 | uint32_t bmlen; |
2567 | __be32 *p; | 2516 | __be32 *p; |
2568 | 2517 | ||
2569 | READ_BUF(4); | 2518 | p = xdr_inline_decode(xdr, 4); |
2570 | READ32(bmlen); | 2519 | if (unlikely(!p)) |
2520 | goto out_overflow; | ||
2521 | bmlen = be32_to_cpup(p); | ||
2571 | 2522 | ||
2572 | bitmap[0] = bitmap[1] = 0; | 2523 | bitmap[0] = bitmap[1] = 0; |
2573 | READ_BUF((bmlen << 2)); | 2524 | p = xdr_inline_decode(xdr, (bmlen << 2)); |
2525 | if (unlikely(!p)) | ||
2526 | goto out_overflow; | ||
2574 | if (bmlen > 0) { | 2527 | if (bmlen > 0) { |
2575 | READ32(bitmap[0]); | 2528 | bitmap[0] = be32_to_cpup(p++); |
2576 | if (bmlen > 1) | 2529 | if (bmlen > 1) |
2577 | READ32(bitmap[1]); | 2530 | bitmap[1] = be32_to_cpup(p); |
2578 | } | 2531 | } |
2579 | return 0; | 2532 | return 0; |
2533 | out_overflow: | ||
2534 | print_overflow_msg(__func__, xdr); | ||
2535 | return -EIO; | ||
2580 | } | 2536 | } |
2581 | 2537 | ||
2582 | static inline int decode_attr_length(struct xdr_stream *xdr, uint32_t *attrlen, __be32 **savep) | 2538 | static inline int decode_attr_length(struct xdr_stream *xdr, uint32_t *attrlen, __be32 **savep) |
2583 | { | 2539 | { |
2584 | __be32 *p; | 2540 | __be32 *p; |
2585 | 2541 | ||
2586 | READ_BUF(4); | 2542 | p = xdr_inline_decode(xdr, 4); |
2587 | READ32(*attrlen); | 2543 | if (unlikely(!p)) |
2544 | goto out_overflow; | ||
2545 | *attrlen = be32_to_cpup(p); | ||
2588 | *savep = xdr->p; | 2546 | *savep = xdr->p; |
2589 | return 0; | 2547 | return 0; |
2548 | out_overflow: | ||
2549 | print_overflow_msg(__func__, xdr); | ||
2550 | return -EIO; | ||
2590 | } | 2551 | } |
2591 | 2552 | ||
2592 | static int decode_attr_supported(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *bitmask) | 2553 | static int decode_attr_supported(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *bitmask) |
@@ -2609,8 +2570,10 @@ static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t * | |||
2609 | if (unlikely(bitmap[0] & (FATTR4_WORD0_TYPE - 1U))) | 2570 | if (unlikely(bitmap[0] & (FATTR4_WORD0_TYPE - 1U))) |
2610 | return -EIO; | 2571 | return -EIO; |
2611 | if (likely(bitmap[0] & FATTR4_WORD0_TYPE)) { | 2572 | if (likely(bitmap[0] & FATTR4_WORD0_TYPE)) { |
2612 | READ_BUF(4); | 2573 | p = xdr_inline_decode(xdr, 4); |
2613 | READ32(*type); | 2574 | if (unlikely(!p)) |
2575 | goto out_overflow; | ||
2576 | *type = be32_to_cpup(p); | ||
2614 | if (*type < NF4REG || *type > NF4NAMEDATTR) { | 2577 | if (*type < NF4REG || *type > NF4NAMEDATTR) { |
2615 | dprintk("%s: bad type %d\n", __func__, *type); | 2578 | dprintk("%s: bad type %d\n", __func__, *type); |
2616 | return -EIO; | 2579 | return -EIO; |
@@ -2620,6 +2583,9 @@ static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t * | |||
2620 | } | 2583 | } |
2621 | dprintk("%s: type=0%o\n", __func__, nfs_type2fmt[*type]); | 2584 | dprintk("%s: type=0%o\n", __func__, nfs_type2fmt[*type]); |
2622 | return ret; | 2585 | return ret; |
2586 | out_overflow: | ||
2587 | print_overflow_msg(__func__, xdr); | ||
2588 | return -EIO; | ||
2623 | } | 2589 | } |
2624 | 2590 | ||
2625 | static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *change) | 2591 | static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *change) |
@@ -2631,14 +2597,19 @@ static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t | |||
2631 | if (unlikely(bitmap[0] & (FATTR4_WORD0_CHANGE - 1U))) | 2597 | if (unlikely(bitmap[0] & (FATTR4_WORD0_CHANGE - 1U))) |
2632 | return -EIO; | 2598 | return -EIO; |
2633 | if (likely(bitmap[0] & FATTR4_WORD0_CHANGE)) { | 2599 | if (likely(bitmap[0] & FATTR4_WORD0_CHANGE)) { |
2634 | READ_BUF(8); | 2600 | p = xdr_inline_decode(xdr, 8); |
2635 | READ64(*change); | 2601 | if (unlikely(!p)) |
2602 | goto out_overflow; | ||
2603 | xdr_decode_hyper(p, change); | ||
2636 | bitmap[0] &= ~FATTR4_WORD0_CHANGE; | 2604 | bitmap[0] &= ~FATTR4_WORD0_CHANGE; |
2637 | ret = NFS_ATTR_FATTR_CHANGE; | 2605 | ret = NFS_ATTR_FATTR_CHANGE; |
2638 | } | 2606 | } |
2639 | dprintk("%s: change attribute=%Lu\n", __func__, | 2607 | dprintk("%s: change attribute=%Lu\n", __func__, |
2640 | (unsigned long long)*change); | 2608 | (unsigned long long)*change); |
2641 | return ret; | 2609 | return ret; |
2610 | out_overflow: | ||
2611 | print_overflow_msg(__func__, xdr); | ||
2612 | return -EIO; | ||
2642 | } | 2613 | } |
2643 | 2614 | ||
2644 | static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *size) | 2615 | static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *size) |
@@ -2650,13 +2621,18 @@ static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t * | |||
2650 | if (unlikely(bitmap[0] & (FATTR4_WORD0_SIZE - 1U))) | 2621 | if (unlikely(bitmap[0] & (FATTR4_WORD0_SIZE - 1U))) |
2651 | return -EIO; | 2622 | return -EIO; |
2652 | if (likely(bitmap[0] & FATTR4_WORD0_SIZE)) { | 2623 | if (likely(bitmap[0] & FATTR4_WORD0_SIZE)) { |
2653 | READ_BUF(8); | 2624 | p = xdr_inline_decode(xdr, 8); |
2654 | READ64(*size); | 2625 | if (unlikely(!p)) |
2626 | goto out_overflow; | ||
2627 | xdr_decode_hyper(p, size); | ||
2655 | bitmap[0] &= ~FATTR4_WORD0_SIZE; | 2628 | bitmap[0] &= ~FATTR4_WORD0_SIZE; |
2656 | ret = NFS_ATTR_FATTR_SIZE; | 2629 | ret = NFS_ATTR_FATTR_SIZE; |
2657 | } | 2630 | } |
2658 | dprintk("%s: file size=%Lu\n", __func__, (unsigned long long)*size); | 2631 | dprintk("%s: file size=%Lu\n", __func__, (unsigned long long)*size); |
2659 | return ret; | 2632 | return ret; |
2633 | out_overflow: | ||
2634 | print_overflow_msg(__func__, xdr); | ||
2635 | return -EIO; | ||
2660 | } | 2636 | } |
2661 | 2637 | ||
2662 | static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) | 2638 | static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) |
@@ -2667,12 +2643,17 @@ static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, ui | |||
2667 | if (unlikely(bitmap[0] & (FATTR4_WORD0_LINK_SUPPORT - 1U))) | 2643 | if (unlikely(bitmap[0] & (FATTR4_WORD0_LINK_SUPPORT - 1U))) |
2668 | return -EIO; | 2644 | return -EIO; |
2669 | if (likely(bitmap[0] & FATTR4_WORD0_LINK_SUPPORT)) { | 2645 | if (likely(bitmap[0] & FATTR4_WORD0_LINK_SUPPORT)) { |
2670 | READ_BUF(4); | 2646 | p = xdr_inline_decode(xdr, 4); |
2671 | READ32(*res); | 2647 | if (unlikely(!p)) |
2648 | goto out_overflow; | ||
2649 | *res = be32_to_cpup(p); | ||
2672 | bitmap[0] &= ~FATTR4_WORD0_LINK_SUPPORT; | 2650 | bitmap[0] &= ~FATTR4_WORD0_LINK_SUPPORT; |
2673 | } | 2651 | } |
2674 | dprintk("%s: link support=%s\n", __func__, *res == 0 ? "false" : "true"); | 2652 | dprintk("%s: link support=%s\n", __func__, *res == 0 ? "false" : "true"); |
2675 | return 0; | 2653 | return 0; |
2654 | out_overflow: | ||
2655 | print_overflow_msg(__func__, xdr); | ||
2656 | return -EIO; | ||
2676 | } | 2657 | } |
2677 | 2658 | ||
2678 | static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) | 2659 | static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) |
@@ -2683,12 +2664,17 @@ static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, | |||
2683 | if (unlikely(bitmap[0] & (FATTR4_WORD0_SYMLINK_SUPPORT - 1U))) | 2664 | if (unlikely(bitmap[0] & (FATTR4_WORD0_SYMLINK_SUPPORT - 1U))) |
2684 | return -EIO; | 2665 | return -EIO; |
2685 | if (likely(bitmap[0] & FATTR4_WORD0_SYMLINK_SUPPORT)) { | 2666 | if (likely(bitmap[0] & FATTR4_WORD0_SYMLINK_SUPPORT)) { |
2686 | READ_BUF(4); | 2667 | p = xdr_inline_decode(xdr, 4); |
2687 | READ32(*res); | 2668 | if (unlikely(!p)) |
2669 | goto out_overflow; | ||
2670 | *res = be32_to_cpup(p); | ||
2688 | bitmap[0] &= ~FATTR4_WORD0_SYMLINK_SUPPORT; | 2671 | bitmap[0] &= ~FATTR4_WORD0_SYMLINK_SUPPORT; |
2689 | } | 2672 | } |
2690 | dprintk("%s: symlink support=%s\n", __func__, *res == 0 ? "false" : "true"); | 2673 | dprintk("%s: symlink support=%s\n", __func__, *res == 0 ? "false" : "true"); |
2691 | return 0; | 2674 | return 0; |
2675 | out_overflow: | ||
2676 | print_overflow_msg(__func__, xdr); | ||
2677 | return -EIO; | ||
2692 | } | 2678 | } |
2693 | 2679 | ||
2694 | static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fsid *fsid) | 2680 | static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fsid *fsid) |
@@ -2701,9 +2687,11 @@ static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs | |||
2701 | if (unlikely(bitmap[0] & (FATTR4_WORD0_FSID - 1U))) | 2687 | if (unlikely(bitmap[0] & (FATTR4_WORD0_FSID - 1U))) |
2702 | return -EIO; | 2688 | return -EIO; |
2703 | if (likely(bitmap[0] & FATTR4_WORD0_FSID)) { | 2689 | if (likely(bitmap[0] & FATTR4_WORD0_FSID)) { |
2704 | READ_BUF(16); | 2690 | p = xdr_inline_decode(xdr, 16); |
2705 | READ64(fsid->major); | 2691 | if (unlikely(!p)) |
2706 | READ64(fsid->minor); | 2692 | goto out_overflow; |
2693 | p = xdr_decode_hyper(p, &fsid->major); | ||
2694 | xdr_decode_hyper(p, &fsid->minor); | ||
2707 | bitmap[0] &= ~FATTR4_WORD0_FSID; | 2695 | bitmap[0] &= ~FATTR4_WORD0_FSID; |
2708 | ret = NFS_ATTR_FATTR_FSID; | 2696 | ret = NFS_ATTR_FATTR_FSID; |
2709 | } | 2697 | } |
@@ -2711,6 +2699,9 @@ static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs | |||
2711 | (unsigned long long)fsid->major, | 2699 | (unsigned long long)fsid->major, |
2712 | (unsigned long long)fsid->minor); | 2700 | (unsigned long long)fsid->minor); |
2713 | return ret; | 2701 | return ret; |
2702 | out_overflow: | ||
2703 | print_overflow_msg(__func__, xdr); | ||
2704 | return -EIO; | ||
2714 | } | 2705 | } |
2715 | 2706 | ||
2716 | static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) | 2707 | static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) |
@@ -2721,12 +2712,17 @@ static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint | |||
2721 | if (unlikely(bitmap[0] & (FATTR4_WORD0_LEASE_TIME - 1U))) | 2712 | if (unlikely(bitmap[0] & (FATTR4_WORD0_LEASE_TIME - 1U))) |
2722 | return -EIO; | 2713 | return -EIO; |
2723 | if (likely(bitmap[0] & FATTR4_WORD0_LEASE_TIME)) { | 2714 | if (likely(bitmap[0] & FATTR4_WORD0_LEASE_TIME)) { |
2724 | READ_BUF(4); | 2715 | p = xdr_inline_decode(xdr, 4); |
2725 | READ32(*res); | 2716 | if (unlikely(!p)) |
2717 | goto out_overflow; | ||
2718 | *res = be32_to_cpup(p); | ||
2726 | bitmap[0] &= ~FATTR4_WORD0_LEASE_TIME; | 2719 | bitmap[0] &= ~FATTR4_WORD0_LEASE_TIME; |
2727 | } | 2720 | } |
2728 | dprintk("%s: file size=%u\n", __func__, (unsigned int)*res); | 2721 | dprintk("%s: file size=%u\n", __func__, (unsigned int)*res); |
2729 | return 0; | 2722 | return 0; |
2723 | out_overflow: | ||
2724 | print_overflow_msg(__func__, xdr); | ||
2725 | return -EIO; | ||
2730 | } | 2726 | } |
2731 | 2727 | ||
2732 | static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) | 2728 | static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) |
@@ -2737,12 +2733,17 @@ static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint | |||
2737 | if (unlikely(bitmap[0] & (FATTR4_WORD0_ACLSUPPORT - 1U))) | 2733 | if (unlikely(bitmap[0] & (FATTR4_WORD0_ACLSUPPORT - 1U))) |
2738 | return -EIO; | 2734 | return -EIO; |
2739 | if (likely(bitmap[0] & FATTR4_WORD0_ACLSUPPORT)) { | 2735 | if (likely(bitmap[0] & FATTR4_WORD0_ACLSUPPORT)) { |
2740 | READ_BUF(4); | 2736 | p = xdr_inline_decode(xdr, 4); |
2741 | READ32(*res); | 2737 | if (unlikely(!p)) |
2738 | goto out_overflow; | ||
2739 | *res = be32_to_cpup(p); | ||
2742 | bitmap[0] &= ~FATTR4_WORD0_ACLSUPPORT; | 2740 | bitmap[0] &= ~FATTR4_WORD0_ACLSUPPORT; |
2743 | } | 2741 | } |
2744 | dprintk("%s: ACLs supported=%u\n", __func__, (unsigned int)*res); | 2742 | dprintk("%s: ACLs supported=%u\n", __func__, (unsigned int)*res); |
2745 | return 0; | 2743 | return 0; |
2744 | out_overflow: | ||
2745 | print_overflow_msg(__func__, xdr); | ||
2746 | return -EIO; | ||
2746 | } | 2747 | } |
2747 | 2748 | ||
2748 | static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid) | 2749 | static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid) |
@@ -2754,13 +2755,18 @@ static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t | |||
2754 | if (unlikely(bitmap[0] & (FATTR4_WORD0_FILEID - 1U))) | 2755 | if (unlikely(bitmap[0] & (FATTR4_WORD0_FILEID - 1U))) |
2755 | return -EIO; | 2756 | return -EIO; |
2756 | if (likely(bitmap[0] & FATTR4_WORD0_FILEID)) { | 2757 | if (likely(bitmap[0] & FATTR4_WORD0_FILEID)) { |
2757 | READ_BUF(8); | 2758 | p = xdr_inline_decode(xdr, 8); |
2758 | READ64(*fileid); | 2759 | if (unlikely(!p)) |
2760 | goto out_overflow; | ||
2761 | xdr_decode_hyper(p, fileid); | ||
2759 | bitmap[0] &= ~FATTR4_WORD0_FILEID; | 2762 | bitmap[0] &= ~FATTR4_WORD0_FILEID; |
2760 | ret = NFS_ATTR_FATTR_FILEID; | 2763 | ret = NFS_ATTR_FATTR_FILEID; |
2761 | } | 2764 | } |
2762 | dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid); | 2765 | dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid); |
2763 | return ret; | 2766 | return ret; |
2767 | out_overflow: | ||
2768 | print_overflow_msg(__func__, xdr); | ||
2769 | return -EIO; | ||
2764 | } | 2770 | } |
2765 | 2771 | ||
2766 | static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid) | 2772 | static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid) |
@@ -2772,13 +2778,18 @@ static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitma | |||
2772 | if (unlikely(bitmap[1] & (FATTR4_WORD1_MOUNTED_ON_FILEID - 1U))) | 2778 | if (unlikely(bitmap[1] & (FATTR4_WORD1_MOUNTED_ON_FILEID - 1U))) |
2773 | return -EIO; | 2779 | return -EIO; |
2774 | if (likely(bitmap[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)) { | 2780 | if (likely(bitmap[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)) { |
2775 | READ_BUF(8); | 2781 | p = xdr_inline_decode(xdr, 8); |
2776 | READ64(*fileid); | 2782 | if (unlikely(!p)) |
2783 | goto out_overflow; | ||
2784 | xdr_decode_hyper(p, fileid); | ||
2777 | bitmap[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; | 2785 | bitmap[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; |
2778 | ret = NFS_ATTR_FATTR_FILEID; | 2786 | ret = NFS_ATTR_FATTR_FILEID; |
2779 | } | 2787 | } |
2780 | dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid); | 2788 | dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid); |
2781 | return ret; | 2789 | return ret; |
2790 | out_overflow: | ||
2791 | print_overflow_msg(__func__, xdr); | ||
2792 | return -EIO; | ||
2782 | } | 2793 | } |
2783 | 2794 | ||
2784 | static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) | 2795 | static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) |
@@ -2790,12 +2801,17 @@ static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uin | |||
2790 | if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_AVAIL - 1U))) | 2801 | if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_AVAIL - 1U))) |
2791 | return -EIO; | 2802 | return -EIO; |
2792 | if (likely(bitmap[0] & FATTR4_WORD0_FILES_AVAIL)) { | 2803 | if (likely(bitmap[0] & FATTR4_WORD0_FILES_AVAIL)) { |
2793 | READ_BUF(8); | 2804 | p = xdr_inline_decode(xdr, 8); |
2794 | READ64(*res); | 2805 | if (unlikely(!p)) |
2806 | goto out_overflow; | ||
2807 | xdr_decode_hyper(p, res); | ||
2795 | bitmap[0] &= ~FATTR4_WORD0_FILES_AVAIL; | 2808 | bitmap[0] &= ~FATTR4_WORD0_FILES_AVAIL; |
2796 | } | 2809 | } |
2797 | dprintk("%s: files avail=%Lu\n", __func__, (unsigned long long)*res); | 2810 | dprintk("%s: files avail=%Lu\n", __func__, (unsigned long long)*res); |
2798 | return status; | 2811 | return status; |
2812 | out_overflow: | ||
2813 | print_overflow_msg(__func__, xdr); | ||
2814 | return -EIO; | ||
2799 | } | 2815 | } |
2800 | 2816 | ||
2801 | static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) | 2817 | static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) |
@@ -2807,12 +2823,17 @@ static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint | |||
2807 | if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_FREE - 1U))) | 2823 | if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_FREE - 1U))) |
2808 | return -EIO; | 2824 | return -EIO; |
2809 | if (likely(bitmap[0] & FATTR4_WORD0_FILES_FREE)) { | 2825 | if (likely(bitmap[0] & FATTR4_WORD0_FILES_FREE)) { |
2810 | READ_BUF(8); | 2826 | p = xdr_inline_decode(xdr, 8); |
2811 | READ64(*res); | 2827 | if (unlikely(!p)) |
2828 | goto out_overflow; | ||
2829 | xdr_decode_hyper(p, res); | ||
2812 | bitmap[0] &= ~FATTR4_WORD0_FILES_FREE; | 2830 | bitmap[0] &= ~FATTR4_WORD0_FILES_FREE; |
2813 | } | 2831 | } |
2814 | dprintk("%s: files free=%Lu\n", __func__, (unsigned long long)*res); | 2832 | dprintk("%s: files free=%Lu\n", __func__, (unsigned long long)*res); |
2815 | return status; | 2833 | return status; |
2834 | out_overflow: | ||
2835 | print_overflow_msg(__func__, xdr); | ||
2836 | return -EIO; | ||
2816 | } | 2837 | } |
2817 | 2838 | ||
2818 | static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) | 2839 | static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) |
@@ -2824,12 +2845,17 @@ static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uin | |||
2824 | if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_TOTAL - 1U))) | 2845 | if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_TOTAL - 1U))) |
2825 | return -EIO; | 2846 | return -EIO; |
2826 | if (likely(bitmap[0] & FATTR4_WORD0_FILES_TOTAL)) { | 2847 | if (likely(bitmap[0] & FATTR4_WORD0_FILES_TOTAL)) { |
2827 | READ_BUF(8); | 2848 | p = xdr_inline_decode(xdr, 8); |
2828 | READ64(*res); | 2849 | if (unlikely(!p)) |
2850 | goto out_overflow; | ||
2851 | xdr_decode_hyper(p, res); | ||
2829 | bitmap[0] &= ~FATTR4_WORD0_FILES_TOTAL; | 2852 | bitmap[0] &= ~FATTR4_WORD0_FILES_TOTAL; |
2830 | } | 2853 | } |
2831 | dprintk("%s: files total=%Lu\n", __func__, (unsigned long long)*res); | 2854 | dprintk("%s: files total=%Lu\n", __func__, (unsigned long long)*res); |
2832 | return status; | 2855 | return status; |
2856 | out_overflow: | ||
2857 | print_overflow_msg(__func__, xdr); | ||
2858 | return -EIO; | ||
2833 | } | 2859 | } |
2834 | 2860 | ||
2835 | static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path) | 2861 | static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path) |
@@ -2838,8 +2864,10 @@ static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path) | |||
2838 | __be32 *p; | 2864 | __be32 *p; |
2839 | int status = 0; | 2865 | int status = 0; |
2840 | 2866 | ||
2841 | READ_BUF(4); | 2867 | p = xdr_inline_decode(xdr, 4); |
2842 | READ32(n); | 2868 | if (unlikely(!p)) |
2869 | goto out_overflow; | ||
2870 | n = be32_to_cpup(p); | ||
2843 | if (n == 0) | 2871 | if (n == 0) |
2844 | goto root_path; | 2872 | goto root_path; |
2845 | dprintk("path "); | 2873 | dprintk("path "); |
@@ -2873,6 +2901,9 @@ out_eio: | |||
2873 | dprintk(" status %d", status); | 2901 | dprintk(" status %d", status); |
2874 | status = -EIO; | 2902 | status = -EIO; |
2875 | goto out; | 2903 | goto out; |
2904 | out_overflow: | ||
2905 | print_overflow_msg(__func__, xdr); | ||
2906 | return -EIO; | ||
2876 | } | 2907 | } |
2877 | 2908 | ||
2878 | static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_fs_locations *res) | 2909 | static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_fs_locations *res) |
@@ -2890,8 +2921,10 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st | |||
2890 | status = decode_pathname(xdr, &res->fs_path); | 2921 | status = decode_pathname(xdr, &res->fs_path); |
2891 | if (unlikely(status != 0)) | 2922 | if (unlikely(status != 0)) |
2892 | goto out; | 2923 | goto out; |
2893 | READ_BUF(4); | 2924 | p = xdr_inline_decode(xdr, 4); |
2894 | READ32(n); | 2925 | if (unlikely(!p)) |
2926 | goto out_overflow; | ||
2927 | n = be32_to_cpup(p); | ||
2895 | if (n <= 0) | 2928 | if (n <= 0) |
2896 | goto out_eio; | 2929 | goto out_eio; |
2897 | res->nlocations = 0; | 2930 | res->nlocations = 0; |
@@ -2899,8 +2932,10 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st | |||
2899 | u32 m; | 2932 | u32 m; |
2900 | struct nfs4_fs_location *loc = &res->locations[res->nlocations]; | 2933 | struct nfs4_fs_location *loc = &res->locations[res->nlocations]; |
2901 | 2934 | ||
2902 | READ_BUF(4); | 2935 | p = xdr_inline_decode(xdr, 4); |
2903 | READ32(m); | 2936 | if (unlikely(!p)) |
2937 | goto out_overflow; | ||
2938 | m = be32_to_cpup(p); | ||
2904 | 2939 | ||
2905 | loc->nservers = 0; | 2940 | loc->nservers = 0; |
2906 | dprintk("%s: servers ", __func__); | 2941 | dprintk("%s: servers ", __func__); |
@@ -2939,6 +2974,8 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st | |||
2939 | out: | 2974 | out: |
2940 | dprintk("%s: fs_locations done, error = %d\n", __func__, status); | 2975 | dprintk("%s: fs_locations done, error = %d\n", __func__, status); |
2941 | return status; | 2976 | return status; |
2977 | out_overflow: | ||
2978 | print_overflow_msg(__func__, xdr); | ||
2942 | out_eio: | 2979 | out_eio: |
2943 | status = -EIO; | 2980 | status = -EIO; |
2944 | goto out; | 2981 | goto out; |
@@ -2953,12 +2990,17 @@ static int decode_attr_maxfilesize(struct xdr_stream *xdr, uint32_t *bitmap, uin | |||
2953 | if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXFILESIZE - 1U))) | 2990 | if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXFILESIZE - 1U))) |
2954 | return -EIO; | 2991 | return -EIO; |
2955 | if (likely(bitmap[0] & FATTR4_WORD0_MAXFILESIZE)) { | 2992 | if (likely(bitmap[0] & FATTR4_WORD0_MAXFILESIZE)) { |
2956 | READ_BUF(8); | 2993 | p = xdr_inline_decode(xdr, 8); |
2957 | READ64(*res); | 2994 | if (unlikely(!p)) |
2995 | goto out_overflow; | ||
2996 | xdr_decode_hyper(p, res); | ||
2958 | bitmap[0] &= ~FATTR4_WORD0_MAXFILESIZE; | 2997 | bitmap[0] &= ~FATTR4_WORD0_MAXFILESIZE; |
2959 | } | 2998 | } |
2960 | dprintk("%s: maxfilesize=%Lu\n", __func__, (unsigned long long)*res); | 2999 | dprintk("%s: maxfilesize=%Lu\n", __func__, (unsigned long long)*res); |
2961 | return status; | 3000 | return status; |
3001 | out_overflow: | ||
3002 | print_overflow_msg(__func__, xdr); | ||
3003 | return -EIO; | ||
2962 | } | 3004 | } |
2963 | 3005 | ||
2964 | static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxlink) | 3006 | static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxlink) |
@@ -2970,12 +3012,17 @@ static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ | |||
2970 | if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXLINK - 1U))) | 3012 | if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXLINK - 1U))) |
2971 | return -EIO; | 3013 | return -EIO; |
2972 | if (likely(bitmap[0] & FATTR4_WORD0_MAXLINK)) { | 3014 | if (likely(bitmap[0] & FATTR4_WORD0_MAXLINK)) { |
2973 | READ_BUF(4); | 3015 | p = xdr_inline_decode(xdr, 4); |
2974 | READ32(*maxlink); | 3016 | if (unlikely(!p)) |
3017 | goto out_overflow; | ||
3018 | *maxlink = be32_to_cpup(p); | ||
2975 | bitmap[0] &= ~FATTR4_WORD0_MAXLINK; | 3019 | bitmap[0] &= ~FATTR4_WORD0_MAXLINK; |
2976 | } | 3020 | } |
2977 | dprintk("%s: maxlink=%u\n", __func__, *maxlink); | 3021 | dprintk("%s: maxlink=%u\n", __func__, *maxlink); |
2978 | return status; | 3022 | return status; |
3023 | out_overflow: | ||
3024 | print_overflow_msg(__func__, xdr); | ||
3025 | return -EIO; | ||
2979 | } | 3026 | } |
2980 | 3027 | ||
2981 | static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxname) | 3028 | static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxname) |
@@ -2987,12 +3034,17 @@ static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ | |||
2987 | if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXNAME - 1U))) | 3034 | if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXNAME - 1U))) |
2988 | return -EIO; | 3035 | return -EIO; |
2989 | if (likely(bitmap[0] & FATTR4_WORD0_MAXNAME)) { | 3036 | if (likely(bitmap[0] & FATTR4_WORD0_MAXNAME)) { |
2990 | READ_BUF(4); | 3037 | p = xdr_inline_decode(xdr, 4); |
2991 | READ32(*maxname); | 3038 | if (unlikely(!p)) |
3039 | goto out_overflow; | ||
3040 | *maxname = be32_to_cpup(p); | ||
2992 | bitmap[0] &= ~FATTR4_WORD0_MAXNAME; | 3041 | bitmap[0] &= ~FATTR4_WORD0_MAXNAME; |
2993 | } | 3042 | } |
2994 | dprintk("%s: maxname=%u\n", __func__, *maxname); | 3043 | dprintk("%s: maxname=%u\n", __func__, *maxname); |
2995 | return status; | 3044 | return status; |
3045 | out_overflow: | ||
3046 | print_overflow_msg(__func__, xdr); | ||
3047 | return -EIO; | ||
2996 | } | 3048 | } |
2997 | 3049 | ||
2998 | static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) | 3050 | static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) |
@@ -3005,8 +3057,10 @@ static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ | |||
3005 | return -EIO; | 3057 | return -EIO; |
3006 | if (likely(bitmap[0] & FATTR4_WORD0_MAXREAD)) { | 3058 | if (likely(bitmap[0] & FATTR4_WORD0_MAXREAD)) { |
3007 | uint64_t maxread; | 3059 | uint64_t maxread; |
3008 | READ_BUF(8); | 3060 | p = xdr_inline_decode(xdr, 8); |
3009 | READ64(maxread); | 3061 | if (unlikely(!p)) |
3062 | goto out_overflow; | ||
3063 | xdr_decode_hyper(p, &maxread); | ||
3010 | if (maxread > 0x7FFFFFFF) | 3064 | if (maxread > 0x7FFFFFFF) |
3011 | maxread = 0x7FFFFFFF; | 3065 | maxread = 0x7FFFFFFF; |
3012 | *res = (uint32_t)maxread; | 3066 | *res = (uint32_t)maxread; |
@@ -3014,6 +3068,9 @@ static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ | |||
3014 | } | 3068 | } |
3015 | dprintk("%s: maxread=%lu\n", __func__, (unsigned long)*res); | 3069 | dprintk("%s: maxread=%lu\n", __func__, (unsigned long)*res); |
3016 | return status; | 3070 | return status; |
3071 | out_overflow: | ||
3072 | print_overflow_msg(__func__, xdr); | ||
3073 | return -EIO; | ||
3017 | } | 3074 | } |
3018 | 3075 | ||
3019 | static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) | 3076 | static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) |
@@ -3026,8 +3083,10 @@ static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32 | |||
3026 | return -EIO; | 3083 | return -EIO; |
3027 | if (likely(bitmap[0] & FATTR4_WORD0_MAXWRITE)) { | 3084 | if (likely(bitmap[0] & FATTR4_WORD0_MAXWRITE)) { |
3028 | uint64_t maxwrite; | 3085 | uint64_t maxwrite; |
3029 | READ_BUF(8); | 3086 | p = xdr_inline_decode(xdr, 8); |
3030 | READ64(maxwrite); | 3087 | if (unlikely(!p)) |
3088 | goto out_overflow; | ||
3089 | xdr_decode_hyper(p, &maxwrite); | ||
3031 | if (maxwrite > 0x7FFFFFFF) | 3090 | if (maxwrite > 0x7FFFFFFF) |
3032 | maxwrite = 0x7FFFFFFF; | 3091 | maxwrite = 0x7FFFFFFF; |
3033 | *res = (uint32_t)maxwrite; | 3092 | *res = (uint32_t)maxwrite; |
@@ -3035,6 +3094,9 @@ static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32 | |||
3035 | } | 3094 | } |
3036 | dprintk("%s: maxwrite=%lu\n", __func__, (unsigned long)*res); | 3095 | dprintk("%s: maxwrite=%lu\n", __func__, (unsigned long)*res); |
3037 | return status; | 3096 | return status; |
3097 | out_overflow: | ||
3098 | print_overflow_msg(__func__, xdr); | ||
3099 | return -EIO; | ||
3038 | } | 3100 | } |
3039 | 3101 | ||
3040 | static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, umode_t *mode) | 3102 | static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, umode_t *mode) |
@@ -3047,14 +3109,19 @@ static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, umode_t *m | |||
3047 | if (unlikely(bitmap[1] & (FATTR4_WORD1_MODE - 1U))) | 3109 | if (unlikely(bitmap[1] & (FATTR4_WORD1_MODE - 1U))) |
3048 | return -EIO; | 3110 | return -EIO; |
3049 | if (likely(bitmap[1] & FATTR4_WORD1_MODE)) { | 3111 | if (likely(bitmap[1] & FATTR4_WORD1_MODE)) { |
3050 | READ_BUF(4); | 3112 | p = xdr_inline_decode(xdr, 4); |
3051 | READ32(tmp); | 3113 | if (unlikely(!p)) |
3114 | goto out_overflow; | ||
3115 | tmp = be32_to_cpup(p); | ||
3052 | *mode = tmp & ~S_IFMT; | 3116 | *mode = tmp & ~S_IFMT; |
3053 | bitmap[1] &= ~FATTR4_WORD1_MODE; | 3117 | bitmap[1] &= ~FATTR4_WORD1_MODE; |
3054 | ret = NFS_ATTR_FATTR_MODE; | 3118 | ret = NFS_ATTR_FATTR_MODE; |
3055 | } | 3119 | } |
3056 | dprintk("%s: file mode=0%o\n", __func__, (unsigned int)*mode); | 3120 | dprintk("%s: file mode=0%o\n", __func__, (unsigned int)*mode); |
3057 | return ret; | 3121 | return ret; |
3122 | out_overflow: | ||
3123 | print_overflow_msg(__func__, xdr); | ||
3124 | return -EIO; | ||
3058 | } | 3125 | } |
3059 | 3126 | ||
3060 | static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *nlink) | 3127 | static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *nlink) |
@@ -3066,16 +3133,22 @@ static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t | |||
3066 | if (unlikely(bitmap[1] & (FATTR4_WORD1_NUMLINKS - 1U))) | 3133 | if (unlikely(bitmap[1] & (FATTR4_WORD1_NUMLINKS - 1U))) |
3067 | return -EIO; | 3134 | return -EIO; |
3068 | if (likely(bitmap[1] & FATTR4_WORD1_NUMLINKS)) { | 3135 | if (likely(bitmap[1] & FATTR4_WORD1_NUMLINKS)) { |
3069 | READ_BUF(4); | 3136 | p = xdr_inline_decode(xdr, 4); |
3070 | READ32(*nlink); | 3137 | if (unlikely(!p)) |
3138 | goto out_overflow; | ||
3139 | *nlink = be32_to_cpup(p); | ||
3071 | bitmap[1] &= ~FATTR4_WORD1_NUMLINKS; | 3140 | bitmap[1] &= ~FATTR4_WORD1_NUMLINKS; |
3072 | ret = NFS_ATTR_FATTR_NLINK; | 3141 | ret = NFS_ATTR_FATTR_NLINK; |
3073 | } | 3142 | } |
3074 | dprintk("%s: nlink=%u\n", __func__, (unsigned int)*nlink); | 3143 | dprintk("%s: nlink=%u\n", __func__, (unsigned int)*nlink); |
3075 | return ret; | 3144 | return ret; |
3145 | out_overflow: | ||
3146 | print_overflow_msg(__func__, xdr); | ||
3147 | return -EIO; | ||
3076 | } | 3148 | } |
3077 | 3149 | ||
3078 | static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, uint32_t *uid) | 3150 | static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, |
3151 | struct nfs_client *clp, uint32_t *uid, int may_sleep) | ||
3079 | { | 3152 | { |
3080 | uint32_t len; | 3153 | uint32_t len; |
3081 | __be32 *p; | 3154 | __be32 *p; |
@@ -3085,10 +3158,16 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nf | |||
3085 | if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER - 1U))) | 3158 | if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER - 1U))) |
3086 | return -EIO; | 3159 | return -EIO; |
3087 | if (likely(bitmap[1] & FATTR4_WORD1_OWNER)) { | 3160 | if (likely(bitmap[1] & FATTR4_WORD1_OWNER)) { |
3088 | READ_BUF(4); | 3161 | p = xdr_inline_decode(xdr, 4); |
3089 | READ32(len); | 3162 | if (unlikely(!p)) |
3090 | READ_BUF(len); | 3163 | goto out_overflow; |
3091 | if (len < XDR_MAX_NETOBJ) { | 3164 | len = be32_to_cpup(p); |
3165 | p = xdr_inline_decode(xdr, len); | ||
3166 | if (unlikely(!p)) | ||
3167 | goto out_overflow; | ||
3168 | if (!may_sleep) { | ||
3169 | /* do nothing */ | ||
3170 | } else if (len < XDR_MAX_NETOBJ) { | ||
3092 | if (nfs_map_name_to_uid(clp, (char *)p, len, uid) == 0) | 3171 | if (nfs_map_name_to_uid(clp, (char *)p, len, uid) == 0) |
3093 | ret = NFS_ATTR_FATTR_OWNER; | 3172 | ret = NFS_ATTR_FATTR_OWNER; |
3094 | else | 3173 | else |
@@ -3101,9 +3180,13 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nf | |||
3101 | } | 3180 | } |
3102 | dprintk("%s: uid=%d\n", __func__, (int)*uid); | 3181 | dprintk("%s: uid=%d\n", __func__, (int)*uid); |
3103 | return ret; | 3182 | return ret; |
3183 | out_overflow: | ||
3184 | print_overflow_msg(__func__, xdr); | ||
3185 | return -EIO; | ||
3104 | } | 3186 | } |
3105 | 3187 | ||
3106 | static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, uint32_t *gid) | 3188 | static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, |
3189 | struct nfs_client *clp, uint32_t *gid, int may_sleep) | ||
3107 | { | 3190 | { |
3108 | uint32_t len; | 3191 | uint32_t len; |
3109 | __be32 *p; | 3192 | __be32 *p; |
@@ -3113,10 +3196,16 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nf | |||
3113 | if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER_GROUP - 1U))) | 3196 | if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER_GROUP - 1U))) |
3114 | return -EIO; | 3197 | return -EIO; |
3115 | if (likely(bitmap[1] & FATTR4_WORD1_OWNER_GROUP)) { | 3198 | if (likely(bitmap[1] & FATTR4_WORD1_OWNER_GROUP)) { |
3116 | READ_BUF(4); | 3199 | p = xdr_inline_decode(xdr, 4); |
3117 | READ32(len); | 3200 | if (unlikely(!p)) |
3118 | READ_BUF(len); | 3201 | goto out_overflow; |
3119 | if (len < XDR_MAX_NETOBJ) { | 3202 | len = be32_to_cpup(p); |
3203 | p = xdr_inline_decode(xdr, len); | ||
3204 | if (unlikely(!p)) | ||
3205 | goto out_overflow; | ||
3206 | if (!may_sleep) { | ||
3207 | /* do nothing */ | ||
3208 | } else if (len < XDR_MAX_NETOBJ) { | ||
3120 | if (nfs_map_group_to_gid(clp, (char *)p, len, gid) == 0) | 3209 | if (nfs_map_group_to_gid(clp, (char *)p, len, gid) == 0) |
3121 | ret = NFS_ATTR_FATTR_GROUP; | 3210 | ret = NFS_ATTR_FATTR_GROUP; |
3122 | else | 3211 | else |
@@ -3129,6 +3218,9 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nf | |||
3129 | } | 3218 | } |
3130 | dprintk("%s: gid=%d\n", __func__, (int)*gid); | 3219 | dprintk("%s: gid=%d\n", __func__, (int)*gid); |
3131 | return ret; | 3220 | return ret; |
3221 | out_overflow: | ||
3222 | print_overflow_msg(__func__, xdr); | ||
3223 | return -EIO; | ||
3132 | } | 3224 | } |
3133 | 3225 | ||
3134 | static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rdev) | 3226 | static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rdev) |
@@ -3143,9 +3235,11 @@ static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rde | |||
3143 | if (likely(bitmap[1] & FATTR4_WORD1_RAWDEV)) { | 3235 | if (likely(bitmap[1] & FATTR4_WORD1_RAWDEV)) { |
3144 | dev_t tmp; | 3236 | dev_t tmp; |
3145 | 3237 | ||
3146 | READ_BUF(8); | 3238 | p = xdr_inline_decode(xdr, 8); |
3147 | READ32(major); | 3239 | if (unlikely(!p)) |
3148 | READ32(minor); | 3240 | goto out_overflow; |
3241 | major = be32_to_cpup(p++); | ||
3242 | minor = be32_to_cpup(p); | ||
3149 | tmp = MKDEV(major, minor); | 3243 | tmp = MKDEV(major, minor); |
3150 | if (MAJOR(tmp) == major && MINOR(tmp) == minor) | 3244 | if (MAJOR(tmp) == major && MINOR(tmp) == minor) |
3151 | *rdev = tmp; | 3245 | *rdev = tmp; |
@@ -3154,6 +3248,9 @@ static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rde | |||
3154 | } | 3248 | } |
3155 | dprintk("%s: rdev=(0x%x:0x%x)\n", __func__, major, minor); | 3249 | dprintk("%s: rdev=(0x%x:0x%x)\n", __func__, major, minor); |
3156 | return ret; | 3250 | return ret; |
3251 | out_overflow: | ||
3252 | print_overflow_msg(__func__, xdr); | ||
3253 | return -EIO; | ||
3157 | } | 3254 | } |
3158 | 3255 | ||
3159 | static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) | 3256 | static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) |
@@ -3165,12 +3262,17 @@ static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uin | |||
3165 | if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_AVAIL - 1U))) | 3262 | if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_AVAIL - 1U))) |
3166 | return -EIO; | 3263 | return -EIO; |
3167 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_AVAIL)) { | 3264 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_AVAIL)) { |
3168 | READ_BUF(8); | 3265 | p = xdr_inline_decode(xdr, 8); |
3169 | READ64(*res); | 3266 | if (unlikely(!p)) |
3267 | goto out_overflow; | ||
3268 | xdr_decode_hyper(p, res); | ||
3170 | bitmap[1] &= ~FATTR4_WORD1_SPACE_AVAIL; | 3269 | bitmap[1] &= ~FATTR4_WORD1_SPACE_AVAIL; |
3171 | } | 3270 | } |
3172 | dprintk("%s: space avail=%Lu\n", __func__, (unsigned long long)*res); | 3271 | dprintk("%s: space avail=%Lu\n", __func__, (unsigned long long)*res); |
3173 | return status; | 3272 | return status; |
3273 | out_overflow: | ||
3274 | print_overflow_msg(__func__, xdr); | ||
3275 | return -EIO; | ||
3174 | } | 3276 | } |
3175 | 3277 | ||
3176 | static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) | 3278 | static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) |
@@ -3182,12 +3284,17 @@ static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint | |||
3182 | if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_FREE - 1U))) | 3284 | if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_FREE - 1U))) |
3183 | return -EIO; | 3285 | return -EIO; |
3184 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_FREE)) { | 3286 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_FREE)) { |
3185 | READ_BUF(8); | 3287 | p = xdr_inline_decode(xdr, 8); |
3186 | READ64(*res); | 3288 | if (unlikely(!p)) |
3289 | goto out_overflow; | ||
3290 | xdr_decode_hyper(p, res); | ||
3187 | bitmap[1] &= ~FATTR4_WORD1_SPACE_FREE; | 3291 | bitmap[1] &= ~FATTR4_WORD1_SPACE_FREE; |
3188 | } | 3292 | } |
3189 | dprintk("%s: space free=%Lu\n", __func__, (unsigned long long)*res); | 3293 | dprintk("%s: space free=%Lu\n", __func__, (unsigned long long)*res); |
3190 | return status; | 3294 | return status; |
3295 | out_overflow: | ||
3296 | print_overflow_msg(__func__, xdr); | ||
3297 | return -EIO; | ||
3191 | } | 3298 | } |
3192 | 3299 | ||
3193 | static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) | 3300 | static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) |
@@ -3199,12 +3306,17 @@ static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uin | |||
3199 | if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_TOTAL - 1U))) | 3306 | if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_TOTAL - 1U))) |
3200 | return -EIO; | 3307 | return -EIO; |
3201 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_TOTAL)) { | 3308 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_TOTAL)) { |
3202 | READ_BUF(8); | 3309 | p = xdr_inline_decode(xdr, 8); |
3203 | READ64(*res); | 3310 | if (unlikely(!p)) |
3311 | goto out_overflow; | ||
3312 | xdr_decode_hyper(p, res); | ||
3204 | bitmap[1] &= ~FATTR4_WORD1_SPACE_TOTAL; | 3313 | bitmap[1] &= ~FATTR4_WORD1_SPACE_TOTAL; |
3205 | } | 3314 | } |
3206 | dprintk("%s: space total=%Lu\n", __func__, (unsigned long long)*res); | 3315 | dprintk("%s: space total=%Lu\n", __func__, (unsigned long long)*res); |
3207 | return status; | 3316 | return status; |
3317 | out_overflow: | ||
3318 | print_overflow_msg(__func__, xdr); | ||
3319 | return -EIO; | ||
3208 | } | 3320 | } |
3209 | 3321 | ||
3210 | static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *used) | 3322 | static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *used) |
@@ -3216,14 +3328,19 @@ static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint | |||
3216 | if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_USED - 1U))) | 3328 | if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_USED - 1U))) |
3217 | return -EIO; | 3329 | return -EIO; |
3218 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_USED)) { | 3330 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_USED)) { |
3219 | READ_BUF(8); | 3331 | p = xdr_inline_decode(xdr, 8); |
3220 | READ64(*used); | 3332 | if (unlikely(!p)) |
3333 | goto out_overflow; | ||
3334 | xdr_decode_hyper(p, used); | ||
3221 | bitmap[1] &= ~FATTR4_WORD1_SPACE_USED; | 3335 | bitmap[1] &= ~FATTR4_WORD1_SPACE_USED; |
3222 | ret = NFS_ATTR_FATTR_SPACE_USED; | 3336 | ret = NFS_ATTR_FATTR_SPACE_USED; |
3223 | } | 3337 | } |
3224 | dprintk("%s: space used=%Lu\n", __func__, | 3338 | dprintk("%s: space used=%Lu\n", __func__, |
3225 | (unsigned long long)*used); | 3339 | (unsigned long long)*used); |
3226 | return ret; | 3340 | return ret; |
3341 | out_overflow: | ||
3342 | print_overflow_msg(__func__, xdr); | ||
3343 | return -EIO; | ||
3227 | } | 3344 | } |
3228 | 3345 | ||
3229 | static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time) | 3346 | static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time) |
@@ -3232,12 +3349,17 @@ static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time) | |||
3232 | uint64_t sec; | 3349 | uint64_t sec; |
3233 | uint32_t nsec; | 3350 | uint32_t nsec; |
3234 | 3351 | ||
3235 | READ_BUF(12); | 3352 | p = xdr_inline_decode(xdr, 12); |
3236 | READ64(sec); | 3353 | if (unlikely(!p)) |
3237 | READ32(nsec); | 3354 | goto out_overflow; |
3355 | p = xdr_decode_hyper(p, &sec); | ||
3356 | nsec = be32_to_cpup(p); | ||
3238 | time->tv_sec = (time_t)sec; | 3357 | time->tv_sec = (time_t)sec; |
3239 | time->tv_nsec = (long)nsec; | 3358 | time->tv_nsec = (long)nsec; |
3240 | return 0; | 3359 | return 0; |
3360 | out_overflow: | ||
3361 | print_overflow_msg(__func__, xdr); | ||
3362 | return -EIO; | ||
3241 | } | 3363 | } |
3242 | 3364 | ||
3243 | static int decode_attr_time_access(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time) | 3365 | static int decode_attr_time_access(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time) |
@@ -3315,11 +3437,16 @@ static int decode_change_info(struct xdr_stream *xdr, struct nfs4_change_info *c | |||
3315 | { | 3437 | { |
3316 | __be32 *p; | 3438 | __be32 *p; |
3317 | 3439 | ||
3318 | READ_BUF(20); | 3440 | p = xdr_inline_decode(xdr, 20); |
3319 | READ32(cinfo->atomic); | 3441 | if (unlikely(!p)) |
3320 | READ64(cinfo->before); | 3442 | goto out_overflow; |
3321 | READ64(cinfo->after); | 3443 | cinfo->atomic = be32_to_cpup(p++); |
3444 | p = xdr_decode_hyper(p, &cinfo->before); | ||
3445 | xdr_decode_hyper(p, &cinfo->after); | ||
3322 | return 0; | 3446 | return 0; |
3447 | out_overflow: | ||
3448 | print_overflow_msg(__func__, xdr); | ||
3449 | return -EIO; | ||
3323 | } | 3450 | } |
3324 | 3451 | ||
3325 | static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access) | 3452 | static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access) |
@@ -3331,40 +3458,62 @@ static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access) | |||
3331 | status = decode_op_hdr(xdr, OP_ACCESS); | 3458 | status = decode_op_hdr(xdr, OP_ACCESS); |
3332 | if (status) | 3459 | if (status) |
3333 | return status; | 3460 | return status; |
3334 | READ_BUF(8); | 3461 | p = xdr_inline_decode(xdr, 8); |
3335 | READ32(supp); | 3462 | if (unlikely(!p)) |
3336 | READ32(acc); | 3463 | goto out_overflow; |
3464 | supp = be32_to_cpup(p++); | ||
3465 | acc = be32_to_cpup(p); | ||
3337 | access->supported = supp; | 3466 | access->supported = supp; |
3338 | access->access = acc; | 3467 | access->access = acc; |
3339 | return 0; | 3468 | return 0; |
3469 | out_overflow: | ||
3470 | print_overflow_msg(__func__, xdr); | ||
3471 | return -EIO; | ||
3340 | } | 3472 | } |
3341 | 3473 | ||
3342 | static int decode_close(struct xdr_stream *xdr, struct nfs_closeres *res) | 3474 | static int decode_opaque_fixed(struct xdr_stream *xdr, void *buf, size_t len) |
3343 | { | 3475 | { |
3344 | __be32 *p; | 3476 | __be32 *p; |
3477 | |||
3478 | p = xdr_inline_decode(xdr, len); | ||
3479 | if (likely(p)) { | ||
3480 | memcpy(buf, p, len); | ||
3481 | return 0; | ||
3482 | } | ||
3483 | print_overflow_msg(__func__, xdr); | ||
3484 | return -EIO; | ||
3485 | } | ||
3486 | |||
3487 | static int decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid) | ||
3488 | { | ||
3489 | return decode_opaque_fixed(xdr, stateid->data, NFS4_STATEID_SIZE); | ||
3490 | } | ||
3491 | |||
3492 | static int decode_close(struct xdr_stream *xdr, struct nfs_closeres *res) | ||
3493 | { | ||
3345 | int status; | 3494 | int status; |
3346 | 3495 | ||
3347 | status = decode_op_hdr(xdr, OP_CLOSE); | 3496 | status = decode_op_hdr(xdr, OP_CLOSE); |
3348 | if (status != -EIO) | 3497 | if (status != -EIO) |
3349 | nfs_increment_open_seqid(status, res->seqid); | 3498 | nfs_increment_open_seqid(status, res->seqid); |
3350 | if (status) | 3499 | if (!status) |
3351 | return status; | 3500 | status = decode_stateid(xdr, &res->stateid); |
3352 | READ_BUF(NFS4_STATEID_SIZE); | 3501 | return status; |
3353 | COPYMEM(res->stateid.data, NFS4_STATEID_SIZE); | 3502 | } |
3354 | return 0; | 3503 | |
3504 | static int decode_verifier(struct xdr_stream *xdr, void *verifier) | ||
3505 | { | ||
3506 | return decode_opaque_fixed(xdr, verifier, 8); | ||
3355 | } | 3507 | } |
3356 | 3508 | ||
3357 | static int decode_commit(struct xdr_stream *xdr, struct nfs_writeres *res) | 3509 | static int decode_commit(struct xdr_stream *xdr, struct nfs_writeres *res) |
3358 | { | 3510 | { |
3359 | __be32 *p; | ||
3360 | int status; | 3511 | int status; |
3361 | 3512 | ||
3362 | status = decode_op_hdr(xdr, OP_COMMIT); | 3513 | status = decode_op_hdr(xdr, OP_COMMIT); |
3363 | if (status) | 3514 | if (!status) |
3364 | return status; | 3515 | status = decode_verifier(xdr, res->verf->verifier); |
3365 | READ_BUF(8); | 3516 | return status; |
3366 | COPYMEM(res->verf->verifier, 8); | ||
3367 | return 0; | ||
3368 | } | 3517 | } |
3369 | 3518 | ||
3370 | static int decode_create(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) | 3519 | static int decode_create(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) |
@@ -3378,10 +3527,16 @@ static int decode_create(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) | |||
3378 | return status; | 3527 | return status; |
3379 | if ((status = decode_change_info(xdr, cinfo))) | 3528 | if ((status = decode_change_info(xdr, cinfo))) |
3380 | return status; | 3529 | return status; |
3381 | READ_BUF(4); | 3530 | p = xdr_inline_decode(xdr, 4); |
3382 | READ32(bmlen); | 3531 | if (unlikely(!p)) |
3383 | READ_BUF(bmlen << 2); | 3532 | goto out_overflow; |
3384 | return 0; | 3533 | bmlen = be32_to_cpup(p); |
3534 | p = xdr_inline_decode(xdr, bmlen << 2); | ||
3535 | if (likely(p)) | ||
3536 | return 0; | ||
3537 | out_overflow: | ||
3538 | print_overflow_msg(__func__, xdr); | ||
3539 | return -EIO; | ||
3385 | } | 3540 | } |
3386 | 3541 | ||
3387 | static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_res *res) | 3542 | static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_res *res) |
@@ -3466,7 +3621,8 @@ xdr_error: | |||
3466 | return status; | 3621 | return status; |
3467 | } | 3622 | } |
3468 | 3623 | ||
3469 | static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, const struct nfs_server *server) | 3624 | static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, |
3625 | const struct nfs_server *server, int may_sleep) | ||
3470 | { | 3626 | { |
3471 | __be32 *savep; | 3627 | __be32 *savep; |
3472 | uint32_t attrlen, | 3628 | uint32_t attrlen, |
@@ -3538,12 +3694,14 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, cons | |||
3538 | goto xdr_error; | 3694 | goto xdr_error; |
3539 | fattr->valid |= status; | 3695 | fattr->valid |= status; |
3540 | 3696 | ||
3541 | status = decode_attr_owner(xdr, bitmap, server->nfs_client, &fattr->uid); | 3697 | status = decode_attr_owner(xdr, bitmap, server->nfs_client, |
3698 | &fattr->uid, may_sleep); | ||
3542 | if (status < 0) | 3699 | if (status < 0) |
3543 | goto xdr_error; | 3700 | goto xdr_error; |
3544 | fattr->valid |= status; | 3701 | fattr->valid |= status; |
3545 | 3702 | ||
3546 | status = decode_attr_group(xdr, bitmap, server->nfs_client, &fattr->gid); | 3703 | status = decode_attr_group(xdr, bitmap, server->nfs_client, |
3704 | &fattr->gid, may_sleep); | ||
3547 | if (status < 0) | 3705 | if (status < 0) |
3548 | goto xdr_error; | 3706 | goto xdr_error; |
3549 | fattr->valid |= status; | 3707 | fattr->valid |= status; |
@@ -3633,14 +3791,21 @@ static int decode_getfh(struct xdr_stream *xdr, struct nfs_fh *fh) | |||
3633 | if (status) | 3791 | if (status) |
3634 | return status; | 3792 | return status; |
3635 | 3793 | ||
3636 | READ_BUF(4); | 3794 | p = xdr_inline_decode(xdr, 4); |
3637 | READ32(len); | 3795 | if (unlikely(!p)) |
3796 | goto out_overflow; | ||
3797 | len = be32_to_cpup(p); | ||
3638 | if (len > NFS4_FHSIZE) | 3798 | if (len > NFS4_FHSIZE) |
3639 | return -EIO; | 3799 | return -EIO; |
3640 | fh->size = len; | 3800 | fh->size = len; |
3641 | READ_BUF(len); | 3801 | p = xdr_inline_decode(xdr, len); |
3642 | COPYMEM(fh->data, len); | 3802 | if (unlikely(!p)) |
3803 | goto out_overflow; | ||
3804 | memcpy(fh->data, p, len); | ||
3643 | return 0; | 3805 | return 0; |
3806 | out_overflow: | ||
3807 | print_overflow_msg(__func__, xdr); | ||
3808 | return -EIO; | ||
3644 | } | 3809 | } |
3645 | 3810 | ||
3646 | static int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) | 3811 | static int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) |
@@ -3662,10 +3827,12 @@ static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl) | |||
3662 | __be32 *p; | 3827 | __be32 *p; |
3663 | uint32_t namelen, type; | 3828 | uint32_t namelen, type; |
3664 | 3829 | ||
3665 | READ_BUF(32); | 3830 | p = xdr_inline_decode(xdr, 32); |
3666 | READ64(offset); | 3831 | if (unlikely(!p)) |
3667 | READ64(length); | 3832 | goto out_overflow; |
3668 | READ32(type); | 3833 | p = xdr_decode_hyper(p, &offset); |
3834 | p = xdr_decode_hyper(p, &length); | ||
3835 | type = be32_to_cpup(p++); | ||
3669 | if (fl != NULL) { | 3836 | if (fl != NULL) { |
3670 | fl->fl_start = (loff_t)offset; | 3837 | fl->fl_start = (loff_t)offset; |
3671 | fl->fl_end = fl->fl_start + (loff_t)length - 1; | 3838 | fl->fl_end = fl->fl_start + (loff_t)length - 1; |
@@ -3676,23 +3843,27 @@ static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl) | |||
3676 | fl->fl_type = F_RDLCK; | 3843 | fl->fl_type = F_RDLCK; |
3677 | fl->fl_pid = 0; | 3844 | fl->fl_pid = 0; |
3678 | } | 3845 | } |
3679 | READ64(clientid); | 3846 | p = xdr_decode_hyper(p, &clientid); |
3680 | READ32(namelen); | 3847 | namelen = be32_to_cpup(p); |
3681 | READ_BUF(namelen); | 3848 | p = xdr_inline_decode(xdr, namelen); |
3682 | return -NFS4ERR_DENIED; | 3849 | if (likely(p)) |
3850 | return -NFS4ERR_DENIED; | ||
3851 | out_overflow: | ||
3852 | print_overflow_msg(__func__, xdr); | ||
3853 | return -EIO; | ||
3683 | } | 3854 | } |
3684 | 3855 | ||
3685 | static int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res) | 3856 | static int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res) |
3686 | { | 3857 | { |
3687 | __be32 *p; | ||
3688 | int status; | 3858 | int status; |
3689 | 3859 | ||
3690 | status = decode_op_hdr(xdr, OP_LOCK); | 3860 | status = decode_op_hdr(xdr, OP_LOCK); |
3691 | if (status == -EIO) | 3861 | if (status == -EIO) |
3692 | goto out; | 3862 | goto out; |
3693 | if (status == 0) { | 3863 | if (status == 0) { |
3694 | READ_BUF(NFS4_STATEID_SIZE); | 3864 | status = decode_stateid(xdr, &res->stateid); |
3695 | COPYMEM(res->stateid.data, NFS4_STATEID_SIZE); | 3865 | if (unlikely(status)) |
3866 | goto out; | ||
3696 | } else if (status == -NFS4ERR_DENIED) | 3867 | } else if (status == -NFS4ERR_DENIED) |
3697 | status = decode_lock_denied(xdr, NULL); | 3868 | status = decode_lock_denied(xdr, NULL); |
3698 | if (res->open_seqid != NULL) | 3869 | if (res->open_seqid != NULL) |
@@ -3713,16 +3884,13 @@ static int decode_lockt(struct xdr_stream *xdr, struct nfs_lockt_res *res) | |||
3713 | 3884 | ||
3714 | static int decode_locku(struct xdr_stream *xdr, struct nfs_locku_res *res) | 3885 | static int decode_locku(struct xdr_stream *xdr, struct nfs_locku_res *res) |
3715 | { | 3886 | { |
3716 | __be32 *p; | ||
3717 | int status; | 3887 | int status; |
3718 | 3888 | ||
3719 | status = decode_op_hdr(xdr, OP_LOCKU); | 3889 | status = decode_op_hdr(xdr, OP_LOCKU); |
3720 | if (status != -EIO) | 3890 | if (status != -EIO) |
3721 | nfs_increment_lock_seqid(status, res->seqid); | 3891 | nfs_increment_lock_seqid(status, res->seqid); |
3722 | if (status == 0) { | 3892 | if (status == 0) |
3723 | READ_BUF(NFS4_STATEID_SIZE); | 3893 | status = decode_stateid(xdr, &res->stateid); |
3724 | COPYMEM(res->stateid.data, NFS4_STATEID_SIZE); | ||
3725 | } | ||
3726 | return status; | 3894 | return status; |
3727 | } | 3895 | } |
3728 | 3896 | ||
@@ -3737,34 +3905,46 @@ static int decode_space_limit(struct xdr_stream *xdr, u64 *maxsize) | |||
3737 | __be32 *p; | 3905 | __be32 *p; |
3738 | uint32_t limit_type, nblocks, blocksize; | 3906 | uint32_t limit_type, nblocks, blocksize; |
3739 | 3907 | ||
3740 | READ_BUF(12); | 3908 | p = xdr_inline_decode(xdr, 12); |
3741 | READ32(limit_type); | 3909 | if (unlikely(!p)) |
3910 | goto out_overflow; | ||
3911 | limit_type = be32_to_cpup(p++); | ||
3742 | switch (limit_type) { | 3912 | switch (limit_type) { |
3743 | case 1: | 3913 | case 1: |
3744 | READ64(*maxsize); | 3914 | xdr_decode_hyper(p, maxsize); |
3745 | break; | 3915 | break; |
3746 | case 2: | 3916 | case 2: |
3747 | READ32(nblocks); | 3917 | nblocks = be32_to_cpup(p++); |
3748 | READ32(blocksize); | 3918 | blocksize = be32_to_cpup(p); |
3749 | *maxsize = (uint64_t)nblocks * (uint64_t)blocksize; | 3919 | *maxsize = (uint64_t)nblocks * (uint64_t)blocksize; |
3750 | } | 3920 | } |
3751 | return 0; | 3921 | return 0; |
3922 | out_overflow: | ||
3923 | print_overflow_msg(__func__, xdr); | ||
3924 | return -EIO; | ||
3752 | } | 3925 | } |
3753 | 3926 | ||
3754 | static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) | 3927 | static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) |
3755 | { | 3928 | { |
3756 | __be32 *p; | 3929 | __be32 *p; |
3757 | uint32_t delegation_type; | 3930 | uint32_t delegation_type; |
3931 | int status; | ||
3758 | 3932 | ||
3759 | READ_BUF(4); | 3933 | p = xdr_inline_decode(xdr, 4); |
3760 | READ32(delegation_type); | 3934 | if (unlikely(!p)) |
3935 | goto out_overflow; | ||
3936 | delegation_type = be32_to_cpup(p); | ||
3761 | if (delegation_type == NFS4_OPEN_DELEGATE_NONE) { | 3937 | if (delegation_type == NFS4_OPEN_DELEGATE_NONE) { |
3762 | res->delegation_type = 0; | 3938 | res->delegation_type = 0; |
3763 | return 0; | 3939 | return 0; |
3764 | } | 3940 | } |
3765 | READ_BUF(NFS4_STATEID_SIZE+4); | 3941 | status = decode_stateid(xdr, &res->delegation); |
3766 | COPYMEM(res->delegation.data, NFS4_STATEID_SIZE); | 3942 | if (unlikely(status)) |
3767 | READ32(res->do_recall); | 3943 | return status; |
3944 | p = xdr_inline_decode(xdr, 4); | ||
3945 | if (unlikely(!p)) | ||
3946 | goto out_overflow; | ||
3947 | res->do_recall = be32_to_cpup(p); | ||
3768 | 3948 | ||
3769 | switch (delegation_type) { | 3949 | switch (delegation_type) { |
3770 | case NFS4_OPEN_DELEGATE_READ: | 3950 | case NFS4_OPEN_DELEGATE_READ: |
@@ -3776,6 +3956,9 @@ static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) | |||
3776 | return -EIO; | 3956 | return -EIO; |
3777 | } | 3957 | } |
3778 | return decode_ace(xdr, NULL, res->server->nfs_client); | 3958 | return decode_ace(xdr, NULL, res->server->nfs_client); |
3959 | out_overflow: | ||
3960 | print_overflow_msg(__func__, xdr); | ||
3961 | return -EIO; | ||
3779 | } | 3962 | } |
3780 | 3963 | ||
3781 | static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) | 3964 | static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) |
@@ -3787,23 +3970,27 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) | |||
3787 | status = decode_op_hdr(xdr, OP_OPEN); | 3970 | status = decode_op_hdr(xdr, OP_OPEN); |
3788 | if (status != -EIO) | 3971 | if (status != -EIO) |
3789 | nfs_increment_open_seqid(status, res->seqid); | 3972 | nfs_increment_open_seqid(status, res->seqid); |
3790 | if (status) | 3973 | if (!status) |
3974 | status = decode_stateid(xdr, &res->stateid); | ||
3975 | if (unlikely(status)) | ||
3791 | return status; | 3976 | return status; |
3792 | READ_BUF(NFS4_STATEID_SIZE); | ||
3793 | COPYMEM(res->stateid.data, NFS4_STATEID_SIZE); | ||
3794 | 3977 | ||
3795 | decode_change_info(xdr, &res->cinfo); | 3978 | decode_change_info(xdr, &res->cinfo); |
3796 | 3979 | ||
3797 | READ_BUF(8); | 3980 | p = xdr_inline_decode(xdr, 8); |
3798 | READ32(res->rflags); | 3981 | if (unlikely(!p)) |
3799 | READ32(bmlen); | 3982 | goto out_overflow; |
3983 | res->rflags = be32_to_cpup(p++); | ||
3984 | bmlen = be32_to_cpup(p); | ||
3800 | if (bmlen > 10) | 3985 | if (bmlen > 10) |
3801 | goto xdr_error; | 3986 | goto xdr_error; |
3802 | 3987 | ||
3803 | READ_BUF(bmlen << 2); | 3988 | p = xdr_inline_decode(xdr, bmlen << 2); |
3989 | if (unlikely(!p)) | ||
3990 | goto out_overflow; | ||
3804 | savewords = min_t(uint32_t, bmlen, NFS4_BITMAP_SIZE); | 3991 | savewords = min_t(uint32_t, bmlen, NFS4_BITMAP_SIZE); |
3805 | for (i = 0; i < savewords; ++i) | 3992 | for (i = 0; i < savewords; ++i) |
3806 | READ32(res->attrset[i]); | 3993 | res->attrset[i] = be32_to_cpup(p++); |
3807 | for (; i < NFS4_BITMAP_SIZE; i++) | 3994 | for (; i < NFS4_BITMAP_SIZE; i++) |
3808 | res->attrset[i] = 0; | 3995 | res->attrset[i] = 0; |
3809 | 3996 | ||
@@ -3811,36 +3998,33 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) | |||
3811 | xdr_error: | 3998 | xdr_error: |
3812 | dprintk("%s: Bitmap too large! Length = %u\n", __func__, bmlen); | 3999 | dprintk("%s: Bitmap too large! Length = %u\n", __func__, bmlen); |
3813 | return -EIO; | 4000 | return -EIO; |
4001 | out_overflow: | ||
4002 | print_overflow_msg(__func__, xdr); | ||
4003 | return -EIO; | ||
3814 | } | 4004 | } |
3815 | 4005 | ||
3816 | static int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmres *res) | 4006 | static int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmres *res) |
3817 | { | 4007 | { |
3818 | __be32 *p; | ||
3819 | int status; | 4008 | int status; |
3820 | 4009 | ||
3821 | status = decode_op_hdr(xdr, OP_OPEN_CONFIRM); | 4010 | status = decode_op_hdr(xdr, OP_OPEN_CONFIRM); |
3822 | if (status != -EIO) | 4011 | if (status != -EIO) |
3823 | nfs_increment_open_seqid(status, res->seqid); | 4012 | nfs_increment_open_seqid(status, res->seqid); |
3824 | if (status) | 4013 | if (!status) |
3825 | return status; | 4014 | status = decode_stateid(xdr, &res->stateid); |
3826 | READ_BUF(NFS4_STATEID_SIZE); | 4015 | return status; |
3827 | COPYMEM(res->stateid.data, NFS4_STATEID_SIZE); | ||
3828 | return 0; | ||
3829 | } | 4016 | } |
3830 | 4017 | ||
3831 | static int decode_open_downgrade(struct xdr_stream *xdr, struct nfs_closeres *res) | 4018 | static int decode_open_downgrade(struct xdr_stream *xdr, struct nfs_closeres *res) |
3832 | { | 4019 | { |
3833 | __be32 *p; | ||
3834 | int status; | 4020 | int status; |
3835 | 4021 | ||
3836 | status = decode_op_hdr(xdr, OP_OPEN_DOWNGRADE); | 4022 | status = decode_op_hdr(xdr, OP_OPEN_DOWNGRADE); |
3837 | if (status != -EIO) | 4023 | if (status != -EIO) |
3838 | nfs_increment_open_seqid(status, res->seqid); | 4024 | nfs_increment_open_seqid(status, res->seqid); |
3839 | if (status) | 4025 | if (!status) |
3840 | return status; | 4026 | status = decode_stateid(xdr, &res->stateid); |
3841 | READ_BUF(NFS4_STATEID_SIZE); | 4027 | return status; |
3842 | COPYMEM(res->stateid.data, NFS4_STATEID_SIZE); | ||
3843 | return 0; | ||
3844 | } | 4028 | } |
3845 | 4029 | ||
3846 | static int decode_putfh(struct xdr_stream *xdr) | 4030 | static int decode_putfh(struct xdr_stream *xdr) |
@@ -3863,9 +4047,11 @@ static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_ | |||
3863 | status = decode_op_hdr(xdr, OP_READ); | 4047 | status = decode_op_hdr(xdr, OP_READ); |
3864 | if (status) | 4048 | if (status) |
3865 | return status; | 4049 | return status; |
3866 | READ_BUF(8); | 4050 | p = xdr_inline_decode(xdr, 8); |
3867 | READ32(eof); | 4051 | if (unlikely(!p)) |
3868 | READ32(count); | 4052 | goto out_overflow; |
4053 | eof = be32_to_cpup(p++); | ||
4054 | count = be32_to_cpup(p); | ||
3869 | hdrlen = (u8 *) p - (u8 *) iov->iov_base; | 4055 | hdrlen = (u8 *) p - (u8 *) iov->iov_base; |
3870 | recvd = req->rq_rcv_buf.len - hdrlen; | 4056 | recvd = req->rq_rcv_buf.len - hdrlen; |
3871 | if (count > recvd) { | 4057 | if (count > recvd) { |
@@ -3878,6 +4064,9 @@ static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_ | |||
3878 | res->eof = eof; | 4064 | res->eof = eof; |
3879 | res->count = count; | 4065 | res->count = count; |
3880 | return 0; | 4066 | return 0; |
4067 | out_overflow: | ||
4068 | print_overflow_msg(__func__, xdr); | ||
4069 | return -EIO; | ||
3881 | } | 4070 | } |
3882 | 4071 | ||
3883 | static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs4_readdir_res *readdir) | 4072 | static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs4_readdir_res *readdir) |
@@ -3892,17 +4081,17 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n | |||
3892 | int status; | 4081 | int status; |
3893 | 4082 | ||
3894 | status = decode_op_hdr(xdr, OP_READDIR); | 4083 | status = decode_op_hdr(xdr, OP_READDIR); |
3895 | if (status) | 4084 | if (!status) |
4085 | status = decode_verifier(xdr, readdir->verifier.data); | ||
4086 | if (unlikely(status)) | ||
3896 | return status; | 4087 | return status; |
3897 | READ_BUF(8); | ||
3898 | COPYMEM(readdir->verifier.data, 8); | ||
3899 | dprintk("%s: verifier = %08x:%08x\n", | 4088 | dprintk("%s: verifier = %08x:%08x\n", |
3900 | __func__, | 4089 | __func__, |
3901 | ((u32 *)readdir->verifier.data)[0], | 4090 | ((u32 *)readdir->verifier.data)[0], |
3902 | ((u32 *)readdir->verifier.data)[1]); | 4091 | ((u32 *)readdir->verifier.data)[1]); |
3903 | 4092 | ||
3904 | 4093 | ||
3905 | hdrlen = (char *) p - (char *) iov->iov_base; | 4094 | hdrlen = (char *) xdr->p - (char *) iov->iov_base; |
3906 | recvd = rcvbuf->len - hdrlen; | 4095 | recvd = rcvbuf->len - hdrlen; |
3907 | if (pglen > recvd) | 4096 | if (pglen > recvd) |
3908 | pglen = recvd; | 4097 | pglen = recvd; |
@@ -3990,8 +4179,10 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) | |||
3990 | return status; | 4179 | return status; |
3991 | 4180 | ||
3992 | /* Convert length of symlink */ | 4181 | /* Convert length of symlink */ |
3993 | READ_BUF(4); | 4182 | p = xdr_inline_decode(xdr, 4); |
3994 | READ32(len); | 4183 | if (unlikely(!p)) |
4184 | goto out_overflow; | ||
4185 | len = be32_to_cpup(p); | ||
3995 | if (len >= rcvbuf->page_len || len <= 0) { | 4186 | if (len >= rcvbuf->page_len || len <= 0) { |
3996 | dprintk("nfs: server returned giant symlink!\n"); | 4187 | dprintk("nfs: server returned giant symlink!\n"); |
3997 | return -ENAMETOOLONG; | 4188 | return -ENAMETOOLONG; |
@@ -4015,6 +4206,9 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) | |||
4015 | kaddr[len+rcvbuf->page_base] = '\0'; | 4206 | kaddr[len+rcvbuf->page_base] = '\0'; |
4016 | kunmap_atomic(kaddr, KM_USER0); | 4207 | kunmap_atomic(kaddr, KM_USER0); |
4017 | return 0; | 4208 | return 0; |
4209 | out_overflow: | ||
4210 | print_overflow_msg(__func__, xdr); | ||
4211 | return -EIO; | ||
4018 | } | 4212 | } |
4019 | 4213 | ||
4020 | static int decode_remove(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) | 4214 | static int decode_remove(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) |
@@ -4112,10 +4306,16 @@ static int decode_setattr(struct xdr_stream *xdr) | |||
4112 | status = decode_op_hdr(xdr, OP_SETATTR); | 4306 | status = decode_op_hdr(xdr, OP_SETATTR); |
4113 | if (status) | 4307 | if (status) |
4114 | return status; | 4308 | return status; |
4115 | READ_BUF(4); | 4309 | p = xdr_inline_decode(xdr, 4); |
4116 | READ32(bmlen); | 4310 | if (unlikely(!p)) |
4117 | READ_BUF(bmlen << 2); | 4311 | goto out_overflow; |
4118 | return 0; | 4312 | bmlen = be32_to_cpup(p); |
4313 | p = xdr_inline_decode(xdr, bmlen << 2); | ||
4314 | if (likely(p)) | ||
4315 | return 0; | ||
4316 | out_overflow: | ||
4317 | print_overflow_msg(__func__, xdr); | ||
4318 | return -EIO; | ||
4119 | } | 4319 | } |
4120 | 4320 | ||
4121 | static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp) | 4321 | static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp) |
@@ -4124,35 +4324,50 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp) | |||
4124 | uint32_t opnum; | 4324 | uint32_t opnum; |
4125 | int32_t nfserr; | 4325 | int32_t nfserr; |
4126 | 4326 | ||
4127 | READ_BUF(8); | 4327 | p = xdr_inline_decode(xdr, 8); |
4128 | READ32(opnum); | 4328 | if (unlikely(!p)) |
4329 | goto out_overflow; | ||
4330 | opnum = be32_to_cpup(p++); | ||
4129 | if (opnum != OP_SETCLIENTID) { | 4331 | if (opnum != OP_SETCLIENTID) { |
4130 | dprintk("nfs: decode_setclientid: Server returned operation" | 4332 | dprintk("nfs: decode_setclientid: Server returned operation" |
4131 | " %d\n", opnum); | 4333 | " %d\n", opnum); |
4132 | return -EIO; | 4334 | return -EIO; |
4133 | } | 4335 | } |
4134 | READ32(nfserr); | 4336 | nfserr = be32_to_cpup(p); |
4135 | if (nfserr == NFS_OK) { | 4337 | if (nfserr == NFS_OK) { |
4136 | READ_BUF(8 + NFS4_VERIFIER_SIZE); | 4338 | p = xdr_inline_decode(xdr, 8 + NFS4_VERIFIER_SIZE); |
4137 | READ64(clp->cl_clientid); | 4339 | if (unlikely(!p)) |
4138 | COPYMEM(clp->cl_confirm.data, NFS4_VERIFIER_SIZE); | 4340 | goto out_overflow; |
4341 | p = xdr_decode_hyper(p, &clp->cl_clientid); | ||
4342 | memcpy(clp->cl_confirm.data, p, NFS4_VERIFIER_SIZE); | ||
4139 | } else if (nfserr == NFSERR_CLID_INUSE) { | 4343 | } else if (nfserr == NFSERR_CLID_INUSE) { |
4140 | uint32_t len; | 4344 | uint32_t len; |
4141 | 4345 | ||
4142 | /* skip netid string */ | 4346 | /* skip netid string */ |
4143 | READ_BUF(4); | 4347 | p = xdr_inline_decode(xdr, 4); |
4144 | READ32(len); | 4348 | if (unlikely(!p)) |
4145 | READ_BUF(len); | 4349 | goto out_overflow; |
4350 | len = be32_to_cpup(p); | ||
4351 | p = xdr_inline_decode(xdr, len); | ||
4352 | if (unlikely(!p)) | ||
4353 | goto out_overflow; | ||
4146 | 4354 | ||
4147 | /* skip uaddr string */ | 4355 | /* skip uaddr string */ |
4148 | READ_BUF(4); | 4356 | p = xdr_inline_decode(xdr, 4); |
4149 | READ32(len); | 4357 | if (unlikely(!p)) |
4150 | READ_BUF(len); | 4358 | goto out_overflow; |
4359 | len = be32_to_cpup(p); | ||
4360 | p = xdr_inline_decode(xdr, len); | ||
4361 | if (unlikely(!p)) | ||
4362 | goto out_overflow; | ||
4151 | return -NFSERR_CLID_INUSE; | 4363 | return -NFSERR_CLID_INUSE; |
4152 | } else | 4364 | } else |
4153 | return nfs4_stat_to_errno(nfserr); | 4365 | return nfs4_stat_to_errno(nfserr); |
4154 | 4366 | ||
4155 | return 0; | 4367 | return 0; |
4368 | out_overflow: | ||
4369 | print_overflow_msg(__func__, xdr); | ||
4370 | return -EIO; | ||
4156 | } | 4371 | } |
4157 | 4372 | ||
4158 | static int decode_setclientid_confirm(struct xdr_stream *xdr) | 4373 | static int decode_setclientid_confirm(struct xdr_stream *xdr) |
@@ -4169,11 +4384,16 @@ static int decode_write(struct xdr_stream *xdr, struct nfs_writeres *res) | |||
4169 | if (status) | 4384 | if (status) |
4170 | return status; | 4385 | return status; |
4171 | 4386 | ||
4172 | READ_BUF(16); | 4387 | p = xdr_inline_decode(xdr, 16); |
4173 | READ32(res->count); | 4388 | if (unlikely(!p)) |
4174 | READ32(res->verf->committed); | 4389 | goto out_overflow; |
4175 | COPYMEM(res->verf->verifier, 8); | 4390 | res->count = be32_to_cpup(p++); |
4391 | res->verf->committed = be32_to_cpup(p++); | ||
4392 | memcpy(res->verf->verifier, p, 8); | ||
4176 | return 0; | 4393 | return 0; |
4394 | out_overflow: | ||
4395 | print_overflow_msg(__func__, xdr); | ||
4396 | return -EIO; | ||
4177 | } | 4397 | } |
4178 | 4398 | ||
4179 | static int decode_delegreturn(struct xdr_stream *xdr) | 4399 | static int decode_delegreturn(struct xdr_stream *xdr) |
@@ -4187,6 +4407,7 @@ static int decode_exchange_id(struct xdr_stream *xdr, | |||
4187 | { | 4407 | { |
4188 | __be32 *p; | 4408 | __be32 *p; |
4189 | uint32_t dummy; | 4409 | uint32_t dummy; |
4410 | char *dummy_str; | ||
4190 | int status; | 4411 | int status; |
4191 | struct nfs_client *clp = res->client; | 4412 | struct nfs_client *clp = res->client; |
4192 | 4413 | ||
@@ -4194,36 +4415,45 @@ static int decode_exchange_id(struct xdr_stream *xdr, | |||
4194 | if (status) | 4415 | if (status) |
4195 | return status; | 4416 | return status; |
4196 | 4417 | ||
4197 | READ_BUF(8); | 4418 | p = xdr_inline_decode(xdr, 8); |
4198 | READ64(clp->cl_ex_clid); | 4419 | if (unlikely(!p)) |
4199 | READ_BUF(12); | 4420 | goto out_overflow; |
4200 | READ32(clp->cl_seqid); | 4421 | xdr_decode_hyper(p, &clp->cl_ex_clid); |
4201 | READ32(clp->cl_exchange_flags); | 4422 | p = xdr_inline_decode(xdr, 12); |
4423 | if (unlikely(!p)) | ||
4424 | goto out_overflow; | ||
4425 | clp->cl_seqid = be32_to_cpup(p++); | ||
4426 | clp->cl_exchange_flags = be32_to_cpup(p++); | ||
4202 | 4427 | ||
4203 | /* We ask for SP4_NONE */ | 4428 | /* We ask for SP4_NONE */ |
4204 | READ32(dummy); | 4429 | dummy = be32_to_cpup(p); |
4205 | if (dummy != SP4_NONE) | 4430 | if (dummy != SP4_NONE) |
4206 | return -EIO; | 4431 | return -EIO; |
4207 | 4432 | ||
4208 | /* Throw away minor_id */ | 4433 | /* Throw away minor_id */ |
4209 | READ_BUF(8); | 4434 | p = xdr_inline_decode(xdr, 8); |
4435 | if (unlikely(!p)) | ||
4436 | goto out_overflow; | ||
4210 | 4437 | ||
4211 | /* Throw away Major id */ | 4438 | /* Throw away Major id */ |
4212 | READ_BUF(4); | 4439 | status = decode_opaque_inline(xdr, &dummy, &dummy_str); |
4213 | READ32(dummy); | 4440 | if (unlikely(status)) |
4214 | READ_BUF(dummy); | 4441 | return status; |
4215 | 4442 | ||
4216 | /* Throw away server_scope */ | 4443 | /* Throw away server_scope */ |
4217 | READ_BUF(4); | 4444 | status = decode_opaque_inline(xdr, &dummy, &dummy_str); |
4218 | READ32(dummy); | 4445 | if (unlikely(status)) |
4219 | READ_BUF(dummy); | 4446 | return status; |
4220 | 4447 | ||
4221 | /* Throw away Implementation id array */ | 4448 | /* Throw away Implementation id array */ |
4222 | READ_BUF(4); | 4449 | status = decode_opaque_inline(xdr, &dummy, &dummy_str); |
4223 | READ32(dummy); | 4450 | if (unlikely(status)) |
4224 | READ_BUF(dummy); | 4451 | return status; |
4225 | 4452 | ||
4226 | return 0; | 4453 | return 0; |
4454 | out_overflow: | ||
4455 | print_overflow_msg(__func__, xdr); | ||
4456 | return -EIO; | ||
4227 | } | 4457 | } |
4228 | 4458 | ||
4229 | static int decode_chan_attrs(struct xdr_stream *xdr, | 4459 | static int decode_chan_attrs(struct xdr_stream *xdr, |
@@ -4232,22 +4462,35 @@ static int decode_chan_attrs(struct xdr_stream *xdr, | |||
4232 | __be32 *p; | 4462 | __be32 *p; |
4233 | u32 nr_attrs; | 4463 | u32 nr_attrs; |
4234 | 4464 | ||
4235 | READ_BUF(28); | 4465 | p = xdr_inline_decode(xdr, 28); |
4236 | READ32(attrs->headerpadsz); | 4466 | if (unlikely(!p)) |
4237 | READ32(attrs->max_rqst_sz); | 4467 | goto out_overflow; |
4238 | READ32(attrs->max_resp_sz); | 4468 | attrs->headerpadsz = be32_to_cpup(p++); |
4239 | READ32(attrs->max_resp_sz_cached); | 4469 | attrs->max_rqst_sz = be32_to_cpup(p++); |
4240 | READ32(attrs->max_ops); | 4470 | attrs->max_resp_sz = be32_to_cpup(p++); |
4241 | READ32(attrs->max_reqs); | 4471 | attrs->max_resp_sz_cached = be32_to_cpup(p++); |
4242 | READ32(nr_attrs); | 4472 | attrs->max_ops = be32_to_cpup(p++); |
4473 | attrs->max_reqs = be32_to_cpup(p++); | ||
4474 | nr_attrs = be32_to_cpup(p); | ||
4243 | if (unlikely(nr_attrs > 1)) { | 4475 | if (unlikely(nr_attrs > 1)) { |
4244 | printk(KERN_WARNING "%s: Invalid rdma channel attrs count %u\n", | 4476 | printk(KERN_WARNING "%s: Invalid rdma channel attrs count %u\n", |
4245 | __func__, nr_attrs); | 4477 | __func__, nr_attrs); |
4246 | return -EINVAL; | 4478 | return -EINVAL; |
4247 | } | 4479 | } |
4248 | if (nr_attrs == 1) | 4480 | if (nr_attrs == 1) { |
4249 | READ_BUF(4); /* skip rdma_attrs */ | 4481 | p = xdr_inline_decode(xdr, 4); /* skip rdma_attrs */ |
4482 | if (unlikely(!p)) | ||
4483 | goto out_overflow; | ||
4484 | } | ||
4250 | return 0; | 4485 | return 0; |
4486 | out_overflow: | ||
4487 | print_overflow_msg(__func__, xdr); | ||
4488 | return -EIO; | ||
4489 | } | ||
4490 | |||
4491 | static int decode_sessionid(struct xdr_stream *xdr, struct nfs4_sessionid *sid) | ||
4492 | { | ||
4493 | return decode_opaque_fixed(xdr, sid->data, NFS4_MAX_SESSIONID_LEN); | ||
4251 | } | 4494 | } |
4252 | 4495 | ||
4253 | static int decode_create_session(struct xdr_stream *xdr, | 4496 | static int decode_create_session(struct xdr_stream *xdr, |
@@ -4259,24 +4502,26 @@ static int decode_create_session(struct xdr_stream *xdr, | |||
4259 | struct nfs4_session *session = clp->cl_session; | 4502 | struct nfs4_session *session = clp->cl_session; |
4260 | 4503 | ||
4261 | status = decode_op_hdr(xdr, OP_CREATE_SESSION); | 4504 | status = decode_op_hdr(xdr, OP_CREATE_SESSION); |
4262 | 4505 | if (!status) | |
4263 | if (status) | 4506 | status = decode_sessionid(xdr, &session->sess_id); |
4507 | if (unlikely(status)) | ||
4264 | return status; | 4508 | return status; |
4265 | 4509 | ||
4266 | /* sessionid */ | ||
4267 | READ_BUF(NFS4_MAX_SESSIONID_LEN); | ||
4268 | COPYMEM(&session->sess_id, NFS4_MAX_SESSIONID_LEN); | ||
4269 | |||
4270 | /* seqid, flags */ | 4510 | /* seqid, flags */ |
4271 | READ_BUF(8); | 4511 | p = xdr_inline_decode(xdr, 8); |
4272 | READ32(clp->cl_seqid); | 4512 | if (unlikely(!p)) |
4273 | READ32(session->flags); | 4513 | goto out_overflow; |
4514 | clp->cl_seqid = be32_to_cpup(p++); | ||
4515 | session->flags = be32_to_cpup(p); | ||
4274 | 4516 | ||
4275 | /* Channel attributes */ | 4517 | /* Channel attributes */ |
4276 | status = decode_chan_attrs(xdr, &session->fc_attrs); | 4518 | status = decode_chan_attrs(xdr, &session->fc_attrs); |
4277 | if (!status) | 4519 | if (!status) |
4278 | status = decode_chan_attrs(xdr, &session->bc_attrs); | 4520 | status = decode_chan_attrs(xdr, &session->bc_attrs); |
4279 | return status; | 4521 | return status; |
4522 | out_overflow: | ||
4523 | print_overflow_msg(__func__, xdr); | ||
4524 | return -EIO; | ||
4280 | } | 4525 | } |
4281 | 4526 | ||
4282 | static int decode_destroy_session(struct xdr_stream *xdr, void *dummy) | 4527 | static int decode_destroy_session(struct xdr_stream *xdr, void *dummy) |
@@ -4300,7 +4545,9 @@ static int decode_sequence(struct xdr_stream *xdr, | |||
4300 | return 0; | 4545 | return 0; |
4301 | 4546 | ||
4302 | status = decode_op_hdr(xdr, OP_SEQUENCE); | 4547 | status = decode_op_hdr(xdr, OP_SEQUENCE); |
4303 | if (status) | 4548 | if (!status) |
4549 | status = decode_sessionid(xdr, &id); | ||
4550 | if (unlikely(status)) | ||
4304 | goto out_err; | 4551 | goto out_err; |
4305 | 4552 | ||
4306 | /* | 4553 | /* |
@@ -4309,36 +4556,43 @@ static int decode_sequence(struct xdr_stream *xdr, | |||
4309 | */ | 4556 | */ |
4310 | status = -ESERVERFAULT; | 4557 | status = -ESERVERFAULT; |
4311 | 4558 | ||
4312 | slot = &res->sr_session->fc_slot_table.slots[res->sr_slotid]; | ||
4313 | READ_BUF(NFS4_MAX_SESSIONID_LEN + 20); | ||
4314 | COPYMEM(id.data, NFS4_MAX_SESSIONID_LEN); | ||
4315 | if (memcmp(id.data, res->sr_session->sess_id.data, | 4559 | if (memcmp(id.data, res->sr_session->sess_id.data, |
4316 | NFS4_MAX_SESSIONID_LEN)) { | 4560 | NFS4_MAX_SESSIONID_LEN)) { |
4317 | dprintk("%s Invalid session id\n", __func__); | 4561 | dprintk("%s Invalid session id\n", __func__); |
4318 | goto out_err; | 4562 | goto out_err; |
4319 | } | 4563 | } |
4564 | |||
4565 | p = xdr_inline_decode(xdr, 20); | ||
4566 | if (unlikely(!p)) | ||
4567 | goto out_overflow; | ||
4568 | |||
4320 | /* seqid */ | 4569 | /* seqid */ |
4321 | READ32(dummy); | 4570 | slot = &res->sr_session->fc_slot_table.slots[res->sr_slotid]; |
4571 | dummy = be32_to_cpup(p++); | ||
4322 | if (dummy != slot->seq_nr) { | 4572 | if (dummy != slot->seq_nr) { |
4323 | dprintk("%s Invalid sequence number\n", __func__); | 4573 | dprintk("%s Invalid sequence number\n", __func__); |
4324 | goto out_err; | 4574 | goto out_err; |
4325 | } | 4575 | } |
4326 | /* slot id */ | 4576 | /* slot id */ |
4327 | READ32(dummy); | 4577 | dummy = be32_to_cpup(p++); |
4328 | if (dummy != res->sr_slotid) { | 4578 | if (dummy != res->sr_slotid) { |
4329 | dprintk("%s Invalid slot id\n", __func__); | 4579 | dprintk("%s Invalid slot id\n", __func__); |
4330 | goto out_err; | 4580 | goto out_err; |
4331 | } | 4581 | } |
4332 | /* highest slot id - currently not processed */ | 4582 | /* highest slot id - currently not processed */ |
4333 | READ32(dummy); | 4583 | dummy = be32_to_cpup(p++); |
4334 | /* target highest slot id - currently not processed */ | 4584 | /* target highest slot id - currently not processed */ |
4335 | READ32(dummy); | 4585 | dummy = be32_to_cpup(p++); |
4336 | /* result flags - currently not processed */ | 4586 | /* result flags - currently not processed */ |
4337 | READ32(dummy); | 4587 | dummy = be32_to_cpup(p); |
4338 | status = 0; | 4588 | status = 0; |
4339 | out_err: | 4589 | out_err: |
4340 | res->sr_status = status; | 4590 | res->sr_status = status; |
4341 | return status; | 4591 | return status; |
4592 | out_overflow: | ||
4593 | print_overflow_msg(__func__, xdr); | ||
4594 | status = -EIO; | ||
4595 | goto out_err; | ||
4342 | #else /* CONFIG_NFS_V4_1 */ | 4596 | #else /* CONFIG_NFS_V4_1 */ |
4343 | return 0; | 4597 | return 0; |
4344 | #endif /* CONFIG_NFS_V4_1 */ | 4598 | #endif /* CONFIG_NFS_V4_1 */ |
@@ -4370,7 +4624,8 @@ static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, __be32 *p, struct | |||
4370 | status = decode_open_downgrade(&xdr, res); | 4624 | status = decode_open_downgrade(&xdr, res); |
4371 | if (status != 0) | 4625 | if (status != 0) |
4372 | goto out; | 4626 | goto out; |
4373 | decode_getfattr(&xdr, res->fattr, res->server); | 4627 | decode_getfattr(&xdr, res->fattr, res->server, |
4628 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
4374 | out: | 4629 | out: |
4375 | return status; | 4630 | return status; |
4376 | } | 4631 | } |
@@ -4397,7 +4652,8 @@ static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_ac | |||
4397 | status = decode_access(&xdr, res); | 4652 | status = decode_access(&xdr, res); |
4398 | if (status != 0) | 4653 | if (status != 0) |
4399 | goto out; | 4654 | goto out; |
4400 | decode_getfattr(&xdr, res->fattr, res->server); | 4655 | decode_getfattr(&xdr, res->fattr, res->server, |
4656 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
4401 | out: | 4657 | out: |
4402 | return status; | 4658 | return status; |
4403 | } | 4659 | } |
@@ -4424,7 +4680,8 @@ static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_lo | |||
4424 | goto out; | 4680 | goto out; |
4425 | if ((status = decode_getfh(&xdr, res->fh)) != 0) | 4681 | if ((status = decode_getfh(&xdr, res->fh)) != 0) |
4426 | goto out; | 4682 | goto out; |
4427 | status = decode_getfattr(&xdr, res->fattr, res->server); | 4683 | status = decode_getfattr(&xdr, res->fattr, res->server |
4684 | ,!RPC_IS_ASYNC(rqstp->rq_task)); | ||
4428 | out: | 4685 | out: |
4429 | return status; | 4686 | return status; |
4430 | } | 4687 | } |
@@ -4448,7 +4705,8 @@ static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, __be32 *p, struct nf | |||
4448 | if ((status = decode_putrootfh(&xdr)) != 0) | 4705 | if ((status = decode_putrootfh(&xdr)) != 0) |
4449 | goto out; | 4706 | goto out; |
4450 | if ((status = decode_getfh(&xdr, res->fh)) == 0) | 4707 | if ((status = decode_getfh(&xdr, res->fh)) == 0) |
4451 | status = decode_getfattr(&xdr, res->fattr, res->server); | 4708 | status = decode_getfattr(&xdr, res->fattr, res->server, |
4709 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
4452 | out: | 4710 | out: |
4453 | return status; | 4711 | return status; |
4454 | } | 4712 | } |
@@ -4473,7 +4731,8 @@ static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, __be32 *p, struct nfs_rem | |||
4473 | goto out; | 4731 | goto out; |
4474 | if ((status = decode_remove(&xdr, &res->cinfo)) != 0) | 4732 | if ((status = decode_remove(&xdr, &res->cinfo)) != 0) |
4475 | goto out; | 4733 | goto out; |
4476 | decode_getfattr(&xdr, &res->dir_attr, res->server); | 4734 | decode_getfattr(&xdr, &res->dir_attr, res->server, |
4735 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
4477 | out: | 4736 | out: |
4478 | return status; | 4737 | return status; |
4479 | } | 4738 | } |
@@ -4503,11 +4762,13 @@ static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_re | |||
4503 | if ((status = decode_rename(&xdr, &res->old_cinfo, &res->new_cinfo)) != 0) | 4762 | if ((status = decode_rename(&xdr, &res->old_cinfo, &res->new_cinfo)) != 0) |
4504 | goto out; | 4763 | goto out; |
4505 | /* Current FH is target directory */ | 4764 | /* Current FH is target directory */ |
4506 | if (decode_getfattr(&xdr, res->new_fattr, res->server) != 0) | 4765 | if (decode_getfattr(&xdr, res->new_fattr, res->server, |
4766 | !RPC_IS_ASYNC(rqstp->rq_task)) != 0) | ||
4507 | goto out; | 4767 | goto out; |
4508 | if ((status = decode_restorefh(&xdr)) != 0) | 4768 | if ((status = decode_restorefh(&xdr)) != 0) |
4509 | goto out; | 4769 | goto out; |
4510 | decode_getfattr(&xdr, res->old_fattr, res->server); | 4770 | decode_getfattr(&xdr, res->old_fattr, res->server, |
4771 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
4511 | out: | 4772 | out: |
4512 | return status; | 4773 | return status; |
4513 | } | 4774 | } |
@@ -4540,11 +4801,13 @@ static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_link | |||
4540 | * Note order: OP_LINK leaves the directory as the current | 4801 | * Note order: OP_LINK leaves the directory as the current |
4541 | * filehandle. | 4802 | * filehandle. |
4542 | */ | 4803 | */ |
4543 | if (decode_getfattr(&xdr, res->dir_attr, res->server) != 0) | 4804 | if (decode_getfattr(&xdr, res->dir_attr, res->server, |
4805 | !RPC_IS_ASYNC(rqstp->rq_task)) != 0) | ||
4544 | goto out; | 4806 | goto out; |
4545 | if ((status = decode_restorefh(&xdr)) != 0) | 4807 | if ((status = decode_restorefh(&xdr)) != 0) |
4546 | goto out; | 4808 | goto out; |
4547 | decode_getfattr(&xdr, res->fattr, res->server); | 4809 | decode_getfattr(&xdr, res->fattr, res->server, |
4810 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
4548 | out: | 4811 | out: |
4549 | return status; | 4812 | return status; |
4550 | } | 4813 | } |
@@ -4573,11 +4836,13 @@ static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_cr | |||
4573 | goto out; | 4836 | goto out; |
4574 | if ((status = decode_getfh(&xdr, res->fh)) != 0) | 4837 | if ((status = decode_getfh(&xdr, res->fh)) != 0) |
4575 | goto out; | 4838 | goto out; |
4576 | if (decode_getfattr(&xdr, res->fattr, res->server) != 0) | 4839 | if (decode_getfattr(&xdr, res->fattr, res->server, |
4840 | !RPC_IS_ASYNC(rqstp->rq_task)) != 0) | ||
4577 | goto out; | 4841 | goto out; |
4578 | if ((status = decode_restorefh(&xdr)) != 0) | 4842 | if ((status = decode_restorefh(&xdr)) != 0) |
4579 | goto out; | 4843 | goto out; |
4580 | decode_getfattr(&xdr, res->dir_fattr, res->server); | 4844 | decode_getfattr(&xdr, res->dir_fattr, res->server, |
4845 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
4581 | out: | 4846 | out: |
4582 | return status; | 4847 | return status; |
4583 | } | 4848 | } |
@@ -4609,7 +4874,8 @@ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_g | |||
4609 | status = decode_putfh(&xdr); | 4874 | status = decode_putfh(&xdr); |
4610 | if (status) | 4875 | if (status) |
4611 | goto out; | 4876 | goto out; |
4612 | status = decode_getfattr(&xdr, res->fattr, res->server); | 4877 | status = decode_getfattr(&xdr, res->fattr, res->server, |
4878 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
4613 | out: | 4879 | out: |
4614 | return status; | 4880 | return status; |
4615 | } | 4881 | } |
@@ -4716,7 +4982,8 @@ static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, __be32 *p, struct nfs_clos | |||
4716 | * an ESTALE error. Shouldn't be a problem, | 4982 | * an ESTALE error. Shouldn't be a problem, |
4717 | * though, since fattr->valid will remain unset. | 4983 | * though, since fattr->valid will remain unset. |
4718 | */ | 4984 | */ |
4719 | decode_getfattr(&xdr, res->fattr, res->server); | 4985 | decode_getfattr(&xdr, res->fattr, res->server, |
4986 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
4720 | out: | 4987 | out: |
4721 | return status; | 4988 | return status; |
4722 | } | 4989 | } |
@@ -4748,11 +5015,13 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openr | |||
4748 | goto out; | 5015 | goto out; |
4749 | if (decode_getfh(&xdr, &res->fh) != 0) | 5016 | if (decode_getfh(&xdr, &res->fh) != 0) |
4750 | goto out; | 5017 | goto out; |
4751 | if (decode_getfattr(&xdr, res->f_attr, res->server) != 0) | 5018 | if (decode_getfattr(&xdr, res->f_attr, res->server, |
5019 | !RPC_IS_ASYNC(rqstp->rq_task)) != 0) | ||
4752 | goto out; | 5020 | goto out; |
4753 | if (decode_restorefh(&xdr) != 0) | 5021 | if (decode_restorefh(&xdr) != 0) |
4754 | goto out; | 5022 | goto out; |
4755 | decode_getfattr(&xdr, res->dir_attr, res->server); | 5023 | decode_getfattr(&xdr, res->dir_attr, res->server, |
5024 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
4756 | out: | 5025 | out: |
4757 | return status; | 5026 | return status; |
4758 | } | 5027 | } |
@@ -4800,7 +5069,8 @@ static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, __be32 *p, struct nf | |||
4800 | status = decode_open(&xdr, res); | 5069 | status = decode_open(&xdr, res); |
4801 | if (status) | 5070 | if (status) |
4802 | goto out; | 5071 | goto out; |
4803 | decode_getfattr(&xdr, res->f_attr, res->server); | 5072 | decode_getfattr(&xdr, res->f_attr, res->server, |
5073 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
4804 | out: | 5074 | out: |
4805 | return status; | 5075 | return status; |
4806 | } | 5076 | } |
@@ -4827,7 +5097,8 @@ static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_se | |||
4827 | status = decode_setattr(&xdr); | 5097 | status = decode_setattr(&xdr); |
4828 | if (status) | 5098 | if (status) |
4829 | goto out; | 5099 | goto out; |
4830 | decode_getfattr(&xdr, res->fattr, res->server); | 5100 | decode_getfattr(&xdr, res->fattr, res->server, |
5101 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
4831 | out: | 5102 | out: |
4832 | return status; | 5103 | return status; |
4833 | } | 5104 | } |
@@ -5001,7 +5272,8 @@ static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, __be32 *p, struct nfs_writ | |||
5001 | status = decode_write(&xdr, res); | 5272 | status = decode_write(&xdr, res); |
5002 | if (status) | 5273 | if (status) |
5003 | goto out; | 5274 | goto out; |
5004 | decode_getfattr(&xdr, res->fattr, res->server); | 5275 | decode_getfattr(&xdr, res->fattr, res->server, |
5276 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
5005 | if (!status) | 5277 | if (!status) |
5006 | status = res->count; | 5278 | status = res->count; |
5007 | out: | 5279 | out: |
@@ -5030,7 +5302,8 @@ static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, __be32 *p, struct nfs_wri | |||
5030 | status = decode_commit(&xdr, res); | 5302 | status = decode_commit(&xdr, res); |
5031 | if (status) | 5303 | if (status) |
5032 | goto out; | 5304 | goto out; |
5033 | decode_getfattr(&xdr, res->fattr, res->server); | 5305 | decode_getfattr(&xdr, res->fattr, res->server, |
5306 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
5034 | out: | 5307 | out: |
5035 | return status; | 5308 | return status; |
5036 | } | 5309 | } |
@@ -5194,7 +5467,8 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, __be32 *p, struct nf | |||
5194 | if (status != 0) | 5467 | if (status != 0) |
5195 | goto out; | 5468 | goto out; |
5196 | status = decode_delegreturn(&xdr); | 5469 | status = decode_delegreturn(&xdr); |
5197 | decode_getfattr(&xdr, res->fattr, res->server); | 5470 | decode_getfattr(&xdr, res->fattr, res->server, |
5471 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
5198 | out: | 5472 | out: |
5199 | return status; | 5473 | return status; |
5200 | } | 5474 | } |
@@ -5222,7 +5496,8 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p, | |||
5222 | goto out; | 5496 | goto out; |
5223 | xdr_enter_page(&xdr, PAGE_SIZE); | 5497 | xdr_enter_page(&xdr, PAGE_SIZE); |
5224 | status = decode_getfattr(&xdr, &res->fs_locations->fattr, | 5498 | status = decode_getfattr(&xdr, &res->fs_locations->fattr, |
5225 | res->fs_locations->server); | 5499 | res->fs_locations->server, |
5500 | !RPC_IS_ASYNC(req->rq_task)); | ||
5226 | out: | 5501 | out: |
5227 | return status; | 5502 | return status; |
5228 | } | 5503 | } |