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>
re #13613 rb4516 Tunables needs volatile keyword

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/nfs/nfs_client.c
          +++ new/usr/src/uts/common/fs/nfs/nfs_client.c
↓ open down ↓ 10 lines elided ↑ open up ↑
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
       21 +
  21   22  /*
  22   23   * Copyright (c) 1986, 2010, Oracle and/or its affiliates. All rights reserved.
  23      - *
       24 + */
       25 +
       26 +/*
  24   27   *      Copyright (c) 1983,1984,1985,1986,1987,1988,1989  AT&T.
  25   28   *      All rights reserved.
  26   29   */
  27   30  
       31 +/*
       32 + * Copyright 2018 Nexenta Systems, Inc.
       33 + */
       34 +
  28   35  #include <sys/param.h>
  29   36  #include <sys/types.h>
  30   37  #include <sys/systm.h>
  31   38  #include <sys/thread.h>
  32   39  #include <sys/t_lock.h>
  33   40  #include <sys/time.h>
  34   41  #include <sys/vnode.h>
  35   42  #include <sys/vfs.h>
  36   43  #include <sys/errno.h>
  37   44  #include <sys/buf.h>
↓ open down ↓ 15 lines elided ↑ open up ↑
  53   60  #include <sys/list.h>
  54   61  #include <sys/zone.h>
  55   62  
  56   63  #include <rpc/types.h>
  57   64  #include <rpc/xdr.h>
  58   65  #include <rpc/auth.h>
  59   66  #include <rpc/clnt.h>
  60   67  
  61   68  #include <nfs/nfs.h>
  62   69  #include <nfs/nfs_clnt.h>
       70 +#include <nfs/nfs_cmd.h>
  63   71  
  64   72  #include <nfs/rnode.h>
  65   73  #include <nfs/nfs_acl.h>
  66   74  #include <nfs/lm.h>
  67   75  
  68   76  #include <vm/hat.h>
  69   77  #include <vm/as.h>
  70   78  #include <vm/page.h>
  71   79  #include <vm/pvn.h>
  72   80  #include <vm/seg.h>
↓ open down ↓ 1101 lines elided ↑ open up ↑
1174 1182  }
1175 1183  
1176 1184  /*
1177 1185   * Asynchronous I/O parameters.  nfs_async_threads is the high-water mark
1178 1186   * for the demand-based allocation of async threads per-mount.  The
1179 1187   * nfs_async_timeout is the amount of time a thread will live after it
1180 1188   * becomes idle, unless new I/O requests are received before the thread
1181 1189   * dies.  See nfs_async_putpage and nfs_async_start.
1182 1190   */
1183 1191  
1184      -int nfs_async_timeout = -1;     /* uninitialized */
     1192 +volatile int nfs_async_timeout = -1;    /* uninitialized */
1185 1193  
1186 1194  static void     nfs_async_start(struct vfs *);
1187 1195  static void     nfs_async_pgops_start(struct vfs *);
1188 1196  static void     nfs_async_common_start(struct vfs *, int);
1189 1197  
1190 1198  static void
1191 1199  free_async_args(struct nfs_async_reqs *args)
1192 1200  {
1193 1201          rnode_t *rp;
1194 1202  
↓ open down ↓ 152 lines elided ↑ open up ↑
1347 1355          mi->mi_flags |= MI_ASYNC_MGR_STOP;
1348 1356          mutex_exit(&mi->mi_lock);
1349 1357          cv_broadcast(&mi->mi_async_reqs_cv);
1350 1358          while (mi->mi_manager_thread != NULL)
1351 1359                  cv_wait(&mi->mi_async_cv, &mi->mi_async_lock);
1352 1360          mutex_exit(&mi->mi_async_lock);
1353 1361  }
1354 1362  
1355 1363  int
1356 1364  nfs_async_readahead(vnode_t *vp, u_offset_t blkoff, caddr_t addr,
1357      -        struct seg *seg, cred_t *cr, void (*readahead)(vnode_t *,
1358      -        u_offset_t, caddr_t, struct seg *, cred_t *))
     1365 +    struct seg *seg, cred_t *cr, void (*readahead)(vnode_t *, u_offset_t,
     1366 +    caddr_t, struct seg *, cred_t *))
