1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com>
4  */
5 #ifndef __LINUX_FS_NFS_NFS4_2XDR_H
6 #define __LINUX_FS_NFS_NFS4_2XDR_H
7 
8 #include "nfs42.h"
9 
10 /* Not limited by NFS itself, limited by the generic xattr code */
11 #define nfs4_xattr_name_maxsz   XDR_QUADLEN(XATTR_NAME_MAX)
12 
13 #define encode_fallocate_maxsz		(encode_stateid_maxsz + \
14 					 2 /* offset */ + \
15 					 2 /* length */)
16 #define NFS42_WRITE_RES_SIZE		(1 /* wr_callback_id size */ +\
17 					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
18 					 2 /* wr_count */ + \
19 					 1 /* wr_committed */ + \
20 					 XDR_QUADLEN(NFS4_VERIFIER_SIZE))
21 #define encode_allocate_maxsz		(op_encode_hdr_maxsz + \
22 					 encode_fallocate_maxsz)
23 #define decode_allocate_maxsz		(op_decode_hdr_maxsz)
24 #define encode_copy_maxsz		(op_encode_hdr_maxsz +          \
25 					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
26 					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
27 					 2 + 2 + 2 + 1 + 1 + 1 +\
28 					 1 + /* One cnr_source_server */\
29 					 1 + /* nl4_type */ \
30 					 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
31 #define decode_copy_maxsz		(op_decode_hdr_maxsz + \
32 					 NFS42_WRITE_RES_SIZE + \
33 					 1 /* cr_consecutive */ + \
34 					 1 /* cr_synchronous */)
35 #define encode_offload_cancel_maxsz	(op_encode_hdr_maxsz + \
36 					 XDR_QUADLEN(NFS4_STATEID_SIZE))
37 #define decode_offload_cancel_maxsz	(op_decode_hdr_maxsz)
38 #define encode_offload_status_maxsz	(op_encode_hdr_maxsz + \
39 					 XDR_QUADLEN(NFS4_STATEID_SIZE))
40 #define decode_offload_status_maxsz	(op_decode_hdr_maxsz + \
41 					 2 /* osr_count */ + \
42 					 2 /* osr_complete */)
43 #define encode_copy_notify_maxsz	(op_encode_hdr_maxsz + \
44 					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
45 					 1 + /* nl4_type */ \
46 					 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
47 #define decode_copy_notify_maxsz	(op_decode_hdr_maxsz + \
48 					 3 + /* cnr_lease_time */\
49 					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
50 					 1 + /* Support 1 cnr_source_server */\
51 					 1 + /* nl4_type */ \
52 					 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
53 #define encode_deallocate_maxsz		(op_encode_hdr_maxsz + \
54 					 encode_fallocate_maxsz)
55 #define decode_deallocate_maxsz		(op_decode_hdr_maxsz)
56 #define encode_read_plus_maxsz		(op_encode_hdr_maxsz + \
57 					 encode_stateid_maxsz + 3)
58 #define NFS42_READ_PLUS_DATA_SEGMENT_SIZE \
59 					(1 /* data_content4 */ + \
60 					 2 /* data_info4.di_offset */ + \
61 					 1 /* data_info4.di_length */)
62 #define NFS42_READ_PLUS_HOLE_SEGMENT_SIZE \
63 					(1 /* data_content4 */ + \
64 					 2 /* data_info4.di_offset */ + \
65 					 2 /* data_info4.di_length */)
66 #define READ_PLUS_SEGMENT_SIZE_DIFF	(NFS42_READ_PLUS_HOLE_SEGMENT_SIZE - \
67 					 NFS42_READ_PLUS_DATA_SEGMENT_SIZE)
68 #define decode_read_plus_maxsz		(op_decode_hdr_maxsz + \
69 					 1 /* rpr_eof */ + \
70 					 1 /* rpr_contents count */ + \
71 					 NFS42_READ_PLUS_HOLE_SEGMENT_SIZE)
72 #define encode_seek_maxsz		(op_encode_hdr_maxsz + \
73 					 encode_stateid_maxsz + \
74 					 2 /* offset */ + \
75 					 1 /* whence */)
76 #define decode_seek_maxsz		(op_decode_hdr_maxsz + \
77 					 1 /* eof */ + \
78 					 1 /* whence */ + \
79 					 2 /* offset */ + \
80 					 2 /* length */)
81 #define encode_io_info_maxsz		4
82 #define encode_layoutstats_maxsz	(op_decode_hdr_maxsz + \
83 					2 /* offset */ + \
84 					2 /* length */ + \
85 					encode_stateid_maxsz + \
86 					encode_io_info_maxsz + \
87 					encode_io_info_maxsz + \
88 					1 /* opaque devaddr4 length */ + \
89 					XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE))
90 #define decode_layoutstats_maxsz	(op_decode_hdr_maxsz)
91 #define encode_device_error_maxsz	(XDR_QUADLEN(NFS4_DEVICEID4_SIZE) + \
92 					1 /* status */ + 1 /* opnum */)
93 #define encode_layouterror_maxsz	(op_decode_hdr_maxsz + \
94 					2 /* offset */ + \
95 					2 /* length */ + \
96 					encode_stateid_maxsz + \
97 					1 /* Array size */ + \
98 					encode_device_error_maxsz)
99 #define decode_layouterror_maxsz	(op_decode_hdr_maxsz)
100 #define encode_clone_maxsz		(encode_stateid_maxsz + \
101 					encode_stateid_maxsz + \
102 					2 /* src offset */ + \
103 					2 /* dst offset */ + \
104 					2 /* count */)
105 #define decode_clone_maxsz		(op_decode_hdr_maxsz)
106 #define encode_getxattr_maxsz		(op_encode_hdr_maxsz + 1 + \
107 					 nfs4_xattr_name_maxsz)
108 #define decode_getxattr_maxsz		(op_decode_hdr_maxsz + 1 + pagepad_maxsz)
109 #define encode_setxattr_maxsz		(op_encode_hdr_maxsz + \
110 					 1 + nfs4_xattr_name_maxsz + 1)
111 #define decode_setxattr_maxsz		(op_decode_hdr_maxsz + decode_change_info_maxsz)
112 #define encode_listxattrs_maxsz		(op_encode_hdr_maxsz + 2 + 1)
113 #define decode_listxattrs_maxsz		(op_decode_hdr_maxsz + 2 + 1 + 1 + 1)
114 #define encode_removexattr_maxsz	(op_encode_hdr_maxsz + 1 + \
115 					 nfs4_xattr_name_maxsz)
116 #define decode_removexattr_maxsz	(op_decode_hdr_maxsz + \
117 					 decode_change_info_maxsz)
118 
119 #define NFS4_enc_allocate_sz		(compound_encode_hdr_maxsz + \
120 					 encode_sequence_maxsz + \
121 					 encode_putfh_maxsz + \
122 					 encode_allocate_maxsz + \
123 					 encode_getattr_maxsz)
124 #define NFS4_dec_allocate_sz		(compound_decode_hdr_maxsz + \
125 					 decode_sequence_maxsz + \
126 					 decode_putfh_maxsz + \
127 					 decode_allocate_maxsz + \
128 					 decode_getattr_maxsz)
129 #define NFS4_enc_copy_sz		(compound_encode_hdr_maxsz + \
130 					 encode_sequence_maxsz + \
131 					 encode_putfh_maxsz + \
132 					 encode_savefh_maxsz + \
133 					 encode_putfh_maxsz + \
134 					 encode_copy_maxsz + \
135 					 encode_commit_maxsz)
136 #define NFS4_dec_copy_sz		(compound_decode_hdr_maxsz + \
137 					 decode_sequence_maxsz + \
138 					 decode_putfh_maxsz + \
139 					 decode_savefh_maxsz + \
140 					 decode_putfh_maxsz + \
141 					 decode_copy_maxsz + \
142 					 decode_commit_maxsz)
143 #define NFS4_enc_offload_cancel_sz	(compound_encode_hdr_maxsz + \
144 					 encode_sequence_maxsz + \
145 					 encode_putfh_maxsz + \
146 					 encode_offload_cancel_maxsz)
147 #define NFS4_dec_offload_cancel_sz	(compound_decode_hdr_maxsz + \
148 					 decode_sequence_maxsz + \
149 					 decode_putfh_maxsz + \
150 					 decode_offload_cancel_maxsz)
151 #define NFS4_enc_offload_status_sz	(compound_encode_hdr_maxsz + \
152 					 encode_sequence_maxsz + \
153 					 encode_putfh_maxsz + \
154 					 encode_offload_status_maxsz)
155 #define NFS4_dec_offload_status_sz	(compound_decode_hdr_maxsz + \
156 					 decode_sequence_maxsz + \
157 					 decode_putfh_maxsz + \
158 					 decode_offload_status_maxsz)
159 #define NFS4_enc_copy_notify_sz		(compound_encode_hdr_maxsz + \
160 					 encode_sequence_maxsz + \
161 					 encode_putfh_maxsz + \
162 					 encode_copy_notify_maxsz)
163 #define NFS4_dec_copy_notify_sz		(compound_decode_hdr_maxsz + \
164 					 decode_sequence_maxsz + \
165 					 decode_putfh_maxsz + \
166 					 decode_copy_notify_maxsz)
167 #define NFS4_enc_deallocate_sz		(compound_encode_hdr_maxsz + \
168 					 encode_sequence_maxsz + \
169 					 encode_putfh_maxsz + \
170 					 encode_deallocate_maxsz + \
171 					 encode_getattr_maxsz)
172 #define NFS4_dec_deallocate_sz		(compound_decode_hdr_maxsz + \
173 					 decode_sequence_maxsz + \
174 					 decode_putfh_maxsz + \
175 					 decode_deallocate_maxsz + \
176 					 decode_getattr_maxsz)
177 #define NFS4_enc_read_plus_sz		(compound_encode_hdr_maxsz + \
178 					 encode_sequence_maxsz + \
179 					 encode_putfh_maxsz + \
180 					 encode_read_plus_maxsz)
181 #define NFS4_dec_read_plus_sz		(compound_decode_hdr_maxsz + \
182 					 decode_sequence_maxsz + \
183 					 decode_putfh_maxsz + \
184 					 decode_read_plus_maxsz)
185 #define NFS4_enc_seek_sz		(compound_encode_hdr_maxsz + \
186 					 encode_sequence_maxsz + \
187 					 encode_putfh_maxsz + \
188 					 encode_seek_maxsz)
189 #define NFS4_dec_seek_sz		(compound_decode_hdr_maxsz + \
190 					 decode_sequence_maxsz + \
191 					 decode_putfh_maxsz + \
192 					 decode_seek_maxsz)
193 #define NFS4_enc_layoutstats_sz		(compound_encode_hdr_maxsz + \
194 					 encode_sequence_maxsz + \
195 					 encode_putfh_maxsz + \
196 					 PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz)
197 #define NFS4_dec_layoutstats_sz		(compound_decode_hdr_maxsz + \
198 					 decode_sequence_maxsz + \
199 					 decode_putfh_maxsz + \
200 					 PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz)
201 #define NFS4_enc_layouterror_sz		(compound_encode_hdr_maxsz + \
202 					 encode_sequence_maxsz + \
203 					 encode_putfh_maxsz + \
204 					 NFS42_LAYOUTERROR_MAX * \
205 					 encode_layouterror_maxsz)
206 #define NFS4_dec_layouterror_sz		(compound_decode_hdr_maxsz + \
207 					 decode_sequence_maxsz + \
208 					 decode_putfh_maxsz + \
209 					 NFS42_LAYOUTERROR_MAX * \
210 					 decode_layouterror_maxsz)
211 #define NFS4_enc_clone_sz		(compound_encode_hdr_maxsz + \
212 					 encode_sequence_maxsz + \
213 					 encode_putfh_maxsz + \
214 					 encode_savefh_maxsz + \
215 					 encode_putfh_maxsz + \
216 					 encode_clone_maxsz + \
217 					 encode_getattr_maxsz)
218 #define NFS4_dec_clone_sz		(compound_decode_hdr_maxsz + \
219 					 decode_sequence_maxsz + \
220 					 decode_putfh_maxsz + \
221 					 decode_savefh_maxsz + \
222 					 decode_putfh_maxsz + \
223 					 decode_clone_maxsz + \
224 					 decode_getattr_maxsz)
225 #define NFS4_enc_getxattr_sz		(compound_encode_hdr_maxsz + \
226 					 encode_sequence_maxsz + \
227 					 encode_putfh_maxsz + \
228 					 encode_getxattr_maxsz)
229 #define NFS4_dec_getxattr_sz		(compound_decode_hdr_maxsz + \
230 					 decode_sequence_maxsz + \
231 					 decode_putfh_maxsz + \
232 					 decode_getxattr_maxsz)
233 #define NFS4_enc_setxattr_sz		(compound_encode_hdr_maxsz + \
234 					 encode_sequence_maxsz + \
235 					 encode_putfh_maxsz + \
236 					 encode_setxattr_maxsz + \
237 					 encode_getattr_maxsz)
238 #define NFS4_dec_setxattr_sz		(compound_decode_hdr_maxsz + \
239 					 decode_sequence_maxsz + \
240 					 decode_putfh_maxsz + \
241 					 decode_setxattr_maxsz + \
242 					 decode_getattr_maxsz)
243 #define NFS4_enc_listxattrs_sz		(compound_encode_hdr_maxsz + \
244 					 encode_sequence_maxsz + \
245 					 encode_putfh_maxsz + \
246 					 encode_listxattrs_maxsz)
247 #define NFS4_dec_listxattrs_sz		(compound_decode_hdr_maxsz + \
248 					 decode_sequence_maxsz + \
249 					 decode_putfh_maxsz + \
250 					 decode_listxattrs_maxsz)
251 #define NFS4_enc_removexattr_sz		(compound_encode_hdr_maxsz + \
252 					 encode_sequence_maxsz + \
253 					 encode_putfh_maxsz + \
254 					 encode_removexattr_maxsz)
255 #define NFS4_dec_removexattr_sz		(compound_decode_hdr_maxsz + \
256 					 decode_sequence_maxsz + \
257 					 decode_putfh_maxsz + \
258 					 decode_removexattr_maxsz)
259 
260 /*
261  * These values specify the maximum amount of data that is not
262  * associated with the extended attribute name or extended
263  * attribute list in the SETXATTR, GETXATTR and LISTXATTR
264  * respectively.
265  */
266 const u32 nfs42_maxsetxattr_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
267 					compound_encode_hdr_maxsz +
268 					encode_sequence_maxsz +
269 					encode_putfh_maxsz + 1 +
270 					nfs4_xattr_name_maxsz)
271 					* XDR_UNIT);
272 
273 const u32 nfs42_maxgetxattr_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
274 					compound_decode_hdr_maxsz +
275 					decode_sequence_maxsz +
276 					decode_putfh_maxsz + 1) * XDR_UNIT);
277 
278 const u32 nfs42_maxlistxattrs_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
279 					compound_decode_hdr_maxsz +
280 					decode_sequence_maxsz +
281 					decode_putfh_maxsz + 3) * XDR_UNIT);
282 
encode_fallocate(struct xdr_stream * xdr,const struct nfs42_falloc_args * args)283 static void encode_fallocate(struct xdr_stream *xdr,
284 			     const struct nfs42_falloc_args *args)
285 {
286 	encode_nfs4_stateid(xdr, &args->falloc_stateid);
287 	encode_uint64(xdr, args->falloc_offset);
288 	encode_uint64(xdr, args->falloc_length);
289 }
290 
encode_allocate(struct xdr_stream * xdr,const struct nfs42_falloc_args * args,struct compound_hdr * hdr)291 static void encode_allocate(struct xdr_stream *xdr,
292 			    const struct nfs42_falloc_args *args,
293 			    struct compound_hdr *hdr)
294 {
295 	encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr);
296 	encode_fallocate(xdr, args);
297 }
298 
encode_nl4_server(struct xdr_stream * xdr,const struct nl4_server * ns)299 static void encode_nl4_server(struct xdr_stream *xdr,
300 			      const struct nl4_server *ns)
301 {
302 	encode_uint32(xdr, ns->nl4_type);
303 	switch (ns->nl4_type) {
304 	case NL4_NAME:
305 	case NL4_URL:
306 		encode_string(xdr, ns->u.nl4_str_sz, ns->u.nl4_str);
307 		break;
308 	case NL4_NETADDR:
309 		encode_string(xdr, ns->u.nl4_addr.netid_len,
310 			      ns->u.nl4_addr.netid);
311 		encode_string(xdr, ns->u.nl4_addr.addr_len,
312 			      ns->u.nl4_addr.addr);
313 		break;
314 	default:
315 		WARN_ON_ONCE(1);
316 	}
317 }
318 
encode_copy(struct xdr_stream * xdr,const struct nfs42_copy_args * args,struct compound_hdr * hdr)319 static void encode_copy(struct xdr_stream *xdr,
320 			const struct nfs42_copy_args *args,
321 			struct compound_hdr *hdr)
322 {
323 	encode_op_hdr(xdr, OP_COPY, decode_copy_maxsz, hdr);
324 	encode_nfs4_stateid(xdr, &args->src_stateid);
325 	encode_nfs4_stateid(xdr, &args->dst_stateid);
326 
327 	encode_uint64(xdr, args->src_pos);
328 	encode_uint64(xdr, args->dst_pos);
329 	encode_uint64(xdr, args->count);
330 
331 	encode_uint32(xdr, 1); /* consecutive = true */
332 	encode_uint32(xdr, args->sync);
333 	if (args->cp_src == NULL) { /* intra-ssc */
334 		encode_uint32(xdr, 0); /* no src server list */
335 		return;
336 	}
337 	encode_uint32(xdr, 1); /* supporting 1 server */
338 	encode_nl4_server(xdr, args->cp_src);
339 }
340 
encode_copy_commit(struct xdr_stream * xdr,const struct nfs42_copy_args * args,struct compound_hdr * hdr)341 static void encode_copy_commit(struct xdr_stream *xdr,
342 			  const struct nfs42_copy_args *args,
343 			  struct compound_hdr *hdr)
344 {
345 	__be32 *p;
346 
347 	encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr);
348 	p = reserve_space(xdr, 12);
349 	p = xdr_encode_hyper(p, args->dst_pos);
350 	*p = cpu_to_be32(args->count);
351 }
352 
encode_offload_cancel(struct xdr_stream * xdr,const struct nfs42_offload_status_args * args,struct compound_hdr * hdr)353 static void encode_offload_cancel(struct xdr_stream *xdr,
354 				  const struct nfs42_offload_status_args *args,
355 				  struct compound_hdr *hdr)
356 {
357 	encode_op_hdr(xdr, OP_OFFLOAD_CANCEL, decode_offload_cancel_maxsz, hdr);
358 	encode_nfs4_stateid(xdr, &args->osa_stateid);
359 }
360 
encode_offload_status(struct xdr_stream * xdr,const struct nfs42_offload_status_args * args,struct compound_hdr * hdr)361 static void encode_offload_status(struct xdr_stream *xdr,
362 				  const struct nfs42_offload_status_args *args,
363 				  struct compound_hdr *hdr)
364 {
365 	encode_op_hdr(xdr, OP_OFFLOAD_STATUS, decode_offload_status_maxsz, hdr);
366 	encode_nfs4_stateid(xdr, &args->osa_stateid);
367 }
368 
encode_copy_notify(struct xdr_stream * xdr,const struct nfs42_copy_notify_args * args,struct compound_hdr * hdr)369 static void encode_copy_notify(struct xdr_stream *xdr,
370 			       const struct nfs42_copy_notify_args *args,
371 			       struct compound_hdr *hdr)
372 {
373 	encode_op_hdr(xdr, OP_COPY_NOTIFY, decode_copy_notify_maxsz, hdr);
374 	encode_nfs4_stateid(xdr, &args->cna_src_stateid);
375 	encode_nl4_server(xdr, &args->cna_dst);
376 }
377 
encode_deallocate(struct xdr_stream * xdr,const struct nfs42_falloc_args * args,struct compound_hdr * hdr)378 static void encode_deallocate(struct xdr_stream *xdr,
379 			      const struct nfs42_falloc_args *args,
380 			      struct compound_hdr *hdr)
381 {
382 	encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr);
383 	encode_fallocate(xdr, args);
384 }
385 
encode_read_plus(struct xdr_stream * xdr,const struct nfs_pgio_args * args,struct compound_hdr * hdr)386 static void encode_read_plus(struct xdr_stream *xdr,
387 			     const struct nfs_pgio_args *args,
388 			     struct compound_hdr *hdr)
389 {
390 	encode_op_hdr(xdr, OP_READ_PLUS, decode_read_plus_maxsz, hdr);
391 	encode_nfs4_stateid(xdr, &args->stateid);
392 	encode_uint64(xdr, args->offset);
393 	encode_uint32(xdr, args->count);
394 }
395 
encode_seek(struct xdr_stream * xdr,const struct nfs42_seek_args * args,struct compound_hdr * hdr)396 static void encode_seek(struct xdr_stream *xdr,
397 			const struct nfs42_seek_args *args,
398 			struct compound_hdr *hdr)
399 {
400 	encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr);
401 	encode_nfs4_stateid(xdr, &args->sa_stateid);
402 	encode_uint64(xdr, args->sa_offset);
403 	encode_uint32(xdr, args->sa_what);
404 }
405 
encode_layoutstats(struct xdr_stream * xdr,const struct nfs42_layoutstat_args * args,struct nfs42_layoutstat_devinfo * devinfo,struct compound_hdr * hdr)406 static void encode_layoutstats(struct xdr_stream *xdr,
407 			       const struct nfs42_layoutstat_args *args,
408 			       struct nfs42_layoutstat_devinfo *devinfo,
409 			       struct compound_hdr *hdr)
410 {
411 	__be32 *p;
412 
413 	encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr);
414 	p = reserve_space(xdr, 8 + 8);
415 	p = xdr_encode_hyper(p, devinfo->offset);
416 	p = xdr_encode_hyper(p, devinfo->length);
417 	encode_nfs4_stateid(xdr, &args->stateid);
418 	p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4);
419 	p = xdr_encode_hyper(p, devinfo->read_count);
420 	p = xdr_encode_hyper(p, devinfo->read_bytes);
421 	p = xdr_encode_hyper(p, devinfo->write_count);
422 	p = xdr_encode_hyper(p, devinfo->write_bytes);
423 	p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data,
424 			NFS4_DEVICEID4_SIZE);
425 	/* Encode layoutupdate4 */
426 	*p++ = cpu_to_be32(devinfo->layout_type);
427 	if (devinfo->ld_private.ops)
428 		devinfo->ld_private.ops->encode(xdr, args,
429 				&devinfo->ld_private);
430 	else
431 		encode_uint32(xdr, 0);
432 }
433 
encode_clone(struct xdr_stream * xdr,const struct nfs42_clone_args * args,struct compound_hdr * hdr)434 static void encode_clone(struct xdr_stream *xdr,
435 			 const struct nfs42_clone_args *args,
436 			 struct compound_hdr *hdr)
437 {
438 	__be32 *p;
439 
440 	encode_op_hdr(xdr, OP_CLONE, decode_clone_maxsz, hdr);
441 	encode_nfs4_stateid(xdr, &args->src_stateid);
442 	encode_nfs4_stateid(xdr, &args->dst_stateid);
443 	p = reserve_space(xdr, 3*8);
444 	p = xdr_encode_hyper(p, args->src_offset);
445 	p = xdr_encode_hyper(p, args->dst_offset);
446 	xdr_encode_hyper(p, args->count);
447 }
448 
encode_device_error(struct xdr_stream * xdr,const struct nfs42_device_error * error)449 static void encode_device_error(struct xdr_stream *xdr,
450 				const struct nfs42_device_error *error)
451 {
452 	__be32 *p;
453 
454 	p = reserve_space(xdr, NFS4_DEVICEID4_SIZE + 2*4);
455 	p = xdr_encode_opaque_fixed(p, error->dev_id.data,
456 			NFS4_DEVICEID4_SIZE);
457 	*p++ = cpu_to_be32(error->status);
458 	*p = cpu_to_be32(error->opnum);
459 }
460 
encode_layouterror(struct xdr_stream * xdr,const struct nfs42_layout_error * args,struct compound_hdr * hdr)461 static void encode_layouterror(struct xdr_stream *xdr,
462 			       const struct nfs42_layout_error *args,
463 			       struct compound_hdr *hdr)
464 {
465 	__be32 *p;
466 
467 	encode_op_hdr(xdr, OP_LAYOUTERROR, decode_layouterror_maxsz, hdr);
468 	p = reserve_space(xdr, 8 + 8);
469 	p = xdr_encode_hyper(p, args->offset);
470 	p = xdr_encode_hyper(p, args->length);
471 	encode_nfs4_stateid(xdr, &args->stateid);
472 	p = reserve_space(xdr, 4);
473 	*p = cpu_to_be32(1);
474 	encode_device_error(xdr, &args->errors[0]);
475 }
476 
encode_setxattr(struct xdr_stream * xdr,const struct nfs42_setxattrargs * arg,struct compound_hdr * hdr)477 static void encode_setxattr(struct xdr_stream *xdr,
478 			    const struct nfs42_setxattrargs *arg,
479 			    struct compound_hdr *hdr)
480 {
481 	__be32 *p;
482 
483 	BUILD_BUG_ON(XATTR_CREATE != SETXATTR4_CREATE);
484 	BUILD_BUG_ON(XATTR_REPLACE != SETXATTR4_REPLACE);
485 
486 	encode_op_hdr(xdr, OP_SETXATTR, decode_setxattr_maxsz, hdr);
487 	p = reserve_space(xdr, 4);
488 	*p = cpu_to_be32(arg->xattr_flags);
489 	encode_string(xdr, strlen(arg->xattr_name), arg->xattr_name);
490 	p = reserve_space(xdr, 4);
491 	*p = cpu_to_be32(arg->xattr_len);
492 	if (arg->xattr_len)
493 		xdr_write_pages(xdr, arg->xattr_pages, 0, arg->xattr_len);
494 }
495 
encode_getxattr(struct xdr_stream * xdr,const char * name,struct compound_hdr * hdr)496 static void encode_getxattr(struct xdr_stream *xdr, const char *name,
497 			    struct compound_hdr *hdr)
498 {
499 	encode_op_hdr(xdr, OP_GETXATTR, decode_getxattr_maxsz, hdr);
500 	encode_string(xdr, strlen(name), name);
501 }
502 
encode_removexattr(struct xdr_stream * xdr,const char * name,struct compound_hdr * hdr)503 static void encode_removexattr(struct xdr_stream *xdr, const char *name,
504 			       struct compound_hdr *hdr)
505 {
506 	encode_op_hdr(xdr, OP_REMOVEXATTR, decode_removexattr_maxsz, hdr);
507 	encode_string(xdr, strlen(name), name);
508 }
509 
encode_listxattrs(struct xdr_stream * xdr,const struct nfs42_listxattrsargs * arg,struct compound_hdr * hdr)510 static void encode_listxattrs(struct xdr_stream *xdr,
511 			     const struct nfs42_listxattrsargs *arg,
512 			     struct compound_hdr *hdr)
513 {
514 	__be32 *p;
515 
516 	encode_op_hdr(xdr, OP_LISTXATTRS, decode_listxattrs_maxsz, hdr);
517 
518 	p = reserve_space(xdr, 12);
519 	if (unlikely(!p))
520 		return;
521 
522 	p = xdr_encode_hyper(p, arg->cookie);
523 	/*
524 	 * RFC 8276 says to specify the full max length of the LISTXATTRS
525 	 * XDR reply. Count is set to the XDR length of the names array
526 	 * plus the EOF marker. So, add the cookie and the names count.
527 	 */
528 	*p = cpu_to_be32(arg->count + 8 + 4);
529 }
530 
531 /*
532  * Encode ALLOCATE request
533  */
nfs4_xdr_enc_allocate(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)534 static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
535 				  struct xdr_stream *xdr,
536 				  const void *data)
537 {
538 	const struct nfs42_falloc_args *args = data;
539 	struct compound_hdr hdr = {
540 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
541 	};
542 
543 	encode_compound_hdr(xdr, req, &hdr);
544 	encode_sequence(xdr, &args->seq_args, &hdr);
545 	encode_putfh(xdr, args->falloc_fh, &hdr);
546 	encode_allocate(xdr, args, &hdr);
547 	encode_getfattr(xdr, args->falloc_bitmask, &hdr);
548 	encode_nops(&hdr);
549 }
550 
551 /*
552  * Encode COPY request
553  */
nfs4_xdr_enc_copy(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)554 static void nfs4_xdr_enc_copy(struct rpc_rqst *req,
555 			      struct xdr_stream *xdr,
556 			      const void *data)
557 {
558 	const struct nfs42_copy_args *args = data;
559 	struct compound_hdr hdr = {
560 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
561 	};
562 
563 	encode_compound_hdr(xdr, req, &hdr);
564 	encode_sequence(xdr, &args->seq_args, &hdr);
565 	encode_putfh(xdr, args->src_fh, &hdr);
566 	encode_savefh(xdr, &hdr);
567 	encode_putfh(xdr, args->dst_fh, &hdr);
568 	encode_copy(xdr, args, &hdr);
569 	if (args->sync)
570 		encode_copy_commit(xdr, args, &hdr);
571 	encode_nops(&hdr);
572 }
573 
574 /*
575  * Encode OFFLOAD_CANCEL request
576  */
nfs4_xdr_enc_offload_cancel(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)577 static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req,
578 					struct xdr_stream *xdr,
579 					const void *data)
580 {
581 	const struct nfs42_offload_status_args *args = data;
582 	struct compound_hdr hdr = {
583 		.minorversion = nfs4_xdr_minorversion(&args->osa_seq_args),
584 	};
585 
586 	encode_compound_hdr(xdr, req, &hdr);
587 	encode_sequence(xdr, &args->osa_seq_args, &hdr);
588 	encode_putfh(xdr, args->osa_src_fh, &hdr);
589 	encode_offload_cancel(xdr, args, &hdr);
590 	encode_nops(&hdr);
591 }
592 
593 /*
594  * Encode OFFLOAD_STATUS request
595  */
nfs4_xdr_enc_offload_status(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)596 static void nfs4_xdr_enc_offload_status(struct rpc_rqst *req,
597 					struct xdr_stream *xdr,
598 					const void *data)
599 {
600 	const struct nfs42_offload_status_args *args = data;
601 	struct compound_hdr hdr = {
602 		.minorversion = nfs4_xdr_minorversion(&args->osa_seq_args),
603 	};
604 
605 	encode_compound_hdr(xdr, req, &hdr);
606 	encode_sequence(xdr, &args->osa_seq_args, &hdr);
607 	encode_putfh(xdr, args->osa_src_fh, &hdr);
608 	encode_offload_status(xdr, args, &hdr);
609 	encode_nops(&hdr);
610 }
611 
612 /*
613  * Encode COPY_NOTIFY request
614  */
nfs4_xdr_enc_copy_notify(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)615 static void nfs4_xdr_enc_copy_notify(struct rpc_rqst *req,
616 				     struct xdr_stream *xdr,
617 				     const void *data)
618 {
619 	const struct nfs42_copy_notify_args *args = data;
620 	struct compound_hdr hdr = {
621 		.minorversion = nfs4_xdr_minorversion(&args->cna_seq_args),
622 	};
623 
624 	encode_compound_hdr(xdr, req, &hdr);
625 	encode_sequence(xdr, &args->cna_seq_args, &hdr);
626 	encode_putfh(xdr, args->cna_src_fh, &hdr);
627 	encode_copy_notify(xdr, args, &hdr);
628 	encode_nops(&hdr);
629 }
630 
631 /*
632  * Encode DEALLOCATE request
633  */
nfs4_xdr_enc_deallocate(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)634 static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
635 				    struct xdr_stream *xdr,
636 				    const void *data)
637 {
638 	const struct nfs42_falloc_args *args = data;
639 	struct compound_hdr hdr = {
640 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
641 	};
642 
643 	encode_compound_hdr(xdr, req, &hdr);
644 	encode_sequence(xdr, &args->seq_args, &hdr);
645 	encode_putfh(xdr, args->falloc_fh, &hdr);
646 	encode_deallocate(xdr, args, &hdr);
647 	encode_getfattr(xdr, args->falloc_bitmask, &hdr);
648 	encode_nops(&hdr);
649 }
650 
651 /*
652  * Encode READ_PLUS request
653  */
nfs4_xdr_enc_read_plus(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)654 static void nfs4_xdr_enc_read_plus(struct rpc_rqst *req,
655 				   struct xdr_stream *xdr,
656 				   const void *data)
657 {
658 	const struct nfs_pgio_args *args = data;
659 	struct compound_hdr hdr = {
660 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
661 	};
662 
663 	encode_compound_hdr(xdr, req, &hdr);
664 	encode_sequence(xdr, &args->seq_args, &hdr);
665 	encode_putfh(xdr, args->fh, &hdr);
666 	encode_read_plus(xdr, args, &hdr);
667 
668 	rpc_prepare_reply_pages(req, args->pages, args->pgbase, args->count,
669 				hdr.replen - READ_PLUS_SEGMENT_SIZE_DIFF);
670 	encode_nops(&hdr);
671 }
672 
673 /*
674  * Encode SEEK request
675  */
nfs4_xdr_enc_seek(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)676 static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
677 			      struct xdr_stream *xdr,
678 			      const void *data)
679 {
680 	const struct nfs42_seek_args *args = data;
681 	struct compound_hdr hdr = {
682 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
683 	};
684 
685 	encode_compound_hdr(xdr, req, &hdr);
686 	encode_sequence(xdr, &args->seq_args, &hdr);
687 	encode_putfh(xdr, args->sa_fh, &hdr);
688 	encode_seek(xdr, args, &hdr);
689 	encode_nops(&hdr);
690 }
691 
692 /*
693  * Encode LAYOUTSTATS request
694  */
nfs4_xdr_enc_layoutstats(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)695 static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req,
696 				     struct xdr_stream *xdr,
697 				     const void *data)
698 {
699 	const struct nfs42_layoutstat_args *args = data;
700 	int i;
701 
702 	struct compound_hdr hdr = {
703 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
704 	};
705 
706 	encode_compound_hdr(xdr, req, &hdr);
707 	encode_sequence(xdr, &args->seq_args, &hdr);
708 	encode_putfh(xdr, args->fh, &hdr);
709 	WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
710 	for (i = 0; i < args->num_dev; i++)
711 		encode_layoutstats(xdr, args, &args->devinfo[i], &hdr);
712 	encode_nops(&hdr);
713 }
714 
715 /*
716  * Encode CLONE request
717  */
nfs4_xdr_enc_clone(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)718 static void nfs4_xdr_enc_clone(struct rpc_rqst *req,
719 			       struct xdr_stream *xdr,
720 			       const void *data)
721 {
722 	const struct nfs42_clone_args *args = data;
723 	struct compound_hdr hdr = {
724 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
725 	};
726 
727 	encode_compound_hdr(xdr, req, &hdr);
728 	encode_sequence(xdr, &args->seq_args, &hdr);
729 	encode_putfh(xdr, args->src_fh, &hdr);
730 	encode_savefh(xdr, &hdr);
731 	encode_putfh(xdr, args->dst_fh, &hdr);
732 	encode_clone(xdr, args, &hdr);
733 	encode_getfattr(xdr, args->dst_bitmask, &hdr);
734 	encode_nops(&hdr);
735 }
736 
737 /*
738  * Encode LAYOUTERROR request
739  */
nfs4_xdr_enc_layouterror(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)740 static void nfs4_xdr_enc_layouterror(struct rpc_rqst *req,
741 				     struct xdr_stream *xdr,
742 				     const void *data)
743 {
744 	const struct nfs42_layouterror_args *args = data;
745 	struct compound_hdr hdr = {
746 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
747 	};
748 	int i;
749 
750 	encode_compound_hdr(xdr, req, &hdr);
751 	encode_sequence(xdr, &args->seq_args, &hdr);
752 	encode_putfh(xdr, NFS_FH(args->inode), &hdr);
753 	for (i = 0; i < args->num_errors; i++)
754 		encode_layouterror(xdr, &args->errors[i], &hdr);
755 	encode_nops(&hdr);
756 }
757 
758 /*
759  * Encode SETXATTR request
760  */
nfs4_xdr_enc_setxattr(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)761 static void nfs4_xdr_enc_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
762 				  const void *data)
763 {
764 	const struct nfs42_setxattrargs *args = data;
765 	struct compound_hdr hdr = {
766 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
767 	};
768 
769 	encode_compound_hdr(xdr, req, &hdr);
770 	encode_sequence(xdr, &args->seq_args, &hdr);
771 	encode_putfh(xdr, args->fh, &hdr);
772 	encode_setxattr(xdr, args, &hdr);
773 	encode_getfattr(xdr, args->bitmask, &hdr);
774 	encode_nops(&hdr);
775 }
776 
777 /*
778  * Encode GETXATTR request
779  */
nfs4_xdr_enc_getxattr(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)780 static void nfs4_xdr_enc_getxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
781 				  const void *data)
782 {
783 	const struct nfs42_getxattrargs *args = data;
784 	struct compound_hdr hdr = {
785 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
786 	};
787 	uint32_t replen;
788 
789 	encode_compound_hdr(xdr, req, &hdr);
790 	encode_sequence(xdr, &args->seq_args, &hdr);
791 	encode_putfh(xdr, args->fh, &hdr);
792 	replen = hdr.replen + op_decode_hdr_maxsz + 1;
793 	encode_getxattr(xdr, args->xattr_name, &hdr);
794 
795 	rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->xattr_len,
796 				replen);
797 
798 	encode_nops(&hdr);
799 }
800 
801 /*
802  * Encode LISTXATTR request
803  */
nfs4_xdr_enc_listxattrs(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)804 static void nfs4_xdr_enc_listxattrs(struct rpc_rqst *req,
805 				    struct xdr_stream *xdr, const void *data)
806 {
807 	const struct nfs42_listxattrsargs *args = data;
808 	struct compound_hdr hdr = {
809 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
810 	};
811 	uint32_t replen;
812 
813 	encode_compound_hdr(xdr, req, &hdr);
814 	encode_sequence(xdr, &args->seq_args, &hdr);
815 	encode_putfh(xdr, args->fh, &hdr);
816 	replen = hdr.replen + op_decode_hdr_maxsz + 2 + 1;
817 	encode_listxattrs(xdr, args, &hdr);
818 
819 	rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->count, replen);
820 
821 	encode_nops(&hdr);
822 }
823 
824 /*
825  * Encode REMOVEXATTR request
826  */
nfs4_xdr_enc_removexattr(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)827 static void nfs4_xdr_enc_removexattr(struct rpc_rqst *req,
828 				     struct xdr_stream *xdr, const void *data)
829 {
830 	const struct nfs42_removexattrargs *args = data;
831 	struct compound_hdr hdr = {
832 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
833 	};
834 
835 	encode_compound_hdr(xdr, req, &hdr);
836 	encode_sequence(xdr, &args->seq_args, &hdr);
837 	encode_putfh(xdr, args->fh, &hdr);
838 	encode_removexattr(xdr, args->xattr_name, &hdr);
839 	encode_nops(&hdr);
840 }
841 
decode_allocate(struct xdr_stream * xdr,struct nfs42_falloc_res * res)842 static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
843 {
844 	return decode_op_hdr(xdr, OP_ALLOCATE);
845 }
846 
decode_write_response(struct xdr_stream * xdr,struct nfs42_write_res * res)847 static int decode_write_response(struct xdr_stream *xdr,
848 				 struct nfs42_write_res *res)
849 {
850 	__be32 *p;
851 	int status, count;
852 
853 	p = xdr_inline_decode(xdr, 4);
854 	if (unlikely(!p))
855 		return -EIO;
856 	count = be32_to_cpup(p);
857 	if (count > 1)
858 		return -EREMOTEIO;
859 	else if (count == 1) {
860 		status = decode_opaque_fixed(xdr, &res->stateid,
861 				NFS4_STATEID_SIZE);
862 		if (unlikely(status))
863 			return -EIO;
864 	}
865 	p = xdr_inline_decode(xdr, 8 + 4);
866 	if (unlikely(!p))
867 		return -EIO;
868 	p = xdr_decode_hyper(p, &res->count);
869 	res->verifier.committed = be32_to_cpup(p);
870 	return decode_verifier(xdr, &res->verifier.verifier);
871 }
872 
decode_nl4_server(struct xdr_stream * xdr,struct nl4_server * ns)873 static int decode_nl4_server(struct xdr_stream *xdr, struct nl4_server *ns)
874 {
875 	struct nfs42_netaddr *naddr;
876 	uint32_t dummy;
877 	char *dummy_str;
878 	__be32 *p;
879 	int status;
880 
881 	/* nl_type */
882 	p = xdr_inline_decode(xdr, 4);
883 	if (unlikely(!p))
884 		return -EIO;
885 	ns->nl4_type = be32_to_cpup(p);
886 	switch (ns->nl4_type) {
887 	case NL4_NAME:
888 	case NL4_URL:
889 		status = decode_opaque_inline(xdr, &dummy, &dummy_str);
890 		if (unlikely(status))
891 			return status;
892 		if (unlikely(dummy > NFS4_OPAQUE_LIMIT))
893 			return -EIO;
894 		memcpy(&ns->u.nl4_str, dummy_str, dummy);
895 		ns->u.nl4_str_sz = dummy;
896 		break;
897 	case NL4_NETADDR:
898 		naddr = &ns->u.nl4_addr;
899 
900 		/* netid string */
901 		status = decode_opaque_inline(xdr, &dummy, &dummy_str);
902 		if (unlikely(status))
903 			return status;
904 		if (unlikely(dummy > RPCBIND_MAXNETIDLEN))
905 			return -EIO;
906 		naddr->netid_len = dummy;
907 		memcpy(naddr->netid, dummy_str, naddr->netid_len);
908 
909 		/* uaddr string */
910 		status = decode_opaque_inline(xdr, &dummy, &dummy_str);
911 		if (unlikely(status))
912 			return status;
913 		if (unlikely(dummy > RPCBIND_MAXUADDRLEN))
914 			return -EIO;
915 		naddr->addr_len = dummy;
916 		memcpy(naddr->addr, dummy_str, naddr->addr_len);
917 		break;
918 	default:
919 		WARN_ON_ONCE(1);
920 		return -EIO;
921 	}
922 	return 0;
923 }
924 
decode_copy_requirements(struct xdr_stream * xdr,struct nfs42_copy_res * res)925 static int decode_copy_requirements(struct xdr_stream *xdr,
926 				    struct nfs42_copy_res *res) {
927 	__be32 *p;
928 
929 	p = xdr_inline_decode(xdr, 4 + 4);
930 	if (unlikely(!p))
931 		return -EIO;
932 
933 	res->consecutive = be32_to_cpup(p++);
934 	res->synchronous = be32_to_cpup(p++);
935 	return 0;
936 }
937 
decode_copy(struct xdr_stream * xdr,struct nfs42_copy_res * res)938 static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res)
939 {
940 	int status;
941 
942 	status = decode_op_hdr(xdr, OP_COPY);
943 	if (status == NFS4ERR_OFFLOAD_NO_REQS) {
944 		status = decode_copy_requirements(xdr, res);
945 		if (status)
946 			return status;
947 		return NFS4ERR_OFFLOAD_NO_REQS;
948 	} else if (status)
949 		return status;
950 
951 	status = decode_write_response(xdr, &res->write_res);
952 	if (status)
953 		return status;
954 
955 	return decode_copy_requirements(xdr, res);
956 }
957 
decode_offload_cancel(struct xdr_stream * xdr,struct nfs42_offload_status_res * res)958 static int decode_offload_cancel(struct xdr_stream *xdr,
959 				 struct nfs42_offload_status_res *res)
960 {
961 	return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL);
962 }
963 
decode_offload_status(struct xdr_stream * xdr,struct nfs42_offload_status_res * res)964 static int decode_offload_status(struct xdr_stream *xdr,
965 				 struct nfs42_offload_status_res *res)
966 {
967 	ssize_t result;
968 	int status;
969 
970 	status = decode_op_hdr(xdr, OP_OFFLOAD_STATUS);
971 	if (status)
972 		return status;
973 	/* osr_count */
974 	if (xdr_stream_decode_u64(xdr, &res->osr_count) < 0)
975 		return -EIO;
976 	/* osr_complete<1> */
977 	result = xdr_stream_decode_uint32_array(xdr, &res->osr_complete, 1);
978 	if (result < 0)
979 		return -EIO;
980 	res->complete_count = result;
981 	return 0;
982 }
983 
decode_copy_notify(struct xdr_stream * xdr,struct nfs42_copy_notify_res * res)984 static int decode_copy_notify(struct xdr_stream *xdr,
985 			      struct nfs42_copy_notify_res *res)
986 {
987 	__be32 *p;
988 	int status, count;
989 
990 	status = decode_op_hdr(xdr, OP_COPY_NOTIFY);
991 	if (status)
992 		return status;
993 	/* cnr_lease_time */
994 	p = xdr_inline_decode(xdr, 12);
995 	if (unlikely(!p))
996 		return -EIO;
997 	p = xdr_decode_hyper(p, &res->cnr_lease_time.seconds);
998 	res->cnr_lease_time.nseconds = be32_to_cpup(p);
999 
1000 	status = decode_opaque_fixed(xdr, &res->cnr_stateid, NFS4_STATEID_SIZE);
1001 	if (unlikely(status))
1002 		return -EIO;
1003 
1004 	/* number of source addresses */
1005 	p = xdr_inline_decode(xdr, 4);
1006 	if (unlikely(!p))
1007 		return -EIO;
1008 
1009 	count = be32_to_cpup(p);
1010 	if (count > 1)
1011 		pr_warn("NFS: %s: nsvr %d > Supported. Use first servers\n",
1012 			 __func__, count);
1013 
1014 	status = decode_nl4_server(xdr, &res->cnr_src);
1015 	if (unlikely(status))
1016 		return -EIO;
1017 	return 0;
1018 }
1019 
decode_deallocate(struct xdr_stream * xdr,struct nfs42_falloc_res * res)1020 static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
1021 {
1022 	return decode_op_hdr(xdr, OP_DEALLOCATE);
1023 }
1024 
1025 struct read_plus_segment {
1026 	enum data_content4 type;
1027 	uint64_t offset;
1028 	union {
1029 		struct {
1030 			uint64_t length;
1031 		} hole;
1032 
1033 		struct {
1034 			uint32_t length;
1035 			unsigned int from;
1036 		} data;
1037 	};
1038 };
1039 
read_plus_segment_length(struct read_plus_segment * seg)1040 static inline uint64_t read_plus_segment_length(struct read_plus_segment *seg)
1041 {
1042 	return seg->type == NFS4_CONTENT_DATA ? seg->data.length : seg->hole.length;
1043 }
1044 
decode_read_plus_segment(struct xdr_stream * xdr,struct read_plus_segment * seg)1045 static int decode_read_plus_segment(struct xdr_stream *xdr,
1046 				    struct read_plus_segment *seg)
1047 {
1048 	__be32 *p;
1049 
1050 	p = xdr_inline_decode(xdr, 4);
1051 	if (!p)
1052 		return -EIO;
1053 	seg->type = be32_to_cpup(p++);
1054 
1055 	p = xdr_inline_decode(xdr, seg->type == NFS4_CONTENT_DATA ? 12 : 16);
1056 	if (!p)
1057 		return -EIO;
1058 	p = xdr_decode_hyper(p, &seg->offset);
1059 
1060 	if (seg->type == NFS4_CONTENT_DATA) {
1061 		struct xdr_buf buf;
1062 		uint32_t len = be32_to_cpup(p);
1063 
1064 		seg->data.length = len;
1065 		seg->data.from = xdr_stream_pos(xdr);
1066 
1067 		if (!xdr_stream_subsegment(xdr, &buf, xdr_align_size(len)))
1068 			return -EIO;
1069 	} else if (seg->type == NFS4_CONTENT_HOLE) {
1070 		xdr_decode_hyper(p, &seg->hole.length);
1071 	} else
1072 		return -EINVAL;
1073 	return 0;
1074 }
1075 
process_read_plus_segment(struct xdr_stream * xdr,struct nfs_pgio_args * args,struct nfs_pgio_res * res,struct read_plus_segment * seg)1076 static int process_read_plus_segment(struct xdr_stream *xdr,
1077 				     struct nfs_pgio_args *args,
1078 				     struct nfs_pgio_res *res,
1079 				     struct read_plus_segment *seg)
1080 {
1081 	unsigned long offset = seg->offset;
1082 	unsigned long length = read_plus_segment_length(seg);
1083 	unsigned int bufpos;
1084 
1085 	if (offset + length < args->offset)
1086 		return 0;
1087 	else if (offset > args->offset + args->count) {
1088 		res->eof = 0;
1089 		return 0;
1090 	} else if (offset < args->offset) {
1091 		length -= (args->offset - offset);
1092 		offset = args->offset;
1093 	} else if (offset + length > args->offset + args->count) {
1094 		length = (args->offset + args->count) - offset;
1095 		res->eof = 0;
1096 	}
1097 
1098 	bufpos = xdr->buf->head[0].iov_len + (offset - args->offset);
1099 	if (seg->type == NFS4_CONTENT_HOLE)
1100 		return xdr_stream_zero(xdr, bufpos, length);
1101 	else
1102 		return xdr_stream_move_subsegment(xdr, seg->data.from, bufpos, length);
1103 }
1104 
decode_read_plus(struct xdr_stream * xdr,struct nfs_pgio_res * res)1105 static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)
1106 {
1107 	struct nfs_pgio_header *hdr =
1108 		container_of(res, struct nfs_pgio_header, res);
1109 	struct nfs_pgio_args *args = &hdr->args;
1110 	uint32_t segments;
1111 	struct read_plus_segment *segs;
1112 	int status, i;
1113 	__be32 *p;
1114 
1115 	status = decode_op_hdr(xdr, OP_READ_PLUS);
1116 	if (status)
1117 		return status;
1118 
1119 	p = xdr_inline_decode(xdr, 4 + 4);
1120 	if (unlikely(!p))
1121 		return -EIO;
1122 
1123 	res->count = 0;
1124 	res->eof = be32_to_cpup(p++);
1125 	segments = be32_to_cpup(p++);
1126 	if (segments == 0)
1127 		return 0;
1128 
1129 	segs = kmalloc_array(segments, sizeof(*segs), GFP_KERNEL);
1130 	if (!segs)
1131 		return -ENOMEM;
1132 
1133 	for (i = 0; i < segments; i++) {
1134 		status = decode_read_plus_segment(xdr, &segs[i]);
1135 		if (status < 0)
1136 			goto out;
1137 	}
1138 
1139 	xdr_set_pagelen(xdr, xdr_align_size(args->count));
1140 	for (i = segments; i > 0; i--)
1141 		res->count += process_read_plus_segment(xdr, args, res, &segs[i-1]);
1142 	status = 0;
1143 
1144 out:
1145 	kfree(segs);
1146 	return status;
1147 }
1148 
decode_seek(struct xdr_stream * xdr,struct nfs42_seek_res * res)1149 static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
1150 {
1151 	int status;
1152 	__be32 *p;
1153 
1154 	status = decode_op_hdr(xdr, OP_SEEK);
1155 	if (status)
1156 		return status;
1157 
1158 	p = xdr_inline_decode(xdr, 4 + 8);
1159 	if (unlikely(!p))
1160 		return -EIO;
1161 
1162 	res->sr_eof = be32_to_cpup(p++);
1163 	p = xdr_decode_hyper(p, &res->sr_offset);
1164 	return 0;
1165 }
1166 
decode_layoutstats(struct xdr_stream * xdr)1167 static int decode_layoutstats(struct xdr_stream *xdr)
1168 {
1169 	return decode_op_hdr(xdr, OP_LAYOUTSTATS);
1170 }
1171 
decode_clone(struct xdr_stream * xdr)1172 static int decode_clone(struct xdr_stream *xdr)
1173 {
1174 	return decode_op_hdr(xdr, OP_CLONE);
1175 }
1176 
decode_layouterror(struct xdr_stream * xdr)1177 static int decode_layouterror(struct xdr_stream *xdr)
1178 {
1179 	return decode_op_hdr(xdr, OP_LAYOUTERROR);
1180 }
1181 
decode_setxattr(struct xdr_stream * xdr,struct nfs4_change_info * cinfo)1182 static int decode_setxattr(struct xdr_stream *xdr,
1183 			   struct nfs4_change_info *cinfo)
1184 {
1185 	int status;
1186 
1187 	status = decode_op_hdr(xdr, OP_SETXATTR);
1188 	if (status)
1189 		goto out;
1190 	status = decode_change_info(xdr, cinfo);
1191 out:
1192 	return status;
1193 }
1194 
decode_getxattr(struct xdr_stream * xdr,struct nfs42_getxattrres * res,struct rpc_rqst * req)1195 static int decode_getxattr(struct xdr_stream *xdr,
1196 			   struct nfs42_getxattrres *res,
1197 			   struct rpc_rqst *req)
1198 {
1199 	int status;
1200 	__be32 *p;
1201 	u32 len, rdlen;
1202 
1203 	status = decode_op_hdr(xdr, OP_GETXATTR);
1204 	if (status)
1205 		return status;
1206 
1207 	p = xdr_inline_decode(xdr, 4);
1208 	if (unlikely(!p))
1209 		return -EIO;
1210 
1211 	len = be32_to_cpup(p);
1212 
1213 	/*
1214 	 * Only check against the page length here. The actual
1215 	 * requested length may be smaller, but that is only
1216 	 * checked against after possibly caching a valid reply.
1217 	 */
1218 	if (len > req->rq_rcv_buf.page_len)
1219 		return -ERANGE;
1220 
1221 	res->xattr_len = len;
1222 
1223 	if (len > 0) {
1224 		rdlen = xdr_read_pages(xdr, len);
1225 		if (rdlen < len)
1226 			return -EIO;
1227 	}
1228 
1229 	return 0;
1230 }
1231 
decode_removexattr(struct xdr_stream * xdr,struct nfs4_change_info * cinfo)1232 static int decode_removexattr(struct xdr_stream *xdr,
1233 			   struct nfs4_change_info *cinfo)
1234 {
1235 	int status;
1236 
1237 	status = decode_op_hdr(xdr, OP_REMOVEXATTR);
1238 	if (status)
1239 		goto out;
1240 
1241 	status = decode_change_info(xdr, cinfo);
1242 out:
1243 	return status;
1244 }
1245 
decode_listxattrs(struct xdr_stream * xdr,struct nfs42_listxattrsres * res)1246 static int decode_listxattrs(struct xdr_stream *xdr,
1247 			    struct nfs42_listxattrsres *res)
1248 {
1249 	int status;
1250 	__be32 *p;
1251 	u32 count, len, ulen;
1252 	size_t left, copied;
1253 	char *buf;
1254 
1255 	status = decode_op_hdr(xdr, OP_LISTXATTRS);
1256 	if (status) {
1257 		/*
1258 		 * Special case: for LISTXATTRS, NFS4ERR_TOOSMALL
1259 		 * should be translated to ERANGE.
1260 		 */
1261 		if (status == -ETOOSMALL)
1262 			status = -ERANGE;
1263 		/*
1264 		 * Special case: for LISTXATTRS, NFS4ERR_NOXATTR
1265 		 * should be translated to success with zero-length reply.
1266 		 */
1267 		if (status == -ENODATA) {
1268 			res->eof = true;
1269 			status = 0;
1270 		}
1271 		goto out;
1272 	}
1273 
1274 	p = xdr_inline_decode(xdr, 8);
1275 	if (unlikely(!p))
1276 		return -EIO;
1277 
1278 	xdr_decode_hyper(p, &res->cookie);
1279 
1280 	p = xdr_inline_decode(xdr, 4);
1281 	if (unlikely(!p))
1282 		return -EIO;
1283 
1284 	left = res->xattr_len;
1285 	buf = res->xattr_buf;
1286 
1287 	count = be32_to_cpup(p);
1288 	copied = 0;
1289 
1290 	/*
1291 	 * We have asked for enough room to encode the maximum number
1292 	 * of possible attribute names, so everything should fit.
1293 	 *
1294 	 * But, don't rely on that assumption. Just decode entries
1295 	 * until they don't fit anymore, just in case the server did
1296 	 * something odd.
1297 	 */
1298 	while (count--) {
1299 		p = xdr_inline_decode(xdr, 4);
1300 		if (unlikely(!p))
1301 			return -EIO;
1302 
1303 		len = be32_to_cpup(p);
1304 		if (len > (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN)) {
1305 			status = -ERANGE;
1306 			goto out;
1307 		}
1308 
1309 		p = xdr_inline_decode(xdr, len);
1310 		if (unlikely(!p))
1311 			return -EIO;
1312 
1313 		ulen = len + XATTR_USER_PREFIX_LEN + 1;
1314 		if (buf) {
1315 			if (ulen > left) {
1316 				status = -ERANGE;
1317 				goto out;
1318 			}
1319 
1320 			memcpy(buf, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
1321 			memcpy(buf + XATTR_USER_PREFIX_LEN, p, len);
1322 
1323 			buf[ulen - 1] = 0;
1324 			buf += ulen;
1325 			left -= ulen;
1326 		}
1327 		copied += ulen;
1328 	}
1329 
1330 	p = xdr_inline_decode(xdr, 4);
1331 	if (unlikely(!p))
1332 		return -EIO;
1333 
1334 	res->eof = be32_to_cpup(p);
1335 	res->copied = copied;
1336 
1337 out:
1338 	if (status == -ERANGE && res->xattr_len == XATTR_LIST_MAX)
1339 		status = -E2BIG;
1340 
1341 	return status;
1342 }
1343 
1344 /*
1345  * Decode ALLOCATE request
1346  */
nfs4_xdr_dec_allocate(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1347 static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp,
1348 				 struct xdr_stream *xdr,
1349 				 void *data)
1350 {
1351 	struct nfs42_falloc_res *res = data;
1352 	struct compound_hdr hdr;
1353 	int status;
1354 
1355 	status = decode_compound_hdr(xdr, &hdr);
1356 	if (status)
1357 		goto out;
1358 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1359 	if (status)
1360 		goto out;
1361 	status = decode_putfh(xdr);
1362 	if (status)
1363 		goto out;
1364 	status = decode_allocate(xdr, res);
1365 	if (status)
1366 		goto out;
1367 	decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
1368 out:
1369 	return status;
1370 }
1371 
1372 /*
1373  * Decode COPY response
1374  */
nfs4_xdr_dec_copy(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1375 static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp,
1376 			     struct xdr_stream *xdr,
1377 			     void *data)
1378 {
1379 	struct nfs42_copy_res *res = data;
1380 	struct compound_hdr hdr;
1381 	int status;
1382 
1383 	status = decode_compound_hdr(xdr, &hdr);
1384 	if (status)
1385 		goto out;
1386 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1387 	if (status)
1388 		goto out;
1389 	status = decode_putfh(xdr);
1390 	if (status)
1391 		goto out;
1392 	status = decode_savefh(xdr);
1393 	if (status)
1394 		goto out;
1395 	status = decode_putfh(xdr);
1396 	if (status)
1397 		goto out;
1398 	status = decode_copy(xdr, res);
1399 	if (status)
1400 		goto out;
1401 	if (res->commit_res.verf)
1402 		status = decode_commit(xdr, &res->commit_res);
1403 out:
1404 	return status;
1405 }
1406 
1407 /*
1408  * Decode OFFLOAD_CANCEL response
1409  */
nfs4_xdr_dec_offload_cancel(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1410 static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp,
1411 				       struct xdr_stream *xdr,
1412 				       void *data)
1413 {
1414 	struct nfs42_offload_status_res *res = data;
1415 	struct compound_hdr hdr;
1416 	int status;
1417 
1418 	status = decode_compound_hdr(xdr, &hdr);
1419 	if (status)
1420 		goto out;
1421 	status = decode_sequence(xdr, &res->osr_seq_res, rqstp);
1422 	if (status)
1423 		goto out;
1424 	status = decode_putfh(xdr);
1425 	if (status)
1426 		goto out;
1427 	status = decode_offload_cancel(xdr, res);
1428 
1429 out:
1430 	return status;
1431 }
1432 
1433 /*
1434  * Decode OFFLOAD_STATUS response
1435  */
nfs4_xdr_dec_offload_status(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1436 static int nfs4_xdr_dec_offload_status(struct rpc_rqst *rqstp,
1437 				       struct xdr_stream *xdr,
1438 				       void *data)
1439 {
1440 	struct nfs42_offload_status_res *res = data;
1441 	struct compound_hdr hdr;
1442 	int status;
1443 
1444 	status = decode_compound_hdr(xdr, &hdr);
1445 	if (status)
1446 		goto out;
1447 	status = decode_sequence(xdr, &res->osr_seq_res, rqstp);
1448 	if (status)
1449 		goto out;
1450 	status = decode_putfh(xdr);
1451 	if (status)
1452 		goto out;
1453 	status = decode_offload_status(xdr, res);
1454 
1455 out:
1456 	return status;
1457 }
1458 
1459 /*
1460  * Decode COPY_NOTIFY response
1461  */
nfs4_xdr_dec_copy_notify(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1462 static int nfs4_xdr_dec_copy_notify(struct rpc_rqst *rqstp,
1463 				    struct xdr_stream *xdr,
1464 				    void *data)
1465 {
1466 	struct nfs42_copy_notify_res *res = data;
1467 	struct compound_hdr hdr;
1468 	int status;
1469 
1470 	status = decode_compound_hdr(xdr, &hdr);
1471 	if (status)
1472 		goto out;
1473 	status = decode_sequence(xdr, &res->cnr_seq_res, rqstp);
1474 	if (status)
1475 		goto out;
1476 	status = decode_putfh(xdr);
1477 	if (status)
1478 		goto out;
1479 	status = decode_copy_notify(xdr, res);
1480 
1481 out:
1482 	return status;
1483 }
1484 
1485 /*
1486  * Decode DEALLOCATE request
1487  */
nfs4_xdr_dec_deallocate(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1488 static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
1489 				   struct xdr_stream *xdr,
1490 				   void *data)
1491 {
1492 	struct nfs42_falloc_res *res = data;
1493 	struct compound_hdr hdr;
1494 	int status;
1495 
1496 	status = decode_compound_hdr(xdr, &hdr);
1497 	if (status)
1498 		goto out;
1499 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1500 	if (status)
1501 		goto out;
1502 	status = decode_putfh(xdr);
1503 	if (status)
1504 		goto out;
1505 	status = decode_deallocate(xdr, res);
1506 	if (status)
1507 		goto out;
1508 	decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
1509 out:
1510 	return status;
1511 }
1512 
1513 /*
1514  * Decode READ_PLUS request
1515  */
nfs4_xdr_dec_read_plus(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1516 static int nfs4_xdr_dec_read_plus(struct rpc_rqst *rqstp,
1517 				  struct xdr_stream *xdr,
1518 				  void *data)
1519 {
1520 	struct nfs_pgio_res *res = data;
1521 	struct compound_hdr hdr;
1522 	int status;
1523 
1524 	xdr_set_scratch_buffer(xdr, res->scratch, READ_PLUS_SCRATCH_SIZE);
1525 
1526 	status = decode_compound_hdr(xdr, &hdr);
1527 	if (status)
1528 		goto out;
1529 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1530 	if (status)
1531 		goto out;
1532 	status = decode_putfh(xdr);
1533 	if (status)
1534 		goto out;
1535 	status = decode_read_plus(xdr, res);
1536 	if (!status)
1537 		status = res->count;
1538 out:
1539 	return status;
1540 }
1541 
1542 /*
1543  * Decode SEEK request
1544  */
nfs4_xdr_dec_seek(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1545 static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp,
1546 			     struct xdr_stream *xdr,
1547 			     void *data)
1548 {
1549 	struct nfs42_seek_res *res = data;
1550 	struct compound_hdr hdr;
1551 	int status;
1552 
1553 	status = decode_compound_hdr(xdr, &hdr);
1554 	if (status)
1555 		goto out;
1556 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1557 	if (status)
1558 		goto out;
1559 	status = decode_putfh(xdr);
1560 	if (status)
1561 		goto out;
1562 	status = decode_seek(xdr, res);
1563 out:
1564 	return status;
1565 }
1566 
1567 /*
1568  * Decode LAYOUTSTATS request
1569  */
nfs4_xdr_dec_layoutstats(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1570 static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp,
1571 				    struct xdr_stream *xdr,
1572 				    void *data)
1573 {
1574 	struct nfs42_layoutstat_res *res = data;
1575 	struct compound_hdr hdr;
1576 	int status, i;
1577 
1578 	status = decode_compound_hdr(xdr, &hdr);
1579 	if (status)
1580 		goto out;
1581 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1582 	if (status)
1583 		goto out;
1584 	status = decode_putfh(xdr);
1585 	if (status)
1586 		goto out;
1587 	WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
1588 	for (i = 0; i < res->num_dev; i++) {
1589 		status = decode_layoutstats(xdr);
1590 		if (status)
1591 			goto out;
1592 	}
1593 out:
1594 	res->rpc_status = status;
1595 	return status;
1596 }
1597 
1598 /*
1599  * Decode CLONE request
1600  */
nfs4_xdr_dec_clone(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1601 static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp,
1602 			      struct xdr_stream *xdr,
1603 			      void *data)
1604 {
1605 	struct nfs42_clone_res *res = data;
1606 	struct compound_hdr hdr;
1607 	int status;
1608 
1609 	status = decode_compound_hdr(xdr, &hdr);
1610 	if (status)
1611 		goto out;
1612 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1613 	if (status)
1614 		goto out;
1615 	status = decode_putfh(xdr);
1616 	if (status)
1617 		goto out;
1618 	status = decode_savefh(xdr);
1619 	if (status)
1620 		goto out;
1621 	status = decode_putfh(xdr);
1622 	if (status)
1623 		goto out;
1624 	status = decode_clone(xdr);
1625 	if (status)
1626 		goto out;
1627 	decode_getfattr(xdr, res->dst_fattr, res->server);
1628 out:
1629 	res->rpc_status = status;
1630 	return status;
1631 }
1632 
1633 /*
1634  * Decode LAYOUTERROR request
1635  */
nfs4_xdr_dec_layouterror(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1636 static int nfs4_xdr_dec_layouterror(struct rpc_rqst *rqstp,
1637 				    struct xdr_stream *xdr,
1638 				    void *data)
1639 {
1640 	struct nfs42_layouterror_res *res = data;
1641 	struct compound_hdr hdr;
1642 	int status, i;
1643 
1644 	status = decode_compound_hdr(xdr, &hdr);
1645 	if (status)
1646 		goto out;
1647 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1648 	if (status)
1649 		goto out;
1650 	status = decode_putfh(xdr);
1651 
1652 	for (i = 0; i < res->num_errors && status == 0; i++)
1653 		status = decode_layouterror(xdr);
1654 out:
1655 	res->rpc_status = status;
1656 	return status;
1657 }
1658 
1659 /*
1660  * Decode SETXATTR request
1661  */
nfs4_xdr_dec_setxattr(struct rpc_rqst * req,struct xdr_stream * xdr,void * data)1662 static int nfs4_xdr_dec_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
1663 				 void *data)
1664 {
1665 	struct nfs42_setxattrres *res = data;
1666 	struct compound_hdr hdr;
1667 	int status;
1668 
1669 	status = decode_compound_hdr(xdr, &hdr);
1670 	if (status)
1671 		goto out;
1672 	status = decode_sequence(xdr, &res->seq_res, req);
1673 	if (status)
1674 		goto out;
1675 	status = decode_putfh(xdr);
1676 	if (status)
1677 		goto out;
1678 	status = decode_setxattr(xdr, &res->cinfo);
1679 	if (status)
1680 		goto out;
1681 	status = decode_getfattr(xdr, res->fattr, res->server);
1682 out:
1683 	return status;
1684 }
1685 
1686 /*
1687  * Decode GETXATTR request
1688  */
nfs4_xdr_dec_getxattr(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1689 static int nfs4_xdr_dec_getxattr(struct rpc_rqst *rqstp,
1690 				 struct xdr_stream *xdr, void *data)
1691 {
1692 	struct nfs42_getxattrres *res = data;
1693 	struct compound_hdr hdr;
1694 	int status;
1695 
1696 	status = decode_compound_hdr(xdr, &hdr);
1697 	if (status)
1698 		goto out;
1699 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1700 	if (status)
1701 		goto out;
1702 	status = decode_putfh(xdr);
1703 	if (status)
1704 		goto out;
1705 	status = decode_getxattr(xdr, res, rqstp);
1706 out:
1707 	return status;
1708 }
1709 
1710 /*
1711  * Decode LISTXATTR request
1712  */
nfs4_xdr_dec_listxattrs(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1713 static int nfs4_xdr_dec_listxattrs(struct rpc_rqst *rqstp,
1714 				   struct xdr_stream *xdr, void *data)
1715 {
1716 	struct nfs42_listxattrsres *res = data;
1717 	struct compound_hdr hdr;
1718 	int status;
1719 
1720 	xdr_set_scratch_page(xdr, res->scratch);
1721 
1722 	status = decode_compound_hdr(xdr, &hdr);
1723 	if (status)
1724 		goto out;
1725 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1726 	if (status)
1727 		goto out;
1728 	status = decode_putfh(xdr);
1729 	if (status)
1730 		goto out;
1731 	status = decode_listxattrs(xdr, res);
1732 out:
1733 	return status;
1734 }
1735 
1736 /*
1737  * Decode REMOVEXATTR request
1738  */
nfs4_xdr_dec_removexattr(struct rpc_rqst * req,struct xdr_stream * xdr,void * data)1739 static int nfs4_xdr_dec_removexattr(struct rpc_rqst *req,
1740 				    struct xdr_stream *xdr, void *data)
1741 {
1742 	struct nfs42_removexattrres *res = data;
1743 	struct compound_hdr hdr;
1744 	int status;
1745 
1746 	status = decode_compound_hdr(xdr, &hdr);
1747 	if (status)
1748 		goto out;
1749 	status = decode_sequence(xdr, &res->seq_res, req);
1750 	if (status)
1751 		goto out;
1752 	status = decode_putfh(xdr);
1753 	if (status)
1754 		goto out;
1755 
1756 	status = decode_removexattr(xdr, &res->cinfo);
1757 out:
1758 	return status;
1759 }
1760 #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */
1761