usr/src/uts/common/fs/zfs/zfs_vfsops.c
author ek110237
Wed, 24 Oct 2007 16:54:46 -0700
changeset 5326 6752aa2bd5bc
parent 5147 5e950ccc9585
child 5331 3047ad28a67b
permissions -rw-r--r--
6425096 want online 'zfs recv' (read only and read/write) 6597182 .zfs/snapshot code could use a little more comments
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     1
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     2
 * CDDL HEADER START
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     3
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
1484
d330e98f8ed7 6350001 ZFS lookup performance still much slower than UFS : help tar : help spec SFS
ek110237
parents: 1298
diff changeset
     5
 * Common Development and Distribution License (the "License").
d330e98f8ed7 6350001 ZFS lookup performance still much slower than UFS : help tar : help spec SFS
ek110237
parents: 1298
diff changeset
     6
 * You may not use this file except in compliance with the License.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     7
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    11
 * and limitations under the License.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    12
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    18
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    19
 * CDDL HEADER END
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    20
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    21
/*
3461
c19b22f347d6 6514331 in-memory delete queue is not needed
ahrens
parents: 3265
diff changeset
    22
 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    23
 * Use is subject to license terms.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    24
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    25
3246
7a46b8f56ee0 6351954 zfs missing noxattr mount flag (fix keywords)
ck153898
parents: 3234
diff changeset
    26
#pragma ident	"%Z%%M%	%I%	%E% SMI"
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    27
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
#include <sys/types.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
#include <sys/param.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
#include <sys/systm.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
#include <sys/sysmacros.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
#include <sys/kmem.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
#include <sys/pathname.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    34
#include <sys/vnode.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
#include <sys/vfs.h>
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3461
diff changeset
    36
#include <sys/vfs_opreg.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
#include <sys/mntent.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    38
#include <sys/mount.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    39
#include <sys/cmn_err.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    40
#include "fs/fs_subr.h"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    41
#include <sys/zfs_znode.h>
3461
c19b22f347d6 6514331 in-memory delete queue is not needed
ahrens
parents: 3265
diff changeset
    42
#include <sys/zfs_dir.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    43
#include <sys/zil.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
#include <sys/fs/zfs.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    45
#include <sys/dmu.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
#include <sys/dsl_prop.h>
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
    47
#include <sys/dsl_dataset.h>
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
    48
#include <sys/dsl_deleg.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
#include <sys/spa.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
#include <sys/zap.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    51
#include <sys/varargs.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
#include <sys/policy.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
#include <sys/atomic.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    54
#include <sys/mkdev.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
#include <sys/modctl.h>
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
    56
#include <sys/refstr.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
#include <sys/zfs_ioctl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
#include <sys/zfs_ctldir.h>
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
    59
#include <sys/bootconf.h>
849
8d799fd81a9b 6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents: 789
diff changeset
    60
#include <sys/sunddi.h>
1484
d330e98f8ed7 6350001 ZFS lookup performance still much slower than UFS : help tar : help spec SFS
ek110237
parents: 1298
diff changeset
    61
#include <sys/dnlc.h>
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
    62
#include <sys/dmu_objset.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    63
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
int zfsfstype;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    65
vfsops_t *zfs_vfsops = NULL;
849
8d799fd81a9b 6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents: 789
diff changeset
    66
static major_t zfs_major;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    67
static minor_t zfs_minor;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
static kmutex_t	zfs_dev_mtx;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    70
static int zfs_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    71
static int zfs_umount(vfs_t *vfsp, int fflag, cred_t *cr);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
    72
static int zfs_mountroot(vfs_t *vfsp, enum whymountroot);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    73
static int zfs_root(vfs_t *vfsp, vnode_t **vpp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    74
static int zfs_statvfs(vfs_t *vfsp, struct statvfs64 *statp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    75
static int zfs_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    76
static void zfs_freevfs(vfs_t *vfsp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    77
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    78
static const fs_operation_def_t zfs_vfsops_template[] = {
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3461
diff changeset
    79
	VFSNAME_MOUNT,		{ .vfs_mount = zfs_mount },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3461
diff changeset
    80
	VFSNAME_MOUNTROOT,	{ .vfs_mountroot = zfs_mountroot },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3461
diff changeset
    81
	VFSNAME_UNMOUNT,	{ .vfs_unmount = zfs_umount },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3461
diff changeset
    82
	VFSNAME_ROOT,		{ .vfs_root = zfs_root },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3461
diff changeset
    83
	VFSNAME_STATVFS,	{ .vfs_statvfs = zfs_statvfs },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3461
diff changeset
    84
	VFSNAME_SYNC,		{ .vfs_sync = zfs_sync },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3461
diff changeset
    85
	VFSNAME_VGET,		{ .vfs_vget = zfs_vget },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3461
diff changeset
    86
	VFSNAME_FREEVFS,	{ .vfs_freevfs = zfs_freevfs },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3461
diff changeset
    87
	NULL,			NULL
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    88
};
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    89
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    90
static const fs_operation_def_t zfs_vfsops_eio_template[] = {
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3461
diff changeset
    91
	VFSNAME_FREEVFS,	{ .vfs_freevfs =  zfs_freevfs },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3461
diff changeset
    92
	NULL,			NULL
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    93
};
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    94
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    95
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    96
 * We need to keep a count of active fs's.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    97
 * This is necessary to prevent our module
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    98
 * from being unloaded after a umount -f
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    99
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   100
static uint32_t	zfs_active_fs_count = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   101
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   102
static char *noatime_cancel[] = { MNTOPT_ATIME, NULL };
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   103
static char *atime_cancel[] = { MNTOPT_NOATIME, NULL };
3234
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   104
static char *noxattr_cancel[] = { MNTOPT_XATTR, NULL };
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   105
static char *xattr_cancel[] = { MNTOPT_NOXATTR, NULL };
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   106
3234
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   107
/*
4596
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   108
 * MO_DEFAULT is not used since the default value is determined
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   109
 * by the equivalent property.
3234
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   110
 */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   111
