at master 21 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * linux/fs/lockd/svcproc.c 4 * 5 * Lockd server procedures. We don't implement the NLM_*_RES 6 * procedures because we don't use the async procedures. 7 * 8 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> 9 */ 10 11#include <linux/types.h> 12#include <linux/time.h> 13#include <linux/lockd/lockd.h> 14#include <linux/lockd/share.h> 15#include <linux/sunrpc/svc_xprt.h> 16 17#define NLMDBG_FACILITY NLMDBG_CLIENT 18 19#ifdef CONFIG_LOCKD_V4 20static __be32 21cast_to_nlm(__be32 status, u32 vers) 22{ 23 /* Note: status is assumed to be in network byte order !!! */ 24 if (vers != 4){ 25 switch (status) { 26 case nlm_granted: 27 case nlm_lck_denied: 28 case nlm_lck_denied_nolocks: 29 case nlm_lck_blocked: 30 case nlm_lck_denied_grace_period: 31 case nlm_drop_reply: 32 break; 33 case nlm4_deadlock: 34 status = nlm_lck_denied; 35 break; 36 default: 37 status = nlm_lck_denied_nolocks; 38 } 39 } 40 41 return (status); 42} 43#define cast_status(status) (cast_to_nlm(status, rqstp->rq_vers)) 44#else 45#define cast_status(status) (status) 46#endif 47 48/* 49 * Obtain client and file from arguments 50 */ 51static __be32 52nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, 53 struct nlm_host **hostp, struct nlm_file **filp) 54{ 55 struct nlm_host *host = NULL; 56 struct nlm_file *file = NULL; 57 struct nlm_lock *lock = &argp->lock; 58 int mode; 59 __be32 error = 0; 60 61 /* nfsd callbacks must have been installed for this procedure */ 62 if (!nlmsvc_ops) 63 return nlm_lck_denied_nolocks; 64 65 /* Obtain host handle */ 66 if (!(host = nlmsvc_lookup_host(rqstp, lock->caller, lock->len)) 67 || (argp->monitor && nsm_monitor(host) < 0)) 68 goto no_locks; 69 *hostp = host; 70 71 /* Obtain file pointer. Not used by FREE_ALL call. */ 72 if (filp != NULL) { 73 error = cast_status(nlm_lookup_file(rqstp, &file, lock)); 74 if (error != 0) 75 goto no_locks; 76 *filp = file; 77 78 /* Set up the missing parts of the file_lock structure */ 79 mode = lock_to_openmode(&lock->fl); 80 lock->fl.c.flc_flags = FL_POSIX; 81 lock->fl.c.flc_file = file->f_file[mode]; 82 lock->fl.c.flc_pid = current->tgid; 83 lock->fl.fl_lmops = &nlmsvc_lock_operations; 84 nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid); 85 if (!lock->fl.c.flc_owner) { 86 /* lockowner allocation has failed */ 87 nlmsvc_release_host(host); 88 return nlm_lck_denied_nolocks; 89 } 90 } 91 92 return 0; 93 94no_locks: 95 nlmsvc_release_host(host); 96 if (error) 97 return error; 98 return nlm_lck_denied_nolocks; 99} 100 101/* 102 * NULL: Test for presence of service 103 */ 104static __be32 105nlmsvc_proc_null(struct svc_rqst *rqstp) 106{ 107 dprintk("lockd: NULL called\n"); 108 return rpc_success; 109} 110 111/* 112 * TEST: Check for conflicting lock 113 */ 114static __be32 115__nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_res *resp) 116{ 117 struct nlm_args *argp = rqstp->rq_argp; 118 struct nlm_host *host; 119 struct nlm_file *file; 120 __be32 rc = rpc_success; 121 122 dprintk("lockd: TEST called\n"); 123 resp->cookie = argp->cookie; 124 125 /* Obtain client and file */ 126 if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) 127 return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; 128 129 /* Now check for conflicting locks */ 130 resp->status = cast_status(nlmsvc_testlock(rqstp, file, host, 131 &argp->lock, &resp->lock)); 132 if (resp->status == nlm_drop_reply) 133 rc = rpc_drop_reply; 134 else 135 dprintk("lockd: TEST status %d vers %d\n", 136 ntohl(resp->status), rqstp->rq_vers); 137 138 nlmsvc_release_lockowner(&argp->lock); 139 nlmsvc_release_host(host); 140 nlm_release_file(file); 141 return rc; 142} 143 144static __be32 145nlmsvc_proc_test(struct svc_rqst *rqstp) 146{ 147 return __nlmsvc_proc_test(rqstp, rqstp->rq_resp); 148} 149 150static __be32 151__nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_res *resp) 152{ 153 struct nlm_args *argp = rqstp->rq_argp; 154 struct nlm_host *host; 155 struct nlm_file *file; 156 __be32 rc = rpc_success; 157 158 dprintk("lockd: LOCK called\n"); 159 160 resp->cookie = argp->cookie; 161 162 /* Obtain client and file */ 163 if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) 164 return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; 165 166 /* Now try to lock the file */ 167 resp->status = cast_status(nlmsvc_lock(rqstp, file, host, &argp->lock, 168 argp->block, &argp->cookie, 169 argp->reclaim)); 170 if (resp->status == nlm_drop_reply) 171 rc = rpc_drop_reply; 172 else 173 dprintk("lockd: LOCK status %d\n", ntohl(resp->status)); 174 175 nlmsvc_release_lockowner(&argp->lock); 176 nlmsvc_release_host(host); 177 nlm_release_file(file); 178 return rc; 179} 180 181static __be32 182nlmsvc_proc_lock(struct svc_rqst *rqstp) 183{ 184 return __nlmsvc_proc_lock(rqstp, rqstp->rq_resp); 185} 186 187static __be32 188__nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_res *resp) 189{ 190 struct nlm_args *argp = rqstp->rq_argp; 191 struct nlm_host *host; 192 struct nlm_file *file; 193 struct net *net = SVC_NET(rqstp); 194 195 dprintk("lockd: CANCEL called\n"); 196 197 resp->cookie = argp->cookie; 198 199 /* Don't accept requests during grace period */ 200 if (locks_in_grace(net)) { 201 resp->status = nlm_lck_denied_grace_period; 202 return rpc_success; 203 } 204 205 /* Obtain client and file */ 206 if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) 207 return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; 208 209 /* Try to cancel request. */ 210 resp->status = cast_status(nlmsvc_cancel_blocked(net, file, &argp->lock)); 211 212 dprintk("lockd: CANCEL status %d\n", ntohl(resp->status)); 213 nlmsvc_release_lockowner(&argp->lock); 214 nlmsvc_release_host(host); 215 nlm_release_file(file); 216 return rpc_success; 217} 218 219static __be32 220nlmsvc_proc_cancel(struct svc_rqst *rqstp) 221{ 222 return __nlmsvc_proc_cancel(rqstp, rqstp->rq_resp); 223} 224 225/* 226 * UNLOCK: release a lock 227 */ 228static __be32 229__nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_res *resp) 230{ 231 struct nlm_args *argp = rqstp->rq_argp; 232 struct nlm_host *host; 233 struct nlm_file *file; 234 struct net *net = SVC_NET(rqstp); 235 236 dprintk("lockd: UNLOCK called\n"); 237 238 resp->cookie = argp->cookie; 239 240 /* Don't accept new lock requests during grace period */ 241 if (locks_in_grace(net)) { 242 resp->status = nlm_lck_denied_grace_period; 243 return rpc_success; 244 } 245 246 /* Obtain client and file */ 247 if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) 248 return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; 249 250 /* Now try to remove the lock */ 251 resp->status = cast_status(nlmsvc_unlock(net, file, &argp->lock)); 252 253 dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status)); 254 nlmsvc_release_lockowner(&argp->lock); 255 nlmsvc_release_host(host); 256 nlm_release_file(file); 257 return rpc_success; 258} 259 260static __be32 261nlmsvc_proc_unlock(struct svc_rqst *rqstp) 262{ 263 return __nlmsvc_proc_unlock(rqstp, rqstp->rq_resp); 264} 265 266/* 267 * GRANTED: A server calls us to tell that a process' lock request 268 * was granted 269 */ 270static __be32 271__nlmsvc_proc_granted(struct svc_rqst *rqstp, struct nlm_res *resp) 272{ 273 struct nlm_args *argp = rqstp->rq_argp; 274 275 resp->cookie = argp->cookie; 276 277 dprintk("lockd: GRANTED called\n"); 278 resp->status = nlmclnt_grant(svc_addr(rqstp), &argp->lock); 279 dprintk("lockd: GRANTED status %d\n", ntohl(resp->status)); 280 return rpc_success; 281} 282 283static __be32 284nlmsvc_proc_granted(struct svc_rqst *rqstp) 285{ 286 return __nlmsvc_proc_granted(rqstp, rqstp->rq_resp); 287} 288 289/* 290 * This is the generic lockd callback for async RPC calls 291 */ 292static void nlmsvc_callback_exit(struct rpc_task *task, void *data) 293{ 294} 295 296void nlmsvc_release_call(struct nlm_rqst *call) 297{ 298 if (!refcount_dec_and_test(&call->a_count)) 299 return; 300 nlmsvc_release_host(call->a_host); 301 kfree(call); 302} 303 304static void nlmsvc_callback_release(void *data) 305{ 306 nlmsvc_release_call(data); 307} 308 309static const struct rpc_call_ops nlmsvc_callback_ops = { 310 .rpc_call_done = nlmsvc_callback_exit, 311 .rpc_release = nlmsvc_callback_release, 312}; 313 314/* 315 * `Async' versions of the above service routines. They aren't really, 316 * because we send the callback before the reply proper. I hope this 317 * doesn't break any clients. 318 */ 319static __be32 nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, 320 __be32 (*func)(struct svc_rqst *, struct nlm_res *)) 321{ 322 struct nlm_args *argp = rqstp->rq_argp; 323 struct nlm_host *host; 324 struct nlm_rqst *call; 325 __be32 stat; 326 327 host = nlmsvc_lookup_host(rqstp, 328 argp->lock.caller, 329 argp->lock.len); 330 if (host == NULL) 331 return rpc_system_err; 332 333 call = nlm_alloc_call(host); 334 nlmsvc_release_host(host); 335 if (call == NULL) 336 return rpc_system_err; 337 338 stat = func(rqstp, &call->a_res); 339 if (stat != 0) { 340 nlmsvc_release_call(call); 341 return stat; 342 } 343 344 call->a_flags = RPC_TASK_ASYNC; 345 if (nlm_async_reply(call, proc, &nlmsvc_callback_ops) < 0) 346 return rpc_system_err; 347 return rpc_success; 348} 349 350static __be32 nlmsvc_proc_test_msg(struct svc_rqst *rqstp) 351{ 352 dprintk("lockd: TEST_MSG called\n"); 353 return nlmsvc_callback(rqstp, NLMPROC_TEST_RES, __nlmsvc_proc_test); 354} 355 356static __be32 nlmsvc_proc_lock_msg(struct svc_rqst *rqstp) 357{ 358 dprintk("lockd: LOCK_MSG called\n"); 359 return nlmsvc_callback(rqstp, NLMPROC_LOCK_RES, __nlmsvc_proc_lock); 360} 361 362static __be32 nlmsvc_proc_cancel_msg(struct svc_rqst *rqstp) 363{ 364 dprintk("lockd: CANCEL_MSG called\n"); 365 return nlmsvc_callback(rqstp, NLMPROC_CANCEL_RES, __nlmsvc_proc_cancel); 366} 367 368static __be32 369nlmsvc_proc_unlock_msg(struct svc_rqst *rqstp) 370{ 371 dprintk("lockd: UNLOCK_MSG called\n"); 372 return nlmsvc_callback(rqstp, NLMPROC_UNLOCK_RES, __nlmsvc_proc_unlock); 373} 374 375static __be32 376nlmsvc_proc_granted_msg(struct svc_rqst *rqstp) 377{ 378 dprintk("lockd: GRANTED_MSG called\n"); 379 return nlmsvc_callback(rqstp, NLMPROC_GRANTED_RES, __nlmsvc_proc_granted); 380} 381 382/* 383 * SHARE: create a DOS share or alter existing share. 384 */ 385static __be32 386nlmsvc_proc_share(struct svc_rqst *rqstp) 387{ 388 struct nlm_args *argp = rqstp->rq_argp; 389 struct nlm_res *resp = rqstp->rq_resp; 390 struct nlm_host *host; 391 struct nlm_file *file; 392 393 dprintk("lockd: SHARE called\n"); 394 395 resp->cookie = argp->cookie; 396 397 /* Don't accept new lock requests during grace period */ 398 if (locks_in_grace(SVC_NET(rqstp)) && !argp->reclaim) { 399 resp->status = nlm_lck_denied_grace_period; 400 return rpc_success; 401 } 402 403 /* Obtain client and file */ 404 if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) 405 return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; 406 407 /* Now try to create the share */ 408 resp->status = cast_status(nlmsvc_share_file(host, file, argp)); 409 410 dprintk("lockd: SHARE status %d\n", ntohl(resp->status)); 411 nlmsvc_release_lockowner(&argp->lock); 412 nlmsvc_release_host(host); 413 nlm_release_file(file); 414 return rpc_success; 415} 416 417/* 418 * UNSHARE: Release a DOS share. 419 */ 420static __be32 421nlmsvc_proc_unshare(struct svc_rqst *rqstp) 422{ 423 struct nlm_args *argp = rqstp->rq_argp; 424 struct nlm_res *resp = rqstp->rq_resp; 425 struct nlm_host *host; 426 struct nlm_file *file; 427 428 dprintk("lockd: UNSHARE called\n"); 429 430 resp->cookie = argp->cookie; 431 432 /* Don't accept requests during grace period */ 433 if (locks_in_grace(SVC_NET(rqstp))) { 434 resp->status = nlm_lck_denied_grace_period; 435 return rpc_success; 436 } 437 438 /* Obtain client and file */ 439 if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) 440 return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; 441 442 /* Now try to unshare the file */ 443 resp->status = cast_status(nlmsvc_unshare_file(host, file, argp)); 444 445 dprintk("lockd: UNSHARE status %d\n", ntohl(resp->status)); 446 nlmsvc_release_lockowner(&argp->lock); 447 nlmsvc_release_host(host); 448 nlm_release_file(file); 449 return rpc_success; 450} 451 452/* 453 * NM_LOCK: Create an unmonitored lock 454 */ 455static __be32 456nlmsvc_proc_nm_lock(struct svc_rqst *rqstp) 457{ 458 struct nlm_args *argp = rqstp->rq_argp; 459 460 dprintk("lockd: NM_LOCK called\n"); 461 462 argp->monitor = 0; /* just clean the monitor flag */ 463 return nlmsvc_proc_lock(rqstp); 464} 465 466/* 467 * FREE_ALL: Release all locks and shares held by client 468 */ 469static __be32 470nlmsvc_proc_free_all(struct svc_rqst *rqstp) 471{ 472 struct nlm_args *argp = rqstp->rq_argp; 473 struct nlm_host *host; 474 475 /* Obtain client */ 476 if (nlmsvc_retrieve_args(rqstp, argp, &host, NULL)) 477 return rpc_success; 478 479 nlmsvc_free_host_resources(host); 480 nlmsvc_release_host(host); 481 return rpc_success; 482} 483 484/* 485 * SM_NOTIFY: private callback from statd (not part of official NLM proto) 486 */ 487static __be32 488nlmsvc_proc_sm_notify(struct svc_rqst *rqstp) 489{ 490 struct nlm_reboot *argp = rqstp->rq_argp; 491 492 dprintk("lockd: SM_NOTIFY called\n"); 493 494 if (!nlm_privileged_requester(rqstp)) { 495 char buf[RPC_MAX_ADDRBUFLEN]; 496 printk(KERN_WARNING "lockd: rejected NSM callback from %s\n", 497 svc_print_addr(rqstp, buf, sizeof(buf))); 498 return rpc_system_err; 499 } 500 501 nlm_host_rebooted(SVC_NET(rqstp), argp); 502 return rpc_success; 503} 504 505/* 506 * client sent a GRANTED_RES, let's remove the associated block 507 */ 508static __be32 509nlmsvc_proc_granted_res(struct svc_rqst *rqstp) 510{ 511 struct nlm_res *argp = rqstp->rq_argp; 512 513 if (!nlmsvc_ops) 514 return rpc_success; 515 516 dprintk("lockd: GRANTED_RES called\n"); 517 518 nlmsvc_grant_reply(&argp->cookie, argp->status); 519 return rpc_success; 520} 521 522static __be32 523nlmsvc_proc_unused(struct svc_rqst *rqstp) 524{ 525 return rpc_proc_unavail; 526} 527 528/* 529 * NLM Server procedures. 530 */ 531 532struct nlm_void { int dummy; }; 533 534#define Ck (1+XDR_QUADLEN(NLM_MAXCOOKIELEN)) /* cookie */ 535#define St 1 /* status */ 536#define No (1+1024/4) /* Net Obj */ 537#define Rg 2 /* range - offset + size */ 538 539const struct svc_procedure nlmsvc_procedures[24] = { 540 [NLMPROC_NULL] = { 541 .pc_func = nlmsvc_proc_null, 542 .pc_decode = nlmsvc_decode_void, 543 .pc_encode = nlmsvc_encode_void, 544 .pc_argsize = sizeof(struct nlm_void), 545 .pc_argzero = sizeof(struct nlm_void), 546 .pc_ressize = sizeof(struct nlm_void), 547 .pc_xdrressize = St, 548 .pc_name = "NULL", 549 }, 550 [NLMPROC_TEST] = { 551 .pc_func = nlmsvc_proc_test, 552 .pc_decode = nlmsvc_decode_testargs, 553 .pc_encode = nlmsvc_encode_testres, 554 .pc_argsize = sizeof(struct nlm_args), 555 .pc_argzero = sizeof(struct nlm_args), 556 .pc_ressize = sizeof(struct nlm_res), 557 .pc_xdrressize = Ck+St+2+No+Rg, 558 .pc_name = "TEST", 559 }, 560 [NLMPROC_LOCK] = { 561 .pc_func = nlmsvc_proc_lock, 562 .pc_decode = nlmsvc_decode_lockargs, 563 .pc_encode = nlmsvc_encode_res, 564 .pc_argsize = sizeof(struct nlm_args), 565 .pc_argzero = sizeof(struct nlm_args), 566 .pc_ressize = sizeof(struct nlm_res), 567 .pc_xdrressize = Ck+St, 568 .pc_name = "LOCK", 569 }, 570 [NLMPROC_CANCEL] = { 571 .pc_func = nlmsvc_proc_cancel, 572 .pc_decode = nlmsvc_decode_cancargs, 573 .pc_encode = nlmsvc_encode_res, 574 .pc_argsize = sizeof(struct nlm_args), 575 .pc_argzero = sizeof(struct nlm_args), 576 .pc_ressize = sizeof(struct nlm_res), 577 .pc_xdrressize = Ck+St, 578 .pc_name = "CANCEL", 579 }, 580 [NLMPROC_UNLOCK] = { 581 .pc_func = nlmsvc_proc_unlock, 582 .pc_decode = nlmsvc_decode_unlockargs, 583 .pc_encode = nlmsvc_encode_res, 584 .pc_argsize = sizeof(struct nlm_args), 585 .pc_argzero = sizeof(struct nlm_args), 586 .pc_ressize = sizeof(struct nlm_res), 587 .pc_xdrressize = Ck+St, 588 .pc_name = "UNLOCK", 589 }, 590 [NLMPROC_GRANTED] = { 591 .pc_func = nlmsvc_proc_granted, 592 .pc_decode = nlmsvc_decode_testargs, 593 .pc_encode = nlmsvc_encode_res, 594 .pc_argsize = sizeof(struct nlm_args), 595 .pc_argzero = sizeof(struct nlm_args), 596 .pc_ressize = sizeof(struct nlm_res), 597 .pc_xdrressize = Ck+St, 598 .pc_name = "GRANTED", 599 }, 600 [NLMPROC_TEST_MSG] = { 601 .pc_func = nlmsvc_proc_test_msg, 602 .pc_decode = nlmsvc_decode_testargs, 603 .pc_encode = nlmsvc_encode_void, 604 .pc_argsize = sizeof(struct nlm_args), 605 .pc_argzero = sizeof(struct nlm_args), 606 .pc_ressize = sizeof(struct nlm_void), 607 .pc_xdrressize = St, 608 .pc_name = "TEST_MSG", 609 }, 610 [NLMPROC_LOCK_MSG] = { 611 .pc_func = nlmsvc_proc_lock_msg, 612 .pc_decode = nlmsvc_decode_lockargs, 613 .pc_encode = nlmsvc_encode_void, 614 .pc_argsize = sizeof(struct nlm_args), 615 .pc_argzero = sizeof(struct nlm_args), 616 .pc_ressize = sizeof(struct nlm_void), 617 .pc_xdrressize = St, 618 .pc_name = "LOCK_MSG", 619 }, 620 [NLMPROC_CANCEL_MSG] = { 621 .pc_func = nlmsvc_proc_cancel_msg, 622 .pc_decode = nlmsvc_decode_cancargs, 623 .pc_encode = nlmsvc_encode_void, 624 .pc_argsize = sizeof(struct nlm_args), 625 .pc_argzero = sizeof(struct nlm_args), 626 .pc_ressize = sizeof(struct nlm_void), 627 .pc_xdrressize = St, 628 .pc_name = "CANCEL_MSG", 629 }, 630 [NLMPROC_UNLOCK_MSG] = { 631 .pc_func = nlmsvc_proc_unlock_msg, 632 .pc_decode = nlmsvc_decode_unlockargs, 633 .pc_encode = nlmsvc_encode_void, 634 .pc_argsize = sizeof(struct nlm_args), 635 .pc_argzero = sizeof(struct nlm_args), 636 .pc_ressize = sizeof(struct nlm_void), 637 .pc_xdrressize = St, 638 .pc_name = "UNLOCK_MSG", 639 }, 640 [NLMPROC_GRANTED_MSG] = { 641 .pc_func = nlmsvc_proc_granted_msg, 642 .pc_decode = nlmsvc_decode_testargs, 643 .pc_encode = nlmsvc_encode_void, 644 .pc_argsize = sizeof(struct nlm_args), 645 .pc_argzero = sizeof(struct nlm_args), 646 .pc_ressize = sizeof(struct nlm_void), 647 .pc_xdrressize = St, 648 .pc_name = "GRANTED_MSG", 649 }, 650 [NLMPROC_TEST_RES] = { 651 .pc_func = nlmsvc_proc_null, 652 .pc_decode = nlmsvc_decode_void, 653 .pc_encode = nlmsvc_encode_void, 654 .pc_argsize = sizeof(struct nlm_res), 655 .pc_argzero = sizeof(struct nlm_res), 656 .pc_ressize = sizeof(struct nlm_void), 657 .pc_xdrressize = St, 658 .pc_name = "TEST_RES", 659 }, 660 [NLMPROC_LOCK_RES] = { 661 .pc_func = nlmsvc_proc_null, 662 .pc_decode = nlmsvc_decode_void, 663 .pc_encode = nlmsvc_encode_void, 664 .pc_argsize = sizeof(struct nlm_res), 665 .pc_argzero = sizeof(struct nlm_res), 666 .pc_ressize = sizeof(struct nlm_void), 667 .pc_xdrressize = St, 668 .pc_name = "LOCK_RES", 669 }, 670 [NLMPROC_CANCEL_RES] = { 671 .pc_func = nlmsvc_proc_null, 672 .pc_decode = nlmsvc_decode_void, 673 .pc_encode = nlmsvc_encode_void, 674 .pc_argsize = sizeof(struct nlm_res), 675 .pc_argzero = sizeof(struct nlm_res), 676 .pc_ressize = sizeof(struct nlm_void), 677 .pc_xdrressize = St, 678 .pc_name = "CANCEL_RES", 679 }, 680 [NLMPROC_UNLOCK_RES] = { 681 .pc_func = nlmsvc_proc_null, 682 .pc_decode = nlmsvc_decode_void, 683 .pc_encode = nlmsvc_encode_void, 684 .pc_argsize = sizeof(struct nlm_res), 685 .pc_argzero = sizeof(struct nlm_res), 686 .pc_ressize = sizeof(struct nlm_void), 687 .pc_xdrressize = St, 688 .pc_name = "UNLOCK_RES", 689 }, 690 [NLMPROC_GRANTED_RES] = { 691 .pc_func = nlmsvc_proc_granted_res, 692 .pc_decode = nlmsvc_decode_res, 693 .pc_encode = nlmsvc_encode_void, 694 .pc_argsize = sizeof(struct nlm_res), 695 .pc_argzero = sizeof(struct nlm_res), 696 .pc_ressize = sizeof(struct nlm_void), 697 .pc_xdrressize = St, 698 .pc_name = "GRANTED_RES", 699 }, 700 [NLMPROC_NSM_NOTIFY] = { 701 .pc_func = nlmsvc_proc_sm_notify, 702 .pc_decode = nlmsvc_decode_reboot, 703 .pc_encode = nlmsvc_encode_void, 704 .pc_argsize = sizeof(struct nlm_reboot), 705 .pc_argzero = sizeof(struct nlm_reboot), 706 .pc_ressize = sizeof(struct nlm_void), 707 .pc_xdrressize = St, 708 .pc_name = "SM_NOTIFY", 709 }, 710 [17] = { 711 .pc_func = nlmsvc_proc_unused, 712 .pc_decode = nlmsvc_decode_void, 713 .pc_encode = nlmsvc_encode_void, 714 .pc_argsize = sizeof(struct nlm_void), 715 .pc_argzero = sizeof(struct nlm_void), 716 .pc_ressize = sizeof(struct nlm_void), 717 .pc_xdrressize = St, 718 .pc_name = "UNUSED", 719 }, 720 [18] = { 721 .pc_func = nlmsvc_proc_unused, 722 .pc_decode = nlmsvc_decode_void, 723 .pc_encode = nlmsvc_encode_void, 724 .pc_argsize = sizeof(struct nlm_void), 725 .pc_argzero = sizeof(struct nlm_void), 726 .pc_ressize = sizeof(struct nlm_void), 727 .pc_xdrressize = St, 728 .pc_name = "UNUSED", 729 }, 730 [19] = { 731 .pc_func = nlmsvc_proc_unused, 732 .pc_decode = nlmsvc_decode_void, 733 .pc_encode = nlmsvc_encode_void, 734 .pc_argsize = sizeof(struct nlm_void), 735 .pc_argzero = sizeof(struct nlm_void), 736 .pc_ressize = sizeof(struct nlm_void), 737 .pc_xdrressize = St, 738 .pc_name = "UNUSED", 739 }, 740 [NLMPROC_SHARE] = { 741 .pc_func = nlmsvc_proc_share, 742 .pc_decode = nlmsvc_decode_shareargs, 743 .pc_encode = nlmsvc_encode_shareres, 744 .pc_argsize = sizeof(struct nlm_args), 745 .pc_argzero = sizeof(struct nlm_args), 746 .pc_ressize = sizeof(struct nlm_res), 747 .pc_xdrressize = Ck+St+1, 748 .pc_name = "SHARE", 749 }, 750 [NLMPROC_UNSHARE] = { 751 .pc_func = nlmsvc_proc_unshare, 752 .pc_decode = nlmsvc_decode_shareargs, 753 .pc_encode = nlmsvc_encode_shareres, 754 .pc_argsize = sizeof(struct nlm_args), 755 .pc_argzero = sizeof(struct nlm_args), 756 .pc_ressize = sizeof(struct nlm_res), 757 .pc_xdrressize = Ck+St+1, 758 .pc_name = "UNSHARE", 759 }, 760 [NLMPROC_NM_LOCK] = { 761 .pc_func = nlmsvc_proc_nm_lock, 762 .pc_decode = nlmsvc_decode_lockargs, 763 .pc_encode = nlmsvc_encode_res, 764 .pc_argsize = sizeof(struct nlm_args), 765 .pc_argzero = sizeof(struct nlm_args), 766 .pc_ressize = sizeof(struct nlm_res), 767 .pc_xdrressize = Ck+St, 768 .pc_name = "NM_LOCK", 769 }, 770 [NLMPROC_FREE_ALL] = { 771 .pc_func = nlmsvc_proc_free_all, 772 .pc_decode = nlmsvc_decode_notify, 773 .pc_encode = nlmsvc_encode_void, 774 .pc_argsize = sizeof(struct nlm_args), 775 .pc_argzero = sizeof(struct nlm_args), 776 .pc_ressize = sizeof(struct nlm_void), 777 .pc_xdrressize = 0, 778 .pc_name = "FREE_ALL", 779 }, 780};