Commit | Line | Data |
---|---|---|
1c6dcbe5 AS |
1 | /* |
2 | * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com> | |
3 | */ | |
4 | #ifndef __LINUX_FS_NFS_NFS4_2XDR_H | |
5 | #define __LINUX_FS_NFS_NFS4_2XDR_H | |
6 | ||
be3a5d23 TM |
7 | #include "nfs42.h" |
8 | ||
f4ac1674 AS |
9 | #define encode_fallocate_maxsz (encode_stateid_maxsz + \ |
10 | 2 /* offset */ + \ | |
11 | 2 /* length */) | |
12 | #define encode_allocate_maxsz (op_encode_hdr_maxsz + \ | |
13 | encode_fallocate_maxsz) | |
14 | #define decode_allocate_maxsz (op_decode_hdr_maxsz) | |
624bd5b7 AS |
15 | #define encode_deallocate_maxsz (op_encode_hdr_maxsz + \ |
16 | encode_fallocate_maxsz) | |
17 | #define decode_deallocate_maxsz (op_decode_hdr_maxsz) | |
1c6dcbe5 AS |
18 | #define encode_seek_maxsz (op_encode_hdr_maxsz + \ |
19 | encode_stateid_maxsz + \ | |
20 | 2 /* offset */ + \ | |
21 | 1 /* whence */) | |
22 | #define decode_seek_maxsz (op_decode_hdr_maxsz + \ | |
23 | 1 /* eof */ + \ | |
24 | 1 /* whence */ + \ | |
25 | 2 /* offset */ + \ | |
26 | 2 /* length */) | |
be3a5d23 TM |
27 | #define encode_io_info_maxsz 4 |
28 | #define encode_layoutstats_maxsz (op_decode_hdr_maxsz + \ | |
29 | 2 /* offset */ + \ | |
30 | 2 /* length */ + \ | |
31 | encode_stateid_maxsz + \ | |
32 | encode_io_info_maxsz + \ | |
33 | encode_io_info_maxsz + \ | |
34 | 1 /* opaque devaddr4 length */ + \ | |
35 | XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE)) | |
36 | #define decode_layoutstats_maxsz (op_decode_hdr_maxsz) | |
36022770 PT |
37 | #define encode_clone_maxsz (encode_stateid_maxsz + \ |
38 | encode_stateid_maxsz + \ | |
39 | 2 /* src offset */ + \ | |
40 | 2 /* dst offset */ + \ | |
41 | 2 /* count */) | |
42 | #define decode_clone_maxsz (op_decode_hdr_maxsz) | |
1c6dcbe5 | 43 | |
f4ac1674 AS |
44 | #define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \ |
45 | encode_putfh_maxsz + \ | |
9a51940b AS |
46 | encode_allocate_maxsz + \ |
47 | encode_getattr_maxsz) | |
f4ac1674 AS |
48 | #define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \ |
49 | decode_putfh_maxsz + \ | |
9a51940b AS |
50 | decode_allocate_maxsz + \ |
51 | decode_getattr_maxsz) | |
624bd5b7 AS |
52 | #define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \ |
53 | encode_putfh_maxsz + \ | |
9a51940b AS |
54 | encode_deallocate_maxsz + \ |
55 | encode_getattr_maxsz) | |
624bd5b7 AS |
56 | #define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \ |
57 | decode_putfh_maxsz + \ | |
9a51940b AS |
58 | decode_deallocate_maxsz + \ |
59 | decode_getattr_maxsz) | |
1c6dcbe5 AS |
60 | #define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \ |
61 | encode_putfh_maxsz + \ | |
62 | encode_seek_maxsz) | |
63 | #define NFS4_dec_seek_sz (compound_decode_hdr_maxsz + \ | |
64 | decode_putfh_maxsz + \ | |
65 | decode_seek_maxsz) | |
be3a5d23 TM |
66 | #define NFS4_enc_layoutstats_sz (compound_encode_hdr_maxsz + \ |
67 | encode_sequence_maxsz + \ | |
68 | encode_putfh_maxsz + \ | |
69 | PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz) | |
70 | #define NFS4_dec_layoutstats_sz (compound_decode_hdr_maxsz + \ | |
71 | decode_sequence_maxsz + \ | |
72 | decode_putfh_maxsz + \ | |
73 | PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz) | |
36022770 PT |
74 | #define NFS4_enc_clone_sz (compound_encode_hdr_maxsz + \ |
75 | encode_sequence_maxsz + \ | |
76 | encode_putfh_maxsz + \ | |
77 | encode_savefh_maxsz + \ | |
78 | encode_putfh_maxsz + \ | |
79 | encode_clone_maxsz + \ | |
80 | encode_getattr_maxsz) | |
81 | #define NFS4_dec_clone_sz (compound_decode_hdr_maxsz + \ | |
82 | decode_sequence_maxsz + \ | |
83 | decode_putfh_maxsz + \ | |
84 | decode_savefh_maxsz + \ | |
85 | decode_putfh_maxsz + \ | |
86 | decode_clone_maxsz + \ | |
87 | decode_getattr_maxsz) | |
1c6dcbe5 | 88 | |
f4ac1674 AS |
89 | static void encode_fallocate(struct xdr_stream *xdr, |
90 | struct nfs42_falloc_args *args) | |
91 | { | |
92 | encode_nfs4_stateid(xdr, &args->falloc_stateid); | |
93 | encode_uint64(xdr, args->falloc_offset); | |
94 | encode_uint64(xdr, args->falloc_length); | |
95 | } | |
96 | ||
97 | static void encode_allocate(struct xdr_stream *xdr, | |
98 | struct nfs42_falloc_args *args, | |
99 | struct compound_hdr *hdr) | |
100 | { | |
101 | encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr); | |
102 | encode_fallocate(xdr, args); | |
103 | } | |
104 | ||
624bd5b7 AS |
105 | static void encode_deallocate(struct xdr_stream *xdr, |
106 | struct nfs42_falloc_args *args, | |
107 | struct compound_hdr *hdr) | |
108 | { | |
109 | encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr); | |
110 | encode_fallocate(xdr, args); | |
111 | } | |
112 | ||
1c6dcbe5 AS |
113 | static void encode_seek(struct xdr_stream *xdr, |
114 | struct nfs42_seek_args *args, | |
115 | struct compound_hdr *hdr) | |
116 | { | |
117 | encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr); | |
118 | encode_nfs4_stateid(xdr, &args->sa_stateid); | |
119 | encode_uint64(xdr, args->sa_offset); | |
120 | encode_uint32(xdr, args->sa_what); | |
121 | } | |
122 | ||
be3a5d23 TM |
123 | static void encode_layoutstats(struct xdr_stream *xdr, |
124 | struct nfs42_layoutstat_args *args, | |
125 | struct nfs42_layoutstat_devinfo *devinfo, | |
126 | struct compound_hdr *hdr) | |
127 | { | |
128 | __be32 *p; | |
129 | ||
130 | encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr); | |
131 | p = reserve_space(xdr, 8 + 8); | |
132 | p = xdr_encode_hyper(p, devinfo->offset); | |
133 | p = xdr_encode_hyper(p, devinfo->length); | |
134 | encode_nfs4_stateid(xdr, &args->stateid); | |
135 | p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4); | |
136 | p = xdr_encode_hyper(p, devinfo->read_count); | |
137 | p = xdr_encode_hyper(p, devinfo->read_bytes); | |
138 | p = xdr_encode_hyper(p, devinfo->write_count); | |
139 | p = xdr_encode_hyper(p, devinfo->write_bytes); | |
140 | p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data, | |
141 | NFS4_DEVICEID4_SIZE); | |
142 | /* Encode layoutupdate4 */ | |
143 | *p++ = cpu_to_be32(devinfo->layout_type); | |
144 | if (devinfo->layoutstats_encode != NULL) | |
145 | devinfo->layoutstats_encode(xdr, args, devinfo); | |
146 | else | |
147 | encode_uint32(xdr, 0); | |
148 | } | |
149 | ||
36022770 PT |
150 | static void encode_clone(struct xdr_stream *xdr, |
151 | struct nfs42_clone_args *args, | |
152 | struct compound_hdr *hdr) | |
153 | { | |
154 | __be32 *p; | |
155 | ||
156 | encode_op_hdr(xdr, OP_CLONE, decode_clone_maxsz, hdr); | |
157 | encode_nfs4_stateid(xdr, &args->src_stateid); | |
158 | encode_nfs4_stateid(xdr, &args->dst_stateid); | |
159 | p = reserve_space(xdr, 3*8); | |
160 | p = xdr_encode_hyper(p, args->src_offset); | |
161 | p = xdr_encode_hyper(p, args->dst_offset); | |
162 | xdr_encode_hyper(p, args->count); | |
163 | } | |
164 | ||
f4ac1674 AS |
165 | /* |
166 | * Encode ALLOCATE request | |
167 | */ | |
168 | static void nfs4_xdr_enc_allocate(struct rpc_rqst *req, | |
169 | struct xdr_stream *xdr, | |
170 | struct nfs42_falloc_args *args) | |
171 | { | |
172 | struct compound_hdr hdr = { | |
173 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | |
174 | }; | |
175 | ||
176 | encode_compound_hdr(xdr, req, &hdr); | |
177 | encode_sequence(xdr, &args->seq_args, &hdr); | |
178 | encode_putfh(xdr, args->falloc_fh, &hdr); | |
179 | encode_allocate(xdr, args, &hdr); | |
9a51940b | 180 | encode_getfattr(xdr, args->falloc_bitmask, &hdr); |
f4ac1674 AS |
181 | encode_nops(&hdr); |
182 | } | |
183 | ||
624bd5b7 AS |
184 | /* |
185 | * Encode DEALLOCATE request | |
186 | */ | |
187 | static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req, | |
188 | struct xdr_stream *xdr, | |
189 | struct nfs42_falloc_args *args) | |
190 | { | |
191 | struct compound_hdr hdr = { | |
192 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | |
193 | }; | |
194 | ||
195 | encode_compound_hdr(xdr, req, &hdr); | |
196 | encode_sequence(xdr, &args->seq_args, &hdr); | |
197 | encode_putfh(xdr, args->falloc_fh, &hdr); | |
198 | encode_deallocate(xdr, args, &hdr); | |
9a51940b | 199 | encode_getfattr(xdr, args->falloc_bitmask, &hdr); |
624bd5b7 AS |
200 | encode_nops(&hdr); |
201 | } | |
202 | ||
1c6dcbe5 AS |
203 | /* |
204 | * Encode SEEK request | |
205 | */ | |
206 | static void nfs4_xdr_enc_seek(struct rpc_rqst *req, | |
207 | struct xdr_stream *xdr, | |
208 | struct nfs42_seek_args *args) | |
209 | { | |
210 | struct compound_hdr hdr = { | |
211 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | |
212 | }; | |
213 | ||
214 | encode_compound_hdr(xdr, req, &hdr); | |
215 | encode_sequence(xdr, &args->seq_args, &hdr); | |
216 | encode_putfh(xdr, args->sa_fh, &hdr); | |
217 | encode_seek(xdr, args, &hdr); | |
218 | encode_nops(&hdr); | |
219 | } | |
220 | ||
be3a5d23 TM |
221 | /* |
222 | * Encode LAYOUTSTATS request | |
223 | */ | |
224 | static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req, | |
225 | struct xdr_stream *xdr, | |
226 | struct nfs42_layoutstat_args *args) | |
227 | { | |
228 | int i; | |
229 | ||
230 | struct compound_hdr hdr = { | |
231 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | |
232 | }; | |
233 | ||
234 | encode_compound_hdr(xdr, req, &hdr); | |
235 | encode_sequence(xdr, &args->seq_args, &hdr); | |
236 | encode_putfh(xdr, args->fh, &hdr); | |
237 | WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV); | |
238 | for (i = 0; i < args->num_dev; i++) | |
239 | encode_layoutstats(xdr, args, &args->devinfo[i], &hdr); | |
240 | encode_nops(&hdr); | |
241 | } | |
242 | ||
36022770 PT |
243 | /* |
244 | * Encode CLONE request | |
245 | */ | |
246 | static void nfs4_xdr_enc_clone(struct rpc_rqst *req, | |
247 | struct xdr_stream *xdr, | |
248 | struct nfs42_clone_args *args) | |
249 | { | |
250 | struct compound_hdr hdr = { | |
251 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | |
252 | }; | |
253 | ||
254 | encode_compound_hdr(xdr, req, &hdr); | |
255 | encode_sequence(xdr, &args->seq_args, &hdr); | |
256 | encode_putfh(xdr, args->src_fh, &hdr); | |
257 | encode_savefh(xdr, &hdr); | |
258 | encode_putfh(xdr, args->dst_fh, &hdr); | |
259 | encode_clone(xdr, args, &hdr); | |
260 | encode_getfattr(xdr, args->dst_bitmask, &hdr); | |
261 | encode_nops(&hdr); | |
262 | } | |
263 | ||
f4ac1674 AS |
264 | static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) |
265 | { | |
266 | return decode_op_hdr(xdr, OP_ALLOCATE); | |
267 | } | |
268 | ||
624bd5b7 AS |
269 | static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) |
270 | { | |
271 | return decode_op_hdr(xdr, OP_DEALLOCATE); | |
272 | } | |
273 | ||
1c6dcbe5 AS |
274 | static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res) |
275 | { | |
276 | int status; | |
277 | __be32 *p; | |
278 | ||
279 | status = decode_op_hdr(xdr, OP_SEEK); | |
280 | if (status) | |
281 | return status; | |
282 | ||
283 | p = xdr_inline_decode(xdr, 4 + 8); | |
284 | if (unlikely(!p)) | |
285 | goto out_overflow; | |
286 | ||
287 | res->sr_eof = be32_to_cpup(p++); | |
288 | p = xdr_decode_hyper(p, &res->sr_offset); | |
289 | return 0; | |
290 | ||
291 | out_overflow: | |
292 | print_overflow_msg(__func__, xdr); | |
293 | return -EIO; | |
294 | } | |
295 | ||
19cf6335 | 296 | static int decode_layoutstats(struct xdr_stream *xdr) |
be3a5d23 | 297 | { |
da2e8127 | 298 | return decode_op_hdr(xdr, OP_LAYOUTSTATS); |
be3a5d23 TM |
299 | } |
300 | ||
36022770 PT |
301 | static int decode_clone(struct xdr_stream *xdr) |
302 | { | |
303 | return decode_op_hdr(xdr, OP_CLONE); | |
304 | } | |
305 | ||
f4ac1674 AS |
306 | /* |
307 | * Decode ALLOCATE request | |
308 | */ | |
309 | static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp, | |
310 | struct xdr_stream *xdr, | |
311 | struct nfs42_falloc_res *res) | |
312 | { | |
313 | struct compound_hdr hdr; | |
314 | int status; | |
315 | ||
316 | status = decode_compound_hdr(xdr, &hdr); | |
317 | if (status) | |
318 | goto out; | |
319 | status = decode_sequence(xdr, &res->seq_res, rqstp); | |
320 | if (status) | |
321 | goto out; | |
322 | status = decode_putfh(xdr); | |
323 | if (status) | |
324 | goto out; | |
325 | status = decode_allocate(xdr, res); | |
9a51940b AS |
326 | if (status) |
327 | goto out; | |
328 | decode_getfattr(xdr, res->falloc_fattr, res->falloc_server); | |
f4ac1674 AS |
329 | out: |
330 | return status; | |
331 | } | |
332 | ||
624bd5b7 AS |
333 | /* |
334 | * Decode DEALLOCATE request | |
335 | */ | |
336 | static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp, | |
337 | struct xdr_stream *xdr, | |
338 | struct nfs42_falloc_res *res) | |
339 | { | |
340 | struct compound_hdr hdr; | |
341 | int status; | |
342 | ||
343 | status = decode_compound_hdr(xdr, &hdr); | |
344 | if (status) | |
345 | goto out; | |
346 | status = decode_sequence(xdr, &res->seq_res, rqstp); | |
347 | if (status) | |
348 | goto out; | |
349 | status = decode_putfh(xdr); | |
350 | if (status) | |
351 | goto out; | |
352 | status = decode_deallocate(xdr, res); | |
9a51940b AS |
353 | if (status) |
354 | goto out; | |
355 | decode_getfattr(xdr, res->falloc_fattr, res->falloc_server); | |
624bd5b7 AS |
356 | out: |
357 | return status; | |
358 | } | |
359 | ||
1c6dcbe5 AS |
360 | /* |
361 | * Decode SEEK request | |
362 | */ | |
363 | static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp, | |
364 | struct xdr_stream *xdr, | |
365 | struct nfs42_seek_res *res) | |
366 | { | |
367 | struct compound_hdr hdr; | |
368 | int status; | |
369 | ||
370 | status = decode_compound_hdr(xdr, &hdr); | |
371 | if (status) | |
372 | goto out; | |
373 | status = decode_sequence(xdr, &res->seq_res, rqstp); | |
374 | if (status) | |
375 | goto out; | |
376 | status = decode_putfh(xdr); | |
377 | if (status) | |
378 | goto out; | |
379 | status = decode_seek(xdr, res); | |
380 | out: | |
381 | return status; | |
382 | } | |
be3a5d23 TM |
383 | |
384 | /* | |
385 | * Decode LAYOUTSTATS request | |
386 | */ | |
387 | static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp, | |
388 | struct xdr_stream *xdr, | |
389 | struct nfs42_layoutstat_res *res) | |
390 | { | |
391 | struct compound_hdr hdr; | |
392 | int status, i; | |
393 | ||
394 | status = decode_compound_hdr(xdr, &hdr); | |
395 | if (status) | |
396 | goto out; | |
397 | status = decode_sequence(xdr, &res->seq_res, rqstp); | |
398 | if (status) | |
399 | goto out; | |
400 | status = decode_putfh(xdr); | |
401 | if (status) | |
402 | goto out; | |
403 | WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV); | |
404 | for (i = 0; i < res->num_dev; i++) { | |
19cf6335 | 405 | status = decode_layoutstats(xdr); |
be3a5d23 TM |
406 | if (status) |
407 | goto out; | |
408 | } | |
409 | out: | |
410 | res->rpc_status = status; | |
411 | return status; | |
412 | } | |
413 | ||
36022770 PT |
414 | /* |
415 | * Decode CLONE request | |
416 | */ | |
417 | static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp, | |
418 | struct xdr_stream *xdr, | |
419 | struct nfs42_clone_res *res) | |
420 | { | |
421 | struct compound_hdr hdr; | |
422 | int status; | |
423 | ||
424 | status = decode_compound_hdr(xdr, &hdr); | |
425 | if (status) | |
426 | goto out; | |
427 | status = decode_sequence(xdr, &res->seq_res, rqstp); | |
428 | if (status) | |
429 | goto out; | |
430 | status = decode_putfh(xdr); | |
431 | if (status) | |
432 | goto out; | |
433 | status = decode_savefh(xdr); | |
434 | if (status) | |
435 | goto out; | |
436 | status = decode_putfh(xdr); | |
437 | if (status) | |
438 | goto out; | |
439 | status = decode_clone(xdr); | |
440 | if (status) | |
441 | goto out; | |
442 | status = decode_getfattr(xdr, res->dst_fattr, res->server); | |
443 | ||
444 | out: | |
445 | res->rpc_status = status; | |
446 | return status; | |
447 | } | |
448 | ||
1c6dcbe5 | 449 | #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */ |