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 | } |
