1181834Sroberto// SPDX-License-Identifier: GPL-2.0 2181834Sroberto/* 3290001Sglebius * linux/fs/lockd/svcproc.c 4181834Sroberto * 5181834Sroberto * Lockd server procedures. We don't implement the NLM_*_RES 6290001Sglebius * procedures because we don't use the async procedures. 7290001Sglebius * 8290001Sglebius * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> 9181834Sroberto */ 10181834Sroberto 11290001Sglebius#include <linux/types.h> 12290001Sglebius#include <linux/time.h> 13290001Sglebius#include <linux/lockd/lockd.h> 14181834Sroberto#include <linux/lockd/share.h> 15290001Sglebius#include <linux/sunrpc/svc_xprt.h> 16290001Sglebius 17290001Sglebius#define NLMDBG_FACILITY NLMDBG_CLIENT 18181834Sroberto 19290001Sglebius#ifdef CONFIG_LOCKD_V4 20290001Sglebiusstatic __be32 21181834Srobertocast_to_nlm(__be32 status, u32 vers) 22290001Sglebius{ 23290001Sglebius /* Note: status is assumed to be in network byte order !!! */ 24181834Sroberto if (vers != 4){ 25290001Sglebius switch (status) { 26181834Sroberto case nlm_granted: 27290001Sglebius case nlm_lck_denied: 28290001Sglebius case nlm_lck_denied_nolocks: 29290001Sglebius case nlm_lck_blocked: 30181834Sroberto case nlm_lck_denied_grace_period: 31181834Sroberto case nlm_drop_reply: 32181834Sroberto break; 33181834Sroberto case nlm4_deadlock: 34290001Sglebius status = nlm_lck_denied; 35290001Sglebius break; 36181834Sroberto default: 37181834Sroberto status = nlm_lck_denied_nolocks; 38290001Sglebius } 39290001Sglebius } 40181834Sroberto 41181834Sroberto return (status); 42290001Sglebius} 43290001Sglebius#define cast_status(status) (cast_to_nlm(status, rqstp->rq_vers)) 44181834Sroberto#else 45181834Sroberto#define cast_status(status) (status) 46181834Sroberto#endif 47290001Sglebius 48181834Sroberto/* 49181834Sroberto * Obtain client and file from arguments 50181834Sroberto */ 51181834Srobertostatic __be32 52290001Sglebiusnlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, 53290001Sglebius struct nlm_host **hostp, struct nlm_file **filp) 54181834Sroberto{ 55181834Sroberto struct nlm_host *host = NULL; 56181834Sroberto struct nlm_file *file = NULL; 57181834Sroberto struct nlm_lock *lock = &argp->lock; 58181834Sroberto int mode; 59181834Sroberto __be32 error = 0; 60181834Sroberto 61181834Sroberto /* nfsd callbacks must have been installed for this procedure */ 62181834Sroberto if (!nlmsvc_ops) 63181834Sroberto return nlm_lck_denied_nolocks; 64181834Sroberto 65181834Sroberto /* Obtain host handle */ 66290001Sglebius if (!(host = nlmsvc_lookup_host(rqstp, lock->caller, lock->len)) 67181834Sroberto || (argp->monitor && nsm_monitor(host) < 0)) 68181834Sroberto goto no_locks; 69181834Sroberto *hostp = host; 70181834Sroberto 71181834Sroberto /* Obtain file pointer. Not used by FREE_ALL call. */ 72181834Sroberto if (filp != NULL) { 73181834Sroberto error = cast_status(nlm_lookup_file(rqstp, &file, lock)); 74181834Sroberto if (error != 0) 75181834Sroberto goto no_locks; 76181834Sroberto *filp = file; 77181834Sroberto 78181834Sroberto /* Set up the missing parts of the file_lock structure */ 79181834Sroberto mode = lock_to_openmode(&lock->fl); 80181834Sroberto lock->fl.c.flc_flags = FL_POSIX; 81181834Sroberto lock->fl.c.flc_file = file->f_file[mode]; 82290001Sglebius lock->fl.c.flc_pid = current->tgid; 83181834Sroberto lock->fl.fl_lmops = &nlmsvc_lock_operations; 84181834Sroberto nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid); 85290001Sglebius if (!lock->fl.c.flc_owner) { 86181834Sroberto /* lockowner allocation has failed */ 87181834Sroberto nlmsvc_release_host(host); 88181834Sroberto return nlm_lck_denied_nolocks; 89181834Sroberto } 90290001Sglebius } 91290001Sglebius 92181834Sroberto return 0; 93181834Sroberto 94181834Srobertono_locks: 95181834Sroberto nlmsvc_release_host(host); 96181834Sroberto if (error) 97181834Sroberto return error; 98181834Sroberto return nlm_lck_denied_nolocks; 99181834Sroberto} 100181834Sroberto 101181834Sroberto/* 102181834Sroberto * NULL: Test for presence of service 103290001Sglebius */ 104181834Srobertostatic __be32 105181834Srobertonlmsvc_proc_null(struct svc_rqst *rqstp) 106181834Sroberto{ 107181834Sroberto dprintk("lockd: NULL called\n"); 108181834Sroberto return rpc_success; 109181834Sroberto} 110181834Sroberto 111181834Sroberto/* 112181834Sroberto * TEST: Check for conflicting lock 113181834Sroberto */ 114181834Srobertostatic __be32 115181834Sroberto__nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_res *resp) 116181834Sroberto{ 117181834Sroberto struct nlm_args *argp = rqstp->rq_argp; 118181834Sroberto struct nlm_host *host; 119290001Sglebius struct nlm_file *file; 120181834Sroberto struct nlm_lockowner *test_owner; 121181834Sroberto __be32 rc = rpc_success; 122290001Sglebius 123290001Sglebius dprintk("lockd: TEST called\n"); 124290001Sglebius resp->cookie = argp->cookie; 125181834Sroberto 126181834Sroberto /* Obtain client and file */ 127181834Sroberto if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) 128181834Sroberto return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; 129181834Sroberto 130181834Sroberto test_owner = argp->lock.fl.c.flc_owner; 131181834Sroberto 132181834Sroberto /* Now check for conflicting locks */ 133290001Sglebius resp->status = cast_status(nlmsvc_testlock(rqstp, file, host, &argp->lock, &resp->lock, &resp->cookie)); 134290001Sglebius if (resp->status == nlm_drop_reply) 135181834Sroberto rc = rpc_drop_reply; 136290001Sglebius else 137290001Sglebius dprintk("lockd: TEST status %d vers %d\n", 138181834Sroberto ntohl(resp->status), rqstp->rq_vers); 139181834Sroberto 140181834Sroberto nlmsvc_put_lockowner(test_owner); 141181834Sroberto nlmsvc_release_host(host); 142181834Sroberto nlm_release_file(file); 143181834Sroberto return rc; 144290001Sglebius} 145181834Sroberto 146181834Srobertostatic __be32 147181834Srobertonlmsvc_proc_test(struct svc_rqst *rqstp) 148181834Sroberto{ 149181834Sroberto return __nlmsvc_proc_test(rqstp, rqstp->rq_resp); 150181834Sroberto} 151290001Sglebius 152181834Srobertostatic __be32 153181834Sroberto__nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_res *resp) 154290001Sglebius{ 155290001Sglebius struct nlm_args *argp = rqstp->rq_argp; 156290001Sglebius struct nlm_host *host; 157290001Sglebius struct nlm_file *file; 158181834Sroberto __be32 rc = rpc_success; 159181834Sroberto 160181834Sroberto dprintk("lockd: LOCK called\n"); 161181834Sroberto 162181834Sroberto resp->cookie = argp->cookie; 163181834Sroberto 164181834Sroberto /* Obtain client and file */ 165290001Sglebius if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) 166290001Sglebius return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; 167181834Sroberto 168290001Sglebius#if 0 169290001Sglebius /* If supplied state doesn't match current state, we assume it's 170181834Sroberto * an old request that time-warped somehow. Any error return would 171181834Sroberto * do in this case because it's irrelevant anyway. 172181834Sroberto * 173181834Sroberto * NB: We don't retrieve the remote host's state yet. 174181834Sroberto */ 175181834Sroberto if (host->h_nsmstate && host->h_nsmstate != argp->state) { 176181834Sroberto resp->status = nlm_lck_denied_nolocks; 177181834Sroberto } else 178181834Sroberto#endif 179181834Sroberto 180181834Sroberto /* Now try to lock the file */ 181181834Sroberto resp->status = cast_status(nlmsvc_lock(rqstp, file, host, &argp->lock, 182290001Sglebius argp->block, &argp->cookie, 183181834Sroberto argp->reclaim)); 184290001Sglebius if (resp->status == nlm_drop_reply) 185290001Sglebius rc = rpc_drop_reply; 186290001Sglebius else 187290001Sglebius dprintk("lockd: LOCK status %d\n", ntohl(resp->status)); 188181834Sroberto 189181834Sroberto nlmsvc_release_lockowner(&argp->lock); 190181834Sroberto nlmsvc_release_host(host); 191181834Sroberto nlm_release_file(file); 192181834Sroberto return rc; 193181834Sroberto} 194290001Sglebius 195290001Sglebiusstatic __be32 196181834Srobertonlmsvc_proc_lock(struct svc_rqst *rqstp) 197181834Sroberto{ 198181834Sroberto return __nlmsvc_proc_lock(rqstp, rqstp->rq_resp); 199181834Sroberto} 200181834Sroberto 201290001Sglebiusstatic __be32 202290001Sglebius__nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_res *resp) 203181834Sroberto{ 204181834Sroberto struct nlm_args *argp = rqstp->rq_argp; 205290001Sglebius struct nlm_host *host; 206181834Sroberto struct nlm_file *file; 207290001Sglebius struct net *net = SVC_NET(rqstp); 208181834Sroberto 209181834Sroberto dprintk("lockd: CANCEL called\n"); 210181834Sroberto 211290001Sglebius resp->cookie = argp->cookie; 212290001Sglebius 213181834Sroberto /* Don't accept requests during grace period */ 214181834Sroberto if (locks_in_grace(net)) { 215181834Sroberto resp->status = nlm_lck_denied_grace_period; 216181834Sroberto return rpc_success; 217181834Sroberto } 218181834Sroberto 219181834Sroberto /* Obtain client and file */ 220290001Sglebius if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) 221181834Sroberto return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; 222181834Sroberto 223181834Sroberto /* Try to cancel request. */ 224181834Sroberto resp->status = cast_status(nlmsvc_cancel_blocked(net, file, &argp->lock)); 225181834Sroberto 226181834Sroberto dprintk("lockd: CANCEL status %d\n", ntohl(resp->status)); 227290001Sglebius nlmsvc_release_lockowner(&argp->lock); 228181834Sroberto nlmsvc_release_host(host); 229181834Sroberto nlm_release_file(file); 230181834Sroberto return rpc_success; 231181834Sroberto} 232290001Sglebius 233290001Sglebiusstatic __be32 234290001Sglebiusnlmsvc_proc_cancel(struct svc_rqst *rqstp) 235181834Sroberto{ 236181834Sroberto return __nlmsvc_proc_cancel(rqstp, rqstp->rq_resp); 237181834Sroberto} 238290001Sglebius 239181834Sroberto/* 240181834Sroberto * UNLOCK: release a lock 241181834Sroberto */ 242181834Srobertostatic __be32 243290001Sglebius__nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_res *resp) 244181834Sroberto{ 245181834Sroberto struct nlm_args *argp = rqstp->rq_argp; 246181834Sroberto struct nlm_host *host; 247181834Sroberto struct nlm_file *file; 248181834Sroberto struct net *net = SVC_NET(rqstp); 249181834Sroberto 250181834Sroberto dprintk("lockd: UNLOCK called\n"); 251290001Sglebius 252290001Sglebius resp->cookie = argp->cookie; 253290001Sglebius 254181834Sroberto /* Don't accept new lock requests during grace period */ 255181834Sroberto if (locks_in_grace(net)) { 256290001Sglebius resp->status = nlm_lck_denied_grace_period; 257181834Sroberto return rpc_success; 258181834Sroberto } 259181834Sroberto 260181834Sroberto /* Obtain client and file */ 261181834Sroberto if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) 262181834Sroberto return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; 263181834Sroberto 264181834Sroberto /* Now try to remove the lock */ 265290001Sglebius resp->status = cast_status(nlmsvc_unlock(net, file, &argp->lock)); 266290001Sglebius 267181834Sroberto dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status)); 268290001Sglebius nlmsvc_release_lockowner(&argp->lock); 269181834Sroberto nlmsvc_release_host(host); 270181834Sroberto nlm_release_file(file); 271181834Sroberto return rpc_success; 272290001Sglebius} 273181834Sroberto 274181834Srobertostatic __be32 275181834Srobertonlmsvc_proc_unlock(struct svc_rqst *rqstp) 276181834Sroberto{ 277181834Sroberto return __nlmsvc_proc_unlock(rqstp, rqstp->rq_resp); 278181834Sroberto} 279181834Sroberto 280181834Sroberto/* 281181834Sroberto * GRANTED: A server calls us to tell that a process' lock request 282290001Sglebius * was granted 283181834Sroberto */ 284181834Srobertostatic __be32 285181834Sroberto__nlmsvc_proc_granted(struct svc_rqst *rqstp, struct nlm_res *resp) 286181834Sroberto{ 287181834Sroberto struct nlm_args *argp = rqstp->rq_argp; 288181834Sroberto 289181834Sroberto resp->cookie = argp->cookie; 290181834Sroberto 291290001Sglebius dprintk("lockd: GRANTED called\n"); 292290001Sglebius resp->status = nlmclnt_grant(svc_addr(rqstp), &argp->lock); 293181834Sroberto dprintk("lockd: GRANTED status %d\n", ntohl(resp->status)); 294181834Sroberto return rpc_success; 295181834Sroberto} 296181834Sroberto 297181834Srobertostatic __be32 298290001Sglebiusnlmsvc_proc_granted(struct svc_rqst *rqstp) 299181834Sroberto{ 300181834Sroberto return __nlmsvc_proc_granted(rqstp, rqstp->rq_resp); 301181834Sroberto} 302181834Sroberto 303181834Sroberto/* 304290001Sglebius * This is the generic lockd callback for async RPC calls 305181834Sroberto */ 306181834Srobertostatic void nlmsvc_callback_exit(struct rpc_task *task, void *data) 307181834Sroberto{ 308181834Sroberto} 309181834Sroberto 310181834Srobertovoid nlmsvc_release_call(struct nlm_rqst *call) 311181834Sroberto{ 312290001Sglebius if (!refcount_dec_and_test(&call->a_count)) 313290001Sglebius return; 314181834Sroberto nlmsvc_release_host(call->a_host); 315181834Sroberto kfree(call); 316181834Sroberto} 317290001Sglebius 318290001Sglebiusstatic void nlmsvc_callback_release(void *data) 319181834Sroberto{ 320290001Sglebius nlmsvc_release_call(data); 321290001Sglebius} 322181834Sroberto 323181834Srobertostatic const struct rpc_call_ops nlmsvc_callback_ops = { 324290001Sglebius .rpc_call_done = nlmsvc_callback_exit, 325290001Sglebius .rpc_release = nlmsvc_callback_release, 326181834Sroberto}; 327181834Sroberto 328181834Sroberto/* 329181834Sroberto * `Async' versions of the above service routines. They aren't really, 330181834Sroberto * because we send the callback before the reply proper. I hope this 331181834Sroberto * doesn't break any clients. 332181834Sroberto */ 333290001Sglebiusstatic __be32 nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, 334290001Sglebius __be32 (*func)(struct svc_rqst *, struct nlm_res *)) 335181834Sroberto{ 336181834Sroberto struct nlm_args *argp = rqstp->rq_argp; 337181834Sroberto struct nlm_host *host; 338181834Sroberto struct nlm_rqst *call; 339181834Sroberto __be32 stat; 340181834Sroberto 341 host = nlmsvc_lookup_host(rqstp, 342 argp->lock.caller, 343 argp->lock.len); 344 if (host == NULL) 345 return rpc_system_err; 346 347 call = nlm_alloc_call(host); 348 nlmsvc_release_host(host); 349 if (call == NULL) 350 return rpc_system_err; 351 352 stat = func(rqstp, &call->a_res); 353 if (stat != 0) { 354 nlmsvc_release_call(call); 355 return stat; 356 } 357 358 call->a_flags = RPC_TASK_ASYNC; 359 if (nlm_async_reply(call, proc, &nlmsvc_callback_ops) < 0) 360 return rpc_system_err; 361 return rpc_success; 362} 363 364static __be32 nlmsvc_proc_test_msg(struct svc_rqst *rqstp) 365{ 366 dprintk("lockd: TEST_MSG called\n"); 367 return nlmsvc_callback(rqstp, NLMPROC_TEST_RES, __nlmsvc_proc_test); 368} 369 370static __be32 nlmsvc_proc_lock_msg(struct svc_rqst *rqstp) 371{ 372 dprintk("lockd: LOCK_MSG called\n"); 373 return nlmsvc_callback(rqstp, NLMPROC_LOCK_RES, __nlmsvc_proc_lock); 374} 375 376static __be32 nlmsvc_proc_cancel_msg(struct svc_rqst *rqstp) 377{ 378 dprintk("lockd: CANCEL_MSG called\n"); 379 return nlmsvc_callback(rqstp, NLMPROC_CANCEL_RES, __nlmsvc_proc_cancel); 380} 381 382static __be32 383nlmsvc_proc_unlock_msg(struct svc_rqst *rqstp) 384{ 385 dprintk("lockd: UNLOCK_MSG called\n"); 386 return nlmsvc_callback(rqstp, NLMPROC_UNLOCK_RES, __nlmsvc_proc_unlock); 387} 388 389static __be32 390nlmsvc_proc_granted_msg(struct svc_rqst *rqstp) 391{ 392 dprintk("lockd: GRANTED_MSG called\n"); 393 return nlmsvc_callback(rqstp, NLMPROC_GRANTED_RES, __nlmsvc_proc_granted); 394} 395 396/* 397 * SHARE: create a DOS share or alter existing share. 398 */ 399static __be32 400nlmsvc_proc_share(struct svc_rqst *rqstp) 401{ 402 struct nlm_args *argp = rqstp->rq_argp; 403 struct nlm_res *resp = rqstp->rq_resp; 404 struct nlm_host *host; 405 struct nlm_file *file; 406 407 dprintk("lockd: SHARE called\n"); 408 409 resp->cookie = argp->cookie; 410 411 /* Don't accept new lock requests during grace period */ 412 if (locks_in_grace(SVC_NET(rqstp)) && !argp->reclaim) { 413 resp->status = nlm_lck_denied_grace_period; 414 return rpc_success; 415 } 416 417 /* Obtain client and file */ 418 if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) 419 return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; 420 421 /* Now try to create the share */ 422 resp->status = cast_status(nlmsvc_share_file(host, file, argp)); 423 424 dprintk("lockd: SHARE status %d\n", ntohl(resp->status)); 425 nlmsvc_release_lockowner(&argp->lock); 426 nlmsvc_release_host(host); 427 nlm_release_file(file); 428 return rpc_success; 429} 430 431/* 432 * UNSHARE: Release a DOS share. 433 */ 434static __be32 435nlmsvc_proc_unshare(struct svc_rqst *rqstp) 436{ 437 struct nlm_args *argp = rqstp->rq_argp; 438 struct nlm_res *resp = rqstp->rq_resp; 439 struct nlm_host *host; 440 struct nlm_file *file; 441 442 dprintk("lockd: UNSHARE called\n"); 443 444 resp->cookie = argp->cookie; 445 446 /* Don't accept requests during grace period */ 447 if (locks_in_grace(SVC_NET(rqstp))) { 448 resp->status = nlm_lck_denied_grace_period; 449 return rpc_success; 450 } 451 452 /* Obtain client and file */ 453 if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) 454 return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; 455 456 /* Now try to unshare the file */ 457 resp->status = cast_status(nlmsvc_unshare_file(host, file, argp)); 458 459 dprintk("lockd: UNSHARE status %d\n", ntohl(resp->status)); 460 nlmsvc_release_lockowner(&argp->lock); 461 nlmsvc_release_host(host); 462 nlm_release_file(file); 463 return rpc_success; 464} 465 466/* 467 * NM_LOCK: Create an unmonitored lock 468 */ 469static __be32 470nlmsvc_proc_nm_lock(struct svc_rqst *rqstp) 471{ 472 struct nlm_args *argp = rqstp->rq_argp; 473 474 dprintk("lockd: NM_LOCK called\n"); 475 476 argp->monitor = 0; /* just clean the monitor flag */ 477 return nlmsvc_proc_lock(rqstp); 478} 479 480/* 481 * FREE_ALL: Release all locks and shares held by client 482 */ 483static __be32 484nlmsvc_proc_free_all(struct svc_rqst *rqstp) 485{ 486 struct nlm_args *argp = rqstp->rq_argp; 487 struct nlm_host *host; 488 489 /* Obtain client */ 490 if (nlmsvc_retrieve_args(rqstp, argp, &host, NULL)) 491 return rpc_success; 492 493 nlmsvc_free_host_resources(host); 494 nlmsvc_release_host(host); 495 return rpc_success; 496} 497 498/* 499 * SM_NOTIFY: private callback from statd (not part of official NLM proto) 500 */ 501static __be32 502nlmsvc_proc_sm_notify(struct svc_rqst *rqstp) 503{ 504 struct nlm_reboot *argp = rqstp->rq_argp; 505 506 dprintk("lockd: SM_NOTIFY called\n"); 507 508 if (!nlm_privileged_requester(rqstp)) { 509 char buf[RPC_MAX_ADDRBUFLEN]; 510 printk(KERN_WARNING "lockd: rejected NSM callback from %s\n", 511 svc_print_addr(rqstp, buf, sizeof(buf))); 512 return rpc_system_err; 513 } 514 515 nlm_host_rebooted(SVC_NET(rqstp), argp); 516 return rpc_success; 517} 518 519/* 520 * client sent a GRANTED_RES, let's remove the associated block 521 */ 522static __be32 523nlmsvc_proc_granted_res(struct svc_rqst *rqstp) 524{ 525 struct nlm_res *argp = rqstp->rq_argp; 526 527 if (!nlmsvc_ops) 528 return rpc_success; 529 530 dprintk("lockd: GRANTED_RES called\n"); 531 532 nlmsvc_grant_reply(&argp->cookie, argp->status); 533 return rpc_success; 534} 535 536static __be32 537nlmsvc_proc_unused(struct svc_rqst *rqstp) 538{ 539 return rpc_proc_unavail; 540} 541 542/* 543 * NLM Server procedures. 544 */ 545 546struct nlm_void { int dummy; }; 547 548#define Ck (1+XDR_QUADLEN(NLM_MAXCOOKIELEN)) /* cookie */ 549#define St 1 /* status */ 550#define No (1+1024/4) /* Net Obj */ 551#define Rg 2 /* range - offset + size */ 552 553const struct svc_procedure nlmsvc_procedures[24] = { 554 [NLMPROC_NULL] = { 555 .pc_func = nlmsvc_proc_null, 556 .pc_decode = nlmsvc_decode_void, 557 .pc_encode = nlmsvc_encode_void, 558 .pc_argsize = sizeof(struct nlm_void), 559 .pc_argzero = sizeof(struct nlm_void), 560 .pc_ressize = sizeof(struct nlm_void), 561 .pc_xdrressize = St, 562 .pc_name = "NULL", 563 }, 564 [NLMPROC_TEST] = { 565 .pc_func = nlmsvc_proc_test, 566 .pc_decode = nlmsvc_decode_testargs, 567 .pc_encode = nlmsvc_encode_testres, 568 .pc_argsize = sizeof(struct nlm_args), 569 .pc_argzero = sizeof(struct nlm_args), 570 .pc_ressize = sizeof(struct nlm_res), 571 .pc_xdrressize = Ck+St+2+No+Rg, 572 .pc_name = "TEST", 573 }, 574 [NLMPROC_LOCK] = { 575 .pc_func = nlmsvc_proc_lock, 576 .pc_decode = nlmsvc_decode_lockargs, 577 .pc_encode = nlmsvc_encode_res, 578 .pc_argsize = sizeof(struct nlm_args), 579 .pc_argzero = sizeof(struct nlm_args), 580 .pc_ressize = sizeof(struct nlm_res), 581 .pc_xdrressize = Ck+St, 582 .pc_name = "LOCK", 583 }, 584 [NLMPROC_CANCEL] = { 585 .pc_func = nlmsvc_proc_cancel, 586 .pc_decode = nlmsvc_decode_cancargs, 587 .pc_encode = nlmsvc_encode_res, 588 .pc_argsize = sizeof(struct nlm_args), 589 .pc_argzero = sizeof(struct nlm_args), 590 .pc_ressize = sizeof(struct nlm_res), 591 .pc_xdrressize = Ck+St, 592 .pc_name = "CANCEL", 593 }, 594 [NLMPROC_UNLOCK] = { 595 .pc_func = nlmsvc_proc_unlock, 596 .pc_decode = nlmsvc_decode_unlockargs, 597 .pc_encode = nlmsvc_encode_res, 598 .pc_argsize = sizeof(struct nlm_args), 599 .pc_argzero = sizeof(struct nlm_args), 600 .pc_ressize = sizeof(struct nlm_res), 601 .pc_xdrressize = Ck+St, 602 .pc_name = "UNLOCK", 603 }, 604 [NLMPROC_GRANTED] = { 605 .pc_func = nlmsvc_proc_granted, 606 .pc_decode = nlmsvc_decode_testargs, 607 .pc_encode = nlmsvc_encode_res, 608 .pc_argsize = sizeof(struct nlm_args), 609 .pc_argzero = sizeof(struct nlm_args), 610 .pc_ressize = sizeof(struct nlm_res), 611 .pc_xdrressize = Ck+St, 612 .pc_name = "GRANTED", 613 }, 614 [NLMPROC_TEST_MSG] = { 615 .pc_func = nlmsvc_proc_test_msg, 616 .pc_decode = nlmsvc_decode_testargs, 617 .pc_encode = nlmsvc_encode_void, 618 .pc_argsize = sizeof(struct nlm_args), 619 .pc_argzero = sizeof(struct nlm_args), 620 .pc_ressize = sizeof(struct nlm_void), 621 .pc_xdrressize = St, 622 .pc_name = "TEST_MSG", 623 }, 624 [NLMPROC_LOCK_MSG] = { 625 .pc_func = nlmsvc_proc_lock_msg, 626 .pc_decode = nlmsvc_decode_lockargs, 627 .pc_encode = nlmsvc_encode_void, 628 .pc_argsize = sizeof(struct nlm_args), 629 .pc_argzero = sizeof(struct nlm_args), 630 .pc_ressize = sizeof(struct nlm_void), 631 .pc_xdrressize = St, 632 .pc_name = "LOCK_MSG", 633 }, 634 [NLMPROC_CANCEL_MSG] = { 635 .pc_func = nlmsvc_proc_cancel_msg, 636 .pc_decode = nlmsvc_decode_cancargs, 637 .pc_encode = nlmsvc_encode_void, 638 .pc_argsize = sizeof(struct nlm_args), 639 .pc_argzero = sizeof(struct nlm_args), 640 .pc_ressize = sizeof(struct nlm_void), 641 .pc_xdrressize = St, 642 .pc_name = "CANCEL_MSG", 643 }, 644 [NLMPROC_UNLOCK_MSG] = { 645 .pc_func = nlmsvc_proc_unlock_msg, 646 .pc_decode = nlmsvc_decode_unlockargs, 647 .pc_encode = nlmsvc_encode_void, 648 .pc_argsize = sizeof(struct nlm_args), 649 .pc_argzero = sizeof(struct nlm_args), 650 .pc_ressize = sizeof(struct nlm_void), 651 .pc_xdrressize = St, 652 .pc_name = "UNLOCK_MSG", 653 }, 654 [NLMPROC_GRANTED_MSG] = { 655 .pc_func = nlmsvc_proc_granted_msg, 656 .pc_decode = nlmsvc_decode_testargs, 657 .pc_encode = nlmsvc_encode_void, 658 .pc_argsize = sizeof(struct nlm_args), 659 .pc_argzero = sizeof(struct nlm_args), 660 .pc_ressize = sizeof(struct nlm_void), 661 .pc_xdrressize = St, 662 .pc_name = "GRANTED_MSG", 663 }, 664 [NLMPROC_TEST_RES] = { 665 .pc_func = nlmsvc_proc_null, 666 .pc_decode = nlmsvc_decode_void, 667 .pc_encode = nlmsvc_encode_void, 668 .pc_argsize = sizeof(struct nlm_res), 669 .pc_argzero = sizeof(struct nlm_res), 670 .pc_ressize = sizeof(struct nlm_void), 671 .pc_xdrressize = St, 672 .pc_name = "TEST_RES", 673 }, 674 [NLMPROC_LOCK_RES] = { 675 .pc_func = nlmsvc_proc_null, 676 .pc_decode = nlmsvc_decode_void, 677 .pc_encode = nlmsvc_encode_void, 678 .pc_argsize = sizeof(struct nlm_res), 679 .pc_argzero = sizeof(struct nlm_res), 680 .pc_ressize = sizeof(struct nlm_void), 681 .pc_xdrressize = St, 682 .pc_name = "LOCK_RES", 683 }, 684 [NLMPROC_CANCEL_RES] = { 685 .pc_func = nlmsvc_proc_null, 686 .pc_decode = nlmsvc_decode_void, 687 .pc_encode = nlmsvc_encode_void, 688 .pc_argsize = sizeof(struct nlm_res), 689 .pc_argzero = sizeof(struct nlm_res), 690 .pc_ressize = sizeof(struct nlm_void), 691 .pc_xdrressize = St, 692 .pc_name = "CANCEL_RES", 693 }, 694 [NLMPROC_UNLOCK_RES] = { 695 .pc_func = nlmsvc_proc_null, 696 .pc_decode = nlmsvc_decode_void, 697 .pc_encode = nlmsvc_encode_void, 698 .pc_argsize = sizeof(struct nlm_res), 699 .pc_argzero = sizeof(struct nlm_res), 700 .pc_ressize = sizeof(struct nlm_void), 701 .pc_xdrressize = St, 702 .pc_name = "UNLOCK_RES", 703 }, 704 [NLMPROC_GRANTED_RES] = { 705 .pc_func = nlmsvc_proc_granted_res, 706 .pc_decode = nlmsvc_decode_res, 707 .pc_encode = nlmsvc_encode_void, 708 .pc_argsize = sizeof(struct nlm_res), 709 .pc_argzero = sizeof(struct nlm_res), 710 .pc_ressize = sizeof(struct nlm_void), 711 .pc_xdrressize = St, 712 .pc_name = "GRANTED_RES", 713 }, 714 [NLMPROC_NSM_NOTIFY] = { 715 .pc_func = nlmsvc_proc_sm_notify, 716 .pc_decode = nlmsvc_decode_reboot, 717 .pc_encode = nlmsvc_encode_void, 718 .pc_argsize = sizeof(struct nlm_reboot), 719 .pc_argzero = sizeof(struct nlm_reboot), 720 .pc_ressize = sizeof(struct nlm_void), 721 .pc_xdrressize = St, 722 .pc_name = "SM_NOTIFY", 723 }, 724 [17] = { 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_argzero = sizeof(struct nlm_void), 730 .pc_ressize = sizeof(struct nlm_void), 731 .pc_xdrressize = St, 732 .pc_name = "UNUSED", 733 }, 734 [18] = { 735 .pc_func = nlmsvc_proc_unused, 736 .pc_decode = nlmsvc_decode_void, 737 .pc_encode = nlmsvc_encode_void, 738 .pc_argsize = sizeof(struct nlm_void), 739 .pc_argzero = sizeof(struct nlm_void), 740 .pc_ressize = sizeof(struct nlm_void), 741 .pc_xdrressize = St, 742 .pc_name = "UNUSED", 743 }, 744 [19] = { 745 .pc_func = nlmsvc_proc_unused, 746 .pc_decode = nlmsvc_decode_void, 747 .pc_encode = nlmsvc_encode_void, 748 .pc_argsize = sizeof(struct nlm_void), 749 .pc_argzero = sizeof(struct nlm_void), 750 .pc_ressize = sizeof(struct nlm_void), 751 .pc_xdrressize = St, 752 .pc_name = "UNUSED", 753 }, 754 [NLMPROC_SHARE] = { 755 .pc_func = nlmsvc_proc_share, 756 .pc_decode = nlmsvc_decode_shareargs, 757 .pc_encode = nlmsvc_encode_shareres, 758 .pc_argsize = sizeof(struct nlm_args), 759 .pc_argzero = sizeof(struct nlm_args), 760 .pc_ressize = sizeof(struct nlm_res), 761 .pc_xdrressize = Ck+St+1, 762 .pc_name = "SHARE", 763 }, 764 [NLMPROC_UNSHARE] = { 765 .pc_func = nlmsvc_proc_unshare, 766 .pc_decode = nlmsvc_decode_shareargs, 767 .pc_encode = nlmsvc_encode_shareres, 768 .pc_argsize = sizeof(struct nlm_args), 769 .pc_argzero = sizeof(struct nlm_args), 770 .pc_ressize = sizeof(struct nlm_res), 771 .pc_xdrressize = Ck+St+1, 772 .pc_name = "UNSHARE", 773 }, 774 [NLMPROC_NM_LOCK] = { 775 .pc_func = nlmsvc_proc_nm_lock, 776 .pc_decode = nlmsvc_decode_lockargs, 777 .pc_encode = nlmsvc_encode_res, 778 .pc_argsize = sizeof(struct nlm_args), 779 .pc_argzero = sizeof(struct nlm_args), 780 .pc_ressize = sizeof(struct nlm_res), 781 .pc_xdrressize = Ck+St, 782 .pc_name = "NM_LOCK", 783 }, 784 [NLMPROC_FREE_ALL] = { 785 .pc_func = nlmsvc_proc_free_all, 786 .pc_decode = nlmsvc_decode_notify, 787 .pc_encode = nlmsvc_encode_void, 788 .pc_argsize = sizeof(struct nlm_args), 789 .pc_argzero = sizeof(struct nlm_args), 790 .pc_ressize = sizeof(struct nlm_void), 791 .pc_xdrressize = 0, 792 .pc_name = "FREE_ALL", 793 }, 794}; 795