Print this page
Bad assertions
nfs_export_zone_init() can't assume called in zone-context.
curzone reality check and teardown changes to use the RIGHT zone


 675          * Done. Update curdata.
 676          * Free up the existing secinfo list in curdata and
 677          * set the new value.
 678          */
 679         curdata->ex_seccnt = tcnt;
 680         curdata->ex_secinfo = msec;
 681 }
 682 
 683 /*
 684  * Find for given treenode the exportinfo which has its
 685  * exp_visible linked on its exi_visible list.
 686  *
 687  * Note: We could add new pointer either to treenode or
 688  * to exp_visible, which will point there directly.
 689  * This would buy some speed for some memory.
 690  */
 691 exportinfo_t *
 692 vis2exi(treenode_t *tnode)
 693 {
 694         exportinfo_t *exi_ret = NULL;



 695 
 696         for (;;) {
 697                 tnode = tnode->tree_parent;




 698                 if (TREE_ROOT(tnode)) {

 699                         exi_ret = tnode->tree_exi;
 700                         break;
 701                 }
 702         }
 703 
 704         ASSERT(exi_ret); /* Every visible should have its home exportinfo */
 705         return (exi_ret);
 706 }
 707 
 708 /*
 709  * For NFS V4.
 710  * Add or remove the newly exported or unexported security flavors of the
 711  * given exportinfo from its ancestors upto the system root.
 712  */
 713 void
 714 srv_secinfo_treeclimb(nfs_export_t *ne, exportinfo_t *exip, secinfo_t *sec,
 715     int seccnt, bool_t isadd)
 716 {
 717         treenode_t *tnode = exip->exi_tree;
 718 


 858 
 859         rw_init(&ne->exported_lock, NULL, RW_DEFAULT, NULL);
 860 
 861         /*
 862          * Allocate the place holder for the public file handle, which
 863          * is all zeroes. It is initially set to the root filesystem.
 864          */
 865         ne->exi_root = kmem_zalloc(sizeof (*ne->exi_root), KM_SLEEP);
 866         ne->exi_public = ne->exi_root;
 867 
 868         ne->exi_root->exi_export.ex_flags = EX_PUBLIC;
 869         ne->exi_root->exi_export.ex_pathlen = 1;  /* length of "/" */
 870         ne->exi_root->exi_export.ex_path =
 871             kmem_alloc(ne->exi_root->exi_export.ex_pathlen + 1, KM_SLEEP);
 872         ne->exi_root->exi_export.ex_path[0] = '/';
 873         ne->exi_root->exi_export.ex_path[1] = '\0';
 874 
 875         ne->exi_root->exi_count = 1;
 876         mutex_init(&ne->exi_root->exi_lock, NULL, MUTEX_DEFAULT, NULL);
 877 
 878         ne->exi_root->exi_vp = ZONE_ROOTVP();

 879         ne->exi_rootfid.fid_len = MAXFIDSZ;
 880         if (vop_fid_pseudo(ne->exi_root->exi_vp, &ne->exi_rootfid) != 0) {
 881                 mutex_destroy(&ne->exi_root->exi_lock);
 882                 kmem_free(ne->exi_root->exi_export.ex_path,
 883                     ne->exi_root->exi_export.ex_pathlen + 1);
 884                 kmem_free(ne->exi_root, sizeof (*ne->exi_root));
 885                 return (NULL);
 886         }
 887 
 888         /* Initialize auth cache and auth cache lock */
 889         for (i = 0; i < AUTH_TABLESIZE; i++) {
 890                 ne->exi_root->exi_cache[i] = kmem_alloc(sizeof (avl_tree_t),
 891                     KM_SLEEP);
 892                 avl_create(ne->exi_root->exi_cache[i],
 893                     nfsauth_cache_clnt_compar, sizeof (struct auth_cache_clnt),
 894                     offsetof(struct auth_cache_clnt, authc_link));
 895         }
 896         rw_init(&ne->exi_root->exi_cache_lock, NULL, RW_DEFAULT, NULL);
 897 
 898         /* Setup the fhandle template */


1283                     VN_CMP(ex2->exi_vp, vp) &&
1284                     strcmp(ex2->exi_export.ex_path, lookpn.pn_path) != 0) {
1285                         DTRACE_PROBE(nfss__i__exported_lock2_stop);
1286                         rw_exit(&ne->exported_lock);
1287                         VN_RELE(vp);
1288                         if (dvp != NULL)
1289                                 VN_RELE(dvp);
1290                         pn_free(&lookpn);
1291                         return (EEXIST);
1292                 }
1293         }
1294         DTRACE_PROBE(nfss__i__exported_lock2_stop);
1295         rw_exit(&ne->exported_lock);
1296         pn_free(&lookpn);
1297 
1298         exi = kmem_zalloc(sizeof (*exi), KM_SLEEP);
1299         exi->exi_fsid = fsid;
1300         exi->exi_fid = fid;
1301         exi->exi_vp = vp;
1302         exi->exi_count = 1;
1303         exi->exi_zoneid = crgetzoneid(cr);


