Print this page
Untrip aggressive assert AND use EXI_TO_ZONEROOTVP
Revert exi_zone to exi_zoneid, and install exi_ne backpointer
Hyperaggressive asserts pt 1/N
Ooops exi_zoneid isn't a variable again yet
Be far more judicious in the use of curzone-using macros.
(Merge and extra asserts by danmcd.)
Bad assertions
nfs_export_zone_init() can't assume called in zone-context.
curzone reality check and teardown changes to use the RIGHT zone
Try to remove assumption that zone's root vnode is marked VROOT

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/nfs/nfs_export.c
          +++ new/usr/src/uts/common/fs/nfs/nfs_export.c
↓ open down ↓ 694 lines elided ↑ open up ↑
 695  695          exportinfo_t *exi_ret = NULL;
 696  696  
 697  697          for (;;) {
 698  698                  tnode = tnode->tree_parent;
 699  699                  if (TREE_ROOT(tnode)) {
 700  700                          exi_ret = tnode->tree_exi;
 701  701                          break;
 702  702                  }
 703  703          }
 704  704  
 705      -        ASSERT(exi_ret); /* Every visible should have its home exportinfo */
      705 +        /* Every visible should have its home exportinfo */
      706 +        ASSERT(exi_ret != NULL);
 706  707          return (exi_ret);
 707  708  }
 708  709  
 709  710  /*
 710  711   * For NFS V4.
 711  712   * Add or remove the newly exported or unexported security flavors of the
 712  713   * given exportinfo from its ancestors upto the system root.
 713  714   */
 714      -void
      715 +static void
 715  716  srv_secinfo_treeclimb(nfs_export_t *ne, exportinfo_t *exip, secinfo_t *sec,
 716  717      int seccnt, bool_t isadd)
 717  718  {
 718  719          treenode_t *tnode;
 719  720  
 720  721          ASSERT(RW_WRITE_HELD(&ne->exported_lock));
 721  722  
 722  723          /*
 723  724           * exi_tree can be null for the zone root
 724  725           * which means we're already at the "top"
↓ open down ↓ 10 lines elided ↑ open up ↑
 735  736                  return;
 736  737  
 737  738          /*
 738  739           * If flavors are being added and the new export root isn't
 739  740           * also VROOT, its implicitly allowed flavors are inherited from
 740  741           * its pseudonode.
 741  742           * Note - for VROOT exports the implicitly allowed flavors were
 742  743           * transferred from the PSEUDO export in exportfs()
 743  744           */
 744  745          if (isadd && !(exip->exi_vp->v_flag & VROOT) &&
      746 +            !VN_CMP(exip->exi_vp, EXI_TO_ZONEROOTVP(exip)) &&
 745  747              tnode->tree_vis->vis_seccnt > 0) {
 746  748                  srv_secinfo_add(&exip->exi_export.ex_secinfo,
 747  749                      &exip->exi_export.ex_seccnt, tnode->tree_vis->vis_secinfo,
 748  750                      tnode->tree_vis->vis_seccnt, FALSE);
 749  751          }
 750  752  
 751  753          /*
 752  754           * Move to parent node and propagate sec flavor
 753  755           * to exportinfo and to visible structures.
 754  756           */
↓ open down ↓ 45 lines elided ↑ open up ↑
 800  802          if ((exi)->hash_name.next) \
 801  803                  (exi)->hash_name.next->hash_name.prev = (exi); \
 802  804          *(bucket) = (exi);
 803  805  
 804  806  void
 805  807  export_link(nfs_export_t *ne, exportinfo_t *exi)
 806  808  {
 807  809          exportinfo_t **bckt;
 808  810  
 809  811          ASSERT(RW_WRITE_HELD(&ne->exported_lock));
 810      -        ASSERT(exi->exi_zoneid == ne->ne_globals->nfs_zoneid);
 811  812  
 812  813          bckt = &ne->exptable[exptablehash(&exi->exi_fsid, &exi->exi_fid)];
 813  814          exp_hash_link(exi, fid_hash, bckt);
 814  815  
 815  816          bckt = &ne->exptable_path_hash[pkp_tab_hash(exi->exi_export.ex_path,
 816  817              strlen(exi->exi_export.ex_path))];
 817  818          exp_hash_link(exi, path_hash, bckt);
      819 +        exi->exi_ne = ne;
 818  820  }
 819  821  
 820  822  /*
 821  823   * Helper functions for exi_id handling
 822  824   */
 823  825  static int
 824  826  exi_id_compar(const void *v1, const void *v2)
 825  827  {
 826  828          const struct exportinfo *e1 = v1;
 827  829          const struct exportinfo *e2 = v2;
↓ open down ↓ 56 lines elided ↑ open up ↑
 884  886          ne->exi_root->exi_fh.fh_len = sizeof (ne->exi_root->exi_fh.fh_data);
 885  887  
 886  888          return (0);
 887  889  }
 888  890  
 889  891  void
 890  892  nfs_export_zone_init(nfs_globals_t *ng)
 891  893  {
 892  894          int i;
 893  895          nfs_export_t *ne;
      896 +        zone_t *zone;
 894  897  
 895  898          ne = kmem_zalloc(sizeof (*ne), KM_SLEEP);
 896  899  
 897  900          rw_init(&ne->exported_lock, NULL, RW_DEFAULT, NULL);
 898  901  
 899  902          ne->ne_globals = ng; /* "up" pointer */
 900  903  
 901  904          /*
 902  905           * Allocate the place holder for the public file handle, which
 903  906           * is all zeroes. It is initially set to the root filesystem.
↓ open down ↓ 4 lines elided ↑ open up ↑
 908  911          ne->exi_root->exi_export.ex_flags = EX_PUBLIC;
 909  912          ne->exi_root->exi_export.ex_pathlen = 1;        /* length of "/" */
 910  913          ne->exi_root->exi_export.ex_path =
 911  914              kmem_alloc(ne->exi_root->exi_export.ex_pathlen + 1, KM_SLEEP);
 912  915          ne->exi_root->exi_export.ex_path[0] = '/';
 913  916          ne->exi_root->exi_export.ex_path[1] = '\0';
 914  917  
 915  918          ne->exi_root->exi_count = 1;
 916  919          mutex_init(&ne->exi_root->exi_lock, NULL, MUTEX_DEFAULT, NULL);
 917  920  
 918      -        ne->exi_root->exi_vp = ZONE_ROOTVP();
      921 +        /*
      922 +         * Because we cannot:
      923 +         *      ASSERT(curzone->zone_id == ng->nfs_zoneid);
      924 +         * We grab the zone pointer explicitly (like netstacks do) and
      925 +         * set the rootvp here.
      926 +         *
      927 +         * Subsequent exportinfo_t's that get export_link()ed to "ne" also
      928 +         * will backpoint to "ne" such that exi->exi_ne->exi_root->exi_vp
      929 +         * will get the zone's rootvp for a given exportinfo_t.
      930 +         */
      931 +        zone = zone_find_by_id_nolock(ng->nfs_zoneid);
      932 +        ne->exi_root->exi_vp = zone->zone_rootvp;
 919  933          ne->exi_root->exi_zoneid = ng->nfs_zoneid;
 920  934  
 921  935          /*
 922  936           * Fill in ne->exi_rootfid later, in nfs_export_get_rootfid
 923  937           * because we can't correctly return errors here.
 924  938           */
 925  939  
 926  940          /* Initialize auth cache and auth cache lock */
 927  941          for (i = 0; i < AUTH_TABLESIZE; i++) {
 928  942                  ne->exi_root->exi_cache[i] = kmem_alloc(sizeof (avl_tree_t),
↓ open down ↓ 459 lines elided ↑ open up ↑
1388 1402          DTRACE_PROBE(nfss__i__exported_lock2_stop);
1389 1403          rw_exit(&ne->exported_lock);
1390 1404          pn_free(&lookpn);
1391 1405  
1392 1406          exi = kmem_zalloc(sizeof (*exi), KM_SLEEP);
1393 1407          exi->exi_fsid = fsid;
1394 1408          exi->exi_fid = fid;
1395 1409          exi->exi_vp = vp;
1396 1410          exi->exi_count = 1;
1397 1411          exi->exi_zoneid = crgetzoneid(cr);
     1412 +        ASSERT3U(exi->exi_zoneid, ==, curzone->zone_id);
1398 1413          exi->exi_volatile_dev = (vfssw[vp->v_vfsp->vfs_fstype].vsw_flag &
1399 1414              VSW_VOLATILEDEV) ? 1 : 0;
1400 1415          mutex_init(&exi->exi_lock, NULL, MUTEX_DEFAULT, NULL);
1401 1416          exi->exi_dvp = dvp;
1402 1417  
1403 1418          /*
1404 1419           * Initialize auth cache and auth cache lock
1405 1420           */
1406 1421          for (i = 0; i < AUTH_TABLESIZE; i++) {
1407 1422                  exi->exi_cache[i] = kmem_alloc(sizeof (avl_tree_t), KM_SLEEP);
↓ open down ↓ 449 lines elided ↑ open up ↑
1857 1872  /*
1858 1873   * Remove the exportinfo from the export list
1859 1874   */
1860 1875  void
1861 1876  export_unlink(nfs_export_t *ne, struct exportinfo *exi)
1862 1877  {
1863 1878          ASSERT(RW_WRITE_HELD(&ne->exported_lock));
1864 1879  
1865 1880          exp_hash_unlink(exi, fid_hash);
1866 1881          exp_hash_unlink(exi, path_hash);
     1882 +        ASSERT3P(exi->exi_ne, ==, ne);
     1883 +        exi->exi_ne = NULL;
1867 1884  }
1868 1885  
1869 1886  /*
1870 1887   * Unexport an exported filesystem
1871 1888   */
1872 1889  static int
1873 1890  unexport(nfs_export_t *ne, struct exportinfo *exi)
1874 1891  {
1875 1892          struct secinfo cursec[MAX_FLAVORS];
1876 1893          int curcnt;
↓ open down ↓ 53 lines elided ↑ open up ↑
1930 1947          /*
1931 1948           * Notify the lock manager that the filesystem is being
1932 1949           * unexported.
1933 1950           */
1934 1951          lm_unexport(exi);
1935 1952  
1936 1953          /*
1937 1954           * If this was a public export, restore
1938 1955           * the public filehandle to the root.
1939 1956           */
     1957 +
     1958 +        /*
     1959 +         * XXX KEBE ASKS --> Should CRED() instead be
     1960 +         * exi->exi_zone->zone_kcred?
     1961 +         */
1940 1962          if (exi == ne->exi_public) {
1941 1963                  ne->exi_public = ne->exi_root;
1942 1964  
1943 1965                  nfslog_share_record(ne->exi_public, CRED());
1944 1966          }
1945 1967  
1946 1968          if (exi->exi_export.ex_flags & EX_LOG)
1947 1969                  nfslog_unshare_record(exi, CRED());
1948 1970  
1949 1971          exi_rele(exi);
↓ open down ↓ 214 lines elided ↑ open up ↑
2164 2186                           * Found the export info
2165 2187                           */
2166 2188                          break;
2167 2189                  }
2168 2190  
2169 2191                  /*
2170 2192                   * We have just failed finding a matching export.
2171 2193                   * If we're at the root of this filesystem, then
2172 2194                   * it's time to stop (with failure).
2173 2195                   */
2174      -                if (vp->v_flag & VROOT) {
     2196 +                ASSERT3P(vp->v_vfsp->vfs_zone, ==, curzone);
     2197 +                if ((vp->v_flag & VROOT) || VN_IS_CURZONEROOT(vp)) {
2175 2198                          error = EINVAL;
2176 2199                          break;
2177 2200                  }
2178 2201  
2179 2202                  if (walk != NULL)
2180 2203                          (*walk)++;
2181 2204  
2182 2205                  /*
2183 2206                   * Now, do a ".." up vp. If dvp is supplied, use it,
2184 2207                   * otherwise, look it up.
↓ open down ↓ 784 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX