aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4xdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r--fs/nfs/nfs4xdr.c511
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
776const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH + 827const 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
1130static void
1131encode_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
1079static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) 1159static 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
1085static void encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) 1165static 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
1091static void encode_fs_locations(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) 1174static 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
1829static void 1912static void
1913encode_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
1932static void
1830encode_getdeviceinfo(struct xdr_stream *xdr, 1933encode_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
2045static int
2046encode_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
2059static 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
2073static 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 */
2857static 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 */
2712static void nfs4_xdr_enc_getdeviceinfo(struct rpc_rqst *req, 2875static 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 */
2960static 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 */
2979static 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 */
2996static 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
2795static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) 3011static 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;
2903out_overflow: 3122out_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:
3984static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_res *res) 4204static 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:
4010static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat) 4230static 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:
4042static int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf) 4262static 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 */
4494static 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
4271static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) 4513static 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);
4304xdr_error: 4549xdr_error:
@@ -4714,17 +4959,18 @@ decode_restorefh(struct xdr_stream *xdr)
4714} 4959}
4715 4960
4716static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, 4961static 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 */
5411static 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;
5451out_overflow:
5452 print_overflow_msg(__func__, xdr);
5453 return -EIO;
5454}
5144 5455
5145static int decode_getdeviceinfo(struct xdr_stream *xdr, 5456static 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
5638static 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;
5661out_overflow:
5662 print_overflow_msg(__func__, xdr);
5663out:
5664 return -EIO;
5665}
5666
5667static 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;
5682out_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
5687out: 6048out:
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 */
6732static 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);
6751out:
6752 return status;
6753}
6754
6755/*
6369 * Decode GETDEVINFO response 6756 * Decode GETDEVINFO response
6370 */ 6757 */
6371static int nfs4_xdr_dec_getdeviceinfo(struct rpc_rqst *rqstp, 6758static int nfs4_xdr_dec_getdeviceinfo(struct rpc_rqst *rqstp,
@@ -6461,6 +6848,72 @@ static int nfs4_xdr_dec_layoutcommit(struct rpc_rqst *rqstp,
6461out: 6848out:
6462 return status; 6849 return status;
6463} 6850}
6851
6852/*
6853 * Decode SECINFO_NO_NAME response
6854 */
6855static 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);
6872out:
6873 return status;
6874}
6875
6876/*
6877 * Decode TEST_STATEID response
6878 */
6879static 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);
6893out:
6894 return status;
6895}
6896
6897/*
6898 * Decode FREE_STATEID response
6899 */
6900static 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);
6914out:
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:
6480int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, 6933int 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