1304         exi->exi_volatile_dev = (vfssw[vp->v_vfsp->vfs_fstype].vsw_flag &
1305             VSW_VOLATILEDEV) ? 1 : 0;
1306         mutex_init(&exi->exi_lock, NULL, MUTEX_DEFAULT, NULL);
1307         exi->exi_dvp = dvp;
1308 
1309         /*
1310          * Initialize auth cache and auth cache lock
1311          */
1312         for (i = 0; i < AUTH_TABLESIZE; i++) {
1313                 exi->exi_cache[i] = kmem_alloc(sizeof (avl_tree_t), KM_SLEEP);
1314                 avl_create(exi->exi_cache[i], nfsauth_cache_clnt_compar,
1315                     sizeof (struct auth_cache_clnt),
1316                     offsetof(struct auth_cache_clnt, authc_link));
1317         }
1318         rw_init(&exi->exi_cache_lock, NULL, RW_DEFAULT, NULL);
1319 
1320         /*
1321          * Build up the template fhandle
1322          */
1323         exi->exi_fh.fh_fsid = fsid;


1797         /*
1798          * Remove security flavors before treeclimb_unexport() is called
1799          * because srv_secinfo_treeclimb needs the namespace tree
1800          */
1801         curcnt = build_seclist_nodups(&exi->exi_export, cursec, TRUE);
1802         srv_secinfo_treeclimb(ne, exi, cursec, curcnt, FALSE);
1803 
1804         /*
1805          * If there's a visible list, then need to leave
1806          * a pseudo export here to retain the visible list
1807          * for paths to exports below.
1808          */
1809         if (exi->exi_visible != NULL) {
1810                 struct exportinfo *newexi;
1811 
1812                 newexi = pseudo_exportfs(ne, exi->exi_vp, &exi->exi_fid,
1813                     exi->exi_visible, &exi->exi_export);
1814                 exi->exi_visible = NULL;
1815 
1816                 /* interconnect the existing treenode with the new exportinfo */

1817                 newexi->exi_tree = exi->exi_tree;
1818                 newexi->exi_tree->tree_exi = newexi;
1819 
1820                 /* Update the change timestamp */
1821                 tree_update_change(ne, exi->exi_tree, NULL);
1822         } else {
1823                 treeclimb_unexport(ne, exi);
1824         }
1825 
1826         rw_exit(&ne->exported_lock);
1827 
1828         /*
1829          * Need to call into the NFSv4 server and release all data
1830          * held on this particular export.  This is important since
1831          * the v4 server may be holding file locks or vnodes under
1832          * this export.
1833          */
1834         rfs4_clean_state_exi(exi);
1835 
1836         /*
1837          * Notify the lock manager that the filesystem is being
1838          * unexported.
1839          */
1840         lm_unexport(exi);
1841 
1842         /*
1843          * If this was a public export, restore
1844          * the public filehandle to the root.
1845          */





