xref: /linux/fs/nfs/nfs42xdr.c (revision e0bf6c5ca2d3281f231c5f0c9bf145e9513644de)
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 #define encode_fallocate_maxsz		(encode_stateid_maxsz + \
8 					 2 /* offset */ + \
9 					 2 /* length */)
10 #define encode_allocate_maxsz		(op_encode_hdr_maxsz + \
11 					 encode_fallocate_maxsz)
12 #define decode_allocate_maxsz		(op_decode_hdr_maxsz)
13 #define encode_deallocate_maxsz		(op_encode_hdr_maxsz + \
14 					 encode_fallocate_maxsz)
15 #define decode_deallocate_maxsz		(op_decode_hdr_maxsz)
16 #define encode_seek_maxsz		(op_encode_hdr_maxsz + \
17 					 encode_stateid_maxsz + \
18 					 2 /* offset */ + \
19 					 1 /* whence */)
20 #define decode_seek_maxsz		(op_decode_hdr_maxsz + \
21 					 1 /* eof */ + \
22 					 1 /* whence */ + \
23 					 2 /* offset */ + \
24 					 2 /* length */)
25 
26 #define NFS4_enc_allocate_sz		(compound_encode_hdr_maxsz + \
27 					 encode_putfh_maxsz + \
28 					 encode_allocate_maxsz)
29 #define NFS4_dec_allocate_sz		(compound_decode_hdr_maxsz + \
30 					 decode_putfh_maxsz + \
31 					 decode_allocate_maxsz)
32 #define NFS4_enc_deallocate_sz		(compound_encode_hdr_maxsz + \
33 					 encode_putfh_maxsz + \
34 					 encode_deallocate_maxsz)
35 #define NFS4_dec_deallocate_sz		(compound_decode_hdr_maxsz + \
36 					 decode_putfh_maxsz + \
37 					 decode_deallocate_maxsz)
38 #define NFS4_enc_seek_sz		(compound_encode_hdr_maxsz + \
39 					 encode_putfh_maxsz + \
40 					 encode_seek_maxsz)
41 #define NFS4_dec_seek_sz		(compound_decode_hdr_maxsz + \
42 					 decode_putfh_maxsz + \
43 					 decode_seek_maxsz)
44 
45 
46 static void encode_fallocate(struct xdr_stream *xdr,
47 			     struct nfs42_falloc_args *args)
48 {
49 	encode_nfs4_stateid(xdr, &args->falloc_stateid);
50 	encode_uint64(xdr, args->falloc_offset);
51 	encode_uint64(xdr, args->falloc_length);
52 }
53 
54 static void encode_allocate(struct xdr_stream *xdr,
55 			    struct nfs42_falloc_args *args,
56 			    struct compound_hdr *hdr)
57 {
58 	encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr);
59 	encode_fallocate(xdr, args);
60 }
61 
62 static void encode_deallocate(struct xdr_stream *xdr,
63 			      struct nfs42_falloc_args *args,
64 			      struct compound_hdr *hdr)
65 {
66 	encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr);
67 	encode_fallocate(xdr, args);
68 }
69 
70 static void encode_seek(struct xdr_stream *xdr,
71 			struct nfs42_seek_args *args,
72 			struct compound_hdr *hdr)
73 {
74 	encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr);
75 	encode_nfs4_stateid(xdr, &args->sa_stateid);
76 	encode_uint64(xdr, args->sa_offset);
77 	encode_uint32(xdr, args->sa_what);
78 }
79 
80 /*
81  * Encode ALLOCATE request
82  */
83 static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
84 				  struct xdr_stream *xdr,
85 				  struct nfs42_falloc_args *args)
86 {
87 	struct compound_hdr hdr = {
88 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
89 	};
90 
91 	encode_compound_hdr(xdr, req, &hdr);
92 	encode_sequence(xdr, &args->seq_args, &hdr);
93 	encode_putfh(xdr, args->falloc_fh, &hdr);
94 	encode_allocate(xdr, args, &hdr);
95 	encode_nops(&hdr);
96 }
97 
98 /*
99  * Encode DEALLOCATE request
100  */
101 static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
102 				    struct xdr_stream *xdr,
103 				    struct nfs42_falloc_args *args)
104 {
105 	struct compound_hdr hdr = {
106 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
107 	};
108 
109 	encode_compound_hdr(xdr, req, &hdr);
110 	encode_sequence(xdr, &args->seq_args, &hdr);
111 	encode_putfh(xdr, args->falloc_fh, &hdr);
112 	encode_deallocate(xdr, args, &hdr);
113 	encode_nops(&hdr);
114 }
115 
116 /*
117  * Encode SEEK request
118  */
119 static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
120 			      struct xdr_stream *xdr,
121 			      struct nfs42_seek_args *args)
122 {
123 	struct compound_hdr hdr = {
124 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
125 	};
126 
127 	encode_compound_hdr(xdr, req, &hdr);
128 	encode_sequence(xdr, &args->seq_args, &hdr);
129 	encode_putfh(xdr, args->sa_fh, &hdr);
130 	encode_seek(xdr, args, &hdr);
131 	encode_nops(&hdr);
132 }
133 
134 static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
135 {
136 	return decode_op_hdr(xdr, OP_ALLOCATE);
137 }
138 
139 static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
140 {
141 	return decode_op_hdr(xdr, OP_DEALLOCATE);
142 }
143 
144 static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
145 {
146 	int status;
147 	__be32 *p;
148 
149 	status = decode_op_hdr(xdr, OP_SEEK);
150 	if (status)
151 		return status;
152 
153 	p = xdr_inline_decode(xdr, 4 + 8);
154 	if (unlikely(!p))
155 		goto out_overflow;
156 
157 	res->sr_eof = be32_to_cpup(p++);
158 	p = xdr_decode_hyper(p, &res->sr_offset);
159 	return 0;
160 
161 out_overflow:
162 	print_overflow_msg(__func__, xdr);
163 	return -EIO;
164 }
165 
166 /*
167  * Decode ALLOCATE request
168  */
169 static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp,
170 				 struct xdr_stream *xdr,
171 				 struct nfs42_falloc_res *res)
172 {
173 	struct compound_hdr hdr;
174 	int status;
175 
176 	status = decode_compound_hdr(xdr, &hdr);
177 	if (status)
178 		goto out;
179 	status = decode_sequence(xdr, &res->seq_res, rqstp);
180 	if (status)
181 		goto out;
182 	status = decode_putfh(xdr);
183 	if (status)
184 		goto out;
185 	status = decode_allocate(xdr, res);
186 out:
187 	return status;
188 }
189 
190 /*
191  * Decode DEALLOCATE request
192  */
193 static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
194 				   struct xdr_stream *xdr,
195 				   struct nfs42_falloc_res *res)
196 {
197 	struct compound_hdr hdr;
198 	int status;
199 
200 	status = decode_compound_hdr(xdr, &hdr);
201 	if (status)
202 		goto out;
203 	status = decode_sequence(xdr, &res->seq_res, rqstp);
204 	if (status)
205 		goto out;
206 	status = decode_putfh(xdr);
207 	if (status)
208 		goto out;
209 	status = decode_deallocate(xdr, res);
210 out:
211 	return status;
212 }
213 
214 /*
215  * Decode SEEK request
216  */
217 static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp,
218 			     struct xdr_stream *xdr,
219 			     struct nfs42_seek_res *res)
220 {
221 	struct compound_hdr hdr;
222 	int status;
223 
224 	status = decode_compound_hdr(xdr, &hdr);
225 	if (status)
226 		goto out;
227 	status = decode_sequence(xdr, &res->seq_res, rqstp);
228 	if (status)
229 		goto out;
230 	status = decode_putfh(xdr);
231 	if (status)
232 		goto out;
233 	status = decode_seek(xdr, res);
234 out:
235 	return status;
236 }
237 #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */
238