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