1359 1367  {
1360 1368          rnode_t *rp;
1361 1369          mntinfo_t *mi;
1362 1370          struct nfs_async_reqs *args;
1363 1371  
1364 1372          rp = VTOR(vp);
1365 1373          ASSERT(rp->r_freef == NULL);
1366 1374  
1367 1375          mi = VTOMI(vp);
1368 1376  
↓ open down ↓ 78 lines elided ↑ open up ↑
1447 1455          cv_broadcast(&rp->r_cv);
1448 1456          mutex_exit(&rp->r_statelock);
1449 1457          VN_RELE(vp);
1450 1458          crfree(cr);
1451 1459          kmem_free(args, sizeof (*args));
1452 1460          return (-1);
1453 1461  }
1454 1462  
1455 1463  int
1456 1464  nfs_async_putapage(vnode_t *vp, page_t *pp, u_offset_t off, size_t len,
1457      -        int flags, cred_t *cr, int (*putapage)(vnode_t *, page_t *,
1458      -        u_offset_t, size_t, int, cred_t *))
     1465 +    int flags, cred_t *cr, int (*putapage)(vnode_t *, page_t *, u_offset_t,
     1466 +    size_t, int, cred_t *))
1459 1467  {
1460 1468          rnode_t *rp;
1461 1469          mntinfo_t *mi;
1462 1470          struct nfs_async_reqs *args;
1463 1471  
1464 1472          ASSERT(flags & B_ASYNC);
1465 1473          ASSERT(vp->v_vfsp != NULL);
1466 1474  
1467 1475          rp = VTOR(vp);
1468 1476          ASSERT(rp->r_count > 0);
↓ open down ↓ 100 lines elided ↑ open up ↑
1569 1577                   * knows what they're doing if they set it.
1570 1578                   */
1571 1579                  pvn_write_done(pp, flags | B_ERROR);
1572 1580                  return (EPERM);
1573 1581          }
1574 1582          return ((*putapage)(vp, pp, off, len, flags, cr));
1575 1583  }
1576 1584  
1577 1585  int
1578 1586  nfs_async_pageio(vnode_t *vp, page_t *pp, u_offset_t io_off, size_t io_len,
1579      -        int flags, cred_t *cr, int (*pageio)(vnode_t *, page_t *, u_offset_t,
1580      -        size_t, int, cred_t *))
     1587 +    int flags, cred_t *cr, int (*pageio)(vnode_t *, page_t *, u_offset_t,
     1588 +    size_t, int, cred_t *))
1581 1589  {
1582 1590          rnode_t *rp;
1583 1591          mntinfo_t *mi;
1584 1592          struct nfs_async_reqs *args;
1585 1593  
1586 1594          ASSERT(flags & B_ASYNC);
1587 1595          ASSERT(vp->v_vfsp != NULL);
1588 1596  
1589 1597          rp = VTOR(vp);
1590 1598          ASSERT(rp->r_count > 0);
↓ open down ↓ 111 lines elided ↑ open up ↑
1702 1710                   * knows what they're doing if they set it.
1703 1711                   */
1704 1712                  pvn_write_done(pp, flags | B_ERROR);
1705 1713                  return (EPERM);
1706 1714          }
1707 1715          return ((*pageio)(vp, pp, io_off, io_len, flags, cr));
1708 1716  }
1709 1717  
1710 1718  void
1711 1719  nfs_async_readdir(vnode_t *vp, rddir_cache *rdc, cred_t *cr,
1712      -        int (*readdir)(vnode_t *, rddir_cache *, cred_t *))
     1720 +    int (*readdir)(vnode_t *, rddir_cache *, cred_t *))
1713 1721  {
1714 1722          rnode_t *rp;
1715 1723          mntinfo_t *mi;
1716 1724          struct nfs_async_reqs *args;
1717 1725  
1718 1726          rp = VTOR(vp);
1719 1727          ASSERT(rp->r_freef == NULL);
1720 1728  
1721 1729          mi = VTOMI(vp);
1722 1730  
↓ open down ↓ 76 lines elided ↑ open up ↑
1799 1807          if (rdc->flags & RDDIRWAIT) {
1800 1808                  rdc->flags &= ~RDDIRWAIT;
1801 1809                  cv_broadcast(&rdc->cv);
1802 1810          }
1803 1811          mutex_exit(&rp->r_statelock);
1804 1812          rddir_cache_rele(rdc);
1805 1813  }
1806 1814  
1807 1815  void
1808 1816  nfs_async_commit(vnode_t *vp, page_t *plist, offset3 offset, count3 count,
1809      -        cred_t *cr, void (*commit)(vnode_t *, page_t *, offset3, count3,
1810      -        cred_t *))
     1817 +    cred_t *cr, void (*commit)(vnode_t *, page_t *, offset3, count3, cred_t *))
