Print this page
NEX-15279 support NFS server in zone
NEX-15520 online NFS shares cause zoneadm halt to hang in nfs_export_zone_fini
Portions contributed by: Dan Kruchinin dan.kruchinin@nexenta.com
Portions contributed by: Stepan Zastupov stepan.zastupov@gmail.com
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-6778 NFS kstats leak and cause system to hang
Revert "NEX-4261 Per-client NFS server IOPS, bandwidth, and latency kstats"
This reverts commit 586c3ab1927647487f01c337ddc011c642575a52.
Revert "NEX-5354 Aggregated IOPS, bandwidth, and latency kstats for NFS server"
This reverts commit c91d7614da8618ef48018102b077f60ecbbac8c2.
Revert "NEX-5667 nfssrv_stats_flags does not work for aggregated kstats"
This reverts commit 3dcf42618be7dd5f408c327f429c81e07ca08e74.
Revert "NEX-5750 Time values for aggregated NFS server kstats should be normalized"
This reverts commit 1f4d4f901153b0191027969fa4a8064f9d3b9ee1.
Revert "NEX-5942 Panic in rfs4_minorvers_mismatch() with NFSv4.1 client"
This reverts commit 40766417094a162f5e4cc8786c0fa0a7e5871cd9.
Revert "NEX-5752 NFS server: namespace collision in kstats"
This reverts commit ae81e668db86050da8e483264acb0cce0444a132.
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-5942 Panic in rfs4_minorvers_mismatch() with NFSv4.1 client
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-4261 Per-client NFS server IOPS, bandwidth, and latency kstats
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-3097 IOPS, bandwidth, and latency kstats for NFS server
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>

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  
  57   56  static void rfs4_resource_err(struct svc_req *req, COMPOUND4args *argsp);
  58   57  
       58 +extern zone_key_t rfs4_zone_key;
       59 +
  59   60  /*
  60   61   * Initialize a duplicate request cache.
  61   62   */
  62   63  rfs4_drc_t *
  63   64  rfs4_init_drc(uint32_t drc_size, uint32_t drc_hash_size)
  64   65  {
  65   66          rfs4_drc_t *drc;
  66   67          uint32_t   bki;
  67   68  
  68   69          ASSERT(drc_size);
↓ open down ↓ 18 lines elided ↑ open up ↑
  87   88          list_create(&(drc->dr_cache), sizeof (rfs4_dupreq_t),
  88   89              offsetof(rfs4_dupreq_t, dr_next));
  89   90  
  90   91          return (drc);
  91   92  }
  92   93  
  93   94  /*
  94   95   * Destroy a duplicate request cache.
  95   96   */
  96   97  void
  97      -rfs4_fini_drc(rfs4_drc_t *drc)
       98 +rfs4_fini_drc(void)
  98   99  {
      100 +        nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
      101 +        rfs4_drc_t *drc = nsrv4->nfs4_drc;
  99  102          rfs4_dupreq_t *drp, *drp_next;
 100  103  
 101      -        ASSERT(drc);
 102      -
 103  104          /* iterate over the dr_cache and free the enties */
 104  105          for (drp = list_head(&(drc->dr_cache)); drp != NULL; drp = drp_next) {
 105  106  
 106  107                  if (drp->dr_state == NFS4_DUP_REPLAY)
 107  108                          rfs4_compound_free(&(drp->dr_res));
 108  109  
 109  110                  if (drp->dr_addr.buf != NULL)
 110  111                          kmem_free(drp->dr_addr.buf, drp->dr_addr.maxlen);
 111  112  
 112  113                  drp_next = list_next(&(drc->dr_cache), drp);
↓ open down ↓ 240 lines elided ↑ open up ↑
 353  354   *
 354  355   * This function handles the duplicate request cache,
 355  356   * NULL_PROC and COMPOUND procedure calls for NFSv4;
 356  357   *
 357  358   * Passed into this function are:-
 358  359   *
 359  360   *      disp    A pointer to our dispatch table entry
 360  361   *      req     The request to process
 361  362   *      xprt    The server transport handle
 362  363   *      ap      A pointer to the arguments
      364 + *      rlen    A pointer to the reply length (output)
 363  365   *
 364  366   *
 365  367   * When appropriate this function is responsible for inserting
 366  368   * the reply into the duplicate cache or replaying an existing
 367  369   * cached reply.
 368  370   *
 369  371   * dr_stat      reflects the state of the duplicate request that
 370  372   *              has been inserted into or retrieved from the cache
 371  373   *
 372  374   * drp          is the duplicate request entry
 373  375   *
 374  376   */
 375  377  int
 376  378  rfs4_dispatch(struct rpcdisp *disp, struct svc_req *req,
 377      -                SVCXPRT *xprt, char *ap)
      379 +    SVCXPRT *xprt, char *ap, size_t *rlen)
 378  380  {
 379  381  
 380  382          COMPOUND4res     res_buf;
 381  383          COMPOUND4res    *rbp;
 382  384          COMPOUND4args   *cap;
 383  385          cred_t          *cr = NULL;
 384  386          int              error = 0;
 385  387          int              dis_flags = 0;
 386  388          int              dr_stat = NFS4_NOT_DUP;
 387  389          rfs4_dupreq_t   *drp = NULL;
 388  390          int              rv;
      391 +        nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
      392 +        rfs4_drc_t *nfs4_drc = nsrv4->nfs4_drc;
 389  393  
 390  394          ASSERT(disp);
 391  395  
 392  396          /*
 393  397           * Short circuit the RPC_NULL proc.
 394  398           */
 395  399          if (disp->dis_proc == rpc_null) {
 396  400                  DTRACE_NFSV4_1(null__start, struct svc_req *, req);
 397  401                  if (!svc_sendreply(xprt, xdr_void, NULL)) {
 398  402                          DTRACE_NFSV4_1(null__done, struct svc_req *, req);
 399  403                          svcerr_systemerr(xprt);
 400  404                          return (1);
 401  405                  }
 402  406                  DTRACE_NFSV4_1(null__done, struct svc_req *, req);
      407 +                *rlen = xdr_sizeof(xdr_void, NULL);
 403  408                  return (0);
 404  409          }
 405  410  
 406  411          /* Only NFSv4 Compounds from this point onward */
 407  412  
 408  413          rbp = &res_buf;
 409  414          cap = (COMPOUND4args *)ap;
 410  415  
 411  416          /*
      417 +         * Update kstats
      418 +         */
      419 +        rfs4_compound_kstat_args(cap);
      420 +
      421 +        /*
 412  422           * Figure out the disposition of the whole COMPOUND
 413  423           * and record it's IDEMPOTENTCY.
 414  424           */
 415  425          rfs4_compound_flagproc(cap, &dis_flags);
 416  426  
 417  427          /*
 418  428           * If NON-IDEMPOTENT then we need to figure out if this
 419  429           * request can be replied from the duplicate cache.
 420  430           *
 421  431           * If this is a new request then we need to insert the
↓ open down ↓ 63 lines elided ↑ open up ↑
 485  495  
 486  496                  if (curthread->t_flag & T_WOULDBLOCK) {
 487  497                          curthread->t_flag &= ~T_WOULDBLOCK;
 488  498                          return (1);
 489  499                  }
 490  500          }
 491  501  
 492  502          /*
 493  503           * Send out the replayed reply or the 'real' one.
 494  504           */
 495      -        if (!svc_sendreply(xprt,  xdr_COMPOUND4res_srv, (char *)rbp)) {
      505 +        if (!svc_sendreply(xprt, xdr_COMPOUND4res_srv, (char *)rbp)) {
 496  506                  DTRACE_PROBE2(nfss__e__dispatch_sendfail,
 497  507                      struct svc_req *, xprt,
 498  508                      char *, rbp);
 499  509                  svcerr_systemerr(xprt);
 500  510                  error++;
      511 +        } else {
      512 +                /*
      513 +                 * Update kstats
      514 +                 */
      515 +                rfs4_compound_kstat_res(rbp);
      516 +                *rlen = xdr_sizeof(xdr_COMPOUND4res_srv, rbp);
 501  517          }
 502  518  
 503  519          /*
 504  520           * If this reply was just inserted into the duplicate cache
 505  521           * or it was replayed from the dup cache; (re)mark it as
 506  522           * available for replay
 507  523           *
 508  524           * At first glance, this 'if' statement seems a little strange;
 509  525           * testing for NFS4_DUP_REPLAY, and then calling...
 510  526           *
↓ open down ↓ 102 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX