]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - fs/nfs/nfs42xdr.c
Merge branch 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[mirror_ubuntu-bionic-kernel.git] / fs / nfs / nfs42xdr.c
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
7 #include "nfs42.h"
8
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)
15 #define encode_deallocate_maxsz (op_encode_hdr_maxsz + \
16 encode_fallocate_maxsz)
17 #define decode_deallocate_maxsz (op_decode_hdr_maxsz)
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 */)
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)
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)
43
44 #define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \
45 encode_putfh_maxsz + \
46 encode_allocate_maxsz + \
47 encode_getattr_maxsz)
48 #define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \
49 decode_putfh_maxsz + \
50 decode_allocate_maxsz + \
51 decode_getattr_maxsz)
52 #define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \
53 encode_putfh_maxsz + \
54 encode_deallocate_maxsz + \
55 encode_getattr_maxsz)
56 #define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \
57 decode_putfh_maxsz + \
58 decode_deallocate_maxsz + \
59 decode_getattr_maxsz)
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)
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)
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)
88
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
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
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
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
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
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);
180 encode_getfattr(xdr, args->falloc_bitmask, &hdr);
181 encode_nops(&hdr);
182 }
183
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);
199 encode_getfattr(xdr, args->falloc_bitmask, &hdr);
200 encode_nops(&hdr);
201 }
202
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
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
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
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
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
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
296 static int decode_layoutstats(struct xdr_stream *xdr)
297 {
298 return decode_op_hdr(xdr, OP_LAYOUTSTATS);
299 }
300
301 static int decode_clone(struct xdr_stream *xdr)
302 {
303 return decode_op_hdr(xdr, OP_CLONE);
304 }
305
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);
326 if (status)
327 goto out;
328 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
329 out:
330 return status;
331 }
332
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);
353 if (status)
354 goto out;
355 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
356 out:
357 return status;
358 }
359
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 }
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++) {
405 status = decode_layoutstats(xdr);
406 if (status)
407 goto out;
408 }
409 out:
410 res->rpc_status = status;
411 return status;
412 }
413
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
449 #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */