aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2010-12-14 09:57:22 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-12-16 12:37:23 -0500
commita033db487eec09afde00a3562842982a8053c887 (patch)
tree8f1259105c54739e5292b55c4f77cc9b6eaafea1
parent3460f29a27344db8c7af62cafdb961286ef0b6cd (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.c255
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
53enum 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*/
85static inline __be32 *
86xdr_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
171static __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 */
194enum 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
210static 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 */
223static 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 */
241static 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
204static void 250/*
205encode_stateid(struct xdr_stream *xdr, stateid_t *sid) 251 * sessionid4
252 *
253 * typedef opaque sessionid4[NFS4_SESSIONID_SIZE];
254 */
255static 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
214static void 265/*
215encode_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*/
275static 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 */
227static void encode_cb_nops(struct nfs4_cb_compound_hdr *hdr) 292static 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
232static void 298/*
233encode_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 */
307static 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
249static void 324/*
250encode_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 */
336static 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
271static int 359/*
272nfs4_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 */
371static 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
281static int 380/*
282nfs4_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 */
383static 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}