These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / 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 */