1 /*
   2  * Copyright (c) 2008 Isilon Inc http://www.isilon.com/
   3  * Authors: Doug Rabson <dfr@rabson.org>
   4  * Developed with Red Inc: Alfred Perlstein <alfred@freebsd.org>
   5  *
   6  * Redistribution and use in source and binary forms, with or without
   7  * modification, are permitted provided that the following conditions
   8  * are met:
   9  * 1. Redistributions of source code must retain the above copyright
  10  *    notice, this list of conditions and the following disclaimer.
  11  * 2. Redistributions in binary form must reproduce the above copyright
  12  *    notice, this list of conditions and the following disclaimer in the
  13  *    documentation and/or other materials provided with the distribution.
  14  *
  15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  25  * SUCH DAMAGE.
  26  */
  27 
  28 /*
  29  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  30  * Copyright (c) 2012 by Delphix. All rights reserved.
  31  */
  32 
  33 /*
  34  * NFS Lock Manager, RPC service functions (nlm_..._svc)
  35  * Called via nlm_dispatch.c tables.
  36  *
  37  * Source code derived from FreeBSD nlm_prot_server.c
  38  *
  39  * The real service functions all use nlm4_... args and return
  40  * data types.  These wrappers convert older forms to and from
  41  * the new forms and call the nlm_do_... service functions.
  42  */
  43 
  44 #include <sys/param.h>
  45 #include <sys/systm.h>
  46 
  47 #include <rpcsvc/nlm_prot.h>
  48 #include "nlm_impl.h"
  49 
  50 /*
  51  * Convert between various versions of the protocol structures.
  52  */
  53 
  54 /*
  55  * Down-convert, for granted_1 call
  56  *
  57  * This converts a 64-bit lock to 32-bit form for our granted
  58  * call-back when we're dealing with a 32-bit NLM client.
  59  * Our NLM_LOCK handler ensures that any lock we grant to a
  60  * 32-bit client can be represented in 32-bits.  If the
  61  * ASSERTs here fire, then the call to nlm_init_flock in
  62  * nlm_do_lock has failed to restrict a 32-bit client to
  63  * 32-bit lock ranges.
  64  */
  65 static void
  66 nlm_convert_to_nlm_lock(struct nlm_lock *dst, struct nlm4_lock *src)
  67 {
  68         dst->caller_name = src->caller_name;
  69         dst->fh = src->fh;
  70         dst->oh = src->oh;
  71         dst->svid = src->svid;
  72         ASSERT(src->l_offset <= MAX_UOFF32);
  73         dst->l_offset = (uint32_t)src->l_offset;
  74         ASSERT(src->l_len <= MAX_UOFF32);
  75         dst->l_len = (uint32_t)src->l_len;
  76 }
  77 
  78 /*
  79  * Up-convert for v1 svc functions with a 32-bit lock range arg.
  80  * Note that lock range checks (like overflow) are done later,
  81  * in nlm_init_flock().
  82  */
  83 static void
  84 nlm_convert_to_nlm4_lock(struct nlm4_lock *dst, struct nlm_lock *src)
  85 {
  86 
  87         dst->caller_name = src->caller_name;
  88         dst->fh = src->fh;
  89         dst->oh = src->oh;
  90         dst->svid = src->svid;
  91         dst->l_offset = src->l_offset;
  92         dst->l_len = src->l_len;
  93 }
  94 
  95 static void
  96 nlm_convert_to_nlm4_share(struct nlm4_share *dst, struct nlm_share *src)
  97 {
  98 
  99         dst->caller_name = src->caller_name;
 100         dst->fh = src->fh;
 101         dst->oh = src->oh;
 102         dst->mode = src->mode;
 103         dst->access = src->access;
 104 }
 105 
 106 /*
 107  * Down-convert for v1 NLM_TEST or NLM_TEST_MSG response.
 108  * Note that nlm_do_test is careful to give us lock ranges
 109  * that can be represented with 32-bit values.  If the
 110  * ASSERTs here fire, then the code in nlm_do_test that
 111  * builds an nlm4_holder for a 32-bit client has failed to
 112  * restrict the reported conflicting lock range so it's a
 113  * valid 32-bit lock range.
 114  */
 115 static void
 116 nlm_convert_to_nlm_holder(struct nlm_holder *dst, struct nlm4_holder *src)
 117 {
 118         dst->exclusive = src->exclusive;
 119         dst->svid = src->svid;
 120         dst->oh = src->oh;
 121         ASSERT(src->l_offset <= MAX_UOFF32);
 122         dst->l_offset = (uint32_t)src->l_offset;
 123         ASSERT(src->l_len <= MAX_UOFF32);
 124         dst->l_len = (uint32_t)src->l_len;
 125 }
 126 
 127 static enum nlm_stats
 128 nlm_convert_to_nlm_stats(enum nlm4_stats src)
 129 {
 130         if (src > nlm4_deadlck)
 131                 return (nlm_denied);
 132         return ((enum nlm_stats)src);
 133 }
 134 
 135 static void
 136 nlm_convert_to_nlm_res(struct nlm_res *dst, struct nlm4_res *src)
 137 {
 138         dst->cookie = src->cookie;
 139         dst->stat.stat = nlm_convert_to_nlm_stats(src->stat.stat);
 140 }
 141 
 142 /* ******************************************************************** */
 143 
 144 /*
 145  * Version 1 svc functions
 146  */
 147 
 148 bool_t
 149 nlm_test_1_svc(struct nlm_testargs *argp, nlm_testres *resp,
 150     struct svc_req *sr)
 151 {
 152         nlm4_testargs args4;
 153         nlm4_testres res4;
 154 
 155         bzero(&args4, sizeof (args4));
 156         bzero(&res4, sizeof (res4));
 157 
 158         args4.cookie = argp->cookie;
 159         args4.exclusive = argp->exclusive;
 160         nlm_convert_to_nlm4_lock(&args4.alock, &argp->alock);
 161 
 162         nlm_do_test(&args4, &res4, sr, NULL);
 163 
 164         resp->cookie = res4.cookie;
 165         resp->stat.stat = nlm_convert_to_nlm_stats(res4.stat.stat);
 166         if (resp->stat.stat == nlm_denied)
 167                 nlm_convert_to_nlm_holder(
 168                     &resp->stat.nlm_testrply_u.holder,
 169                     &res4.stat.nlm4_testrply_u.holder);
 170 
 171         return (TRUE);
 172 }
 173 
 174 /*
 175  * Callback functions for nlm_lock_1_svc
 176  */
 177 static bool_t nlm_lock_1_reply(SVCXPRT *, nlm4_res *);
 178 static enum clnt_stat nlm_granted_1_cb(nlm4_testargs *, void *, CLIENT *);
 179 
 180 bool_t
 181 nlm_lock_1_svc(nlm_lockargs *argp, nlm_res *resp,
 182     struct svc_req *sr)
 183 {
 184         nlm4_lockargs args4;
 185         nlm4_res res4;
 186 
 187         bzero(&res4, sizeof (res4));
 188 
 189         args4.cookie = argp->cookie;
 190         args4.block = argp->block;
 191         args4.exclusive = argp->exclusive;
 192         nlm_convert_to_nlm4_lock(&args4.alock, &argp->alock);
 193         args4.reclaim = argp->reclaim;
 194         args4.state = argp->state;
 195 
 196         /* NLM_LOCK */
 197         nlm_do_lock(&args4, &res4, sr,
 198             nlm_lock_1_reply, NULL,
 199             nlm_granted_1_cb);
 200 
 201         /* for freeresult */
 202         nlm_convert_to_nlm_res(resp, &res4);
 203 
 204         /* above does its own reply */
 205         return (FALSE);
 206 }
 207 
 208 static bool_t
 209 nlm_lock_1_reply(SVCXPRT *transp, nlm4_res *resp)
 210 {
 211         nlm_res res1;
 212 
 213         nlm_convert_to_nlm_res(&res1, resp);
 214         return (svc_sendreply(transp, xdr_nlm_res, (char *)&res1));
 215 }
 216 
 217 static enum clnt_stat
 218 nlm_granted_1_cb(nlm4_testargs *argp, void *resp, CLIENT *clnt)
 219 {
 220         nlm_testargs args1;
 221         nlm_res res1;
 222         int rv;
 223 
 224         bzero(&res1, sizeof (res1));
 225 
 226         args1.cookie = argp->cookie;
 227         args1.exclusive = argp->exclusive;
 228         nlm_convert_to_nlm_lock(&args1.alock, &argp->alock);
 229 
 230         rv = nlm_granted_1(&args1, &res1, clnt);
 231 
 232         /* NB: We have a result our caller will not free. */
 233         xdr_free((xdrproc_t)xdr_nlm_res, (void *)&res1);
 234         (void) resp;
 235 
 236         return (rv);
 237 }
 238 
 239 bool_t
 240 nlm_cancel_1_svc(struct nlm_cancargs *argp, nlm_res *resp,
 241     struct svc_req *sr)
 242 {
 243         nlm4_cancargs args4;
 244         nlm4_res res4;
 245 
 246         bzero(&res4, sizeof (res4));
 247 
 248         args4.cookie = argp->cookie;
 249         args4.block = argp->block;
 250         args4.exclusive = argp->exclusive;
 251         nlm_convert_to_nlm4_lock(&args4.alock, &argp->alock);
 252 
 253         nlm_do_cancel(&args4, &res4, sr, NULL);
 254 
 255         nlm_convert_to_nlm_res(resp, &res4);
 256 
 257         return (TRUE);
 258 }
 259 
 260 bool_t
 261 nlm_unlock_1_svc(struct nlm_unlockargs *argp, nlm_res *resp,
 262     struct svc_req *sr)
 263 {
 264         nlm4_unlockargs args4;
 265         nlm4_res res4;
 266 
 267         bzero(&res4, sizeof (res4));
 268 
 269         args4.cookie = argp->cookie;
 270         nlm_convert_to_nlm4_lock(&args4.alock, &argp->alock);
 271 
 272         nlm_do_unlock(&args4, &res4, sr, NULL);
 273 
 274         nlm_convert_to_nlm_res(resp, &res4);
 275 
 276         return (TRUE);
 277 }
 278 
 279 bool_t
 280 nlm_granted_1_svc(struct nlm_testargs *argp, nlm_res *resp,
 281     struct svc_req *sr)
 282 {
 283         nlm4_testargs args4;
 284         nlm4_res res4;
 285 
 286         bzero(&res4, sizeof (res4));
 287 
 288         args4.cookie = argp->cookie;
 289         args4.exclusive = argp->exclusive;
 290         nlm_convert_to_nlm4_lock(&args4.alock, &argp->alock);
 291 
 292         nlm_do_granted(&args4, &res4, sr, NULL);
 293 
 294         nlm_convert_to_nlm_res(resp, &res4);
 295 
 296         return (TRUE);
 297 }
 298 
 299 /*
 300  * The _msg_ calls get no reply.  Instead, these callers
 301  * expect an RPC call to the corresponding _res function.
 302  * We pass this callback function to nlm_do_test so it will
 303  * use it to do the RPC callback, with the correct res type.
 304  *
 305  * The callback functions have nearly the same arg signature
 306  * as the client call functions so that many of those can be
 307  * optimized to nothing by the compiler.  Also, passing the
 308  * null result arg for these just to reduce warnings.
 309  *
 310  * See similar callbacks for other _msg functions below.
 311  */
 312 
 313 static enum clnt_stat nlm_test_res_1_cb(nlm4_testres *, void *, CLIENT *);
 314 
 315 bool_t
 316 nlm_test_msg_1_svc(struct nlm_testargs *argp, void *resp,
 317     struct svc_req *sr)
 318 {
 319         nlm4_testargs args4;
 320         nlm4_testres res4;
 321 
 322         bzero(&res4, sizeof (res4));
 323 
 324         args4.cookie = argp->cookie;
 325         args4.exclusive = argp->exclusive;
 326         nlm_convert_to_nlm4_lock(&args4.alock, &argp->alock);
 327 
 328         nlm_do_test(&args4, &res4, sr,
 329             nlm_test_res_1_cb);
 330 
 331         /* NB: We have a result our caller will not free. */
 332         xdr_free((xdrproc_t)xdr_nlm4_testres, (void *)&res4);
 333         (void) resp;
 334 
 335         /* The _msg_ calls get no reply. */
 336         return (FALSE);
 337 }
 338 
 339 static enum clnt_stat
 340 nlm_test_res_1_cb(nlm4_testres *res4, void *null, CLIENT *clnt)
 341 {
 342         nlm_testres res1;
 343 
 344         res1.cookie = res4->cookie;
 345         res1.stat.stat = nlm_convert_to_nlm_stats(res4->stat.stat);
 346         if (res1.stat.stat == nlm_denied)
 347                 nlm_convert_to_nlm_holder(
 348                     &res1.stat.nlm_testrply_u.holder,
 349                     &res4->stat.nlm4_testrply_u.holder);
 350 
 351         return (nlm_test_res_1(&res1, null, clnt));
 352 }
 353 
 354 /*
 355  * Callback functions for nlm_lock_msg_1_svc
 356  */
 357 static enum clnt_stat nlm_lock_res_1_cb(nlm4_res *, void *, CLIENT *);
 358 static enum clnt_stat nlm_granted_msg_1_cb(nlm4_testargs *, void *, CLIENT *);
 359 
 360 bool_t
 361 nlm_lock_msg_1_svc(nlm_lockargs *argp, void *resp,
 362     struct svc_req *sr)
 363 {
 364         nlm4_lockargs args4;
 365         nlm4_res res4;
 366 
 367         bzero(&res4, sizeof (res4));
 368 
 369         args4.cookie = argp->cookie;
 370         args4.block = argp->block;
 371         args4.exclusive = argp->exclusive;
 372         nlm_convert_to_nlm4_lock(&args4.alock, &argp->alock);
 373         args4.reclaim = argp->reclaim;
 374         args4.state = argp->state;
 375 
 376         /* NLM_LOCK_MSG */
 377         nlm_do_lock(&args4, &res4, sr,
 378             NULL, nlm_lock_res_1_cb,
 379             nlm_granted_msg_1_cb);
 380 
 381         /* NB: We have a result our caller will not free. */
 382         xdr_free((xdrproc_t)xdr_nlm4_res, (void *)&res4);
 383         (void) resp;
 384 
 385         /* The _msg_ calls get no reply. */
 386         return (FALSE);
 387 }
 388 
 389 static enum clnt_stat
 390 nlm_lock_res_1_cb(nlm4_res *resp, void *null, CLIENT *clnt)
 391 {
 392         nlm_res res1;
 393 
 394         nlm_convert_to_nlm_res(&res1, resp);
 395         return (nlm_lock_res_1(&res1, null, clnt));
 396 }
 397 
 398 static enum clnt_stat
 399 nlm_granted_msg_1_cb(nlm4_testargs *argp, void *null, CLIENT *clnt)
 400 {
 401         nlm_testargs args1;
 402 
 403         args1.cookie = argp->cookie;
 404         args1.exclusive = argp->exclusive;
 405         nlm_convert_to_nlm_lock(&args1.alock, &argp->alock);
 406 
 407         return (nlm_granted_msg_1(&args1, null, clnt));
 408 
 409 }
 410 
 411 
 412 static enum clnt_stat nlm_cancel_res_1_cb(nlm4_res *, void *, CLIENT *);
 413 
 414 bool_t
 415 nlm_cancel_msg_1_svc(struct nlm_cancargs *argp, void *resp,
 416     struct svc_req *sr)
 417 {
 418         nlm4_cancargs args4;
 419         nlm4_res res4;
 420 
 421         bzero(&res4, sizeof (res4));
 422 
 423         args4.cookie = argp->cookie;
 424         args4.block = argp->block;
 425         args4.exclusive = argp->exclusive;
 426         nlm_convert_to_nlm4_lock(&args4.alock, &argp->alock);
 427 
 428         nlm_do_cancel(&args4, &res4, sr,
 429             nlm_cancel_res_1_cb);
 430 
 431         /* NB: We have a result our caller will not free. */
 432         xdr_free((xdrproc_t)xdr_nlm4_res, (void *)&res4);
 433         (void) resp;
 434 
 435         /* The _msg_ calls get no reply. */
 436         return (FALSE);
 437 }
 438 
 439 static enum clnt_stat
 440 nlm_cancel_res_1_cb(nlm4_res *res4, void *null, CLIENT *clnt)
 441 {
 442         nlm_res res1;
 443 
 444         nlm_convert_to_nlm_res(&res1, res4);
 445         return (nlm_cancel_res_1(&res1, null, clnt));
 446 }
 447 
 448 
 449 static enum clnt_stat nlm_unlock_res_1_cb(nlm4_res *, void *, CLIENT *);
 450 
 451 bool_t
 452 nlm_unlock_msg_1_svc(struct nlm_unlockargs *argp, void *resp,
 453     struct svc_req *sr)
 454 {
 455         nlm4_unlockargs args4;
 456         nlm4_res res4;
 457 
 458         bzero(&res4, sizeof (res4));
 459 
 460         args4.cookie = argp->cookie;
 461         nlm_convert_to_nlm4_lock(&args4.alock, &argp->alock);
 462 
 463         nlm_do_unlock(&args4, &res4, sr,
 464             nlm_unlock_res_1_cb);
 465 
 466         /* NB: We have a result our caller will not free. */
 467         xdr_free((xdrproc_t)xdr_nlm4_res, (void *)&res4);
 468         (void) resp;
 469 
 470         /* The _msg_ calls get no reply. */
 471         return (FALSE);
 472 }
 473 
 474 static enum clnt_stat
 475 nlm_unlock_res_1_cb(nlm4_res *res4, void *null, CLIENT *clnt)
 476 {
 477         nlm_res res1;
 478 
 479         nlm_convert_to_nlm_res(&res1, res4);
 480         return (nlm_unlock_res_1(&res1, null, clnt));
 481 }
 482 
 483 
 484 static enum clnt_stat nlm_granted_res_1_cb(nlm4_res *, void *, CLIENT *);
 485 
 486 bool_t
 487 nlm_granted_msg_1_svc(struct nlm_testargs *argp, void *resp,
 488     struct svc_req *sr)
 489 {
 490         nlm4_testargs args4;
 491         nlm4_res res4;
 492 
 493         bzero(&res4, sizeof (res4));
 494 
 495         args4.cookie = argp->cookie;
 496         args4.exclusive = argp->exclusive;
 497         nlm_convert_to_nlm4_lock(&args4.alock, &argp->alock);
 498 
 499         nlm_do_granted(&args4, &res4, sr,
 500             nlm_granted_res_1_cb);
 501 
 502         /* NB: We have a result our caller will not free. */
 503         xdr_free((xdrproc_t)xdr_nlm4_res, (void *)&res4);
 504         (void) resp;
 505 
 506         /* The _msg_ calls get no reply. */
 507         return (FALSE);
 508 }
 509 
 510 static enum clnt_stat
 511 nlm_granted_res_1_cb(nlm4_res *res4, void *null, CLIENT *clnt)
 512 {
 513         nlm_res res1;
 514 
 515         nlm_convert_to_nlm_res(&res1, res4);
 516         return (nlm_granted_res_1(&res1, null, clnt));
 517 }
 518 
 519 /*
 520  * The _res_ calls get no reply.  These RPC calls are
 521  * "call backs" in response to RPC _msg_ calls.
 522  * We don't care about these responses.
 523  */
 524 
 525 /* ARGSUSED */
 526 bool_t
 527 nlm_test_res_1_svc(nlm_testres *argp, void *resp, struct svc_req *sr)
 528 {
 529         /* The _res_ calls get no reply. */
 530         return (FALSE);
 531 }
 532 
 533 /* ARGSUSED */
 534 bool_t
 535 nlm_lock_res_1_svc(nlm_res *argp, void *resp, struct svc_req *sr)
 536 {
 537         /* The _res_ calls get no reply. */
 538         return (FALSE);
 539 }
 540 
 541 /* ARGSUSED */
 542 bool_t
 543 nlm_cancel_res_1_svc(nlm_res *argp, void *resp, struct svc_req *sr)
 544 {
 545         /* The _res_ calls get no reply. */
 546         return (FALSE);
 547 }
 548 
 549 /* ARGSUSED */
 550 bool_t
 551 nlm_unlock_res_1_svc(nlm_res *argp, void *resp, struct svc_req *sr)
 552 {
 553         /* The _res_ calls get no reply. */
 554         return (FALSE);
 555 }
 556 
 557 /* ARGSUSED */
 558 bool_t
 559 nlm_granted_res_1_svc(nlm_res *argp, void *resp, struct svc_req *sr)
 560 {
 561         /* The _res_ calls get no reply. */
 562         return (FALSE);
 563 }
 564 
 565 /*
 566  * Version 2 svc functions (used by local statd)
 567  */
 568 
 569 bool_t
 570 nlm_sm_notify1_2_svc(struct nlm_sm_status *argp, void *resp,
 571     struct svc_req *sr)
 572 {
 573         nlm_do_notify1(argp, resp, sr);
 574         return (TRUE);
 575 }
 576 
 577 bool_t
 578 nlm_sm_notify2_2_svc(struct nlm_sm_status *argp, void *resp,
 579     struct svc_req *sr)
 580 {
 581         nlm_do_notify2(argp, resp, sr);
 582         return (TRUE);
 583 }
 584 
 585 /*
 586  * Version 3 svc functions
 587  */
 588 
 589 bool_t
 590 nlm_share_3_svc(nlm_shareargs *argp, nlm_shareres *resp,
 591     struct svc_req *sr)
 592 {
 593         nlm4_shareargs args4;
 594         nlm4_shareres res4;
 595 
 596         bzero(&res4, sizeof (res4));
 597 
 598         args4.cookie = argp->cookie;
 599         nlm_convert_to_nlm4_share(&args4.share, &argp->share);
 600         args4.reclaim = argp->reclaim;
 601 
 602         nlm_do_share(&args4, &res4, sr);
 603 
 604         resp->cookie = res4.cookie;
 605         resp->stat = nlm_convert_to_nlm_stats(res4.stat);
 606         resp->sequence = res4.sequence;
 607 
 608         return (TRUE);
 609 }
 610 
 611 bool_t
 612 nlm_unshare_3_svc(nlm_shareargs *argp, nlm_shareres *resp,
 613     struct svc_req *sr)
 614 {
 615         nlm4_shareargs args4;
 616         nlm4_shareres res4;
 617 
 618         bzero(&res4, sizeof (res4));
 619 
 620         args4.cookie = argp->cookie;
 621         nlm_convert_to_nlm4_share(&args4.share, &argp->share);
 622         args4.reclaim = argp->reclaim;
 623 
 624         nlm_do_unshare(&args4, &res4, sr);
 625 
 626         resp->cookie = res4.cookie;
 627         resp->stat = nlm_convert_to_nlm_stats(res4.stat);
 628         resp->sequence = res4.sequence;
 629 
 630         return (TRUE);
 631 }
 632 
 633 bool_t
 634 nlm_nm_lock_3_svc(nlm_lockargs *argp, nlm_res *resp, struct svc_req *sr)
 635 {
 636         nlm4_lockargs args4;
 637         nlm4_res res4;
 638 
 639         bzero(&res4, sizeof (res4));
 640 
 641         args4.cookie = argp->cookie;
 642         args4.block = argp->block;
 643         args4.exclusive = argp->exclusive;
 644         nlm_convert_to_nlm4_lock(&args4.alock, &argp->alock);
 645         args4.reclaim = argp->reclaim;
 646         args4.state = argp->state;
 647 
 648         /*
 649          * Don't allow blocking for non-monitored (nm_lock) calls.
 650          * These clients don't handle any callbacks, including
 651          * the granted call we make after a blocking lock.
 652          * Same reply callback as nlm_lock_1_svc
 653          */
 654         args4.block = FALSE;
 655 
 656         /* NLM_NM_LOCK */
 657         nlm_do_lock(&args4, &res4, sr,
 658             nlm_lock_1_reply, NULL,
 659             NULL); /* indicates non-monitored */
 660 
 661         /* for freeresult */
 662         nlm_convert_to_nlm_res(resp, &res4);
 663 
 664         /* above does its own reply */
 665         return (FALSE);
 666 }
 667 
 668 bool_t
 669 nlm_free_all_3_svc(nlm_notify *argp, void *resp, struct svc_req *sr)
 670 {
 671         struct nlm4_notify args4;
 672 
 673         args4.name = argp->name;
 674         args4.state = argp->state;
 675 
 676         nlm_do_free_all(&args4, resp, sr);
 677 
 678         return (TRUE);
 679 }
 680 
 681 /*
 682  * Version 4 svc functions
 683  */
 684 
 685 bool_t
 686 nlm4_test_4_svc(nlm4_testargs *argp, nlm4_testres *resp, struct svc_req *sr)
 687 {
 688         nlm_do_test(argp, resp, sr, NULL);
 689         return (TRUE);
 690 }
 691 
 692 /*
 693  * Callback functions for nlm4_lock_4_svc
 694  */
 695 static bool_t nlm4_lock_4_reply(SVCXPRT *, nlm4_res *);
 696 static enum clnt_stat nlm4_granted_4_cb(nlm4_testargs *, void *, CLIENT *);
 697 
 698 bool_t
 699 nlm4_lock_4_svc(nlm4_lockargs *argp, nlm4_res *resp,
 700     struct svc_req *sr)
 701 {
 702 
 703         /* NLM4_LOCK */
 704         nlm_do_lock(argp, resp, sr,
 705             nlm4_lock_4_reply, NULL,
 706             nlm4_granted_4_cb);
 707 
 708         /* above does its own reply */
 709         return (FALSE);
 710 }
 711 
 712 static bool_t
 713 nlm4_lock_4_reply(SVCXPRT *transp, nlm4_res *resp)
 714 {
 715         return (svc_sendreply(transp, xdr_nlm4_res, (char *)resp));
 716 }
 717 
 718 static enum clnt_stat
 719 nlm4_granted_4_cb(nlm4_testargs *argp, void *resp, CLIENT *clnt)
 720 {
 721         nlm4_res res4;
 722         int rv;
 723 
 724         bzero(&res4, sizeof (res4));
 725         rv = nlm4_granted_4(argp, &res4, clnt);
 726 
 727         /* NB: We have a result our caller will not free. */
 728         xdr_free((xdrproc_t)xdr_nlm4_res, (void *)&res4);
 729         (void) resp;
 730 
 731         return (rv);
 732 }
 733 
 734 bool_t
 735 nlm4_cancel_4_svc(nlm4_cancargs *argp, nlm4_res *resp, struct svc_req *sr)
 736 {
 737         nlm_do_cancel(argp, resp, sr, NULL);
 738         return (TRUE);
 739 }
 740 
 741 bool_t
 742 nlm4_unlock_4_svc(nlm4_unlockargs *argp, nlm4_res *resp, struct svc_req *sr)
 743 {
 744         nlm_do_unlock(argp, resp, sr, NULL);
 745         return (TRUE);
 746 }
 747 
 748 bool_t
 749 nlm4_granted_4_svc(nlm4_testargs *argp, nlm4_res *resp, struct svc_req *sr)
 750 {
 751         nlm_do_granted(argp, resp, sr, NULL);
 752         return (TRUE);
 753 }
 754 
 755 bool_t
 756 nlm4_test_msg_4_svc(nlm4_testargs *argp, void *resp, struct svc_req *sr)
 757 {
 758         nlm4_testres res4;
 759 
 760         bzero(&res4, sizeof (res4));
 761         nlm_do_test(argp, &res4, sr,
 762             nlm4_test_res_4);
 763 
 764         /* NB: We have a result our caller will not free. */
 765         xdr_free((xdrproc_t)xdr_nlm4_testres, (void *)&res4);
 766         (void) resp;
 767 
 768         /* The _msg_ calls get no reply. */
 769         return (FALSE);
 770 }
 771 
 772 /*
 773  * Callback functions for nlm4_lock_msg_4_svc
 774  * (using the RPC client stubs directly)
 775  */
 776 
 777 bool_t
 778 nlm4_lock_msg_4_svc(nlm4_lockargs *argp, void *resp,
 779     struct svc_req *sr)
 780 {
 781         nlm4_res res4;
 782 
 783         /* NLM4_LOCK_MSG */
 784         bzero(&res4, sizeof (res4));
 785         nlm_do_lock(argp, &res4, sr,
 786             NULL, nlm4_lock_res_4,
 787             nlm4_granted_msg_4);
 788 
 789         /* NB: We have a result our caller will not free. */
 790         xdr_free((xdrproc_t)xdr_nlm4_res, (void *)&res4);
 791         (void) resp;
 792 
 793         /* The _msg_ calls get no reply. */
 794         return (FALSE);
 795 }
 796 
 797 bool_t
 798 nlm4_cancel_msg_4_svc(nlm4_cancargs *argp, void *resp, struct svc_req *sr)
 799 {
 800         nlm4_res res4;
 801 
 802         bzero(&res4, sizeof (res4));
 803         nlm_do_cancel(argp, &res4, sr,
 804             nlm4_cancel_res_4);
 805 
 806         /* NB: We have a result our caller will not free. */
 807         xdr_free((xdrproc_t)xdr_nlm4_res, (void *)&res4);
 808         (void) resp;
 809 
 810         /* The _msg_ calls get no reply. */
 811         return (FALSE);
 812 }
 813 
 814 bool_t
 815 nlm4_unlock_msg_4_svc(nlm4_unlockargs *argp, void *resp, struct svc_req *sr)
 816 {
 817         nlm4_res res4;
 818 
 819         bzero(&res4, sizeof (res4));
 820         nlm_do_unlock(argp, &res4, sr,
 821             nlm4_unlock_res_4);
 822 
 823         /* NB: We have a result our caller will not free. */
 824         xdr_free((xdrproc_t)xdr_nlm4_res, (void *)&res4);
 825         (void) resp;
 826 
 827         /* The _msg_ calls get no reply. */
 828         return (FALSE);
 829 }
 830 
 831 bool_t
 832 nlm4_granted_msg_4_svc(nlm4_testargs *argp, void *resp, struct svc_req *sr)
 833 {
 834         nlm4_res res4;
 835 
 836         bzero(&res4, sizeof (res4));
 837         nlm_do_granted(argp, &res4, sr,
 838             nlm4_granted_res_4);
 839 
 840         /* NB: We have a result our caller will not free. */
 841         xdr_free((xdrproc_t)xdr_nlm4_res, (void *)&res4);
 842         (void) resp;
 843 
 844         /* The _msg_ calls get no reply. */
 845         return (FALSE);
 846 }
 847 
 848 /* ARGSUSED */
 849 bool_t
 850 nlm4_test_res_4_svc(nlm4_testres *argp, void *resp, struct svc_req *sr)
 851 {
 852         /* The _res_ calls get no reply. */
 853         return (FALSE);
 854 }
 855 
 856 /* ARGSUSED */
 857 bool_t
 858 nlm4_lock_res_4_svc(nlm4_res *argp, void *resp, struct svc_req *sr)
 859 {
 860         /* The _res_ calls get no reply. */
 861         return (FALSE);
 862 }
 863 
 864 /* ARGSUSED */
 865 bool_t
 866 nlm4_cancel_res_4_svc(nlm4_res *argp, void *resp, struct svc_req *sr)
 867 {
 868         /* The _res_ calls get no reply. */
 869         return (FALSE);
 870 }
 871 
 872 /* ARGSUSED */
 873 bool_t
 874 nlm4_unlock_res_4_svc(nlm4_res *argp, void *resp, struct svc_req *sr)
 875 {
 876         /* The _res_ calls get no reply. */
 877         return (FALSE);
 878 }
 879 
 880 /* ARGSUSED */
 881 bool_t
 882 nlm4_granted_res_4_svc(nlm4_res *argp, void *resp, struct svc_req *sr)
 883 {
 884         /* The _res_ calls get no reply. */
 885         return (FALSE);
 886 }
 887 
 888 /* ARGSUSED */
 889 bool_t
 890 nlm4_share_4_svc(nlm4_shareargs *argp, nlm4_shareres *resp,
 891     struct svc_req *sr)
 892 {
 893         nlm_do_share(argp, resp, sr);
 894         return (TRUE);
 895 }
 896 
 897 /* ARGSUSED */
 898 bool_t
 899 nlm4_unshare_4_svc(nlm4_shareargs *argp, nlm4_shareres *resp,
 900     struct svc_req *sr)
 901 {
 902         nlm_do_unshare(argp, resp, sr);
 903         return (TRUE);
 904 }
 905 
 906 bool_t
 907 nlm4_nm_lock_4_svc(nlm4_lockargs *argp, nlm4_res *resp, struct svc_req *sr)
 908 {
 909 
 910         /*
 911          * Don't allow blocking for non-monitored (nm_lock) calls.
 912          * These clients don't handle any callbacks, including
 913          * the granted call we make after a blocking lock.
 914          * Same reply callback as nlm4_lock_4_svc
 915          */
 916         argp->block = FALSE;
 917 
 918         /* NLM4_NM_LOCK */
 919         nlm_do_lock(argp, resp, sr,
 920             nlm4_lock_4_reply, NULL,
 921             NULL); /* indicates non-monitored */
 922 
 923         /* above does its own reply */
 924         return (FALSE);
 925 }
 926 
 927 bool_t
 928 nlm4_free_all_4_svc(nlm4_notify *argp, void *resp, struct svc_req *sr)
 929 {
 930         nlm_do_free_all(argp, resp, sr);
 931         return (TRUE);
 932 }