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>

@@ -22,10 +22,14 @@
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
+/*
+ * Copyright 2018 Nexenta Systems, Inc.
+ */
+
 #include <sys/systm.h>
 #include <sys/sdt.h>
 #include <rpc/types.h>
 #include <rpc/auth.h>
 #include <rpc/auth_unix.h>

@@ -37,15 +41,10 @@
 #include <nfs/nfs4_drc.h>
 
 #define NFS4_MAX_MINOR_VERSION  0
 
 /*
- * This is the duplicate request cache for NFSv4
- */
-rfs4_drc_t *nfs4_drc = NULL;
-
-/*
  * The default size of the duplicate request cache
  */
 uint32_t nfs4_drc_max = 8 * 1024;
 
 /*

@@ -54,10 +53,12 @@
  */
 uint32_t nfs4_drc_hash = 541;
 
 static void rfs4_resource_err(struct svc_req *req, COMPOUND4args *argsp);
 
+extern zone_key_t rfs4_zone_key;
+
 /*
  * Initialize a duplicate request cache.
  */
 rfs4_drc_t *
 rfs4_init_drc(uint32_t drc_size, uint32_t drc_hash_size)

@@ -92,16 +93,16 @@
 
 /*
  * Destroy a duplicate request cache.
  */
 void
-rfs4_fini_drc(rfs4_drc_t *drc)
+rfs4_fini_drc(void)
 {
+        nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+        rfs4_drc_t *drc = nsrv4->nfs4_drc;
         rfs4_dupreq_t *drp, *drp_next;
 
-        ASSERT(drc);
-
         /* iterate over the dr_cache and free the enties */
         for (drp = list_head(&(drc->dr_cache)); drp != NULL; drp = drp_next) {
 
                 if (drp->dr_state == NFS4_DUP_REPLAY)
                         rfs4_compound_free(&(drp->dr_res));

@@ -358,10 +359,11 @@
  *
  *      disp    A pointer to our dispatch table entry
  *      req     The request to process
  *      xprt    The server transport handle
  *      ap      A pointer to the arguments
+ *      rlen    A pointer to the reply length (output)
  *
  *
  * When appropriate this function is responsible for inserting
  * the reply into the duplicate cache or replaying an existing
  * cached reply.

@@ -372,11 +374,11 @@
  * drp          is the duplicate request entry
  *
  */
 int
 rfs4_dispatch(struct rpcdisp *disp, struct svc_req *req,
-                SVCXPRT *xprt, char *ap)
+    SVCXPRT *xprt, char *ap, size_t *rlen)
 {
 
         COMPOUND4res     res_buf;
         COMPOUND4res    *rbp;
         COMPOUND4args   *cap;

@@ -384,10 +386,12 @@
         int              error = 0;
         int              dis_flags = 0;
         int              dr_stat = NFS4_NOT_DUP;
         rfs4_dupreq_t   *drp = NULL;
         int              rv;
+        nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+        rfs4_drc_t *nfs4_drc = nsrv4->nfs4_drc;
 
         ASSERT(disp);
 
         /*
          * Short circuit the RPC_NULL proc.

@@ -398,19 +402,25 @@
                         DTRACE_NFSV4_1(null__done, struct svc_req *, req);
                         svcerr_systemerr(xprt);
                         return (1);
                 }
                 DTRACE_NFSV4_1(null__done, struct svc_req *, req);
+                *rlen = xdr_sizeof(xdr_void, NULL);
                 return (0);
         }
 
         /* Only NFSv4 Compounds from this point onward */
 
         rbp = &res_buf;
         cap = (COMPOUND4args *)ap;
 
         /*
+         * Update kstats
+         */
+        rfs4_compound_kstat_args(cap);
+
+        /*
          * Figure out the disposition of the whole COMPOUND
          * and record it's IDEMPOTENTCY.
          */
         rfs4_compound_flagproc(cap, &dis_flags);
 

@@ -496,10 +506,16 @@
                 DTRACE_PROBE2(nfss__e__dispatch_sendfail,
                     struct svc_req *, xprt,
                     char *, rbp);
                 svcerr_systemerr(xprt);
                 error++;
+        } else {
+                /*
+                 * Update kstats
+                 */
+                rfs4_compound_kstat_res(rbp);
+                *rlen = xdr_sizeof(xdr_COMPOUND4res_srv, rbp);
         }
 
         /*
          * If this reply was just inserted into the duplicate cache
          * or it was replayed from the dup cache; (re)mark it as