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)
|