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