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