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