static mntopt_t mntopts[] = {
3234
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   112
	{ MNTOPT_NOXATTR, noxattr_cancel, NULL, 0, NULL },
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   113
	{ MNTOPT_XATTR, xattr_cancel, NULL, 0, NULL },
4596
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   114
	{ MNTOPT_NOATIME, noatime_cancel, NULL, 0, NULL },
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   115
	{ MNTOPT_ATIME, atime_cancel, NULL, 0, NULL }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   116
};
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   117
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   118
static mntopts_t zfs_mntopts = {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   119
	sizeof (mntopts) / sizeof (mntopt_t),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   120
	mntopts
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   121
};
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   122
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   123
/*ARGSUSED*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   124
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   125
zfs_sync(vfs_t *vfsp, short flag, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   126
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   127
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   128
	 * Data integrity is job one.  We don't want a compromised kernel
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   129
	 * writing to the storage pool, so we never sync during panic.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   130
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   131
	if (panicstr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   132
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   133
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   134
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   135
	 * SYNC_ATTR is used by fsflush() to force old filesystems like UFS
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   136
	 * to sync metadata, which they would otherwise cache indefinitely.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   137
	 * Semantically, the only requirement is that the sync be initiated.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   138
	 * The DMU syncs out txgs frequently, so there's nothing to do.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   139
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   140
	if (flag & SYNC_ATTR)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   141
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   142
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   143
	if (vfsp != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   144
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   145
		 * Sync a specific filesystem.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   146
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   147
		zfsvfs_t *zfsvfs = vfsp->vfs_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   148
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   149
		ZFS_ENTER(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   150
		if (zfsvfs->z_log != NULL)
2638
4f583dfeae92 6413510 zfs: writing to ZFS filesystem slows down fsync() on other files in the same FS
perrin
parents: 2474
diff changeset
   151
			zil_commit(zfsvfs->z_log, UINT64_MAX, 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   152
		else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   153
			txg_wait_synced(dmu_objset_pool(zfsvfs->z_os), 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   154
		ZFS_EXIT(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   155
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   156
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   157
		 * Sync all ZFS filesystems.  This is what happens when you
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   158
		 * run sync(1M).  Unlike other filesystems, ZFS honors the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   159
		 * request by waiting for all pools to commit all dirty data.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   160
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   161
		spa_sync_allpools();
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   162
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   163
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   164
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   165
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   166
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   167
static int
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   168
zfs_create_unique_device(dev_t *dev)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   169
{
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   170
	major_t new_major;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   171
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   172
	do {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   173
		ASSERT3U(zfs_minor, <=, MAXMIN32);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   174
		minor_t start = zfs_minor;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   175
		do {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   176
			mutex_enter(&zfs_dev_mtx);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   177
			if (zfs_minor >= MAXMIN32) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   178
				/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   179
				 * If we're still using the real major
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   180
				 * keep out of /dev/zfs and /dev/zvol minor
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   181
				 * number space.  If we're using a getudev()'ed
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   182
				 * major number, we can use all of its minors.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   183
				 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   184
				if (zfs_major == ddi_name_to_major(ZFS_DRIVER))
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   185
					zfs_minor = ZFS_MIN_MINOR;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   186
				else
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   187
					zfs_minor = 0;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   188
			} else {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   189
				zfs_minor++;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   190
			}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   191
			*dev = makedevice(zfs_major, zfs_minor);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   192
			mutex_exit(&zfs_dev_mtx);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   193
		} while (vfs_devismounted(*dev) && zfs_minor != start);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   194
		if (zfs_minor == start) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   195
			/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   196
			 * We are using all ~262,000 minor numbers for the
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   197
			 * current major number.  Create a new major number.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   198
			 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   199
			if ((new_major = getudev()) == (major_t)-1) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   200
				cmn_err(CE_WARN,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   201
				    "zfs_mount: Can't get unique major "
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   202
				    "device number.");
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   203
				return (-1);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   204
			}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   205
			mutex_enter(&zfs_dev_mtx);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   206
			zfs_major = new_major;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   207
			zfs_minor = 0;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   208
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   209
			mutex_exit(&zfs_dev_mtx);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   210
		} else {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   211
			break;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   212
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   213
		/* CONSTANTCONDITION */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   214
	} while (1);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   215
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   216
	return (0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   217
}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   218
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   219
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   220
atime_changed_cb(void *arg, uint64_t newval)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   221
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   222
	zfsvfs_t *zfsvfs = arg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   223
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   224
	if (newval == TRUE) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   225
		zfsvfs->z_atime = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   226
		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_NOATIME);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   227
		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_ATIME, NULL, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   228
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   229
		zfsvfs->z_atime = FALSE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   230
		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_ATIME);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   231
		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_NOATIME, NULL, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   232
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   233
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   234
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   235
static void
3234
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   236
xattr_changed_cb(void *arg, uint64_t newval)
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   237
{
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   238
	zfsvfs_t *zfsvfs = arg;
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   239
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   240
	if (newval == TRUE) {
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   241
		/* XXX locking on vfs_flag? */
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   242
		zfsvfs->z_vfs->vfs_flag |= VFS_XATTR;
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   243
		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_NOXATTR);
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   244
		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_XATTR, NULL, 0);
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   245
	} else {
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   246
		/* XXX locking on vfs_flag? */
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   247
		zfsvfs->z_vfs->vfs_flag &= ~VFS_XATTR;
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   248
		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_XATTR);
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   249
		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_NOXATTR, NULL, 0);
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   250
	}
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   251
}
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   252
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   253
static void
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   254
blksz_changed_cb(void *arg, uint64_t newval)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   255
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   256
	zfsvfs_t *zfsvfs = arg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   257
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   258
	if (newval < SPA_MINBLOCKSIZE ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   259
	    newval > SPA_MAXBLOCKSIZE || !ISP2(newval))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   260
		newval = SPA_MAXBLOCKSIZE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   261
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   262
	zfsvfs->z_max_blksz = newval;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   263
	zfsvfs->z_vfs->vfs_bsize = newval;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   264
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   265
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   266
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   267
readonly_changed_cb(void *arg, uint64_t newval)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   268
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   269
	zfsvfs_t *zfsvfs = arg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   270
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   271
	if (newval) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   272
		/* XXX locking on vfs_flag? */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   273
		zfsvfs->z_vfs->vfs_flag |= VFS_RDONLY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   274
		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_RW);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   275
		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_RO, NULL, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   276
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   277
		/* XXX locking on vfs_flag? */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   278
		zfsvfs->z_vfs->vfs_flag &= ~VFS_RDONLY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   279
		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_RO);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   280
		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_RW, NULL, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   281
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   282
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   283
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   284
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   285
devices_changed_cb(void *arg, uint64_t newval)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   286
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   287
	zfsvfs_t *zfsvfs = arg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   288
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   289
	if (newval == FALSE) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   290
		zfsvfs->z_vfs->vfs_flag |= VFS_NODEVICES;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   291
		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_DEVICES);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   292
		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_NODEVICES, NULL, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   293
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   294
		zfsvfs->z_vfs->vfs_flag &= ~VFS_NODEVICES;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   295
		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_NODEVICES);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   296
		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_DEVICES, NULL, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   297
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   298
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   299
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   300
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   301
setuid_changed_cb(void *arg, uint64_t newval)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   302
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   303
	zfsvfs_t *zfsvfs = arg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   304
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   305
	if (newval == FALSE) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   306
		zfsvfs->z_vfs->vfs_flag |= VFS_NOSETUID;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   307
		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_SETUID);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   308
		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_NOSETUID, NULL, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   309
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   310
		zfsvfs->z_vfs->vfs_flag &= ~VFS_NOSETUID;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   311
		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_NOSETUID);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   312
		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_SETUID, NULL, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   313
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   314
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   315
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   316
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   317
exec_changed_cb(void *arg, uint64_t newval)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   318
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   319
	zfsvfs_t *zfsvfs = arg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   320
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   321
	if (newval == FALSE) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   322
		zfsvfs->z_vfs->vfs_flag |= VFS_NOEXEC;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   323
		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_EXEC);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   324
		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_NOEXEC, NULL, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   325
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   326
		zfsvfs->z_vfs->vfs_flag &= ~VFS_NOEXEC;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   327
		vfs_clearmntopt(zfsvfs->z_vfs, MNTOPT_NOEXEC);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   328
		vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_EXEC, NULL, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   329
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   330
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   331
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   332
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   333
snapdir_changed_cb(void *arg, uint64_t newval)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   334
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   335
	zfsvfs_t *zfsvfs = arg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   336
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   337
	zfsvfs->z_show_ctldir = newval;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   338
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   339
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   340
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   341
acl_mode_changed_cb(void *arg, uint64_t newval)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   342
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   343
	zfsvfs_t *zfsvfs = arg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   344
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   345
	zfsvfs->z_acl_mode = newval;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   346
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   347
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   348
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   349
acl_inherit_changed_cb(void *arg, uint64_t newval)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   350
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   351
	zfsvfs_t *zfsvfs = arg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   352
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   353
	zfsvfs->z_acl_inherit = newval;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   354
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   355
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   356
static int
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   357
zfs_register_callbacks(vfs_t *vfsp)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   358
{
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   359
	struct dsl_dataset *ds = NULL;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   360
	objset_t *os = NULL;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   361
	zfsvfs_t *zfsvfs = NULL;
3265
967e0fca6143 6463140 zfs recv with a snapshot name that has 2 @@ in a row succeeds
ahrens
parents: 3246
diff changeset
   362
	int readonly, do_readonly = FALSE;
967e0fca6143 6463140 zfs recv with a snapshot name that has 2 @@ in a row succeeds
ahrens
parents: 3246
diff changeset
   363
	int setuid, do_setuid = FALSE;
967e0fca6143 6463140 zfs recv with a snapshot name that has 2 @@ in a row succeeds
ahrens
parents: 3246
diff changeset
   364
	int exec, do_exec = FALSE;
967e0fca6143 6463140 zfs recv with a snapshot name that has 2 @@ in a row succeeds
ahrens
parents: 3246
diff changeset
   365
	int devices, do_devices = FALSE;
967e0fca6143 6463140 zfs recv with a snapshot name that has 2 @@ in a row succeeds
ahrens
parents: 3246
diff changeset
   366
	int xattr, do_xattr = FALSE;
4596
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   367
	int atime, do_atime = FALSE;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   368
	int error = 0;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   369
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   370
	ASSERT(vfsp);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   371
	zfsvfs = vfsp->vfs_data;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   372
	ASSERT(zfsvfs);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   373
	os = zfsvfs->z_os;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   374
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   375
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   376
	 * The act of registering our callbacks will destroy any mount
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   377
	 * options we may have.  In order to enable temporary overrides
3234
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   378
	 * of mount options, we stash away the current values and
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   379
	 * restore them after we register the callbacks.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   380
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   381
	if (vfs_optionisset(vfsp, MNTOPT_RO, NULL)) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   382
		readonly = B_TRUE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   383
		do_readonly = B_TRUE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   384
	} else if (vfs_optionisset(vfsp, MNTOPT_RW, NULL)) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   385
		readonly = B_FALSE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   386
		do_readonly = B_TRUE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   387
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   388
	if (vfs_optionisset(vfsp, MNTOPT_NOSUID, NULL)) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   389
		devices = B_FALSE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   390
		setuid = B_FALSE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   391
		do_devices = B_TRUE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   392
		do_setuid = B_TRUE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   393
	} else {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   394
		if (vfs_optionisset(vfsp, MNTOPT_NODEVICES, NULL)) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   395
			devices = B_FALSE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   396
			do_devices = B_TRUE;
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   397
		} else if (vfs_optionisset(vfsp, MNTOPT_DEVICES, NULL)) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   398
			devices = B_TRUE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   399
			do_devices = B_TRUE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   400
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   401
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   402
		if (vfs_optionisset(vfsp, MNTOPT_NOSETUID, NULL)) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   403
			setuid = B_FALSE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   404
			do_setuid = B_TRUE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   405
		} else if (vfs_optionisset(vfsp, MNTOPT_SETUID, NULL)) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   406
			setuid = B_TRUE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   407
			do_setuid = B_TRUE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   408
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   409
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   410
	if (vfs_optionisset(vfsp, MNTOPT_NOEXEC, NULL)) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   411
		exec = B_FALSE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   412
		do_exec = B_TRUE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   413
	} else if (vfs_optionisset(vfsp, MNTOPT_EXEC, NULL)) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   414
		exec = B_TRUE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   415
		do_exec = B_TRUE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   416
	}