1846         if (exi == ne->exi_public) {
1847                 ne->exi_public = ne->exi_root;
1848 
1849                 nfslog_share_record(ne->exi_public, CRED());
1850         }
1851 
1852         if (exi->exi_export.ex_flags & EX_LOG)
1853                 nfslog_unshare_record(exi, CRED());
1854 
1855         exi_rele(exi);
1856         return (0);
1857 }
1858 
1859 /*
1860  * Get file handle system call.
1861  * Takes file name and returns a file handle for it.
1862  * Credentials must be verified before calling.
1863  */
1864 int
1865 nfs_getfh(struct nfs_getfh_args *args, model_t model, cred_t *cr)




 675          * Done. Update curdata.
 676          * Free up the existing secinfo list in curdata and
 677          * set the new value.
 678          */
 679         curdata->ex_seccnt = tcnt;
 680         curdata->ex_secinfo = msec;
 681 }
 682 
 683 /*
 684  * Find for given treenode the exportinfo which has its
 685  * exp_visible linked on its exi_visible list.
 686  *
 687  * Note: We could add new pointer either to treenode or
 688  * to exp_visible, which will point there directly.
 689  * This would buy some speed for some memory.
 690  */
 691 exportinfo_t *
 692 vis2exi(treenode_t *tnode)
 693 {
 694         exportinfo_t *exi_ret = NULL;
 695 #ifdef DEBUG
 696         zone_t *zone = NULL;
 697 #endif
 698 
 699         for (;;) {
 700                 tnode = tnode->tree_parent;
 701 #ifdef DEBUG
 702                 if (zone == NULL && tnode->tree_exi != NULL)
 703                         zone = tnode->tree_exi->exi_zone;
 704 #endif
 705                 if (TREE_ROOT(tnode)) {
 706                         ASSERT3P(zone, ==, tnode->tree_exi->exi_zone);
 707                         exi_ret = tnode->tree_exi;
 708                         break;
 709                 }
 710         }
 711 
 712         ASSERT(exi_ret); /* Every visible should have its home exportinfo */
 713         return (exi_ret);
 714 }
 715 
 716 /*
 717  * For NFS V4.
 718  * Add or remove the newly exported or unexported security flavors of the
 719  * given exportinfo from its ancestors upto the system root.
 720  */
 721 void
 722 srv_secinfo_treeclimb(nfs_export_t *ne, exportinfo_t *exip, secinfo_t *sec,
 723     int seccnt, bool_t isadd)
 724 {
 725         treenode_t *tnode = exip->exi_tree;
 726 


 866 
 867         rw_init(&ne->exported_lock, NULL, RW_DEFAULT, NULL);
 868 
 869         /*
 870          * Allocate the place holder for the public file handle, which
 871          * is all zeroes. It is initially set to the root filesystem.
 872          */
 873         ne->exi_root = kmem_zalloc(sizeof (*ne->exi_root), KM_SLEEP);
 874         ne->exi_public = ne->exi_root;
 875 
 876         ne->exi_root->exi_export.ex_flags = EX_PUBLIC;
 877         ne->exi_root->exi_export.ex_pathlen = 1;  /* length of "/" */
 878         ne->exi_root->exi_export.ex_path =
 879             kmem_alloc(ne->exi_root->exi_export.ex_pathlen + 1, KM_SLEEP);
 880         ne->exi_root->exi_export.ex_path[0] = '/';
 881         ne->exi_root->exi_export.ex_path[1] = '\0';
 882 
 883         ne->exi_root->exi_count = 1;
 884         mutex_init(&ne->exi_root->exi_lock, NULL, MUTEX_DEFAULT, NULL);
 885 
 886         ne->exi_root->exi_zone = zone_find_by_id_nolock(zoneid);
 887         ne->exi_root->exi_vp = ne->exi_root->exi_zone->zone_rootvp;
 888         ne->exi_rootfid.fid_len = MAXFIDSZ;
 889         if (vop_fid_pseudo(ne->exi_root->exi_vp, &ne->exi_rootfid) != 0) {
 890                 mutex_destroy(&ne->exi_root->exi_lock);
 891                 kmem_free(ne->exi_root->exi_export.ex_path,
 892                     ne->exi_root->exi_export.ex_pathlen + 1);
 893                 kmem_free(ne->exi_root, sizeof (*ne->exi_root));
 894                 return (NULL);
 895         }
 896 
 897         /* Initialize auth cache and auth cache lock */
 898         for (i = 0; i < AUTH_TABLESIZE; i++) {
 899                 ne->exi_root->exi_cache[i] = kmem_alloc(sizeof (avl_tree_t),
 900                     KM_SLEEP);
 901                 avl_create(ne->exi_root->exi_cache[i],
 902                     nfsauth_cache_clnt_compar, sizeof (struct auth_cache_clnt),
 903                     offsetof(struct auth_cache_clnt, authc_link));
 904         }
 905         rw_init(&ne->exi_root->exi_cache_lock, NULL, RW_DEFAULT, NULL);
 906 
 907         /* Setup the fhandle template */


1292                     VN_CMP(ex2->exi_vp, vp) &&
1293                     strcmp(ex2->exi_export.ex_path, lookpn.pn_path) != 0) {
1294                         DTRACE_PROBE(nfss__i__exported_lock2_stop);
1295                         rw_exit(&ne->exported_lock);
1296                         VN_RELE(vp);
1297                         if (dvp != NULL)
1298                                 VN_RELE(dvp);
1299                         pn_free(&lookpn);
1300                         return (EEXIST);
1301                 }
1302         }
1303         DTRACE_PROBE(nfss__i__exported_lock2_stop);
1304         rw_exit(&ne->exported_lock);
1305         pn_free(&lookpn);
1306 
1307         exi = kmem_zalloc(sizeof (*exi), KM_SLEEP);
1308         exi->exi_fsid = fsid;
1309         exi->exi_fid = fid;
1310         exi->exi_vp = vp;
1311         exi->exi_count = 1;
1312         exi->exi_zone = crgetzone(cr);
1313         ASSERT(exi->exi_zone != NULL);               /* XXX KEBE ASKS... */
1314         ASSERT3P(exi->exi_zone, ==, curzone);        /* ... are these legit? */
1315         exi->exi_volatile_dev = (vfssw[vp->v_vfsp->vfs_fstype].vsw_flag &
1316             VSW_VOLATILEDEV) ? 1 : 0;
1317         mutex_init(&exi->exi_lock, NULL, MUTEX_DEFAULT, NULL);
1318         exi->exi_dvp = dvp;
1319 
1320         /*
1321          * Initialize auth cache and auth cache lock
1322          */
1323         for (i = 0; i < AUTH_TABLESIZE; i++) {
1324                 exi->exi_cache[i] = kmem_alloc(sizeof (avl_tree_t), KM_SLEEP);
1325                 avl_create(exi->exi_cache[i], nfsauth_cache_clnt_compar,
1326                     sizeof (struct auth_cache_clnt),
1327                     offsetof(struct auth_cache_clnt, authc_link));
1328         }
1329         rw_init(&exi->exi_cache_lock, NULL, RW_DEFAULT, NULL);
1330 
1331         /*
1332          * Build up the template fhandle
1333          */
1334         exi->exi_fh.fh_fsid = fsid;


