diff options
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r-- | fs/nfs/nfs4xdr.c | 511 |
1 files changed, 484 insertions, 27 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index e6e8f3b9a1d..97f987a981c 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -113,7 +113,11 @@ static int nfs4_stat_to_errno(int); | |||
113 | #define encode_restorefh_maxsz (op_encode_hdr_maxsz) | 113 | #define encode_restorefh_maxsz (op_encode_hdr_maxsz) |
114 | #define decode_restorefh_maxsz (op_decode_hdr_maxsz) | 114 | #define decode_restorefh_maxsz (op_decode_hdr_maxsz) |
115 | #define encode_fsinfo_maxsz (encode_getattr_maxsz) | 115 | #define encode_fsinfo_maxsz (encode_getattr_maxsz) |
116 | #define decode_fsinfo_maxsz (op_decode_hdr_maxsz + 15) | 116 | /* The 5 accounts for the PNFS attributes, and assumes that at most three |
117 | * layout types will be returned. | ||
118 | */ | ||
119 | #define decode_fsinfo_maxsz (op_decode_hdr_maxsz + \ | ||
120 | nfs4_fattr_bitmap_maxsz + 4 + 8 + 5) | ||
117 | #define encode_renew_maxsz (op_encode_hdr_maxsz + 3) | 121 | #define encode_renew_maxsz (op_encode_hdr_maxsz + 3) |
118 | #define decode_renew_maxsz (op_decode_hdr_maxsz) | 122 | #define decode_renew_maxsz (op_decode_hdr_maxsz) |
119 | #define encode_setclientid_maxsz \ | 123 | #define encode_setclientid_maxsz \ |
@@ -314,6 +318,17 @@ static int nfs4_stat_to_errno(int); | |||
314 | XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5) | 318 | XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5) |
315 | #define encode_reclaim_complete_maxsz (op_encode_hdr_maxsz + 4) | 319 | #define encode_reclaim_complete_maxsz (op_encode_hdr_maxsz + 4) |
316 | #define decode_reclaim_complete_maxsz (op_decode_hdr_maxsz + 4) | 320 | #define decode_reclaim_complete_maxsz (op_decode_hdr_maxsz + 4) |
321 | #define encode_getdevicelist_maxsz (op_encode_hdr_maxsz + 4 + \ | ||
322 | encode_verifier_maxsz) | ||
323 | #define decode_getdevicelist_maxsz (op_decode_hdr_maxsz + \ | ||
324 | 2 /* nfs_cookie4 gdlr_cookie */ + \ | ||
325 | decode_verifier_maxsz \ | ||
326 | /* verifier4 gdlr_verifier */ + \ | ||
327 | 1 /* gdlr_deviceid_list count */ + \ | ||
328 | XDR_QUADLEN(NFS4_PNFS_GETDEVLIST_MAXNUM * \ | ||
329 | NFS4_DEVICEID4_SIZE) \ | ||
330 | /* gdlr_deviceid_list */ + \ | ||
331 | 1 /* bool gdlr_eof */) | ||
317 | #define encode_getdeviceinfo_maxsz (op_encode_hdr_maxsz + 4 + \ | 332 | #define encode_getdeviceinfo_maxsz (op_encode_hdr_maxsz + 4 + \ |
318 | XDR_QUADLEN(NFS4_DEVICEID4_SIZE)) | 333 | XDR_QUADLEN(NFS4_DEVICEID4_SIZE)) |
319 | #define decode_getdeviceinfo_maxsz (op_decode_hdr_maxsz + \ | 334 | #define decode_getdeviceinfo_maxsz (op_decode_hdr_maxsz + \ |
@@ -343,6 +358,14 @@ static int nfs4_stat_to_errno(int); | |||
343 | 1 /* FIXME: opaque lrf_body always empty at the moment */) | 358 | 1 /* FIXME: opaque lrf_body always empty at the moment */) |
344 | #define decode_layoutreturn_maxsz (op_decode_hdr_maxsz + \ | 359 | #define decode_layoutreturn_maxsz (op_decode_hdr_maxsz + \ |
345 | 1 + decode_stateid_maxsz) | 360 | 1 + decode_stateid_maxsz) |
361 | #define encode_secinfo_no_name_maxsz (op_encode_hdr_maxsz + 1) | ||
362 | #define decode_secinfo_no_name_maxsz decode_secinfo_maxsz | ||
363 | #define encode_test_stateid_maxsz (op_encode_hdr_maxsz + 2 + \ | ||
364 | XDR_QUADLEN(NFS4_STATEID_SIZE)) | ||
365 | #define decode_test_stateid_maxsz (op_decode_hdr_maxsz + 2 + 1) | ||
366 | #define encode_free_stateid_maxsz (op_encode_hdr_maxsz + 1 + \ | ||
367 | XDR_QUADLEN(NFS4_STATEID_SIZE)) | ||
368 | #define decode_free_stateid_maxsz (op_decode_hdr_maxsz + 1) | ||
346 | #else /* CONFIG_NFS_V4_1 */ | 369 | #else /* CONFIG_NFS_V4_1 */ |
347 | #define encode_sequence_maxsz 0 | 370 | #define encode_sequence_maxsz 0 |
348 | #define decode_sequence_maxsz 0 | 371 | #define decode_sequence_maxsz 0 |
@@ -740,6 +763,14 @@ static int nfs4_stat_to_errno(int); | |||
740 | #define NFS4_dec_reclaim_complete_sz (compound_decode_hdr_maxsz + \ | 763 | #define NFS4_dec_reclaim_complete_sz (compound_decode_hdr_maxsz + \ |
741 | decode_sequence_maxsz + \ | 764 | decode_sequence_maxsz + \ |
742 | decode_reclaim_complete_maxsz) | 765 | decode_reclaim_complete_maxsz) |
766 | #define NFS4_enc_getdevicelist_sz (compound_encode_hdr_maxsz + \ | ||
767 | encode_sequence_maxsz + \ | ||
768 | encode_putfh_maxsz + \ | ||
769 | encode_getdevicelist_maxsz) | ||
770 | #define NFS4_dec_getdevicelist_sz (compound_decode_hdr_maxsz + \ | ||
771 | decode_sequence_maxsz + \ | ||
772 | decode_putfh_maxsz + \ | ||
773 | decode_getdevicelist_maxsz) | ||
743 | #define NFS4_enc_getdeviceinfo_sz (compound_encode_hdr_maxsz + \ | 774 | #define NFS4_enc_getdeviceinfo_sz (compound_encode_hdr_maxsz + \ |
744 | encode_sequence_maxsz +\ | 775 | encode_sequence_maxsz +\ |
745 | encode_getdeviceinfo_maxsz) | 776 | encode_getdeviceinfo_maxsz) |
@@ -772,6 +803,26 @@ static int nfs4_stat_to_errno(int); | |||
772 | decode_sequence_maxsz + \ | 803 | decode_sequence_maxsz + \ |
773 | decode_putfh_maxsz + \ | 804 | decode_putfh_maxsz + \ |
774 | decode_layoutreturn_maxsz) | 805 | decode_layoutreturn_maxsz) |
806 | #define NFS4_enc_secinfo_no_name_sz (compound_encode_hdr_maxsz + \ | ||
807 | encode_sequence_maxsz + \ | ||
808 | encode_putrootfh_maxsz +\ | ||
809 | encode_secinfo_no_name_maxsz) | ||
810 | #define NFS4_dec_secinfo_no_name_sz (compound_decode_hdr_maxsz + \ | ||
811 | decode_sequence_maxsz + \ | ||
812 | decode_putrootfh_maxsz + \ | ||
813 | decode_secinfo_no_name_maxsz) | ||
814 | #define NFS4_enc_test_stateid_sz (compound_encode_hdr_maxsz + \ | ||
815 | encode_sequence_maxsz + \ | ||
816 | encode_test_stateid_maxsz) | ||
817 | #define NFS4_dec_test_stateid_sz (compound_decode_hdr_maxsz + \ | ||
818 | decode_sequence_maxsz + \ | ||
819 | decode_test_stateid_maxsz) | ||
820 | #define NFS4_enc_free_stateid_sz (compound_encode_hdr_maxsz + \ | ||
821 | encode_sequence_maxsz + \ | ||
822 | encode_free_stateid_maxsz) | ||
823 | #define NFS4_dec_free_stateid_sz (compound_decode_hdr_maxsz + \ | ||
824 | decode_sequence_maxsz + \ | ||
825 | decode_free_stateid_maxsz) | ||
775 | 826 | ||
776 | const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH + | 827 | const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH + |
777 | compound_encode_hdr_maxsz + | 828 | compound_encode_hdr_maxsz + |
@@ -1076,6 +1127,35 @@ static void encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm | |||
1076 | hdr->replen += decode_getattr_maxsz; | 1127 | hdr->replen += decode_getattr_maxsz; |
1077 | } | 1128 | } |
1078 | 1129 | ||
1130 | static void | ||
1131 | encode_getattr_three(struct xdr_stream *xdr, | ||
1132 | uint32_t bm0, uint32_t bm1, uint32_t bm2, | ||
1133 | struct compound_hdr *hdr) | ||
1134 | { | ||
1135 | __be32 *p; | ||
1136 | |||
1137 | p = reserve_space(xdr, 4); | ||
1138 | *p = cpu_to_be32(OP_GETATTR); | ||
1139 | if (bm2) { | ||
1140 | p = reserve_space(xdr, 16); | ||
1141 | *p++ = cpu_to_be32(3); | ||
1142 | *p++ = cpu_to_be32(bm0); | ||
1143 | *p++ = cpu_to_be32(bm1); | ||
1144 | *p = cpu_to_be32(bm2); | ||
1145 | } else if (bm1) { | ||
1146 | p = reserve_space(xdr, 12); | ||
1147 | *p++ = cpu_to_be32(2); | ||
1148 | *p++ = cpu_to_be32(bm0); | ||
1149 | *p = cpu_to_be32(bm1); | ||
1150 | } else { | ||
1151 | p = reserve_space(xdr, 8); | ||
1152 | *p++ = cpu_to_be32(1); | ||
1153 | *p = cpu_to_be32(bm0); | ||
1154 | } | ||
1155 | hdr->nops++; | ||
1156 | hdr->replen += decode_getattr_maxsz; | ||
1157 | } | ||
1158 | |||
1079 | static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) | 1159 | static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) |
1080 | { | 1160 | { |
1081 | encode_getattr_two(xdr, bitmask[0] & nfs4_fattr_bitmap[0], | 1161 | encode_getattr_two(xdr, bitmask[0] & nfs4_fattr_bitmap[0], |
@@ -1084,8 +1164,11 @@ static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct c | |||
1084 | 1164 | ||
1085 | static void encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) | 1165 | static void encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) |
1086 | { | 1166 | { |
1087 | encode_getattr_two(xdr, bitmask[0] & nfs4_fsinfo_bitmap[0], | 1167 | encode_getattr_three(xdr, |
1088 | bitmask[1] & nfs4_fsinfo_bitmap[1], hdr); | 1168 | bitmask[0] & nfs4_fsinfo_bitmap[0], |
1169 | bitmask[1] & nfs4_fsinfo_bitmap[1], | ||
1170 | bitmask[2] & nfs4_fsinfo_bitmap[2], | ||
1171 | hdr); | ||
1089 | } | 1172 | } |
1090 | 1173 | ||
1091 | static void encode_fs_locations(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) | 1174 | static void encode_fs_locations(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) |
@@ -1827,6 +1910,26 @@ static void encode_sequence(struct xdr_stream *xdr, | |||
1827 | 1910 | ||
1828 | #ifdef CONFIG_NFS_V4_1 | 1911 | #ifdef CONFIG_NFS_V4_1 |
1829 | static void | 1912 | static void |
1913 | encode_getdevicelist(struct xdr_stream *xdr, | ||
1914 | const struct nfs4_getdevicelist_args *args, | ||
1915 | struct compound_hdr *hdr) | ||
1916 | { | ||
1917 | __be32 *p; | ||
1918 | nfs4_verifier dummy = { | ||
1919 | .data = "dummmmmy", | ||
1920 | }; | ||
1921 | |||
1922 | p = reserve_space(xdr, 20); | ||
1923 | *p++ = cpu_to_be32(OP_GETDEVICELIST); | ||
1924 | *p++ = cpu_to_be32(args->layoutclass); | ||
1925 | *p++ = cpu_to_be32(NFS4_PNFS_GETDEVLIST_MAXNUM); | ||
1926 | xdr_encode_hyper(p, 0ULL); /* cookie */ | ||
1927 | encode_nfs4_verifier(xdr, &dummy); | ||
1928 | hdr->nops++; | ||
1929 | hdr->replen += decode_getdevicelist_maxsz; | ||
1930 | } | ||
1931 | |||
1932 | static void | ||
1830 | encode_getdeviceinfo(struct xdr_stream *xdr, | 1933 | encode_getdeviceinfo(struct xdr_stream *xdr, |
1831 | const struct nfs4_getdeviceinfo_args *args, | 1934 | const struct nfs4_getdeviceinfo_args *args, |
1832 | struct compound_hdr *hdr) | 1935 | struct compound_hdr *hdr) |
@@ -1888,7 +1991,7 @@ encode_layoutcommit(struct xdr_stream *xdr, | |||
1888 | *p++ = cpu_to_be32(OP_LAYOUTCOMMIT); | 1991 | *p++ = cpu_to_be32(OP_LAYOUTCOMMIT); |
1889 | /* Only whole file layouts */ | 1992 | /* Only whole file layouts */ |
1890 | p = xdr_encode_hyper(p, 0); /* offset */ | 1993 | p = xdr_encode_hyper(p, 0); /* offset */ |
1891 | p = xdr_encode_hyper(p, NFS4_MAX_UINT64); /* length */ | 1994 | p = xdr_encode_hyper(p, args->lastbytewritten + 1); /* length */ |
1892 | *p++ = cpu_to_be32(0); /* reclaim */ | 1995 | *p++ = cpu_to_be32(0); /* reclaim */ |
1893 | p = xdr_encode_opaque_fixed(p, args->stateid.data, NFS4_STATEID_SIZE); | 1996 | p = xdr_encode_opaque_fixed(p, args->stateid.data, NFS4_STATEID_SIZE); |
1894 | *p++ = cpu_to_be32(1); /* newoffset = TRUE */ | 1997 | *p++ = cpu_to_be32(1); /* newoffset = TRUE */ |
@@ -1938,6 +2041,46 @@ encode_layoutreturn(struct xdr_stream *xdr, | |||
1938 | hdr->nops++; | 2041 | hdr->nops++; |
1939 | hdr->replen += decode_layoutreturn_maxsz; | 2042 | hdr->replen += decode_layoutreturn_maxsz; |
1940 | } | 2043 | } |
2044 | |||
2045 | static int | ||
2046 | encode_secinfo_no_name(struct xdr_stream *xdr, | ||
2047 | const struct nfs41_secinfo_no_name_args *args, | ||
2048 | struct compound_hdr *hdr) | ||
2049 | { | ||
2050 | __be32 *p; | ||
2051 | p = reserve_space(xdr, 8); | ||
2052 | *p++ = cpu_to_be32(OP_SECINFO_NO_NAME); | ||
2053 | *p++ = cpu_to_be32(args->style); | ||
2054 | hdr->nops++; | ||
2055 | hdr->replen += decode_secinfo_no_name_maxsz; | ||
2056 | return 0; | ||
2057 | } | ||
2058 | |||
2059 | static void encode_test_stateid(struct xdr_stream *xdr, | ||
2060 | struct nfs41_test_stateid_args *args, | ||
2061 | struct compound_hdr *hdr) | ||
2062 | { | ||
2063 | __be32 *p; | ||
2064 | |||
2065 | p = reserve_space(xdr, 8 + NFS4_STATEID_SIZE); | ||
2066 | *p++ = cpu_to_be32(OP_TEST_STATEID); | ||
2067 | *p++ = cpu_to_be32(1); | ||
2068 | xdr_encode_opaque_fixed(p, args->stateid->data, NFS4_STATEID_SIZE); | ||
2069 | hdr->nops++; | ||
2070 | hdr->replen += decode_test_stateid_maxsz; | ||
2071 | } | ||
2072 | |||
2073 | static void encode_free_stateid(struct xdr_stream *xdr, | ||
2074 | struct nfs41_free_stateid_args *args, | ||
2075 | struct compound_hdr *hdr) | ||
2076 | { | ||
2077 | __be32 *p; | ||
2078 | p = reserve_space(xdr, 4 + NFS4_STATEID_SIZE); | ||
2079 | *p++ = cpu_to_be32(OP_FREE_STATEID); | ||
2080 | xdr_encode_opaque_fixed(p, args->stateid->data, NFS4_STATEID_SIZE); | ||
2081 | hdr->nops++; | ||
2082 | hdr->replen += decode_free_stateid_maxsz; | ||
2083 | } | ||
1941 | #endif /* CONFIG_NFS_V4_1 */ | 2084 | #endif /* CONFIG_NFS_V4_1 */ |
1942 | 2085 | ||
1943 | /* | 2086 | /* |
@@ -2374,11 +2517,13 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr, | |||
2374 | encode_compound_hdr(xdr, req, &hdr); | 2517 | encode_compound_hdr(xdr, req, &hdr); |
2375 | encode_sequence(xdr, &args->seq_args, &hdr); | 2518 | encode_sequence(xdr, &args->seq_args, &hdr); |
2376 | encode_putfh(xdr, args->fh, &hdr); | 2519 | encode_putfh(xdr, args->fh, &hdr); |
2377 | replen = hdr.replen + op_decode_hdr_maxsz + nfs4_fattr_bitmap_maxsz + 1; | 2520 | replen = hdr.replen + op_decode_hdr_maxsz + 1; |
2378 | encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr); | 2521 | encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr); |
2379 | 2522 | ||
2380 | xdr_inline_pages(&req->rq_rcv_buf, replen << 2, | 2523 | xdr_inline_pages(&req->rq_rcv_buf, replen << 2, |
2381 | args->acl_pages, args->acl_pgbase, args->acl_len); | 2524 | args->acl_pages, args->acl_pgbase, args->acl_len); |
2525 | xdr_set_scratch_buffer(xdr, page_address(args->acl_scratch), PAGE_SIZE); | ||
2526 | |||
2382 | encode_nops(&hdr); | 2527 | encode_nops(&hdr); |
2383 | } | 2528 | } |
2384 | 2529 | ||
@@ -2536,7 +2681,7 @@ static void nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, | |||
2536 | struct compound_hdr hdr = { | 2681 | struct compound_hdr hdr = { |
2537 | .nops = 0, | 2682 | .nops = 0, |
2538 | }; | 2683 | }; |
2539 | const u32 lease_bitmap[2] = { FATTR4_WORD0_LEASE_TIME, 0 }; | 2684 | const u32 lease_bitmap[3] = { FATTR4_WORD0_LEASE_TIME }; |
2540 | 2685 | ||
2541 | encode_compound_hdr(xdr, req, &hdr); | 2686 | encode_compound_hdr(xdr, req, &hdr); |
2542 | encode_setclientid_confirm(xdr, arg, &hdr); | 2687 | encode_setclientid_confirm(xdr, arg, &hdr); |
@@ -2680,7 +2825,7 @@ static void nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req, | |||
2680 | struct compound_hdr hdr = { | 2825 | struct compound_hdr hdr = { |
2681 | .minorversion = nfs4_xdr_minorversion(&args->la_seq_args), | 2826 | .minorversion = nfs4_xdr_minorversion(&args->la_seq_args), |
2682 | }; | 2827 | }; |
2683 | const u32 lease_bitmap[2] = { FATTR4_WORD0_LEASE_TIME, 0 }; | 2828 | const u32 lease_bitmap[3] = { FATTR4_WORD0_LEASE_TIME }; |
2684 | 2829 | ||
2685 | encode_compound_hdr(xdr, req, &hdr); | 2830 | encode_compound_hdr(xdr, req, &hdr); |
2686 | encode_sequence(xdr, &args->la_seq_args, &hdr); | 2831 | encode_sequence(xdr, &args->la_seq_args, &hdr); |
@@ -2707,6 +2852,24 @@ static void nfs4_xdr_enc_reclaim_complete(struct rpc_rqst *req, | |||
2707 | } | 2852 | } |
2708 | 2853 | ||
2709 | /* | 2854 | /* |
2855 | * Encode GETDEVICELIST request | ||
2856 | */ | ||
2857 | static void nfs4_xdr_enc_getdevicelist(struct rpc_rqst *req, | ||
2858 | struct xdr_stream *xdr, | ||
2859 | struct nfs4_getdevicelist_args *args) | ||
2860 | { | ||
2861 | struct compound_hdr hdr = { | ||
2862 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | ||
2863 | }; | ||
2864 | |||
2865 | encode_compound_hdr(xdr, req, &hdr); | ||
2866 | encode_sequence(xdr, &args->seq_args, &hdr); | ||
2867 | encode_putfh(xdr, args->fh, &hdr); | ||
2868 | encode_getdevicelist(xdr, args, &hdr); | ||
2869 | encode_nops(&hdr); | ||
2870 | } | ||
2871 | |||
2872 | /* | ||
2710 | * Encode GETDEVICEINFO request | 2873 | * Encode GETDEVICEINFO request |
2711 | */ | 2874 | */ |
2712 | static void nfs4_xdr_enc_getdeviceinfo(struct rpc_rqst *req, | 2875 | static void nfs4_xdr_enc_getdeviceinfo(struct rpc_rqst *req, |
@@ -2790,6 +2953,59 @@ static void nfs4_xdr_enc_layoutreturn(struct rpc_rqst *req, | |||
2790 | encode_layoutreturn(xdr, args, &hdr); | 2953 | encode_layoutreturn(xdr, args, &hdr); |
2791 | encode_nops(&hdr); | 2954 | encode_nops(&hdr); |
2792 | } | 2955 | } |
2956 | |||
2957 | /* | ||
2958 | * Encode SECINFO_NO_NAME request | ||
2959 | */ | ||
2960 | static int nfs4_xdr_enc_secinfo_no_name(struct rpc_rqst *req, | ||
2961 | struct xdr_stream *xdr, | ||
2962 | struct nfs41_secinfo_no_name_args *args) | ||
2963 | { | ||
2964 | struct compound_hdr hdr = { | ||
2965 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | ||
2966 | }; | ||
2967 | |||
2968 | encode_compound_hdr(xdr, req, &hdr); | ||
2969 | encode_sequence(xdr, &args->seq_args, &hdr); | ||
2970 | encode_putrootfh(xdr, &hdr); | ||
2971 | encode_secinfo_no_name(xdr, args, &hdr); | ||
2972 | encode_nops(&hdr); | ||
2973 | return 0; | ||
2974 | } | ||
2975 | |||
2976 | /* | ||
2977 | * Encode TEST_STATEID request | ||
2978 | */ | ||
2979 | static void nfs4_xdr_enc_test_stateid(struct rpc_rqst *req, | ||
2980 | struct xdr_stream *xdr, | ||
2981 | struct nfs41_test_stateid_args *args) | ||
2982 | { | ||
2983 | struct compound_hdr hdr = { | ||
2984 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | ||
2985 | }; | ||
2986 | |||
2987 | encode_compound_hdr(xdr, req, &hdr); | ||
2988 | encode_sequence(xdr, &args->seq_args, &hdr); | ||
2989 | encode_test_stateid(xdr, args, &hdr); | ||
2990 | encode_nops(&hdr); | ||
2991 | } | ||
2992 | |||
2993 | /* | ||
2994 | * Encode FREE_STATEID request | ||
2995 | */ | ||
2996 | static void nfs4_xdr_enc_free_stateid(struct rpc_rqst *req, | ||
2997 | struct xdr_stream *xdr, | ||
2998 | struct nfs41_free_stateid_args *args) | ||
2999 | { | ||
3000 | struct compound_hdr hdr = { | ||
3001 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | ||
3002 | }; | ||
3003 | |||
3004 | encode_compound_hdr(xdr, req, &hdr); | ||
3005 | encode_sequence(xdr, &args->seq_args, &hdr); | ||
3006 | encode_free_stateid(xdr, args, &hdr); | ||
3007 | encode_nops(&hdr); | ||
3008 | } | ||
2793 | #endif /* CONFIG_NFS_V4_1 */ | 3009 | #endif /* CONFIG_NFS_V4_1 */ |
2794 | 3010 | ||
2795 | static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) | 3011 | static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) |
@@ -2890,14 +3106,17 @@ static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) | |||
2890 | goto out_overflow; | 3106 | goto out_overflow; |
2891 | bmlen = be32_to_cpup(p); | 3107 | bmlen = be32_to_cpup(p); |
2892 | 3108 | ||
2893 | bitmap[0] = bitmap[1] = 0; | 3109 | bitmap[0] = bitmap[1] = bitmap[2] = 0; |
2894 | p = xdr_inline_decode(xdr, (bmlen << 2)); | 3110 | p = xdr_inline_decode(xdr, (bmlen << 2)); |
2895 | if (unlikely(!p)) | 3111 | if (unlikely(!p)) |
2896 | goto out_overflow; | 3112 | goto out_overflow; |
2897 | if (bmlen > 0) { | 3113 | if (bmlen > 0) { |
2898 | bitmap[0] = be32_to_cpup(p++); | 3114 | bitmap[0] = be32_to_cpup(p++); |
2899 | if (bmlen > 1) | 3115 | if (bmlen > 1) { |
2900 | bitmap[1] = be32_to_cpup(p); | 3116 | bitmap[1] = be32_to_cpup(p++); |
3117 | if (bmlen > 2) | ||
3118 | bitmap[2] = be32_to_cpup(p); | ||
3119 | } | ||
2901 | } | 3120 | } |
2902 | return 0; | 3121 | return 0; |
2903 | out_overflow: | 3122 | out_overflow: |
@@ -2929,8 +3148,9 @@ static int decode_attr_supported(struct xdr_stream *xdr, uint32_t *bitmap, uint3 | |||
2929 | return ret; | 3148 | return ret; |
2930 | bitmap[0] &= ~FATTR4_WORD0_SUPPORTED_ATTRS; | 3149 | bitmap[0] &= ~FATTR4_WORD0_SUPPORTED_ATTRS; |
2931 | } else | 3150 | } else |
2932 | bitmask[0] = bitmask[1] = 0; | 3151 | bitmask[0] = bitmask[1] = bitmask[2] = 0; |
2933 | dprintk("%s: bitmask=%08x:%08x\n", __func__, bitmask[0], bitmask[1]); | 3152 | dprintk("%s: bitmask=%08x:%08x:%08x\n", __func__, |
3153 | bitmask[0], bitmask[1], bitmask[2]); | ||
2934 | return 0; | 3154 | return 0; |
2935 | } | 3155 | } |
2936 | 3156 | ||
@@ -3984,7 +4204,7 @@ out_overflow: | |||
3984 | static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_res *res) | 4204 | static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_res *res) |
3985 | { | 4205 | { |
3986 | __be32 *savep; | 4206 | __be32 *savep; |
3987 | uint32_t attrlen, bitmap[2] = {0}; | 4207 | uint32_t attrlen, bitmap[3] = {0}; |
3988 | int status; | 4208 | int status; |
3989 | 4209 | ||
3990 | if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) | 4210 | if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) |
@@ -4010,7 +4230,7 @@ xdr_error: | |||
4010 | static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat) | 4230 | static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat) |
4011 | { | 4231 | { |
4012 | __be32 *savep; | 4232 | __be32 *savep; |
4013 | uint32_t attrlen, bitmap[2] = {0}; | 4233 | uint32_t attrlen, bitmap[3] = {0}; |
4014 | int status; | 4234 | int status; |
4015 | 4235 | ||
4016 | if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) | 4236 | if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) |
@@ -4042,7 +4262,7 @@ xdr_error: | |||
4042 | static int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf) | 4262 | static int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf) |
4043 | { | 4263 | { |
4044 | __be32 *savep; | 4264 | __be32 *savep; |
4045 | uint32_t attrlen, bitmap[2] = {0}; | 4265 | uint32_t attrlen, bitmap[3] = {0}; |
4046 | int status; | 4266 | int status; |
4047 | 4267 | ||
4048 | if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) | 4268 | if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) |
@@ -4182,7 +4402,7 @@ static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fat | |||
4182 | { | 4402 | { |
4183 | __be32 *savep; | 4403 | __be32 *savep; |
4184 | uint32_t attrlen, | 4404 | uint32_t attrlen, |
4185 | bitmap[2] = {0}; | 4405 | bitmap[3] = {0}; |
4186 | int status; | 4406 | int status; |
4187 | 4407 | ||
4188 | status = decode_op_hdr(xdr, OP_GETATTR); | 4408 | status = decode_op_hdr(xdr, OP_GETATTR); |
@@ -4268,10 +4488,32 @@ static int decode_attr_pnfstype(struct xdr_stream *xdr, uint32_t *bitmap, | |||
4268 | return status; | 4488 | return status; |
4269 | } | 4489 | } |
4270 | 4490 | ||
4491 | /* | ||
4492 | * The prefered block size for layout directed io | ||
4493 | */ | ||
4494 | static int decode_attr_layout_blksize(struct xdr_stream *xdr, uint32_t *bitmap, | ||
4495 | uint32_t *res) | ||
4496 | { | ||
4497 | __be32 *p; | ||
4498 | |||
4499 | dprintk("%s: bitmap is %x\n", __func__, bitmap[2]); | ||
4500 | *res = 0; | ||
4501 | if (bitmap[2] & FATTR4_WORD2_LAYOUT_BLKSIZE) { | ||
4502 | p = xdr_inline_decode(xdr, 4); | ||
4503 | if (unlikely(!p)) { | ||
4504 | print_overflow_msg(__func__, xdr); | ||
4505 | return -EIO; | ||
4506 | } | ||
4507 | *res = be32_to_cpup(p); | ||
4508 | bitmap[2] &= ~FATTR4_WORD2_LAYOUT_BLKSIZE; | ||
4509 | } | ||
4510 | return 0; | ||
4511 | } | ||
4512 | |||
4271 | static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) | 4513 | static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) |
4272 | { | 4514 | { |
4273 | __be32 *savep; | 4515 | __be32 *savep; |
4274 | uint32_t attrlen, bitmap[2]; | 4516 | uint32_t attrlen, bitmap[3]; |
4275 | int status; | 4517 | int status; |
4276 | 4518 | ||
4277 | if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) | 4519 | if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) |
@@ -4299,6 +4541,9 @@ static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) | |||
4299 | status = decode_attr_pnfstype(xdr, bitmap, &fsinfo->layouttype); | 4541 | status = decode_attr_pnfstype(xdr, bitmap, &fsinfo->layouttype); |
4300 | if (status != 0) | 4542 | if (status != 0) |
4301 | goto xdr_error; | 4543 | goto xdr_error; |
4544 | status = decode_attr_layout_blksize(xdr, bitmap, &fsinfo->blksize); | ||
4545 | if (status) | ||
4546 | goto xdr_error; | ||
4302 | 4547 | ||
4303 | status = verify_attr_len(xdr, savep, attrlen); | 4548 | status = verify_attr_len(xdr, savep, attrlen); |
4304 | xdr_error: | 4549 | xdr_error: |
@@ -4714,17 +4959,18 @@ decode_restorefh(struct xdr_stream *xdr) | |||
4714 | } | 4959 | } |
4715 | 4960 | ||
4716 | static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, | 4961 | static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, |
4717 | size_t *acl_len) | 4962 | struct nfs_getaclres *res) |
4718 | { | 4963 | { |
4719 | __be32 *savep; | 4964 | __be32 *savep, *bm_p; |
4720 | uint32_t attrlen, | 4965 | uint32_t attrlen, |
4721 | bitmap[2] = {0}; | 4966 | bitmap[3] = {0}; |
4722 | struct kvec *iov = req->rq_rcv_buf.head; | 4967 | struct kvec *iov = req->rq_rcv_buf.head; |
4723 | int status; | 4968 | int status; |
4724 | 4969 | ||
4725 | *acl_len = 0; | 4970 | res->acl_len = 0; |
4726 | if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) | 4971 | if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) |
4727 | goto out; | 4972 | goto out; |
4973 | bm_p = xdr->p; | ||
4728 | if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) | 4974 | if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) |
4729 | goto out; | 4975 | goto out; |
4730 | if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0) | 4976 | if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0) |
@@ -4736,18 +4982,30 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, | |||
4736 | size_t hdrlen; | 4982 | size_t hdrlen; |
4737 | u32 recvd; | 4983 | u32 recvd; |
4738 | 4984 | ||
4985 | /* The bitmap (xdr len + bitmaps) and the attr xdr len words | ||
4986 | * are stored with the acl data to handle the problem of | ||
4987 | * variable length bitmaps.*/ | ||
4988 | xdr->p = bm_p; | ||
4989 | res->acl_data_offset = be32_to_cpup(bm_p) + 2; | ||
4990 | res->acl_data_offset <<= 2; | ||
4991 | |||
4739 | /* We ignore &savep and don't do consistency checks on | 4992 | /* We ignore &savep and don't do consistency checks on |
4740 | * the attr length. Let userspace figure it out.... */ | 4993 | * the attr length. Let userspace figure it out.... */ |
4741 | hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base; | 4994 | hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base; |
4995 | attrlen += res->acl_data_offset; | ||
4742 | recvd = req->rq_rcv_buf.len - hdrlen; | 4996 | recvd = req->rq_rcv_buf.len - hdrlen; |
4743 | if (attrlen > recvd) { | 4997 | if (attrlen > recvd) { |
4744 | dprintk("NFS: server cheating in getattr" | 4998 | if (res->acl_flags & NFS4_ACL_LEN_REQUEST) { |
4745 | " acl reply: attrlen %u > recvd %u\n", | 4999 | /* getxattr interface called with a NULL buf */ |
5000 | res->acl_len = attrlen; | ||
5001 | goto out; | ||
5002 | } | ||
5003 | dprintk("NFS: acl reply: attrlen %u > recvd %u\n", | ||
4746 | attrlen, recvd); | 5004 | attrlen, recvd); |
4747 | return -EINVAL; | 5005 | return -EINVAL; |
4748 | } | 5006 | } |
4749 | xdr_read_pages(xdr, attrlen); | 5007 | xdr_read_pages(xdr, attrlen); |
4750 | *acl_len = attrlen; | 5008 | res->acl_len = attrlen; |
4751 | } else | 5009 | } else |
4752 | status = -EOPNOTSUPP; | 5010 | status = -EOPNOTSUPP; |
4753 | 5011 | ||
@@ -4977,11 +5235,17 @@ static int decode_exchange_id(struct xdr_stream *xdr, | |||
4977 | if (unlikely(status)) | 5235 | if (unlikely(status)) |
4978 | return status; | 5236 | return status; |
4979 | 5237 | ||
4980 | /* Throw away server_scope */ | 5238 | /* Save server_scope */ |
4981 | status = decode_opaque_inline(xdr, &dummy, &dummy_str); | 5239 | status = decode_opaque_inline(xdr, &dummy, &dummy_str); |
4982 | if (unlikely(status)) | 5240 | if (unlikely(status)) |
4983 | return status; | 5241 | return status; |
4984 | 5242 | ||
5243 | if (unlikely(dummy > NFS4_OPAQUE_LIMIT)) | ||
5244 | return -EIO; | ||
5245 | |||
5246 | memcpy(res->server_scope->server_scope, dummy_str, dummy); | ||
5247 | res->server_scope->server_scope_sz = dummy; | ||
5248 | |||
4985 | /* Throw away Implementation id array */ | 5249 | /* Throw away Implementation id array */ |
4986 | status = decode_opaque_inline(xdr, &dummy, &dummy_str); | 5250 | status = decode_opaque_inline(xdr, &dummy, &dummy_str); |
4987 | if (unlikely(status)) | 5251 | if (unlikely(status)) |
@@ -5141,6 +5405,53 @@ out_overflow: | |||
5141 | } | 5405 | } |
5142 | 5406 | ||
5143 | #if defined(CONFIG_NFS_V4_1) | 5407 | #if defined(CONFIG_NFS_V4_1) |
5408 | /* | ||
5409 | * TODO: Need to handle case when EOF != true; | ||
5410 | */ | ||
5411 | static int decode_getdevicelist(struct xdr_stream *xdr, | ||
5412 | struct pnfs_devicelist *res) | ||
5413 | { | ||
5414 | __be32 *p; | ||
5415 | int status, i; | ||
5416 | struct nfs_writeverf verftemp; | ||
5417 | |||
5418 | status = decode_op_hdr(xdr, OP_GETDEVICELIST); | ||
5419 | if (status) | ||
5420 | return status; | ||
5421 | |||
5422 | p = xdr_inline_decode(xdr, 8 + 8 + 4); | ||
5423 | if (unlikely(!p)) | ||
5424 | goto out_overflow; | ||
5425 | |||
5426 | /* TODO: Skip cookie for now */ | ||
5427 | p += 2; | ||
5428 | |||
5429 | /* Read verifier */ | ||
5430 | p = xdr_decode_opaque_fixed(p, verftemp.verifier, 8); | ||
5431 | |||
5432 | res->num_devs = be32_to_cpup(p); | ||
5433 | |||
5434 | dprintk("%s: num_dev %d\n", __func__, res->num_devs); | ||
5435 | |||
5436 | if (res->num_devs > NFS4_PNFS_GETDEVLIST_MAXNUM) { | ||
5437 | printk(KERN_ERR "%s too many result dev_num %u\n", | ||
5438 | __func__, res->num_devs); | ||
5439 | return -EIO; | ||
5440 | } | ||
5441 | |||
5442 | p = xdr_inline_decode(xdr, | ||
5443 | res->num_devs * NFS4_DEVICEID4_SIZE + 4); | ||
5444 | if (unlikely(!p)) | ||
5445 | goto out_overflow; | ||
5446 | for (i = 0; i < res->num_devs; i++) | ||
5447 | p = xdr_decode_opaque_fixed(p, res->dev_id[i].data, | ||
5448 | NFS4_DEVICEID4_SIZE); | ||
5449 | res->eof = be32_to_cpup(p); | ||
5450 | return 0; | ||
5451 | out_overflow: | ||
5452 | print_overflow_msg(__func__, xdr); | ||
5453 | return -EIO; | ||
5454 | } | ||
5144 | 5455 | ||
5145 | static int decode_getdeviceinfo(struct xdr_stream *xdr, | 5456 | static int decode_getdeviceinfo(struct xdr_stream *xdr, |
5146 | struct pnfs_device *pdev) | 5457 | struct pnfs_device *pdev) |
@@ -5303,6 +5614,7 @@ static int decode_layoutcommit(struct xdr_stream *xdr, | |||
5303 | int status; | 5614 | int status; |
5304 | 5615 | ||
5305 | status = decode_op_hdr(xdr, OP_LAYOUTCOMMIT); | 5616 | status = decode_op_hdr(xdr, OP_LAYOUTCOMMIT); |
5617 | res->status = status; | ||
5306 | if (status) | 5618 | if (status) |
5307 | return status; | 5619 | return status; |
5308 | 5620 | ||
@@ -5322,6 +5634,55 @@ out_overflow: | |||
5322 | print_overflow_msg(__func__, xdr); | 5634 | print_overflow_msg(__func__, xdr); |
5323 | return -EIO; | 5635 | return -EIO; |
5324 | } | 5636 | } |
5637 | |||
5638 | static int decode_test_stateid(struct xdr_stream *xdr, | ||
5639 | struct nfs41_test_stateid_res *res) | ||
5640 | { | ||
5641 | __be32 *p; | ||
5642 | int status; | ||
5643 | int num_res; | ||
5644 | |||
5645 | status = decode_op_hdr(xdr, OP_TEST_STATEID); | ||
5646 | if (status) | ||
5647 | return status; | ||
5648 | |||
5649 | p = xdr_inline_decode(xdr, 4); | ||
5650 | if (unlikely(!p)) | ||
5651 | goto out_overflow; | ||
5652 | num_res = be32_to_cpup(p++); | ||
5653 | if (num_res != 1) | ||
5654 | goto out; | ||
5655 | |||
5656 | p = xdr_inline_decode(xdr, 4); | ||
5657 | if (unlikely(!p)) | ||
5658 | goto out_overflow; | ||
5659 | res->status = be32_to_cpup(p++); | ||
5660 | return res->status; | ||
5661 | out_overflow: | ||
5662 | print_overflow_msg(__func__, xdr); | ||
5663 | out: | ||
5664 | return -EIO; | ||
5665 | } | ||
5666 | |||
5667 | static int decode_free_stateid(struct xdr_stream *xdr, | ||
5668 | struct nfs41_free_stateid_res *res) | ||
5669 | { | ||
5670 | __be32 *p; | ||
5671 | int status; | ||
5672 | |||
5673 | status = decode_op_hdr(xdr, OP_FREE_STATEID); | ||
5674 | if (status) | ||
5675 | return status; | ||
5676 | |||
5677 | p = xdr_inline_decode(xdr, 4); | ||
5678 | if (unlikely(!p)) | ||
5679 | goto out_overflow; | ||
5680 | res->status = be32_to_cpup(p++); | ||
5681 | return res->status; | ||
5682 | out_overflow: | ||
5683 | print_overflow_msg(__func__, xdr); | ||
5684 | return -EIO; | ||
5685 | } | ||
5325 | #endif /* CONFIG_NFS_V4_1 */ | 5686 | #endif /* CONFIG_NFS_V4_1 */ |
5326 | 5687 | ||
5327 | /* | 5688 | /* |
@@ -5682,7 +6043,7 @@ nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, struct xdr_stream *xdr, | |||
5682 | status = decode_putfh(xdr); | 6043 | status = decode_putfh(xdr); |
5683 | if (status) | 6044 | if (status) |
5684 | goto out; | 6045 | goto out; |
5685 | status = decode_getacl(xdr, rqstp, &res->acl_len); | 6046 | status = decode_getacl(xdr, rqstp, res); |
5686 | 6047 | ||
5687 | out: | 6048 | out: |
5688 | return status; | 6049 | return status; |
@@ -6366,6 +6727,32 @@ static int nfs4_xdr_dec_reclaim_complete(struct rpc_rqst *rqstp, | |||
6366 | } | 6727 | } |
6367 | 6728 | ||
6368 | /* | 6729 | /* |
6730 | * Decode GETDEVICELIST response | ||
6731 | */ | ||
6732 | static int nfs4_xdr_dec_getdevicelist(struct rpc_rqst *rqstp, | ||
6733 | struct xdr_stream *xdr, | ||
6734 | struct nfs4_getdevicelist_res *res) | ||
6735 | { | ||
6736 | struct compound_hdr hdr; | ||
6737 | int status; | ||
6738 | |||
6739 | dprintk("encoding getdevicelist!\n"); | ||
6740 | |||
6741 | status = decode_compound_hdr(xdr, &hdr); | ||
6742 | if (status != 0) | ||
6743 | goto out; | ||
6744 | status = decode_sequence(xdr, &res->seq_res, rqstp); | ||
6745 | if (status != 0) | ||
6746 | goto out; | ||
6747 | status = decode_putfh(xdr); | ||
6748 | if (status != 0) | ||
6749 | goto out; | ||
6750 | status = decode_getdevicelist(xdr, res->devlist); | ||
6751 | out: | ||
6752 | return status; | ||
6753 | } | ||
6754 | |||
6755 | /* | ||
6369 | * Decode GETDEVINFO response | 6756 | * Decode GETDEVINFO response |
6370 | */ | 6757 | */ |
6371 | static int nfs4_xdr_dec_getdeviceinfo(struct rpc_rqst *rqstp, | 6758 | static int nfs4_xdr_dec_getdeviceinfo(struct rpc_rqst *rqstp, |
@@ -6461,6 +6848,72 @@ static int nfs4_xdr_dec_layoutcommit(struct rpc_rqst *rqstp, | |||
6461 | out: | 6848 | out: |
6462 | return status; | 6849 | return status; |
6463 | } | 6850 | } |
6851 | |||
6852 | /* | ||
6853 | * Decode SECINFO_NO_NAME response | ||
6854 | */ | ||
6855 | static int nfs4_xdr_dec_secinfo_no_name(struct rpc_rqst *rqstp, | ||
6856 | struct xdr_stream *xdr, | ||
6857 | struct nfs4_secinfo_res *res) | ||
6858 | { | ||
6859 | struct compound_hdr hdr; | ||
6860 | int status; | ||
6861 | |||
6862 | status = decode_compound_hdr(xdr, &hdr); | ||
6863 | if (status) | ||
6864 | goto out; | ||
6865 | status = decode_sequence(xdr, &res->seq_res, rqstp); | ||
6866 | if (status) | ||
6867 | goto out; | ||
6868 | status = decode_putrootfh(xdr); | ||
6869 | if (status) | ||
6870 | goto out; | ||
6871 | status = decode_secinfo(xdr, res); | ||
6872 | out: | ||
6873 | return status; | ||
6874 | } | ||
6875 | |||
6876 | /* | ||
6877 | * Decode TEST_STATEID response | ||
6878 | */ | ||
6879 | static int nfs4_xdr_dec_test_stateid(struct rpc_rqst *rqstp, | ||
6880 | struct xdr_stream *xdr, | ||
6881 | struct nfs41_test_stateid_res *res) | ||
6882 | { | ||
6883 | struct compound_hdr hdr; | ||
6884 | int status; | ||
6885 | |||
6886 | status = decode_compound_hdr(xdr, &hdr); | ||
6887 | if (status) | ||
6888 | goto out; | ||
6889 | status = decode_sequence(xdr, &res->seq_res, rqstp); | ||
6890 | if (status) | ||
6891 | goto out; | ||
6892 | status = decode_test_stateid(xdr, res); | ||
6893 | out: | ||
6894 | return status; | ||
6895 | } | ||
6896 | |||
6897 | /* | ||
6898 | * Decode FREE_STATEID response | ||
6899 | */ | ||
6900 | static int nfs4_xdr_dec_free_stateid(struct rpc_rqst *rqstp, | ||
6901 | struct xdr_stream *xdr, | ||
6902 | struct nfs41_free_stateid_res *res) | ||
6903 | { | ||
6904 | struct compound_hdr hdr; | ||
6905 | int status; | ||
6906 | |||
6907 | status = decode_compound_hdr(xdr, &hdr); | ||
6908 | if (status) | ||
6909 | goto out; | ||
6910 | status = decode_sequence(xdr, &res->seq_res, rqstp); | ||
6911 | if (status) | ||
6912 | goto out; | ||
6913 | status = decode_free_stateid(xdr, res); | ||
6914 | out: | ||
6915 | return status; | ||
6916 | } | ||
6464 | #endif /* CONFIG_NFS_V4_1 */ | 6917 | #endif /* CONFIG_NFS_V4_1 */ |
6465 | 6918 | ||
6466 | /** | 6919 | /** |
@@ -6480,7 +6933,7 @@ out: | |||
6480 | int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, | 6933 | int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, |
6481 | int plus) | 6934 | int plus) |
6482 | { | 6935 | { |
6483 | uint32_t bitmap[2] = {0}; | 6936 | uint32_t bitmap[3] = {0}; |
6484 | uint32_t len; | 6937 | uint32_t len; |
6485 | __be32 *p = xdr_inline_decode(xdr, 4); | 6938 | __be32 *p = xdr_inline_decode(xdr, 4); |
6486 | if (unlikely(!p)) | 6939 | if (unlikely(!p)) |
@@ -6663,6 +7116,10 @@ struct rpc_procinfo nfs4_procedures[] = { | |||
6663 | PROC(LAYOUTGET, enc_layoutget, dec_layoutget), | 7116 | PROC(LAYOUTGET, enc_layoutget, dec_layoutget), |
6664 | PROC(LAYOUTCOMMIT, enc_layoutcommit, dec_layoutcommit), | 7117 | PROC(LAYOUTCOMMIT, enc_layoutcommit, dec_layoutcommit), |
6665 | PROC(LAYOUTRETURN, enc_layoutreturn, dec_layoutreturn), | 7118 | PROC(LAYOUTRETURN, enc_layoutreturn, dec_layoutreturn), |
7119 | PROC(SECINFO_NO_NAME, enc_secinfo_no_name, dec_secinfo_no_name), | ||
7120 | PROC(TEST_STATEID, enc_test_stateid, dec_test_stateid), | ||
7121 | PROC(FREE_STATEID, enc_free_stateid, dec_free_stateid), | ||
7122 | PROC(GETDEVICELIST, enc_getdevicelist, dec_getdevicelist), | ||
6666 | #endif /* CONFIG_NFS_V4_1 */ | 7123 | #endif /* CONFIG_NFS_V4_1 */ |
6667 | }; | 7124 | }; |
6668 | 7125 | ||