3234
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   417
	if (vfs_optionisset(vfsp, MNTOPT_NOXATTR, NULL)) {
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   418
		xattr = B_FALSE;
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   419
		do_xattr = B_TRUE;
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   420
	} else if (vfs_optionisset(vfsp, MNTOPT_XATTR, NULL)) {
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   421
		xattr = B_TRUE;
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   422
		do_xattr = B_TRUE;
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   423
	}
4596
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   424
	if (vfs_optionisset(vfsp, MNTOPT_NOATIME, NULL)) {
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   425
		atime = B_FALSE;
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   426
		do_atime = B_TRUE;
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   427
	} else if (vfs_optionisset(vfsp, MNTOPT_ATIME, NULL)) {
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   428
		atime = B_TRUE;
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   429
		do_atime = B_TRUE;
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   430
	}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   431
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   432
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   433
	 * Register property callbacks.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   434
	 *
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   435
	 * It would probably be fine to just check for i/o error from
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   436
	 * the first prop_register(), but I guess I like to go
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   437
	 * overboard...
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   438
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   439
	ds = dmu_objset_ds(os);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   440
	error = dsl_prop_register(ds, "atime", atime_changed_cb, zfsvfs);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   441
	error = error ? error : dsl_prop_register(ds,
3234
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   442
	    "xattr", xattr_changed_cb, zfsvfs);
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   443
	error = error ? error : dsl_prop_register(ds,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   444
	    "recordsize", blksz_changed_cb, zfsvfs);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   445
	error = error ? error : dsl_prop_register(ds,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   446
	    "readonly", readonly_changed_cb, zfsvfs);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   447
	error = error ? error : dsl_prop_register(ds,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   448
	    "devices", devices_changed_cb, zfsvfs);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   449
	error = error ? error : dsl_prop_register(ds,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   450
	    "setuid", setuid_changed_cb, zfsvfs);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   451
	error = error ? error : dsl_prop_register(ds,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   452
	    "exec", exec_changed_cb, zfsvfs);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   453
	error = error ? error : dsl_prop_register(ds,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   454
	    "snapdir", snapdir_changed_cb, zfsvfs);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   455
	error = error ? error : dsl_prop_register(ds,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   456
	    "aclmode", acl_mode_changed_cb, zfsvfs);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   457
	error = error ? error : dsl_prop_register(ds,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   458
	    "aclinherit", acl_inherit_changed_cb, zfsvfs);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   459
	if (error)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   460
		goto unregister;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   461
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   462
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   463
	 * Invoke our callbacks to restore temporary mount options.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   464
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   465
	if (do_readonly)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   466
		readonly_changed_cb(zfsvfs, readonly);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   467
	if (do_setuid)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   468
		setuid_changed_cb(zfsvfs, setuid);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   469
	if (do_exec)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   470
		exec_changed_cb(zfsvfs, exec);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   471
	if (do_devices)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   472
		devices_changed_cb(zfsvfs, devices);
3234
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   473
	if (do_xattr)
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   474
		xattr_changed_cb(zfsvfs, xattr);
