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