zfs_vfsops.c revision 215260
1168404Spjd/*
2168404Spjd * CDDL HEADER START
3168404Spjd *
4168404Spjd * The contents of this file are subject to the terms of the
5168404Spjd * Common Development and Distribution License (the "License").
6168404Spjd * You may not use this file except in compliance with the License.
7168404Spjd *
8168404Spjd * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9168404Spjd * or http://www.opensolaris.org/os/licensing.
10168404Spjd * See the License for the specific language governing permissions
11168404Spjd * and limitations under the License.
12168404Spjd *
13168404Spjd * When distributing Covered Code, include this CDDL HEADER in each
14168404Spjd * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15168404Spjd * If applicable, add the following below this CDDL HEADER, with the
16168404Spjd * fields enclosed by brackets "[]" replaced with your own identifying
17168404Spjd * information: Portions Copyright [yyyy] [name of copyright owner]
18168404Spjd *
19168404Spjd * CDDL HEADER END
20168404Spjd */
21168404Spjd/*
22209962Smm * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23168404Spjd * Use is subject to license terms.
24168404Spjd */
25168404Spjd
26168404Spjd#include <sys/types.h>
27168404Spjd#include <sys/param.h>
28168404Spjd#include <sys/systm.h>
29168404Spjd#include <sys/kernel.h>
30168404Spjd#include <sys/sysmacros.h>
31168404Spjd#include <sys/kmem.h>
32168404Spjd#include <sys/acl.h>
33168404Spjd#include <sys/vnode.h>
34168404Spjd#include <sys/vfs.h>
35168404Spjd#include <sys/mntent.h>
36168404Spjd#include <sys/mount.h>
37168404Spjd#include <sys/cmn_err.h>
38168404Spjd#include <sys/zfs_znode.h>
39168404Spjd#include <sys/zfs_dir.h>
40168404Spjd#include <sys/zil.h>
41168404Spjd#include <sys/fs/zfs.h>
42168404Spjd#include <sys/dmu.h>
43168404Spjd#include <sys/dsl_prop.h>
44168404Spjd#include <sys/dsl_dataset.h>
45185029Spjd#include <sys/dsl_deleg.h>
46168404Spjd#include <sys/spa.h>
47168404Spjd#include <sys/zap.h>
48168404Spjd#include <sys/varargs.h>
49168962Spjd#include <sys/policy.h>
50168404Spjd#include <sys/atomic.h>
51168404Spjd#include <sys/zfs_ioctl.h>
52168404Spjd#include <sys/zfs_ctldir.h>
53185029Spjd#include <sys/zfs_fuid.h>
54168962Spjd#include <sys/sunddi.h>
55168404Spjd#include <sys/dnlc.h>
56185029Spjd#include <sys/dmu_objset.h>
57185029Spjd#include <sys/spa_boot.h>
58168404Spjd
59168404Spjdstruct mtx zfs_debug_mtx;
60168404SpjdMTX_SYSINIT(zfs_debug_mtx, &zfs_debug_mtx, "zfs_debug", MTX_DEF);
61185029Spjd
62168404SpjdSYSCTL_NODE(_vfs, OID_AUTO, zfs, CTLFLAG_RW, 0, "ZFS file system");
63185029Spjd
64185029Spjdint zfs_super_owner = 0;
65185029SpjdSYSCTL_INT(_vfs_zfs, OID_AUTO, super_owner, CTLFLAG_RW, &zfs_super_owner, 0,
66185029Spjd    "File system owner can perform privileged operation on his file systems");
67185029Spjd
68168404Spjdint zfs_debug_level = 0;
69168713SpjdTUNABLE_INT("vfs.zfs.debug", &zfs_debug_level);
70168404SpjdSYSCTL_INT(_vfs_zfs, OID_AUTO, debug, CTLFLAG_RW, &zfs_debug_level, 0,
71168404Spjd    "Debug level");
72168404Spjd
73185029SpjdSYSCTL_NODE(_vfs_zfs, OID_AUTO, version, CTLFLAG_RD, 0, "ZFS versions");
74185029Spjdstatic int zfs_version_acl = ZFS_ACL_VERSION;
75185029SpjdSYSCTL_INT(_vfs_zfs_version, OID_AUTO, acl, CTLFLAG_RD, &zfs_version_acl, 0,
76185029Spjd    "ZFS_ACL_VERSION");
77185029Spjdstatic int zfs_version_dmu_backup_header = DMU_BACKUP_HEADER_VERSION;
78185029SpjdSYSCTL_INT(_vfs_zfs_version, OID_AUTO, dmu_backup_header, CTLFLAG_RD,
79185029Spjd    &zfs_version_dmu_backup_header, 0, "DMU_BACKUP_HEADER_VERSION");
80185029Spjdstatic int zfs_version_dmu_backup_stream = DMU_BACKUP_STREAM_VERSION;
81185029SpjdSYSCTL_INT(_vfs_zfs_version, OID_AUTO, dmu_backup_stream, CTLFLAG_RD,
82185029Spjd    &zfs_version_dmu_backup_stream, 0, "DMU_BACKUP_STREAM_VERSION");
83185029Spjdstatic int zfs_version_spa = SPA_VERSION;
84185029SpjdSYSCTL_INT(_vfs_zfs_version, OID_AUTO, spa, CTLFLAG_RD, &zfs_version_spa, 0,
85185029Spjd    "SPA_VERSION");
86185029Spjdstatic int zfs_version_zpl = ZPL_VERSION;
87185029SpjdSYSCTL_INT(_vfs_zfs_version, OID_AUTO, zpl, CTLFLAG_RD, &zfs_version_zpl, 0,
88185029Spjd    "ZPL_VERSION");
89185029Spjd
90191990Sattiliostatic int zfs_mount(vfs_t *vfsp);
91191990Sattiliostatic int zfs_umount(vfs_t *vfsp, int fflag);
92191990Sattiliostatic int zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp);
93191990Sattiliostatic int zfs_statfs(vfs_t *vfsp, struct statfs *statp);
94168404Spjdstatic int zfs_vget(vfs_t *vfsp, ino_t ino, int flags, vnode_t **vpp);
95191990Sattiliostatic int zfs_sync(vfs_t *vfsp, int waitfor);
96196982Spjdstatic int zfs_checkexp(vfs_t *vfsp, struct sockaddr *nam, int *extflagsp,
97196982Spjd    struct ucred **credanonp, int *numsecflavors, int **secflavors);
98168404Spjdstatic int zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, vnode_t **vpp);
99168404Spjdstatic void zfs_objset_close(zfsvfs_t *zfsvfs);
100168404Spjdstatic void zfs_freevfs(vfs_t *vfsp);
101168404Spjd
102168404Spjdstatic struct vfsops zfs_vfsops = {
103168404Spjd	.vfs_mount =		zfs_mount,
104168404Spjd	.vfs_unmount =		zfs_umount,
105168404Spjd	.vfs_root =		zfs_root,
106168404Spjd	.vfs_statfs =		zfs_statfs,
107168404Spjd	.vfs_vget =		zfs_vget,
108168404Spjd	.vfs_sync =		zfs_sync,
109196982Spjd	.vfs_checkexp =		zfs_checkexp,
110168404Spjd	.vfs_fhtovp =		zfs_fhtovp,
111168404Spjd};
112168404Spjd
113185029SpjdVFS_SET(zfs_vfsops, zfs, VFCF_JAIL | VFCF_DELEGADMIN);
114168404Spjd
115168404Spjd/*
116168404Spjd * We need to keep a count of active fs's.
117168404Spjd * This is necessary to prevent our module
118168404Spjd * from being unloaded after a umount -f
119168404Spjd */
120168404Spjdstatic uint32_t	zfs_active_fs_count = 0;
121168404Spjd
122168404Spjd/*ARGSUSED*/
123168404Spjdstatic int
124191990Sattiliozfs_sync(vfs_t *vfsp, int waitfor)
125168404Spjd{
126168404Spjd
127168404Spjd	/*
128168404Spjd	 * Data integrity is job one.  We don't want a compromised kernel
129168404Spjd	 * writing to the storage pool, so we never sync during panic.
130168404Spjd	 */
131168404Spjd	if (panicstr)
132168404Spjd		return (0);
133168404Spjd
134168404Spjd	if (vfsp != NULL) {
135168404Spjd		/*
136168404Spjd		 * Sync a specific filesystem.
137168404Spjd		 */
138168404Spjd		zfsvfs_t *zfsvfs = vfsp->vfs_data;
139209962Smm		dsl_pool_t *dp;
140168404Spjd		int error;
141168404Spjd
142191990Sattilio		error = vfs_stdsync(vfsp, waitfor);
143168404Spjd		if (error != 0)
144168404Spjd			return (error);
145168404Spjd
146168404Spjd		ZFS_ENTER(zfsvfs);
147209962Smm		dp = dmu_objset_pool(zfsvfs->z_os);
148209962Smm
149209962Smm		/*
150209962Smm		 * If the system is shutting down, then skip any
151209962Smm		 * filesystems which may exist on a suspended pool.
152209962Smm		 */
153209962Smm		if (sys_shutdown && spa_suspended(dp->dp_spa)) {
154209962Smm			ZFS_EXIT(zfsvfs);
155209962Smm			return (0);
156209962Smm		}
157209962Smm
158168404Spjd		if (zfsvfs->z_log != NULL)
159168404Spjd			zil_commit(zfsvfs->z_log, UINT64_MAX, 0);
160168404Spjd		else
161209962Smm			txg_wait_synced(dp, 0);
162168404Spjd		ZFS_EXIT(zfsvfs);
163168404Spjd	} else {
164168404Spjd		/*
165168404Spjd		 * Sync all ZFS filesystems.  This is what happens when you
166168404Spjd		 * run sync(1M).  Unlike other filesystems, ZFS honors the
167168404Spjd		 * request by waiting for all pools to commit all dirty data.
168168404Spjd		 */
169168404Spjd		spa_sync_allpools();
170168404Spjd	}
171168404Spjd
172168404Spjd	return (0);
173168404Spjd}
174168404Spjd
175168404Spjdstatic void
176168404Spjdatime_changed_cb(void *arg, uint64_t newval)
177168404Spjd{
178168404Spjd	zfsvfs_t *zfsvfs = arg;
179168404Spjd
180168404Spjd	if (newval == TRUE) {
181168404Spjd		zfsvfs->z_atime = TRUE;
182168404Spjd		zfsvfs->z_vfs->vfs_flag &= ~MNT_NOATIME;
183168404Spjd		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_NOATIME);
184168404Spjd		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_ATIME, NULL, 0);
185168404Spjd	} else {
186168404Spjd		zfsvfs->z_atime = FALSE;
187168404Spjd		zfsvfs->z_vfs->vfs_flag |= MNT_NOATIME;
188168404Spjd		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_ATIME);
189168404Spjd		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_NOATIME, NULL, 0);
190168404Spjd	}
191168404Spjd}
192168404Spjd
193168404Spjdstatic void
194168404Spjdxattr_changed_cb(void *arg, uint64_t newval)
195168404Spjd{
196168404Spjd	zfsvfs_t *zfsvfs = arg;
197168404Spjd
198168404Spjd	if (newval == TRUE) {
199168404Spjd		/* XXX locking on vfs_flag? */
200168404Spjd#ifdef TODO
201168404Spjd		zfsvfs->z_vfs->vfs_flag |= VFS_XATTR;
202168404Spjd#endif
203168404Spjd		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_NOXATTR);
204168404Spjd		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_XATTR, NULL, 0);
205168404Spjd	} else {
206168404Spjd		/* XXX locking on vfs_flag? */
207168404Spjd#ifdef TODO
208168404Spjd		zfsvfs->z_vfs->vfs_flag &= ~VFS_XATTR;
209168404Spjd#endif
210168404Spjd		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_XATTR);
211168404Spjd		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_NOXATTR, NULL, 0);
212168404Spjd	}
213168404Spjd}
214168404Spjd
215168404Spjdstatic void
216168404Spjdblksz_changed_cb(void *arg, uint64_t newval)
217168404Spjd{
218168404Spjd	zfsvfs_t *zfsvfs = arg;
219168404Spjd
220168404Spjd	if (newval < SPA_MINBLOCKSIZE ||
221168404Spjd	    newval > SPA_MAXBLOCKSIZE || !ISP2(newval))
222168404Spjd		newval = SPA_MAXBLOCKSIZE;
223168404Spjd
224168404Spjd	zfsvfs->z_max_blksz = newval;
225204101Spjd	zfsvfs->z_vfs->mnt_stat.f_iosize = newval;
226168404Spjd}
227168404Spjd
228168404Spjdstatic void
229168404Spjdreadonly_changed_cb(void *arg, uint64_t newval)
230168404Spjd{
231168404Spjd	zfsvfs_t *zfsvfs = arg;
232168404Spjd
233168404Spjd	if (newval) {
234168404Spjd		/* XXX locking on vfs_flag? */
235168404Spjd		zfsvfs->z_vfs->vfs_flag |= VFS_RDONLY;
236168404Spjd		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_RW);
237168404Spjd		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_RO, NULL, 0);
238168404Spjd	} else {
239168404Spjd		/* XXX locking on vfs_flag? */
240168404Spjd		zfsvfs->z_vfs->vfs_flag &= ~VFS_RDONLY;
241168404Spjd		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_RO);
242168404Spjd		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_RW, NULL, 0);
243168404Spjd	}
244168404Spjd}
245168404Spjd
246168404Spjdstatic void
247168404Spjdsetuid_changed_cb(void *arg, uint64_t newval)
248168404Spjd{
249168404Spjd	zfsvfs_t *zfsvfs = arg;
250168404Spjd
251168404Spjd	if (newval == FALSE) {
252168404Spjd		zfsvfs->z_vfs->vfs_flag |= VFS_NOSETUID;
253168404Spjd		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_SETUID);
254168404Spjd		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_NOSETUID, NULL, 0);
255168404Spjd	} else {
256168404Spjd		zfsvfs->z_vfs->vfs_flag &= ~VFS_NOSETUID;
257168404Spjd		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_NOSETUID);
258168404Spjd		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_SETUID, NULL, 0);
259168404Spjd	}
260168404Spjd}
261168404Spjd
262168404Spjdstatic void
263168404Spjdexec_changed_cb(void *arg, uint64_t newval)
264168404Spjd{
265168404Spjd	zfsvfs_t *zfsvfs = arg;
266168404Spjd
267168404Spjd	if (newval == FALSE) {
268168404Spjd		zfsvfs->z_vfs->vfs_flag |= VFS_NOEXEC;
269168404Spjd		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_EXEC);
270168404Spjd		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_NOEXEC, NULL, 0);
271168404Spjd	} else {
272168404Spjd		zfsvfs->z_vfs->vfs_flag &= ~VFS_NOEXEC;
273168404Spjd		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_NOEXEC);
274168404Spjd		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_EXEC, NULL, 0);
275168404Spjd	}
276168404Spjd}
277168404Spjd
278185029Spjd/*
279185029Spjd * The nbmand mount option can be changed at mount time.
280185029Spjd * We can't allow it to be toggled on live file systems or incorrect
281185029Spjd * behavior may be seen from cifs clients
282185029Spjd *
283185029Spjd * This property isn't registered via dsl_prop_register(), but this callback
284185029Spjd * will be called when a file system is first mounted
285185029Spjd */
286168404Spjdstatic void
287185029Spjdnbmand_changed_cb(void *arg, uint64_t newval)
288185029Spjd{
289185029Spjd	zfsvfs_t *zfsvfs = arg;
290185029Spjd	if (newval == FALSE) {
291185029Spjd		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_NBMAND);
292185029Spjd		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_NONBMAND, NULL, 0);
293185029Spjd	} else {
294185029Spjd		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_NONBMAND);
295185029Spjd		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_NBMAND, NULL, 0);
296185029Spjd	}
297185029Spjd}
298185029Spjd
299185029Spjdstatic void
300168404Spjdsnapdir_changed_cb(void *arg, uint64_t newval)
301168404Spjd{
302168404Spjd	zfsvfs_t *zfsvfs = arg;
303168404Spjd
304168404Spjd	zfsvfs->z_show_ctldir = newval;
305168404Spjd}
306168404Spjd
307168404Spjdstatic void
308185029Spjdvscan_changed_cb(void *arg, uint64_t newval)
309185029Spjd{
310185029Spjd	zfsvfs_t *zfsvfs = arg;
311185029Spjd
312185029Spjd	zfsvfs->z_vscan = newval;
313185029Spjd}
314185029Spjd
315185029Spjdstatic void
316168404Spjdacl_mode_changed_cb(void *arg, uint64_t newval)
317168404Spjd{
318168404Spjd	zfsvfs_t *zfsvfs = arg;
319168404Spjd
320168404Spjd	zfsvfs->z_acl_mode = newval;
321168404Spjd}
322168404Spjd
323168404Spjdstatic void
324168404Spjdacl_inherit_changed_cb(void *arg, uint64_t newval)
325168404Spjd{
326168404Spjd	zfsvfs_t *zfsvfs = arg;
327168404Spjd
328168404Spjd	zfsvfs->z_acl_inherit = newval;
329168404Spjd}
330168404Spjd
331168404Spjdstatic int
332168404Spjdzfs_register_callbacks(vfs_t *vfsp)
333168404Spjd{
334168404Spjd	struct dsl_dataset *ds = NULL;
335168404Spjd	objset_t *os = NULL;
336168404Spjd	zfsvfs_t *zfsvfs = NULL;
337185029Spjd	uint64_t nbmand;
338168404Spjd	int readonly, do_readonly = FALSE;
339168404Spjd	int setuid, do_setuid = FALSE;
340168404Spjd	int exec, do_exec = FALSE;
341168404Spjd	int xattr, do_xattr = FALSE;
342185029Spjd	int atime, do_atime = FALSE;
343168404Spjd	int error = 0;
344168404Spjd
345168404Spjd	ASSERT(vfsp);
346168404Spjd	zfsvfs = vfsp->vfs_data;
347168404Spjd	ASSERT(zfsvfs);
348168404Spjd	os = zfsvfs->z_os;
349168404Spjd
350168404Spjd	/*
351196965Spjd	 * This function can be called for a snapshot when we update snapshot's
352196965Spjd	 * mount point, which isn't really supported.
353196965Spjd	 */
354196965Spjd	if (dmu_objset_is_snapshot(os))
355196965Spjd		return (EOPNOTSUPP);
356196965Spjd
357196965Spjd	/*
358168404Spjd	 * The act of registering our callbacks will destroy any mount
359168404Spjd	 * options we may have.  In order to enable temporary overrides
360168404Spjd	 * of mount options, we stash away the current values and
361168404Spjd	 * restore them after we register the callbacks.
362168404Spjd	 */
363168404Spjd	if (vfs_optionisset(vfsp, MNTOPT_RO, NULL)) {
364168404Spjd		readonly = B_TRUE;
365168404Spjd		do_readonly = B_TRUE;
366168404Spjd	} else if (vfs_optionisset(vfsp, MNTOPT_RW, NULL)) {
367168404Spjd		readonly = B_FALSE;
368168404Spjd		do_readonly = B_TRUE;
369168404Spjd	}
370168404Spjd	if (vfs_optionisset(vfsp, MNTOPT_NOSUID, NULL)) {
371168404Spjd		setuid = B_FALSE;
372168404Spjd		do_setuid = B_TRUE;
373168404Spjd	} else {
374168404Spjd		if (vfs_optionisset(vfsp, MNTOPT_NOSETUID, NULL)) {
375168404Spjd			setuid = B_FALSE;
376168404Spjd			do_setuid = B_TRUE;
377168404Spjd		} else if (vfs_optionisset(vfsp, MNTOPT_SETUID, NULL)) {
378168404Spjd			setuid = B_TRUE;
379168404Spjd			do_setuid = B_TRUE;
380168404Spjd		}
381168404Spjd	}
382168404Spjd	if (vfs_optionisset(vfsp, MNTOPT_NOEXEC, NULL)) {
383168404Spjd		exec = B_FALSE;
384168404Spjd		do_exec = B_TRUE;
385168404Spjd	} else if (vfs_optionisset(vfsp, MNTOPT_EXEC, NULL)) {
386168404Spjd		exec = B_TRUE;
387168404Spjd		do_exec = B_TRUE;
388168404Spjd	}
389168404Spjd	if (vfs_optionisset(vfsp, MNTOPT_NOXATTR, NULL)) {
390168404Spjd		xattr = B_FALSE;
391168404Spjd		do_xattr = B_TRUE;
392168404Spjd	} else if (vfs_optionisset(vfsp, MNTOPT_XATTR, NULL)) {
393168404Spjd		xattr = B_TRUE;
394168404Spjd		do_xattr = B_TRUE;
395168404Spjd	}
396185029Spjd	if (vfs_optionisset(vfsp, MNTOPT_NOATIME, NULL)) {
397185029Spjd		atime = B_FALSE;
398185029Spjd		do_atime = B_TRUE;
399185029Spjd	} else if (vfs_optionisset(vfsp, MNTOPT_ATIME, NULL)) {
400185029Spjd		atime = B_TRUE;
401185029Spjd		do_atime = B_TRUE;
402185029Spjd	}
403168404Spjd
404168404Spjd	/*
405185029Spjd	 * nbmand is a special property.  It can only be changed at
406185029Spjd	 * mount time.
407185029Spjd	 *
408185029Spjd	 * This is weird, but it is documented to only be changeable
409185029Spjd	 * at mount time.
410185029Spjd	 */
411185029Spjd	if (vfs_optionisset(vfsp, MNTOPT_NONBMAND, NULL)) {
412185029Spjd		nbmand = B_FALSE;
413185029Spjd	} else if (vfs_optionisset(vfsp, MNTOPT_NBMAND, NULL)) {
414185029Spjd		nbmand = B_TRUE;
415185029Spjd	} else {
416185029Spjd		char osname[MAXNAMELEN];
417185029Spjd
418185029Spjd		dmu_objset_name(os, osname);
419185029Spjd		if (error = dsl_prop_get_integer(osname, "nbmand", &nbmand,
420185029Spjd		    NULL)) {
421185029Spjd			return (error);
422185029Spjd		}
423185029Spjd	}
424185029Spjd
425185029Spjd	/*
426168404Spjd	 * Register property callbacks.
427168404Spjd	 *
428168404Spjd	 * It would probably be fine to just check for i/o error from
429168404Spjd	 * the first prop_register(), but I guess I like to go
430168404Spjd	 * overboard...
431168404Spjd	 */
432168404Spjd	ds = dmu_objset_ds(os);
433168404Spjd	error = dsl_prop_register(ds, "atime", atime_changed_cb, zfsvfs);
434168404Spjd	error = error ? error : dsl_prop_register(ds,
435168404Spjd	    "xattr", xattr_changed_cb, zfsvfs);
436168404Spjd	error = error ? error : dsl_prop_register(ds,
437168404Spjd	    "recordsize", blksz_changed_cb, zfsvfs);
438168404Spjd	error = error ? error : dsl_prop_register(ds,
439168404Spjd	    "readonly", readonly_changed_cb, zfsvfs);
440168404Spjd	error = error ? error : dsl_prop_register(ds,
441168404Spjd	    "setuid", setuid_changed_cb, zfsvfs);
442168404Spjd	error = error ? error : dsl_prop_register(ds,
443168404Spjd	    "exec", exec_changed_cb, zfsvfs);
444168404Spjd	error = error ? error : dsl_prop_register(ds,
445168404Spjd	    "snapdir", snapdir_changed_cb, zfsvfs);
446168404Spjd	error = error ? error : dsl_prop_register(ds,
447168404Spjd	    "aclmode", acl_mode_changed_cb, zfsvfs);
448168404Spjd	error = error ? error : dsl_prop_register(ds,
449168404Spjd	    "aclinherit", acl_inherit_changed_cb, zfsvfs);
450185029Spjd	error = error ? error : dsl_prop_register(ds,
451185029Spjd	    "vscan", vscan_changed_cb, zfsvfs);
452168404Spjd	if (error)
453168404Spjd		goto unregister;
454168404Spjd
455168404Spjd	/*
456168404Spjd	 * Invoke our callbacks to restore temporary mount options.
457168404Spjd	 */
458168404Spjd	if (do_readonly)
459168404Spjd		readonly_changed_cb(zfsvfs, readonly);
460168404Spjd	if (do_setuid)
461168404Spjd		setuid_changed_cb(zfsvfs, setuid);
462168404Spjd	if (do_exec)
463168404Spjd		exec_changed_cb(zfsvfs, exec);
464168404Spjd	if (do_xattr)
465168404Spjd		xattr_changed_cb(zfsvfs, xattr);
466185029Spjd	if (do_atime)
467185029Spjd		atime_changed_cb(zfsvfs, atime);
468168404Spjd
469185029Spjd	nbmand_changed_cb(zfsvfs, nbmand);
470185029Spjd
471168404Spjd	return (0);
472168404Spjd
473168404Spjdunregister:
474168404Spjd	/*
475168404Spjd	 * We may attempt to unregister some callbacks that are not
476168404Spjd	 * registered, but this is OK; it will simply return ENOMSG,
477168404Spjd	 * which we will ignore.
478168404Spjd	 */
479168404Spjd	(void) dsl_prop_unregister(ds, "atime", atime_changed_cb, zfsvfs);
480168404Spjd	(void) dsl_prop_unregister(ds, "xattr", xattr_changed_cb, zfsvfs);
481168404Spjd	(void) dsl_prop_unregister(ds, "recordsize", blksz_changed_cb, zfsvfs);
482168404Spjd	(void) dsl_prop_unregister(ds, "readonly", readonly_changed_cb, zfsvfs);
483168404Spjd	(void) dsl_prop_unregister(ds, "setuid", setuid_changed_cb, zfsvfs);
484168404Spjd	(void) dsl_prop_unregister(ds, "exec", exec_changed_cb, zfsvfs);
485168404Spjd	(void) dsl_prop_unregister(ds, "snapdir", snapdir_changed_cb, zfsvfs);
486168404Spjd	(void) dsl_prop_unregister(ds, "aclmode", acl_mode_changed_cb, zfsvfs);
487168404Spjd	(void) dsl_prop_unregister(ds, "aclinherit", acl_inherit_changed_cb,
488168404Spjd	    zfsvfs);
489185029Spjd	(void) dsl_prop_unregister(ds, "vscan", vscan_changed_cb, zfsvfs);
490168404Spjd	return (error);
491168404Spjd
492168404Spjd}
493168404Spjd
494209962Smmstatic void
495209962Smmuidacct(objset_t *os, boolean_t isgroup, uint64_t fuid,
496209962Smm    int64_t delta, dmu_tx_t *tx)
497209962Smm{
498209962Smm	uint64_t used = 0;
499209962Smm	char buf[32];
500209962Smm	int err;
501209962Smm	uint64_t obj = isgroup ? DMU_GROUPUSED_OBJECT : DMU_USERUSED_OBJECT;
502209962Smm
503209962Smm	if (delta == 0)
504209962Smm		return;
505209962Smm
506209962Smm	(void) snprintf(buf, sizeof (buf), "%llx", (longlong_t)fuid);
507209962Smm	err = zap_lookup(os, obj, buf, 8, 1, &used);
508209962Smm	ASSERT(err == 0 || err == ENOENT);
509209962Smm	/* no underflow/overflow */
510209962Smm	ASSERT(delta > 0 || used >= -delta);
511209962Smm	ASSERT(delta < 0 || used + delta > used);
512209962Smm	used += delta;
513209962Smm	if (used == 0)
514209962Smm		err = zap_remove(os, obj, buf, tx);
515209962Smm	else
516209962Smm		err = zap_update(os, obj, buf, 8, 1, &used, tx);
517209962Smm	ASSERT(err == 0);
518209962Smm}
519209962Smm
520209962Smmstatic void
521209962Smmzfs_space_delta_cb(objset_t *os, dmu_object_type_t bonustype,
522209962Smm    void *oldbonus, void *newbonus,
523209962Smm    uint64_t oldused, uint64_t newused, dmu_tx_t *tx)
524209962Smm{
525209962Smm	znode_phys_t *oldznp = oldbonus;
526209962Smm	znode_phys_t *newznp = newbonus;
527209962Smm
528209962Smm	if (bonustype != DMU_OT_ZNODE)
529209962Smm		return;
530209962Smm
531209962Smm	/* We charge 512 for the dnode (if it's allocated). */
532209962Smm	if (oldznp->zp_gen != 0)
533209962Smm		oldused += DNODE_SIZE;
534209962Smm	if (newznp->zp_gen != 0)
535209962Smm		newused += DNODE_SIZE;
536209962Smm
537209962Smm	if (oldznp->zp_uid == newznp->zp_uid) {
538209962Smm		uidacct(os, B_FALSE, oldznp->zp_uid, newused-oldused, tx);
539209962Smm	} else {
540209962Smm		uidacct(os, B_FALSE, oldznp->zp_uid, -oldused, tx);
541209962Smm		uidacct(os, B_FALSE, newznp->zp_uid, newused, tx);
542209962Smm	}
543209962Smm
544209962Smm	if (oldznp->zp_gid == newznp->zp_gid) {
545209962Smm		uidacct(os, B_TRUE, oldznp->zp_gid, newused-oldused, tx);
546209962Smm	} else {
547209962Smm		uidacct(os, B_TRUE, oldznp->zp_gid, -oldused, tx);
548209962Smm		uidacct(os, B_TRUE, newznp->zp_gid, newused, tx);
549209962Smm	}
550209962Smm}
551209962Smm
552209962Smmstatic void
553209962Smmfuidstr_to_sid(zfsvfs_t *zfsvfs, const char *fuidstr,
554209962Smm    char *domainbuf, int buflen, uid_t *ridp)
555209962Smm{
556209962Smm	uint64_t fuid;
557209962Smm	const char *domain;
558209962Smm
559209962Smm	fuid = strtonum(fuidstr, NULL);
560209962Smm
561209962Smm	domain = zfs_fuid_find_by_idx(zfsvfs, FUID_INDEX(fuid));
562209962Smm	if (domain)
563209962Smm		(void) strlcpy(domainbuf, domain, buflen);
564209962Smm	else
565209962Smm		domainbuf[0] = '\0';
566209962Smm	*ridp = FUID_RID(fuid);
567209962Smm}
568209962Smm
569209962Smmstatic uint64_t
570209962Smmzfs_userquota_prop_to_obj(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type)
571209962Smm{
572209962Smm	switch (type) {
573209962Smm	case ZFS_PROP_USERUSED:
574209962Smm		return (DMU_USERUSED_OBJECT);
575209962Smm	case ZFS_PROP_GROUPUSED:
576209962Smm		return (DMU_GROUPUSED_OBJECT);
577209962Smm	case ZFS_PROP_USERQUOTA:
578209962Smm		return (zfsvfs->z_userquota_obj);
579209962Smm	case ZFS_PROP_GROUPQUOTA:
580209962Smm		return (zfsvfs->z_groupquota_obj);
581209962Smm	}
582209962Smm	return (0);
583209962Smm}
584209962Smm
585209962Smmint
586209962Smmzfs_userspace_many(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type,
587209962Smm    uint64_t *cookiep, void *vbuf, uint64_t *bufsizep)
588209962Smm{
589209962Smm	int error;
590209962Smm	zap_cursor_t zc;
591209962Smm	zap_attribute_t za;
592209962Smm	zfs_useracct_t *buf = vbuf;
593209962Smm	uint64_t obj;
594209962Smm
595209962Smm	if (!dmu_objset_userspace_present(zfsvfs->z_os))
596209962Smm		return (ENOTSUP);
597209962Smm
598209962Smm	obj = zfs_userquota_prop_to_obj(zfsvfs, type);
599209962Smm	if (obj == 0) {
600209962Smm		*bufsizep = 0;
601209962Smm		return (0);
602209962Smm	}
603209962Smm
604209962Smm	for (zap_cursor_init_serialized(&zc, zfsvfs->z_os, obj, *cookiep);
605209962Smm	    (error = zap_cursor_retrieve(&zc, &za)) == 0;
606209962Smm	    zap_cursor_advance(&zc)) {
607209962Smm		if ((uintptr_t)buf - (uintptr_t)vbuf + sizeof (zfs_useracct_t) >
608209962Smm		    *bufsizep)
609209962Smm			break;
610209962Smm
611209962Smm		fuidstr_to_sid(zfsvfs, za.za_name,
612209962Smm		    buf->zu_domain, sizeof (buf->zu_domain), &buf->zu_rid);
613209962Smm
614209962Smm		buf->zu_space = za.za_first_integer;
615209962Smm		buf++;
616209962Smm	}
617209962Smm	if (error == ENOENT)
618209962Smm		error = 0;
619209962Smm
620209962Smm	ASSERT3U((uintptr_t)buf - (uintptr_t)vbuf, <=, *bufsizep);
621209962Smm	*bufsizep = (uintptr_t)buf - (uintptr_t)vbuf;
622209962Smm	*cookiep = zap_cursor_serialize(&zc);
623209962Smm	zap_cursor_fini(&zc);
624209962Smm	return (error);
625209962Smm}
626209962Smm
627209962Smm/*
628209962Smm * buf must be big enough (eg, 32 bytes)
629209962Smm */
630168404Spjdstatic int
631209962Smmid_to_fuidstr(zfsvfs_t *zfsvfs, const char *domain, uid_t rid,
632209962Smm    char *buf, boolean_t addok)
633209962Smm{
634209962Smm	uint64_t fuid;
635209962Smm	int domainid = 0;
636209962Smm
637209962Smm	if (domain && domain[0]) {
638209962Smm		domainid = zfs_fuid_find_by_domain(zfsvfs, domain, NULL, addok);
639209962Smm		if (domainid == -1)
640209962Smm			return (ENOENT);
641209962Smm	}
642209962Smm	fuid = FUID_ENCODE(domainid, rid);
643209962Smm	(void) sprintf(buf, "%llx", (longlong_t)fuid);
644209962Smm	return (0);
645209962Smm}
646209962Smm
647209962Smmint
648209962Smmzfs_userspace_one(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type,
649209962Smm    const char *domain, uint64_t rid, uint64_t *valp)
650209962Smm{
651209962Smm	char buf[32];
652209962Smm	int err;
653209962Smm	uint64_t obj;
654209962Smm
655209962Smm	*valp = 0;
656209962Smm
657209962Smm	if (!dmu_objset_userspace_present(zfsvfs->z_os))
658209962Smm		return (ENOTSUP);
659209962Smm
660209962Smm	obj = zfs_userquota_prop_to_obj(zfsvfs, type);
661209962Smm	if (obj == 0)
662209962Smm		return (0);
663209962Smm
664209962Smm	err = id_to_fuidstr(zfsvfs, domain, rid, buf, B_FALSE);
665209962Smm	if (err)
666209962Smm		return (err);
667209962Smm
668209962Smm	err = zap_lookup(zfsvfs->z_os, obj, buf, 8, 1, valp);
669209962Smm	if (err == ENOENT)
670209962Smm		err = 0;
671209962Smm	return (err);
672209962Smm}
673209962Smm
674209962Smmint
675209962Smmzfs_set_userquota(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type,
676209962Smm    const char *domain, uint64_t rid, uint64_t quota)
677209962Smm{
678209962Smm	char buf[32];
679209962Smm	int err;
680209962Smm	dmu_tx_t *tx;
681209962Smm	uint64_t *objp;
682209962Smm	boolean_t fuid_dirtied;
683209962Smm
684209962Smm	if (type != ZFS_PROP_USERQUOTA && type != ZFS_PROP_GROUPQUOTA)
685209962Smm		return (EINVAL);
686209962Smm
687209962Smm	if (zfsvfs->z_version < ZPL_VERSION_USERSPACE)
688209962Smm		return (ENOTSUP);
689209962Smm
690209962Smm	objp = (type == ZFS_PROP_USERQUOTA) ? &zfsvfs->z_userquota_obj :
691209962Smm	    &zfsvfs->z_groupquota_obj;
692209962Smm
693209962Smm	err = id_to_fuidstr(zfsvfs, domain, rid, buf, B_TRUE);
694209962Smm	if (err)
695209962Smm		return (err);
696209962Smm	fuid_dirtied = zfsvfs->z_fuid_dirty;
697209962Smm
698209962Smm	tx = dmu_tx_create(zfsvfs->z_os);
699209962Smm	dmu_tx_hold_zap(tx, *objp ? *objp : DMU_NEW_OBJECT, B_TRUE, NULL);
700209962Smm	if (*objp == 0) {
701209962Smm		dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, B_TRUE,
702209962Smm		    zfs_userquota_prop_prefixes[type]);
703209962Smm	}
704209962Smm	if (fuid_dirtied)
705209962Smm		zfs_fuid_txhold(zfsvfs, tx);
706209962Smm	err = dmu_tx_assign(tx, TXG_WAIT);
707209962Smm	if (err) {
708209962Smm		dmu_tx_abort(tx);
709209962Smm		return (err);
710209962Smm	}
711209962Smm
712209962Smm	mutex_enter(&zfsvfs->z_lock);
713209962Smm	if (*objp == 0) {
714209962Smm		*objp = zap_create(zfsvfs->z_os, DMU_OT_USERGROUP_QUOTA,
715209962Smm		    DMU_OT_NONE, 0, tx);
716209962Smm		VERIFY(0 == zap_add(zfsvfs->z_os, MASTER_NODE_OBJ,
717209962Smm		    zfs_userquota_prop_prefixes[type], 8, 1, objp, tx));
718209962Smm	}
719209962Smm	mutex_exit(&zfsvfs->z_lock);
720209962Smm
721209962Smm	if (quota == 0) {
722209962Smm		err = zap_remove(zfsvfs->z_os, *objp, buf, tx);
723209962Smm		if (err == ENOENT)
724209962Smm			err = 0;
725209962Smm	} else {
726209962Smm		err = zap_update(zfsvfs->z_os, *objp, buf, 8, 1, &quota, tx);
727209962Smm	}
728209962Smm	ASSERT(err == 0);
729209962Smm	if (fuid_dirtied)
730209962Smm		zfs_fuid_sync(zfsvfs, tx);
731209962Smm	dmu_tx_commit(tx);
732209962Smm	return (err);
733209962Smm}
734209962Smm
735209962Smmboolean_t
736209962Smmzfs_usergroup_overquota(zfsvfs_t *zfsvfs, boolean_t isgroup, uint64_t fuid)
737209962Smm{
738209962Smm	char buf[32];
739209962Smm	uint64_t used, quota, usedobj, quotaobj;
740209962Smm	int err;
741209962Smm
742209962Smm	usedobj = isgroup ? DMU_GROUPUSED_OBJECT : DMU_USERUSED_OBJECT;
743209962Smm	quotaobj = isgroup ? zfsvfs->z_groupquota_obj : zfsvfs->z_userquota_obj;
744209962Smm
745209962Smm	if (quotaobj == 0 || zfsvfs->z_replay)
746209962Smm		return (B_FALSE);
747209962Smm
748209962Smm	(void) sprintf(buf, "%llx", (longlong_t)fuid);
749209962Smm	err = zap_lookup(zfsvfs->z_os, quotaobj, buf, 8, 1, &quota);
750209962Smm	if (err != 0)
751209962Smm		return (B_FALSE);
752209962Smm
753209962Smm	err = zap_lookup(zfsvfs->z_os, usedobj, buf, 8, 1, &used);
754209962Smm	if (err != 0)
755209962Smm		return (B_FALSE);
756209962Smm	return (used >= quota);
757209962Smm}
758209962Smm
759209962Smmint
760209962Smmzfsvfs_create(const char *osname, int mode, zfsvfs_t **zvp)
761209962Smm{
762209962Smm	objset_t *os;
763209962Smm	zfsvfs_t *zfsvfs;
764209962Smm	uint64_t zval;
765209962Smm	int i, error;
766209962Smm
767209962Smm	if (error = dsl_prop_get_integer(osname, "readonly", &zval, NULL))
768209962Smm		return (error);
769209962Smm	if (zval)
770209962Smm		mode |= DS_MODE_READONLY;
771209962Smm
772209962Smm	error = dmu_objset_open(osname, DMU_OST_ZFS, mode, &os);
773209962Smm	if (error == EROFS) {
774209962Smm		mode |= DS_MODE_READONLY;
775209962Smm		error = dmu_objset_open(osname, DMU_OST_ZFS, mode, &os);
776209962Smm	}
777209962Smm	if (error)
778209962Smm		return (error);
779209962Smm
780209962Smm	/*
781209962Smm	 * Initialize the zfs-specific filesystem structure.
782209962Smm	 * Should probably make this a kmem cache, shuffle fields,
783209962Smm	 * and just bzero up to z_hold_mtx[].
784209962Smm	 */
785209962Smm	zfsvfs = kmem_zalloc(sizeof (zfsvfs_t), KM_SLEEP);
786209962Smm	zfsvfs->z_vfs = NULL;
787209962Smm	zfsvfs->z_parent = zfsvfs;
788209962Smm	zfsvfs->z_max_blksz = SPA_MAXBLOCKSIZE;
789209962Smm	zfsvfs->z_show_ctldir = ZFS_SNAPDIR_VISIBLE;
790209962Smm	zfsvfs->z_os = os;
791209962Smm
792209962Smm	error = zfs_get_zplprop(os, ZFS_PROP_VERSION, &zfsvfs->z_version);
793209962Smm	if (error) {
794209962Smm		goto out;
795209962Smm	} else if (zfsvfs->z_version > ZPL_VERSION) {
796209962Smm		(void) printf("Mismatched versions:  File system "
797209962Smm		    "is version %llu on-disk format, which is "
798209962Smm		    "incompatible with this software version %lld!",
799209962Smm		    (u_longlong_t)zfsvfs->z_version, ZPL_VERSION);
800209962Smm		error = ENOTSUP;
801209962Smm		goto out;
802209962Smm	}
803209962Smm
804209962Smm	if ((error = zfs_get_zplprop(os, ZFS_PROP_NORMALIZE, &zval)) != 0)
805209962Smm		goto out;
806209962Smm	zfsvfs->z_norm = (int)zval;
807209962Smm
808209962Smm	if ((error = zfs_get_zplprop(os, ZFS_PROP_UTF8ONLY, &zval)) != 0)
809209962Smm		goto out;
810209962Smm	zfsvfs->z_utf8 = (zval != 0);
811209962Smm
812209962Smm	if ((error = zfs_get_zplprop(os, ZFS_PROP_CASE, &zval)) != 0)
813209962Smm		goto out;
814209962Smm	zfsvfs->z_case = (uint_t)zval;
815209962Smm
816209962Smm	/*
817209962Smm	 * Fold case on file systems that are always or sometimes case
818209962Smm	 * insensitive.
819209962Smm	 */
820209962Smm	if (zfsvfs->z_case == ZFS_CASE_INSENSITIVE ||
821209962Smm	    zfsvfs->z_case == ZFS_CASE_MIXED)
822209962Smm		zfsvfs->z_norm |= U8_TEXTPREP_TOUPPER;
823209962Smm
824209962Smm	zfsvfs->z_use_fuids = USE_FUIDS(zfsvfs->z_version, zfsvfs->z_os);
825209962Smm
826209962Smm	error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_ROOT_OBJ, 8, 1,
827209962Smm	    &zfsvfs->z_root);
828209962Smm	if (error)
829209962Smm		goto out;
830209962Smm	ASSERT(zfsvfs->z_root != 0);
831209962Smm
832209962Smm	error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_UNLINKED_SET, 8, 1,
833209962Smm	    &zfsvfs->z_unlinkedobj);
834209962Smm	if (error)
835209962Smm		goto out;
836209962Smm
837209962Smm	error = zap_lookup(os, MASTER_NODE_OBJ,
838209962Smm	    zfs_userquota_prop_prefixes[ZFS_PROP_USERQUOTA],
839209962Smm	    8, 1, &zfsvfs->z_userquota_obj);
840209962Smm	if (error && error != ENOENT)
841209962Smm		goto out;
842209962Smm
843209962Smm	error = zap_lookup(os, MASTER_NODE_OBJ,
844209962Smm	    zfs_userquota_prop_prefixes[ZFS_PROP_GROUPQUOTA],
845209962Smm	    8, 1, &zfsvfs->z_groupquota_obj);
846209962Smm	if (error && error != ENOENT)
847209962Smm		goto out;
848209962Smm
849209962Smm	error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_FUID_TABLES, 8, 1,
850209962Smm	    &zfsvfs->z_fuid_obj);
851209962Smm	if (error && error != ENOENT)
852209962Smm		goto out;
853209962Smm
854209962Smm	error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_SHARES_DIR, 8, 1,
855209962Smm	    &zfsvfs->z_shares_dir);
856209962Smm	if (error && error != ENOENT)
857209962Smm		goto out;
858209962Smm
859209962Smm	mutex_init(&zfsvfs->z_znodes_lock, NULL, MUTEX_DEFAULT, NULL);
860209962Smm	mutex_init(&zfsvfs->z_online_recv_lock, NULL, MUTEX_DEFAULT, NULL);
861209962Smm	mutex_init(&zfsvfs->z_lock, NULL, MUTEX_DEFAULT, NULL);
862209962Smm	list_create(&zfsvfs->z_all_znodes, sizeof (znode_t),
863209962Smm	    offsetof(znode_t, z_link_node));
864209962Smm	rrw_init(&zfsvfs->z_teardown_lock);
865209962Smm	rw_init(&zfsvfs->z_teardown_inactive_lock, NULL, RW_DEFAULT, NULL);
866209962Smm	rw_init(&zfsvfs->z_fuid_lock, NULL, RW_DEFAULT, NULL);
867209962Smm	for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
868209962Smm		mutex_init(&zfsvfs->z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL);
869209962Smm
870209962Smm	*zvp = zfsvfs;
871209962Smm	return (0);
872209962Smm
873209962Smmout:
874209962Smm	dmu_objset_close(os);
875209962Smm	*zvp = NULL;
876209962Smm	kmem_free(zfsvfs, sizeof (zfsvfs_t));
877209962Smm	return (error);
878209962Smm}
879209962Smm
880209962Smmstatic int
881185029Spjdzfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t mounting)
882168404Spjd{
883185029Spjd	int error;
884185029Spjd
885185029Spjd	error = zfs_register_callbacks(zfsvfs->z_vfs);
886185029Spjd	if (error)
887185029Spjd		return (error);
888185029Spjd
889185029Spjd	/*
890185029Spjd	 * Set the objset user_ptr to track its zfsvfs.
891185029Spjd	 */
892185029Spjd	mutex_enter(&zfsvfs->z_os->os->os_user_ptr_lock);
893185029Spjd	dmu_objset_set_user(zfsvfs->z_os, zfsvfs);
894185029Spjd	mutex_exit(&zfsvfs->z_os->os->os_user_ptr_lock);
895185029Spjd
896208689Smm	zfsvfs->z_log = zil_open(zfsvfs->z_os, zfs_get_data);
897208689Smm	if (zil_disable) {
898208689Smm		zil_destroy(zfsvfs->z_log, B_FALSE);
899208689Smm		zfsvfs->z_log = NULL;
900208689Smm	}
901208689Smm
902185029Spjd	/*
903185029Spjd	 * If we are not mounting (ie: online recv), then we don't
904185029Spjd	 * have to worry about replaying the log as we blocked all
905185029Spjd	 * operations out since we closed the ZIL.
906185029Spjd	 */
907185029Spjd	if (mounting) {
908185029Spjd		boolean_t readonly;
909185029Spjd
910185029Spjd		/*
911185029Spjd		 * During replay we remove the read only flag to
912185029Spjd		 * allow replays to succeed.
913185029Spjd		 */
914185029Spjd		readonly = zfsvfs->z_vfs->vfs_flag & VFS_RDONLY;
915208689Smm		if (readonly != 0)
916208689Smm			zfsvfs->z_vfs->vfs_flag &= ~VFS_RDONLY;
917208689Smm		else
918208689Smm			zfs_unlinked_drain(zfsvfs);
919185029Spjd
920208689Smm		if (zfsvfs->z_log) {
921208689Smm			/*
922208689Smm			 * Parse and replay the intent log.
923208689Smm			 *
924208689Smm			 * Because of ziltest, this must be done after
925208689Smm			 * zfs_unlinked_drain().  (Further note: ziltest
926208689Smm			 * doesn't use readonly mounts, where
927208689Smm			 * zfs_unlinked_drain() isn't called.)  This is because
928208689Smm			 * ziltest causes spa_sync() to think it's committed,
929208689Smm			 * but actually it is not, so the intent log contains
930208689Smm			 * many txg's worth of changes.
931208689Smm			 *
932208689Smm			 * In particular, if object N is in the unlinked set in
933208689Smm			 * the last txg to actually sync, then it could be
934208689Smm			 * actually freed in a later txg and then reallocated
935208689Smm			 * in a yet later txg.  This would write a "create
936208689Smm			 * object N" record to the intent log.  Normally, this
937208689Smm			 * would be fine because the spa_sync() would have
938208689Smm			 * written out the fact that object N is free, before
939208689Smm			 * we could write the "create object N" intent log
940208689Smm			 * record.
941208689Smm			 *
942208689Smm			 * But when we are in ziltest mode, we advance the "open
943208689Smm			 * txg" without actually spa_sync()-ing the changes to
944208689Smm			 * disk.  So we would see that object N is still
945208689Smm			 * allocated and in the unlinked set, and there is an
946208689Smm			 * intent log record saying to allocate it.
947208689Smm			 */
948209962Smm			zfsvfs->z_replay = B_TRUE;
949209962Smm			zil_replay(zfsvfs->z_os, zfsvfs, zfs_replay_vector);
950209962Smm			zfsvfs->z_replay = B_FALSE;
951208689Smm		}
952185029Spjd		zfsvfs->z_vfs->vfs_flag |= readonly; /* restore readonly bit */
953185029Spjd	}
954185029Spjd
955185029Spjd	return (0);
956185029Spjd}
957185029Spjd
958210470Smmextern krwlock_t zfsvfs_lock; /* in zfs_znode.c */
959210470Smm
960209962Smmvoid
961209962Smmzfsvfs_free(zfsvfs_t *zfsvfs)
962185029Spjd{
963209962Smm	int i;
964209962Smm
965210470Smm	/*
966210470Smm	 * This is a barrier to prevent the filesystem from going away in
967210470Smm	 * zfs_znode_move() until we can safely ensure that the filesystem is
968210470Smm	 * not unmounted. We consider the filesystem valid before the barrier
969210470Smm	 * and invalid after the barrier.
970210470Smm	 */
971210470Smm	rw_enter(&zfsvfs_lock, RW_READER);
972210470Smm	rw_exit(&zfsvfs_lock);
973210470Smm
974209962Smm	zfs_fuid_destroy(zfsvfs);
975209962Smm
976185029Spjd	mutex_destroy(&zfsvfs->z_znodes_lock);
977185029Spjd	mutex_destroy(&zfsvfs->z_online_recv_lock);
978209962Smm	mutex_destroy(&zfsvfs->z_lock);
979185029Spjd	list_destroy(&zfsvfs->z_all_znodes);
980185029Spjd	rrw_destroy(&zfsvfs->z_teardown_lock);
981185029Spjd	rw_destroy(&zfsvfs->z_teardown_inactive_lock);
982185029Spjd	rw_destroy(&zfsvfs->z_fuid_lock);
983209962Smm	for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
984209962Smm		mutex_destroy(&zfsvfs->z_hold_mtx[i]);
985185029Spjd	kmem_free(zfsvfs, sizeof (zfsvfs_t));
986185029Spjd}
987185029Spjd
988209962Smmstatic void
989209962Smmzfs_set_fuid_feature(zfsvfs_t *zfsvfs)
990209962Smm{
991209962Smm	zfsvfs->z_use_fuids = USE_FUIDS(zfsvfs->z_version, zfsvfs->z_os);
992209962Smm	if (zfsvfs->z_use_fuids && zfsvfs->z_vfs) {
993209962Smm		vfs_set_feature(zfsvfs->z_vfs, VFSFT_XVATTR);
994209962Smm		vfs_set_feature(zfsvfs->z_vfs, VFSFT_SYSATTR_VIEWS);
995209962Smm		vfs_set_feature(zfsvfs->z_vfs, VFSFT_ACEMASKONACCESS);
996209962Smm		vfs_set_feature(zfsvfs->z_vfs, VFSFT_ACLONCREATE);
997211932Smm		vfs_set_feature(zfsvfs->z_vfs, VFSFT_ACCESS_FILTER);
998209962Smm	}
999209962Smm}
1000209962Smm
1001185029Spjdstatic int
1002185029Spjdzfs_domount(vfs_t *vfsp, char *osname)
1003185029Spjd{
1004209962Smm	uint64_t recordsize, fsid_guid;
1005168404Spjd	int error = 0;
1006168404Spjd	zfsvfs_t *zfsvfs;
1007209962Smm	vnode_t *vp;
1008168404Spjd
1009168404Spjd	ASSERT(vfsp);
1010168404Spjd	ASSERT(osname);
1011168404Spjd
1012209962Smm	error = zfsvfs_create(osname, DS_MODE_OWNER, &zfsvfs);
1013209962Smm	if (error)
1014209962Smm		return (error);
1015168404Spjd	zfsvfs->z_vfs = vfsp;
1016168404Spjd
1017168404Spjd	if (error = dsl_prop_get_integer(osname, "recordsize", &recordsize,
1018168404Spjd	    NULL))
1019168404Spjd		goto out;
1020204101Spjd	zfsvfs->z_vfs->vfs_bsize = SPA_MINBLOCKSIZE;
1021204101Spjd	zfsvfs->z_vfs->mnt_stat.f_iosize = recordsize;
1022168404Spjd
1023168404Spjd	vfsp->vfs_data = zfsvfs;
1024168404Spjd	vfsp->mnt_flag |= MNT_LOCAL;
1025168404Spjd	vfsp->mnt_kern_flag |= MNTK_MPSAFE;
1026168404Spjd	vfsp->mnt_kern_flag |= MNTK_LOOKUP_SHARED;
1027193440Sps	vfsp->mnt_kern_flag |= MNTK_SHARED_WRITES;
1028168404Spjd
1029168404Spjd
1030209962Smm	/*
1031209962Smm	 * The fsid is 64 bits, composed of an 8-bit fs type, which
1032209962Smm	 * separates our fsid from any other filesystem types, and a
1033209962Smm	 * 56-bit objset unique ID.  The objset unique ID is unique to
1034209962Smm	 * all objsets open on this system, provided by unique_create().
1035209962Smm	 * The 8-bit fs type must be put in the low bits of fsid[1]
1036209962Smm	 * because that's where other Solaris filesystems put it.
1037209962Smm	 */
1038209962Smm	fsid_guid = dmu_objset_fsid_guid(zfsvfs->z_os);
1039209962Smm	ASSERT((fsid_guid & ~((1ULL<<56)-1)) == 0);
1040209962Smm	vfsp->vfs_fsid.val[0] = fsid_guid;
1041209962Smm	vfsp->vfs_fsid.val[1] = ((fsid_guid>>32) << 8) |
1042209962Smm	    vfsp->mnt_vfc->vfc_typenum & 0xFF;
1043168404Spjd
1044185029Spjd	/*
1045185029Spjd	 * Set features for file system.
1046185029Spjd	 */
1047209962Smm	zfs_set_fuid_feature(zfsvfs);
1048185029Spjd	if (zfsvfs->z_case == ZFS_CASE_INSENSITIVE) {
1049185029Spjd		vfs_set_feature(vfsp, VFSFT_DIRENTFLAGS);
1050185029Spjd		vfs_set_feature(vfsp, VFSFT_CASEINSENSITIVE);
1051185029Spjd		vfs_set_feature(vfsp, VFSFT_NOCASESENSITIVE);
1052185029Spjd	} else if (zfsvfs->z_case == ZFS_CASE_MIXED) {
1053185029Spjd		vfs_set_feature(vfsp, VFSFT_DIRENTFLAGS);
1054185029Spjd		vfs_set_feature(vfsp, VFSFT_CASEINSENSITIVE);
1055185029Spjd	}
1056185029Spjd
1057168404Spjd	if (dmu_objset_is_snapshot(zfsvfs->z_os)) {
1058185029Spjd		uint64_t pval;
1059168404Spjd
1060168404Spjd		atime_changed_cb(zfsvfs, B_FALSE);
1061168404Spjd		readonly_changed_cb(zfsvfs, B_TRUE);
1062185029Spjd		if (error = dsl_prop_get_integer(osname, "xattr", &pval, NULL))
1063168404Spjd			goto out;
1064185029Spjd		xattr_changed_cb(zfsvfs, pval);
1065168404Spjd		zfsvfs->z_issnap = B_TRUE;
1066209962Smm
1067209962Smm		mutex_enter(&zfsvfs->z_os->os->os_user_ptr_lock);
1068209962Smm		dmu_objset_set_user(zfsvfs->z_os, zfsvfs);
1069209962Smm		mutex_exit(&zfsvfs->z_os->os->os_user_ptr_lock);
1070168404Spjd	} else {
1071185029Spjd		error = zfsvfs_setup(zfsvfs, B_TRUE);
1072168404Spjd	}
1073168404Spjd
1074168404Spjd	vfs_mountedfrom(vfsp, osname);
1075209962Smm	/* Grab extra reference. */
1076209962Smm	VERIFY(VFS_ROOT(vfsp, LK_EXCLUSIVE, &vp) == 0);
1077209962Smm	VOP_UNLOCK(vp, 0);
1078168404Spjd
1079168404Spjd	if (!zfsvfs->z_issnap)
1080168404Spjd		zfsctl_create(zfsvfs);
1081168404Spjdout:
1082168404Spjd	if (error) {
1083209962Smm		dmu_objset_close(zfsvfs->z_os);
1084209962Smm		zfsvfs_free(zfsvfs);
1085168404Spjd	} else {
1086168404Spjd		atomic_add_32(&zfs_active_fs_count, 1);
1087168404Spjd	}
1088168404Spjd
1089168404Spjd	return (error);
1090168404Spjd}
1091168404Spjd
1092168404Spjdvoid
1093168404Spjdzfs_unregister_callbacks(zfsvfs_t *zfsvfs)
1094168404Spjd{
1095168404Spjd	objset_t *os = zfsvfs->z_os;
1096168404Spjd	struct dsl_dataset *ds;
1097168404Spjd
1098168404Spjd	/*
1099168404Spjd	 * Unregister properties.
1100168404Spjd	 */
1101168404Spjd	if (!dmu_objset_is_snapshot(os)) {
1102168404Spjd		ds = dmu_objset_ds(os);
1103168404Spjd		VERIFY(dsl_prop_unregister(ds, "atime", atime_changed_cb,
1104168404Spjd		    zfsvfs) == 0);
1105168404Spjd
1106168404Spjd		VERIFY(dsl_prop_unregister(ds, "xattr", xattr_changed_cb,
1107168404Spjd		    zfsvfs) == 0);
1108168404Spjd
1109168404Spjd		VERIFY(dsl_prop_unregister(ds, "recordsize", blksz_changed_cb,
1110168404Spjd		    zfsvfs) == 0);
1111168404Spjd
1112168404Spjd		VERIFY(dsl_prop_unregister(ds, "readonly", readonly_changed_cb,
1113168404Spjd		    zfsvfs) == 0);
1114168404Spjd
1115168404Spjd		VERIFY(dsl_prop_unregister(ds, "setuid", setuid_changed_cb,
1116168404Spjd		    zfsvfs) == 0);
1117168404Spjd
1118168404Spjd		VERIFY(dsl_prop_unregister(ds, "exec", exec_changed_cb,
1119168404Spjd		    zfsvfs) == 0);
1120168404Spjd
1121168404Spjd		VERIFY(dsl_prop_unregister(ds, "snapdir", snapdir_changed_cb,
1122168404Spjd		    zfsvfs) == 0);
1123168404Spjd
1124168404Spjd		VERIFY(dsl_prop_unregister(ds, "aclmode", acl_mode_changed_cb,
1125168404Spjd		    zfsvfs) == 0);
1126168404Spjd
1127168404Spjd		VERIFY(dsl_prop_unregister(ds, "aclinherit",
1128168404Spjd		    acl_inherit_changed_cb, zfsvfs) == 0);
1129185029Spjd
1130185029Spjd		VERIFY(dsl_prop_unregister(ds, "vscan",
1131185029Spjd		    vscan_changed_cb, zfsvfs) == 0);
1132168404Spjd	}
1133168404Spjd}
1134168404Spjd
1135168404Spjd/*ARGSUSED*/
1136168404Spjdstatic int
1137191990Sattiliozfs_mount(vfs_t *vfsp)
1138168404Spjd{
1139191990Sattilio	kthread_t	*td = curthread;
1140185029Spjd	vnode_t		*mvp = vfsp->mnt_vnodecovered;
1141185029Spjd	cred_t		*cr = td->td_ucred;
1142185029Spjd	char		*osname;
1143185029Spjd	int		error = 0;
1144185029Spjd	int		canwrite;
1145168404Spjd
1146185029Spjd	if (vfs_getopt(vfsp->mnt_optnew, "from", (void **)&osname, NULL))
1147185029Spjd		return (EINVAL);
1148185029Spjd
1149168404Spjd	/*
1150185029Spjd	 * If full-owner-access is enabled and delegated administration is
1151185029Spjd	 * turned on, we must set nosuid.
1152185029Spjd	 */
1153185029Spjd	if (zfs_super_owner &&
1154185029Spjd	    dsl_deleg_access(osname, ZFS_DELEG_PERM_MOUNT, cr) != ECANCELED) {
1155185029Spjd		secpolicy_fs_mount_clearopts(cr, vfsp);
1156185029Spjd	}
1157185029Spjd
1158185029Spjd	/*
1159185029Spjd	 * Check for mount privilege?
1160185029Spjd	 *
1161185029Spjd	 * If we don't have privilege then see if
1162185029Spjd	 * we have local permission to allow it
1163185029Spjd	 */
1164185029Spjd	error = secpolicy_fs_mount(cr, mvp, vfsp);
1165185029Spjd	if (error) {
1166212694Smm		if (dsl_deleg_access(osname, ZFS_DELEG_PERM_MOUNT, cr) != 0)
1167196944Spjd			goto out;
1168196944Spjd
1169196944Spjd		if (!(vfsp->vfs_flag & MS_REMOUNT)) {
1170185029Spjd			vattr_t		vattr;
1171185029Spjd
1172185029Spjd			/*
1173185029Spjd			 * Make sure user is the owner of the mount point
1174185029Spjd			 * or has sufficient privileges.
1175185029Spjd			 */
1176185029Spjd
1177185029Spjd			vattr.va_mask = AT_UID;
1178185029Spjd
1179196662Spjd			vn_lock(mvp, LK_SHARED | LK_RETRY);
1180212694Smm			if (VOP_GETATTR(mvp, &vattr, cr)) {
1181196662Spjd				VOP_UNLOCK(mvp, 0);
1182185029Spjd				goto out;
1183185029Spjd			}
1184185029Spjd
1185185029Spjd			if (secpolicy_vnode_owner(mvp, cr, vattr.va_uid) != 0 &&
1186185029Spjd			    VOP_ACCESS(mvp, VWRITE, cr, td) != 0) {
1187196662Spjd				VOP_UNLOCK(mvp, 0);
1188185029Spjd				goto out;
1189185029Spjd			}
1190196662Spjd			VOP_UNLOCK(mvp, 0);
1191196944Spjd		}
1192185029Spjd
1193196944Spjd		secpolicy_fs_mount_clearopts(cr, vfsp);
1194185029Spjd	}
1195185029Spjd
1196185029Spjd	/*
1197185029Spjd	 * Refuse to mount a filesystem if we are in a local zone and the
1198185029Spjd	 * dataset is not visible.
1199185029Spjd	 */
1200185029Spjd	if (!INGLOBALZONE(curthread) &&
1201185029Spjd	    (!zone_dataset_visible(osname, &canwrite) || !canwrite)) {
1202185029Spjd		error = EPERM;
1203185029Spjd		goto out;
1204185029Spjd	}
1205185029Spjd
1206185029Spjd	/*
1207168404Spjd	 * When doing a remount, we simply refresh our temporary properties
1208168404Spjd	 * according to those options set in the current VFS options.
1209168404Spjd	 */
1210185029Spjd	if (vfsp->vfs_flag & MS_REMOUNT) {
1211185029Spjd		/* refresh mount options */
1212185029Spjd		zfs_unregister_callbacks(vfsp->vfs_data);
1213185029Spjd		error = zfs_register_callbacks(vfsp);
1214185029Spjd		goto out;
1215185029Spjd	}
1216168404Spjd
1217168510Spjd	DROP_GIANT();
1218185029Spjd	error = zfs_domount(vfsp, osname);
1219168510Spjd	PICKUP_GIANT();
1220209962Smm
1221215260Smm#ifdef sun
1222209962Smm	/*
1223209962Smm	 * Add an extra VFS_HOLD on our parent vfs so that it can't
1224209962Smm	 * disappear due to a forced unmount.
1225209962Smm	 */
1226209962Smm	if (error == 0 && ((zfsvfs_t *)vfsp->vfs_data)->z_issnap)
1227209962Smm		VFS_HOLD(mvp->v_vfsp);
1228215260Smm#endif	/* sun */
1229209962Smm
1230185029Spjdout:
1231168510Spjd	return (error);
1232168404Spjd}
1233168404Spjd
1234168404Spjdstatic int
1235191990Sattiliozfs_statfs(vfs_t *vfsp, struct statfs *statp)
1236169170Spjd{
1237168404Spjd	zfsvfs_t *zfsvfs = vfsp->vfs_data;
1238168404Spjd	uint64_t refdbytes, availbytes, usedobjs, availobjs;
1239168404Spjd
1240168404Spjd	statp->f_version = STATFS_VERSION;
1241168404Spjd
1242168404Spjd	ZFS_ENTER(zfsvfs);
1243168404Spjd
1244168404Spjd	dmu_objset_space(zfsvfs->z_os,
1245168404Spjd	    &refdbytes, &availbytes, &usedobjs, &availobjs);
1246168404Spjd
1247168404Spjd	/*
1248168404Spjd	 * The underlying storage pool actually uses multiple block sizes.
1249168404Spjd	 * We report the fragsize as the smallest block size we support,
1250168404Spjd	 * and we report our blocksize as the filesystem's maximum blocksize.
1251168404Spjd	 */
1252204101Spjd	statp->f_bsize = SPA_MINBLOCKSIZE;
1253204101Spjd	statp->f_iosize = zfsvfs->z_vfs->mnt_stat.f_iosize;
1254168404Spjd
1255168404Spjd	/*
1256168404Spjd	 * The following report "total" blocks of various kinds in the
1257168404Spjd	 * file system, but reported in terms of f_frsize - the
1258168404Spjd	 * "fragment" size.
1259168404Spjd	 */
1260168404Spjd
1261204101Spjd	statp->f_blocks = (refdbytes + availbytes) >> SPA_MINBLOCKSHIFT;
1262168404Spjd	statp->f_bfree = availbytes / statp->f_bsize;
1263168404Spjd	statp->f_bavail = statp->f_bfree; /* no root reservation */
1264168404Spjd
1265168404Spjd	/*
1266168404Spjd	 * statvfs() should really be called statufs(), because it assumes
1267168404Spjd	 * static metadata.  ZFS doesn't preallocate files, so the best
1268168404Spjd	 * we can do is report the max that could possibly fit in f_files,
1269168404Spjd	 * and that minus the number actually used in f_ffree.
1270168404Spjd	 * For f_ffree, report the smaller of the number of object available
1271168404Spjd	 * and the number of blocks (each object will take at least a block).
1272168404Spjd	 */
1273168404Spjd	statp->f_ffree = MIN(availobjs, statp->f_bfree);
1274168404Spjd	statp->f_files = statp->f_ffree + usedobjs;
1275168404Spjd
1276168404Spjd	/*
1277168404Spjd	 * We're a zfs filesystem.
1278168404Spjd	 */
1279168404Spjd	(void) strlcpy(statp->f_fstypename, "zfs", sizeof(statp->f_fstypename));
1280168404Spjd
1281168404Spjd	strlcpy(statp->f_mntfromname, vfsp->mnt_stat.f_mntfromname,
1282168404Spjd	    sizeof(statp->f_mntfromname));
1283168404Spjd	strlcpy(statp->f_mntonname, vfsp->mnt_stat.f_mntonname,
1284168404Spjd	    sizeof(statp->f_mntonname));
1285168404Spjd
1286168404Spjd	statp->f_namemax = ZFS_MAXNAMELEN;
1287168404Spjd
1288168404Spjd	ZFS_EXIT(zfsvfs);
1289168404Spjd	return (0);
1290168404Spjd}
1291168404Spjd
1292168404Spjdstatic int
1293191990Sattiliozfs_root(vfs_t *vfsp, int flags, vnode_t **vpp)
1294168404Spjd{
1295168404Spjd	zfsvfs_t *zfsvfs = vfsp->vfs_data;
1296168404Spjd	znode_t *rootzp;
1297168404Spjd	int error;
1298168404Spjd
1299197459Spjd	ZFS_ENTER_NOERROR(zfsvfs);
1300168404Spjd
1301168404Spjd	error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp);
1302206667Spjd
1303206667Spjd	ZFS_EXIT(zfsvfs);
1304206667Spjd
1305168404Spjd	if (error == 0) {
1306168404Spjd		*vpp = ZTOV(rootzp);
1307175202Sattilio		error = vn_lock(*vpp, flags);
1308168404Spjd		(*vpp)->v_vflag |= VV_ROOT;
1309168404Spjd	}
1310168404Spjd
1311168404Spjd	return (error);
1312168404Spjd}
1313168404Spjd
1314185029Spjd/*
1315185029Spjd * Teardown the zfsvfs::z_os.
1316185029Spjd *
1317185029Spjd * Note, if 'unmounting' if FALSE, we return with the 'z_teardown_lock'
1318185029Spjd * and 'z_teardown_inactive_lock' held.
1319185029Spjd */
1320185029Spjdstatic int
1321185029Spjdzfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
1322185029Spjd{
1323185029Spjd	znode_t	*zp;
1324185029Spjd
1325185029Spjd	rrw_enter(&zfsvfs->z_teardown_lock, RW_WRITER, FTAG);
1326185029Spjd
1327185029Spjd	if (!unmounting) {
1328185029Spjd		/*
1329185029Spjd		 * We purge the parent filesystem's vfsp as the parent
1330185029Spjd		 * filesystem and all of its snapshots have their vnode's
1331185029Spjd		 * v_vfsp set to the parent's filesystem's vfsp.  Note,
1332185029Spjd		 * 'z_parent' is self referential for non-snapshots.
1333185029Spjd		 */
1334185029Spjd		(void) dnlc_purge_vfsp(zfsvfs->z_parent->z_vfs, 0);
1335197351Spjd#ifdef FREEBSD_NAMECACHE
1336197351Spjd		cache_purgevfs(zfsvfs->z_parent->z_vfs);
1337197351Spjd#endif
1338185029Spjd	}
1339185029Spjd
1340185029Spjd	/*
1341185029Spjd	 * Close the zil. NB: Can't close the zil while zfs_inactive
1342185029Spjd	 * threads are blocked as zil_close can call zfs_inactive.
1343185029Spjd	 */
1344185029Spjd	if (zfsvfs->z_log) {
1345185029Spjd		zil_close(zfsvfs->z_log);
1346185029Spjd		zfsvfs->z_log = NULL;
1347185029Spjd	}
1348185029Spjd
1349185029Spjd	rw_enter(&zfsvfs->z_teardown_inactive_lock, RW_WRITER);
1350185029Spjd
1351185029Spjd	/*
1352185029Spjd	 * If we are not unmounting (ie: online recv) and someone already
1353185029Spjd	 * unmounted this file system while we were doing the switcheroo,
1354185029Spjd	 * or a reopen of z_os failed then just bail out now.
1355185029Spjd	 */
1356185029Spjd	if (!unmounting && (zfsvfs->z_unmounted || zfsvfs->z_os == NULL)) {
1357185029Spjd		rw_exit(&zfsvfs->z_teardown_inactive_lock);
1358185029Spjd		rrw_exit(&zfsvfs->z_teardown_lock, FTAG);
1359185029Spjd		return (EIO);
1360185029Spjd	}
1361185029Spjd
1362185029Spjd	/*
1363185029Spjd	 * At this point there are no vops active, and any new vops will
1364185029Spjd	 * fail with EIO since we have z_teardown_lock for writer (only
1365185029Spjd	 * relavent for forced unmount).
1366185029Spjd	 *
1367185029Spjd	 * Release all holds on dbufs.
1368185029Spjd	 */
1369185029Spjd	mutex_enter(&zfsvfs->z_znodes_lock);
1370185029Spjd	for (zp = list_head(&zfsvfs->z_all_znodes); zp != NULL;
1371185029Spjd	    zp = list_next(&zfsvfs->z_all_znodes, zp))
1372185029Spjd		if (zp->z_dbuf) {
1373196297Spjd			ASSERT(ZTOV(zp)->v_count >= 0);
1374185029Spjd			zfs_znode_dmu_fini(zp);
1375185029Spjd		}
1376185029Spjd	mutex_exit(&zfsvfs->z_znodes_lock);
1377185029Spjd
1378185029Spjd	/*
1379185029Spjd	 * If we are unmounting, set the unmounted flag and let new vops
1380185029Spjd	 * unblock.  zfs_inactive will have the unmounted behavior, and all
1381185029Spjd	 * other vops will fail with EIO.
1382185029Spjd	 */
1383185029Spjd	if (unmounting) {
1384185029Spjd		zfsvfs->z_unmounted = B_TRUE;
1385185029Spjd		rrw_exit(&zfsvfs->z_teardown_lock, FTAG);
1386185029Spjd		rw_exit(&zfsvfs->z_teardown_inactive_lock);
1387197133Spjd
1388197133Spjd#ifdef __FreeBSD__
1389197133Spjd		/*
1390197133Spjd		 * Some znodes might not be fully reclaimed, wait for them.
1391197133Spjd		 */
1392197133Spjd		mutex_enter(&zfsvfs->z_znodes_lock);
1393197133Spjd		while (list_head(&zfsvfs->z_all_znodes) != NULL) {
1394197133Spjd			msleep(zfsvfs, &zfsvfs->z_znodes_lock, 0,
1395197133Spjd			    "zteardown", 0);
1396197133Spjd		}
1397197133Spjd		mutex_exit(&zfsvfs->z_znodes_lock);
1398197133Spjd#endif
1399185029Spjd	}
1400185029Spjd
1401185029Spjd	/*
1402185029Spjd	 * z_os will be NULL if there was an error in attempting to reopen
1403185029Spjd	 * zfsvfs, so just return as the properties had already been
1404185029Spjd	 * unregistered and cached data had been evicted before.
1405185029Spjd	 */
1406185029Spjd	if (zfsvfs->z_os == NULL)
1407185029Spjd		return (0);
1408185029Spjd
1409185029Spjd	/*
1410185029Spjd	 * Unregister properties.
1411185029Spjd	 */
1412185029Spjd	zfs_unregister_callbacks(zfsvfs);
1413185029Spjd
1414185029Spjd	/*
1415185029Spjd	 * Evict cached data
1416185029Spjd	 */
1417185029Spjd	if (dmu_objset_evict_dbufs(zfsvfs->z_os)) {
1418185029Spjd		txg_wait_synced(dmu_objset_pool(zfsvfs->z_os), 0);
1419185029Spjd		(void) dmu_objset_evict_dbufs(zfsvfs->z_os);
1420185029Spjd	}
1421185029Spjd
1422185029Spjd	return (0);
1423185029Spjd}
1424185029Spjd
1425168404Spjd/*ARGSUSED*/
1426168404Spjdstatic int
1427191990Sattiliozfs_umount(vfs_t *vfsp, int fflag)
1428168404Spjd{
1429209962Smm	kthread_t *td = curthread;
1430168404Spjd	zfsvfs_t *zfsvfs = vfsp->vfs_data;
1431185029Spjd	objset_t *os;
1432209962Smm	cred_t *cr = td->td_ucred;
1433168404Spjd	int ret;
1434168404Spjd
1435185029Spjd	ret = secpolicy_fs_unmount(cr, vfsp);
1436185029Spjd	if (ret) {
1437212694Smm		if (dsl_deleg_access((char *)refstr_value(vfsp->vfs_resource),
1438212694Smm		    ZFS_DELEG_PERM_MOUNT, cr))
1439185029Spjd			return (ret);
1440185029Spjd	}
1441185029Spjd	/*
1442185029Spjd	 * We purge the parent filesystem's vfsp as the parent filesystem
1443185029Spjd	 * and all of its snapshots have their vnode's v_vfsp set to the
1444185029Spjd	 * parent's filesystem's vfsp.  Note, 'z_parent' is self
1445185029Spjd	 * referential for non-snapshots.
1446185029Spjd	 */
1447185029Spjd	(void) dnlc_purge_vfsp(zfsvfs->z_parent->z_vfs, 0);
1448168404Spjd
1449168404Spjd	/*
1450168404Spjd	 * Unmount any snapshots mounted under .zfs before unmounting the
1451168404Spjd	 * dataset itself.
1452168404Spjd	 */
1453169170Spjd	if (zfsvfs->z_ctldir != NULL) {
1454168404Spjd		if ((ret = zfsctl_umount_snapshots(vfsp, fflag, cr)) != 0)
1455168404Spjd			return (ret);
1456209962Smm		ret = vflush(vfsp, 0, 0, td);
1457168404Spjd		ASSERT(ret == EBUSY);
1458168404Spjd		if (!(fflag & MS_FORCE)) {
1459168404Spjd			if (zfsvfs->z_ctldir->v_count > 1)
1460168404Spjd				return (EBUSY);
1461168404Spjd			ASSERT(zfsvfs->z_ctldir->v_count == 1);
1462168404Spjd		}
1463168404Spjd		zfsctl_destroy(zfsvfs);
1464168404Spjd		ASSERT(zfsvfs->z_ctldir == NULL);
1465168404Spjd	}
1466168404Spjd
1467197459Spjd	if (fflag & MS_FORCE) {
1468197459Spjd		/*
1469197459Spjd		 * Mark file system as unmounted before calling
1470197459Spjd		 * vflush(FORCECLOSE). This way we ensure no future vnops
1471197459Spjd		 * will be called and risk operating on DOOMED vnodes.
1472197459Spjd		 */
1473197459Spjd		rrw_enter(&zfsvfs->z_teardown_lock, RW_WRITER, FTAG);
1474197459Spjd		zfsvfs->z_unmounted = B_TRUE;
1475197459Spjd		rrw_exit(&zfsvfs->z_teardown_lock, FTAG);
1476197459Spjd	}
1477197459Spjd
1478168404Spjd	/*
1479168404Spjd	 * Flush all the files.
1480168404Spjd	 */
1481209962Smm	ret = vflush(vfsp, 1, (fflag & MS_FORCE) ? FORCECLOSE : 0, td);
1482168404Spjd	if (ret != 0) {
1483168404Spjd		if (!zfsvfs->z_issnap) {
1484168404Spjd			zfsctl_create(zfsvfs);
1485168404Spjd			ASSERT(zfsvfs->z_ctldir != NULL);
1486168404Spjd		}
1487168404Spjd		return (ret);
1488168404Spjd	}
1489168404Spjd
1490185029Spjd	if (!(fflag & MS_FORCE)) {
1491185029Spjd		/*
1492185029Spjd		 * Check the number of active vnodes in the file system.
1493185029Spjd		 * Our count is maintained in the vfs structure, but the
1494185029Spjd		 * number is off by 1 to indicate a hold on the vfs
1495185029Spjd		 * structure itself.
1496185029Spjd		 *
1497185029Spjd		 * The '.zfs' directory maintains a reference of its
1498185029Spjd		 * own, and any active references underneath are
1499185029Spjd		 * reflected in the vnode count.
1500185029Spjd		 */
1501185029Spjd		if (zfsvfs->z_ctldir == NULL) {
1502185029Spjd			if (vfsp->vfs_count > 1)
1503185029Spjd				return (EBUSY);
1504185029Spjd		} else {
1505185029Spjd			if (vfsp->vfs_count > 2 ||
1506185029Spjd			    zfsvfs->z_ctldir->v_count > 1)
1507185029Spjd				return (EBUSY);
1508185029Spjd		}
1509185029Spjd	} else {
1510168404Spjd		MNT_ILOCK(vfsp);
1511168404Spjd		vfsp->mnt_kern_flag |= MNTK_UNMOUNTF;
1512168404Spjd		MNT_IUNLOCK(vfsp);
1513185029Spjd	}
1514168404Spjd
1515185029Spjd	VERIFY(zfsvfs_teardown(zfsvfs, B_TRUE) == 0);
1516185029Spjd	os = zfsvfs->z_os;
1517185029Spjd
1518185029Spjd	/*
1519185029Spjd	 * z_os will be NULL if there was an error in
1520185029Spjd	 * attempting to reopen zfsvfs.
1521185029Spjd	 */
1522185029Spjd	if (os != NULL) {
1523168404Spjd		/*
1524185029Spjd		 * Unset the objset user_ptr.
1525168404Spjd		 */
1526185029Spjd		mutex_enter(&os->os->os_user_ptr_lock);
1527185029Spjd		dmu_objset_set_user(os, NULL);
1528185029Spjd		mutex_exit(&os->os->os_user_ptr_lock);
1529185029Spjd
1530185029Spjd		/*
1531185029Spjd		 * Finally release the objset
1532185029Spjd		 */
1533185029Spjd		dmu_objset_close(os);
1534168404Spjd	}
1535168404Spjd
1536185029Spjd	/*
1537185029Spjd	 * We can now safely destroy the '.zfs' directory node.
1538185029Spjd	 */
1539185029Spjd	if (zfsvfs->z_ctldir != NULL)
1540185029Spjd		zfsctl_destroy(zfsvfs);
1541185029Spjd	if (zfsvfs->z_issnap) {
1542185029Spjd		vnode_t *svp = vfsp->mnt_vnodecovered;
1543185029Spjd
1544197515Spjd		if (svp->v_count >= 2)
1545192211Skmacy			VN_RELE(svp);
1546185029Spjd	}
1547168404Spjd	zfs_freevfs(vfsp);
1548168404Spjd
1549168404Spjd	return (0);
1550168404Spjd}
1551168404Spjd
1552168404Spjdstatic int
1553168404Spjdzfs_vget(vfs_t *vfsp, ino_t ino, int flags, vnode_t **vpp)
1554168404Spjd{
1555168404Spjd	zfsvfs_t	*zfsvfs = vfsp->vfs_data;
1556168404Spjd	znode_t		*zp;
1557168404Spjd	int 		err;
1558168404Spjd
1559197167Spjd	/*
1560211855Spjd	 * zfs_zget() can't operate on virtual entires like .zfs/ or
1561211855Spjd	 * .zfs/snapshot/ directories, that's why we return EOPNOTSUPP.
1562211855Spjd	 * This will make NFS to switch to LOOKUP instead of using VGET.
1563197167Spjd	 */
1564197167Spjd	if (ino == ZFSCTL_INO_ROOT || ino == ZFSCTL_INO_SNAPDIR)
1565197167Spjd		return (EOPNOTSUPP);
1566197167Spjd
1567168404Spjd	ZFS_ENTER(zfsvfs);
1568168404Spjd	err = zfs_zget(zfsvfs, ino, &zp);
1569168404Spjd	if (err == 0 && zp->z_unlinked) {
1570168404Spjd		VN_RELE(ZTOV(zp));
1571168404Spjd		err = EINVAL;
1572168404Spjd	}
1573206667Spjd	ZFS_EXIT(zfsvfs);
1574168404Spjd	if (err != 0)
1575168404Spjd		*vpp = NULL;
1576168404Spjd	else {
1577168404Spjd		*vpp = ZTOV(zp);
1578175202Sattilio		vn_lock(*vpp, flags);
1579168404Spjd	}
1580171063Sdfr	return (err);
1581168404Spjd}
1582168404Spjd
1583168404Spjdstatic int
1584196982Spjdzfs_checkexp(vfs_t *vfsp, struct sockaddr *nam, int *extflagsp,
1585196982Spjd    struct ucred **credanonp, int *numsecflavors, int **secflavors)
1586196982Spjd{
1587196982Spjd	zfsvfs_t *zfsvfs = vfsp->vfs_data;
1588196982Spjd
1589196982Spjd	/*
1590196982Spjd	 * If this is regular file system vfsp is the same as
1591196982Spjd	 * zfsvfs->z_parent->z_vfs, but if it is snapshot,
1592196982Spjd	 * zfsvfs->z_parent->z_vfs represents parent file system
1593196982Spjd	 * which we have to use here, because only this file system
1594196982Spjd	 * has mnt_export configured.
1595196982Spjd	 */
1596196982Spjd	return (vfs_stdcheckexp(zfsvfs->z_parent->z_vfs, nam, extflagsp,
1597196982Spjd	    credanonp, numsecflavors, secflavors));
1598196982Spjd}
1599196982Spjd
1600197151SpjdCTASSERT(SHORT_FID_LEN <= sizeof(struct fid));
1601197151SpjdCTASSERT(LONG_FID_LEN <= sizeof(struct fid));
1602196982Spjd
1603196982Spjdstatic int
1604168404Spjdzfs_fhtovp(vfs_t *vfsp, fid_t *fidp, vnode_t **vpp)
1605168404Spjd{
1606168404Spjd	zfsvfs_t	*zfsvfs = vfsp->vfs_data;
1607168404Spjd	znode_t		*zp;
1608168404Spjd	uint64_t	object = 0;
1609168404Spjd	uint64_t	fid_gen = 0;
1610168404Spjd	uint64_t	gen_mask;
1611168404Spjd	uint64_t	zp_gen;
1612168404Spjd	int		i, err;
1613168404Spjd
1614168404Spjd	*vpp = NULL;
1615168404Spjd
1616168404Spjd	ZFS_ENTER(zfsvfs);
1617168404Spjd
1618196979Spjd	/*
1619197177Spjd	 * On FreeBSD we can get snapshot's mount point or its parent file
1620197177Spjd	 * system mount point depending if snapshot is already mounted or not.
1621196979Spjd	 */
1622197177Spjd	if (zfsvfs->z_parent == zfsvfs && fidp->fid_len == LONG_FID_LEN) {
1623168404Spjd		zfid_long_t	*zlfid = (zfid_long_t *)fidp;
1624168404Spjd		uint64_t	objsetid = 0;
1625168404Spjd		uint64_t	setgen = 0;
1626168404Spjd
1627168404Spjd		for (i = 0; i < sizeof (zlfid->zf_setid); i++)
1628168404Spjd			objsetid |= ((uint64_t)zlfid->zf_setid[i]) << (8 * i);
1629168404Spjd
1630168404Spjd		for (i = 0; i < sizeof (zlfid->zf_setgen); i++)
1631168404Spjd			setgen |= ((uint64_t)zlfid->zf_setgen[i]) << (8 * i);
1632168404Spjd
1633168404Spjd		ZFS_EXIT(zfsvfs);
1634168404Spjd
1635168404Spjd		err = zfsctl_lookup_objset(vfsp, objsetid, &zfsvfs);
1636168404Spjd		if (err)
1637168404Spjd			return (EINVAL);
1638168404Spjd		ZFS_ENTER(zfsvfs);
1639168404Spjd	}
1640168404Spjd
1641168404Spjd	if (fidp->fid_len == SHORT_FID_LEN || fidp->fid_len == LONG_FID_LEN) {
1642168404Spjd		zfid_short_t	*zfid = (zfid_short_t *)fidp;
1643168404Spjd
1644168404Spjd		for (i = 0; i < sizeof (zfid->zf_object); i++)
1645168404Spjd			object |= ((uint64_t)zfid->zf_object[i]) << (8 * i);
1646168404Spjd
1647168404Spjd		for (i = 0; i < sizeof (zfid->zf_gen); i++)
1648168404Spjd			fid_gen |= ((uint64_t)zfid->zf_gen[i]) << (8 * i);
1649168404Spjd	} else {
1650168404Spjd		ZFS_EXIT(zfsvfs);
1651168404Spjd		return (EINVAL);
1652168404Spjd	}
1653168404Spjd
1654168404Spjd	/* A zero fid_gen means we are in the .zfs control directories */
1655168404Spjd	if (fid_gen == 0 &&
1656168404Spjd	    (object == ZFSCTL_INO_ROOT || object == ZFSCTL_INO_SNAPDIR)) {
1657168404Spjd		*vpp = zfsvfs->z_ctldir;
1658168404Spjd		ASSERT(*vpp != NULL);
1659168404Spjd		if (object == ZFSCTL_INO_SNAPDIR) {
1660168404Spjd			VERIFY(zfsctl_root_lookup(*vpp, "snapshot", vpp, NULL,
1661185029Spjd			    0, NULL, NULL, NULL, NULL, NULL) == 0);
1662168404Spjd		} else {
1663168404Spjd			VN_HOLD(*vpp);
1664168404Spjd		}
1665206667Spjd		ZFS_EXIT(zfsvfs);
1666196978Spjd		vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
1667168404Spjd		return (0);
1668168404Spjd	}
1669168404Spjd
1670168404Spjd	gen_mask = -1ULL >> (64 - 8 * i);
1671168404Spjd
1672168404Spjd	dprintf("getting %llu [%u mask %llx]\n", object, fid_gen, gen_mask);
1673168404Spjd	if (err = zfs_zget(zfsvfs, object, &zp)) {
1674168404Spjd		ZFS_EXIT(zfsvfs);
1675168404Spjd		return (err);
1676168404Spjd	}
1677168404Spjd	zp_gen = zp->z_phys->zp_gen & gen_mask;
1678168404Spjd	if (zp_gen == 0)
1679168404Spjd		zp_gen = 1;
1680168404Spjd	if (zp->z_unlinked || zp_gen != fid_gen) {
1681168404Spjd		dprintf("znode gen (%u) != fid gen (%u)\n", zp_gen, fid_gen);
1682168404Spjd		VN_RELE(ZTOV(zp));
1683168404Spjd		ZFS_EXIT(zfsvfs);
1684168404Spjd		return (EINVAL);
1685168404Spjd	}
1686168404Spjd
1687206667Spjd	ZFS_EXIT(zfsvfs);
1688206667Spjd
1689168404Spjd	*vpp = ZTOV(zp);
1690175202Sattilio	vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
1691185029Spjd	vnode_create_vobject(*vpp, zp->z_phys->zp_size, curthread);
1692168404Spjd	return (0);
1693168404Spjd}
1694168404Spjd
1695185029Spjd/*
1696185029Spjd * Block out VOPs and close zfsvfs_t::z_os
1697185029Spjd *
1698185029Spjd * Note, if successful, then we return with the 'z_teardown_lock' and
1699185029Spjd * 'z_teardown_inactive_lock' write held.
1700185029Spjd */
1701185029Spjdint
1702209962Smmzfs_suspend_fs(zfsvfs_t *zfsvfs, char *name, int *modep)
1703168404Spjd{
1704185029Spjd	int error;
1705168404Spjd
1706185029Spjd	if ((error = zfsvfs_teardown(zfsvfs, B_FALSE)) != 0)
1707185029Spjd		return (error);
1708168404Spjd
1709209962Smm	*modep = zfsvfs->z_os->os_mode;
1710209962Smm	if (name)
1711209962Smm		dmu_objset_name(zfsvfs->z_os, name);
1712185029Spjd	dmu_objset_close(zfsvfs->z_os);
1713168404Spjd
1714185029Spjd	return (0);
1715185029Spjd}
1716168404Spjd
1717185029Spjd/*
1718185029Spjd * Reopen zfsvfs_t::z_os and release VOPs.
1719185029Spjd */
1720185029Spjdint
1721185029Spjdzfs_resume_fs(zfsvfs_t *zfsvfs, const char *osname, int mode)
1722185029Spjd{
1723185029Spjd	int err;
1724168404Spjd
1725185029Spjd	ASSERT(RRW_WRITE_HELD(&zfsvfs->z_teardown_lock));
1726185029Spjd	ASSERT(RW_WRITE_HELD(&zfsvfs->z_teardown_inactive_lock));
1727185029Spjd
1728185029Spjd	err = dmu_objset_open(osname, DMU_OST_ZFS, mode, &zfsvfs->z_os);
1729185029Spjd	if (err) {
1730185029Spjd		zfsvfs->z_os = NULL;
1731185029Spjd	} else {
1732185029Spjd		znode_t *zp;
1733185029Spjd
1734185029Spjd		VERIFY(zfsvfs_setup(zfsvfs, B_FALSE) == 0);
1735185029Spjd
1736185029Spjd		/*
1737185029Spjd		 * Attempt to re-establish all the active znodes with
1738185029Spjd		 * their dbufs.  If a zfs_rezget() fails, then we'll let
1739185029Spjd		 * any potential callers discover that via ZFS_ENTER_VERIFY_VP
1740185029Spjd		 * when they try to use their znode.
1741185029Spjd		 */
1742185029Spjd		mutex_enter(&zfsvfs->z_znodes_lock);
1743185029Spjd		for (zp = list_head(&zfsvfs->z_all_znodes); zp;
1744185029Spjd		    zp = list_next(&zfsvfs->z_all_znodes, zp)) {
1745185029Spjd			(void) zfs_rezget(zp);
1746185029Spjd		}
1747185029Spjd		mutex_exit(&zfsvfs->z_znodes_lock);
1748185029Spjd
1749168404Spjd	}
1750168404Spjd
1751185029Spjd	/* release the VOPs */
1752185029Spjd	rw_exit(&zfsvfs->z_teardown_inactive_lock);
1753185029Spjd	rrw_exit(&zfsvfs->z_teardown_lock, FTAG);
1754185029Spjd
1755185029Spjd	if (err) {
1756185029Spjd		/*
1757185029Spjd		 * Since we couldn't reopen zfsvfs::z_os, force
1758185029Spjd		 * unmount this file system.
1759185029Spjd		 */
1760185029Spjd		if (vn_vfswlock(zfsvfs->z_vfs->vfs_vnodecovered) == 0)
1761185029Spjd			(void) dounmount(zfsvfs->z_vfs, MS_FORCE, curthread);
1762168404Spjd	}
1763185029Spjd	return (err);
1764168404Spjd}
1765168404Spjd
1766168404Spjdstatic void
1767168404Spjdzfs_freevfs(vfs_t *vfsp)
1768168404Spjd{
1769168404Spjd	zfsvfs_t *zfsvfs = vfsp->vfs_data;
1770168404Spjd
1771215260Smm#ifdef sun
1772209962Smm	/*
1773209962Smm	 * If this is a snapshot, we have an extra VFS_HOLD on our parent
1774209962Smm	 * from zfs_mount().  Release it here.
1775209962Smm	 */
1776209962Smm	if (zfsvfs->z_issnap)
1777209962Smm		VFS_RELE(zfsvfs->z_parent->z_vfs);
1778215260Smm#endif	/* sun */
1779168404Spjd
1780209962Smm	zfsvfs_free(zfsvfs);
1781185029Spjd
1782168404Spjd	atomic_add_32(&zfs_active_fs_count, -1);
1783168404Spjd}
1784168404Spjd
1785172135Spjd#ifdef __i386__
1786172135Spjdstatic int desiredvnodes_backup;
1787172135Spjd#endif
1788172135Spjd
1789172135Spjdstatic void
1790172135Spjdzfs_vnodes_adjust(void)
1791172135Spjd{
1792172135Spjd#ifdef __i386__
1793185029Spjd	int newdesiredvnodes;
1794172135Spjd
1795172135Spjd	desiredvnodes_backup = desiredvnodes;
1796172135Spjd
1797172135Spjd	/*
1798172135Spjd	 * We calculate newdesiredvnodes the same way it is done in
1799172135Spjd	 * vntblinit(). If it is equal to desiredvnodes, it means that
1800172135Spjd	 * it wasn't tuned by the administrator and we can tune it down.
1801172135Spjd	 */
1802185029Spjd	newdesiredvnodes = min(maxproc + cnt.v_page_count / 4, 2 *
1803185029Spjd	    vm_kmem_size / (5 * (sizeof(struct vm_object) +
1804185029Spjd	    sizeof(struct vnode))));
1805185029Spjd	if (newdesiredvnodes == desiredvnodes)
1806185029Spjd		desiredvnodes = (3 * newdesiredvnodes) / 4;
1807172135Spjd#endif
1808172135Spjd}
1809172135Spjd
1810172135Spjdstatic void
1811172135Spjdzfs_vnodes_adjust_back(void)
1812172135Spjd{
1813172135Spjd
1814172135Spjd#ifdef __i386__
1815172135Spjd	desiredvnodes = desiredvnodes_backup;
1816172135Spjd#endif
1817172135Spjd}
1818172135Spjd
1819168404Spjdvoid
1820168404Spjdzfs_init(void)
1821168404Spjd{
1822168404Spjd
1823202129Sdelphij	printf("ZFS filesystem version " ZPL_VERSION_STRING "\n");
1824168404Spjd
1825168404Spjd	/*
1826185029Spjd	 * Initialize znode cache, vnode ops, etc...
1827168404Spjd	 */
1828185029Spjd	zfs_znode_init();
1829168404Spjd
1830168404Spjd	/*
1831185029Spjd	 * Initialize .zfs directory structures
1832168404Spjd	 */
1833185029Spjd	zfsctl_init();
1834172135Spjd
1835172135Spjd	/*
1836185029Spjd	 * Reduce number of vnode. Originally number of vnodes is calculated
1837172135Spjd	 * with UFS inode in mind. We reduce it here, because it's too big for
1838172135Spjd	 * ZFS/i386.
1839172135Spjd	 */
1840172135Spjd	zfs_vnodes_adjust();
1841209962Smm
1842209962Smm	dmu_objset_register_type(DMU_OST_ZFS, zfs_space_delta_cb);
1843168404Spjd}
1844168404Spjd
1845168404Spjdvoid
1846168404Spjdzfs_fini(void)
1847168404Spjd{
1848168404Spjd	zfsctl_fini();
1849168404Spjd	zfs_znode_fini();
1850172135Spjd	zfs_vnodes_adjust_back();
1851168404Spjd}
1852168404Spjd
1853168404Spjdint
1854168404Spjdzfs_busy(void)
1855168404Spjd{
1856168404Spjd	return (zfs_active_fs_count != 0);
1857168404Spjd}
1858185029Spjd
1859185029Spjdint
1860209962Smmzfs_set_version(zfsvfs_t *zfsvfs, uint64_t newvers)
1861185029Spjd{
1862185029Spjd	int error;
1863209962Smm	objset_t *os = zfsvfs->z_os;
1864185029Spjd	dmu_tx_t *tx;
1865185029Spjd
1866185029Spjd	if (newvers < ZPL_VERSION_INITIAL || newvers > ZPL_VERSION)
1867185029Spjd		return (EINVAL);
1868185029Spjd
1869209962Smm	if (newvers < zfsvfs->z_version)
1870209962Smm		return (EINVAL);
1871185029Spjd
1872185029Spjd	tx = dmu_tx_create(os);
1873209962Smm	dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, B_FALSE, ZPL_VERSION_STR);
1874185029Spjd	error = dmu_tx_assign(tx, TXG_WAIT);
1875185029Spjd	if (error) {
1876185029Spjd		dmu_tx_abort(tx);
1877209962Smm		return (error);
1878185029Spjd	}
1879209962Smm	error = zap_update(os, MASTER_NODE_OBJ, ZPL_VERSION_STR,
1880209962Smm	    8, 1, &newvers, tx);
1881185029Spjd
1882209962Smm	if (error) {
1883209962Smm		dmu_tx_commit(tx);
1884209962Smm		return (error);
1885209962Smm	}
1886209962Smm
1887185029Spjd	spa_history_internal_log(LOG_DS_UPGRADE,
1888185029Spjd	    dmu_objset_spa(os), tx, CRED(),
1889209962Smm	    "oldver=%llu newver=%llu dataset = %llu",
1890209962Smm	    zfsvfs->z_version, newvers, dmu_objset_id(os));
1891209962Smm
1892185029Spjd	dmu_tx_commit(tx);
1893185029Spjd
1894209962Smm	zfsvfs->z_version = newvers;
1895209962Smm
1896209962Smm	if (zfsvfs->z_version >= ZPL_VERSION_FUID)
1897209962Smm		zfs_set_fuid_feature(zfsvfs);
1898209962Smm
1899209962Smm	return (0);
1900185029Spjd}
1901185029Spjd/*
1902185029Spjd * Read a property stored within the master node.
1903185029Spjd */
1904185029Spjdint
1905185029Spjdzfs_get_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value)
1906185029Spjd{
1907185029Spjd	const char *pname;
1908185029Spjd	int error = ENOENT;
1909185029Spjd
1910185029Spjd	/*
1911185029Spjd	 * Look up the file system's value for the property.  For the
1912185029Spjd	 * version property, we look up a slightly different string.
1913185029Spjd	 */
1914185029Spjd	if (prop == ZFS_PROP_VERSION)
1915185029Spjd		pname = ZPL_VERSION_STR;
1916185029Spjd	else
1917185029Spjd		pname = zfs_prop_to_name(prop);
1918185029Spjd
1919185029Spjd	if (os != NULL)
1920185029Spjd		error = zap_lookup(os, MASTER_NODE_OBJ, pname, 8, 1, value);
1921185029Spjd
1922185029Spjd	if (error == ENOENT) {
1923185029Spjd		/* No value set, use the default value */
1924185029Spjd		switch (prop) {
1925185029Spjd		case ZFS_PROP_VERSION:
1926185029Spjd			*value = ZPL_VERSION;
1927185029Spjd			break;
1928185029Spjd		case ZFS_PROP_NORMALIZE:
1929185029Spjd		case ZFS_PROP_UTF8ONLY:
1930185029Spjd			*value = 0;
1931185029Spjd			break;
1932185029Spjd		case ZFS_PROP_CASE:
1933185029Spjd			*value = ZFS_CASE_SENSITIVE;
1934185029Spjd			break;
1935185029Spjd		default:
1936185029Spjd			return (error);
1937185029Spjd		}
1938185029Spjd		error = 0;
1939185029Spjd	}
1940185029Spjd	return (error);
1941185029Spjd}
1942