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) | |
1c6dcbe5 | 37 | |
f4ac1674 AS |
38 | #define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \ |
39 | encode_putfh_maxsz + \ | |
9a51940b AS |
40 | encode_allocate_maxsz + \ |
41 | encode_getattr_maxsz) | |
f4ac1674 AS |
42 | #define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \ |
43 | decode_putfh_maxsz + \ | |
9a51940b AS |
44 | decode_allocate_maxsz + \ |
45 | decode_getattr_maxsz) | |
624bd5b7 AS |
46 | #define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \ |
47 | encode_putfh_maxsz + \ | |
9a51940b AS |
48 | encode_deallocate_maxsz + \ |
49 | encode_getattr_maxsz) | |
624bd5b7 AS |
50 | #define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \ |
51 | decode_putfh_maxsz + \ | |
9a51940b AS |
52 | decode_deallocate_maxsz + \ |
53 | decode_getattr_maxsz) | |
1c6dcbe5 AS |
54 | #define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \ |
55 | encode_putfh_maxsz + \ | |
56 | encode_seek_maxsz) | |
57 | #define NFS4_dec_seek_sz (compound_decode_hdr_maxsz + \ | |
58 | decode_putfh_maxsz + \ | |
59 | decode_seek_maxsz) | |
be3a5d23 TM |
60 | #define NFS4_enc_layoutstats_sz (compound_encode_hdr_maxsz + \ |
61 | encode_sequence_maxsz + \ | |
62 | encode_putfh_maxsz + \ | |
63 | PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz) | |
64 | #define NFS4_dec_layoutstats_sz (compound_decode_hdr_maxsz + \ | |
65 | decode_sequence_maxsz + \ | |
66 | decode_putfh_maxsz + \ | |
67 | PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz) | |
1c6dcbe5 AS |
68 | |
69 | ||
f4ac1674 AS |
70 | static void encode_fallocate(struct xdr_stream *xdr, |
71 | struct nfs42_falloc_args *args) | |
72 | { | |
73 | encode_nfs4_stateid(xdr, &args->falloc_stateid); | |
74 | encode_uint64(xdr, args->falloc_offset); | |
75 | encode_uint64(xdr, args->falloc_length); | |
76 | } | |
77 | ||
78 | static void encode_allocate(struct xdr_stream *xdr, | |
79 | struct nfs42_falloc_args *args, | |
80 | struct compound_hdr *hdr) | |
81 | { | |
82 | encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr); | |
83 | encode_fallocate(xdr, args); | |
84 | } | |
85 | ||
624bd5b7 AS |
86 | static void encode_deallocate(struct xdr_stream *xdr, |
87 | struct nfs42_falloc_args *args, | |
88 | struct compound_hdr *hdr) | |
89 | { | |
90 | encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr); | |
91 | encode_fallocate(xdr, args); | |
92 | } | |
93 | ||
1c6dcbe5 AS |
94 | static void encode_seek(struct xdr_stream *xdr, |
95 | struct nfs42_seek_args *args, | |
96 | struct compound_hdr *hdr) | |
97 | { | |
98 | encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr); | |
99 | encode_nfs4_stateid(xdr, &args->sa_stateid); | |
100 | encode_uint64(xdr, args->sa_offset); | |
101 | encode_uint32(xdr, args->sa_what); | |
102 | } | |
103 | ||
be3a5d23 TM |
104 | static void encode_layoutstats(struct xdr_stream *xdr, |
105 | struct nfs42_layoutstat_args *args, | |
106 | struct nfs42_layoutstat_devinfo *devinfo, | |
107 | struct compound_hdr *hdr) | |
108 | { | |
109 | __be32 *p; | |
110 | ||
111 | encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr); | |
112 | p = reserve_space(xdr, 8 + 8); | |
113 | p = xdr_encode_hyper(p, devinfo->offset); | |
114 | p = xdr_encode_hyper(p, devinfo->length); | |
115 | encode_nfs4_stateid(xdr, &args->stateid); | |
116 | p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4); | |
117 | p = xdr_encode_hyper(p, devinfo->read_count); | |
118 | p = xdr_encode_hyper(p, devinfo->read_bytes); | |
119 | p = xdr_encode_hyper(p, devinfo->write_count); | |
120 | p = xdr_encode_hyper(p, devinfo->write_bytes); | |
121 | p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data, | |
122 | NFS4_DEVICEID4_SIZE); | |
123 | /* Encode layoutupdate4 */ | |
124 | *p++ = cpu_to_be32(devinfo->layout_type); | |
125 | if (devinfo->layoutstats_encode != NULL) | |
126 | devinfo->layoutstats_encode(xdr, args, devinfo); | |
127 | else | |
128 | encode_uint32(xdr, 0); | |
129 | } | |
130 | ||
f4ac1674 AS |
131 | /* |
132 | * Encode ALLOCATE request | |
133 | */ | |
134 | static void nfs4_xdr_enc_allocate(struct rpc_rqst *req, | |
135 | struct xdr_stream *xdr, | |
136 | struct nfs42_falloc_args *args) | |
137 | { | |
138 | struct compound_hdr hdr = { | |
139 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | |
140 | }; | |
141 | ||
142 | encode_compound_hdr(xdr, req, &hdr); | |
143 | encode_sequence(xdr, &args->seq_args, &hdr); | |
144 | encode_putfh(xdr, args->falloc_fh, &hdr); | |
145 | encode_allocate(xdr, args, &hdr); | |
9a51940b | 146 | encode_getfattr(xdr, args->falloc_bitmask, &hdr); |
f4ac1674 AS |
147 | encode_nops(&hdr); |
148 | } | |
149 | ||
624bd5b7 AS |
150 | /* |
151 | * Encode DEALLOCATE request | |
152 | */ | |
153 | static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req, | |
154 | struct xdr_stream *xdr, | |
155 | struct nfs42_falloc_args *args) | |
156 | { | |
157 | struct compound_hdr hdr = { | |
158 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | |
159 | }; | |
160 | ||
161 | encode_compound_hdr(xdr, req, &hdr); | |
162 | encode_sequence(xdr, &args->seq_args, &hdr); | |
163 | encode_putfh(xdr, args->falloc_fh, &hdr); | |
164 | encode_deallocate(xdr, args, &hdr); | |
9a51940b | 165 | encode_getfattr(xdr, args->falloc_bitmask, &hdr); |
624bd5b7 AS |
166 | encode_nops(&hdr); |
167 | } | |
168 | ||
1c6dcbe5 AS |
169 | /* |
170 | * Encode SEEK request | |
171 | */ | |
172 | static void nfs4_xdr_enc_seek(struct rpc_rqst *req, | |
173 | struct xdr_stream *xdr, | |
174 | struct nfs42_seek_args *args) | |
175 | { | |
176 | struct compound_hdr hdr = { | |
177 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | |
178 | }; | |
179 | ||
180 | encode_compound_hdr(xdr, req, &hdr); | |
181 | encode_sequence(xdr, &args->seq_args, &hdr); | |
182 | encode_putfh(xdr, args->sa_fh, &hdr); | |
183 | encode_seek(xdr, args, &hdr); | |
184 | encode_nops(&hdr); | |
185 | } | |
186 | ||
be3a5d23 TM |
187 | /* |
188 | * Encode LAYOUTSTATS request | |
189 | */ | |
190 | static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req, | |
191 | struct xdr_stream *xdr, | |
192 | struct nfs42_layoutstat_args *args) | |
193 | { | |
194 | int i; | |
195 | ||
196 | struct compound_hdr hdr = { | |
197 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | |
198 | }; | |
199 | ||
200 | encode_compound_hdr(xdr, req, &hdr); | |
201 | encode_sequence(xdr, &args->seq_args, &hdr); | |
202 | encode_putfh(xdr, args->fh, &hdr); | |
203 | WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV); | |
204 | for (i = 0; i < args->num_dev; i++) | |
205 | encode_layoutstats(xdr, args, &args->devinfo[i], &hdr); | |
206 | encode_nops(&hdr); | |
207 | } | |
208 | ||
f4ac1674 AS |
209 | static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) |
210 | { | |
211 | return decode_op_hdr(xdr, OP_ALLOCATE); | |
212 | } | |
213 | ||
624bd5b7 AS |
214 | static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) |
215 | { | |
216 | return decode_op_hdr(xdr, OP_DEALLOCATE); | |
217 | } | |
218 | ||
1c6dcbe5 AS |
219 | static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res) |
220 | { | |
221 | int status; | |
222 | __be32 *p; | |
223 | ||
224 | status = decode_op_hdr(xdr, OP_SEEK); | |
225 | if (status) | |
226 | return status; | |
227 | ||
228 | p = xdr_inline_decode(xdr, 4 + 8); | |
229 | if (unlikely(!p)) | |
230 | goto out_overflow; | |
231 | ||
232 | res->sr_eof = be32_to_cpup(p++); | |
233 | p = xdr_decode_hyper(p, &res->sr_offset); | |
234 | return 0; | |
235 | ||
236 | out_overflow: | |
237 | print_overflow_msg(__func__, xdr); | |
238 | return -EIO; | |
239 | } | |
240 | ||
be3a5d23 TM |
241 | static int decode_layoutstats(struct xdr_stream *xdr, |
242 | struct nfs42_layoutstat_res *res) | |
243 | { | |
244 | int status; | |
245 | __be32 *p; | |
246 | ||
247 | status = decode_op_hdr(xdr, OP_LAYOUTSTATS); | |
248 | if (status) | |
249 | return status; | |
250 | ||
251 | p = xdr_inline_decode(xdr, 4); | |
252 | if (unlikely(!p)) | |
253 | goto out_overflow; | |
254 | ||
255 | res->rpc_status = be32_to_cpup(p++); | |
256 | return 0; | |
257 | ||
258 | out_overflow: | |
259 | print_overflow_msg(__func__, xdr); | |
260 | return -EIO; | |
261 | } | |
262 | ||
f4ac1674 AS |
263 | /* |
264 | * Decode ALLOCATE request | |
265 | */ | |
266 | static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp, | |
267 | struct xdr_stream *xdr, | |
268 | struct nfs42_falloc_res *res) | |
269 | { | |
270 | struct compound_hdr hdr; | |
271 | int status; | |
272 | ||
273 | status = decode_compound_hdr(xdr, &hdr); | |
274 | if (status) | |
275 | goto out; | |
276 | status = decode_sequence(xdr, &res->seq_res, rqstp); | |
277 | if (status) | |
278 | goto out; | |
279 | status = decode_putfh(xdr); | |
280 | if (status) | |
281 | goto out; | |
282 | status = decode_allocate(xdr, res); | |
9a51940b AS |
283 | if (status) |
284 | goto out; | |
285 | decode_getfattr(xdr, res->falloc_fattr, res->falloc_server); | |
f4ac1674 AS |
286 | out: |
287 | return status; | |
288 | } | |
289 | ||
624bd5b7 AS |
290 | /* |
291 | * Decode DEALLOCATE request | |
292 | */ | |
293 | static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp, | |
294 | struct xdr_stream *xdr, | |
295 | struct nfs42_falloc_res *res) | |
296 | { | |
297 | struct compound_hdr hdr; | |
298 | int status; | |
299 | ||
300 | status = decode_compound_hdr(xdr, &hdr); | |
301 | if (status) | |
302 | goto out; | |
303 | status = decode_sequence(xdr, &res->seq_res, rqstp); | |
304 | if (status) | |
305 | goto out; | |
306 | status = decode_putfh(xdr); | |
307 | if (status) | |
308 | goto out; | |
309 | status = decode_deallocate(xdr, res); | |
9a51940b AS |
310 | if (status) |
311 | goto out; | |
312 | decode_getfattr(xdr, res->falloc_fattr, res->falloc_server); | |
624bd5b7 AS |
313 | out: |
314 | return status; | |
315 | } | |
316 | ||
1c6dcbe5 AS |
317 | /* |
318 | * Decode SEEK request | |
319 | */ | |
320 | static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp, | |
321 | struct xdr_stream *xdr, | |
322 | struct nfs42_seek_res *res) | |
323 | { | |
324 | struct compound_hdr hdr; | |
325 | int status; | |
326 | ||
327 | status = decode_compound_hdr(xdr, &hdr); | |
328 | if (status) | |
329 | goto out; | |
330 | status = decode_sequence(xdr, &res->seq_res, rqstp); | |
331 | if (status) | |
332 | goto out; | |
333 | status = decode_putfh(xdr); | |
334 | if (status) | |
335 | goto out; | |
336 | status = decode_seek(xdr, res); | |
337 | out: | |
338 | return status; | |
339 | } | |
be3a5d23 TM |
340 | |
341 | /* | |
342 | * Decode LAYOUTSTATS request | |
343 | */ | |
344 | static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp, | |
345 | struct xdr_stream *xdr, | |
346 | struct nfs42_layoutstat_res *res) | |
347 | { | |
348 | struct compound_hdr hdr; | |
349 | int status, i; | |
350 | ||
351 | status = decode_compound_hdr(xdr, &hdr); | |
352 | if (status) | |
353 | goto out; | |
354 | status = decode_sequence(xdr, &res->seq_res, rqstp); | |
355 | if (status) | |
356 | goto out; | |
357 | status = decode_putfh(xdr); | |
358 | if (status) | |
359 | goto out; | |
360 | WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV); | |
361 | for (i = 0; i < res->num_dev; i++) { | |
362 | status = decode_layoutstats(xdr, res); | |
363 | if (status) | |
364 | goto out; | |
365 | } | |
366 | out: | |
367 | res->rpc_status = status; | |
368 | return status; | |
369 | } | |
370 | ||
1c6dcbe5 | 371 | #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */ |