Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
1c6dcbe5 AS |
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 | ||
be3a5d23 TM |
8 | #include "nfs42.h" |
9 | ||
f4ac1674 AS |
10 | #define encode_fallocate_maxsz (encode_stateid_maxsz + \ |
11 | 2 /* offset */ + \ | |
12 | 2 /* length */) | |
2e72448b AS |
13 | #define NFS42_WRITE_RES_SIZE (1 /* wr_callback_id size */ +\ |
14 | XDR_QUADLEN(NFS4_STATEID_SIZE) + \ | |
15 | 2 /* wr_count */ + \ | |
16 | 1 /* wr_committed */ + \ | |
17 | XDR_QUADLEN(NFS4_VERIFIER_SIZE)) | |
f4ac1674 AS |
18 | #define encode_allocate_maxsz (op_encode_hdr_maxsz + \ |
19 | encode_fallocate_maxsz) | |
20 | #define decode_allocate_maxsz (op_decode_hdr_maxsz) | |
2e72448b AS |
21 | #define encode_copy_maxsz (op_encode_hdr_maxsz + \ |
22 | XDR_QUADLEN(NFS4_STATEID_SIZE) + \ | |
23 | XDR_QUADLEN(NFS4_STATEID_SIZE) + \ | |
24 | 2 + 2 + 2 + 1 + 1 + 1) | |
25 | #define decode_copy_maxsz (op_decode_hdr_maxsz + \ | |
26 | NFS42_WRITE_RES_SIZE + \ | |
27 | 1 /* cr_consecutive */ + \ | |
28 | 1 /* cr_synchronous */) | |
cb95deea OK |
29 | #define encode_offload_cancel_maxsz (op_encode_hdr_maxsz + \ |
30 | XDR_QUADLEN(NFS4_STATEID_SIZE)) | |
31 | #define decode_offload_cancel_maxsz (op_decode_hdr_maxsz) | |
624bd5b7 AS |
32 | #define encode_deallocate_maxsz (op_encode_hdr_maxsz + \ |
33 | encode_fallocate_maxsz) | |
34 | #define decode_deallocate_maxsz (op_decode_hdr_maxsz) | |
1c6dcbe5 AS |
35 | #define encode_seek_maxsz (op_encode_hdr_maxsz + \ |
36 | encode_stateid_maxsz + \ | |
37 | 2 /* offset */ + \ | |
38 | 1 /* whence */) | |
39 | #define decode_seek_maxsz (op_decode_hdr_maxsz + \ | |
40 | 1 /* eof */ + \ | |
41 | 1 /* whence */ + \ | |
42 | 2 /* offset */ + \ | |
43 | 2 /* length */) | |
be3a5d23 TM |
44 | #define encode_io_info_maxsz 4 |
45 | #define encode_layoutstats_maxsz (op_decode_hdr_maxsz + \ | |
46 | 2 /* offset */ + \ | |
47 | 2 /* length */ + \ | |
48 | encode_stateid_maxsz + \ | |
49 | encode_io_info_maxsz + \ | |
50 | encode_io_info_maxsz + \ | |
51 | 1 /* opaque devaddr4 length */ + \ | |
52 | XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE)) | |
53 | #define decode_layoutstats_maxsz (op_decode_hdr_maxsz) | |
36022770 PT |
54 | #define encode_clone_maxsz (encode_stateid_maxsz + \ |
55 | encode_stateid_maxsz + \ | |
56 | 2 /* src offset */ + \ | |
57 | 2 /* dst offset */ + \ | |
58 | 2 /* count */) | |
59 | #define decode_clone_maxsz (op_decode_hdr_maxsz) | |
1c6dcbe5 | 60 | |
f4ac1674 AS |
61 | #define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \ |
62 | encode_putfh_maxsz + \ | |
9a51940b AS |
63 | encode_allocate_maxsz + \ |
64 | encode_getattr_maxsz) | |
f4ac1674 AS |
65 | #define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \ |
66 | decode_putfh_maxsz + \ | |
9a51940b AS |
67 | decode_allocate_maxsz + \ |
68 | decode_getattr_maxsz) | |
2e72448b AS |
69 | #define NFS4_enc_copy_sz (compound_encode_hdr_maxsz + \ |
70 | encode_putfh_maxsz + \ | |
71 | encode_savefh_maxsz + \ | |
72 | encode_putfh_maxsz + \ | |
e0926934 OK |
73 | encode_copy_maxsz + \ |
74 | encode_commit_maxsz) | |
2e72448b AS |
75 | #define NFS4_dec_copy_sz (compound_decode_hdr_maxsz + \ |
76 | decode_putfh_maxsz + \ | |
77 | decode_savefh_maxsz + \ | |
78 | decode_putfh_maxsz + \ | |
e0926934 OK |
79 | decode_copy_maxsz + \ |
80 | decode_commit_maxsz) | |
cb95deea OK |
81 | #define NFS4_enc_offload_cancel_sz (compound_encode_hdr_maxsz + \ |
82 | encode_putfh_maxsz + \ | |
83 | encode_offload_cancel_maxsz) | |
84 | #define NFS4_dec_offload_cancel_sz (compound_decode_hdr_maxsz + \ | |
85 | decode_putfh_maxsz + \ | |
86 | decode_offload_cancel_maxsz) | |
624bd5b7 AS |
87 | #define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \ |
88 | encode_putfh_maxsz + \ | |
9a51940b AS |
89 | encode_deallocate_maxsz + \ |
90 | encode_getattr_maxsz) | |
624bd5b7 AS |
91 | #define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \ |
92 | decode_putfh_maxsz + \ | |
9a51940b AS |
93 | decode_deallocate_maxsz + \ |
94 | decode_getattr_maxsz) | |
1c6dcbe5 AS |
95 | #define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \ |
96 | encode_putfh_maxsz + \ | |
97 | encode_seek_maxsz) | |
98 | #define NFS4_dec_seek_sz (compound_decode_hdr_maxsz + \ | |
99 | decode_putfh_maxsz + \ | |
100 | decode_seek_maxsz) | |
be3a5d23 TM |
101 | #define NFS4_enc_layoutstats_sz (compound_encode_hdr_maxsz + \ |
102 | encode_sequence_maxsz + \ | |
103 | encode_putfh_maxsz + \ | |
104 | PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz) | |
105 | #define NFS4_dec_layoutstats_sz (compound_decode_hdr_maxsz + \ | |
106 | decode_sequence_maxsz + \ | |
107 | decode_putfh_maxsz + \ | |
108 | PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz) | |
36022770 PT |
109 | #define NFS4_enc_clone_sz (compound_encode_hdr_maxsz + \ |
110 | encode_sequence_maxsz + \ | |
111 | encode_putfh_maxsz + \ | |
112 | encode_savefh_maxsz + \ | |
113 | encode_putfh_maxsz + \ | |
114 | encode_clone_maxsz + \ | |
115 | encode_getattr_maxsz) | |
116 | #define NFS4_dec_clone_sz (compound_decode_hdr_maxsz + \ | |
117 | decode_sequence_maxsz + \ | |
118 | decode_putfh_maxsz + \ | |
119 | decode_savefh_maxsz + \ | |
120 | decode_putfh_maxsz + \ | |
121 | decode_clone_maxsz + \ | |
122 | decode_getattr_maxsz) | |
1c6dcbe5 | 123 | |
f4ac1674 | 124 | static void encode_fallocate(struct xdr_stream *xdr, |
0096d39b | 125 | const struct nfs42_falloc_args *args) |
f4ac1674 AS |
126 | { |
127 | encode_nfs4_stateid(xdr, &args->falloc_stateid); | |
128 | encode_uint64(xdr, args->falloc_offset); | |
129 | encode_uint64(xdr, args->falloc_length); | |
130 | } | |
131 | ||
132 | static void encode_allocate(struct xdr_stream *xdr, | |
0096d39b | 133 | const struct nfs42_falloc_args *args, |
f4ac1674 AS |
134 | struct compound_hdr *hdr) |
135 | { | |
136 | encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr); | |
137 | encode_fallocate(xdr, args); | |
138 | } | |
139 | ||
2e72448b | 140 | static void encode_copy(struct xdr_stream *xdr, |
0096d39b | 141 | const struct nfs42_copy_args *args, |
2e72448b AS |
142 | struct compound_hdr *hdr) |
143 | { | |
144 | encode_op_hdr(xdr, OP_COPY, decode_copy_maxsz, hdr); | |
145 | encode_nfs4_stateid(xdr, &args->src_stateid); | |
146 | encode_nfs4_stateid(xdr, &args->dst_stateid); | |
147 | ||
148 | encode_uint64(xdr, args->src_pos); | |
149 | encode_uint64(xdr, args->dst_pos); | |
150 | encode_uint64(xdr, args->count); | |
151 | ||
152 | encode_uint32(xdr, 1); /* consecutive = true */ | |
62164f31 | 153 | encode_uint32(xdr, args->sync); |
2e72448b AS |
154 | encode_uint32(xdr, 0); /* src server list */ |
155 | } | |
156 | ||
cb95deea OK |
157 | static void encode_offload_cancel(struct xdr_stream *xdr, |
158 | const struct nfs42_offload_status_args *args, | |
159 | struct compound_hdr *hdr) | |
160 | { | |
161 | encode_op_hdr(xdr, OP_OFFLOAD_CANCEL, decode_offload_cancel_maxsz, hdr); | |
162 | encode_nfs4_stateid(xdr, &args->osa_stateid); | |
163 | } | |
164 | ||
624bd5b7 | 165 | static void encode_deallocate(struct xdr_stream *xdr, |
0096d39b | 166 | const struct nfs42_falloc_args *args, |
624bd5b7 AS |
167 | struct compound_hdr *hdr) |
168 | { | |
169 | encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr); | |
170 | encode_fallocate(xdr, args); | |
171 | } | |
172 | ||
1c6dcbe5 | 173 | static void encode_seek(struct xdr_stream *xdr, |
0096d39b | 174 | const struct nfs42_seek_args *args, |
1c6dcbe5 AS |
175 | struct compound_hdr *hdr) |
176 | { | |
177 | encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr); | |
178 | encode_nfs4_stateid(xdr, &args->sa_stateid); | |
179 | encode_uint64(xdr, args->sa_offset); | |
180 | encode_uint32(xdr, args->sa_what); | |
181 | } | |
182 | ||
be3a5d23 | 183 | static void encode_layoutstats(struct xdr_stream *xdr, |
0096d39b | 184 | const struct nfs42_layoutstat_args *args, |
be3a5d23 TM |
185 | struct nfs42_layoutstat_devinfo *devinfo, |
186 | struct compound_hdr *hdr) | |
187 | { | |
188 | __be32 *p; | |
189 | ||
190 | encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr); | |
191 | p = reserve_space(xdr, 8 + 8); | |
192 | p = xdr_encode_hyper(p, devinfo->offset); | |
193 | p = xdr_encode_hyper(p, devinfo->length); | |
194 | encode_nfs4_stateid(xdr, &args->stateid); | |
195 | p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4); | |
196 | p = xdr_encode_hyper(p, devinfo->read_count); | |
197 | p = xdr_encode_hyper(p, devinfo->read_bytes); | |
198 | p = xdr_encode_hyper(p, devinfo->write_count); | |
199 | p = xdr_encode_hyper(p, devinfo->write_bytes); | |
200 | p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data, | |
201 | NFS4_DEVICEID4_SIZE); | |
202 | /* Encode layoutupdate4 */ | |
203 | *p++ = cpu_to_be32(devinfo->layout_type); | |
422c93c8 TM |
204 | if (devinfo->ld_private.ops) |
205 | devinfo->ld_private.ops->encode(xdr, args, | |
206 | &devinfo->ld_private); | |
be3a5d23 TM |
207 | else |
208 | encode_uint32(xdr, 0); | |
209 | } | |
210 | ||
36022770 | 211 | static void encode_clone(struct xdr_stream *xdr, |
0096d39b | 212 | const struct nfs42_clone_args *args, |
36022770 PT |
213 | struct compound_hdr *hdr) |
214 | { | |
215 | __be32 *p; | |
216 | ||
217 | encode_op_hdr(xdr, OP_CLONE, decode_clone_maxsz, hdr); | |
218 | encode_nfs4_stateid(xdr, &args->src_stateid); | |
219 | encode_nfs4_stateid(xdr, &args->dst_stateid); | |
220 | p = reserve_space(xdr, 3*8); | |
221 | p = xdr_encode_hyper(p, args->src_offset); | |
222 | p = xdr_encode_hyper(p, args->dst_offset); | |
223 | xdr_encode_hyper(p, args->count); | |
224 | } | |
225 | ||
f4ac1674 AS |
226 | /* |
227 | * Encode ALLOCATE request | |
228 | */ | |
229 | static void nfs4_xdr_enc_allocate(struct rpc_rqst *req, | |
230 | struct xdr_stream *xdr, | |
0096d39b | 231 | const void *data) |
f4ac1674 | 232 | { |
0096d39b | 233 | const struct nfs42_falloc_args *args = data; |
f4ac1674 AS |
234 | struct compound_hdr hdr = { |
235 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | |
236 | }; | |
237 | ||
238 | encode_compound_hdr(xdr, req, &hdr); | |
239 | encode_sequence(xdr, &args->seq_args, &hdr); | |
240 | encode_putfh(xdr, args->falloc_fh, &hdr); | |
241 | encode_allocate(xdr, args, &hdr); | |
9a51940b | 242 | encode_getfattr(xdr, args->falloc_bitmask, &hdr); |
f4ac1674 AS |
243 | encode_nops(&hdr); |
244 | } | |
245 | ||
e0926934 | 246 | static void encode_copy_commit(struct xdr_stream *xdr, |
0096d39b | 247 | const struct nfs42_copy_args *args, |
e0926934 OK |
248 | struct compound_hdr *hdr) |
249 | { | |
250 | __be32 *p; | |
251 | ||
252 | encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr); | |
253 | p = reserve_space(xdr, 12); | |
254 | p = xdr_encode_hyper(p, args->dst_pos); | |
255 | *p = cpu_to_be32(args->count); | |
256 | } | |
257 | ||
2e72448b AS |
258 | /* |
259 | * Encode COPY request | |
260 | */ | |
261 | static void nfs4_xdr_enc_copy(struct rpc_rqst *req, | |
262 | struct xdr_stream *xdr, | |
0096d39b | 263 | const void *data) |
2e72448b | 264 | { |
0096d39b | 265 | const struct nfs42_copy_args *args = data; |
2e72448b AS |
266 | struct compound_hdr hdr = { |
267 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | |
268 | }; | |
269 | ||
270 | encode_compound_hdr(xdr, req, &hdr); | |
271 | encode_sequence(xdr, &args->seq_args, &hdr); | |
272 | encode_putfh(xdr, args->src_fh, &hdr); | |
273 | encode_savefh(xdr, &hdr); | |
274 | encode_putfh(xdr, args->dst_fh, &hdr); | |
275 | encode_copy(xdr, args, &hdr); | |
62164f31 OK |
276 | if (args->sync) |
277 | encode_copy_commit(xdr, args, &hdr); | |
2e72448b AS |
278 | encode_nops(&hdr); |
279 | } | |
280 | ||
cb95deea OK |
281 | /* |
282 | * Encode OFFLOAD_CANEL request | |
283 | */ | |
284 | static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req, | |
285 | struct xdr_stream *xdr, | |
286 | const void *data) | |
287 | { | |
288 | const struct nfs42_offload_status_args *args = data; | |
289 | struct compound_hdr hdr = { | |
290 | .minorversion = nfs4_xdr_minorversion(&args->osa_seq_args), | |
291 | }; | |
292 | ||
293 | encode_compound_hdr(xdr, req, &hdr); | |
294 | encode_sequence(xdr, &args->osa_seq_args, &hdr); | |
295 | encode_putfh(xdr, args->osa_src_fh, &hdr); | |
296 | encode_offload_cancel(xdr, args, &hdr); | |
297 | encode_nops(&hdr); | |
298 | } | |
299 | ||
624bd5b7 AS |
300 | /* |
301 | * Encode DEALLOCATE request | |
302 | */ | |
303 | static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req, | |
304 | struct xdr_stream *xdr, | |
0096d39b | 305 | const void *data) |
624bd5b7 | 306 | { |
0096d39b | 307 | const struct nfs42_falloc_args *args = data; |
624bd5b7 AS |
308 | struct compound_hdr hdr = { |
309 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | |
310 | }; | |
311 | ||
312 | encode_compound_hdr(xdr, req, &hdr); | |
313 | encode_sequence(xdr, &args->seq_args, &hdr); | |
314 | encode_putfh(xdr, args->falloc_fh, &hdr); | |
315 | encode_deallocate(xdr, args, &hdr); | |
9a51940b | 316 | encode_getfattr(xdr, args->falloc_bitmask, &hdr); |
624bd5b7 AS |
317 | encode_nops(&hdr); |
318 | } | |
319 | ||
1c6dcbe5 AS |
320 | /* |
321 | * Encode SEEK request | |
322 | */ | |
323 | static void nfs4_xdr_enc_seek(struct rpc_rqst *req, | |
324 | struct xdr_stream *xdr, | |
0096d39b | 325 | const void *data) |
1c6dcbe5 | 326 | { |
0096d39b | 327 | const struct nfs42_seek_args *args = data; |
1c6dcbe5 AS |
328 | struct compound_hdr hdr = { |
329 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | |
330 | }; | |
331 | ||
332 | encode_compound_hdr(xdr, req, &hdr); | |
333 | encode_sequence(xdr, &args->seq_args, &hdr); | |
334 | encode_putfh(xdr, args->sa_fh, &hdr); | |
335 | encode_seek(xdr, args, &hdr); | |
336 | encode_nops(&hdr); | |
337 | } | |
338 | ||
be3a5d23 TM |
339 | /* |
340 | * Encode LAYOUTSTATS request | |
341 | */ | |
342 | static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req, | |
343 | struct xdr_stream *xdr, | |
0096d39b | 344 | const void *data) |
be3a5d23 | 345 | { |
0096d39b | 346 | const struct nfs42_layoutstat_args *args = data; |
be3a5d23 TM |
347 | int i; |
348 | ||
349 | struct compound_hdr hdr = { | |
350 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | |
351 | }; | |
352 | ||
353 | encode_compound_hdr(xdr, req, &hdr); | |
354 | encode_sequence(xdr, &args->seq_args, &hdr); | |
355 | encode_putfh(xdr, args->fh, &hdr); | |
356 | WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV); | |
357 | for (i = 0; i < args->num_dev; i++) | |
358 | encode_layoutstats(xdr, args, &args->devinfo[i], &hdr); | |
359 | encode_nops(&hdr); | |
360 | } | |
361 | ||
36022770 PT |
362 | /* |
363 | * Encode CLONE request | |
364 | */ | |
365 | static void nfs4_xdr_enc_clone(struct rpc_rqst *req, | |
366 | struct xdr_stream *xdr, | |
0096d39b | 367 | const void *data) |
36022770 | 368 | { |
0096d39b | 369 | const struct nfs42_clone_args *args = data; |
36022770 PT |
370 | struct compound_hdr hdr = { |
371 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | |
372 | }; | |
373 | ||
374 | encode_compound_hdr(xdr, req, &hdr); | |
375 | encode_sequence(xdr, &args->seq_args, &hdr); | |
376 | encode_putfh(xdr, args->src_fh, &hdr); | |
377 | encode_savefh(xdr, &hdr); | |
378 | encode_putfh(xdr, args->dst_fh, &hdr); | |
379 | encode_clone(xdr, args, &hdr); | |
380 | encode_getfattr(xdr, args->dst_bitmask, &hdr); | |
381 | encode_nops(&hdr); | |
382 | } | |
383 | ||
f4ac1674 AS |
384 | static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) |
385 | { | |
386 | return decode_op_hdr(xdr, OP_ALLOCATE); | |
387 | } | |
388 | ||
2e72448b AS |
389 | static int decode_write_response(struct xdr_stream *xdr, |
390 | struct nfs42_write_res *res) | |
391 | { | |
392 | __be32 *p; | |
67aa7444 | 393 | int status, count; |
2e72448b | 394 | |
67aa7444 | 395 | p = xdr_inline_decode(xdr, 4); |
2e72448b AS |
396 | if (unlikely(!p)) |
397 | goto out_overflow; | |
67aa7444 OK |
398 | count = be32_to_cpup(p); |
399 | if (count > 1) | |
6fdf339b | 400 | return -EREMOTEIO; |
67aa7444 OK |
401 | else if (count == 1) { |
402 | status = decode_opaque_fixed(xdr, &res->stateid, | |
403 | NFS4_STATEID_SIZE); | |
404 | if (unlikely(status)) | |
405 | goto out_overflow; | |
6fdf339b | 406 | } |
67aa7444 OK |
407 | p = xdr_inline_decode(xdr, 8 + 4); |
408 | if (unlikely(!p)) | |
409 | goto out_overflow; | |
2e72448b AS |
410 | p = xdr_decode_hyper(p, &res->count); |
411 | res->verifier.committed = be32_to_cpup(p); | |
412 | return decode_verifier(xdr, &res->verifier.verifier); | |
413 | ||
414 | out_overflow: | |
415 | print_overflow_msg(__func__, xdr); | |
416 | return -EIO; | |
417 | } | |
418 | ||
419 | static int decode_copy_requirements(struct xdr_stream *xdr, | |
420 | struct nfs42_copy_res *res) { | |
421 | __be32 *p; | |
422 | ||
423 | p = xdr_inline_decode(xdr, 4 + 4); | |
424 | if (unlikely(!p)) | |
425 | goto out_overflow; | |
426 | ||
427 | res->consecutive = be32_to_cpup(p++); | |
428 | res->synchronous = be32_to_cpup(p++); | |
429 | return 0; | |
430 | out_overflow: | |
431 | print_overflow_msg(__func__, xdr); | |
432 | return -EIO; | |
433 | } | |
434 | ||
435 | static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res) | |
436 | { | |
437 | int status; | |
438 | ||
439 | status = decode_op_hdr(xdr, OP_COPY); | |
440 | if (status == NFS4ERR_OFFLOAD_NO_REQS) { | |
441 | status = decode_copy_requirements(xdr, res); | |
442 | if (status) | |
443 | return status; | |
444 | return NFS4ERR_OFFLOAD_NO_REQS; | |
445 | } else if (status) | |
446 | return status; | |
447 | ||
448 | status = decode_write_response(xdr, &res->write_res); | |
449 | if (status) | |
450 | return status; | |
451 | ||
452 | return decode_copy_requirements(xdr, res); | |
453 | } | |
454 | ||
cb95deea OK |
455 | static int decode_offload_cancel(struct xdr_stream *xdr, |
456 | struct nfs42_offload_status_res *res) | |
457 | { | |
458 | return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL); | |
459 | } | |
460 | ||
624bd5b7 AS |
461 | static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) |
462 | { | |
463 | return decode_op_hdr(xdr, OP_DEALLOCATE); | |
464 | } | |
465 | ||
1c6dcbe5 AS |
466 | static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res) |
467 | { | |
468 | int status; | |
469 | __be32 *p; | |
470 | ||
471 | status = decode_op_hdr(xdr, OP_SEEK); | |
472 | if (status) | |
473 | return status; | |
474 | ||
475 | p = xdr_inline_decode(xdr, 4 + 8); | |
476 | if (unlikely(!p)) | |
477 | goto out_overflow; | |
478 | ||
479 | res->sr_eof = be32_to_cpup(p++); | |
480 | p = xdr_decode_hyper(p, &res->sr_offset); | |
481 | return 0; | |
482 | ||
483 | out_overflow: | |
484 | print_overflow_msg(__func__, xdr); | |
485 | return -EIO; | |
486 | } | |
487 | ||
19cf6335 | 488 | static int decode_layoutstats(struct xdr_stream *xdr) |
be3a5d23 | 489 | { |
da2e8127 | 490 | return decode_op_hdr(xdr, OP_LAYOUTSTATS); |
be3a5d23 TM |
491 | } |
492 | ||
36022770 PT |
493 | static int decode_clone(struct xdr_stream *xdr) |
494 | { | |
495 | return decode_op_hdr(xdr, OP_CLONE); | |
496 | } | |
497 | ||
f4ac1674 AS |
498 | /* |
499 | * Decode ALLOCATE request | |
500 | */ | |
501 | static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp, | |
502 | struct xdr_stream *xdr, | |
18d9cff4 | 503 | void *data) |
f4ac1674 | 504 | { |
18d9cff4 | 505 | struct nfs42_falloc_res *res = data; |
f4ac1674 AS |
506 | struct compound_hdr hdr; |
507 | int status; | |
508 | ||
509 | status = decode_compound_hdr(xdr, &hdr); | |
510 | if (status) | |
511 | goto out; | |
512 | status = decode_sequence(xdr, &res->seq_res, rqstp); | |
513 | if (status) | |
514 | goto out; | |
515 | status = decode_putfh(xdr); | |
516 | if (status) | |
517 | goto out; | |
518 | status = decode_allocate(xdr, res); | |
9a51940b AS |
519 | if (status) |
520 | goto out; | |
521 | decode_getfattr(xdr, res->falloc_fattr, res->falloc_server); | |
f4ac1674 AS |
522 | out: |
523 | return status; | |
524 | } | |
525 | ||
2e72448b AS |
526 | /* |
527 | * Decode COPY response | |
528 | */ | |
529 | static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp, | |
530 | struct xdr_stream *xdr, | |
18d9cff4 | 531 | void *data) |
2e72448b | 532 | { |
18d9cff4 | 533 | struct nfs42_copy_res *res = data; |
2e72448b AS |
534 | struct compound_hdr hdr; |
535 | int status; | |
536 | ||
537 | status = decode_compound_hdr(xdr, &hdr); | |
538 | if (status) | |
539 | goto out; | |
540 | status = decode_sequence(xdr, &res->seq_res, rqstp); | |
541 | if (status) | |
542 | goto out; | |
543 | status = decode_putfh(xdr); | |
544 | if (status) | |
545 | goto out; | |
546 | status = decode_savefh(xdr); | |
547 | if (status) | |
548 | goto out; | |
549 | status = decode_putfh(xdr); | |
550 | if (status) | |
551 | goto out; | |
552 | status = decode_copy(xdr, res); | |
e0926934 OK |
553 | if (status) |
554 | goto out; | |
62164f31 OK |
555 | if (res->commit_res.verf) |
556 | status = decode_commit(xdr, &res->commit_res); | |
2e72448b AS |
557 | out: |
558 | return status; | |
559 | } | |
560 | ||
cb95deea OK |
561 | /* |
562 | * Decode OFFLOAD_CANCEL response | |
563 | */ | |
564 | static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp, | |
565 | struct xdr_stream *xdr, | |
566 | void *data) | |
567 | { | |
568 | struct nfs42_offload_status_res *res = data; | |
569 | struct compound_hdr hdr; | |
570 | int status; | |
571 | ||
572 | status = decode_compound_hdr(xdr, &hdr); | |
573 | if (status) | |
574 | goto out; | |
575 | status = decode_sequence(xdr, &res->osr_seq_res, rqstp); | |
576 | if (status) | |
577 | goto out; | |
578 | status = decode_putfh(xdr); | |
579 | if (status) | |
580 | goto out; | |
581 | status = decode_offload_cancel(xdr, res); | |
582 | ||
583 | out: | |
584 | return status; | |
585 | } | |
586 | ||
624bd5b7 AS |
587 | /* |
588 | * Decode DEALLOCATE request | |
589 | */ | |
590 | static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp, | |
591 | struct xdr_stream *xdr, | |
18d9cff4 | 592 | void *data) |
624bd5b7 | 593 | { |
18d9cff4 | 594 | struct nfs42_falloc_res *res = data; |
624bd5b7 AS |
595 | struct compound_hdr hdr; |
596 | int status; | |
597 | ||
598 | status = decode_compound_hdr(xdr, &hdr); | |
599 | if (status) | |
600 | goto out; | |
601 | status = decode_sequence(xdr, &res->seq_res, rqstp); | |
602 | if (status) | |
603 | goto out; | |
604 | status = decode_putfh(xdr); | |
605 | if (status) | |
606 | goto out; | |
607 | status = decode_deallocate(xdr, res); | |
9a51940b AS |
608 | if (status) |
609 | goto out; | |
610 | decode_getfattr(xdr, res->falloc_fattr, res->falloc_server); | |
624bd5b7 AS |
611 | out: |
612 | return status; | |
613 | } | |
614 | ||
1c6dcbe5 AS |
615 | /* |
616 | * Decode SEEK request | |
617 | */ | |
618 | static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp, | |
619 | struct xdr_stream *xdr, | |
18d9cff4 | 620 | void *data) |
1c6dcbe5 | 621 | { |
18d9cff4 | 622 | struct nfs42_seek_res *res = data; |
1c6dcbe5 AS |
623 | struct compound_hdr hdr; |
624 | int status; | |
625 | ||
626 | status = decode_compound_hdr(xdr, &hdr); | |
627 | if (status) | |
628 | goto out; | |
629 | status = decode_sequence(xdr, &res->seq_res, rqstp); | |
630 | if (status) | |
631 | goto out; | |
632 | status = decode_putfh(xdr); | |
633 | if (status) | |
634 | goto out; | |
635 | status = decode_seek(xdr, res); | |
636 | out: | |
637 | return status; | |
638 | } | |
be3a5d23 TM |
639 | |
640 | /* | |
641 | * Decode LAYOUTSTATS request | |
642 | */ | |
643 | static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp, | |
644 | struct xdr_stream *xdr, | |
18d9cff4 | 645 | void *data) |
be3a5d23 | 646 | { |
18d9cff4 | 647 | struct nfs42_layoutstat_res *res = data; |
be3a5d23 TM |
648 | struct compound_hdr hdr; |
649 | int status, i; | |
650 | ||
651 | status = decode_compound_hdr(xdr, &hdr); | |
652 | if (status) | |
653 | goto out; | |
654 | status = decode_sequence(xdr, &res->seq_res, rqstp); | |
655 | if (status) | |
656 | goto out; | |
657 | status = decode_putfh(xdr); | |
658 | if (status) | |
659 | goto out; | |
660 | WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV); | |
661 | for (i = 0; i < res->num_dev; i++) { | |
19cf6335 | 662 | status = decode_layoutstats(xdr); |
be3a5d23 TM |
663 | if (status) |
664 | goto out; | |
665 | } | |
666 | out: | |
667 | res->rpc_status = status; | |
668 | return status; | |
669 | } | |
670 | ||
36022770 PT |
671 | /* |
672 | * Decode CLONE request | |
673 | */ | |
674 | static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp, | |
675 | struct xdr_stream *xdr, | |
18d9cff4 | 676 | void *data) |
36022770 | 677 | { |
18d9cff4 | 678 | struct nfs42_clone_res *res = data; |
36022770 PT |
679 | struct compound_hdr hdr; |
680 | int status; | |
681 | ||
682 | status = decode_compound_hdr(xdr, &hdr); | |
683 | if (status) | |
684 | goto out; | |
685 | status = decode_sequence(xdr, &res->seq_res, rqstp); | |
686 | if (status) | |
687 | goto out; | |
688 | status = decode_putfh(xdr); | |
689 | if (status) | |
690 | goto out; | |
691 | status = decode_savefh(xdr); | |
692 | if (status) | |
693 | goto out; | |
694 | status = decode_putfh(xdr); | |
695 | if (status) | |
696 | goto out; | |
697 | status = decode_clone(xdr); | |
698 | if (status) | |
699 | goto out; | |
700 | status = decode_getfattr(xdr, res->dst_fattr, res->server); | |
701 | ||
702 | out: | |
703 | res->rpc_status = status; | |
704 | return status; | |
705 | } | |
706 | ||
1c6dcbe5 | 707 | #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */ |