Print this page
11083 support NFS server in zone
Portions contributed by: Dan Kruchinin <dan.kruchinin@nexenta.com>
Portions contributed by: Stepan Zastupov <stepan.zastupov@gmail.com>
Portions contributed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Portions contributed by: Mike Zeller <mike@mikezeller.net>
Portions contributed by: Dan McDonald <danmcd@joyent.com>
Portions contributed by: Gordon Ross <gordon.w.ross@gmail.com>
Portions contributed by: Vitaliy Gusev <gusev.vitaliy@gmail.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Jason King <jbk@joyent.com>
Reviewed by: C Fraire <cfraire@me.com>
Change-Id: I22f289d357503f9b48a0bc2482cc4328a6d43d16

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/nfs/nfs4_dispatch.c
          +++ new/usr/src/uts/common/fs/nfs/nfs4_dispatch.c
↓ open down ↓ 16 lines elided ↑ open up ↑
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   */
  26   26  
       27 +/*
       28 + * Copyright 2018 Nexenta Systems, Inc.
       29 + */
       30 +
  27   31  #include <sys/systm.h>
  28   32  #include <sys/sdt.h>
  29   33  #include <rpc/types.h>
  30   34  #include <rpc/auth.h>
  31   35  #include <rpc/auth_unix.h>
  32   36  #include <rpc/auth_des.h>
  33   37  #include <rpc/svc.h>
  34   38  #include <rpc/xdr.h>
  35   39  #include <nfs/nfs4.h>
  36   40  #include <nfs/nfs_dispatch.h>
  37   41  #include <nfs/nfs4_drc.h>
  38   42  
  39   43  #define NFS4_MAX_MINOR_VERSION  0
  40   44  
  41   45  /*
  42      - * This is the duplicate request cache for NFSv4
  43      - */
  44      -rfs4_drc_t *nfs4_drc = NULL;
  45      -
  46      -/*
  47   46   * The default size of the duplicate request cache
  48   47   */
  49   48  uint32_t nfs4_drc_max = 8 * 1024;
  50   49  
  51   50  /*
  52   51   * The number of buckets we'd like to hash the
  53   52   * replies into.. do not change this on the fly.
  54   53   */
  55   54  uint32_t nfs4_drc_hash = 541;
  56   55  
↓ open down ↓ 30 lines elided ↑ open up ↑
  87   86          list_create(&(drc->dr_cache), sizeof (rfs4_dupreq_t),
  88   87              offsetof(rfs4_dupreq_t, dr_next));
  89   88  
  90   89          return (drc);
  91   90  }
  92   91  
  93   92  /*
  94   93   * Destroy a duplicate request cache.
  95   94   */
  96   95  void
  97      -rfs4_fini_drc(rfs4_drc_t *drc)
       96 +rfs4_fini_drc(void)
  98   97  {
       98 +        nfs4_srv_t *nsrv4 = nfs4_get_srv();
       99 +        rfs4_drc_t *drc = nsrv4->nfs4_drc;
  99  100          rfs4_dupreq_t *drp, *drp_next;
 100  101  
 101      -        ASSERT(drc);
 102      -
 103  102          /* iterate over the dr_cache and free the enties */
 104  103          for (drp = list_head(&(drc->dr_cache)); drp != NULL; drp = drp_next) {
 105  104  
 106  105                  if (drp->dr_state == NFS4_DUP_REPLAY)
 107  106                          rfs4_compound_free(&(drp->dr_res));
 108  107  
 109  108                  if (drp->dr_addr.buf != NULL)
 110  109                          kmem_free(drp->dr_addr.buf, drp->dr_addr.maxlen);
 111  110  
 112  111                  drp_next = list_next(&(drc->dr_cache), drp);
↓ open down ↓ 236 lines elided ↑ open up ↑
 349  348          return (NFS4_DUP_NEW);
 350  349  }
 351  350  
 352  351  /*
 353  352   *
 354  353   * This function handles the duplicate request cache,
 355  354   * NULL_PROC and COMPOUND procedure calls for NFSv4;
 356  355   *
 357  356   * Passed into this function are:-
 358  357   *
 359      - *      disp    A pointer to our dispatch table entry
 360      - *      req     The request to process
 361      - *      xprt    The server transport handle
 362      - *      ap      A pointer to the arguments
      358 + *      disp    A pointer to our dispatch table entry
      359 + *      req     The request to process
      360 + *      xprt    The server transport handle
      361 + *      ap      A pointer to the arguments
 363  362   *
 364  363   *
 365  364   * When appropriate this function is responsible for inserting
 366  365   * the reply into the duplicate cache or replaying an existing
 367  366   * cached reply.
 368  367   *
 369      - * dr_stat      reflects the state of the duplicate request that
 370      - *              has been inserted into or retrieved from the cache
      368 + * dr_stat      reflects the state of the duplicate request that
      369 + *              has been inserted into or retrieved from the cache
 371  370   *
 372  371   * drp          is the duplicate request entry
 373  372   *
 374  373   */
 375  374  int
 376      -rfs4_dispatch(struct rpcdisp *disp, struct svc_req *req,
 377      -                SVCXPRT *xprt, char *ap)
      375 +rfs4_dispatch(struct rpcdisp *disp, struct svc_req *req, SVCXPRT *xprt,
      376 +    char *ap)
 378  377  {
 379  378  
 380  379          COMPOUND4res     res_buf;
 381  380          COMPOUND4res    *rbp;
 382  381          COMPOUND4args   *cap;
 383  382          cred_t          *cr = NULL;
 384  383          int              error = 0;
 385  384          int              dis_flags = 0;
 386  385          int              dr_stat = NFS4_NOT_DUP;
 387  386          rfs4_dupreq_t   *drp = NULL;
 388  387          int              rv;
      388 +        nfs4_srv_t *nsrv4 = nfs4_get_srv();
      389 +        rfs4_drc_t *nfs4_drc = nsrv4->nfs4_drc;
 389  390  
 390  391          ASSERT(disp);
 391  392  
 392  393          /*
 393  394           * Short circuit the RPC_NULL proc.
 394  395           */
 395  396          if (disp->dis_proc == rpc_null) {
 396  397                  DTRACE_NFSV4_1(null__start, struct svc_req *, req);
 397  398                  if (!svc_sendreply(xprt, xdr_void, NULL)) {
 398  399                          DTRACE_NFSV4_1(null__done, struct svc_req *, req);
↓ open down ↓ 138 lines elided ↑ open up ↑
 537  538                  return (FALSE);
 538  539  
 539  540          argsp = (COMPOUND4args *)args;
 540  541  
 541  542          if (argsp->minorversion <= NFS4_MAX_MINOR_VERSION)
 542  543                  return (FALSE);
 543  544  
 544  545          resp = &res_buf;
 545  546  
 546  547          /*
 547      -         * Form a reply tag by copying over the reqeuest tag.
      548 +         * Form a reply tag by copying over the request tag.
 548  549           */
 549      -        resp->tag.utf8string_val =
 550      -            kmem_alloc(argsp->tag.utf8string_len, KM_SLEEP);
 551  550          resp->tag.utf8string_len = argsp->tag.utf8string_len;
 552      -        bcopy(argsp->tag.utf8string_val, resp->tag.utf8string_val,
 553      -            resp->tag.utf8string_len);
      551 +        if (argsp->tag.utf8string_len != 0) {
      552 +                resp->tag.utf8string_val =
      553 +                    kmem_alloc(argsp->tag.utf8string_len, KM_SLEEP);
      554 +                bcopy(argsp->tag.utf8string_val, resp->tag.utf8string_val,
      555 +                    resp->tag.utf8string_len);
      556 +        } else {
      557 +                resp->tag.utf8string_val = NULL;
      558 +        }
 554  559          resp->array_len = 0;
 555  560          resp->array = NULL;
 556  561          resp->status = NFS4ERR_MINOR_VERS_MISMATCH;
 557  562          if (!svc_sendreply(xprt,  xdr_COMPOUND4res_srv, (char *)resp)) {
 558  563                  DTRACE_PROBE2(nfss__e__minorvers_mismatch,
 559  564                      SVCXPRT *, xprt, char *, resp);
 560  565                  svcerr_systemerr(xprt);
 561  566          }
 562  567          rfs4_compound_free(resp);
 563  568          return (TRUE);
↓ open down ↓ 4 lines elided ↑ open up ↑
 568  573  {
 569  574          COMPOUND4res res_buf, *rbp;
 570  575          nfs_resop4 *resop;
 571  576          PUTFH4res *resp;
 572  577  
 573  578          rbp = &res_buf;
 574  579  
 575  580          /*
 576  581           * Form a reply tag by copying over the request tag.
 577  582           */
 578      -        rbp->tag.utf8string_val =
 579      -            kmem_alloc(argsp->tag.utf8string_len, KM_SLEEP);
 580  583          rbp->tag.utf8string_len = argsp->tag.utf8string_len;
 581      -        bcopy(argsp->tag.utf8string_val, rbp->tag.utf8string_val,
 582      -            rbp->tag.utf8string_len);
      584 +        if (argsp->tag.utf8string_len != 0) {
      585 +                rbp->tag.utf8string_val =
      586 +                    kmem_alloc(argsp->tag.utf8string_len, KM_SLEEP);
      587 +                bcopy(argsp->tag.utf8string_val, rbp->tag.utf8string_val,
      588 +                    rbp->tag.utf8string_len);
      589 +        } else {
      590 +                rbp->tag.utf8string_val = NULL;
      591 +        }
 583  592  
 584  593          rbp->array_len = 1;
 585  594          rbp->array = kmem_zalloc(rbp->array_len * sizeof (nfs_resop4),
 586  595              KM_SLEEP);
 587  596          resop = &rbp->array[0];
 588  597          resop->resop = argsp->array[0].argop;   /* copy first op over */
 589  598  
 590  599          /* Any op will do, just need to access status field */
 591  600          resp = &resop->nfs_resop4_u.opputfh;
 592  601  
↓ open down ↓ 20 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX