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