blob: 69f72ed2bf879310f0ece97fab1e4cccea75a402 [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001// SPDX-License-Identifier: GPL-2.0
Anna Schumaker1c6dcbe2014-09-26 13:58:48 -04002/*
3 * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com>
4 */
5#ifndef __LINUX_FS_NFS_NFS4_2XDR_H
6#define __LINUX_FS_NFS_NFS4_2XDR_H
7
Trond Myklebustbe3a5d22015-06-23 19:51:55 +08008#include "nfs42.h"
9
Anna Schumakerf4ac1672014-11-25 13:18:15 -050010#define encode_fallocate_maxsz (encode_stateid_maxsz + \
11 2 /* offset */ + \
12 2 /* length */)
Anna Schumaker2e724482013-05-21 16:53:03 -040013#define NFS42_WRITE_RES_SIZE (1 /* wr_callback_id size */ +\
14 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
15 2 /* wr_count */ + \
16 1 /* wr_committed */ + \
17 XDR_QUADLEN(NFS4_VERIFIER_SIZE))
Anna Schumakerf4ac1672014-11-25 13:18:15 -050018#define encode_allocate_maxsz (op_encode_hdr_maxsz + \
19 encode_fallocate_maxsz)
20#define decode_allocate_maxsz (op_decode_hdr_maxsz)
Anna Schumaker2e724482013-05-21 16:53:03 -040021#define encode_copy_maxsz (op_encode_hdr_maxsz + \
22 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
23 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
24 2 + 2 + 2 + 1 + 1 + 1)
25#define decode_copy_maxsz (op_decode_hdr_maxsz + \
26 NFS42_WRITE_RES_SIZE + \
27 1 /* cr_consecutive */ + \
28 1 /* cr_synchronous */)
Olga Kornievskaiacb95dee2018-07-09 15:13:29 -040029#define encode_offload_cancel_maxsz (op_encode_hdr_maxsz + \
30 XDR_QUADLEN(NFS4_STATEID_SIZE))
31#define decode_offload_cancel_maxsz (op_decode_hdr_maxsz)
Anna Schumaker624bd5b2014-11-25 13:18:16 -050032#define encode_deallocate_maxsz (op_encode_hdr_maxsz + \
33 encode_fallocate_maxsz)
34#define decode_deallocate_maxsz (op_decode_hdr_maxsz)
Anna Schumaker1c6dcbe2014-09-26 13:58:48 -040035#define encode_seek_maxsz (op_encode_hdr_maxsz + \
36 encode_stateid_maxsz + \
37 2 /* offset */ + \
38 1 /* whence */)
39#define decode_seek_maxsz (op_decode_hdr_maxsz + \
40 1 /* eof */ + \
41 1 /* whence */ + \
42 2 /* offset */ + \
43 2 /* length */)
Trond Myklebustbe3a5d22015-06-23 19:51:55 +080044#define encode_io_info_maxsz 4
45#define encode_layoutstats_maxsz (op_decode_hdr_maxsz + \
46 2 /* offset */ + \
47 2 /* length */ + \
48 encode_stateid_maxsz + \
49 encode_io_info_maxsz + \
50 encode_io_info_maxsz + \
51 1 /* opaque devaddr4 length */ + \
52 XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE))
53#define decode_layoutstats_maxsz (op_decode_hdr_maxsz)
Peng Tao36022772015-09-26 02:24:34 +080054#define encode_clone_maxsz (encode_stateid_maxsz + \
55 encode_stateid_maxsz + \
56 2 /* src offset */ + \
57 2 /* dst offset */ + \
58 2 /* count */)
59#define decode_clone_maxsz (op_decode_hdr_maxsz)
Anna Schumaker1c6dcbe2014-09-26 13:58:48 -040060
Anna Schumakerf4ac1672014-11-25 13:18:15 -050061#define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \
62 encode_putfh_maxsz + \
Anna Schumaker9a519402015-03-16 14:06:23 -040063 encode_allocate_maxsz + \
64 encode_getattr_maxsz)
Anna Schumakerf4ac1672014-11-25 13:18:15 -050065#define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \
66 decode_putfh_maxsz + \
Anna Schumaker9a519402015-03-16 14:06:23 -040067 decode_allocate_maxsz + \
68 decode_getattr_maxsz)
Anna Schumaker2e724482013-05-21 16:53:03 -040069#define NFS4_enc_copy_sz (compound_encode_hdr_maxsz + \
70 encode_putfh_maxsz + \
71 encode_savefh_maxsz + \
72 encode_putfh_maxsz + \
Olga Kornievskaiae0926932017-05-08 18:02:24 -040073 encode_copy_maxsz + \
74 encode_commit_maxsz)
Anna Schumaker2e724482013-05-21 16:53:03 -040075#define NFS4_dec_copy_sz (compound_decode_hdr_maxsz + \
76 decode_putfh_maxsz + \
77 decode_savefh_maxsz + \
78 decode_putfh_maxsz + \
Olga Kornievskaiae0926932017-05-08 18:02:24 -040079 decode_copy_maxsz + \
80 decode_commit_maxsz)
Olga Kornievskaiacb95dee2018-07-09 15:13:29 -040081#define NFS4_enc_offload_cancel_sz (compound_encode_hdr_maxsz + \
82 encode_putfh_maxsz + \
83 encode_offload_cancel_maxsz)
84#define NFS4_dec_offload_cancel_sz (compound_decode_hdr_maxsz + \
85 decode_putfh_maxsz + \
86 decode_offload_cancel_maxsz)
Anna Schumaker624bd5b2014-11-25 13:18:16 -050087#define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \
88 encode_putfh_maxsz + \
Anna Schumaker9a519402015-03-16 14:06:23 -040089 encode_deallocate_maxsz + \
90 encode_getattr_maxsz)
Anna Schumaker624bd5b2014-11-25 13:18:16 -050091#define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \
92 decode_putfh_maxsz + \
Anna Schumaker9a519402015-03-16 14:06:23 -040093 decode_deallocate_maxsz + \
94 decode_getattr_maxsz)
Anna Schumaker1c6dcbe2014-09-26 13:58:48 -040095#define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \
96 encode_putfh_maxsz + \
97 encode_seek_maxsz)
98#define NFS4_dec_seek_sz (compound_decode_hdr_maxsz + \
99 decode_putfh_maxsz + \
100 decode_seek_maxsz)
Trond Myklebustbe3a5d22015-06-23 19:51:55 +0800101#define NFS4_enc_layoutstats_sz (compound_encode_hdr_maxsz + \
102 encode_sequence_maxsz + \
103 encode_putfh_maxsz + \
104 PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz)
105#define NFS4_dec_layoutstats_sz (compound_decode_hdr_maxsz + \
106 decode_sequence_maxsz + \
107 decode_putfh_maxsz + \
108 PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz)
Peng Tao36022772015-09-26 02:24:34 +0800109#define NFS4_enc_clone_sz (compound_encode_hdr_maxsz + \
110 encode_sequence_maxsz + \
111 encode_putfh_maxsz + \
112 encode_savefh_maxsz + \
113 encode_putfh_maxsz + \
114 encode_clone_maxsz + \
115 encode_getattr_maxsz)
116#define NFS4_dec_clone_sz (compound_decode_hdr_maxsz + \
117 decode_sequence_maxsz + \
118 decode_putfh_maxsz + \
119 decode_savefh_maxsz + \
120 decode_putfh_maxsz + \
121 decode_clone_maxsz + \
122 decode_getattr_maxsz)
Anna Schumaker1c6dcbe2014-09-26 13:58:48 -0400123
Anna Schumakerf4ac1672014-11-25 13:18:15 -0500124static void encode_fallocate(struct xdr_stream *xdr,
Christoph Hellwig0096d392017-05-08 10:01:49 +0200125 const struct nfs42_falloc_args *args)
Anna Schumakerf4ac1672014-11-25 13:18:15 -0500126{
127 encode_nfs4_stateid(xdr, &args->falloc_stateid);
128 encode_uint64(xdr, args->falloc_offset);
129 encode_uint64(xdr, args->falloc_length);
130}
131
132static void encode_allocate(struct xdr_stream *xdr,
Christoph Hellwig0096d392017-05-08 10:01:49 +0200133 const struct nfs42_falloc_args *args,
Anna Schumakerf4ac1672014-11-25 13:18:15 -0500134 struct compound_hdr *hdr)
135{
136 encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr);
137 encode_fallocate(xdr, args);
138}
139
Anna Schumaker2e724482013-05-21 16:53:03 -0400140static void encode_copy(struct xdr_stream *xdr,
Christoph Hellwig0096d392017-05-08 10:01:49 +0200141 const struct nfs42_copy_args *args,
Anna Schumaker2e724482013-05-21 16:53:03 -0400142 struct compound_hdr *hdr)
143{
144 encode_op_hdr(xdr, OP_COPY, decode_copy_maxsz, hdr);
145 encode_nfs4_stateid(xdr, &args->src_stateid);
146 encode_nfs4_stateid(xdr, &args->dst_stateid);
147
148 encode_uint64(xdr, args->src_pos);
149 encode_uint64(xdr, args->dst_pos);
150 encode_uint64(xdr, args->count);
151
152 encode_uint32(xdr, 1); /* consecutive = true */
Olga Kornievskaia62164f32018-07-09 15:13:31 -0400153 encode_uint32(xdr, args->sync);
Anna Schumaker2e724482013-05-21 16:53:03 -0400154 encode_uint32(xdr, 0); /* src server list */
155}
156
Olga Kornievskaiacb95dee2018-07-09 15:13:29 -0400157static void encode_offload_cancel(struct xdr_stream *xdr,
158 const struct nfs42_offload_status_args *args,
159 struct compound_hdr *hdr)
160{
161 encode_op_hdr(xdr, OP_OFFLOAD_CANCEL, decode_offload_cancel_maxsz, hdr);
162 encode_nfs4_stateid(xdr, &args->osa_stateid);
163}
164
Anna Schumaker624bd5b2014-11-25 13:18:16 -0500165static void encode_deallocate(struct xdr_stream *xdr,
Christoph Hellwig0096d392017-05-08 10:01:49 +0200166 const struct nfs42_falloc_args *args,
Anna Schumaker624bd5b2014-11-25 13:18:16 -0500167 struct compound_hdr *hdr)
168{
169 encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr);
170 encode_fallocate(xdr, args);
171}
172
Anna Schumaker1c6dcbe2014-09-26 13:58:48 -0400173static void encode_seek(struct xdr_stream *xdr,
Christoph Hellwig0096d392017-05-08 10:01:49 +0200174 const struct nfs42_seek_args *args,
Anna Schumaker1c6dcbe2014-09-26 13:58:48 -0400175 struct compound_hdr *hdr)
176{
177 encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr);
178 encode_nfs4_stateid(xdr, &args->sa_stateid);
179 encode_uint64(xdr, args->sa_offset);
180 encode_uint32(xdr, args->sa_what);
181}
182
Trond Myklebustbe3a5d22015-06-23 19:51:55 +0800183static void encode_layoutstats(struct xdr_stream *xdr,
Christoph Hellwig0096d392017-05-08 10:01:49 +0200184 const struct nfs42_layoutstat_args *args,
Trond Myklebustbe3a5d22015-06-23 19:51:55 +0800185 struct nfs42_layoutstat_devinfo *devinfo,
186 struct compound_hdr *hdr)
187{
188 __be32 *p;
189
190 encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr);
191 p = reserve_space(xdr, 8 + 8);
192 p = xdr_encode_hyper(p, devinfo->offset);
193 p = xdr_encode_hyper(p, devinfo->length);
194 encode_nfs4_stateid(xdr, &args->stateid);
195 p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4);
196 p = xdr_encode_hyper(p, devinfo->read_count);
197 p = xdr_encode_hyper(p, devinfo->read_bytes);
198 p = xdr_encode_hyper(p, devinfo->write_count);
199 p = xdr_encode_hyper(p, devinfo->write_bytes);
200 p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data,
201 NFS4_DEVICEID4_SIZE);
202 /* Encode layoutupdate4 */
203 *p++ = cpu_to_be32(devinfo->layout_type);
Trond Myklebust422c93c2016-10-06 17:53:20 -0400204 if (devinfo->ld_private.ops)
205 devinfo->ld_private.ops->encode(xdr, args,
206 &devinfo->ld_private);
Trond Myklebustbe3a5d22015-06-23 19:51:55 +0800207 else
208 encode_uint32(xdr, 0);
209}
210
Peng Tao36022772015-09-26 02:24:34 +0800211static void encode_clone(struct xdr_stream *xdr,
Christoph Hellwig0096d392017-05-08 10:01:49 +0200212 const struct nfs42_clone_args *args,
Peng Tao36022772015-09-26 02:24:34 +0800213 struct compound_hdr *hdr)
214{
215 __be32 *p;
216
217 encode_op_hdr(xdr, OP_CLONE, decode_clone_maxsz, hdr);
218 encode_nfs4_stateid(xdr, &args->src_stateid);
219 encode_nfs4_stateid(xdr, &args->dst_stateid);
220 p = reserve_space(xdr, 3*8);
221 p = xdr_encode_hyper(p, args->src_offset);
222 p = xdr_encode_hyper(p, args->dst_offset);
223 xdr_encode_hyper(p, args->count);
224}
225
Anna Schumaker1c6dcbe2014-09-26 13:58:48 -0400226/*
Anna Schumakerf4ac1672014-11-25 13:18:15 -0500227 * Encode ALLOCATE request
228 */
229static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
230 struct xdr_stream *xdr,
Christoph Hellwig0096d392017-05-08 10:01:49 +0200231 const void *data)
Anna Schumakerf4ac1672014-11-25 13:18:15 -0500232{
Christoph Hellwig0096d392017-05-08 10:01:49 +0200233 const struct nfs42_falloc_args *args = data;
Anna Schumakerf4ac1672014-11-25 13:18:15 -0500234 struct compound_hdr hdr = {
235 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
236 };
237
238 encode_compound_hdr(xdr, req, &hdr);
239 encode_sequence(xdr, &args->seq_args, &hdr);
240 encode_putfh(xdr, args->falloc_fh, &hdr);
241 encode_allocate(xdr, args, &hdr);
Anna Schumaker9a519402015-03-16 14:06:23 -0400242 encode_getfattr(xdr, args->falloc_bitmask, &hdr);
Anna Schumakerf4ac1672014-11-25 13:18:15 -0500243 encode_nops(&hdr);
244}
245
Olga Kornievskaiae0926932017-05-08 18:02:24 -0400246static void encode_copy_commit(struct xdr_stream *xdr,
Christoph Hellwig0096d392017-05-08 10:01:49 +0200247 const struct nfs42_copy_args *args,
Olga Kornievskaiae0926932017-05-08 18:02:24 -0400248 struct compound_hdr *hdr)
249{
250 __be32 *p;
251
252 encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr);
253 p = reserve_space(xdr, 12);
254 p = xdr_encode_hyper(p, args->dst_pos);
255 *p = cpu_to_be32(args->count);
256}
257
Anna Schumakerf4ac1672014-11-25 13:18:15 -0500258/*
Anna Schumaker2e724482013-05-21 16:53:03 -0400259 * Encode COPY request
260 */
261static void nfs4_xdr_enc_copy(struct rpc_rqst *req,
262 struct xdr_stream *xdr,
Christoph Hellwig0096d392017-05-08 10:01:49 +0200263 const void *data)
Anna Schumaker2e724482013-05-21 16:53:03 -0400264{
Christoph Hellwig0096d392017-05-08 10:01:49 +0200265 const struct nfs42_copy_args *args = data;
Anna Schumaker2e724482013-05-21 16:53:03 -0400266 struct compound_hdr hdr = {
267 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
268 };
269
270 encode_compound_hdr(xdr, req, &hdr);
271 encode_sequence(xdr, &args->seq_args, &hdr);
272 encode_putfh(xdr, args->src_fh, &hdr);
273 encode_savefh(xdr, &hdr);
274 encode_putfh(xdr, args->dst_fh, &hdr);
275 encode_copy(xdr, args, &hdr);
Olga Kornievskaia62164f32018-07-09 15:13:31 -0400276 if (args->sync)
277 encode_copy_commit(xdr, args, &hdr);
Anna Schumaker2e724482013-05-21 16:53:03 -0400278 encode_nops(&hdr);
279}
280
281/*
Olga Kornievskaiacb95dee2018-07-09 15:13:29 -0400282 * Encode OFFLOAD_CANEL request
283 */
284static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req,
285 struct xdr_stream *xdr,
286 const void *data)
287{
288 const struct nfs42_offload_status_args *args = data;
289 struct compound_hdr hdr = {
290 .minorversion = nfs4_xdr_minorversion(&args->osa_seq_args),
291 };
292
293 encode_compound_hdr(xdr, req, &hdr);
294 encode_sequence(xdr, &args->osa_seq_args, &hdr);
295 encode_putfh(xdr, args->osa_src_fh, &hdr);
296 encode_offload_cancel(xdr, args, &hdr);
297 encode_nops(&hdr);
298}
299
300/*
Anna Schumaker624bd5b2014-11-25 13:18:16 -0500301 * Encode DEALLOCATE request
302 */
303static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
304 struct xdr_stream *xdr,
Christoph Hellwig0096d392017-05-08 10:01:49 +0200305 const void *data)
Anna Schumaker624bd5b2014-11-25 13:18:16 -0500306{
Christoph Hellwig0096d392017-05-08 10:01:49 +0200307 const struct nfs42_falloc_args *args = data;
Anna Schumaker624bd5b2014-11-25 13:18:16 -0500308 struct compound_hdr hdr = {
309 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
310 };
311
312 encode_compound_hdr(xdr, req, &hdr);
313 encode_sequence(xdr, &args->seq_args, &hdr);
314 encode_putfh(xdr, args->falloc_fh, &hdr);
315 encode_deallocate(xdr, args, &hdr);
Anna Schumaker9a519402015-03-16 14:06:23 -0400316 encode_getfattr(xdr, args->falloc_bitmask, &hdr);
Anna Schumaker624bd5b2014-11-25 13:18:16 -0500317 encode_nops(&hdr);
318}
319
320/*
Anna Schumaker1c6dcbe2014-09-26 13:58:48 -0400321 * Encode SEEK request
322 */
323static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
324 struct xdr_stream *xdr,
Christoph Hellwig0096d392017-05-08 10:01:49 +0200325 const void *data)
Anna Schumaker1c6dcbe2014-09-26 13:58:48 -0400326{
Christoph Hellwig0096d392017-05-08 10:01:49 +0200327 const struct nfs42_seek_args *args = data;
Anna Schumaker1c6dcbe2014-09-26 13:58:48 -0400328 struct compound_hdr hdr = {
329 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
330 };
331
332 encode_compound_hdr(xdr, req, &hdr);
333 encode_sequence(xdr, &args->seq_args, &hdr);
334 encode_putfh(xdr, args->sa_fh, &hdr);
335 encode_seek(xdr, args, &hdr);
336 encode_nops(&hdr);
337}
338
Trond Myklebustbe3a5d22015-06-23 19:51:55 +0800339/*
340 * Encode LAYOUTSTATS request
341 */
342static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req,
343 struct xdr_stream *xdr,
Christoph Hellwig0096d392017-05-08 10:01:49 +0200344 const void *data)
Trond Myklebustbe3a5d22015-06-23 19:51:55 +0800345{
Christoph Hellwig0096d392017-05-08 10:01:49 +0200346 const struct nfs42_layoutstat_args *args = data;
Trond Myklebustbe3a5d22015-06-23 19:51:55 +0800347 int i;
348
349 struct compound_hdr hdr = {
350 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
351 };
352
353 encode_compound_hdr(xdr, req, &hdr);
354 encode_sequence(xdr, &args->seq_args, &hdr);
355 encode_putfh(xdr, args->fh, &hdr);
356 WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
357 for (i = 0; i < args->num_dev; i++)
358 encode_layoutstats(xdr, args, &args->devinfo[i], &hdr);
359 encode_nops(&hdr);
360}
361
Peng Tao36022772015-09-26 02:24:34 +0800362/*
363 * Encode CLONE request
364 */
365static void nfs4_xdr_enc_clone(struct rpc_rqst *req,
366 struct xdr_stream *xdr,
Christoph Hellwig0096d392017-05-08 10:01:49 +0200367 const void *data)
Peng Tao36022772015-09-26 02:24:34 +0800368{
Christoph Hellwig0096d392017-05-08 10:01:49 +0200369 const struct nfs42_clone_args *args = data;
Peng Tao36022772015-09-26 02:24:34 +0800370 struct compound_hdr hdr = {
371 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
372 };
373
374 encode_compound_hdr(xdr, req, &hdr);
375 encode_sequence(xdr, &args->seq_args, &hdr);
376 encode_putfh(xdr, args->src_fh, &hdr);
377 encode_savefh(xdr, &hdr);
378 encode_putfh(xdr, args->dst_fh, &hdr);
379 encode_clone(xdr, args, &hdr);
380 encode_getfattr(xdr, args->dst_bitmask, &hdr);
381 encode_nops(&hdr);
382}
383
Anna Schumakerf4ac1672014-11-25 13:18:15 -0500384static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
385{
386 return decode_op_hdr(xdr, OP_ALLOCATE);
387}
388
Anna Schumaker2e724482013-05-21 16:53:03 -0400389static int decode_write_response(struct xdr_stream *xdr,
390 struct nfs42_write_res *res)
391{
392 __be32 *p;
Olga Kornievskaia67aa7442018-07-09 15:13:30 -0400393 int status, count;
Anna Schumaker2e724482013-05-21 16:53:03 -0400394
Olga Kornievskaia67aa7442018-07-09 15:13:30 -0400395 p = xdr_inline_decode(xdr, 4);
Anna Schumaker2e724482013-05-21 16:53:03 -0400396 if (unlikely(!p))
397 goto out_overflow;
Olga Kornievskaia67aa7442018-07-09 15:13:30 -0400398 count = be32_to_cpup(p);
399 if (count > 1)
Trond Myklebust6fdf3392016-07-24 17:17:16 -0400400 return -EREMOTEIO;
Olga Kornievskaia67aa7442018-07-09 15:13:30 -0400401 else if (count == 1) {
402 status = decode_opaque_fixed(xdr, &res->stateid,
403 NFS4_STATEID_SIZE);
404 if (unlikely(status))
405 goto out_overflow;
Trond Myklebust6fdf3392016-07-24 17:17:16 -0400406 }
Olga Kornievskaia67aa7442018-07-09 15:13:30 -0400407 p = xdr_inline_decode(xdr, 8 + 4);
408 if (unlikely(!p))
409 goto out_overflow;
Anna Schumaker2e724482013-05-21 16:53:03 -0400410 p = xdr_decode_hyper(p, &res->count);
411 res->verifier.committed = be32_to_cpup(p);
412 return decode_verifier(xdr, &res->verifier.verifier);
413
414out_overflow:
415 print_overflow_msg(__func__, xdr);
416 return -EIO;
417}
418
419static int decode_copy_requirements(struct xdr_stream *xdr,
420 struct nfs42_copy_res *res) {
421 __be32 *p;
422
423 p = xdr_inline_decode(xdr, 4 + 4);
424 if (unlikely(!p))
425 goto out_overflow;
426
427 res->consecutive = be32_to_cpup(p++);
428 res->synchronous = be32_to_cpup(p++);
429 return 0;
430out_overflow:
431 print_overflow_msg(__func__, xdr);
432 return -EIO;
433}
434
435static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res)
436{
437 int status;
438
439 status = decode_op_hdr(xdr, OP_COPY);
440 if (status == NFS4ERR_OFFLOAD_NO_REQS) {
441 status = decode_copy_requirements(xdr, res);
442 if (status)
443 return status;
444 return NFS4ERR_OFFLOAD_NO_REQS;
445 } else if (status)
446 return status;
447
448 status = decode_write_response(xdr, &res->write_res);
449 if (status)
450 return status;
451
452 return decode_copy_requirements(xdr, res);
453}
454
Olga Kornievskaiacb95dee2018-07-09 15:13:29 -0400455static int decode_offload_cancel(struct xdr_stream *xdr,
456 struct nfs42_offload_status_res *res)
457{
458 return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL);
459}
460
Anna Schumaker624bd5b2014-11-25 13:18:16 -0500461static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
462{
463 return decode_op_hdr(xdr, OP_DEALLOCATE);
464}
465
Anna Schumaker1c6dcbe2014-09-26 13:58:48 -0400466static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
467{
468 int status;
469 __be32 *p;
470
471 status = decode_op_hdr(xdr, OP_SEEK);
472 if (status)
473 return status;
474
475 p = xdr_inline_decode(xdr, 4 + 8);
476 if (unlikely(!p))
477 goto out_overflow;
478
479 res->sr_eof = be32_to_cpup(p++);
480 p = xdr_decode_hyper(p, &res->sr_offset);
481 return 0;
482
483out_overflow:
484 print_overflow_msg(__func__, xdr);
485 return -EIO;
486}
487
Peng Tao19cf6332015-08-26 00:13:15 +0800488static int decode_layoutstats(struct xdr_stream *xdr)
Trond Myklebustbe3a5d22015-06-23 19:51:55 +0800489{
Trond Myklebustda2e8122015-06-27 11:30:57 -0400490 return decode_op_hdr(xdr, OP_LAYOUTSTATS);
Trond Myklebustbe3a5d22015-06-23 19:51:55 +0800491}
492
Peng Tao36022772015-09-26 02:24:34 +0800493static int decode_clone(struct xdr_stream *xdr)
494{
495 return decode_op_hdr(xdr, OP_CLONE);
496}
497
Anna Schumaker1c6dcbe2014-09-26 13:58:48 -0400498/*
Anna Schumakerf4ac1672014-11-25 13:18:15 -0500499 * Decode ALLOCATE request
500 */
501static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp,
502 struct xdr_stream *xdr,
Christoph Hellwig18d9cff2017-05-08 15:09:02 +0200503 void *data)
Anna Schumakerf4ac1672014-11-25 13:18:15 -0500504{
Christoph Hellwig18d9cff2017-05-08 15:09:02 +0200505 struct nfs42_falloc_res *res = data;
Anna Schumakerf4ac1672014-11-25 13:18:15 -0500506 struct compound_hdr hdr;
507 int status;
508
509 status = decode_compound_hdr(xdr, &hdr);
510 if (status)
511 goto out;
512 status = decode_sequence(xdr, &res->seq_res, rqstp);
513 if (status)
514 goto out;
515 status = decode_putfh(xdr);
516 if (status)
517 goto out;
518 status = decode_allocate(xdr, res);
Anna Schumaker9a519402015-03-16 14:06:23 -0400519 if (status)
520 goto out;
521 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
Anna Schumakerf4ac1672014-11-25 13:18:15 -0500522out:
523 return status;
524}
525
526/*
Anna Schumaker2e724482013-05-21 16:53:03 -0400527 * Decode COPY response
528 */
529static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp,
530 struct xdr_stream *xdr,
Christoph Hellwig18d9cff2017-05-08 15:09:02 +0200531 void *data)
Anna Schumaker2e724482013-05-21 16:53:03 -0400532{
Christoph Hellwig18d9cff2017-05-08 15:09:02 +0200533 struct nfs42_copy_res *res = data;
Anna Schumaker2e724482013-05-21 16:53:03 -0400534 struct compound_hdr hdr;
535 int status;
536
537 status = decode_compound_hdr(xdr, &hdr);
538 if (status)
539 goto out;
540 status = decode_sequence(xdr, &res->seq_res, rqstp);
541 if (status)
542 goto out;
543 status = decode_putfh(xdr);
544 if (status)
545 goto out;
546 status = decode_savefh(xdr);
547 if (status)
548 goto out;
549 status = decode_putfh(xdr);
550 if (status)
551 goto out;
552 status = decode_copy(xdr, res);
Olga Kornievskaiae0926932017-05-08 18:02:24 -0400553 if (status)
554 goto out;
Olga Kornievskaia62164f32018-07-09 15:13:31 -0400555 if (res->commit_res.verf)
556 status = decode_commit(xdr, &res->commit_res);
Anna Schumaker2e724482013-05-21 16:53:03 -0400557out:
558 return status;
559}
560
561/*
Olga Kornievskaiacb95dee2018-07-09 15:13:29 -0400562 * Decode OFFLOAD_CANCEL response
563 */
564static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp,
565 struct xdr_stream *xdr,
566 void *data)
567{
568 struct nfs42_offload_status_res *res = data;
569 struct compound_hdr hdr;
570 int status;
571
572 status = decode_compound_hdr(xdr, &hdr);
573 if (status)
574 goto out;
575 status = decode_sequence(xdr, &res->osr_seq_res, rqstp);
576 if (status)
577 goto out;
578 status = decode_putfh(xdr);
579 if (status)
580 goto out;
581 status = decode_offload_cancel(xdr, res);
582
583out:
584 return status;
585}
586
587/*
Anna Schumaker624bd5b2014-11-25 13:18:16 -0500588 * Decode DEALLOCATE request
589 */
590static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
591 struct xdr_stream *xdr,
Christoph Hellwig18d9cff2017-05-08 15:09:02 +0200592 void *data)
Anna Schumaker624bd5b2014-11-25 13:18:16 -0500593{
Christoph Hellwig18d9cff2017-05-08 15:09:02 +0200594 struct nfs42_falloc_res *res = data;
Anna Schumaker624bd5b2014-11-25 13:18:16 -0500595 struct compound_hdr hdr;
596 int status;
597
598 status = decode_compound_hdr(xdr, &hdr);
599 if (status)
600 goto out;
601 status = decode_sequence(xdr, &res->seq_res, rqstp);
602 if (status)
603 goto out;
604 status = decode_putfh(xdr);
605 if (status)
606 goto out;
607 status = decode_deallocate(xdr, res);
Anna Schumaker9a519402015-03-16 14:06:23 -0400608 if (status)
609 goto out;
610 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
Anna Schumaker624bd5b2014-11-25 13:18:16 -0500611out:
612 return status;
613}
614
615/*
Anna Schumaker1c6dcbe2014-09-26 13:58:48 -0400616 * Decode SEEK request
617 */
618static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp,
619 struct xdr_stream *xdr,
Christoph Hellwig18d9cff2017-05-08 15:09:02 +0200620 void *data)
Anna Schumaker1c6dcbe2014-09-26 13:58:48 -0400621{
Christoph Hellwig18d9cff2017-05-08 15:09:02 +0200622 struct nfs42_seek_res *res = data;
Anna Schumaker1c6dcbe2014-09-26 13:58:48 -0400623 struct compound_hdr hdr;
624 int status;
625
626 status = decode_compound_hdr(xdr, &hdr);
627 if (status)
628 goto out;
629 status = decode_sequence(xdr, &res->seq_res, rqstp);
630 if (status)
631 goto out;
632 status = decode_putfh(xdr);
633 if (status)
634 goto out;
635 status = decode_seek(xdr, res);
636out:
637 return status;
638}
Trond Myklebustbe3a5d22015-06-23 19:51:55 +0800639
640/*
641 * Decode LAYOUTSTATS request
642 */
643static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp,
644 struct xdr_stream *xdr,
Christoph Hellwig18d9cff2017-05-08 15:09:02 +0200645 void *data)
Trond Myklebustbe3a5d22015-06-23 19:51:55 +0800646{
Christoph Hellwig18d9cff2017-05-08 15:09:02 +0200647 struct nfs42_layoutstat_res *res = data;
Trond Myklebustbe3a5d22015-06-23 19:51:55 +0800648 struct compound_hdr hdr;
649 int status, i;
650
651 status = decode_compound_hdr(xdr, &hdr);
652 if (status)
653 goto out;
654 status = decode_sequence(xdr, &res->seq_res, rqstp);
655 if (status)
656 goto out;
657 status = decode_putfh(xdr);
658 if (status)
659 goto out;
660 WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
661 for (i = 0; i < res->num_dev; i++) {
Peng Tao19cf6332015-08-26 00:13:15 +0800662 status = decode_layoutstats(xdr);
Trond Myklebustbe3a5d22015-06-23 19:51:55 +0800663 if (status)
664 goto out;
665 }
666out:
667 res->rpc_status = status;
668 return status;
669}
670
Peng Tao36022772015-09-26 02:24:34 +0800671/*
672 * Decode CLONE request
673 */
674static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp,
675 struct xdr_stream *xdr,
Christoph Hellwig18d9cff2017-05-08 15:09:02 +0200676 void *data)
Peng Tao36022772015-09-26 02:24:34 +0800677{
Christoph Hellwig18d9cff2017-05-08 15:09:02 +0200678 struct nfs42_clone_res *res = data;
Peng Tao36022772015-09-26 02:24:34 +0800679 struct compound_hdr hdr;
680 int status;
681
682 status = decode_compound_hdr(xdr, &hdr);
683 if (status)
684 goto out;
685 status = decode_sequence(xdr, &res->seq_res, rqstp);
686 if (status)
687 goto out;
688 status = decode_putfh(xdr);
689 if (status)
690 goto out;
691 status = decode_savefh(xdr);
692 if (status)
693 goto out;
694 status = decode_putfh(xdr);
695 if (status)
696 goto out;
697 status = decode_clone(xdr);
698 if (status)
699 goto out;
700 status = decode_getfattr(xdr, res->dst_fattr, res->server);
701
702out:
703 res->rpc_status = status;
704 return status;
705}
706
Anna Schumaker1c6dcbe2014-09-26 13:58:48 -0400707#endif /* __LINUX_FS_NFS_NFS4_2XDR_H */