diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2010-12-14 09:57:22 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-12-16 12:37:23 -0500 |
commit | a033db487eec09afde00a3562842982a8053c887 (patch) | |
tree | 8f1259105c54739e5292b55c4f77cc9b6eaafea1 | |
parent | 3460f29a27344db8c7af62cafdb961286ef0b6cd (diff) |
NFSD: Update XDR encoders in NFSv4 callback client
Clean up.
Remove old-style NFSv4 XDR macros in favor of the style now used in
fs/nfs/nfs4xdr.c. These were forgotten during the recent nfs4xdr.c
rewrite.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Tested-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfsd/nfs4callback.c | 255 |
1 files changed, 178 insertions, 77 deletions
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 143da2eecd7b..d8148cc461e7 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c | |||
@@ -50,11 +50,6 @@ enum { | |||
50 | NFSPROC4_CLNT_CB_SEQUENCE, | 50 | NFSPROC4_CLNT_CB_SEQUENCE, |
51 | }; | 51 | }; |
52 | 52 | ||
53 | enum nfs_cb_opnum4 { | ||
54 | OP_CB_RECALL = 4, | ||
55 | OP_CB_SEQUENCE = 11, | ||
56 | }; | ||
57 | |||
58 | #define NFS4_MAXTAGLEN 20 | 53 | #define NFS4_MAXTAGLEN 20 |
59 | 54 | ||
60 | #define NFS4_enc_cb_null_sz 0 | 55 | #define NFS4_enc_cb_null_sz 0 |
@@ -80,30 +75,6 @@ enum nfs_cb_opnum4 { | |||
80 | op_dec_sz) | 75 | op_dec_sz) |
81 | 76 | ||
82 | /* | 77 | /* |
83 | * Generic encode routines from fs/nfs/nfs4xdr.c | ||
84 | */ | ||
85 | static inline __be32 * | ||
86 | xdr_writemem(__be32 *p, const void *ptr, int nbytes) | ||
87 | { | ||
88 | int tmp = XDR_QUADLEN(nbytes); | ||
89 | if (!tmp) | ||
90 | return p; | ||
91 | p[tmp-1] = 0; | ||
92 | memcpy(p, ptr, nbytes); | ||
93 | return p + tmp; | ||
94 | } | ||
95 | |||
96 | #define WRITE32(n) *p++ = htonl(n) | ||
97 | #define WRITEMEM(ptr,nbytes) do { \ | ||
98 | p = xdr_writemem(p, ptr, nbytes); \ | ||
99 | } while (0) | ||
100 | #define RESERVE_SPACE(nbytes) do { \ | ||
101 | p = xdr_reserve_space(xdr, nbytes); \ | ||
102 | if (!p) dprintk("NFSD: RESERVE_SPACE(%d) failed in function %s\n", (int) (nbytes), __func__); \ | ||
103 | BUG_ON(!p); \ | ||
104 | } while (0) | ||
105 | |||
106 | /* | ||
107 | * Generic decode routines from fs/nfs/nfs4xdr.c | 78 | * Generic decode routines from fs/nfs/nfs4xdr.c |
108 | */ | 79 | */ |
109 | #define DECODE_TAIL \ | 80 | #define DECODE_TAIL \ |
@@ -197,102 +168,232 @@ nfs_cb_stat_to_errno(int stat) | |||
197 | return stat; | 168 | return stat; |
198 | } | 169 | } |
199 | 170 | ||
171 | static __be32 *xdr_encode_empty_array(__be32 *p) | ||
172 | { | ||
173 | *p++ = xdr_zero; | ||
174 | return p; | ||
175 | } | ||
176 | |||
177 | /* | ||
178 | * Encode/decode NFSv4 CB basic data types | ||
179 | * | ||
180 | * Basic NFSv4 callback data types are defined in section 15 of RFC | ||
181 | * 3530: "Network File System (NFS) version 4 Protocol" and section | ||
182 | * 20 of RFC 5661: "Network File System (NFS) Version 4 Minor Version | ||
183 | * 1 Protocol" | ||
184 | */ | ||
185 | |||
186 | /* | ||
187 | * nfs_cb_opnum4 | ||
188 | * | ||
189 | * enum nfs_cb_opnum4 { | ||
190 | * OP_CB_GETATTR = 3, | ||
191 | * ... | ||
192 | * }; | ||
193 | */ | ||
194 | enum nfs_cb_opnum4 { | ||
195 | OP_CB_GETATTR = 3, | ||
196 | OP_CB_RECALL = 4, | ||
197 | OP_CB_LAYOUTRECALL = 5, | ||
198 | OP_CB_NOTIFY = 6, | ||
199 | OP_CB_PUSH_DELEG = 7, | ||
200 | OP_CB_RECALL_ANY = 8, | ||
201 | OP_CB_RECALLABLE_OBJ_AVAIL = 9, | ||
202 | OP_CB_RECALL_SLOT = 10, | ||
203 | OP_CB_SEQUENCE = 11, | ||
204 | OP_CB_WANTS_CANCELLED = 12, | ||
205 | OP_CB_NOTIFY_LOCK = 13, | ||
206 | OP_CB_NOTIFY_DEVICEID = 14, | ||
207 | OP_CB_ILLEGAL = 10044 | ||
208 | }; | ||
209 | |||
210 | static void encode_nfs_cb_opnum4(struct xdr_stream *xdr, enum nfs_cb_opnum4 op) | ||
211 | { | ||
212 | __be32 *p; | ||
213 | |||
214 | p = xdr_reserve_space(xdr, 4); | ||
215 | *p = cpu_to_be32(op); | ||
216 | } | ||
217 | |||
218 | /* | ||
219 | * nfs_fh4 | ||
220 | * | ||
221 | * typedef opaque nfs_fh4<NFS4_FHSIZE>; | ||
222 | */ | ||
223 | static void encode_nfs_fh4(struct xdr_stream *xdr, const struct knfsd_fh *fh) | ||
224 | { | ||
225 | u32 length = fh->fh_size; | ||
226 | __be32 *p; | ||
227 | |||
228 | BUG_ON(length > NFS4_FHSIZE); | ||
229 | p = xdr_reserve_space(xdr, 4 + length); | ||
230 | xdr_encode_opaque(p, &fh->fh_base, length); | ||
231 | } | ||
232 | |||
200 | /* | 233 | /* |
201 | * XDR encode | 234 | * stateid4 |
235 | * | ||
236 | * struct stateid4 { | ||
237 | * uint32_t seqid; | ||
238 | * opaque other[12]; | ||
239 | * }; | ||
202 | */ | 240 | */ |
241 | static void encode_stateid4(struct xdr_stream *xdr, const stateid_t *sid) | ||
242 | { | ||
243 | __be32 *p; | ||
244 | |||
245 | p = xdr_reserve_space(xdr, NFS4_STATEID_SIZE); | ||
246 | *p++ = cpu_to_be32(sid->si_generation); | ||
247 | xdr_encode_opaque_fixed(p, &sid->si_opaque, NFS4_STATEID_OTHER_SIZE); | ||
248 | } | ||
203 | 249 | ||
204 | static void | 250 | /* |
205 | encode_stateid(struct xdr_stream *xdr, stateid_t *sid) | 251 | * sessionid4 |
252 | * | ||
253 | * typedef opaque sessionid4[NFS4_SESSIONID_SIZE]; | ||
254 | */ | ||
255 | static void encode_sessionid4(struct xdr_stream *xdr, | ||
256 | const struct nfsd4_session *session) | ||
206 | { | 257 | { |
207 | __be32 *p; | 258 | __be32 *p; |
208 | 259 | ||
209 | RESERVE_SPACE(sizeof(stateid_t)); | 260 | p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN); |
210 | WRITE32(sid->si_generation); | 261 | xdr_encode_opaque_fixed(p, session->se_sessionid.data, |
211 | WRITEMEM(&sid->si_opaque, sizeof(stateid_opaque_t)); | 262 | NFS4_MAX_SESSIONID_LEN); |
212 | } | 263 | } |
213 | 264 | ||
214 | static void | 265 | /* |
215 | encode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr) | 266 | * CB_COMPOUND4args |
267 | * | ||
268 | * struct CB_COMPOUND4args { | ||
269 | * utf8str_cs tag; | ||
270 | * uint32_t minorversion; | ||
271 | * uint32_t callback_ident; | ||
272 | * nfs_cb_argop4 argarray<>; | ||
273 | * }; | ||
274 | */ | ||
275 | static void encode_cb_compound4args(struct xdr_stream *xdr, | ||
276 | struct nfs4_cb_compound_hdr *hdr) | ||
216 | { | 277 | { |
217 | __be32 * p; | 278 | __be32 * p; |
218 | 279 | ||
219 | RESERVE_SPACE(16); | 280 | p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4); |
220 | WRITE32(0); /* tag length is always 0 */ | 281 | p = xdr_encode_empty_array(p); /* empty tag */ |
221 | WRITE32(hdr->minorversion); | 282 | *p++ = cpu_to_be32(hdr->minorversion); |
222 | WRITE32(hdr->ident); | 283 | *p++ = cpu_to_be32(hdr->ident); |
284 | |||
223 | hdr->nops_p = p; | 285 | hdr->nops_p = p; |
224 | WRITE32(hdr->nops); | 286 | *p = cpu_to_be32(hdr->nops); /* argarray element count */ |
225 | } | 287 | } |
226 | 288 | ||
289 | /* | ||
290 | * Update argarray element count | ||
291 | */ | ||
227 | static void encode_cb_nops(struct nfs4_cb_compound_hdr *hdr) | 292 | static void encode_cb_nops(struct nfs4_cb_compound_hdr *hdr) |
228 | { | 293 | { |
229 | *hdr->nops_p = htonl(hdr->nops); | 294 | BUG_ON(hdr->nops > NFS4_MAX_BACK_CHANNEL_OPS); |
295 | *hdr->nops_p = cpu_to_be32(hdr->nops); | ||
230 | } | 296 | } |
231 | 297 | ||
232 | static void | 298 | /* |
233 | encode_cb_recall(struct xdr_stream *xdr, struct nfs4_delegation *dp, | 299 | * CB_RECALL4args |
234 | struct nfs4_cb_compound_hdr *hdr) | 300 | * |
301 | * struct CB_RECALL4args { | ||
302 | * stateid4 stateid; | ||
303 | * bool truncate; | ||
304 | * nfs_fh4 fh; | ||
305 | * }; | ||
306 | */ | ||
307 | static void encode_cb_recall4args(struct xdr_stream *xdr, | ||
308 | const struct nfs4_delegation *dp, | ||
309 | struct nfs4_cb_compound_hdr *hdr) | ||
235 | { | 310 | { |
236 | __be32 *p; | 311 | __be32 *p; |
237 | int len = dp->dl_fh.fh_size; | 312 | |
238 | 313 | encode_nfs_cb_opnum4(xdr, OP_CB_RECALL); | |
239 | RESERVE_SPACE(4); | 314 | encode_stateid4(xdr, &dp->dl_stateid); |
240 | WRITE32(OP_CB_RECALL); | 315 | |
241 | encode_stateid(xdr, &dp->dl_stateid); | 316 | p = xdr_reserve_space(xdr, 4); |
242 | RESERVE_SPACE(8 + (XDR_QUADLEN(len) << 2)); | 317 | *p++ = xdr_zero; /* truncate */ |
243 | WRITE32(0); /* truncate optimization not implemented */ | 318 | |
244 | WRITE32(len); | 319 | encode_nfs_fh4(xdr, &dp->dl_fh); |
245 | WRITEMEM(&dp->dl_fh.fh_base, len); | 320 | |
246 | hdr->nops++; | 321 | hdr->nops++; |
247 | } | 322 | } |
248 | 323 | ||
249 | static void | 324 | /* |
250 | encode_cb_sequence(struct xdr_stream *xdr, struct nfsd4_callback *cb, | 325 | * CB_SEQUENCE4args |
251 | struct nfs4_cb_compound_hdr *hdr) | 326 | * |
327 | * struct CB_SEQUENCE4args { | ||
328 | * sessionid4 csa_sessionid; | ||
329 | * sequenceid4 csa_sequenceid; | ||
330 | * slotid4 csa_slotid; | ||
331 | * slotid4 csa_highest_slotid; | ||
332 | * bool csa_cachethis; | ||
333 | * referring_call_list4 csa_referring_call_lists<>; | ||
334 | * }; | ||
335 | */ | ||
336 | static void encode_cb_sequence4args(struct xdr_stream *xdr, | ||
337 | const struct nfsd4_callback *cb, | ||
338 | struct nfs4_cb_compound_hdr *hdr) | ||
252 | { | 339 | { |
340 | struct nfsd4_session *session = cb->cb_clp->cl_cb_session; | ||
253 | __be32 *p; | 341 | __be32 *p; |
254 | struct nfsd4_session *ses = cb->cb_clp->cl_cb_session; | ||
255 | 342 | ||
256 | if (hdr->minorversion == 0) | 343 | if (hdr->minorversion == 0) |
257 | return; | 344 | return; |
258 | 345 | ||
259 | RESERVE_SPACE(1 + NFS4_MAX_SESSIONID_LEN + 20); | 346 | encode_nfs_cb_opnum4(xdr, OP_CB_SEQUENCE); |
347 | encode_sessionid4(xdr, session); | ||
348 | |||
349 | p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4 + 4); | ||
350 | *p++ = cpu_to_be32(session->se_cb_seq_nr); /* csa_sequenceid */ | ||
351 | *p++ = xdr_zero; /* csa_slotid */ | ||
352 | *p++ = xdr_zero; /* csa_highest_slotid */ | ||
353 | *p++ = xdr_zero; /* csa_cachethis */ | ||
354 | xdr_encode_empty_array(p); /* csa_referring_call_lists */ | ||
260 | 355 | ||
261 | WRITE32(OP_CB_SEQUENCE); | ||
262 | WRITEMEM(ses->se_sessionid.data, NFS4_MAX_SESSIONID_LEN); | ||
263 | WRITE32(ses->se_cb_seq_nr); | ||
264 | WRITE32(0); /* slotid, always 0 */ | ||
265 | WRITE32(0); /* highest slotid always 0 */ | ||
266 | WRITE32(0); /* cachethis always 0 */ | ||
267 | WRITE32(0); /* FIXME: support referring_call_lists */ | ||
268 | hdr->nops++; | 356 | hdr->nops++; |
269 | } | 357 | } |
270 | 358 | ||
271 | static int | 359 | /* |
272 | nfs4_xdr_enc_cb_null(struct rpc_rqst *req, __be32 *p) | 360 | * NFSv4.0 and NFSv4.1 XDR encode functions |
361 | * | ||
362 | * NFSv4.0 callback argument types are defined in section 15 of RFC | ||
363 | * 3530: "Network File System (NFS) version 4 Protocol" and section 20 | ||
364 | * of RFC 5661: "Network File System (NFS) Version 4 Minor Version 1 | ||
365 | * Protocol". | ||
366 | */ | ||
367 | |||
368 | /* | ||
369 | * NB: Without this zero space reservation, callbacks over krb5p fail | ||
370 | */ | ||
371 | static int nfs4_xdr_enc_cb_null(struct rpc_rqst *req, __be32 *p, void *__unused) | ||
273 | { | 372 | { |
274 | struct xdr_stream xdrs, *xdr = &xdrs; | 373 | struct xdr_stream xdrs, *xdr = &xdrs; |
275 | 374 | ||
276 | xdr_init_encode(&xdrs, &req->rq_snd_buf, p); | 375 | xdr_init_encode(&xdrs, &req->rq_snd_buf, p); |
277 | RESERVE_SPACE(0); | 376 | xdr_reserve_space(xdr, 0); |
278 | return 0; | 377 | return 0; |
279 | } | 378 | } |
280 | 379 | ||
281 | static int | 380 | /* |
282 | nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, __be32 *p, | 381 | * 20.2. Operation 4: CB_RECALL - Recall a Delegation |
283 | struct nfsd4_callback *cb) | 382 | */ |
383 | static int nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, __be32 *p, | ||
384 | const struct nfsd4_callback *cb) | ||
284 | { | 385 | { |
285 | struct xdr_stream xdr; | 386 | struct xdr_stream xdr; |
286 | struct nfs4_delegation *args = cb->cb_op; | 387 | const struct nfs4_delegation *args = cb->cb_op; |
287 | struct nfs4_cb_compound_hdr hdr = { | 388 | struct nfs4_cb_compound_hdr hdr = { |
288 | .ident = cb->cb_clp->cl_cb_ident, | 389 | .ident = cb->cb_clp->cl_cb_ident, |
289 | .minorversion = cb->cb_minorversion, | 390 | .minorversion = cb->cb_minorversion, |
290 | }; | 391 | }; |
291 | 392 | ||
292 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 393 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); |
293 | encode_cb_compound_hdr(&xdr, &hdr); | 394 | encode_cb_compound4args(&xdr, &hdr); |
294 | encode_cb_sequence(&xdr, cb, &hdr); | 395 | encode_cb_sequence4args(&xdr, cb, &hdr); |
295 | encode_cb_recall(&xdr, args, &hdr); | 396 | encode_cb_recall4args(&xdr, args, &hdr); |
296 | encode_cb_nops(&hdr); | 397 | encode_cb_nops(&hdr); |
297 | return 0; | 398 | return 0; |
298 | } | 399 | } |