1808         /*
1809          * Remove security flavors before treeclimb_unexport() is called
1810          * because srv_secinfo_treeclimb needs the namespace tree
1811          */
1812         curcnt = build_seclist_nodups(&exi->exi_export, cursec, TRUE);
1813         srv_secinfo_treeclimb(ne, exi, cursec, curcnt, FALSE);
1814 
1815         /*
1816          * If there's a visible list, then need to leave
1817          * a pseudo export here to retain the visible list
1818          * for paths to exports below.
1819          */
1820         if (exi->exi_visible != NULL) {
1821                 struct exportinfo *newexi;
1822 
1823                 newexi = pseudo_exportfs(ne, exi->exi_vp, &exi->exi_fid,
1824                     exi->exi_visible, &exi->exi_export);
1825                 exi->exi_visible = NULL;
1826 
1827                 /* interconnect the existing treenode with the new exportinfo */
1828                 newexi->exi_zone = exi->exi_zone;
1829                 newexi->exi_tree = exi->exi_tree;
1830                 newexi->exi_tree->tree_exi = newexi;
1831 
1832                 /* Update the change timestamp */
1833                 tree_update_change(ne, exi->exi_tree, NULL);
1834         } else {
1835                 treeclimb_unexport(ne, exi);
1836         }
1837 
1838         rw_exit(&ne->exported_lock);
1839 
1840         /*
1841          * Need to call into the NFSv4 server and release all data
1842          * held on this particular export.  This is important since
1843          * the v4 server may be holding file locks or vnodes under
1844          * this export.
1845          */
1846         rfs4_clean_state_exi(exi);
1847 
1848         /*
1849          * Notify the lock manager that the filesystem is being
1850          * unexported.
1851          */
1852         lm_unexport(exi);
1853 
1854         /*
1855          * If this was a public export, restore
1856          * the public filehandle to the root.
1857          */
1858 
1859         /*
1860          * XXX KEBE ASKS --> Should CRED() instead be
1861          * exi->exi_zone->zone_kcred?
1862          */
1863         if (exi == ne->exi_public) {
1864                 ne->exi_public = ne->exi_root;
1865 
1866                 nfslog_share_record(ne->exi_public, CRED());
1867         }
1868 
1869         if (exi->exi_export.ex_flags & EX_LOG)
1870                 nfslog_unshare_record(exi, CRED());
1871 
1872         exi_rele(exi);
1873         return (0);
1874 }
1875 
1876 /*
1877  * Get file handle system call.
1878  * Takes file name and returns a file handle for it.
1879  * Credentials must be verified before calling.
1880  */
1881 int
1882 nfs_getfh(struct nfs_getfh_args *args, model_t model, cred_t *cr)