1 /* 2 * Copyright (c) 2001 The Regents of the University of Michigan. 3 * All rights reserved. 4 * 5 * Kendrick Smith <kmsmith@umich.edu> 6 * Andy Adamson <andros@umich.edu> 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the University nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 28 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <linux/sunrpc/clnt.h> 35 #include <linux/sunrpc/svc_xprt.h> 36 #include <linux/slab.h> 37 #include "nfsd.h" 38 #include "state.h" 39 40 #define NFSDDBG_FACILITY NFSDDBG_PROC 41 42 #define NFSPROC4_CB_NULL 0 43 #define NFSPROC4_CB_COMPOUND 1 44 #define NFS4_STATEID_SIZE 16 45 46 /* Index of predefined Linux callback client operations */ 47 48 enum { 49 NFSPROC4_CLNT_CB_NULL = 0, 50 NFSPROC4_CLNT_CB_RECALL, 51 NFSPROC4_CLNT_CB_SEQUENCE, 52 }; 53 54 enum nfs_cb_opnum4 { 55 OP_CB_RECALL = 4, 56 OP_CB_SEQUENCE = 11, 57 }; 58 59 #define NFS4_MAXTAGLEN 20 60 61 #define NFS4_enc_cb_null_sz 0 62 #define NFS4_dec_cb_null_sz 0 63 #define cb_compound_enc_hdr_sz 4 64 #define cb_compound_dec_hdr_sz (3 + (NFS4_MAXTAGLEN >> 2)) 65 #define sessionid_sz (NFS4_MAX_SESSIONID_LEN >> 2) 66 #define cb_sequence_enc_sz (sessionid_sz + 4 + \ 67 1 /* no referring calls list yet */) 68 #define cb_sequence_dec_sz (op_dec_sz + sessionid_sz + 4) 69 70 #define op_enc_sz 1 71 #define op_dec_sz 2 72 #define enc_nfs4_fh_sz (1 + (NFS4_FHSIZE >> 2)) 73 #define enc_stateid_sz (NFS4_STATEID_SIZE >> 2) 74 #define NFS4_enc_cb_recall_sz (cb_compound_enc_hdr_sz + \ 75 cb_sequence_enc_sz + \ 76 1 + enc_stateid_sz + \ 77 enc_nfs4_fh_sz) 78 79 #define NFS4_dec_cb_recall_sz (cb_compound_dec_hdr_sz + \ 80 cb_sequence_dec_sz + \ 81 op_dec_sz) 82 83 /* 84 * Generic encode routines from fs/nfs/nfs4xdr.c 85 */ 86 static inline __be32 * 87 xdr_writemem(__be32 *p, const void *ptr, int nbytes) 88 { 89 int tmp = XDR_QUADLEN(nbytes); 90 if (!tmp) 91 return p; 92 p[tmp-1] = 0; 93 memcpy(p, ptr, nbytes); 94 return p + tmp; 95 } 96 97 #define WRITE32(n) *p++ = htonl(n) 98 #define WRITEMEM(ptr,nbytes) do { \ 99 p = xdr_writemem(p, ptr, nbytes); \ 100 } while (0) 101 #define RESERVE_SPACE(nbytes) do { \ 102 p = xdr_reserve_space(xdr, nbytes); \ 103 if (!p) dprintk("NFSD: RESERVE_SPACE(%d) failed in function %s\n", (int) (nbytes), __func__); \ 104 BUG_ON(!p); \ 105 } while (0) 106 107 /* 108 * Generic decode routines from fs/nfs/nfs4xdr.c 109 */ 110 #define DECODE_TAIL \ 111 status = 0; \ 112 out: \ 113 return status; \ 114 xdr_error: \ 115 dprintk("NFSD: xdr error! (%s:%d)\n", __FILE__, __LINE__); \ 116 status = -EIO; \ 117 goto out 118 119 #define READ32(x) (x) = ntohl(*p++) 120 #define READ64(x) do { \ 121 (x) = (u64)ntohl(*p++) << 32; \ 122 (x) |= ntohl(*p++); \ 123 } while (0) 124 #define READTIME(x) do { \ 125 p++; \ 126 (x.tv_sec) = ntohl(*p++); \ 127 (x.tv_nsec) = ntohl(*p++); \ 128 } while (0) 129 #define READ_BUF(nbytes) do { \ 130 p = xdr_inline_decode(xdr, nbytes); \ 131 if (!p) { \ 132 dprintk("NFSD: %s: reply buffer overflowed in line %d.\n", \ 133 __func__, __LINE__); \ 134 return -EIO; \ 135 } \ 136 } while (0) 137 138 struct nfs4_cb_compound_hdr { 139 /* args */ 140 u32 ident; /* minorversion 0 only */ 141 u32 nops; 142 __be32 *nops_p; 143 u32 minorversion; 144 /* res */ 145 int status; 146 u32 taglen; 147 char *tag; 148 }; 149 150 static struct { 151 int stat; 152 int errno; 153 } nfs_cb_errtbl[] = { 154 { NFS4_OK, 0 }, 155 { NFS4ERR_PERM, EPERM }, 156 { NFS4ERR_NOENT, ENOENT }, 157 { NFS4ERR_IO, EIO }, 158 { NFS4ERR_NXIO, ENXIO }, 159 { NFS4ERR_ACCESS, EACCES }, 160 { NFS4ERR_EXIST, EEXIST }, 161 { NFS4ERR_XDEV, EXDEV }, 162 { NFS4ERR_NOTDIR, ENOTDIR }, 163 { NFS4ERR_ISDIR, EISDIR }, 164 { NFS4ERR_INVAL, EINVAL }, 165 { NFS4ERR_FBIG, EFBIG }, 166 { NFS4ERR_NOSPC, ENOSPC }, 167 { NFS4ERR_ROFS, EROFS }, 168 { NFS4ERR_MLINK, EMLINK }, 169 { NFS4ERR_NAMETOOLONG, ENAMETOOLONG }, 170 { NFS4ERR_NOTEMPTY, ENOTEMPTY }, 171 { NFS4ERR_DQUOT, EDQUOT }, 172 { NFS4ERR_STALE, ESTALE }, 173 { NFS4ERR_BADHANDLE, EBADHANDLE }, 174 { NFS4ERR_BAD_COOKIE, EBADCOOKIE }, 175 { NFS4ERR_NOTSUPP, ENOTSUPP }, 176 { NFS4ERR_TOOSMALL, ETOOSMALL }, 177 { NFS4ERR_SERVERFAULT, ESERVERFAULT }, 178 { NFS4ERR_BADTYPE, EBADTYPE }, 179 { NFS4ERR_LOCKED, EAGAIN }, 180 { NFS4ERR_RESOURCE, EREMOTEIO }, 181 { NFS4ERR_SYMLINK, ELOOP }, 182 { NFS4ERR_OP_ILLEGAL, EOPNOTSUPP }, 183 { NFS4ERR_DEADLOCK, EDEADLK }, 184 { -1, EIO } 185 }; 186 187 static int 188 nfs_cb_stat_to_errno(int stat) 189 { 190 int i; 191 for (i = 0; nfs_cb_errtbl[i].stat != -1; i++) { 192 if (nfs_cb_errtbl[i].stat == stat) 193 return nfs_cb_errtbl[i].errno; 194 } 195 /* If we cannot translate the error, the recovery routines should 196 * handle it. 197 * Note: remaining NFSv4 error codes have values > 10000, so should 198 * not conflict with native Linux error codes. 199 */ 200 return stat; 201 } 202 203 /* 204 * XDR encode 205 */ 206 207 static void 208 encode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr) 209 { 210 __be32 * p; 211 212 RESERVE_SPACE(16); 213 WRITE32(0); /* tag length is always 0 */ 214 WRITE32(hdr->minorversion); 215 WRITE32(hdr->ident); 216 hdr->nops_p = p; 217 WRITE32(hdr->nops); 218 } 219 220 static void encode_cb_nops(struct nfs4_cb_compound_hdr *hdr) 221 { 222 *hdr->nops_p = htonl(hdr->nops); 223 } 224 225 static void 226 encode_cb_recall(struct xdr_stream *xdr, struct nfs4_delegation *dp, 227 struct nfs4_cb_compound_hdr *hdr) 228 { 229 __be32 *p; 230 int len = dp->dl_fh.fh_size; 231 232 RESERVE_SPACE(12+sizeof(dp->dl_stateid) + len); 233 WRITE32(OP_CB_RECALL); 234 WRITE32(dp->dl_stateid.si_generation); 235 WRITEMEM(&dp->dl_stateid.si_opaque, sizeof(stateid_opaque_t)); 236 WRITE32(0); /* truncate optimization not implemented */ 237 WRITE32(len); 238 WRITEMEM(&dp->dl_fh.fh_base, len); 239 hdr->nops++; 240 } 241 242 static void 243 encode_cb_sequence(struct xdr_stream *xdr, struct nfsd4_cb_sequence *args, 244 struct nfs4_cb_compound_hdr *hdr) 245 { 246 __be32 *p; 247 248 if (hdr->minorversion == 0) 249 return; 250 251 RESERVE_SPACE(1 + NFS4_MAX_SESSIONID_LEN + 20); 252 253 WRITE32(OP_CB_SEQUENCE); 254 WRITEMEM(args->cbs_clp->cl_sessionid.data, NFS4_MAX_SESSIONID_LEN); 255 WRITE32(args->cbs_clp->cl_cb_seq_nr); 256 WRITE32(0); /* slotid, always 0 */ 257 WRITE32(0); /* highest slotid always 0 */ 258 WRITE32(0); /* cachethis always 0 */ 259 WRITE32(0); /* FIXME: support referring_call_lists */ 260 hdr->nops++; 261 } 262 263 static int 264 nfs4_xdr_enc_cb_null(struct rpc_rqst *req, __be32 *p) 265 { 266 struct xdr_stream xdrs, *xdr = &xdrs; 267 268 xdr_init_encode(&xdrs, &req->rq_snd_buf, p); 269 RESERVE_SPACE(0); 270 return 0; 271 } 272 273 static int 274 nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, __be32 *p, 275 struct nfs4_rpc_args *rpc_args) 276 { 277 struct xdr_stream xdr; 278 struct nfs4_delegation *args = rpc_args->args_op; 279 struct nfs4_cb_compound_hdr hdr = { 280 .ident = args->dl_ident, 281 .minorversion = rpc_args->args_seq.cbs_minorversion, 282 }; 283 284 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 285 encode_cb_compound_hdr(&xdr, &hdr); 286 encode_cb_sequence(&xdr, &rpc_args->args_seq, &hdr); 287 encode_cb_recall(&xdr, args, &hdr); 288 encode_cb_nops(&hdr); 289 return 0; 290 } 291 292 293 static int 294 decode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr){ 295 __be32 *p; 296 297 READ_BUF(8); 298 READ32(hdr->status); 299 READ32(hdr->taglen); 300 READ_BUF(hdr->taglen + 4); 301 hdr->tag = (char *)p; 302 p += XDR_QUADLEN(hdr->taglen); 303 READ32(hdr->nops); 304 return 0; 305 } 306 307 static int 308 decode_cb_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) 309 { 310 __be32 *p; 311 u32 op; 312 int32_t nfserr; 313 314 READ_BUF(8); 315 READ32(op); 316 if (op != expected) { 317 dprintk("NFSD: decode_cb_op_hdr: Callback server returned " 318 " operation %d but we issued a request for %d\n", 319 op, expected); 320 return -EIO; 321 } 322 READ32(nfserr); 323 if (nfserr != NFS_OK) 324 return -nfs_cb_stat_to_errno(nfserr); 325 return 0; 326 } 327 328 /* 329 * Our current back channel implmentation supports a single backchannel 330 * with a single slot. 331 */ 332 static int 333 decode_cb_sequence(struct xdr_stream *xdr, struct nfsd4_cb_sequence *res, 334 struct rpc_rqst *rqstp) 335 { 336 struct nfs4_sessionid id; 337 int status; 338 u32 dummy; 339 __be32 *p; 340 341 if (res->cbs_minorversion == 0) 342 return 0; 343 344 status = decode_cb_op_hdr(xdr, OP_CB_SEQUENCE); 345 if (status) 346 return status; 347 348 /* 349 * If the server returns different values for sessionID, slotID or 350 * sequence number, the server is looney tunes. 351 */ 352 status = -ESERVERFAULT; 353 354 READ_BUF(NFS4_MAX_SESSIONID_LEN + 16); 355 memcpy(id.data, p, NFS4_MAX_SESSIONID_LEN); 356 p += XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN); 357 if (memcmp(id.data, res->cbs_clp->cl_sessionid.data, 358 NFS4_MAX_SESSIONID_LEN)) { 359 dprintk("%s Invalid session id\n", __func__); 360 goto out; 361 } 362 READ32(dummy); 363 if (dummy != res->cbs_clp->cl_cb_seq_nr) { 364 dprintk("%s Invalid sequence number\n", __func__); 365 goto out; 366 } 367 READ32(dummy); /* slotid must be 0 */ 368 if (dummy != 0) { 369 dprintk("%s Invalid slotid\n", __func__); 370 goto out; 371 } 372 /* FIXME: process highest slotid and target highest slotid */ 373 status = 0; 374 out: 375 return status; 376 } 377 378 379 static int 380 nfs4_xdr_dec_cb_null(struct rpc_rqst *req, __be32 *p) 381 { 382 return 0; 383 } 384 385 static int 386 nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp, __be32 *p, 387 struct nfsd4_cb_sequence *seq) 388 { 389 struct xdr_stream xdr; 390 struct nfs4_cb_compound_hdr hdr; 391 int status; 392 393 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 394 status = decode_cb_compound_hdr(&xdr, &hdr); 395 if (status) 396 goto out; 397 if (seq) { 398 status = decode_cb_sequence(&xdr, seq, rqstp); 399 if (status) 400 goto out; 401 } 402 status = decode_cb_op_hdr(&xdr, OP_CB_RECALL); 403 out: 404 return status; 405 } 406 407 /* 408 * RPC procedure tables 409 */ 410 #define PROC(proc, call, argtype, restype) \ 411 [NFSPROC4_CLNT_##proc] = { \ 412 .p_proc = NFSPROC4_CB_##call, \ 413 .p_encode = (kxdrproc_t) nfs4_xdr_##argtype, \ 414 .p_decode = (kxdrproc_t) nfs4_xdr_##restype, \ 415 .p_arglen = NFS4_##argtype##_sz, \ 416 .p_replen = NFS4_##restype##_sz, \ 417 .p_statidx = NFSPROC4_CB_##call, \ 418 .p_name = #proc, \ 419 } 420 421 static struct rpc_procinfo nfs4_cb_procedures[] = { 422 PROC(CB_NULL, NULL, enc_cb_null, dec_cb_null), 423 PROC(CB_RECALL, COMPOUND, enc_cb_recall, dec_cb_recall), 424 }; 425 426 static struct rpc_version nfs_cb_version4 = { 427 /* 428 * Note on the callback rpc program version number: despite language in rfc 429 * 5661 section 18.36.3 requiring servers to use 4 in this field, the 430 * official xdr descriptions for both 4.0 and 4.1 specify version 1, and 431 * in practice that appears to be what implementations use. The section 432 * 18.36.3 language is expected to be fixed in an erratum. 433 */ 434 .number = 1, 435 .nrprocs = ARRAY_SIZE(nfs4_cb_procedures), 436 .procs = nfs4_cb_procedures 437 }; 438 439 static struct rpc_version * nfs_cb_version[] = { 440 &nfs_cb_version4, 441 }; 442 443 static struct rpc_program cb_program; 444 445 static struct rpc_stat cb_stats = { 446 .program = &cb_program 447 }; 448 449 #define NFS4_CALLBACK 0x40000000 450 static struct rpc_program cb_program = { 451 .name = "nfs4_cb", 452 .number = NFS4_CALLBACK, 453 .nrvers = ARRAY_SIZE(nfs_cb_version), 454 .version = nfs_cb_version, 455 .stats = &cb_stats, 456 .pipe_dir_name = "/nfsd4_cb", 457 }; 458 459 static int max_cb_time(void) 460 { 461 return max(nfsd4_lease/10, (time_t)1) * HZ; 462 } 463 464 /* Reference counting, callback cleanup, etc., all look racy as heck. 465 * And why is cl_cb_set an atomic? */ 466 467 int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *cb) 468 { 469 struct rpc_timeout timeparms = { 470 .to_initval = max_cb_time(), 471 .to_retries = 0, 472 }; 473 struct rpc_create_args args = { 474 .protocol = XPRT_TRANSPORT_TCP, 475 .address = (struct sockaddr *) &cb->cb_addr, 476 .addrsize = cb->cb_addrlen, 477 .timeout = &timeparms, 478 .program = &cb_program, 479 .prognumber = cb->cb_prog, 480 .version = 0, 481 .authflavor = clp->cl_flavor, 482 .flags = (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET), 483 .client_name = clp->cl_principal, 484 }; 485 struct rpc_clnt *client; 486 487 if (!clp->cl_principal && (clp->cl_flavor >= RPC_AUTH_GSS_KRB5)) 488 return -EINVAL; 489 if (cb->cb_minorversion) { 490 args.bc_xprt = cb->cb_xprt; 491 args.protocol = XPRT_TRANSPORT_BC_TCP; 492 } 493 /* Create RPC client */ 494 client = rpc_create(&args); 495 if (IS_ERR(client)) { 496 dprintk("NFSD: couldn't create callback client: %ld\n", 497 PTR_ERR(client)); 498 return PTR_ERR(client); 499 } 500 nfsd4_set_callback_client(clp, client); 501 return 0; 502 503 } 504 505 static void warn_no_callback_path(struct nfs4_client *clp, int reason) 506 { 507 dprintk("NFSD: warning: no callback path to client %.*s: error %d\n", 508 (int)clp->cl_name.len, clp->cl_name.data, reason); 509 } 510 511 static void nfsd4_cb_probe_done(struct rpc_task *task, void *calldata) 512 { 513 struct nfs4_client *clp = calldata; 514 515 if (task->tk_status) 516 warn_no_callback_path(clp, task->tk_status); 517 else 518 atomic_set(&clp->cl_cb_set, 1); 519 } 520 521 static const struct rpc_call_ops nfsd4_cb_probe_ops = { 522 .rpc_call_done = nfsd4_cb_probe_done, 523 }; 524 525 static struct rpc_cred *callback_cred; 526 527 int set_callback_cred(void) 528 { 529 if (callback_cred) 530 return 0; 531 callback_cred = rpc_lookup_machine_cred(); 532 if (!callback_cred) 533 return -ENOMEM; 534 return 0; 535 } 536 537 538 void do_probe_callback(struct nfs4_client *clp) 539 { 540 struct rpc_message msg = { 541 .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL], 542 .rpc_argp = clp, 543 .rpc_cred = callback_cred 544 }; 545 int status; 546 547 status = rpc_call_async(clp->cl_cb_client, &msg, 548 RPC_TASK_SOFT | RPC_TASK_SOFTCONN, 549 &nfsd4_cb_probe_ops, (void *)clp); 550 if (status) 551 warn_no_callback_path(clp, status); 552 } 553 554 /* 555 * Set up the callback client and put a NFSPROC4_CB_NULL on the wire... 556 */ 557 void nfsd4_probe_callback(struct nfs4_client *clp, struct nfs4_cb_conn *cb) 558 { 559 int status; 560 561 BUG_ON(atomic_read(&clp->cl_cb_set)); 562 563 status = setup_callback_client(clp, cb); 564 if (status) { 565 warn_no_callback_path(clp, status); 566 return; 567 } 568 do_probe_callback(clp); 569 } 570 571 /* 572 * There's currently a single callback channel slot. 573 * If the slot is available, then mark it busy. Otherwise, set the 574 * thread for sleeping on the callback RPC wait queue. 575 */ 576 static int nfsd41_cb_setup_sequence(struct nfs4_client *clp, 577 struct rpc_task *task) 578 { 579 struct nfs4_rpc_args *args = task->tk_msg.rpc_argp; 580 u32 *ptr = (u32 *)clp->cl_sessionid.data; 581 int status = 0; 582 583 dprintk("%s: %u:%u:%u:%u\n", __func__, 584 ptr[0], ptr[1], ptr[2], ptr[3]); 585 586 if (test_and_set_bit(0, &clp->cl_cb_slot_busy) != 0) { 587 rpc_sleep_on(&clp->cl_cb_waitq, task, NULL); 588 dprintk("%s slot is busy\n", __func__); 589 status = -EAGAIN; 590 goto out; 591 } 592 593 /* 594 * We'll need the clp during XDR encoding and decoding, 595 * and the sequence during decoding to verify the reply 596 */ 597 args->args_seq.cbs_clp = clp; 598 task->tk_msg.rpc_resp = &args->args_seq; 599 600 out: 601 dprintk("%s status=%d\n", __func__, status); 602 return status; 603 } 604 605 /* 606 * TODO: cb_sequence should support referring call lists, cachethis, multiple 607 * slots, and mark callback channel down on communication errors. 608 */ 609 static void nfsd4_cb_prepare(struct rpc_task *task, void *calldata) 610 { 611 struct nfs4_delegation *dp = calldata; 612 struct nfs4_client *clp = dp->dl_client; 613 struct nfs4_rpc_args *args = task->tk_msg.rpc_argp; 614 u32 minorversion = clp->cl_cb_conn.cb_minorversion; 615 int status = 0; 616 617 args->args_seq.cbs_minorversion = minorversion; 618 if (minorversion) { 619 status = nfsd41_cb_setup_sequence(clp, task); 620 if (status) { 621 if (status != -EAGAIN) { 622 /* terminate rpc task */ 623 task->tk_status = status; 624 task->tk_action = NULL; 625 } 626 return; 627 } 628 } 629 rpc_call_start(task); 630 } 631 632 static void nfsd4_cb_done(struct rpc_task *task, void *calldata) 633 { 634 struct nfs4_delegation *dp = calldata; 635 struct nfs4_client *clp = dp->dl_client; 636 637 dprintk("%s: minorversion=%d\n", __func__, 638 clp->cl_cb_conn.cb_minorversion); 639 640 if (clp->cl_cb_conn.cb_minorversion) { 641 /* No need for lock, access serialized in nfsd4_cb_prepare */ 642 ++clp->cl_cb_seq_nr; 643 clear_bit(0, &clp->cl_cb_slot_busy); 644 rpc_wake_up_next(&clp->cl_cb_waitq); 645 dprintk("%s: freed slot, new seqid=%d\n", __func__, 646 clp->cl_cb_seq_nr); 647 648 /* We're done looking into the sequence information */ 649 task->tk_msg.rpc_resp = NULL; 650 } 651 } 652 653 654 static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata) 655 { 656 struct nfs4_delegation *dp = calldata; 657 struct nfs4_client *clp = dp->dl_client; 658 struct rpc_clnt *current_rpc_client = clp->cl_cb_client; 659 660 nfsd4_cb_done(task, calldata); 661 662 if (current_rpc_client == NULL) { 663 /* We're shutting down; give up. */ 664 /* XXX: err, or is it ok just to fall through 665 * and rpc_restart_call? */ 666 return; 667 } 668 669 switch (task->tk_status) { 670 case -EIO: 671 /* Network partition? */ 672 atomic_set(&clp->cl_cb_set, 0); 673 warn_no_callback_path(clp, task->tk_status); 674 if (current_rpc_client != task->tk_client) { 675 /* queue a callback on the new connection: */ 676 nfsd4_cb_recall(dp); 677 return; 678 } 679 case -EBADHANDLE: 680 case -NFS4ERR_BAD_STATEID: 681 /* Race: client probably got cb_recall 682 * before open reply granting delegation */ 683 break; 684 default: 685 /* success, or error we can't handle */ 686 return; 687 } 688 if (dp->dl_retries--) { 689 rpc_delay(task, 2*HZ); 690 task->tk_status = 0; 691 rpc_restart_call(task); 692 return; 693 } else { 694 atomic_set(&clp->cl_cb_set, 0); 695 warn_no_callback_path(clp, task->tk_status); 696 } 697 } 698 699 static void nfsd4_cb_recall_release(void *calldata) 700 { 701 struct nfs4_delegation *dp = calldata; 702 703 nfs4_put_delegation(dp); 704 } 705 706 static const struct rpc_call_ops nfsd4_cb_recall_ops = { 707 .rpc_call_prepare = nfsd4_cb_prepare, 708 .rpc_call_done = nfsd4_cb_recall_done, 709 .rpc_release = nfsd4_cb_recall_release, 710 }; 711 712 static struct workqueue_struct *callback_wq; 713 714 int nfsd4_create_callback_queue(void) 715 { 716 callback_wq = create_singlethread_workqueue("nfsd4_callbacks"); 717 if (!callback_wq) 718 return -ENOMEM; 719 return 0; 720 } 721 722 void nfsd4_destroy_callback_queue(void) 723 { 724 destroy_workqueue(callback_wq); 725 } 726 727 /* must be called under the state lock */ 728 void nfsd4_set_callback_client(struct nfs4_client *clp, struct rpc_clnt *new) 729 { 730 struct rpc_clnt *old = clp->cl_cb_client; 731 732 clp->cl_cb_client = new; 733 /* 734 * After this, any work that saw the old value of cl_cb_client will 735 * be gone: 736 */ 737 flush_workqueue(callback_wq); 738 /* So we can safely shut it down: */ 739 if (old) 740 rpc_shutdown_client(old); 741 } 742 743 /* 744 * called with dp->dl_count inc'ed. 745 */ 746 static void _nfsd4_cb_recall(struct nfs4_delegation *dp) 747 { 748 struct nfs4_client *clp = dp->dl_client; 749 struct rpc_clnt *clnt = clp->cl_cb_client; 750 struct nfs4_rpc_args *args = &dp->dl_recall.cb_args; 751 struct rpc_message msg = { 752 .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_RECALL], 753 .rpc_cred = callback_cred 754 }; 755 int status; 756 757 if (clnt == NULL) 758 return; /* Client is shutting down; give up. */ 759 760 args->args_op = dp; 761 msg.rpc_argp = args; 762 dp->dl_retries = 1; 763 status = rpc_call_async(clnt, &msg, RPC_TASK_SOFT, 764 &nfsd4_cb_recall_ops, dp); 765 if (status) 766 nfs4_put_delegation(dp); 767 } 768 769 void nfsd4_do_callback_rpc(struct work_struct *w) 770 { 771 /* XXX: for now, just send off delegation recall. */ 772 /* In future, generalize to handle any sort of callback. */ 773 struct nfsd4_callback *c = container_of(w, struct nfsd4_callback, cb_work); 774 struct nfs4_delegation *dp = container_of(c, struct nfs4_delegation, dl_recall); 775 776 _nfsd4_cb_recall(dp); 777 } 778 779 780 void nfsd4_cb_recall(struct nfs4_delegation *dp) 781 { 782 queue_work(callback_wq, &dp->dl_recall.cb_work); 783 } 784