1811 1818  {
1812 1819          rnode_t *rp;
1813 1820          mntinfo_t *mi;
1814 1821          struct nfs_async_reqs *args;
1815 1822          page_t *pp;
1816 1823  
1817 1824          rp = VTOR(vp);
1818 1825          mi = VTOMI(vp);
1819 1826  
1820 1827          /*
↓ open down ↓ 716 lines elided ↑ open up ↑
2537 2544          rp->r_truncaddr = off;
2538 2545          mutex_exit(&rp->r_statelock);
2539 2546          (void) pvn_vplist_dirty(vp, off, rp->r_putapage,
2540 2547              B_INVAL | B_TRUNC, cr);
2541 2548          mutex_enter(&rp->r_statelock);
2542 2549          rp->r_flags &= ~RTRUNCATE;
2543 2550          cv_broadcast(&rp->r_cv);
2544 2551          mutex_exit(&rp->r_statelock);
2545 2552  }
2546 2553  
2547      -static int nfs_write_error_to_cons_only = 0;
     2554 +volatile int nfs_write_error_to_cons_only = 0;
2548 2555  #define MSG(x)  (nfs_write_error_to_cons_only ? (x) : (x) + 1)
2549 2556  
2550 2557  /*
2551 2558   * Print a file handle
2552 2559   */
2553 2560  void
2554 2561  nfs_printfhandle(nfs_fhandle *fhp)
2555 2562  {
2556 2563          int *ip;
2557 2564          char *buf;
↓ open down ↓ 29 lines elided ↑ open up ↑
2587 2594  
2588 2595          kmem_free(buf, bufsize);
2589 2596  }
2590 2597  
2591 2598  /*
2592 2599   * Notify the system administrator that an NFS write error has
2593 2600   * occurred.
2594 2601   */
2595 2602  
2596 2603  /* seconds between ENOSPC/EDQUOT messages */
2597      -clock_t nfs_write_error_interval = 5;
     2604 +volatile clock_t nfs_write_error_interval = 5;
2598 2605  
2599 2606  void
2600 2607  nfs_write_error(vnode_t *vp, int error, cred_t *cr)
2601 2608  {
2602 2609          mntinfo_t *mi;
2603 2610          clock_t now;
2604 2611  
2605 2612          mi = VTOMI(vp);
2606 2613          /*
2607 2614           * In case of forced unmount or zone shutdown, do not print any
↓ open down ↓ 213 lines elided ↑ open up ↑
2821 2828                   * Cleanup nfs_subrinit() work
2822 2829                   */
2823 2830                  nfs_subrfini();
2824 2831                  return (error);
2825 2832          }
2826 2833          zone_key_create(&mi_list_key, nfs_mi_init, nfs_mi_shutdown,
2827 2834              nfs_mi_destroy);
2828 2835  
2829 2836          nfs4_clnt_init();
2830 2837  
     2838 +        nfscmd_init();
     2839 +
2831 2840  #ifdef DEBUG
2832 2841          nfs_clntup = B_TRUE;
2833 2842  #endif
2834 2843  
2835 2844          return (0);
2836 2845  }
2837 2846  
2838 2847  /*
2839 2848   * This routine is only called if the NFS Client has been initialized but
2840 2849   * the module failed to be installed. This routine will cleanup the previously
2841 2850   * allocated/initialized work.
2842 2851   */
2843 2852  void
2844 2853  nfs_clntfini(void)
2845 2854  {
2846 2855          (void) zone_key_delete(mi_list_key);
2847 2856          nfs_subrfini();
2848 2857          nfs_vfsfini();
2849 2858          nfs4_clnt_fini();
     2859 +        nfscmd_fini();
2850 2860  }
2851 2861  
2852 2862  /*
2853 2863   * nfs_lockrelease:
2854 2864   *
2855 2865   * Release any locks on the given vnode that are held by the current
2856 2866   * process.
2857 2867   */
2858 2868  void
2859 2869  nfs_lockrelease(vnode_t *vp, int flag, offset_t offset, cred_t *cr)
↓ open down ↓ 525 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX