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