4596
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   475
	if (do_atime)
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   476
		atime_changed_cb(zfsvfs, atime);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   477
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   478
	return (0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   479
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   480
unregister:
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   481
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   482
	 * We may attempt to unregister some callbacks that are not
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   483
	 * registered, but this is OK; it will simply return ENOMSG,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   484
	 * which we will ignore.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   485
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   486
	(void) dsl_prop_unregister(ds, "atime", atime_changed_cb, zfsvfs);
3234
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   487
	(void) dsl_prop_unregister(ds, "xattr", xattr_changed_cb, zfsvfs);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   488
	(void) dsl_prop_unregister(ds, "recordsize", blksz_changed_cb, zfsvfs);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   489
	(void) dsl_prop_unregister(ds, "readonly", readonly_changed_cb, zfsvfs);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   490
	(void) dsl_prop_unregister(ds, "devices", devices_changed_cb, zfsvfs);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   491
	(void) dsl_prop_unregister(ds, "setuid", setuid_changed_cb, zfsvfs);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   492
	(void) dsl_prop_unregister(ds, "exec", exec_changed_cb, zfsvfs);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   493
	(void) dsl_prop_unregister(ds, "snapdir", snapdir_changed_cb, zfsvfs);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   494
	(void) dsl_prop_unregister(ds, "aclmode", acl_mode_changed_cb, zfsvfs);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   495
	(void) dsl_prop_unregister(ds, "aclinherit", acl_inherit_changed_cb,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   496
	    zfsvfs);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   497
	return (error);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   498
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   499
}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   500
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   501
static int
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   502
zfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t mounting)
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   503
{
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   504
	uint_t readonly;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   505
	int error;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   506
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   507
	error = zfs_register_callbacks(zfsvfs->z_vfs);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   508
	if (error)
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   509
		return (error);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   510
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   511
	/*
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   512
	 * Set the objset user_ptr to track its zfsvfs.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   513
	 */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   514
	mutex_enter(&zfsvfs->z_os->os->os_user_ptr_lock);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   515
	dmu_objset_set_user(zfsvfs->z_os, zfsvfs);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   516
	mutex_exit(&zfsvfs->z_os->os->os_user_ptr_lock);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   517
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   518
	/*
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   519
	 * If we are not mounting (ie: online recv), then we don't
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   520
	 * have to worry about replaying the log as we blocked all
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   521
	 * operations out since we closed the ZIL.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   522
	 */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   523
	if (mounting) {
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   524
		/*
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   525
		 * During replay we remove the read only flag to
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   526
		 * allow replays to succeed.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   527
		 */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   528
		readonly = zfsvfs->z_vfs->vfs_flag & VFS_RDONLY;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   529
		if (readonly != 0)
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   530
			zfsvfs->z_vfs->vfs_flag &= ~VFS_RDONLY;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   531
		else
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   532
			zfs_unlinked_drain(zfsvfs);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   533
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   534
		/*
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   535
		 * Parse and replay the intent log.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   536
		 *
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   537
		 * Because of ziltest, this must be done after
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   538
		 * zfs_unlinked_drain().  (Further note: ziltest doesn't
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   539
		 * use readonly mounts, where zfs_unlinked_drain() isn't
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   540
		 * called.)  This is because ziltest causes spa_sync()
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   541
		 * to think it's committed, but actually it is not, so
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   542
		 * the intent log contains many txg's worth of changes.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   543
		 *
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   544
		 * In particular, if object N is in the unlinked set in
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   545
		 * the last txg to actually sync, then it could be
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   546
		 * actually freed in a later txg and then reallocated in
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   547
		 * a yet later txg.  This would write a "create object
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   548
		 * N" record to the intent log.  Normally, this would be
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   549
		 * fine because the spa_sync() would have written out
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   550
		 * the fact that object N is free, before we could write
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   551
		 * the "create object N" intent log record.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   552
		 *
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   553
		 * But when we are in ziltest mode, we advance the "open
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   554
		 * txg" without actually spa_sync()-ing the changes to
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   555
		 * disk.  So we would see that object N is still
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   556
		 * allocated and in the unlinked set, and there is an
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   557
		 * intent log record saying to allocate it.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   558
		 */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   559
		zil_replay(zfsvfs->z_os, zfsvfs, &zfsvfs->z_assign,
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   560
		    zfs_replay_vector);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   561
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   562
		zfsvfs->z_vfs->vfs_flag |= readonly; /* restore readonly bit */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   563
	}
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   564
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   565
	if (!zil_disable)
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   566
		zfsvfs->z_log = zil_open(zfsvfs->z_os, zfs_get_data);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   567
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   568
	return (0);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   569
}
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   570
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   571
static int
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   572
zfs_domount(vfs_t *vfsp, char *osname, cred_t *cr)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   573
{
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   574
	dev_t mount_dev;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   575
	uint64_t recordsize, readonly;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   576
	int error = 0;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   577
	int mode;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   578
	zfsvfs_t *zfsvfs;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   579
	znode_t *zp = NULL;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   580
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   581
	ASSERT(vfsp);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   582
	ASSERT(osname);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   583
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   584
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   585
	 * Initialize the zfs-specific filesystem structure.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   586
	 * Should probably make this a kmem cache, shuffle fields,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   587
	 * and just bzero up to z_hold_mtx[].
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   588
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   589
	zfsvfs = kmem_zalloc(sizeof (zfsvfs_t), KM_SLEEP);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   590
	zfsvfs->z_vfs = vfsp;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   591
	zfsvfs->z_parent = zfsvfs;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   592
	zfsvfs->z_assign = TXG_NOWAIT;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   593
	zfsvfs->z_max_blksz = SPA_MAXBLOCKSIZE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   594
	zfsvfs->z_show_ctldir = ZFS_SNAPDIR_VISIBLE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   595
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   596
	mutex_init(&zfsvfs->z_znodes_lock, NULL, MUTEX_DEFAULT, NULL);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   597
	list_create(&zfsvfs->z_all_znodes, sizeof (znode_t),
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   598
	    offsetof(znode_t, z_link_node));
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   599
	rrw_init(&zfsvfs->z_teardown_lock);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   600
	rw_init(&zfsvfs->z_teardown_inactive_lock, NULL, RW_DEFAULT, NULL);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   601
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   602
	/* Initialize the generic filesystem structure. */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   603
	vfsp->vfs_bcount = 0;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   604
	vfsp->vfs_data = NULL;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   605
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   606
	if (zfs_create_unique_device(&mount_dev) == -1) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   607
		error = ENODEV;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   608
		goto out;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   609
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   610
	ASSERT(vfs_devismounted(mount_dev) == 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   611
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   612
	if (error = dsl_prop_get_integer(osname, "recordsize", &recordsize,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   613
	    NULL))
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   614
		goto out;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   615
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   616
	vfsp->vfs_dev = mount_dev;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   617
	vfsp->vfs_fstype = zfsfstype;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   618
	vfsp->vfs_bsize = recordsize;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   619
	vfsp->vfs_flag |= VFS_NOTRUNC;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   620
	vfsp->vfs_data = zfsvfs;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   621
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   622
	if (error = dsl_prop_get_integer(osname, "readonly", &readonly, NULL))
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   623
		goto out;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   624
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   625
	if (readonly)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   626
		mode = DS_MODE_PRIMARY | DS_MODE_READONLY;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   627
	else
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   628
		mode = DS_MODE_PRIMARY;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   629
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   630
	error = dmu_objset_open(osname, DMU_OST_ZFS, mode, &zfsvfs->z_os);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   631
	if (error == EROFS) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   632
		mode = DS_MODE_PRIMARY | DS_MODE_READONLY;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   633
		error = dmu_objset_open(osname, DMU_OST_ZFS, mode,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   634
		    &zfsvfs->z_os);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   635
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   636
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   637
	if (error)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   638
		goto out;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   639
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   640
	if (error = zfs_init_fs(zfsvfs, &zp, cr))
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   641
		goto out;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   642
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   643
	/* The call to zfs_init_fs leaves the vnode held, release it here. */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   644
	VN_RELE(ZTOV(zp));
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   645
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   646
	if (dmu_objset_is_snapshot(zfsvfs->z_os)) {
3234
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   647
		uint64_t xattr;
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   648
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   649
		ASSERT(mode & DS_MODE_READONLY);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   650
		atime_changed_cb(zfsvfs, B_FALSE);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   651
		readonly_changed_cb(zfsvfs, B_TRUE);
3234
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   652
		if (error = dsl_prop_get_integer(osname, "xattr", &xattr, NULL))
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   653
			goto out;
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   654
		xattr_changed_cb(zfsvfs, xattr);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   655
		zfsvfs->z_issnap = B_TRUE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   656
	} else {
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   657
		error = zfsvfs_setup(zfsvfs, B_TRUE);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   658
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   659
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   660
	if (!zfsvfs->z_issnap)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   661
		zfsctl_create(zfsvfs);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   662
out:
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   663
	if (error) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   664
		if (zfsvfs->z_os)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   665
			dmu_objset_close(zfsvfs->z_os);
4831
41ec732c6d9f 6584470 zdb needs to initialize the bpl_lock mutex
gw25295
parents: 4787
diff changeset
   666
		mutex_destroy(&zfsvfs->z_znodes_lock);
41ec732c6d9f 6584470 zdb needs to initialize the bpl_lock mutex
gw25295
parents: 4787
diff changeset
   667
		list_destroy(&zfsvfs->z_all_znodes);
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   668
		rrw_destroy(&zfsvfs->z_teardown_lock);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
   669
		rw_destroy(&zfsvfs->z_teardown_inactive_lock);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   670
		kmem_free(zfsvfs, sizeof (zfsvfs_t));
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   671
	} else {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   672
		atomic_add_32(&zfs_active_fs_count, 1);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   673
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   674
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   675
	return (error);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   676
}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   677
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   678
void
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   679
zfs_unregister_callbacks(zfsvfs_t *zfsvfs)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   680
{
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   681
	objset_t *os = zfsvfs->z_os;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   682
	struct dsl_dataset *ds;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   683
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   684
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   685
	 * Unregister properties.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   686
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   687
	if (!dmu_objset_is_snapshot(os)) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   688
		ds = dmu_objset_ds(os);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   689
		VERIFY(dsl_prop_unregister(ds, "atime", atime_changed_cb,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   690
		    zfsvfs) == 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   691
3234
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   692
		VERIFY(dsl_prop_unregister(ds, "xattr", xattr_changed_cb,
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   693
		    zfsvfs) == 0);
28b36f7bbd7e PSARC/2006/638 noxattr ZFS property
ck153898
parents: 2885
diff changeset
   694
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   695
		VERIFY(dsl_prop_unregister(ds, "recordsize", blksz_changed_cb,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   696
		    zfsvfs) == 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   697
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   698
		VERIFY(dsl_prop_unregister(ds, "readonly", readonly_changed_cb,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   699
		    zfsvfs) == 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   700
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   701
		VERIFY(dsl_prop_unregister(ds, "devices", devices_changed_cb,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   702
		    zfsvfs) == 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   703
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   704
		VERIFY(dsl_prop_unregister(ds, "setuid", setuid_changed_cb,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   705
		    zfsvfs) == 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   706
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   707
		VERIFY(dsl_prop_unregister(ds, "exec", exec_changed_cb,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   708
		    zfsvfs) == 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   709
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   710
		VERIFY(dsl_prop_unregister(ds, "snapdir", snapdir_changed_cb,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   711
		    zfsvfs) == 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   712
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   713
		VERIFY(dsl_prop_unregister(ds, "aclmode", acl_mode_changed_cb,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   714
		    zfsvfs) == 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   715
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   716
		VERIFY(dsl_prop_unregister(ds, "aclinherit",
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   717
		    acl_inherit_changed_cb, zfsvfs) == 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   718
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   719
}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   720
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   721
/*
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   722
 * Convert a decimal digit string to a uint64_t integer.
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   723
 */
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   724
static int
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   725
str_to_uint64(char *str, uint64_t *objnum)
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   726
{
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   727
	uint64_t num = 0;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   728
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   729
	while (*str) {
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   730
		if (*str < '0' || *str > '9')
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   731
			return (EINVAL);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   732
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   733
		num = num*10 + *str++ - '0';
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   734
	}
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   735
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   736
	*objnum = num;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   737
	return (0);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   738
}
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   739
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   740
/*
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   741
 * The boot path passed from the boot loader is in the form of
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   742
 * "rootpool-name/root-filesystem-object-number'. Convert this
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   743
 * string to a dataset name: "rootpool-name/root-filesystem-name".
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   744
 */
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   745
static int
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   746
parse_bootpath(char *bpath, char *outpath)
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   747
{
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   748
	char *slashp;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   749
	uint64_t objnum;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   750
	int error;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   751
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   752
	if (*bpath == 0 || *bpath == '/')
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   753
		return (EINVAL);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   754
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   755
	slashp = strchr(bpath, '/');
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   756
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   757
	/* if no '/', just return the pool name */
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   758
	if (slashp == NULL) {
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   759
		(void) strcpy(outpath, bpath);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   760
		return (0);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   761
	}
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   762
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   763
	if (error = str_to_uint64(slashp+1, &objnum))
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   764
		return (error);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   765
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   766
	*slashp = '\0';
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   767
	error = dsl_dsobj_to_dsname(bpath, objnum, outpath);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   768
	*slashp = '/';
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   769
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   770
	return (error);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   771
}
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   772
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   773
static int
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   774
zfs_mountroot(vfs_t *vfsp, enum whymountroot why)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   775
{
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   776
	int error = 0;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   777
	int ret = 0;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   778
	static int zfsrootdone = 0;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   779
	zfsvfs_t *zfsvfs = NULL;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   780
	znode_t *zp = NULL;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   781
	vnode_t *vp = NULL;
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   782
	char *zfs_bootpath;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   783
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   784
	ASSERT(vfsp);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   785
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   786
	/*
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   787
	 * The filesystem that we mount as root is defined in the
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   788
	 * "zfs-bootfs" property.
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   789
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   790
	if (why == ROOT_INIT) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   791
		if (zfsrootdone++)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   792
			return (EBUSY);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   793
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   794
		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(),
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   795
		    DDI_PROP_DONTPASS, "zfs-bootfs", &zfs_bootpath) !=
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   796
		    DDI_SUCCESS)
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   797
			return (EIO);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   798
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   799
		error = parse_bootpath(zfs_bootpath, rootfs.bo_name);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   800
		ddi_prop_free(zfs_bootpath);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   801
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   802
		if (error)
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   803
			return (error);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   804
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   805
		if (error = vfs_lock(vfsp))
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   806
			return (error);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   807
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   808
		if (error = zfs_domount(vfsp, rootfs.bo_name, CRED()))
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   809
			goto out;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   810
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   811
		zfsvfs = (zfsvfs_t *)vfsp->vfs_data;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   812
		ASSERT(zfsvfs);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   813
		if (error = zfs_zget(zfsvfs, zfsvfs->z_root, &zp))
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   814
			goto out;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   815
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   816
		vp = ZTOV(zp);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   817
		mutex_enter(&vp->v_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   818
		vp->v_flag |= VROOT;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   819
		mutex_exit(&vp->v_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   820
		rootvp = vp;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   821
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   822
		/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   823
		 * The zfs_zget call above returns with a hold on vp, we release
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   824
		 * it here.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   825
		 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   826
		VN_RELE(vp);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   827
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   828
		/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   829
		 * Mount root as readonly initially, it will be remouted
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   830
		 * read/write by /lib/svc/method/fs-usr.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   831
		 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   832
		readonly_changed_cb(vfsp->vfs_data, B_TRUE);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   833
		vfs_add((struct vnode *)0, vfsp,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   834
		    (vfsp->vfs_flag & VFS_RDONLY) ? MS_RDONLY : 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   835
out:
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   836
		vfs_unlock(vfsp);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   837
		ret = (error) ? error : 0;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   838
		return (ret);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   839
	} else if (why == ROOT_REMOUNT) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   840
		readonly_changed_cb(vfsp->vfs_data, B_FALSE);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   841
		vfsp->vfs_flag |= VFS_REMOUNT;
4596
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   842
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   843
		/* refresh mount options */
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   844
		zfs_unregister_callbacks(vfsp->vfs_data);
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   845
		return (zfs_register_callbacks(vfsp));
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   846
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   847
	} else if (why == ROOT_UNMOUNT) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   848
		zfs_unregister_callbacks((zfsvfs_t *)vfsp->vfs_data);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   849
		(void) zfs_sync(vfsp, 0, 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   850
		return (0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   851
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   852
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   853
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   854
	 * if "why" is equal to anything else other than ROOT_INIT,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   855
	 * ROOT_REMOUNT, or ROOT_UNMOUNT, we do not support it.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   856
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   857
	return (ENOTSUP);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   858
}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   859
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   860
/*ARGSUSED*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   861
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   862
zfs_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   863
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   864
	char		*osname;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   865
	pathname_t	spn;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   866
	int		error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   867
	uio_seg_t	fromspace = (uap->flags & MS_SYSSPACE) ?
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3898
diff changeset
   868
	    UIO_SYSSPACE : UIO_USERSPACE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   869
	int		canwrite;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   870
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   871
	if (mvp->v_type != VDIR)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   872
		return (ENOTDIR);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   873
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   874
	mutex_enter(&mvp->v_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   875
	if ((uap->flags & MS_REMOUNT) == 0 &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   876
	    (uap->flags & MS_OVERLAY) == 0 &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   877
	    (mvp->v_count != 1 || (mvp->v_flag & VROOT))) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   878
		mutex_exit(&mvp->v_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   879
		return (EBUSY);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   880
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   881
	mutex_exit(&mvp->v_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   882
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   883
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   884
	 * ZFS does not support passing unparsed data in via MS_DATA.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   885
	 * Users should use the MS_OPTIONSTR interface; this means
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   886
	 * that all option parsing is already done and the options struct
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   887
	 * can be interrogated.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   888
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   889
	if ((uap->flags & MS_DATA) && uap->datalen > 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   890
		return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   891
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   892
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   893
	 * Get the objset name (the "special" mount argument).
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   894
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   895
	if (error = pn_get(uap->spec, fromspace, &spn))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   896
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   897
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   898
	osname = spn.pn_path;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   899
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   900
	/*
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   901
	 * Check for mount privilege?
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   902
	 *
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   903
	 * If we don't have privilege then see if
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   904
	 * we have local permission to allow it
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   905
	 */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   906
	error = secpolicy_fs_mount(cr, mvp, vfsp);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   907
	if (error) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   908
		error = dsl_deleg_access(osname, ZFS_DELEG_PERM_MOUNT, cr);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   909
		if (error == 0) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   910
			vattr_t		vattr;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   911
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   912
			/*
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   913
			 * Make sure user is the owner of the mount point
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   914
			 * or has sufficient privileges.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   915
			 */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   916
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   917
			vattr.va_mask = AT_UID;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   918
4614
58fcfc586435 6578215 zfs_mount() needs to handle GETATTR failures better.
marks
parents: 4596
diff changeset
   919
			if (error = VOP_GETATTR(mvp, &vattr, 0, cr)) {
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   920
				goto out;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   921
			}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   922
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   923
			if (error = secpolicy_vnode_owner(cr, vattr.va_uid)) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   924
				goto out;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   925
			}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   926
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   927
			if (error = VOP_ACCESS(mvp, VWRITE, 0, cr)) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   928
				goto out;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   929
			}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   930
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   931
			secpolicy_fs_mount_clearopts(cr, vfsp);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   932
		} else {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   933
			goto out;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   934
		}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
   935
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   936
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   937
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   938
	 * Refuse to mount a filesystem if we are in a local zone and the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   939
	 * dataset is not visible.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   940
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   941
	if (!INGLOBALZONE(curproc) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   942
	    (!zone_dataset_visible(osname, &canwrite) || !canwrite)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   943
		error = EPERM;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   944
		goto out;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   945
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   946
4596
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   947
	/*
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   948
	 * When doing a remount, we simply refresh our temporary properties
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   949
	 * according to those options set in the current VFS options.
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   950
	 */
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   951
	if (uap->flags & MS_REMOUNT) {
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   952
		/* refresh mount options */
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   953
		zfs_unregister_callbacks(vfsp->vfs_data);
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   954
		error = zfs_register_callbacks(vfsp);
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   955
		goto out;
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   956
	}
3aa6e3b5dfca 6561658 xattrs aren't enabled on zfs root filesystem, weirdness with mount output
lling
parents: 4577
diff changeset
   957
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1488
diff changeset
   958
	error = zfs_domount(vfsp, osname, cr);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   959
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   960
out:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   961
	pn_free(&spn);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   962
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   963
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   964
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   965
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   966
zfs_statvfs(vfs_t *vfsp, struct statvfs64 *statp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   967
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   968
	zfsvfs_t *zfsvfs = vfsp->vfs_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   969
	dev32_t d32;
2885
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2676
diff changeset
   970
	uint64_t refdbytes, availbytes, usedobjs, availobjs;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   971
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   972
	ZFS_ENTER(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   973
2885
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2676
diff changeset
   974
	dmu_objset_space(zfsvfs->z_os,
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2676
diff changeset
   975
	    &refdbytes, &availbytes, &usedobjs, &availobjs);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   976
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   977
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   978
	 * The underlying storage pool actually uses multiple block sizes.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   979
	 * We report the fragsize as the smallest block size we support,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   980
	 * and we report our blocksize as the filesystem's maximum blocksize.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   981
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   982
	statp->f_frsize = 1UL << SPA_MINBLOCKSHIFT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   983
	statp->f_bsize = zfsvfs->z_max_blksz;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   984
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   985
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   986
	 * The following report "total" blocks of various kinds in the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   987
	 * file system, but reported in terms of f_frsize - the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   988
	 * "fragment" size.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   989
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   990
2885
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2676
diff changeset
   991
	statp->f_blocks = (refdbytes + availbytes) >> SPA_MINBLOCKSHIFT;
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2676
diff changeset
   992
	statp->f_bfree = availbytes >> SPA_MINBLOCKSHIFT;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   993
	statp->f_bavail = statp->f_bfree; /* no root reservation */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   994
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   995
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   996
	 * statvfs() should really be called statufs(), because it assumes
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   997
	 * static metadata.  ZFS doesn't preallocate files, so the best
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   998
	 * we can do is report the max that could possibly fit in f_files,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   999
	 * and that minus the number actually used in f_ffree.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1000
	 * For f_ffree, report the smaller of the number of object available
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1001
	 * and the number of blocks (each object will take at least a block).
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1002
	 */
2885
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2676
diff changeset
  1003
	statp->f_ffree = MIN(availobjs, statp->f_bfree);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1004
	statp->f_favail = statp->f_ffree;	/* no "root reservation" */
2885
c0259887ebbc 6460059 zfs destroy <snapshot> leaves behind kruft
ahrens
parents: 2676
diff changeset
  1005
	statp->f_files = statp->f_ffree + usedobjs;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1006
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1007
	(void) cmpldev(&d32, vfsp->vfs_dev);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1008
	statp->f_fsid = d32;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1009
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1010
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1011
	 * We're a zfs filesystem.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1012
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1013
	(void) strcpy(statp->f_basetype, vfssw[vfsp->vfs_fstype].vsw_name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1014
1123
02a0390fbc7d 6363529 UNIX03/UNIX98 *vsx* CAPI.os/files/fstatvfs/T.fstatvfs 11 FAILS
marks
parents: 849
diff changeset
  1015
	statp->f_flag = vf_to_stf(vfsp->vfs_flag);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1016
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1017
	statp->f_namemax = ZFS_MAXNAMELEN;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1018
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1019
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1020
	 * We have all of 32 characters to stuff a string here.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1021
	 * Is there anything useful we could/should provide?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1022
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1023
	bzero(statp->f_fstr, sizeof (statp->f_fstr));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1024
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1025
	ZFS_EXIT(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1026
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1027
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1028
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1029
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1030
zfs_root(vfs_t *vfsp, vnode_t **vpp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1031
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1032
	zfsvfs_t *zfsvfs = vfsp->vfs_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1033
	znode_t *rootzp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1034
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1035
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1036
	ZFS_ENTER(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1037
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1038
	error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1039
	if (error == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1040
		*vpp = ZTOV(rootzp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1041
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1042
	ZFS_EXIT(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1043
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1044
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1045
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1046
/*
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1047
 * Teardown the zfsvfs::z_os.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1048
 *
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1049
 * Note, if 'unmounting' if FALSE, we return with the 'z_teardown_lock'
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1050
 * and 'z_teardown_inactive_lock' held.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1051
 */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1052
static int
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1053
zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1054
{
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1055
	objset_t *os = zfsvfs->z_os;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1056
	znode_t	*zp, *nextzp;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1057
	znode_t markerzp;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1058
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1059
	rrw_enter(&zfsvfs->z_teardown_lock, RW_WRITER, FTAG);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1060
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1061
	if (!unmounting) {
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1062
		/*
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1063
		 * We purge the parent filesystem's vfsp as the parent
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1064
		 * filesystem and all of its snapshots have their vnode's
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1065
		 * v_vfsp set to the parent's filesystem's vfsp.  Note,
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1066
		 * 'z_parent' is self referential for non-snapshots.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1067
		 */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1068
		(void) dnlc_purge_vfsp(zfsvfs->z_parent->z_vfs, 0);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1069
	}
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1070
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1071
	/*
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1072
	 * Close the zil. NB: Can't close the zil while zfs_inactive
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1073
	 * threads are blocked as zil_close can call zfs_inactive.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1074
	 */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1075
	if (zfsvfs->z_log) {
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1076
		zil_close(zfsvfs->z_log);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1077
		zfsvfs->z_log = NULL;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1078
	}
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1079
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1080
	rw_enter(&zfsvfs->z_teardown_inactive_lock, RW_WRITER);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1081
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1082
	/*
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1083
	 * If we are not unmounting (ie: online recv) and someone already
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1084
	 * unmounted this file system while we were doing the switcheroo,
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1085
	 * or a reopen of z_os failed then just bail out now.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1086
	 */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1087
	if (!unmounting && (zfsvfs->z_unmounted || zfsvfs->z_os == NULL)) {
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1088
		rw_exit(&zfsvfs->z_teardown_inactive_lock);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1089
		rrw_exit(&zfsvfs->z_teardown_lock, FTAG);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1090
		return (EIO);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1091
	}
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1092
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1093
	/*
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1094
	 * At this point there are no vops active, and any new vops will
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1095
	 * fail with EIO since we have z_teardown_lock for writer (only
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1096
	 * relavent for forced unmount).
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1097
	 *
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1098
	 * Release all holds on dbufs.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1099
	 * Note, the dmu can still callback via znode_pageout_func()
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1100
	 * which can zfs_znode_free() the znode.  So we lock
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1101
	 * z_all_znodes; search the list for a held dbuf; drop the lock
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1102
	 * (we know zp can't disappear if we hold a dbuf lock) then
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1103
	 * regrab the lock and restart.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1104
	 *
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1105
	 * Since we have to restart the search after finding each held dbuf,
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1106
	 * we do two things to speed up searching: we insert a dummy znode
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1107
	 * ('markerzp') to detect the original tail of the list, and move
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1108
	 * non-held znodes to the end of the list.  Once we hit 'markerzp',
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1109
	 * we know we've looked at each znode and can break out.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1110
	 */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1111
	mutex_enter(&zfsvfs->z_znodes_lock);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1112
	list_insert_tail(&zfsvfs->z_all_znodes, &markerzp);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1113
	for (zp = list_head(&zfsvfs->z_all_znodes); zp != &markerzp;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1114
	    zp = nextzp) {
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1115
		nextzp = list_next(&zfsvfs->z_all_znodes, zp);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1116
		if (zp->z_dbuf_held) {
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1117
			/* dbufs should only be held when force unmounting */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1118
			zp->z_dbuf_held = 0;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1119
			mutex_exit(&zfsvfs->z_znodes_lock);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1120
			dmu_buf_rele(zp->z_dbuf, NULL);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1121
			/* Start again */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1122
			mutex_enter(&zfsvfs->z_znodes_lock);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1123
			nextzp = list_head(&zfsvfs->z_all_znodes);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1124
		} else {
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1125
			list_remove(&zfsvfs->z_all_znodes, zp);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1126
			list_insert_tail(&zfsvfs->z_all_znodes, zp);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1127
		}
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1128
	}
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1129
	list_remove(&zfsvfs->z_all_znodes, &markerzp);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1130
	mutex_exit(&zfsvfs->z_znodes_lock);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1131
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1132
	/*
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1133
	 * If we are unmounting, set the unmounted flag and let new vops
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1134
	 * unblock.  zfs_inactive will have the unmounted behavior, and all
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1135
	 * other vops will fail with EIO.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1136
	 */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1137
	if (unmounting) {
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1138
		zfsvfs->z_unmounted = B_TRUE;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1139
		rrw_exit(&zfsvfs->z_teardown_lock, FTAG);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1140
		rw_exit(&zfsvfs->z_teardown_inactive_lock);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1141
	}
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1142
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1143
	/*
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1144
	 * z_os will be NULL if there was an error in attempting to reopen
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1145
	 * zfsvfs, so just return as the properties had already been
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1146
	 * unregistered and cached data had been evicted before.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1147
	 */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1148
	if (zfsvfs->z_os == NULL)
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1149
		return (0);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1150
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1151
	/*
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1152
	 * Unregister properties.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1153
	 */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1154
	zfs_unregister_callbacks(zfsvfs);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1155
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1156
	/*
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1157
	 * Evict cached data
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1158
	 */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1159
	(void) dmu_objset_evict_dbufs(os);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1160
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1161
	return (0);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1162
}
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1163
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1164
/*ARGSUSED*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1165
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1166
zfs_umount(vfs_t *vfsp, int fflag, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1167
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1168
	zfsvfs_t *zfsvfs = vfsp->vfs_data;
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1169
	objset_t *os;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1170
	int ret;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1171
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
  1172
	ret = secpolicy_fs_unmount(cr, vfsp);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
  1173
	if (ret) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
  1174
		ret = dsl_deleg_access((char *)refstr_value(vfsp->vfs_resource),
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
  1175
		    ZFS_DELEG_PERM_MOUNT, cr);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
  1176
		if (ret)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
  1177
			return (ret);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
  1178
	}
1484
d330e98f8ed7 6350001 ZFS lookup performance still much slower than UFS : help tar : help spec SFS
ek110237
parents: 1298
diff changeset
  1179
4736
f8714efb3e12 6509628 unmount of a snapshot (from 'zfs destroy') is slow
ek110237
parents: 4614
diff changeset
  1180
	/*
f8714efb3e12 6509628 unmount of a snapshot (from 'zfs destroy') is slow
ek110237
parents: 4614
diff changeset
  1181
	 * We purge the parent filesystem's vfsp as the parent filesystem
f8714efb3e12 6509628 unmount of a snapshot (from 'zfs destroy') is slow
ek110237
parents: 4614
diff changeset
  1182
	 * and all of its snapshots have their vnode's v_vfsp set to the
f8714efb3e12 6509628 unmount of a snapshot (from 'zfs destroy') is slow
ek110237
parents: 4614
diff changeset
  1183
	 * parent's filesystem's vfsp.  Note, 'z_parent' is self
f8714efb3e12 6509628 unmount of a snapshot (from 'zfs destroy') is slow
ek110237
parents: 4614
diff changeset
  1184
	 * referential for non-snapshots.
f8714efb3e12 6509628 unmount of a snapshot (from 'zfs destroy') is slow
ek110237
parents: 4614
diff changeset
  1185
	 */
f8714efb3e12 6509628 unmount of a snapshot (from 'zfs destroy') is slow
ek110237
parents: 4614
diff changeset
  1186
	(void) dnlc_purge_vfsp(zfsvfs->z_parent->z_vfs, 0);
1484
d330e98f8ed7 6350001 ZFS lookup performance still much slower than UFS : help tar : help spec SFS
ek110237
parents: 1298
diff changeset
  1187
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1188
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1189
	 * Unmount any snapshots mounted under .zfs before unmounting the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1190
	 * dataset itself.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1191
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1192
	if (zfsvfs->z_ctldir != NULL &&
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
  1193
	    (ret = zfsctl_umount_snapshots(vfsp, fflag, cr)) != 0) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1194
		return (ret);
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 4480
diff changeset
  1195
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1196
4787
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1197
	if (!(fflag & MS_FORCE)) {
4480
0976678e58c5 6544140 assertion failed: err == 0 (0x11 == 0x0), file: ../../common/fs/zfs/zfs_znode.c, line: 555
gw25295
parents: 3912
diff changeset
  1198
		/*
4787
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1199
		 * Check the number of active vnodes in the file system.
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1200
		 * Our count is maintained in the vfs structure, but the
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1201
		 * number is off by 1 to indicate a hold on the vfs
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1202
		 * structure itself.
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1203
		 *
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1204
		 * The '.zfs' directory maintains a reference of its
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1205
		 * own, and any active references underneath are
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1206
		 * reflected in the vnode count.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1207
		 */
4787
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1208
		if (zfsvfs->z_ctldir == NULL) {
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1209
			if (vfsp->vfs_count > 1)
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1210
				return (EBUSY);
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1211
		} else {
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1212
			if (vfsp->vfs_count > 2 ||
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1213
			    zfsvfs->z_ctldir->v_count > 1)
4787
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1214
				return (EBUSY);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1215
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1216
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1217
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1218
	vfsp->vfs_flag |= VFS_UNMOUNTED;
4787
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1219
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1220
	VERIFY(zfsvfs_teardown(zfsvfs, B_TRUE) == 0);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1221
	os = zfsvfs->z_os;
4787
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1222
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1223
	/*
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1224
	 * z_os will be NULL if there was an error in
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1225
	 * attempting to reopen zfsvfs.
4787
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1226
	 */
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1227
	if (os != NULL) {
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1228
		/*
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1229
		 * Unset the objset user_ptr.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1230
		 */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1231
		mutex_enter(&os->os->os_user_ptr_lock);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1232
		dmu_objset_set_user(os, NULL);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1233
		mutex_exit(&os->os->os_user_ptr_lock);
4787
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1234
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1235
		/*
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1236
		 * Finally close the objset
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1237
		 */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1238
		dmu_objset_close(os);
4787
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1239
	}
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1240
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1241
	/*
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1242
	 * We can now safely destroy the '.zfs' directory node.
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1243
	 */
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1244
	if (zfsvfs->z_ctldir != NULL)
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1245
		zfsctl_destroy(zfsvfs);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1246
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1247
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1248
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1249
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1250
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1251
zfs_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1252
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1253
	zfsvfs_t	*zfsvfs = vfsp->vfs_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1254
	znode_t		*zp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1255
	uint64_t	object = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1256
	uint64_t	fid_gen = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1257
	uint64_t	gen_mask;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1258
	uint64_t	zp_gen;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1259
	int 		i, err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1260
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1261
	*vpp = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1262
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1263
	ZFS_ENTER(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1264
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1265
	if (fidp->fid_len == LONG_FID_LEN) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1266
		zfid_long_t	*zlfid = (zfid_long_t *)fidp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1267
		uint64_t	objsetid = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1268
		uint64_t	setgen = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1269
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1270
		for (i = 0; i < sizeof (zlfid->zf_setid); i++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1271
			objsetid |= ((uint64_t)zlfid->zf_setid[i]) << (8 * i);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1272
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1273
		for (i = 0; i < sizeof (zlfid->zf_setgen); i++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1274
			setgen |= ((uint64_t)zlfid->zf_setgen[i]) << (8 * i);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1275
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1276
		ZFS_EXIT(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1277
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1278
		err = zfsctl_lookup_objset(vfsp, objsetid, &zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1279
		if (err)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1280
			return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1281
		ZFS_ENTER(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1282
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1283
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1284
	if (fidp->fid_len == SHORT_FID_LEN || fidp->fid_len == LONG_FID_LEN) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1285
		zfid_short_t	*zfid = (zfid_short_t *)fidp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1286
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1287
		for (i = 0; i < sizeof (zfid->zf_object); i++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1288
			object |= ((uint64_t)zfid->zf_object[i]) << (8 * i);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1289
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1290
		for (i = 0; i < sizeof (zfid->zf_gen); i++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1291
			fid_gen |= ((uint64_t)zfid->zf_gen[i]) << (8 * i);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1292
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1293
		ZFS_EXIT(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1294
		return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1295
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1296
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1297
	/* A zero fid_gen means we are in the .zfs control directories */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1298
	if (fid_gen == 0 &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1299
	    (object == ZFSCTL_INO_ROOT || object == ZFSCTL_INO_SNAPDIR)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1300
		*vpp = zfsvfs->z_ctldir;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1301
		ASSERT(*vpp != NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1302
		if (object == ZFSCTL_INO_SNAPDIR) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1303
			VERIFY(zfsctl_root_lookup(*vpp, "snapshot", vpp, NULL,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1304
			    0, NULL, NULL) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1305
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1306
			VN_HOLD(*vpp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1307
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1308
		ZFS_EXIT(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1309
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1310
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1311
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1312
	gen_mask = -1ULL >> (64 - 8 * i);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1313
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1314
	dprintf("getting %llu [%u mask %llx]\n", object, fid_gen, gen_mask);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1315
	if (err = zfs_zget(zfsvfs, object, &zp)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1316
		ZFS_EXIT(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1317
		return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1318
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1319
	zp_gen = zp->z_phys->zp_gen & gen_mask;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1320
	if (zp_gen == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1321
		zp_gen = 1;
3461
c19b22f347d6 6514331 in-memory delete queue is not needed
ahrens
parents: 3265
diff changeset
  1322
	if (zp->z_unlinked || zp_gen != fid_gen) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1323
		dprintf("znode gen (%u) != fid gen (%u)\n", zp_gen, fid_gen);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1324
		VN_RELE(ZTOV(zp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1325
		ZFS_EXIT(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1326
		return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1327
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1328
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1329
	*vpp = ZTOV(zp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1330
	ZFS_EXIT(zfsvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1331
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1332
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1333
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1334
/*
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1335
 * Block out VOPs and close zfsvfs_t::z_os
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1336
 *
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1337
 * Note, if successful, then we return with the 'z_teardown_lock' and
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1338
 * 'z_teardown_inactive_lock' write held.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1339
 */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1340
int
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1341
zfs_suspend_fs(zfsvfs_t *zfsvfs, char *name, int *mode)
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1342
{
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1343
	int error;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1344
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1345
	if ((error = zfsvfs_teardown(zfsvfs, B_FALSE)) != 0)
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1346
		return (error);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1347
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1348
	*mode = zfsvfs->z_os->os_mode;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1349
	dmu_objset_name(zfsvfs->z_os, name);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1350
	dmu_objset_close(zfsvfs->z_os);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1351
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1352
	return (0);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1353
}
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1354
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1355
/*
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1356
 * Reopen zfsvfs_t::z_os and release VOPs.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1357
 */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1358
int
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1359
zfs_resume_fs(zfsvfs_t *zfsvfs, const char *osname, int mode)
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1360
{
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1361
	int err;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1362
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1363
	ASSERT(RRW_WRITE_HELD(&zfsvfs->z_teardown_lock));
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1364
	ASSERT(RW_WRITE_HELD(&zfsvfs->z_teardown_inactive_lock));
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1365
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1366
	err = dmu_objset_open(osname, DMU_OST_ZFS, mode, &zfsvfs->z_os);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1367
	if (err) {
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1368
		zfsvfs->z_os = NULL;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1369
	} else {
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1370
		znode_t *zp;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1371
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1372
		VERIFY(zfsvfs_setup(zfsvfs, B_FALSE) == 0);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1373
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1374
		/*
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1375
		 * Attempt to re-establish all the active znodes with
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1376
		 * their dbufs.  If a zfs_rezget() fails, then we'll let
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1377
		 * any potential callers discover that via ZFS_ENTER_VERIFY_VP
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1378
		 * when they try to use their znode.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1379
		 */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1380
		mutex_enter(&zfsvfs->z_znodes_lock);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1381
		for (zp = list_head(&zfsvfs->z_all_znodes); zp;
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1382
		    zp = list_next(&zfsvfs->z_all_znodes, zp)) {
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1383
			ASSERT(!zp->z_dbuf_held);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1384
			(void) zfs_rezget(zp);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1385
		}
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1386
		mutex_exit(&zfsvfs->z_znodes_lock);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1387
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1388
	}
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1389
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1390
	/* release the VOPs */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1391
	rw_exit(&zfsvfs->z_teardown_inactive_lock);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1392
	rrw_exit(&zfsvfs->z_teardown_lock, FTAG);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1393
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1394
	if (err) {
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1395
		/*
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1396
		 * Since we couldn't reopen zfsvfs::z_os, force
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1397
		 * unmount this file system.
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1398
		 */
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1399
		if (vn_vfswlock(zfsvfs->z_vfs->vfs_vnodecovered) == 0)
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1400
			(void) dounmount(zfsvfs->z_vfs, MS_FORCE, CRED());
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1401
	}
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1402
	return (err);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1403
}
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1404
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1405
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1406
zfs_freevfs(vfs_t *vfsp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1407
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1408
	zfsvfs_t *zfsvfs = vfsp->vfs_data;
4831
41ec732c6d9f 6584470 zdb needs to initialize the bpl_lock mutex
gw25295
parents: 4787
diff changeset
  1409
	int i;
41ec732c6d9f 6584470 zdb needs to initialize the bpl_lock mutex
gw25295
parents: 4787
diff changeset
  1410
41ec732c6d9f 6584470 zdb needs to initialize the bpl_lock mutex
gw25295
parents: 4787
diff changeset
  1411
	for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
41ec732c6d9f 6584470 zdb needs to initialize the bpl_lock mutex
gw25295
parents: 4787
diff changeset
  1412
		mutex_destroy(&zfsvfs->z_hold_mtx[i]);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1413
4787
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 4736
diff changeset
  1414
	mutex_destroy(&zfsvfs->z_znodes_lock);
4831
41ec732c6d9f 6584470 zdb needs to initialize the bpl_lock mutex
gw25295
parents: 4787
diff changeset
  1415
	list_destroy(&zfsvfs->z_all_znodes);
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1416
	rrw_destroy(&zfsvfs->z_teardown_lock);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 5147
diff changeset
  1417
	rw_destroy(&zfsvfs->z_teardown_inactive_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1418
	kmem_free(zfsvfs, sizeof (zfsvfs_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1419
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1420
	atomic_add_32(&zfs_active_fs_count, -1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1421
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1422
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1423
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1424
 * VFS_INIT() initialization.  Note that there is no VFS_FINI(),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1425
 * so we can't safely do any non-idempotent initialization here.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1426
 * Leave that to zfs_init() and zfs_fini(), which are called
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1427
 * from the module's _init() and _fini() entry points.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1428
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1429
/*ARGSUSED*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1430
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1431
zfs_vfsinit(int fstype, char *name)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1432
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1433
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1434
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1435
	zfsfstype = fstype;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1436
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1437
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1438
	 * Setup vfsops and vnodeops tables.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1439
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1440
	error = vfs_setfsops(fstype, zfs_vfsops_template, &zfs_vfsops);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1441
	if (error != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1442
		cmn_err(CE_WARN, "zfs: bad vfs ops template");
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1443
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1444
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1445
	error = zfs_create_op_tables();
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1446
	if (error) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1447
		zfs_remove_op_tables();
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1448
		cmn_err(CE_WARN, "zfs: bad vnode ops template");
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1449
		(void) vfs_freevfsops_by_type(zfsfstype);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1450
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1451
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1452
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1453
	mutex_init(&zfs_dev_mtx, NULL, MUTEX_DEFAULT, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1454
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1455
	/*
849
8d799fd81a9b 6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents: 789
diff changeset
  1456
	 * Unique major number for all zfs mounts.
8d799fd81a9b 6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents: 789
diff changeset
  1457
	 * If we run out of 32-bit minors, we'll getudev() another major.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1458
	 */
849
8d799fd81a9b 6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents: 789
diff changeset
  1459
	zfs_major = ddi_name_to_major(ZFS_DRIVER);
8d799fd81a9b 6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents: 789
diff changeset
  1460
	zfs_minor = ZFS_MIN_MINOR;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1461
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1462
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1463
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1464
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1465
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1466
zfs_init(void)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1467
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1468
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1469
	 * Initialize .zfs directory structures
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1470
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1471
	zfsctl_init();
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1472
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1473
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1474
	 * Initialize znode cache, vnode ops, etc...
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1475
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1476
	zfs_znode_init();
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1477
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1478
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1479
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1480
zfs_fini(void)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1481
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1482
	zfsctl_fini();
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1483
	zfs_znode_fini();
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1484
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1485
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1486
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1487
zfs_busy(void)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1488
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1489
	return (zfs_active_fs_count != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1490
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1491
4577
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1492
int
5147
5e950ccc9585 6596190 "zfs list" is slow due to version property
rm160521
parents: 4944
diff changeset
  1493
zfs_get_version(objset_t *os, uint64_t *version)
4577
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1494
{
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1495
	int error;
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1496
5147
5e950ccc9585 6596190 "zfs list" is slow due to version property
rm160521
parents: 4944
diff changeset
  1497
	error = zap_lookup(os, MASTER_NODE_OBJ, ZPL_VERSION_STR, 8, 1, version);
4577
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1498
	return (error);
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1499
}
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1500
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1501
int
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1502
zfs_set_version(const char *name, uint64_t newvers)
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1503
{
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1504
	int error;
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1505
	objset_t *os;
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1506
	dmu_tx_t *tx;
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1507
	uint64_t curvers;
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1508
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1509
	/*
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1510
	 * XXX for now, require that the filesystem be unmounted.  Would
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1511
	 * be nice to find the zfsvfs_t and just update that if
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1512
	 * possible.
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1513
	 */
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1514
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1515
	if (newvers < ZPL_VERSION_INITIAL || newvers > ZPL_VERSION)
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1516
		return (EINVAL);
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1517
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1518
	error = dmu_objset_open(name, DMU_OST_ZFS, DS_MODE_PRIMARY, &os);
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1519
	if (error)
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1520
		return (error);
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1521
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1522
	error = zap_lookup(os, MASTER_NODE_OBJ, ZPL_VERSION_STR,
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1523
	    8, 1, &curvers);
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1524
	if (error)
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1525
		goto out;
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1526
	if (newvers < curvers) {
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1527
		error = EINVAL;
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1528
		goto out;
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1529
	}
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1530
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1531
	tx = dmu_tx_create(os);
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1532
	dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, 0, ZPL_VERSION_STR);
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1533
	error = dmu_tx_assign(tx, TXG_WAIT);
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1534
	if (error) {
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1535
		dmu_tx_abort(tx);
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1536
		goto out;
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1537
	}
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1538
	error = zap_update(os, MASTER_NODE_OBJ, ZPL_VERSION_STR, 8, 1,
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1539
	    &newvers, tx);
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1540
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1541
	spa_history_internal_log(LOG_DS_UPGRADE,
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1542
	    dmu_objset_spa(os), tx, CRED(),
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1543
	    "oldver=%llu newver=%llu dataset = %llu", curvers, newvers,
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1544
	    dmu_objset_id(os));
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1545
	dmu_tx_commit(tx);
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1546
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1547
out:
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1548
	dmu_objset_close(os);
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1549
	return (error);
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1550
}
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1551
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1552
static vfsdef_t vfw = {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1553
	VFSDEF_VERSION,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1554
	MNTTYPE_ZFS,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1555
	zfs_vfsinit,
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 1484
diff changeset
  1556
	VSW_HASPROTO|VSW_CANRWRO|VSW_CANREMOUNT|VSW_VOLATILEDEV|VSW_STATS,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1557
	&zfs_mntopts
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1558
};
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1559
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1560
struct modlfs zfs_modlfs = {
4577
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4543
diff changeset
  1561
	&mod_fsops, "ZFS filesystem version " SPA_VERSION_STRING, &vfw
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1562
};