1 /* 2 * linux/fs/nfsd/nfs4callback.c 3 * 4 * Copyright (c) 2001 The Regents of the University of Michigan. 5 * All rights reserved. 6 * 7 * Kendrick Smith <kmsmith@umich.edu> 8 * Andy Adamson <andros@umich.edu> 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. Neither the name of the University nor the names of its 20 * contributors may be used to endorse or promote products derived 21 * from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 30 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 #include <linux/module.h> 37 #include <linux/list.h> 38 #include <linux/inet.h> 39 #include <linux/errno.h> 40 #include <linux/delay.h> 41 #include <linux/sched.h> 42 #include <linux/kthread.h> 43 #include <linux/sunrpc/xdr.h> 44 #include <linux/sunrpc/svc.h> 45 #include <linux/sunrpc/clnt.h> 46 #include <linux/nfsd/nfsd.h> 47 #include <linux/nfsd/state.h> 48 #include <linux/sunrpc/sched.h> 49 #include <linux/nfs4.h> 50 51 #define NFSDDBG_FACILITY NFSDDBG_PROC 52 53 #define NFSPROC4_CB_NULL 0 54 #define NFSPROC4_CB_COMPOUND 1 55 56 /* Index of predefined Linux callback client operations */ 57 58 enum { 59 NFSPROC4_CLNT_CB_NULL = 0, 60 NFSPROC4_CLNT_CB_RECALL, 61 }; 62 63 enum nfs_cb_opnum4 { 64 OP_CB_RECALL = 4, 65 }; 66 67 #define NFS4_MAXTAGLEN 20 68 69 #define NFS4_enc_cb_null_sz 0 70 #define NFS4_dec_cb_null_sz 0 71 #define cb_compound_enc_hdr_sz 4 72 #define cb_compound_dec_hdr_sz (3 + (NFS4_MAXTAGLEN >> 2)) 73 #define op_enc_sz 1 74 #define op_dec_sz 2 75 #define enc_nfs4_fh_sz (1 + (NFS4_FHSIZE >> 2)) 76 #define enc_stateid_sz (NFS4_STATEID_SIZE >> 2) 77 #define NFS4_enc_cb_recall_sz (cb_compound_enc_hdr_sz + \ 78 1 + enc_stateid_sz + \ 79 enc_nfs4_fh_sz) 80 81 #define NFS4_dec_cb_recall_sz (cb_compound_dec_hdr_sz + \ 82 op_dec_sz) 83 84 /* 85 * Generic encode routines from fs/nfs/nfs4xdr.c 86 */ 87 static inline __be32 * 88 xdr_writemem(__be32 *p, const void *ptr, int nbytes) 89 { 90 int tmp = XDR_QUADLEN(nbytes); 91 if (!tmp) 92 return p; 93 p[tmp-1] = 0; 94 memcpy(p, ptr, nbytes); 95 return p + tmp; 96 } 97 98 #define WRITE32(n) *p++ = htonl(n) 99 #define WRITEMEM(ptr,nbytes) do { \ 100 p = xdr_writemem(p, ptr, nbytes); \ 101 } while (0) 102 #define RESERVE_SPACE(nbytes) do { \ 103 p = xdr_reserve_space(xdr, nbytes); \ 104 if (!p) dprintk("NFSD: RESERVE_SPACE(%d) failed in function %s\n", (int) (nbytes), __func__); \ 105 BUG_ON(!p); \ 106 } while (0) 107 108 /* 109 * Generic decode routines from fs/nfs/nfs4xdr.c 110 */ 111 #define DECODE_TAIL \ 112 status = 0; \ 113 out: \ 114 return status; \ 115 xdr_error: \ 116 dprintk("NFSD: xdr error! (%s:%d)\n", __FILE__, __LINE__); \ 117 status = -EIO; \ 118 goto out 119 120 #define READ32(x) (x) = ntohl(*p++) 121 #define READ64(x) do { \ 122 (x) = (u64)ntohl(*p++) << 32; \ 123 (x) |= ntohl(*p++); \ 124 } while (0) 125 #define READTIME(x) do { \ 126 p++; \ 127 (x.tv_sec) = ntohl(*p++); \ 128 (x.tv_nsec) = ntohl(*p++); \ 129 } while (0) 130 #define READ_BUF(nbytes) do { \ 131 p = xdr_inline_decode(xdr, nbytes); \ 132 if (!p) { \ 133 dprintk("NFSD: %s: reply buffer overflowed in line %d.\n", \ 134 __func__, __LINE__); \ 135 return -EIO; \ 136 } \ 137 } while (0) 138 139 struct nfs4_cb_compound_hdr { 140 int status; 141 u32 ident; 142 u32 nops; 143 __be32 *nops_p; 144 u32 minorversion; 145 u32 taglen; 146 char *tag; 147 }; 148 149 static struct { 150 int stat; 151 int errno; 152 } nfs_cb_errtbl[] = { 153 { NFS4_OK, 0 }, 154 { NFS4ERR_PERM, EPERM }, 155 { NFS4ERR_NOENT, ENOENT }, 156 { NFS4ERR_IO, EIO }, 157 { NFS4ERR_NXIO, ENXIO }, 158 { NFS4ERR_ACCESS, EACCES }, 159 { NFS4ERR_EXIST, EEXIST }, 160 { NFS4ERR_XDEV, EXDEV }, 161 { NFS4ERR_NOTDIR, ENOTDIR }, 162 { NFS4ERR_ISDIR, EISDIR }, 163 { NFS4ERR_INVAL, EINVAL }, 164 { NFS4ERR_FBIG, EFBIG }, 165 { NFS4ERR_NOSPC, ENOSPC }, 166 { NFS4ERR_ROFS, EROFS }, 167 { NFS4ERR_MLINK, EMLINK }, 168 { NFS4ERR_NAMETOOLONG, ENAMETOOLONG }, 169 { NFS4ERR_NOTEMPTY, ENOTEMPTY }, 170 { NFS4ERR_DQUOT, EDQUOT }, 171 { NFS4ERR_STALE, ESTALE }, 172 { NFS4ERR_BADHANDLE, EBADHANDLE }, 173 { NFS4ERR_BAD_COOKIE, EBADCOOKIE }, 174 { NFS4ERR_NOTSUPP, ENOTSUPP }, 175 { NFS4ERR_TOOSMALL, ETOOSMALL }, 176 { NFS4ERR_SERVERFAULT, ESERVERFAULT }, 177 { NFS4ERR_BADTYPE, EBADTYPE }, 178 { NFS4ERR_LOCKED, EAGAIN }, 179 { NFS4ERR_RESOURCE, EREMOTEIO }, 180 { NFS4ERR_SYMLINK, ELOOP }, 181 { NFS4ERR_OP_ILLEGAL, EOPNOTSUPP }, 182 { NFS4ERR_DEADLOCK, EDEADLK }, 183 { -1, EIO } 184 }; 185 186 static int 187 nfs_cb_stat_to_errno(int stat) 188 { 189 int i; 190 for (i = 0; nfs_cb_errtbl[i].stat != -1; i++) { 191 if (nfs_cb_errtbl[i].stat == stat) 192 return nfs_cb_errtbl[i].errno; 193 } 194 /* If we cannot translate the error, the recovery routines should 195 * handle it. 196 * Note: remaining NFSv4 error codes have values > 10000, so should 197 * not conflict with native Linux error codes. 198 */ 199 return stat; 200 } 201 202 /* 203 * XDR encode 204 */ 205 206 static void 207 encode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr) 208 { 209 __be32 * p; 210 211 RESERVE_SPACE(16); 212 WRITE32(0); /* tag length is always 0 */ 213 WRITE32(hdr->minorversion); 214 WRITE32(hdr->ident); 215 hdr->nops_p = p; 216 WRITE32(hdr->nops); 217 } 218 219 static void encode_cb_nops(struct nfs4_cb_compound_hdr *hdr) 220 { 221 *hdr->nops_p = htonl(hdr->nops); 222 } 223 224 static void 225 encode_cb_recall(struct xdr_stream *xdr, struct nfs4_delegation *dp, 226 struct nfs4_cb_compound_hdr *hdr) 227 { 228 __be32 *p; 229 int len = dp->dl_fh.fh_size; 230 231 RESERVE_SPACE(12+sizeof(dp->dl_stateid) + len); 232 WRITE32(OP_CB_RECALL); 233 WRITE32(dp->dl_stateid.si_generation); 234 WRITEMEM(&dp->dl_stateid.si_opaque, sizeof(stateid_opaque_t)); 235 WRITE32(0); /* truncate optimization not implemented */ 236 WRITE32(len); 237 WRITEMEM(&dp->dl_fh.fh_base, len); 238 hdr->nops++; 239 } 240 241 static int 242 nfs4_xdr_enc_cb_null(struct rpc_rqst *req, __be32 *p) 243 { 244 struct xdr_stream xdrs, *xdr = &xdrs; 245 246 xdr_init_encode(&xdrs, &req->rq_snd_buf, p); 247 RESERVE_SPACE(0); 248 return 0; 249 } 250 251 static int 252 nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, __be32 *p, struct nfs4_delegation *args) 253 { 254 struct xdr_stream xdr; 255 struct nfs4_cb_compound_hdr hdr = { 256 .ident = args->dl_ident, 257 }; 258 259 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 260 encode_cb_compound_hdr(&xdr, &hdr); 261 encode_cb_recall(&xdr, args, &hdr); 262 encode_cb_nops(&hdr); 263 return 0; 264 } 265 266 267 static int 268 decode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr){ 269 __be32 *p; 270 271 READ_BUF(8); 272 READ32(hdr->status); 273 READ32(hdr->taglen); 274 READ_BUF(hdr->taglen + 4); 275 hdr->tag = (char *)p; 276 p += XDR_QUADLEN(hdr->taglen); 277 READ32(hdr->nops); 278 return 0; 279 } 280 281 static int 282 decode_cb_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) 283 { 284 __be32 *p; 285 u32 op; 286 int32_t nfserr; 287 288 READ_BUF(8); 289 READ32(op); 290 if (op != expected) { 291 dprintk("NFSD: decode_cb_op_hdr: Callback server returned " 292 " operation %d but we issued a request for %d\n", 293 op, expected); 294 return -EIO; 295 } 296 READ32(nfserr); 297 if (nfserr != NFS_OK) 298 return -nfs_cb_stat_to_errno(nfserr); 299 return 0; 300 } 301 302 static int 303 nfs4_xdr_dec_cb_null(struct rpc_rqst *req, __be32 *p) 304 { 305 return 0; 306 } 307 308 static int 309 nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp, __be32 *p) 310 { 311 struct xdr_stream xdr; 312 struct nfs4_cb_compound_hdr hdr; 313 int status; 314 315 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 316 status = decode_cb_compound_hdr(&xdr, &hdr); 317 if (status) 318 goto out; 319 status = decode_cb_op_hdr(&xdr, OP_CB_RECALL); 320 out: 321 return status; 322 } 323 324 /* 325 * RPC procedure tables 326 */ 327 #define PROC(proc, call, argtype, restype) \ 328 [NFSPROC4_CLNT_##proc] = { \ 329 .p_proc = NFSPROC4_CB_##call, \ 330 .p_encode = (kxdrproc_t) nfs4_xdr_##argtype, \ 331 .p_decode = (kxdrproc_t) nfs4_xdr_##restype, \ 332 .p_arglen = NFS4_##argtype##_sz, \ 333 .p_replen = NFS4_##restype##_sz, \ 334 .p_statidx = NFSPROC4_CB_##call, \ 335 .p_name = #proc, \ 336 } 337 338 static struct rpc_procinfo nfs4_cb_procedures[] = { 339 PROC(CB_NULL, NULL, enc_cb_null, dec_cb_null), 340 PROC(CB_RECALL, COMPOUND, enc_cb_recall, dec_cb_recall), 341 }; 342 343 static struct rpc_version nfs_cb_version4 = { 344 .number = 1, 345 .nrprocs = ARRAY_SIZE(nfs4_cb_procedures), 346 .procs = nfs4_cb_procedures 347 }; 348 349 static struct rpc_version * nfs_cb_version[] = { 350 NULL, 351 &nfs_cb_version4, 352 }; 353 354 static struct rpc_program cb_program; 355 356 static struct rpc_stat cb_stats = { 357 .program = &cb_program 358 }; 359 360 #define NFS4_CALLBACK 0x40000000 361 static struct rpc_program cb_program = { 362 .name = "nfs4_cb", 363 .number = NFS4_CALLBACK, 364 .nrvers = ARRAY_SIZE(nfs_cb_version), 365 .version = nfs_cb_version, 366 .stats = &cb_stats, 367 .pipe_dir_name = "/nfsd4_cb", 368 }; 369 370 static int max_cb_time(void) 371 { 372 return max(NFSD_LEASE_TIME/10, (time_t)1) * HZ; 373 } 374 375 /* Reference counting, callback cleanup, etc., all look racy as heck. 376 * And why is cb_set an atomic? */ 377 378 int setup_callback_client(struct nfs4_client *clp) 379 { 380 struct sockaddr_in addr; 381 struct nfs4_cb_conn *cb = &clp->cl_cb_conn; 382 struct rpc_timeout timeparms = { 383 .to_initval = max_cb_time(), 384 .to_retries = 0, 385 }; 386 struct rpc_create_args args = { 387 .protocol = IPPROTO_TCP, 388 .address = (struct sockaddr *)&addr, 389 .addrsize = sizeof(addr), 390 .timeout = &timeparms, 391 .program = &cb_program, 392 .prognumber = cb->cb_prog, 393 .version = nfs_cb_version[1]->number, 394 .authflavor = clp->cl_flavor, 395 .flags = (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET), 396 .client_name = clp->cl_principal, 397 }; 398 struct rpc_clnt *client; 399 400 if (!clp->cl_principal && (clp->cl_flavor >= RPC_AUTH_GSS_KRB5)) 401 return -EINVAL; 402 403 /* Initialize address */ 404 memset(&addr, 0, sizeof(addr)); 405 addr.sin_family = AF_INET; 406 addr.sin_port = htons(cb->cb_port); 407 addr.sin_addr.s_addr = htonl(cb->cb_addr); 408 409 /* Create RPC client */ 410 client = rpc_create(&args); 411 if (IS_ERR(client)) { 412 dprintk("NFSD: couldn't create callback client: %ld\n", 413 PTR_ERR(client)); 414 return PTR_ERR(client); 415 } 416 cb->cb_client = client; 417 return 0; 418 419 } 420 421 static void warn_no_callback_path(struct nfs4_client *clp, int reason) 422 { 423 dprintk("NFSD: warning: no callback path to client %.*s: error %d\n", 424 (int)clp->cl_name.len, clp->cl_name.data, reason); 425 } 426 427 static void nfsd4_cb_probe_done(struct rpc_task *task, void *calldata) 428 { 429 struct nfs4_client *clp = calldata; 430 431 if (task->tk_status) 432 warn_no_callback_path(clp, task->tk_status); 433 else 434 atomic_set(&clp->cl_cb_conn.cb_set, 1); 435 put_nfs4_client(clp); 436 } 437 438 static const struct rpc_call_ops nfsd4_cb_probe_ops = { 439 .rpc_call_done = nfsd4_cb_probe_done, 440 }; 441 442 static struct rpc_cred *lookup_cb_cred(struct nfs4_cb_conn *cb) 443 { 444 struct auth_cred acred = { 445 .machine_cred = 1 446 }; 447 448 /* 449 * Note in the gss case this doesn't actually have to wait for a 450 * gss upcall (or any calls to the client); this just creates a 451 * non-uptodate cred which the rpc state machine will fill in with 452 * a refresh_upcall later. 453 */ 454 return rpcauth_lookup_credcache(cb->cb_client->cl_auth, &acred, 455 RPCAUTH_LOOKUP_NEW); 456 } 457 458 void do_probe_callback(struct nfs4_client *clp) 459 { 460 struct nfs4_cb_conn *cb = &clp->cl_cb_conn; 461 struct rpc_message msg = { 462 .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL], 463 .rpc_argp = clp, 464 }; 465 struct rpc_cred *cred; 466 int status; 467 468 cred = lookup_cb_cred(cb); 469 if (IS_ERR(cred)) { 470 status = PTR_ERR(cred); 471 goto out; 472 } 473 cb->cb_cred = cred; 474 msg.rpc_cred = cb->cb_cred; 475 status = rpc_call_async(cb->cb_client, &msg, RPC_TASK_SOFT, 476 &nfsd4_cb_probe_ops, (void *)clp); 477 out: 478 if (status) { 479 warn_no_callback_path(clp, status); 480 put_nfs4_client(clp); 481 } 482 } 483 484 /* 485 * Set up the callback client and put a NFSPROC4_CB_NULL on the wire... 486 */ 487 void 488 nfsd4_probe_callback(struct nfs4_client *clp) 489 { 490 int status; 491 492 BUG_ON(atomic_read(&clp->cl_cb_conn.cb_set)); 493 494 status = setup_callback_client(clp); 495 if (status) { 496 warn_no_callback_path(clp, status); 497 return; 498 } 499 500 /* the task holds a reference to the nfs4_client struct */ 501 atomic_inc(&clp->cl_count); 502 503 do_probe_callback(clp); 504 } 505 506 static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata) 507 { 508 struct nfs4_delegation *dp = calldata; 509 struct nfs4_client *clp = dp->dl_client; 510 511 switch (task->tk_status) { 512 case -EIO: 513 /* Network partition? */ 514 atomic_set(&clp->cl_cb_conn.cb_set, 0); 515 warn_no_callback_path(clp, task->tk_status); 516 case -EBADHANDLE: 517 case -NFS4ERR_BAD_STATEID: 518 /* Race: client probably got cb_recall 519 * before open reply granting delegation */ 520 break; 521 default: 522 /* success, or error we can't handle */ 523 return; 524 } 525 if (dp->dl_retries--) { 526 rpc_delay(task, 2*HZ); 527 task->tk_status = 0; 528 rpc_restart_call(task); 529 } else { 530 atomic_set(&clp->cl_cb_conn.cb_set, 0); 531 warn_no_callback_path(clp, task->tk_status); 532 } 533 } 534 535 static void nfsd4_cb_recall_release(void *calldata) 536 { 537 struct nfs4_delegation *dp = calldata; 538 struct nfs4_client *clp = dp->dl_client; 539 540 nfs4_put_delegation(dp); 541 put_nfs4_client(clp); 542 } 543 544 static const struct rpc_call_ops nfsd4_cb_recall_ops = { 545 .rpc_call_done = nfsd4_cb_recall_done, 546 .rpc_release = nfsd4_cb_recall_release, 547 }; 548 549 /* 550 * called with dp->dl_count inc'ed. 551 */ 552 void 553 nfsd4_cb_recall(struct nfs4_delegation *dp) 554 { 555 struct nfs4_client *clp = dp->dl_client; 556 struct rpc_clnt *clnt = clp->cl_cb_conn.cb_client; 557 struct rpc_message msg = { 558 .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_RECALL], 559 .rpc_argp = dp, 560 .rpc_cred = clp->cl_cb_conn.cb_cred 561 }; 562 int status; 563 564 dp->dl_retries = 1; 565 status = rpc_call_async(clnt, &msg, RPC_TASK_SOFT, 566 &nfsd4_cb_recall_ops, dp); 567 if (status) { 568 put_nfs4_client(clp); 569 nfs4_put_delegation(dp); 570 } 571 } 572