changelog shortlog tags files raw bz2 zip gz

changeset: Fix compilation issues due to onnv_85 update.

changeset 330: 02d648b1676c
parent 328:f9497d34cff0
parent 329:c7ef0056ea08
child 331:89254f878ab3
author: Ricardo Correia <rcorreia@wizy.org>
date: Thu Mar 06 19:59:39 2008 +0000 (2 months ago)
files: CHANGES src/lib/libsolcompat/include/sys/time.h src/lib/libzpool/SConscript src/zfs-fuse/SConscript src/zfs-fuse/zfs_fuid.c
description: Fix compilation issues due to onnv_85 update.
       1--- a/CHANGES	Thu Mar 06 19:36:02 2008 +0000
       2+++ b/CHANGES	Thu Mar 06 19:59:39 2008 +0000
       3@@ -1,6 +1,6 @@
       4 ? - Release 0.4.0_beta2
       5 --------------------------------------------------
       6-	* Updated ZFS code to Nevada build 81.
       7+	* Updated ZFS code to Nevada build 85.
       8 Features:
       9 	* gzip compression support (upstream).
      10 	* Filesystems can have multiple copies of data (zfs set fs copies=x) (upstream).
     1.1--- a/src/lib/libsolcompat/include/sys/time.h	Thu Mar 06 19:36:02 2008 +0000
     1.2+++ b/src/lib/libsolcompat/include/sys/time.h	Thu Mar 06 19:59:39 2008 +0000
     1.3@@ -20,7 +20,7 @@
     1.4  * CDDL HEADER END
     1.5  */
     1.6 /*
     1.7- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
     1.8+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     1.9  * Use is subject to license terms.
    1.10  */
    1.11 
    1.12@@ -31,6 +31,7 @@
    1.13 
    1.14 #include <stdio.h>
    1.15 #include <stdlib.h>
    1.16+#include <stdint.h>
    1.17 #include <sys/types.h>
    1.18 #include <time.h>
    1.19 
    1.20@@ -38,6 +39,11 @@
    1.21 typedef struct timespec timestruc_t;
    1.22 
    1.23 #define NANOSEC 1000000000
    1.24+
    1.25+#define TIME32_MAX INT32_MAX
    1.26+#define TIME32_MIN INT32_MIN
    1.27+
    1.28+#define TIMESPEC_OVERFLOW(ts) ((ts)->tv_sec < TIME32_MIN || (ts)->tv_sec > TIME32_MAX)
    1.29 
    1.30 static inline hrtime_t gethrtime(void) {
    1.31 	struct timespec ts;
     2.1--- a/src/lib/libzpool/SConscript	Thu Mar 06 19:36:02 2008 +0000
     2.2+++ b/src/lib/libzpool/SConscript	Thu Mar 06 19:59:39 2008 +0000
     2.3@@ -3,7 +3,7 @@
     2.4 BuildDir('build-user', '.', duplicate = 0)
     2.5 BuildDir('build-kernel', '.', duplicate = 0)
     2.6 
     2.7-objects = Split('arc.c bplist.c dbuf.c dnode_sync.c dmu.c dmu_object.c dmu_objset.c dmu_send.c dmu_traverse.c dmu_tx.c dmu_zfetch.c dnode.c dsl_dataset.c dsl_deleg.c dsl_dir.c dsl_pool.c dsl_prop.c dsl_synctask.c fletcher.c gzip.c lzjb.c metaslab.c refcount.c rprwlock.c rrwlock.c sha256.c spa.c spa_config.c spa_errlog.c spa_history.c spa_misc.c space_map.c txg.c uberblock.c unique.c util.c vdev.c vdev_cache.c vdev_file.c vdev_label.c vdev_mirror.c vdev_missing.c vdev_queue.c vdev_raidz.c vdev_root.c zap.c zap_leaf.c zap_micro.c zfs_byteswap.c zfs_fm.c zfs_znode.c zil.c zio.c zio_checksum.c zio_compress.c zio_inject.c')
     2.8+objects = Split('arc.c bplist.c dbuf.c dnode_sync.c dmu.c dmu_object.c dmu_objset.c dmu_send.c dmu_traverse.c dmu_tx.c dmu_zfetch.c dnode.c dsl_dataset.c dsl_deleg.c dsl_dir.c dsl_pool.c dsl_prop.c dsl_synctask.c fletcher.c gzip.c lzjb.c metaslab.c refcount.c rprwlock.c rrwlock.c sha256.c spa.c spa_config.c spa_errlog.c spa_history.c spa_misc.c space_map.c txg.c uberblock.c unique.c util.c vdev.c vdev_cache.c vdev_file.c vdev_label.c vdev_mirror.c vdev_missing.c vdev_queue.c vdev_raidz.c vdev_root.c zap.c zap_leaf.c zap_micro.c zfs_byteswap.c zfs_fm.c zfs_fuid.c zfs_znode.c zil.c zio.c zio_checksum.c zio_compress.c zio_inject.c')
     2.9 
    2.10 objects_user = ['build-user/' + o for o in objects] + Split('build-user/kernel.c build-user/taskq.c')
    2.11 objects_kernel = ['build-kernel/' + o for o in objects]
     3.1--- a/src/zfs-fuse/SConscript	Thu Mar 06 19:36:02 2008 +0000
     3.2+++ b/src/zfs-fuse/SConscript	Thu Mar 06 19:59:39 2008 +0000
     3.3@@ -1,6 +1,6 @@
     3.4 Import('env')
     3.5 
     3.6-objects = Split('main.c cmd_listener.c ptrace.c util.c zfs_acl.c zfs_dir.c zfs_fuid.c zfs_ioctl.c zfs_log.c zfs_replay.c zfs_rlock.c zfs_vfsops.c zfs_vnops.c zvol.c fuse_listener.c zfsfuse_socket.c zfs_operations.c #lib/libzpool/libzpool-kernel.a #lib/libzfscommon/libzfscommon-kernel.a #lib/libnvpair/libnvpair-kernel.a #lib/libavl/libavl.a #lib/libumem/libumem.a #lib/libsolkerncompat/libsolkerncompat.a')
     3.7+objects = Split('main.c cmd_listener.c ptrace.c util.c zfs_acl.c zfs_dir.c zfs_ioctl.c zfs_log.c zfs_replay.c zfs_rlock.c zfs_vfsops.c zfs_vnops.c zvol.c fuse_listener.c zfsfuse_socket.c zfs_operations.c #lib/libzpool/libzpool-kernel.a #lib/libzfscommon/libzfscommon-kernel.a #lib/libnvpair/libnvpair-kernel.a #lib/libavl/libavl.a #lib/libumem/libumem.a #lib/libsolkerncompat/libsolkerncompat.a')
     3.8 cpppath = Split('#lib/libavl/include #lib/libnvpair/include #lib/libumem/include #lib/libzfscommon/include #lib/libsolkerncompat/include')
     3.9 ccflags = Split('-D_KERNEL')
    3.10 
     4.1--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2+++ b/src/lib/libzpool/zfs_fuid.c	Thu Mar 06 19:59:39 2008 +0000
     4.3@@ -0,0 +1,688 @@
     4.4+/*
     4.5+ * CDDL HEADER START
     4.6+ *
     4.7+ * The contents of this file are subject to the terms of the
     4.8+ * Common Development and Distribution License (the "License").
     4.9+ * You may not use this file except in compliance with the License.
    4.10+ *
    4.11+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
    4.12+ * or http://www.opensolaris.org/os/licensing.
    4.13+ * See the License for the specific language governing permissions
    4.14+ * and limitations under the License.
    4.15+ *
    4.16+ * When distributing Covered Code, include this CDDL HEADER in each
    4.17+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
    4.18+ * If applicable, add the following below this CDDL HEADER, with the
    4.19+ * fields enclosed by brackets "[]" replaced with your own identifying
    4.20+ * information: Portions Copyright [yyyy] [name of copyright owner]
    4.21+ *
    4.22+ * CDDL HEADER END
    4.23+ */
    4.24+/*
    4.25+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
    4.26+ * Use is subject to license terms.
    4.27+ */
    4.28+
    4.29+
    4.30+
    4.31+#include <sys/zfs_context.h>
    4.32+#include <sys/sunddi.h>
    4.33+#include <sys/dmu.h>
    4.34+#include <sys/avl.h>
    4.35+#include <sys/zap.h>
    4.36+#include <sys/refcount.h>
    4.37+#include <sys/nvpair.h>
    4.38+#ifdef _KERNEL
    4.39+#include <sys/kidmap.h>
    4.40+#include <sys/sid.h>
    4.41+#include <sys/zfs_vfsops.h>
    4.42+#include <sys/zfs_znode.h>
    4.43+#endif
    4.44+#include <sys/zfs_fuid.h>
    4.45+
    4.46+/*
    4.47+ * FUID Domain table(s).
    4.48+ *
    4.49+ * The FUID table is stored as a packed nvlist of an array
    4.50+ * of nvlists which contain an index, domain string and offset
    4.51+ *
    4.52+ * During file system initialization the nvlist(s) are read and
    4.53+ * two AVL trees are created.  One tree is keyed by the index number
    4.54+ * and the other by the domain string.  Nodes are never removed from
    4.55+ * trees, but new entries may be added.  If a new entry is added then the
    4.56+ * on-disk packed nvlist will also be updated.
    4.57+ */
    4.58+
    4.59+#define	FUID_IDX	"fuid_idx"
    4.60+#define	FUID_DOMAIN	"fuid_domain"
    4.61+#define	FUID_OFFSET	"fuid_offset"
    4.62+#define	FUID_NVP_ARRAY	"fuid_nvlist"
    4.63+
    4.64+typedef struct fuid_domain {
    4.65+	avl_node_t	f_domnode;
    4.66+	avl_node_t	f_idxnode;
    4.67+	ksiddomain_t	*f_ksid;
    4.68+	uint64_t	f_idx;
    4.69+} fuid_domain_t;
    4.70+
    4.71+/*
    4.72+ * Compare two indexes.
    4.73+ */
    4.74+static int
    4.75+idx_compare(const void *arg1, const void *arg2)
    4.76+{
    4.77+	const fuid_domain_t *node1 = arg1;
    4.78+	const fuid_domain_t *node2 = arg2;
    4.79+
    4.80+	if (node1->f_idx < node2->f_idx)
    4.81+		return (-1);
    4.82+	else if (node1->f_idx > node2->f_idx)
    4.83+		return (1);
    4.84+	return (0);
    4.85+}
    4.86+
    4.87+/*
    4.88+ * Compare two domain strings.
    4.89+ */
    4.90+static int
    4.91+domain_compare(const void *arg1, const void *arg2)
    4.92+{
    4.93+	const fuid_domain_t *node1 = arg1;
    4.94+	const fuid_domain_t *node2 = arg2;
    4.95+	int val;
    4.96+
    4.97+	val = strcmp(node1->f_ksid->kd_name, node2->f_ksid->kd_name);
    4.98+	if (val == 0)
    4.99+		return (0);
   4.100+	return (val > 0 ? 1 : -1);
   4.101+}
   4.102+
   4.103+/*
   4.104+ * load initial fuid domain and idx trees.  This function is used by
   4.105+ * both the kernel and zdb.
   4.106+ */
   4.107+uint64_t
   4.108+zfs_fuid_table_load(objset_t *os, uint64_t fuid_obj, avl_tree_t *idx_tree,
   4.109+    avl_tree_t *domain_tree)
   4.110+{
   4.111+	dmu_buf_t *db;
   4.112+	uint64_t fuid_size;
   4.113+
   4.114+	avl_create(idx_tree, idx_compare,
   4.115+	    sizeof (fuid_domain_t), offsetof(fuid_domain_t, f_idxnode));
   4.116+	avl_create(domain_tree, domain_compare,
   4.117+	    sizeof (fuid_domain_t), offsetof(fuid_domain_t, f_domnode));
   4.118+
   4.119+	VERIFY(0 == dmu_bonus_hold(os, fuid_obj, FTAG, &db));
   4.120+	fuid_size = *(uint64_t *)db->db_data;
   4.121+	dmu_buf_rele(db, FTAG);
   4.122+
   4.123+	if (fuid_size)  {
   4.124+		nvlist_t **fuidnvp;
   4.125+		nvlist_t *nvp = NULL;
   4.126+		uint_t count;
   4.127+		char *packed;
   4.128+		int i;
   4.129+
   4.130+		packed = kmem_alloc(fuid_size, KM_SLEEP);
   4.131+		VERIFY(dmu_read(os, fuid_obj, 0, fuid_size, packed) == 0);
   4.132+		VERIFY(nvlist_unpack(packed, fuid_size,
   4.133+		    &nvp, 0) == 0);
   4.134+		VERIFY(nvlist_lookup_nvlist_array(nvp, FUID_NVP_ARRAY,
   4.135+		    &fuidnvp, &count) == 0);
   4.136+
   4.137+		for (i = 0; i != count; i++) {
   4.138+			fuid_domain_t *domnode;
   4.139+			char *domain;
   4.140+			uint64_t idx;
   4.141+
   4.142+			VERIFY(nvlist_lookup_string(fuidnvp[i], FUID_DOMAIN,
   4.143+			    &domain) == 0);
   4.144+			VERIFY(nvlist_lookup_uint64(fuidnvp[i], FUID_IDX,
   4.145+			    &idx) == 0);
   4.146+
   4.147+			domnode = kmem_alloc(sizeof (fuid_domain_t), KM_SLEEP);
   4.148+
   4.149+			domnode->f_idx = idx;
   4.150+			domnode->f_ksid = ksid_lookupdomain(domain);
   4.151+			avl_add(idx_tree, domnode);
   4.152+			avl_add(domain_tree, domnode);
   4.153+		}
   4.154+		nvlist_free(nvp);
   4.155+		kmem_free(packed, fuid_size);
   4.156+	}
   4.157+	return (fuid_size);
   4.158+}
   4.159+
   4.160+void
   4.161+zfs_fuid_table_destroy(avl_tree_t *idx_tree, avl_tree_t *domain_tree)
   4.162+{
   4.163+	fuid_domain_t *domnode;
   4.164+	void *cookie;
   4.165+
   4.166+	cookie = NULL;
   4.167+	while (domnode = avl_destroy_nodes(domain_tree, &cookie))
   4.168+		ksiddomain_rele(domnode->f_ksid);
   4.169+
   4.170+	avl_destroy(domain_tree);
   4.171+	cookie = NULL;
   4.172+	while (domnode = avl_destroy_nodes(idx_tree, &cookie))
   4.173+		kmem_free(domnode, sizeof (fuid_domain_t));
   4.174+	avl_destroy(idx_tree);
   4.175+}
   4.176+
   4.177+char *
   4.178+zfs_fuid_idx_domain(avl_tree_t *idx_tree, uint32_t idx)
   4.179+{
   4.180+	fuid_domain_t searchnode, *findnode;
   4.181+	avl_index_t loc;
   4.182+
   4.183+	searchnode.f_idx = idx;
   4.184+
   4.185+	findnode = avl_find(idx_tree, &searchnode, &loc);
   4.186+
   4.187+	return (findnode->f_ksid->kd_name);
   4.188+}
   4.189+
   4.190+#ifdef _KERNEL
   4.191+/*
   4.192+ * Load the fuid table(s) into memory.
   4.193+ */
   4.194+static void
   4.195+zfs_fuid_init(zfsvfs_t *zfsvfs, dmu_tx_t *tx)
   4.196+{
   4.197+	int error = 0;
   4.198+
   4.199+	rw_enter(&zfsvfs->z_fuid_lock, RW_WRITER);
   4.200+
   4.201+	if (zfsvfs->z_fuid_loaded) {
   4.202+		rw_exit(&zfsvfs->z_fuid_lock);
   4.203+		return;
   4.204+	}
   4.205+
   4.206+	if (zfsvfs->z_fuid_obj == 0) {
   4.207+
   4.208+		/* first make sure we need to allocate object */
   4.209+
   4.210+		error = zap_lookup(zfsvfs->z_os, MASTER_NODE_OBJ,
   4.211+		    ZFS_FUID_TABLES, 8, 1, &zfsvfs->z_fuid_obj);
   4.212+		if (error == ENOENT && tx != NULL) {
   4.213+			zfsvfs->z_fuid_obj = dmu_object_alloc(zfsvfs->z_os,
   4.214+			    DMU_OT_FUID, 1 << 14, DMU_OT_FUID_SIZE,
   4.215+			    sizeof (uint64_t), tx);
   4.216+			VERIFY(zap_add(zfsvfs->z_os, MASTER_NODE_OBJ,
   4.217+			    ZFS_FUID_TABLES, sizeof (uint64_t), 1,
   4.218+			    &zfsvfs->z_fuid_obj, tx) == 0);
   4.219+		}
   4.220+	}
   4.221+
   4.222+	zfsvfs->z_fuid_size = zfs_fuid_table_load(zfsvfs->z_os,
   4.223+	    zfsvfs->z_fuid_obj, &zfsvfs->z_fuid_idx, &zfsvfs->z_fuid_domain);
   4.224+
   4.225+	zfsvfs->z_fuid_loaded = B_TRUE;
   4.226+	rw_exit(&zfsvfs->z_fuid_lock);
   4.227+}
   4.228+
   4.229+/*
   4.230+ * Query domain table for a given domain.
   4.231+ *
   4.232+ * If domain isn't found it is added to AVL trees and
   4.233+ * the results are pushed out to disk.
   4.234+ */
   4.235+int
   4.236+zfs_fuid_find_by_domain(zfsvfs_t *zfsvfs, const char *domain, char **retdomain,
   4.237+    dmu_tx_t *tx)
   4.238+{
   4.239+	fuid_domain_t searchnode, *findnode;
   4.240+	avl_index_t loc;
   4.241+
   4.242+	/*
   4.243+	 * If the dummy "nobody" domain then return an index of 0
   4.244+	 * to cause the created FUID to be a standard POSIX id
   4.245+	 * for the user nobody.
   4.246+	 */
   4.247+	if (domain[0] == '\0') {
   4.248+		*retdomain = "";
   4.249+		return (0);
   4.250+	}
   4.251+
   4.252+	searchnode.f_ksid = ksid_lookupdomain(domain);
   4.253+	if (retdomain) {
   4.254+		*retdomain = searchnode.f_ksid->kd_name;
   4.255+	}
   4.256+	if (!zfsvfs->z_fuid_loaded)
   4.257+		zfs_fuid_init(zfsvfs, tx);
   4.258+
   4.259+	rw_enter(&zfsvfs->z_fuid_lock, RW_READER);
   4.260+	findnode = avl_find(&zfsvfs->z_fuid_domain, &searchnode, &loc);
   4.261+	rw_exit(&zfsvfs->z_fuid_lock);
   4.262+
   4.263+	if (findnode) {
   4.264+		ksiddomain_rele(searchnode.f_ksid);
   4.265+		return (findnode->f_idx);
   4.266+	} else {
   4.267+		fuid_domain_t *domnode;
   4.268+		nvlist_t *nvp;
   4.269+		nvlist_t **fuids;
   4.270+		uint64_t retidx;
   4.271+		size_t nvsize = 0;
   4.272+		char *packed;
   4.273+		dmu_buf_t *db;
   4.274+		int i = 0;
   4.275+
   4.276+		domnode = kmem_alloc(sizeof (fuid_domain_t), KM_SLEEP);
   4.277+		domnode->f_ksid = searchnode.f_ksid;
   4.278+
   4.279+		rw_enter(&zfsvfs->z_fuid_lock, RW_WRITER);
   4.280+		retidx = domnode->f_idx = avl_numnodes(&zfsvfs->z_fuid_idx) + 1;
   4.281+
   4.282+		avl_add(&zfsvfs->z_fuid_domain, domnode);
   4.283+		avl_add(&zfsvfs->z_fuid_idx, domnode);
   4.284+		/*
   4.285+		 * Now resync the on-disk nvlist.
   4.286+		 */
   4.287+		VERIFY(nvlist_alloc(&nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0);
   4.288+
   4.289+		domnode = avl_first(&zfsvfs->z_fuid_domain);
   4.290+		fuids = kmem_alloc(retidx * sizeof (void *), KM_SLEEP);
   4.291+		while (domnode) {
   4.292+			VERIFY(nvlist_alloc(&fuids[i],
   4.293+			    NV_UNIQUE_NAME, KM_SLEEP) == 0);
   4.294+			VERIFY(nvlist_add_uint64(fuids[i], FUID_IDX,
   4.295+			    domnode->f_idx) == 0);
   4.296+			VERIFY(nvlist_add_uint64(fuids[i],
   4.297+			    FUID_OFFSET, 0) == 0);
   4.298+			VERIFY(nvlist_add_string(fuids[i++], FUID_DOMAIN,
   4.299+			    domnode->f_ksid->kd_name) == 0);
   4.300+			domnode = AVL_NEXT(&zfsvfs->z_fuid_domain, domnode);
   4.301+		}
   4.302+		VERIFY(nvlist_add_nvlist_array(nvp, FUID_NVP_ARRAY,
   4.303+		    fuids, retidx) == 0);
   4.304+		for (i = 0; i != retidx; i++)
   4.305+			nvlist_free(fuids[i]);
   4.306+		kmem_free(fuids, retidx * sizeof (void *));
   4.307+		VERIFY(nvlist_size(nvp, &nvsize, NV_ENCODE_XDR) == 0);
   4.308+		packed = kmem_alloc(nvsize, KM_SLEEP);
   4.309+		VERIFY(nvlist_pack(nvp, &packed, &nvsize,
   4.310+		    NV_ENCODE_XDR, KM_SLEEP) == 0);
   4.311+		nvlist_free(nvp);
   4.312+		zfsvfs->z_fuid_size = nvsize;
   4.313+		dmu_write(zfsvfs->z_os, zfsvfs->z_fuid_obj, 0,
   4.314+		    zfsvfs->z_fuid_size, packed, tx);
   4.315+		kmem_free(packed, zfsvfs->z_fuid_size);
   4.316+		VERIFY(0 == dmu_bonus_hold(zfsvfs->z_os, zfsvfs->z_fuid_obj,
   4.317+		    FTAG, &db));
   4.318+		dmu_buf_will_dirty(db, tx);
   4.319+		*(uint64_t *)db->db_data = zfsvfs->z_fuid_size;
   4.320+		dmu_buf_rele(db, FTAG);
   4.321+
   4.322+		rw_exit(&zfsvfs->z_fuid_lock);
   4.323+		return (retidx);
   4.324+	}
   4.325+}
   4.326+
   4.327+/*
   4.328+ * Query domain table by index, returning domain string
   4.329+ *
   4.330+ * Returns a pointer from an avl node of the domain string.
   4.331+ *
   4.332+ */
   4.333+static char *
   4.334+zfs_fuid_find_by_idx(zfsvfs_t *zfsvfs, uint32_t idx)
   4.335+{
   4.336+	char *domain;
   4.337+
   4.338+	if (idx == 0 || !zfsvfs->z_use_fuids)
   4.339+		return (NULL);
   4.340+
   4.341+	if (!zfsvfs->z_fuid_loaded)
   4.342+		zfs_fuid_init(zfsvfs, NULL);
   4.343+
   4.344+	rw_enter(&zfsvfs->z_fuid_lock, RW_READER);
   4.345+	domain = zfs_fuid_idx_domain(&zfsvfs->z_fuid_idx, idx);
   4.346+	rw_exit(&zfsvfs->z_fuid_lock);
   4.347+
   4.348+	ASSERT(domain);
   4.349+	return (domain);
   4.350+}
   4.351+
   4.352+void
   4.353+zfs_fuid_map_ids(znode_t *zp, cred_t *cr, uid_t *uidp, uid_t *gidp)
   4.354+{
   4.355+	*uidp = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_phys->zp_uid,
   4.356+	    cr, ZFS_OWNER);
   4.357+	*gidp = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_phys->zp_gid,
   4.358+	    cr, ZFS_GROUP);
   4.359+}
   4.360+
   4.361+uid_t
   4.362+zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid,
   4.363+    cred_t *cr, zfs_fuid_type_t type)
   4.364+{
   4.365+	uint32_t index = FUID_INDEX(fuid);
   4.366+	char *domain;
   4.367+	uid_t id;
   4.368+
   4.369+	if (index == 0)
   4.370+		return (fuid);
   4.371+
   4.372+	domain = zfs_fuid_find_by_idx(zfsvfs, index);
   4.373+	ASSERT(domain != NULL);
   4.374+
   4.375+	if (type == ZFS_OWNER || type == ZFS_ACE_USER) {
   4.376+		(void) kidmap_getuidbysid(crgetzone(cr), domain,
   4.377+		    FUID_RID(fuid), &id);
   4.378+	} else {
   4.379+		(void) kidmap_getgidbysid(crgetzone(cr), domain,
   4.380+		    FUID_RID(fuid), &id);
   4.381+	}
   4.382+	return (id);
   4.383+}
   4.384+
   4.385+/*
   4.386+ * Add a FUID node to the list of fuid's being created for this
   4.387+ * ACL
   4.388+ *
   4.389+ * If ACL has multiple domains, then keep only one copy of each unique
   4.390+ * domain.
   4.391+ */
   4.392+static void
   4.393+zfs_fuid_node_add(zfs_fuid_info_t **fuidpp, const char *domain, uint32_t rid,
   4.394+    uint64_t idx, uint64_t id, zfs_fuid_type_t type)
   4.395+{
   4.396+	zfs_fuid_t *fuid;
   4.397+	zfs_fuid_domain_t *fuid_domain;
   4.398+	zfs_fuid_info_t *fuidp;
   4.399+	uint64_t fuididx;
   4.400+	boolean_t found = B_FALSE;
   4.401+
   4.402+	if (*fuidpp == NULL)
   4.403+		*fuidpp = zfs_fuid_info_alloc();
   4.404+
   4.405+	fuidp = *fuidpp;
   4.406+	/*
   4.407+	 * First find fuid domain index in linked list
   4.408+	 *
   4.409+	 * If one isn't found then create an entry.
   4.410+	 */
   4.411+
   4.412+	for (fuididx = 1, fuid_domain = list_head(&fuidp->z_domains);
   4.413+	    fuid_domain; fuid_domain = list_next(&fuidp->z_domains,
   4.414+	    fuid_domain), fuididx++) {
   4.415+		if (idx == fuid_domain->z_domidx) {
   4.416+			found = B_TRUE;
   4.417+			break;
   4.418+		}
   4.419+	}
   4.420+
   4.421+	if (!found) {
   4.422+		fuid_domain = kmem_alloc(sizeof (zfs_fuid_domain_t), KM_SLEEP);
   4.423+		fuid_domain->z_domain = domain;
   4.424+		fuid_domain->z_domidx = idx;
   4.425+		list_insert_tail(&fuidp->z_domains, fuid_domain);
   4.426+		fuidp->z_domain_str_sz += strlen(domain) + 1;
   4.427+		fuidp->z_domain_cnt++;
   4.428+	}
   4.429+
   4.430+	if (type == ZFS_ACE_USER || type == ZFS_ACE_GROUP) {
   4.431+		/*
   4.432+		 * Now allocate fuid entry and add it on the end of the list
   4.433+		 */
   4.434+
   4.435+		fuid = kmem_alloc(sizeof (zfs_fuid_t), KM_SLEEP);
   4.436+		fuid->z_id = id;
   4.437+		fuid->z_domidx = idx;
   4.438+		fuid->z_logfuid = FUID_ENCODE(fuididx, rid);
   4.439+
   4.440+		list_insert_tail(&fuidp->z_fuids, fuid);
   4.441+		fuidp->z_fuid_cnt++;
   4.442+	} else {
   4.443+		if (type == ZFS_OWNER)
   4.444+			fuidp->z_fuid_owner = FUID_ENCODE(fuididx, rid);
   4.445+		else
   4.446+			fuidp->z_fuid_group = FUID_ENCODE(fuididx, rid);
   4.447+	}
   4.448+}
   4.449+
   4.450+/*
   4.451+ * Create a file system FUID, based on information in the users cred
   4.452+ */
   4.453+uint64_t
   4.454+zfs_fuid_create_cred(zfsvfs_t *zfsvfs, zfs_fuid_type_t type,
   4.455+    dmu_tx_t *tx, cred_t *cr, zfs_fuid_info_t **fuidp)
   4.456+{
   4.457+	uint64_t	idx;
   4.458+	ksid_t		*ksid;
   4.459+	uint32_t	rid;
   4.460+	char 		*kdomain;
   4.461+	const char	*domain;
   4.462+	uid_t		id;
   4.463+
   4.464+	VERIFY(type == ZFS_OWNER || type == ZFS_GROUP);
   4.465+
   4.466+	if (type == ZFS_OWNER)
   4.467+		id = crgetuid(cr);
   4.468+	else
   4.469+		id = crgetgid(cr);
   4.470+
   4.471+	if (!zfsvfs->z_use_fuids || !IS_EPHEMERAL(id))
   4.472+		return ((uint64_t)id);
   4.473+
   4.474+	ksid = crgetsid(cr, (type == ZFS_OWNER) ? KSID_OWNER : KSID_GROUP);
   4.475+
   4.476+	VERIFY(ksid != NULL);
   4.477+	rid = ksid_getrid(ksid);
   4.478+	domain = ksid_getdomain(ksid);
   4.479+
   4.480+	idx = zfs_fuid_find_by_domain(zfsvfs, domain, &kdomain, tx);
   4.481+
   4.482+	zfs_fuid_node_add(fuidp, kdomain, rid, idx, id, type);
   4.483+
   4.484+	return (FUID_ENCODE(idx, rid));
   4.485+}
   4.486+
   4.487+/*
   4.488+ * Create a file system FUID for an ACL ace
   4.489+ * or a chown/chgrp of the file.
   4.490+ * This is similar to zfs_fuid_create_cred, except that
   4.491+ * we can't find the domain + rid information in the
   4.492+ * cred.  Instead we have to query Winchester for the
   4.493+ * domain and rid.
   4.494+ *
   4.495+ * During replay operations the domain+rid information is
   4.496+ * found in the zfs_fuid_info_t that the replay code has
   4.497+ * attached to the zfsvfs of the file system.
   4.498+ */
   4.499+uint64_t
   4.500+zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr,
   4.501+    zfs_fuid_type_t type, dmu_tx_t *tx, zfs_fuid_info_t **fuidpp)
   4.502+{
   4.503+	const char *domain;
   4.504+	char *kdomain;
   4.505+	uint32_t fuid_idx = FUID_INDEX(id);
   4.506+	uint32_t rid;
   4.507+	idmap_stat status;
   4.508+	uint64_t idx;
   4.509+	boolean_t is_replay = (zfsvfs->z_assign >= TXG_INITIAL);
   4.510+	zfs_fuid_t *zfuid = NULL;
   4.511+	zfs_fuid_info_t *fuidp;
   4.512+
   4.513+	/*
   4.514+	 * If POSIX ID, or entry is already a FUID then
   4.515+	 * just return the id
   4.516+	 *
   4.517+	 * We may also be handed an already FUID'ized id via
   4.518+	 * chmod.
   4.519+	 */
   4.520+
   4.521+	if (!zfsvfs->z_use_fuids || !IS_EPHEMERAL(id) || fuid_idx != 0)
   4.522+		return (id);
   4.523+
   4.524+	if (is_replay) {
   4.525+		fuidp = zfsvfs->z_fuid_replay;
   4.526+
   4.527+		/*
   4.528+		 * If we are passed an ephemeral id, but no
   4.529+		 * fuid_info was logged then return NOBODY.
   4.530+		 * This is most likely a result of idmap service
   4.531+		 * not being available.
   4.532+		 */
   4.533+		if (fuidp == NULL)
   4.534+			return (UID_NOBODY);
   4.535+
   4.536+		switch (type) {
   4.537+		case ZFS_ACE_USER:
   4.538+		case ZFS_ACE_GROUP:
   4.539+			zfuid = list_head(&fuidp->z_fuids);
   4.540+			rid = FUID_RID(zfuid->z_logfuid);
   4.541+			idx = FUID_INDEX(zfuid->z_logfuid);
   4.542+			break;
   4.543+		case ZFS_OWNER:
   4.544+			rid = FUID_RID(fuidp->z_fuid_owner);
   4.545+			idx = FUID_INDEX(fuidp->z_fuid_owner);
   4.546+			break;
   4.547+		case ZFS_GROUP:
   4.548+			rid = FUID_RID(fuidp->z_fuid_group);
   4.549+			idx = FUID_INDEX(fuidp->z_fuid_group);
   4.550+			break;
   4.551+		};
   4.552+		domain = fuidp->z_domain_table[idx -1];
   4.553+	} else {
   4.554+		if (type == ZFS_OWNER || type == ZFS_ACE_USER)
   4.555+			status = kidmap_getsidbyuid(crgetzone(cr), id,
   4.556+			    &domain, &rid);
   4.557+		else
   4.558+			status = kidmap_getsidbygid(crgetzone(cr), id,
   4.559+			    &domain, &rid);
   4.560+
   4.561+		if (status != 0) {
   4.562+			/*
   4.563+			 * When returning nobody we will need to
   4.564+			 * make a dummy fuid table entry for logging
   4.565+			 * purposes.
   4.566+			 */
   4.567+			rid = UID_NOBODY;
   4.568+			domain = "";
   4.569+		}
   4.570+	}
   4.571+
   4.572+	idx = zfs_fuid_find_by_domain(zfsvfs, domain, &kdomain, tx);
   4.573+
   4.574+	if (!is_replay)
   4.575+		zfs_fuid_node_add(fuidpp, kdomain, rid, idx, id, type);
   4.576+	else if (zfuid != NULL) {
   4.577+		list_remove(&fuidp->z_fuids, zfuid);
   4.578+		kmem_free(zfuid, sizeof (zfs_fuid_t));
   4.579+	}
   4.580+	return (FUID_ENCODE(idx, rid));
   4.581+}
   4.582+
   4.583+void
   4.584+zfs_fuid_destroy(zfsvfs_t *zfsvfs)
   4.585+{
   4.586+	rw_enter(&zfsvfs->z_fuid_lock, RW_WRITER);
   4.587+	if (!zfsvfs->z_fuid_loaded) {
   4.588+		rw_exit(&zfsvfs->z_fuid_lock);
   4.589+		return;
   4.590+	}
   4.591+	zfs_fuid_table_destroy(&zfsvfs->z_fuid_idx, &zfsvfs->z_fuid_domain);
   4.592+	rw_exit(&zfsvfs->z_fuid_lock);
   4.593+}
   4.594+
   4.595+/*
   4.596+ * Allocate zfs_fuid_info for tracking FUIDs created during
   4.597+ * zfs_mknode, VOP_SETATTR() or VOP_SETSECATTR()
   4.598+ */
   4.599+zfs_fuid_info_t *
   4.600+zfs_fuid_info_alloc(void)
   4.601+{
   4.602+	zfs_fuid_info_t *fuidp;
   4.603+
   4.604+	fuidp = kmem_zalloc(sizeof (zfs_fuid_info_t), KM_SLEEP);
   4.605+	list_create(&fuidp->z_domains, sizeof (zfs_fuid_domain_t),
   4.606+	    offsetof(zfs_fuid_domain_t, z_next));
   4.607+	list_create(&fuidp->z_fuids, sizeof (zfs_fuid_t),
   4.608+	    offsetof(zfs_fuid_t, z_next));
   4.609+	return (fuidp);
   4.610+}
   4.611+
   4.612+/*
   4.613+ * Release all memory associated with zfs_fuid_info_t
   4.614+ */
   4.615+void
   4.616+zfs_fuid_info_free(zfs_fuid_info_t *fuidp)
   4.617+{
   4.618+	zfs_fuid_t *zfuid;
   4.619+	zfs_fuid_domain_t *zdomain;
   4.620+
   4.621+	while ((zfuid = list_head(&fuidp->z_fuids)) != NULL) {
   4.622+		list_remove(&fuidp->z_fuids, zfuid);
   4.623+		kmem_free(zfuid, sizeof (zfs_fuid_t));
   4.624+	}
   4.625+
   4.626+	if (fuidp->z_domain_table != NULL)
   4.627+		kmem_free(fuidp->z_domain_table,
   4.628+		    (sizeof (char **)) * fuidp->z_domain_cnt);
   4.629+
   4.630+	while ((zdomain = list_head(&fuidp->z_domains)) != NULL) {
   4.631+		list_remove(&fuidp->z_domains, zdomain);
   4.632+		kmem_free(zdomain, sizeof (zfs_fuid_domain_t));
   4.633+	}
   4.634+
   4.635+	kmem_free(fuidp, sizeof (zfs_fuid_info_t));
   4.636+}
   4.637+
   4.638+/*
   4.639+ * Check to see if id is a groupmember.  If cred
   4.640+ * has ksid info then sidlist is checked first
   4.641+ * and if still not found then POSIX groups are checked
   4.642+ *
   4.643+ * Will use a straight FUID compare when possible.
   4.644+ */
   4.645+boolean_t
   4.646+zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr)
   4.647+{
   4.648+	ksid_t		*ksid = crgetsid(cr, KSID_GROUP);
   4.649+	uid_t		gid;
   4.650+
   4.651+	if (ksid) {
   4.652+		int 		i;
   4.653+		ksid_t		*ksid_groups;
   4.654+		ksidlist_t	*ksidlist = crgetsidlist(cr);
   4.655+		uint32_t	idx = FUID_INDEX(id);
   4.656+		uint32_t	rid = FUID_RID(id);
   4.657+
   4.658+		ASSERT(ksidlist);
   4.659+		ksid_groups = ksidlist->ksl_sids;
   4.660+
   4.661+		for (i = 0; i != ksidlist->ksl_nsid; i++) {
   4.662+			if (idx == 0) {
   4.663+				if (id != IDMAP_WK_CREATOR_GROUP_GID &&
   4.664+				    id == ksid_groups[i].ks_id) {
   4.665+					return (B_TRUE);
   4.666+				}
   4.667+			} else {
   4.668+				char *domain;
   4.669+
   4.670+				domain = zfs_fuid_find_by_idx(zfsvfs, idx);
   4.671+				ASSERT(domain != NULL);
   4.672+
   4.673+				if (strcmp(domain,
   4.674+				    IDMAP_WK_CREATOR_SID_AUTHORITY) == 0)
   4.675+					return (B_FALSE);
   4.676+
   4.677+				if ((strcmp(domain,
   4.678+				    ksid_groups[i].ks_domain->kd_name) == 0) &&
   4.679+				    rid == ksid_groups[i].ks_rid)
   4.680+					return (B_TRUE);
   4.681+			}
   4.682+		}
   4.683+	}
   4.684+
   4.685+	/*
   4.686+	 * Not found in ksidlist, check posix groups
   4.687+	 */
   4.688+	gid = zfs_fuid_map_id(zfsvfs, id, cr, ZFS_GROUP);
   4.689+	return (groupmember(gid, cr));
   4.690+}
   4.691+#endif
     5.1--- a/src/zfs-fuse/zfs_fuid.c	Thu Mar 06 19:36:02 2008 +0000
     5.2+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3@@ -1,688 +0,0 @@
     5.4-/*
     5.5- * CDDL HEADER START
     5.6- *
     5.7- * The contents of this file are subject to the terms of the
     5.8- * Common Development and Distribution License (the "License").
     5.9- * You may not use this file except in compliance with the License.
    5.10- *
    5.11- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
    5.12- * or http://www.opensolaris.org/os/licensing.
    5.13- * See the License for the specific language governing permissions
    5.14- * and limitations under the License.
    5.15- *
    5.16- * When distributing Covered Code, include this CDDL HEADER in each
    5.17- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
    5.18- * If applicable, add the following below this CDDL HEADER, with the
    5.19- * fields enclosed by brackets "[]" replaced with your own identifying
    5.20- * information: Portions Copyright [yyyy] [name of copyright owner]
    5.21- *
    5.22- * CDDL HEADER END
    5.23- */
    5.24-/*
    5.25- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
    5.26- * Use is subject to license terms.
    5.27- */
    5.28-
    5.29-
    5.30-
    5.31-#include <sys/zfs_context.h>
    5.32-#include <sys/sunddi.h>
    5.33-#include <sys/dmu.h>
    5.34-#include <sys/avl.h>
    5.35-#include <sys/zap.h>
    5.36-#include <sys/refcount.h>
    5.37-#include <sys/nvpair.h>
    5.38-#ifdef _KERNEL
    5.39-#include <sys/kidmap.h>
    5.40-#include <sys/sid.h>
    5.41-#include <sys/zfs_vfsops.h>
    5.42-#include <sys/zfs_znode.h>
    5.43-#endif
    5.44-#include <sys/zfs_fuid.h>
    5.45-
    5.46-/*
    5.47- * FUID Domain table(s).
    5.48- *
    5.49- * The FUID table is stored as a packed nvlist of an array
    5.50- * of nvlists which contain an index, domain string and offset
    5.51- *
    5.52- * During file system initialization the nvlist(s) are read and
    5.53- * two AVL trees are created.  One tree is keyed by the index number
    5.54- * and the other by the domain string.  Nodes are never removed from
    5.55- * trees, but new entries may be added.  If a new entry is added then the
    5.56- * on-disk packed nvlist will also be updated.
    5.57- */
    5.58-
    5.59-#define	FUID_IDX	"fuid_idx"
    5.60-#define	FUID_DOMAIN	"fuid_domain"
    5.61-#define	FUID_OFFSET	"fuid_offset"
    5.62-#define	FUID_NVP_ARRAY	"fuid_nvlist"
    5.63-
    5.64-typedef struct fuid_domain {
    5.65-	avl_node_t	f_domnode;
    5.66-	avl_node_t	f_idxnode;
    5.67-	ksiddomain_t	*f_ksid;
    5.68-	uint64_t	f_idx;
    5.69-} fuid_domain_t;
    5.70-
    5.71-/*
    5.72- * Compare two indexes.
    5.73- */
    5.74-static int
    5.75-idx_compare(const void *arg1, const void *arg2)
    5.76-{
    5.77-	const fuid_domain_t *node1 = arg1;
    5.78-	const fuid_domain_t *node2 = arg2;
    5.79-
    5.80-	if (node1->f_idx < node2->f_idx)
    5.81-		return (-1);
    5.82-	else if (node1->f_idx > node2->f_idx)
    5.83-		return (1);
    5.84-	return (0);
    5.85-}
    5.86-
    5.87-/*
    5.88- * Compare two domain strings.
    5.89- */
    5.90-static int
    5.91-domain_compare(const void *arg1, const void *arg2)
    5.92-{
    5.93-	const fuid_domain_t *node1 = arg1;
    5.94-	const fuid_domain_t *node2 = arg2;
    5.95-	int val;
    5.96-
    5.97-	val = strcmp(node1->f_ksid->kd_name, node2->f_ksid->kd_name);
    5.98-	if (val == 0)
    5.99-		return (0);
   5.100-	return (val > 0 ? 1 : -1);
   5.101-}
   5.102-
   5.103-/*
   5.104- * load initial fuid domain and idx trees.  This function is used by
   5.105- * both the kernel and zdb.
   5.106- */
   5.107-uint64_t
   5.108-zfs_fuid_table_load(objset_t *os, uint64_t fuid_obj, avl_tree_t *idx_tree,
   5.109-    avl_tree_t *domain_tree)
   5.110-{
   5.111-	dmu_buf_t *db;
   5.112-	uint64_t fuid_size;
   5.113-
   5.114-	avl_create(idx_tree, idx_compare,
   5.115-	    sizeof (fuid_domain_t), offsetof(fuid_domain_t, f_idxnode));
   5.116-	avl_create(domain_tree, domain_compare,
   5.117-	    sizeof (fuid_domain_t), offsetof(fuid_domain_t, f_domnode));
   5.118-
   5.119-	VERIFY(0 == dmu_bonus_hold(os, fuid_obj, FTAG, &db));
   5.120-	fuid_size = *(uint64_t *)db->db_data;
   5.121-	dmu_buf_rele(db, FTAG);
   5.122-
   5.123-	if (fuid_size)  {
   5.124-		nvlist_t **fuidnvp;
   5.125-		nvlist_t *nvp = NULL;
   5.126-		uint_t count;
   5.127-		char *packed;
   5.128-		int i;
   5.129-
   5.130-		packed = kmem_alloc(fuid_size, KM_SLEEP);
   5.131-		VERIFY(dmu_read(os, fuid_obj, 0, fuid_size, packed) == 0);
   5.132-		VERIFY(nvlist_unpack(packed, fuid_size,
   5.133-		    &nvp, 0) == 0);
   5.134-		VERIFY(nvlist_lookup_nvlist_array(nvp, FUID_NVP_ARRAY,
   5.135-		    &fuidnvp, &count) == 0);
   5.136-
   5.137-		for (i = 0; i != count; i++) {
   5.138-			fuid_domain_t *domnode;
   5.139-			char *domain;
   5.140-			uint64_t idx;
   5.141-
   5.142-			VERIFY(nvlist_lookup_string(fuidnvp[i], FUID_DOMAIN,
   5.143-			    &domain) == 0);
   5.144-			VERIFY(nvlist_lookup_uint64(fuidnvp[i], FUID_IDX,
   5.145-			    &idx) == 0);
   5.146-
   5.147-			domnode = kmem_alloc(sizeof (fuid_domain_t), KM_SLEEP);
   5.148-
   5.149-			domnode->f_idx = idx;
   5.150-			domnode->f_ksid = ksid_lookupdomain(domain);
   5.151-			avl_add(idx_tree, domnode);
   5.152-			avl_add(domain_tree, domnode);
   5.153-		}
   5.154-		nvlist_free(nvp);
   5.155-		kmem_free(packed, fuid_size);
   5.156-	}
   5.157-	return (fuid_size);
   5.158-}
   5.159-
   5.160-void
   5.161-zfs_fuid_table_destroy(avl_tree_t *idx_tree, avl_tree_t *domain_tree)
   5.162-{
   5.163-	fuid_domain_t *domnode;
   5.164-	void *cookie;
   5.165-
   5.166-	cookie = NULL;
   5.167-	while (domnode = avl_destroy_nodes(domain_tree, &cookie))
   5.168-		ksiddomain_rele(domnode->f_ksid);
   5.169-
   5.170-	avl_destroy(domain_tree);
   5.171-	cookie = NULL;
   5.172-	while (domnode = avl_destroy_nodes(idx_tree, &cookie))
   5.173-		kmem_free(domnode, sizeof (fuid_domain_t));
   5.174-	avl_destroy(idx_tree);
   5.175-}
   5.176-
   5.177-char *
   5.178-zfs_fuid_idx_domain(avl_tree_t *idx_tree, uint32_t idx)
   5.179-{
   5.180-	fuid_domain_t searchnode, *findnode;
   5.181-	avl_index_t loc;
   5.182-
   5.183-	searchnode.f_idx = idx;
   5.184-
   5.185-	findnode = avl_find(idx_tree, &searchnode, &loc);
   5.186-
   5.187-	return (findnode->f_ksid->kd_name);
   5.188-}
   5.189-
   5.190-#ifdef _KERNEL
   5.191-/*
   5.192- * Load the fuid table(s) into memory.
   5.193- */
   5.194-static void
   5.195-zfs_fuid_init(zfsvfs_t *zfsvfs, dmu_tx_t *tx)
   5.196-{
   5.197-	int error = 0;
   5.198-
   5.199-	rw_enter(&zfsvfs->z_fuid_lock, RW_WRITER);
   5.200-
   5.201-	if (zfsvfs->z_fuid_loaded) {
   5.202-		rw_exit(&zfsvfs->z_fuid_lock);
   5.203-		return;
   5.204-	}
   5.205-
   5.206-	if (zfsvfs->z_fuid_obj == 0) {
   5.207-
   5.208-		/* first make sure we need to allocate object */
   5.209-
   5.210-		error = zap_lookup(zfsvfs->z_os, MASTER_NODE_OBJ,
   5.211-		    ZFS_FUID_TABLES, 8, 1, &zfsvfs->z_fuid_obj);
   5.212-		if (error == ENOENT && tx != NULL) {
   5.213-			zfsvfs->z_fuid_obj = dmu_object_alloc(zfsvfs->z_os,
   5.214-			    DMU_OT_FUID, 1 << 14, DMU_OT_FUID_SIZE,
   5.215-			    sizeof (uint64_t), tx);
   5.216-			VERIFY(zap_add(zfsvfs->z_os, MASTER_NODE_OBJ,
   5.217-			    ZFS_FUID_TABLES, sizeof (uint64_t), 1,
   5.218-			    &zfsvfs->z_fuid_obj, tx) == 0);
   5.219-		}
   5.220-	}
   5.221-
   5.222-	zfsvfs->z_fuid_size = zfs_fuid_table_load(zfsvfs->z_os,
   5.223-	    zfsvfs->z_fuid_obj, &zfsvfs->z_fuid_idx, &zfsvfs->z_fuid_domain);
   5.224-
   5.225-	zfsvfs->z_fuid_loaded = B_TRUE;
   5.226-	rw_exit(&zfsvfs->z_fuid_lock);
   5.227-}
   5.228-
   5.229-/*
   5.230- * Query domain table for a given domain.
   5.231- *
   5.232- * If domain isn't found it is added to AVL trees and
   5.233- * the results are pushed out to disk.
   5.234- */
   5.235-int
   5.236-zfs_fuid_find_by_domain(zfsvfs_t *zfsvfs, const char *domain, char **retdomain,
   5.237-    dmu_tx_t *tx)
   5.238-{
   5.239-	fuid_domain_t searchnode, *findnode;
   5.240-	avl_index_t loc;
   5.241-
   5.242-	/*
   5.243-	 * If the dummy "nobody" domain then return an index of 0
   5.244-	 * to cause the created FUID to be a standard POSIX id
   5.245-	 * for the user nobody.
   5.246-	 */
   5.247-	if (domain[0] == '\0') {
   5.248-		*retdomain = "";
   5.249-		return (0);
   5.250-	}
   5.251-
   5.252-	searchnode.f_ksid = ksid_lookupdomain(domain);
   5.253-	if (retdomain) {
   5.254-		*retdomain = searchnode.f_ksid->kd_name;
   5.255-	}
   5.256-	if (!zfsvfs->z_fuid_loaded)
   5.257-		zfs_fuid_init(zfsvfs, tx);
   5.258-
   5.259-	rw_enter(&zfsvfs->z_fuid_lock, RW_READER);
   5.260-	findnode = avl_find(&zfsvfs->z_fuid_domain, &searchnode, &loc);
   5.261-	rw_exit(&zfsvfs->z_fuid_lock);
   5.262-
   5.263-	if (findnode) {
   5.264-		ksiddomain_rele(searchnode.f_ksid);
   5.265-		return (findnode->f_idx);
   5.266-	} else {
   5.267-		fuid_domain_t *domnode;
   5.268-		nvlist_t *nvp;
   5.269-		nvlist_t **fuids;
   5.270-		uint64_t retidx;
   5.271-		size_t nvsize = 0;
   5.272-		char *packed;
   5.273-		dmu_buf_t *db;
   5.274-		int i = 0;
   5.275-
   5.276-		domnode = kmem_alloc(sizeof (fuid_domain_t), KM_SLEEP);
   5.277-		domnode->f_ksid = searchnode.f_ksid;
   5.278-
   5.279-		rw_enter(&zfsvfs->z_fuid_lock, RW_WRITER);
   5.280-		retidx = domnode->f_idx = avl_numnodes(&zfsvfs->z_fuid_idx) + 1;
   5.281-
   5.282-		avl_add(&zfsvfs->z_fuid_domain, domnode);
   5.283-		avl_add(&zfsvfs->z_fuid_idx, domnode);
   5.284-		/*
   5.285-		 * Now resync the on-disk nvlist.
   5.286-		 */
   5.287-		VERIFY(nvlist_alloc(&nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0);
   5.288-
   5.289-		domnode = avl_first(&zfsvfs->z_fuid_domain);
   5.290-		fuids = kmem_alloc(retidx * sizeof (void *), KM_SLEEP);
   5.291-		while (domnode) {
   5.292-			VERIFY(nvlist_alloc(&fuids[i],
   5.293-			    NV_UNIQUE_NAME, KM_SLEEP) == 0);
   5.294-			VERIFY(nvlist_add_uint64(fuids[i], FUID_IDX,
   5.295-			    domnode->f_idx) == 0);
   5.296-			VERIFY(nvlist_add_uint64(fuids[i],
   5.297-			    FUID_OFFSET, 0) == 0);
   5.298-			VERIFY(nvlist_add_string(fuids[i++], FUID_DOMAIN,
   5.299-			    domnode->f_ksid->kd_name) == 0);
   5.300-			domnode = AVL_NEXT(&zfsvfs->z_fuid_domain, domnode);
   5.301-		}
   5.302-		VERIFY(nvlist_add_nvlist_array(nvp, FUID_NVP_ARRAY,
   5.303-		    fuids, retidx) == 0);
   5.304-		for (i = 0; i != retidx; i++)
   5.305-			nvlist_free(fuids[i]);
   5.306-		kmem_free(fuids, retidx * sizeof (void *));
   5.307-		VERIFY(nvlist_size(nvp, &nvsize, NV_ENCODE_XDR) == 0);
   5.308-		packed = kmem_alloc(nvsize, KM_SLEEP);
   5.309-		VERIFY(nvlist_pack(nvp, &packed, &nvsize,
   5.310-		    NV_ENCODE_XDR, KM_SLEEP) == 0);
   5.311-		nvlist_free(nvp);
   5.312-		zfsvfs->z_fuid_size = nvsize;
   5.313-		dmu_write(zfsvfs->z_os, zfsvfs->z_fuid_obj, 0,
   5.314-		    zfsvfs->z_fuid_size, packed, tx);
   5.315-		kmem_free(packed, zfsvfs->z_fuid_size);
   5.316-		VERIFY(0 == dmu_bonus_hold(zfsvfs->z_os, zfsvfs->z_fuid_obj,
   5.317-		    FTAG, &db));
   5.318-		dmu_buf_will_dirty(db, tx);
   5.319-		*(uint64_t *)db->db_data = zfsvfs->z_fuid_size;
   5.320-		dmu_buf_rele(db, FTAG);
   5.321-
   5.322-		rw_exit(&zfsvfs->z_fuid_lock);
   5.323-		return (retidx);
   5.324-	}
   5.325-}
   5.326-
   5.327-/*
   5.328- * Query domain table by index, returning domain string
   5.329- *
   5.330- * Returns a pointer from an avl node of the domain string.
   5.331- *
   5.332- */
   5.333-static char *
   5.334-zfs_fuid_find_by_idx(zfsvfs_t *zfsvfs, uint32_t idx)
   5.335-{
   5.336-	char *domain;
   5.337-
   5.338-	if (idx == 0 || !zfsvfs->z_use_fuids)
   5.339-		return (NULL);
   5.340-
   5.341-	if (!zfsvfs->z_fuid_loaded)
   5.342-		zfs_fuid_init(zfsvfs, NULL);
   5.343-
   5.344-	rw_enter(&zfsvfs->z_fuid_lock, RW_READER);
   5.345-	domain = zfs_fuid_idx_domain(&zfsvfs->z_fuid_idx, idx);
   5.346-	rw_exit(&zfsvfs->z_fuid_lock);
   5.347-
   5.348-	ASSERT(domain);
   5.349-	return (domain);
   5.350-}
   5.351-
   5.352-void
   5.353-zfs_fuid_map_ids(znode_t *zp, cred_t *cr, uid_t *uidp, uid_t *gidp)
   5.354-{
   5.355-	*uidp = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_phys->zp_uid,
   5.356-	    cr, ZFS_OWNER);
   5.357-	*gidp = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_phys->zp_gid,
<