usr/src/uts/common/fs/zfs/vdev.c
author eschrock
Mon, 12 Jun 2006 08:20:57 -0700
changeset 2174 73de7a781492
parent 2082 76b439ec3ac1
child 2237 45affe88ed99
permissions -rw-r--r--
6433717 offline devices should not be marked persistently unavailble 6436524 importing a bogus pool config can panic system 6436800 ztest failure: spa_vdev_attach() returns EBUSY instead of ENOTSUP
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
1485
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
     5
 * Common Development and Distribution License (the "License").
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
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
 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
    21
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    22
/*
1199
6e3b7bca3574 6366731 zfs and gcc don't get along anymore
eschrock
parents: 1175
diff changeset
    23
 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    24
 * Use is subject to license terms.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    25
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    26
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    27
#pragma ident	"%Z%%M%	%I%	%E% SMI"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
#include <sys/zfs_context.h>
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
    30
#include <sys/fm/fs/zfs.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
#include <sys/spa.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
#include <sys/spa_impl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
#include <sys/dmu.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    34
#include <sys/dmu_tx.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
#include <sys/vdev_impl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    36
#include <sys/uberblock_impl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
#include <sys/metaslab.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    38
#include <sys/metaslab_impl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    39
#include <sys/space_map.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    40
#include <sys/zio.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    41
#include <sys/zap.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    42
#include <sys/fs/zfs.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    43
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    45
 * Virtual device management.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
static vdev_ops_t *vdev_ops_table[] = {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
	&vdev_root_ops,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
	&vdev_raidz_ops,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    51
	&vdev_mirror_ops,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
	&vdev_replacing_ops,
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
    53
	&vdev_spare_ops,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    54
	&vdev_disk_ops,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
	&vdev_file_ops,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
	&vdev_missing_ops,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
	NULL
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
};
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    60
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    61
 * Given a vdev type, return the appropriate ops vector.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    62
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    63
static vdev_ops_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
vdev_getops(const char *type)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    65
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    66
	vdev_ops_t *ops, **opspp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    67
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
	for (opspp = vdev_ops_table; (ops = *opspp) != NULL; opspp++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
		if (strcmp(ops->vdev_op_type, type) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    70
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    71
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    72
	return (ops);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    73
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    74
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    75
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    76
 * Default asize function: return the MAX of psize with the asize of
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    77
 * all children.  This is what's used by anything other than RAID-Z.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    78
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    79
uint64_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    80
vdev_default_asize(vdev_t *vd, uint64_t psize)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    81
{
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
    82
	uint64_t asize = P2ROUNDUP(psize, 1ULL << vd->vdev_top->vdev_ashift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    83
	uint64_t csize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    84
	uint64_t c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    85
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    86
	for (c = 0; c < vd->vdev_children; c++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    87
		csize = vdev_psize_to_asize(vd->vdev_child[c], psize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    88
		asize = MAX(asize, csize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    89
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    90
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    91
	return (asize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    92
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    93
1175
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
    94
/*
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
    95
 * Get the replaceable or attachable device size.
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
    96
 * If the parent is a mirror or raidz, the replaceable size is the minimum
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
    97
 * psize of all its children. For the rest, just return our own psize.
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
    98
 *
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
    99
 * e.g.
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   100
 *			psize	rsize
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   101
 * root			-	-
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   102
 *	mirror/raidz	-	-
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   103
 *	    disk1	20g	20g
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   104
 *	    disk2 	40g	20g
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   105
 *	disk3 		80g	80g
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   106
 */
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   107
uint64_t
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   108
vdev_get_rsize(vdev_t *vd)
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   109
{
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   110
	vdev_t *pvd, *cvd;
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   111
	uint64_t c, rsize;
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   112
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   113
	pvd = vd->vdev_parent;
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   114
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   115
	/*
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   116
	 * If our parent is NULL or the root, just return our own psize.
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   117
	 */
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   118
	if (pvd == NULL || pvd->vdev_parent == NULL)
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   119
		return (vd->vdev_psize);
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   120
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   121
	rsize = 0;
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   122
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   123
	for (c = 0; c < pvd->vdev_children; c++) {
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   124
		cvd = pvd->vdev_child[c];
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   125
		rsize = MIN(rsize - 1, cvd->vdev_psize - 1) + 1;
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   126
	}
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   127
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   128
	return (rsize);
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   129
}
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
   130
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   131
vdev_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   132
vdev_lookup_top(spa_t *spa, uint64_t vdev)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   133
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   134
	vdev_t *rvd = spa->spa_root_vdev;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   135
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   136
	if (vdev < rvd->vdev_children)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   137
		return (rvd->vdev_child[vdev]);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   138
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   139
	return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   140
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   141
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   142
vdev_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   143
vdev_lookup_by_guid(vdev_t *vd, uint64_t guid)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   144
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   145
	int c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   146
	vdev_t *mvd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   147
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   148
	if (vd->vdev_guid == guid)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   149
		return (vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   150
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   151
	for (c = 0; c < vd->vdev_children; c++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   152
		if ((mvd = vdev_lookup_by_guid(vd->vdev_child[c], guid)) !=
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   153
		    NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   154
			return (mvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   155
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   156
	return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   157
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   158
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   159
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   160
vdev_add_child(vdev_t *pvd, vdev_t *cvd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   161
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   162
	size_t oldsize, newsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   163
	uint64_t id = cvd->vdev_id;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   164
	vdev_t **newchild;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   165
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   166
	ASSERT(spa_config_held(cvd->vdev_spa, RW_WRITER));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   167
	ASSERT(cvd->vdev_parent == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   168
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   169
	cvd->vdev_parent = pvd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   170
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   171
	if (pvd == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   172
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   173
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   174
	ASSERT(id >= pvd->vdev_children || pvd->vdev_child[id] == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   175
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   176
	oldsize = pvd->vdev_children * sizeof (vdev_t *);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   177
	pvd->vdev_children = MAX(pvd->vdev_children, id + 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   178
	newsize = pvd->vdev_children * sizeof (vdev_t *);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   179
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   180
	newchild = kmem_zalloc(newsize, KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   181
	if (pvd->vdev_child != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   182
		bcopy(pvd->vdev_child, newchild, oldsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   183
		kmem_free(pvd->vdev_child, oldsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   184
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   185
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   186
	pvd->vdev_child = newchild;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   187
	pvd->vdev_child[id] = cvd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   188
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   189
	cvd->vdev_top = (pvd->vdev_top ? pvd->vdev_top: cvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   190
	ASSERT(cvd->vdev_top->vdev_parent->vdev_parent == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   191
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   192
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   193
	 * Walk up all ancestors to update guid sum.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   194
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   195
	for (; pvd != NULL; pvd = pvd->vdev_parent)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   196
		pvd->vdev_guid_sum += cvd->vdev_guid_sum;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   197
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   198
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   199
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   200
vdev_remove_child(vdev_t *pvd, vdev_t *cvd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   201
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   202
	int c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   203
	uint_t id = cvd->vdev_id;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   204
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   205
	ASSERT(cvd->vdev_parent == pvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   206
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   207
	if (pvd == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   208
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   209
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   210
	ASSERT(id < pvd->vdev_children);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   211
	ASSERT(pvd->vdev_child[id] == cvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   212
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   213
	pvd->vdev_child[id] = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   214
	cvd->vdev_parent = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   215
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   216
	for (c = 0; c < pvd->vdev_children; c++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   217
		if (pvd->vdev_child[c])
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   218
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   219
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   220
	if (c == pvd->vdev_children) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   221
		kmem_free(pvd->vdev_child, c * sizeof (vdev_t *));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   222
		pvd->vdev_child = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   223
		pvd->vdev_children = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   224
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   225
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   226
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   227
	 * Walk up all ancestors to update guid sum.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   228
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   229
	for (; pvd != NULL; pvd = pvd->vdev_parent)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   230
		pvd->vdev_guid_sum -= cvd->vdev_guid_sum;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   231
}
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
 * Remove any holes in the child array.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   235
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   236
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   237
vdev_compact_children(vdev_t *pvd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   238
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   239
	vdev_t **newchild, *cvd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   240
	int oldc = pvd->vdev_children;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   241
	int newc, c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   242
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   243
	ASSERT(spa_config_held(pvd->vdev_spa, RW_WRITER));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   244
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   245
	for (c = newc = 0; c < oldc; c++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   246
		if (pvd->vdev_child[c])
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   247
			newc++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   248
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   249
	newchild = kmem_alloc(newc * sizeof (vdev_t *), KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   250
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   251
	for (c = newc = 0; c < oldc; c++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   252
		if ((cvd = pvd->vdev_child[c]) != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   253
			newchild[newc] = cvd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   254
			cvd->vdev_id = newc++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   255
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   256
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   257
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   258
	kmem_free(pvd->vdev_child, oldc * sizeof (vdev_t *));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   259
	pvd->vdev_child = newchild;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   260
	pvd->vdev_children = newc;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   261
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   262
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   263
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   264
 * Allocate and minimally initialize a vdev_t.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   265
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   266
static vdev_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   267
vdev_alloc_common(spa_t *spa, uint_t id, uint64_t guid, vdev_ops_t *ops)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   268
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   269
	vdev_t *vd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   270
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   271
	vd = kmem_zalloc(sizeof (vdev_t), KM_SLEEP);
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   272
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   273
	if (spa->spa_root_vdev == NULL) {
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   274
		ASSERT(ops == &vdev_root_ops);
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   275
		spa->spa_root_vdev = vd;
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   276
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   277
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   278
	if (guid == 0) {
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   279
		if (spa->spa_root_vdev == vd) {
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   280
			/*
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   281
			 * The root vdev's guid will also be the pool guid,
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   282
			 * which must be unique among all pools.
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   283
			 */
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   284
			while (guid == 0 || spa_guid_exists(guid, 0))
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   285
				guid = spa_get_random(-1ULL);
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   286
		} else {
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   287
			/*
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   288
			 * Any other vdev's guid must be unique within the pool.
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   289
			 */
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   290
			while (guid == 0 ||
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   291
			    spa_guid_exists(spa_guid(spa), guid))
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   292
				guid = spa_get_random(-1ULL);
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   293
		}
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   294
		ASSERT(!spa_guid_exists(spa_guid(spa), guid));
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   295
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   296
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   297
	vd->vdev_spa = spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   298
	vd->vdev_id = id;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   299
	vd->vdev_guid = guid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   300
	vd->vdev_guid_sum = guid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   301
	vd->vdev_ops = ops;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   302
	vd->vdev_state = VDEV_STATE_CLOSED;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   303
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   304
	mutex_init(&vd->vdev_dtl_lock, NULL, MUTEX_DEFAULT, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   305
	space_map_create(&vd->vdev_dtl_map, 0, -1ULL, 0, &vd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   306
	space_map_create(&vd->vdev_dtl_scrub, 0, -1ULL, 0, &vd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   307
	txg_list_create(&vd->vdev_ms_list,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   308
	    offsetof(struct metaslab, ms_txg_node));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   309
	txg_list_create(&vd->vdev_dtl_list,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   310
	    offsetof(struct vdev, vdev_dtl_node));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   311
	vd->vdev_stat.vs_timestamp = gethrtime();
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   312
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   313
	return (vd);
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
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   317
 * Free a vdev_t that has been removed from service.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   318
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   319
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   320
vdev_free_common(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   321
{
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   322
	spa_t *spa = vd->vdev_spa;
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   323
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   324
	if (vd->vdev_path)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   325
		spa_strfree(vd->vdev_path);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   326
	if (vd->vdev_devid)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   327
		spa_strfree(vd->vdev_devid);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   328
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   329
	if (vd->vdev_isspare)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   330
		spa_spare_remove(vd->vdev_guid);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   331
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   332
	txg_list_destroy(&vd->vdev_ms_list);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   333
	txg_list_destroy(&vd->vdev_dtl_list);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   334
	mutex_enter(&vd->vdev_dtl_lock);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   335
	space_map_unload(&vd->vdev_dtl_map);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   336
	space_map_destroy(&vd->vdev_dtl_map);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   337
	space_map_vacate(&vd->vdev_dtl_scrub, NULL, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   338
	space_map_destroy(&vd->vdev_dtl_scrub);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   339
	mutex_exit(&vd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   340
	mutex_destroy(&vd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   341
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   342
	if (vd == spa->spa_root_vdev)
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   343
		spa->spa_root_vdev = NULL;
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   344
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   345
	kmem_free(vd, sizeof (vdev_t));
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
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   349
 * Allocate a new vdev.  The 'alloctype' is used to control whether we are
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   350
 * creating a new vdev or loading an existing one - the behavior is slightly
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   351
 * different for each case.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   352
 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   353
int
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   354
vdev_alloc(spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent, uint_t id,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   355
    int alloctype)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   356
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   357
	vdev_ops_t *ops;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   358
	char *type;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   359
	uint64_t guid = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   360
	vdev_t *vd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   361
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   362
	ASSERT(spa_config_held(spa, RW_WRITER));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   363
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   364
	if (nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) != 0)
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   365
		return (EINVAL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   366
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   367
	if ((ops = vdev_getops(type)) == NULL)
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   368
		return (EINVAL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   369
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   370
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   371
	 * If this is a load, get the vdev guid from the nvlist.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   372
	 * Otherwise, vdev_alloc_common() will generate one for us.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   373
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   374
	if (alloctype == VDEV_ALLOC_LOAD) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   375
		uint64_t label_id;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   376
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   377
		if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID, &label_id) ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   378
		    label_id != id)
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   379
			return (EINVAL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   380
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   381
		if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) != 0)
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   382
			return (EINVAL);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   383
	} else if (alloctype == VDEV_ALLOC_SPARE) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   384
		if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   385
			return (EINVAL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   386
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   387
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   388
	/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   389
	 * The first allocated vdev must be of type 'root'.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   390
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   391
	if (ops != &vdev_root_ops && spa->spa_root_vdev == NULL)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   392
		return (EINVAL);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   393
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   394
	vd = vdev_alloc_common(spa, id, guid, ops);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   395
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   396
	if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &vd->vdev_path) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   397
		vd->vdev_path = spa_strdup(vd->vdev_path);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   398
	if (nvlist_lookup_string(nv, ZPOOL_CONFIG_DEVID, &vd->vdev_devid) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   399
		vd->vdev_devid = spa_strdup(vd->vdev_devid);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   400
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   401
	/*
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   402
	 * Set the nparity propery for RAID-Z vdevs.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   403
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   404
	if (ops == &vdev_raidz_ops) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   405
		if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NPARITY,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   406
		    &vd->vdev_nparity) == 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   407
			/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   408
			 * Currently, we can only support 2 parity devices.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   409
			 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   410
			if (vd->vdev_nparity > 2)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   411
				return (EINVAL);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   412
			/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   413
			 * Older versions can only support 1 parity device.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   414
			 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   415
			if (vd->vdev_nparity == 2 &&
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   416
			    spa_version(spa) < ZFS_VERSION_RAID6)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   417
				return (ENOTSUP);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   418
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   419
		} else {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   420
			/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   421
			 * We require the parity to be specified for SPAs that
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   422
			 * support multiple parity levels.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   423
			 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   424
			if (spa_version(spa) >= ZFS_VERSION_RAID6)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   425
				return (EINVAL);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   426
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   427
			/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   428
			 * Otherwise, we default to 1 parity device for RAID-Z.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   429
			 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   430
			vd->vdev_nparity = 1;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   431
		}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   432
	} else {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   433
		vd->vdev_nparity = 0;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   434
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   435
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   436
	/*
1171
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   437
	 * Set the whole_disk property.  If it's not specified, leave the value
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   438
	 * as -1.
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   439
	 */
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   440
	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   441
	    &vd->vdev_wholedisk) != 0)
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   442
		vd->vdev_wholedisk = -1ULL;
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   443
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   444
	/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   445
	 * Look for the 'not present' flag.  This will only be set if the device
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   446
	 * was not present at the time of import.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   447
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   448
	(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   449
	    &vd->vdev_not_present);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   450
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   451
	/*
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   452
	 * Get the alignment requirement.
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   453
	 */
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   454
	(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ASHIFT, &vd->vdev_ashift);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   455
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   456
	/*
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   457
	 * Look for the 'is_spare' flag.  If this is the case, then we are a
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   458
	 * repurposed hot spare.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   459
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   460
	(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_SPARE,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   461
	    &vd->vdev_isspare);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   462
	if (vd->vdev_isspare)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   463
		spa_spare_add(vd->vdev_guid);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   464
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   465
	/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   466
	 * If we're a top-level vdev, try to load the allocation parameters.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   467
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   468
	if (parent && !parent->vdev_parent && alloctype == VDEV_ALLOC_LOAD) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   469
		(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_METASLAB_ARRAY,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   470
		    &vd->vdev_ms_array);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   471
		(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_METASLAB_SHIFT,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   472
		    &vd->vdev_ms_shift);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   473
		(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ASIZE,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   474
		    &vd->vdev_asize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   475
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   476
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   477
	/*
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   478
	 * If we're a leaf vdev, try to load the DTL object and offline state.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   479
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   480
	if (vd->vdev_ops->vdev_op_leaf && alloctype == VDEV_ALLOC_LOAD) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   481
		(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_DTL,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   482
		    &vd->vdev_dtl.smo_object);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   483
		(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_OFFLINE,
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   484
		    &vd->vdev_offline);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   485
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   486
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   487
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   488
	 * Add ourselves to the parent's list of children.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   489
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   490
	vdev_add_child(parent, vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   491
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   492
	*vdp = vd;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   493
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   494
	return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   495
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   496
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   497
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   498
vdev_free(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   499
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   500
	int c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   501
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   502
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   503
	 * vdev_free() implies closing the vdev first.  This is simpler than
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   504
	 * trying to ensure complicated semantics for all callers.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   505
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   506
	vdev_close(vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   507
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   508
	ASSERT(!list_link_active(&vd->vdev_dirty_node));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   509
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   510
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   511
	 * Free all children.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   512
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   513
	for (c = 0; c < vd->vdev_children; c++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   514
		vdev_free(vd->vdev_child[c]);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   515
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   516
	ASSERT(vd->vdev_child == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   517
	ASSERT(vd->vdev_guid_sum == vd->vdev_guid);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   518
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   519
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   520
	 * Discard allocation state.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   521
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   522
	if (vd == vd->vdev_top)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   523
		vdev_metaslab_fini(vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   524
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   525
	ASSERT3U(vd->vdev_stat.vs_space, ==, 0);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   526
	ASSERT3U(vd->vdev_stat.vs_dspace, ==, 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   527
	ASSERT3U(vd->vdev_stat.vs_alloc, ==, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   528
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   529
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   530
	 * Remove this vdev from its parent's child list.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   531
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   532
	vdev_remove_child(vd->vdev_parent, vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   533
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   534
	ASSERT(vd->vdev_parent == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   535
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   536
	vdev_free_common(vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   537
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   538
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   539
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   540
 * Transfer top-level vdev state from svd to tvd.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   541
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   542
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   543
vdev_top_transfer(vdev_t *svd, vdev_t *tvd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   544
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   545
	spa_t *spa = svd->vdev_spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   546
	metaslab_t *msp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   547
	vdev_t *vd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   548
	int t;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   549
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   550
	ASSERT(tvd == tvd->vdev_top);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   551
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   552
	tvd->vdev_ms_array = svd->vdev_ms_array;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   553
	tvd->vdev_ms_shift = svd->vdev_ms_shift;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   554
	tvd->vdev_ms_count = svd->vdev_ms_count;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   555
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   556
	svd->vdev_ms_array = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   557
	svd->vdev_ms_shift = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   558
	svd->vdev_ms_count = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   559
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   560
	tvd->vdev_mg = svd->vdev_mg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   561
	tvd->vdev_ms = svd->vdev_ms;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   562
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   563
	svd->vdev_mg = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   564
	svd->vdev_ms = NULL;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   565
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   566
	if (tvd->vdev_mg != NULL)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   567
		tvd->vdev_mg->mg_vd = tvd;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   568
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   569
	tvd->vdev_stat.vs_alloc = svd->vdev_stat.vs_alloc;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   570
	tvd->vdev_stat.vs_space = svd->vdev_stat.vs_space;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   571
	tvd->vdev_stat.vs_dspace = svd->vdev_stat.vs_dspace;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   572
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   573
	svd->vdev_stat.vs_alloc = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   574
	svd->vdev_stat.vs_space = 0;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   575
	svd->vdev_stat.vs_dspace = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   576
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   577
	for (t = 0; t < TXG_SIZE; t++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   578
		while ((msp = txg_list_remove(&svd->vdev_ms_list, t)) != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   579
			(void) txg_list_add(&tvd->vdev_ms_list, msp, t);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   580
		while ((vd = txg_list_remove(&svd->vdev_dtl_list, t)) != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   581
			(void) txg_list_add(&tvd->vdev_dtl_list, vd, t);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   582
		if (txg_list_remove_this(&spa->spa_vdev_txg_list, svd, t))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   583
			(void) txg_list_add(&spa->spa_vdev_txg_list, tvd, t);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   584
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   585
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   586
	if (list_link_active(&svd->vdev_dirty_node)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   587
		vdev_config_clean(svd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   588
		vdev_config_dirty(tvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   589
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   590
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   591
	tvd->vdev_reopen_wanted = svd->vdev_reopen_wanted;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   592
	svd->vdev_reopen_wanted = 0;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   593
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   594
	tvd->vdev_deflate_ratio = svd->vdev_deflate_ratio;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   595
	svd->vdev_deflate_ratio = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   596
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   597
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   598
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   599
vdev_top_update(vdev_t *tvd, vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   600
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   601
	int c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   602
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   603
	if (vd == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   604
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   605
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   606
	vd->vdev_top = tvd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   607
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   608
	for (c = 0; c < vd->vdev_children; c++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   609
		vdev_top_update(tvd, vd->vdev_child[c]);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   610
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   611
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   612
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   613
 * Add a mirror/replacing vdev above an existing vdev.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   614
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   615
vdev_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   616
vdev_add_parent(vdev_t *cvd, vdev_ops_t *ops)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   617
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   618
	spa_t *spa = cvd->vdev_spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   619
	vdev_t *pvd = cvd->vdev_parent;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   620
	vdev_t *mvd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   621
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   622
	ASSERT(spa_config_held(spa, RW_WRITER));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   623
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   624
	mvd = vdev_alloc_common(spa, cvd->vdev_id, 0, ops);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   625
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   626
	mvd->vdev_asize = cvd->vdev_asize;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   627
	mvd->vdev_ashift = cvd->vdev_ashift;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   628
	mvd->vdev_state = cvd->vdev_state;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   629
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   630
	vdev_remove_child(pvd, cvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   631
	vdev_add_child(pvd, mvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   632
	cvd->vdev_id = mvd->vdev_children;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   633
	vdev_add_child(mvd, cvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   634
	vdev_top_update(cvd->vdev_top, cvd->vdev_top);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   635
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   636
	if (mvd == mvd->vdev_top)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   637
		vdev_top_transfer(cvd, mvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   638
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   639
	return (mvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   640
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   641
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   642
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   643
 * Remove a 1-way mirror/replacing vdev from the tree.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   644
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   645
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   646
vdev_remove_parent(vdev_t *cvd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   647
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   648
	vdev_t *mvd = cvd->vdev_parent;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   649
	vdev_t *pvd = mvd->vdev_parent;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   650
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   651
	ASSERT(spa_config_held(cvd->vdev_spa, RW_WRITER));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   652
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   653
	ASSERT(mvd->vdev_children == 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   654
	ASSERT(mvd->vdev_ops == &vdev_mirror_ops ||
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   655
	    mvd->vdev_ops == &vdev_replacing_ops ||
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   656
	    mvd->vdev_ops == &vdev_spare_ops);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   657
	cvd->vdev_ashift = mvd->vdev_ashift;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   658
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   659
	vdev_remove_child(mvd, cvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   660
	vdev_remove_child(pvd, mvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   661
	cvd->vdev_id = mvd->vdev_id;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   662
	vdev_add_child(pvd, cvd);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   663
	/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   664
	 * If we created a new toplevel vdev, then we need to change the child's
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   665
	 * vdev GUID to match the old toplevel vdev.  Otherwise, we could have
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   666
	 * detached an offline device, and when we go to import the pool we'll
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   667
	 * think we have two toplevel vdevs, instead of a different version of
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   668
	 * the same toplevel vdev.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   669
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   670
	if (cvd->vdev_top == cvd) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   671
		pvd->vdev_guid_sum -= cvd->vdev_guid;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   672
		cvd->vdev_guid_sum -= cvd->vdev_guid;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   673
		cvd->vdev_guid = mvd->vdev_guid;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   674
		cvd->vdev_guid_sum += mvd->vdev_guid;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   675
		pvd->vdev_guid_sum += cvd->vdev_guid;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   676
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   677
	vdev_top_update(cvd->vdev_top, cvd->vdev_top);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   678
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   679
	if (cvd == cvd->vdev_top)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   680
		vdev_top_transfer(mvd, cvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   681
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   682
	ASSERT(mvd->vdev_children == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   683
	vdev_free(mvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   684
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   685
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   686
int
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   687
vdev_metaslab_init(vdev_t *vd, uint64_t txg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   688
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   689
	spa_t *spa = vd->vdev_spa;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   690
	objset_t *mos = spa->spa_meta_objset;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   691
	metaslab_class_t *mc = spa_metaslab_class_select(spa);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   692
	uint64_t m;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   693
	uint64_t oldc = vd->vdev_ms_count;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   694
	uint64_t newc = vd->vdev_asize >> vd->vdev_ms_shift;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   695
	metaslab_t **mspp;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   696
	int error;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   697
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   698
	if (vd->vdev_ms_shift == 0)	/* not being allocated from yet */
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   699
		return (0);
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   700
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   701
	dprintf("%s oldc %llu newc %llu\n", vdev_description(vd), oldc, newc);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   702
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   703
	ASSERT(oldc <= newc);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   704
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   705
	if (vd->vdev_mg == NULL)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   706
		vd->vdev_mg = metaslab_group_create(mc, vd);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   707
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   708
	mspp = kmem_zalloc(newc * sizeof (*mspp), KM_SLEEP);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   709
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   710
	if (oldc != 0) {
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   711
		bcopy(vd->vdev_ms, mspp, oldc * sizeof (*mspp));
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   712
		kmem_free(vd->vdev_ms, oldc * sizeof (*mspp));
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   713
	}
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   714
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   715
	vd->vdev_ms = mspp;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   716
	vd->vdev_ms_count = newc;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   717
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   718
	for (m = oldc; m < newc; m++) {
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   719
		space_map_obj_t smo = { 0, 0, 0 };
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   720
		if (txg == 0) {
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   721
			uint64_t object = 0;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   722
			error = dmu_read(mos, vd->vdev_ms_array,
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   723
			    m * sizeof (uint64_t), sizeof (uint64_t), &object);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   724
			if (error)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   725
				return (error);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   726
			if (object != 0) {
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   727
				dmu_buf_t *db;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   728
				error = dmu_bonus_hold(mos, object, FTAG, &db);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   729
				if (error)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   730
					return (error);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   731
				ASSERT3U(db->db_size, ==, sizeof (smo));
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   732
				bcopy(db->db_data, &smo, db->db_size);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   733
				ASSERT3U(smo.smo_object, ==, object);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   734
				dmu_buf_rele(db, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   735
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   736
		}
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   737
		vd->vdev_ms[m] = metaslab_init(vd->vdev_mg, &smo,
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   738
		    m << vd->vdev_ms_shift, 1ULL << vd->vdev_ms_shift, txg);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   739
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   740
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   741
	return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   742
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   743
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   744
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   745
vdev_metaslab_fini(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   746
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   747
	uint64_t m;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   748
	uint64_t count = vd->vdev_ms_count;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   749
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   750
	if (vd->vdev_ms != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   751
		for (m = 0; m < count; m++)
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   752
			if (vd->vdev_ms[m] != NULL)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   753
				metaslab_fini(vd->vdev_ms[m]);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   754
		kmem_free(vd->vdev_ms, count * sizeof (metaslab_t *));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   755
		vd->vdev_ms = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   756
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   757
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   758
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   759
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   760
 * Prepare a virtual device for access.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   761
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   762
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   763
vdev_open(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   764
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   765
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   766
	vdev_knob_t *vk;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   767
	int c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   768
	uint64_t osize = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   769
	uint64_t asize, psize;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   770
	uint64_t ashift = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   771
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   772
	ASSERT(vd->vdev_state == VDEV_STATE_CLOSED ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   773
	    vd->vdev_state == VDEV_STATE_CANT_OPEN ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   774
	    vd->vdev_state == VDEV_STATE_OFFLINE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   775
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   776
	if (vd->vdev_fault_mode == VDEV_FAULT_COUNT)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   777
		vd->vdev_fault_arg >>= 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   778
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   779
		vd->vdev_fault_mode = VDEV_FAULT_NONE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   780
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   781
	vd->vdev_stat.vs_aux = VDEV_AUX_NONE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   782
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   783
	for (vk = vdev_knob_next(NULL); vk != NULL; vk = vdev_knob_next(vk)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   784
		uint64_t *valp = (uint64_t *)((char *)vd + vk->vk_offset);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   785
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   786
		*valp = vk->vk_default;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   787
		*valp = MAX(*valp, vk->vk_min);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   788
		*valp = MIN(*valp, vk->vk_max);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   789
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   790
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   791
	if (vd->vdev_ops->vdev_op_leaf) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   792
		vdev_cache_init(vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   793
		vdev_queue_init(vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   794
		vd->vdev_cache_active = B_TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   795
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   796
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   797
	if (vd->vdev_offline) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   798
		ASSERT(vd->vdev_children == 0);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   799
		vdev_set_state(vd, B_TRUE, VDEV_STATE_OFFLINE, VDEV_AUX_NONE);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   800
		return (ENXIO);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   801
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   802
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   803
	error = vd->vdev_ops->vdev_op_open(vd, &osize, &ashift);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   804
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   805
	if (zio_injection_enabled && error == 0)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   806
		error = zio_handle_device_injection(vd, ENXIO);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   807
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   808
	dprintf("%s = %d, osize %llu, state = %d\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   809
	    vdev_description(vd), error, osize, vd->vdev_state);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   810
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   811
	if (error) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   812
		vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   813
		    vd->vdev_stat.vs_aux);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   814
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   815
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   816
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   817
	vd->vdev_state = VDEV_STATE_HEALTHY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   818
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   819
	for (c = 0; c < vd->vdev_children; c++)
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   820
		if (vd->vdev_child[c]->vdev_state != VDEV_STATE_HEALTHY) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   821
			vdev_set_state(vd, B_TRUE, VDEV_STATE_DEGRADED,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   822
			    VDEV_AUX_NONE);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   823
			break;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   824
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   825
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   826
	osize = P2ALIGN(osize, (uint64_t)sizeof (vdev_label_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   827
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   828
	if (vd->vdev_children == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   829
		if (osize < SPA_MINDEVSIZE) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   830
			vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   831
			    VDEV_AUX_TOO_SMALL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   832
			return (EOVERFLOW);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   833
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   834
		psize = osize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   835
		asize = osize - (VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   836
	} else {
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   837
		if (vd->vdev_parent != NULL && osize < SPA_MINDEVSIZE -
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   838
		    (VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE)) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   839
			vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   840
			    VDEV_AUX_TOO_SMALL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   841
			return (EOVERFLOW);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   842
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   843
		psize = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   844
		asize = osize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   845
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   846
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   847
	vd->vdev_psize = psize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   848
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   849
	if (vd->vdev_asize == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   850
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   851
		 * This is the first-ever open, so use the computed values.
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   852
		 * For testing purposes, a higher ashift can be requested.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   853
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   854
		vd->vdev_asize = asize;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   855
		vd->vdev_ashift = MAX(ashift, vd->vdev_ashift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   856
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   857
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   858
		 * Make sure the alignment requirement hasn't increased.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   859
		 */
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   860
		if (ashift > vd->vdev_top->vdev_ashift) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   861
			vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   862
			    VDEV_AUX_BAD_LABEL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   863
			return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   864
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   865
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   866
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   867
		 * Make sure the device hasn't shrunk.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   868
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   869
		if (asize < vd->vdev_asize) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   870
			vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   871
			    VDEV_AUX_BAD_LABEL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   872
			return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   873
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   874
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   875
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   876
		 * If all children are healthy and the asize has increased,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   877
		 * then we've experienced dynamic LUN growth.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   878
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   879
		if (vd->vdev_state == VDEV_STATE_HEALTHY &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   880
		    asize > vd->vdev_asize) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   881
			vd->vdev_asize = asize;
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
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   885
	/*
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   886
	 * If this is a top-level vdev, compute the raidz-deflation
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   887
	 * ratio.  Note, we hard-code in 128k (1<<17) because it is the
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   888
	 * current "typical" blocksize.  Even if SPA_MAXBLOCKSIZE
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   889
	 * changes, this algorithm must never change, or we will
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   890
	 * inconsistently account for existing bp's.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   891
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   892
	if (vd->vdev_top == vd) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   893
		vd->vdev_deflate_ratio = (1<<17) /
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   894
		    (vdev_psize_to_asize(vd, 1<<17) >> SPA_MINBLOCKSHIFT);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   895
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   896
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   897
	/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   898
	 * This allows the ZFS DE to close cases appropriately.  If a device
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   899
	 * goes away and later returns, we want to close the associated case.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   900
	 * But it's not enough to simply post this only when a device goes from
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   901
	 * CANT_OPEN -> HEALTHY.  If we reboot the system and the device is
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   902
	 * back, we also need to close the case (otherwise we will try to replay
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   903
	 * it).  So we have to post this notifier every time.  Since this only
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   904
	 * occurs during pool open or error recovery, this should not be an
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   905
	 * issue.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   906
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   907
	zfs_post_ok(vd->vdev_spa, vd);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   908
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   909
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   910
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   911
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   912
/*
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   913
 * Called once the vdevs are all opened, this routine validates the label
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   914
 * contents.  This needs to be done before vdev_load() so that we don't
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   915
 * inadvertently do repair I/Os to the wrong device, and so that vdev_reopen()
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   916
 * won't succeed if the device has been changed underneath.
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   917
 *
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   918
 * This function will only return failure if one of the vdevs indicates that it
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   919
 * has since been destroyed or exported.  This is only possible if
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   920
 * /etc/zfs/zpool.cache was readonly at the time.  Otherwise, the vdev state
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   921
 * will be updated but the function will return 0.
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   922
 */
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   923
int
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   924
vdev_validate(vdev_t *vd)
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   925
{
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   926
	spa_t *spa = vd->vdev_spa;
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   927
	int c;
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   928
	nvlist_t *label;
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   929
	uint64_t guid;
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   930
	uint64_t state;
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   931
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   932
	for (c = 0; c < vd->vdev_children; c++)
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   933
		if (vdev_validate(vd->vdev_child[c]) != 0)
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   934
			return (-1);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   935
2174
73de7a781492 6433717 offline devices should not be marked persistently unavailble
eschrock
parents: 2082
diff changeset
   936
	/*
73de7a781492 6433717 offline devices should not be marked persistently unavailble
eschrock
parents: 2082
diff changeset
   937
	 * If the device has already failed, or was marked offline, don't do
73de7a781492 6433717 offline devices should not be marked persistently unavailble
eschrock
parents: 2082
diff changeset
   938
	 * any further validation.  Otherwise, label I/O will fail and we will
73de7a781492 6433717 offline devices should not be marked persistently unavailble
eschrock
parents: 2082
diff changeset
   939
	 * overwrite the previous state.
73de7a781492 6433717 offline devices should not be marked persistently unavailble
eschrock
parents: 2082
diff changeset
   940
	 */
73de7a781492 6433717 offline devices should not be marked persistently unavailble
eschrock
parents: 2082
diff changeset
   941
	if (vd->vdev_ops->vdev_op_leaf && !vdev_is_dead(vd)) {
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   942
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   943
		if ((label = vdev_label_read_config(vd)) == NULL) {
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   944
			vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   945
			    VDEV_AUX_BAD_LABEL);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   946
			return (0);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   947
		}
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   948
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   949
		if (nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_GUID,
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   950
		    &guid) != 0 || guid != spa_guid(spa)) {
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   951
			vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN,
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   952
			    VDEV_AUX_CORRUPT_DATA);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   953
			nvlist_free(label);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   954
			return (0);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   955
		}
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   956
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   957
		if (nvlist_lookup_uint64(label, ZPOOL_CONFIG_GUID,
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   958
		    &guid) != 0 || guid != vd->vdev_guid) {
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   959
			vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN,
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   960
			    VDEV_AUX_CORRUPT_DATA);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   961
			nvlist_free(label);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   962
			return (0);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   963
		}
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   964
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   965
		if (nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_STATE,
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   966
		    &state) != 0) {
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   967
			vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN,
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   968
			    VDEV_AUX_CORRUPT_DATA);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   969
			nvlist_free(label);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   970
			return (0);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   971
		}
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   972
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   973
		nvlist_free(label);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   974
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   975
		if (spa->spa_load_state == SPA_LOAD_OPEN &&
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   976
		    state != POOL_STATE_ACTIVE)
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   977
			return (-1);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   978
	}
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   979
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   980
	/*
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   981
	 * If we were able to open and validate a vdev that was previously
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   982
	 * marked permanently unavailable, clear that state now.
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   983
	 */
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   984
	if (vd->vdev_not_present)
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   985
		vd->vdev_not_present = 0;
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   987
	return (0);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   988
}
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   989
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   990
/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   991
 * Close a virtual device.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   992
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   993
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   994
vdev_close(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   995
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   996
	vd->vdev_ops->vdev_op_close(vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   997
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   998
	if (vd->vdev_cache_active) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   999
		vdev_cache_fini(vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1000
		vdev_queue_fini(vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1001
		vd->vdev_cache_active = B_FALSE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1002
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1003
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1004
	/*
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1005
	 * We record the previous state before we close it, so  that if we are
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1006
	 * doing a reopen(), we don't generate FMA ereports if we notice that
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1007
	 * it's still faulted.
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1008
	 */
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1009
	vd->vdev_prevstate = vd->vdev_state;
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1010
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1011
	if (vd->vdev_offline)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1012
		vd->vdev_state = VDEV_STATE_OFFLINE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1013
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1014
		vd->vdev_state = VDEV_STATE_CLOSED;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1015
	vd->vdev_stat.vs_aux = VDEV_AUX_NONE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1016
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1017
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1018
void
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1019
vdev_reopen(vdev_t *vd)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1020
{
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1021
	spa_t *spa = vd->vdev_spa;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1022
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1023
	ASSERT(spa_config_held(spa, RW_WRITER));
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1024
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1025
	vdev_close(vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1026
	(void) vdev_open(vd);
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
	 * Reassess root vdev's health.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1030
	 */
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1031
	vdev_propagate_state(spa->spa_root_vdev);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1032
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1033
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1034
int
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1035
vdev_create(vdev_t *vd, uint64_t txg, boolean_t isreplacing)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1036
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1037
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1038
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1039
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1040
	 * Normally, partial opens (e.g. of a mirror) are allowed.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1041
	 * For a create, however, we want to fail the request if
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1042
	 * there are any components we can't open.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1043
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1044
	error = vdev_open(vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1045
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1046
	if (error || vd->vdev_state != VDEV_STATE_HEALTHY) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1047
		vdev_close(vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1048
		return (error ? error : ENXIO);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1049
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1050
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1051
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1052
	 * Recursively initialize all labels.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1053
	 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1054
	if ((error = vdev_label_init(vd, txg, isreplacing)) != 0) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1055
		vdev_close(vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1056
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1057
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1058
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1059
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1060
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1061
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1062
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1063
 * The is the latter half of vdev_create().  It is distinct because it
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1064
 * involves initiating transactions in order to do metaslab creation.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1065
 * For creation, we want to try to create all vdevs at once and then undo it
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1066
 * if anything fails; this is much harder if we have pending transactions.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1067
 */
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1068
void
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1069
vdev_init(vdev_t *vd, uint64_t txg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1070
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1071
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1072
	 * Aim for roughly 200 metaslabs per vdev.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1073
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1074
	vd->vdev_ms_shift = highbit(vd->vdev_asize / 200);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1075
	vd->vdev_ms_shift = MAX(vd->vdev_ms_shift, SPA_MAXBLOCKSHIFT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1076
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1077
	/*
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1078
	 * Initialize the vdev's metaslabs.  This can't fail because
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1079
	 * there's nothing to read when creating all new metaslabs.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1080
	 */
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1081
	VERIFY(vdev_metaslab_init(vd, txg) == 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1082
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1083
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1084
void
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1085
vdev_dirty(vdev_t *vd, int flags, void *arg, uint64_t txg)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1086
{
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1087
	ASSERT(vd == vd->vdev_top);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1088
	ASSERT(ISP2(flags));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1089
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1090
	if (flags & VDD_METASLAB)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1091
		(void) txg_list_add(&vd->vdev_ms_list, arg, txg);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1092
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1093
	if (flags & VDD_DTL)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1094
		(void) txg_list_add(&vd->vdev_dtl_list, arg, txg);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1095
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1096
	(void) txg_list_add(&vd->vdev_spa->spa_vdev_txg_list, vd, txg);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1097
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1098
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1099
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1100
vdev_dtl_dirty(space_map_t *sm, uint64_t txg, uint64_t size)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1101
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1102
	mutex_enter(sm->sm_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1103
	if (!space_map_contains(sm, txg, size))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1104
		space_map_add(sm, txg, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1105
	mutex_exit(sm->sm_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1106
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1107
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1108
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1109
vdev_dtl_contains(space_map_t *sm, uint64_t txg, uint64_t size)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1110
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1111
	int dirty;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1112
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1113
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1114
	 * Quick test without the lock -- covers the common case that
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1115
	 * there are no dirty time segments.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1116
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1117
	if (sm->sm_space == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1118
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1119
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1120
	mutex_enter(sm->sm_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1121
	dirty = space_map_contains(sm, txg, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1122
	mutex_exit(sm->sm_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1123
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1124
	return (dirty);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1125
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1126
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1127
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1128
 * Reassess DTLs after a config change or scrub completion.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1129
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1130
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1131
vdev_dtl_reassess(vdev_t *vd, uint64_t txg, uint64_t scrub_txg, int scrub_done)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1132
{
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1133
	spa_t *spa = vd->vdev_spa;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1134
	int c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1135
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1136
	ASSERT(spa_config_held(spa, RW_WRITER));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1137
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1138
	if (vd->vdev_children == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1139
		mutex_enter(&vd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1140
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1141
		 * We're successfully scrubbed everything up to scrub_txg.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1142
		 * Therefore, excise all old DTLs up to that point, then
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1143
		 * fold in the DTLs for everything we couldn't scrub.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1144
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1145
		if (scrub_txg != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1146
			space_map_excise(&vd->vdev_dtl_map, 0, scrub_txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1147
			space_map_union(&vd->vdev_dtl_map, &vd->vdev_dtl_scrub);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1148
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1149
		if (scrub_done)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1150
			space_map_vacate(&vd->vdev_dtl_scrub, NULL, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1151
		mutex_exit(&vd->vdev_dtl_lock);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1152
		if (txg != 0)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1153
			vdev_dirty(vd->vdev_top, VDD_DTL, vd, txg);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1154
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1155
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1156
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1157
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1158
	 * Make sure the DTLs are always correct under the scrub lock.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1159
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1160
	if (vd == spa->spa_root_vdev)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1161
		mutex_enter(&spa->spa_scrub_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1162
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1163
	mutex_enter(&vd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1164
	space_map_vacate(&vd->vdev_dtl_map, NULL, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1165
	space_map_vacate(&vd->vdev_dtl_scrub, NULL, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1166
	mutex_exit(&vd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1167
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1168
	for (c = 0; c < vd->vdev_children; c++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1169
		vdev_t *cvd = vd->vdev_child[c];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1170
		vdev_dtl_reassess(cvd, txg, scrub_txg, scrub_done);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1171
		mutex_enter(&vd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1172
		space_map_union(&vd->vdev_dtl_map, &cvd->vdev_dtl_map);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1173
		space_map_union(&vd->vdev_dtl_scrub, &cvd->vdev_dtl_scrub);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1174
		mutex_exit(&vd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1175
	}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1176
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1177
	if (vd == spa->spa_root_vdev)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1178
		mutex_exit(&spa->spa_scrub_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1179
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1180
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1181
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1182
vdev_dtl_load(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1183
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1184
	spa_t *spa = vd->vdev_spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1185
	space_map_obj_t *smo = &vd->vdev_dtl;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1186
	objset_t *mos = spa->spa_meta_objset;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1187
	dmu_buf_t *db;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1188
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1189
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1190
	ASSERT(vd->vdev_children == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1191
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1192
	if (smo->smo_object == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1193
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1194
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1195
	if ((error = dmu_bonus_hold(mos, smo->smo_object, FTAG, &db)) != 0)
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1196
		return (error);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1197
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1198
	ASSERT3U(db->db_size, ==, sizeof (*smo));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1199
	bcopy(db->db_data, smo, db->db_size);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1200
	dmu_buf_rele(db, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1201
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1202
	mutex_enter(&vd->vdev_dtl_lock);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1203
	error = space_map_load(&vd->vdev_dtl_map, NULL, SM_ALLOC, smo, mos);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1204
	mutex_exit(&vd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1205
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1206
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1207
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1208
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1209
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1210
vdev_dtl_sync(vdev_t *vd, uint64_t txg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1211
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1212
	spa_t *spa = vd->vdev_spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1213
	space_map_obj_t *smo = &vd->vdev_dtl;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1214
	space_map_t *sm = &vd->vdev_dtl_map;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1215
	objset_t *mos = spa->spa_meta_objset;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1216
	space_map_t smsync;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1217
	kmutex_t smlock;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1218
	dmu_buf_t *db;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1219
	dmu_tx_t *tx;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1220
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1221
	dprintf("%s in txg %llu pass %d\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1222
	    vdev_description(vd), (u_longlong_t)txg, spa_sync_pass(spa));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1223
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1224
	tx = dmu_tx_create_assigned(spa->spa_dsl_pool, txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1225
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1226
	if (vd->vdev_detached) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1227
		if (smo->smo_object != 0) {
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1228
			int err = dmu_object_free(mos, smo->smo_object, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1229
			ASSERT3U(err, ==, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1230
			smo->smo_object = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1231
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1232
		dmu_tx_commit(tx);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1233
		dprintf("detach %s committed in txg %llu\n",
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1234
		    vdev_description(vd), txg);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1235
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1236
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1237
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1238
	if (smo->smo_object == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1239
		ASSERT(smo->smo_objsize == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1240
		ASSERT(smo->smo_alloc == 0);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1241
		smo->smo_object = dmu_object_alloc(mos,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1242
		    DMU_OT_SPACE_MAP, 1 << SPACE_MAP_BLOCKSHIFT,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1243
		    DMU_OT_SPACE_MAP_HEADER, sizeof (*smo), tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1244
		ASSERT(smo->smo_object != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1245
		vdev_config_dirty(vd->vdev_top);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1246
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1247
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1248
	mutex_init(&smlock, NULL, MUTEX_DEFAULT, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1249
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1250
	space_map_create(&smsync, sm->sm_start, sm->sm_size, sm->sm_shift,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1251
	    &smlock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1252
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1253
	mutex_enter(&smlock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1254
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1255
	mutex_enter(&vd->vdev_dtl_lock);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1256
	space_map_walk(sm, space_map_add, &smsync);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1257
	mutex_exit(&vd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1258
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1259
	space_map_truncate(smo, mos, tx);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1260
	space_map_sync(&smsync, SM_ALLOC, smo, mos, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1261
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1262
	space_map_destroy(&smsync);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1263
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1264
	mutex_exit(&smlock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1265
	mutex_destroy(&smlock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1266
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1267
	VERIFY(0 == dmu_bonus_hold(mos, smo->smo_object, FTAG, &db));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1268
	dmu_buf_will_dirty(db, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1269
	ASSERT3U(db->db_size, ==, sizeof (*smo));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1270
	bcopy(smo, db->db_data, db->db_size);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1271
	dmu_buf_rele(db, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1272
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1273
	dmu_tx_commit(tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1274
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1275
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1276
void
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1277
vdev_load(vdev_t *vd)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1278
{
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1279
	int c;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1280
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1281
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1282
	 * Recursively load all children.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1283
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1284
	for (c = 0; c < vd->vdev_children; c++)
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1285
		vdev_load(vd->vdev_child[c]);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1286
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1287
	/*
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1288
	 * If this is a top-level vdev, initialize its metaslabs.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1289
	 */
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1290
	if (vd == vd->vdev_top &&
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1291
	    (vd->vdev_ashift == 0 || vd->vdev_asize == 0 ||
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1292
	    vdev_metaslab_init(vd, 0) != 0))
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1293
		vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN,
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1294
		    VDEV_AUX_CORRUPT_DATA);
789
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
	 * If this is a leaf vdev, load its DTL.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1298
	 */
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1299
	if (vd->vdev_ops->vdev_op_leaf && vdev_dtl_load(vd) != 0)
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1300
		vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN,
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1301
		    VDEV_AUX_CORRUPT_DATA);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1302
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1303
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1304
/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1305
 * This special case of vdev_spare() is used for hot spares.  It's sole purpose
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1306
 * it to set the vdev state for the associated vdev.  To do this, we make sure
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1307
 * that we can open the underlying device, then try to read the label, and make
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1308
 * sure that the label is sane and that it hasn't been repurposed to another
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1309
 * pool.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1310
 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1311
int
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1312
vdev_validate_spare(vdev_t *vd)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1313
{
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1314
	nvlist_t *label;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1315
	uint64_t guid, version;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1316
	uint64_t state;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1317
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1318
	if ((label = vdev_label_read_config(vd)) == NULL) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1319
		vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1320
		    VDEV_AUX_CORRUPT_DATA);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1321
		return (-1);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1322
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1323
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1324
	if (nvlist_lookup_uint64(label, ZPOOL_CONFIG_VERSION, &version) != 0 ||
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1325
	    version > ZFS_VERSION ||
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1326
	    nvlist_lookup_uint64(label, ZPOOL_CONFIG_GUID, &guid) != 0 ||
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1327
	    guid != vd->vdev_guid ||
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1328
	    nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_STATE, &state) != 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1329
		vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1330
		    VDEV_AUX_CORRUPT_DATA);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1331
		nvlist_free(label);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1332
		return (-1);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1333
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1334
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1335
	/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1336
	 * We don't actually check the pool state here.  If it's in fact in
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1337
	 * use by another pool, we update this fact on the fly when requested.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1338
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1339
	nvlist_free(label);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1340
	return (0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1341
}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1342
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1343
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1344
vdev_sync_done(vdev_t *vd, uint64_t txg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1345
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1346
	metaslab_t *msp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1347
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1348
	dprintf("%s txg %llu\n", vdev_description(vd), txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1349
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1350
	while (msp = txg_list_remove(&vd->vdev_ms_list, TXG_CLEAN(txg)))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1351
		metaslab_sync_done(msp, txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1352
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1353
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1354
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1355
vdev_sync(vdev_t *vd, uint64_t txg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1356
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1357
	spa_t *spa = vd->vdev_spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1358
	vdev_t *lvd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1359
	metaslab_t *msp;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1360
	dmu_tx_t *tx;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1361
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1362
	dprintf("%s txg %llu pass %d\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1363
	    vdev_description(vd), (u_longlong_t)txg, spa_sync_pass(spa));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1364
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1365
	if (vd->vdev_ms_array == 0 && vd->vdev_ms_shift != 0) {
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1366
		ASSERT(vd == vd->vdev_top);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1367
		tx = dmu_tx_create_assigned(spa->spa_dsl_pool, txg);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1368
		vd->vdev_ms_array = dmu_object_alloc(spa->spa_meta_objset,
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1369
		    DMU_OT_OBJECT_ARRAY, 0, DMU_OT_NONE, 0, tx);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1370
		ASSERT(vd->vdev_ms_array != 0);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1371
		vdev_config_dirty(vd);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1372
		dmu_tx_commit(tx);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1373
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1374
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1375
	while ((msp = txg_list_remove(&vd->vdev_ms_list, txg)) != NULL) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1376
		metaslab_sync(msp, txg);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1377
		(void) txg_list_add(&vd->vdev_ms_list, msp, TXG_CLEAN(txg));
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1378
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1379
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1380
	while ((lvd = txg_list_remove(&vd->vdev_dtl_list, txg)) != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1381
		vdev_dtl_sync(lvd, txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1382
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1383
	(void) txg_list_add(&spa->spa_vdev_txg_list, vd, TXG_CLEAN(txg));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1384
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1385
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1386
uint64_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1387
vdev_psize_to_asize(vdev_t *vd, uint64_t psize)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1388
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1389
	return (vd->vdev_ops->vdev_op_asize(vd, psize));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1390
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1391
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1392
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1393
vdev_io_start(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1394
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1395
	zio->io_vd->vdev_ops->vdev_op_io_start(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1396
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1397
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1398
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1399
vdev_io_done(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1400
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1401
	zio->io_vd->vdev_ops->vdev_op_io_done(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1402
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1403
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1404
const char *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1405
vdev_description(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1406
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1407
	if (vd == NULL || vd->vdev_ops == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1408
		return ("<unknown>");
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1409
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1410
	if (vd->vdev_path != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1411
		return (vd->vdev_path);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1412
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1413
	if (vd->vdev_parent == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1414
		return (spa_name(vd->vdev_spa));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1415
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1416
	return (vd->vdev_ops->vdev_op_type);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1417
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1418
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1419
int
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1420
vdev_online(spa_t *spa, uint64_t guid)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1421
{
1485
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1422
	vdev_t *rvd, *vd;
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1423
	uint64_t txg;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1424
1485
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1425
	txg = spa_vdev_enter(spa);
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1426
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1427
	rvd = spa->spa_root_vdev;
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1428
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1429
	if ((vd = vdev_lookup_by_guid(rvd, guid)) == NULL)
1485
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1430
		return (spa_vdev_exit(spa, NULL, txg, ENODEV));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1431
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1432
	if (!vd->vdev_ops->vdev_op_leaf)
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1433
		return (spa_vdev_exit(spa, NULL, txg, ENOTSUP));
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1434
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1435
	dprintf("ONLINE: %s\n", vdev_description(vd));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1436
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1437
	vd->vdev_offline = B_FALSE;
1485
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1438
	vd->vdev_tmpoffline = B_FALSE;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1439
	vdev_reopen(vd->vdev_top);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1440
1485
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1441
	vdev_config_dirty(vd->vdev_top);
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1442
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1443
	(void) spa_vdev_exit(spa, NULL, txg, 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1444
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1445
	VERIFY(spa_scrub(spa, POOL_SCRUB_RESILVER, B_TRUE) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1446
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1447
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1448
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1449
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1450
int
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1451
vdev_offline(spa_t *spa, uint64_t guid, int istmp)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1452
{
1485
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1453
	vdev_t *rvd, *vd;
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1454
	uint64_t txg;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1455
1485
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1456
	txg = spa_vdev_enter(spa);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1457
1485
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1458
	rvd = spa->spa_root_vdev;
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1459
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1460
	if ((vd = vdev_lookup_by_guid(rvd, guid)) == NULL)
1485
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1461
		return (spa_vdev_exit(spa, NULL, txg, ENODEV));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1462
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1463
	if (!vd->vdev_ops->vdev_op_leaf)
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1464
		return (spa_vdev_exit(spa, NULL, txg, ENOTSUP));
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1465
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1466
	dprintf("OFFLINE: %s\n", vdev_description(vd));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1467
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1468
	/*
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1469
	 * If the device isn't already offline, try to offline it.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1470
	 */
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1471
	if (!vd->vdev_offline) {
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1472
		/*
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1473
		 * If this device's top-level vdev has a non-empty DTL,
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1474
		 * don't allow the device to be offlined.
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1475
		 *
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1476
		 * XXX -- make this more precise by allowing the offline
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1477
		 * as long as the remaining devices don't have any DTL holes.
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1478
		 */
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1479
		if (vd->vdev_top->vdev_dtl_map.sm_space != 0)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1480
			return (spa_vdev_exit(spa, NULL, txg, EBUSY));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1481
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1482
		/*
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1483
		 * Offline this device and reopen its top-level vdev.
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1484
		 * If this action results in the top-level vdev becoming
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1485
		 * unusable, undo it and fail the request.
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1486
		 */
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1487
		vd->vdev_offline = B_TRUE;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1488
		vdev_reopen(vd->vdev_top);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1489
		if (vdev_is_dead(vd->vdev_top)) {
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1490
			vd->vdev_offline = B_FALSE;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1491
			vdev_reopen(vd->vdev_top);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1492
			return (spa_vdev_exit(spa, NULL, txg, EBUSY));
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1493
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1494
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1495
1485
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1496
	vd->vdev_tmpoffline = istmp;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1497
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1498
	vdev_config_dirty(vd->vdev_top);
1485
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1499
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1500
	return (spa_vdev_exit(spa, NULL, txg, 0));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1501
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1502
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1503
/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1504
 * Clear the error counts associated with this vdev.  Unlike vdev_online() and
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1505
 * vdev_offline(), we assume the spa config is locked.  We also clear all
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1506
 * children.  If 'vd' is NULL, then the user wants to clear all vdevs.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1507
 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1508
void
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1509
vdev_clear(spa_t *spa, vdev_t *vd)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1510
{
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1511
	int c;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1512
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1513
	if (vd == NULL)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1514
		vd = spa->spa_root_vdev;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1515
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1516
	vd->vdev_stat.vs_read_errors = 0;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1517
	vd->vdev_stat.vs_write_errors = 0;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1518
	vd->vdev_stat.vs_checksum_errors = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1519
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1520
	for (c = 0; c < vd->vdev_children; c++)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1521
		vdev_clear(spa, vd->vdev_child[c]);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1522
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1523
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1524
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1525
vdev_is_dead(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1526
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1527
	return (vd->vdev_state <= VDEV_STATE_CANT_OPEN);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1528
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1529
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1530
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1531
vdev_error_inject(vdev_t *vd, zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1532
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1533
	int error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1534
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1535
	if (vd->vdev_fault_mode == VDEV_FAULT_NONE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1536
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1537
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1538
	if (((1ULL << zio->io_type) & vd->vdev_fault_mask) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1539
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1540
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1541
	switch (vd->vdev_fault_mode) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1542
	case VDEV_FAULT_RANDOM:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1543
		if (spa_get_random(vd->vdev_fault_arg) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1544
			error = EIO;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1545
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1546
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1547
	case VDEV_FAULT_COUNT:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1548
		if ((int64_t)--vd->vdev_fault_arg <= 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1549
			vd->vdev_fault_mode = VDEV_FAULT_NONE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1550
		error = EIO;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1551
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1552
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1553
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1554
	if (error != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1555
		dprintf("returning %d for type %d on %s state %d offset %llx\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1556
		    error, zio->io_type, vdev_description(vd),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1557
		    vd->vdev_state, zio->io_offset);
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
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1561
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1562
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1563
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1564
 * Get statistics for the given vdev.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1565
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1566
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1567
vdev_get_stats(vdev_t *vd, vdev_stat_t *vs)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1568
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1569
	vdev_t *rvd = vd->vdev_spa->spa_root_vdev;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1570
	int c, t;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1571
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1572
	mutex_enter(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1573
	bcopy(&vd->vdev_stat, vs, sizeof (*vs));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1574
	vs->vs_timestamp = gethrtime() - vs->vs_timestamp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1575
	vs->vs_state = vd->vdev_state;
1175
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1171
diff changeset
  1576
	vs->vs_rsize = vdev_get_rsize(vd);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1577
	mutex_exit(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1578
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1579
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1580
	 * If we're getting stats on the root vdev, aggregate the I/O counts
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1581
	 * over all top-level vdevs (i.e. the direct children of the root).
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1582
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1583
	if (vd == rvd) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1584
		for (c = 0; c < rvd->vdev_children; c++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1585
			vdev_t *cvd = rvd->vdev_child[c];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1586
			vdev_stat_t *cvs = &cvd->vdev_stat;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1587
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1588
			mutex_enter(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1589
			for (t = 0; t < ZIO_TYPES; t++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1590
				vs->vs_ops[t] += cvs->vs_ops[t];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1591
				vs->vs_bytes[t] += cvs->vs_bytes[t];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1592
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1593
			vs->vs_read_errors += cvs->vs_read_errors;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1594
			vs->vs_write_errors += cvs->vs_write_errors;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1595
			vs->vs_checksum_errors += cvs->vs_checksum_errors;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1596
			vs->vs_scrub_examined += cvs->vs_scrub_examined;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1597
			vs->vs_scrub_errors += cvs->vs_scrub_errors;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1598
			mutex_exit(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1599
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1600
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1601
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1602
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1603
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1604
vdev_stat_update(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1605
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1606
	vdev_t *vd = zio->io_vd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1607
	vdev_t *pvd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1608
	uint64_t txg = zio->io_txg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1609
	vdev_stat_t *vs = &vd->vdev_stat;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1610
	zio_type_t type = zio->io_type;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1611
	int flags = zio->io_flags;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1612
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1613
	if (zio->io_error == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1614
		if (!(flags & ZIO_FLAG_IO_BYPASS)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1615
			mutex_enter(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1616
			vs->vs_ops[type]++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1617
			vs->vs_bytes[type] += zio->io_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1618
			mutex_exit(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1619
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1620
		if ((flags & ZIO_FLAG_IO_REPAIR) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1621
		    zio->io_delegate_list == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1622
			mutex_enter(&vd->vdev_stat_lock);
1807
35c8b566d7af 6410711 intent log blocks don't get invited to pool parties
bonwick
parents: 1775
diff changeset
  1623
			if (flags & ZIO_FLAG_SCRUB_THREAD)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1624
				vs->vs_scrub_repaired += zio->io_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1625
			else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1626
				vs->vs_self_healed += zio->io_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1627
			mutex_exit(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1628
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1629
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1630
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1631
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1632
	if (flags & ZIO_FLAG_SPECULATIVE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1633
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1634
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1635
	if (!vdev_is_dead(vd)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1636
		mutex_enter(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1637
		if (type == ZIO_TYPE_READ) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1638
			if (zio->io_error == ECKSUM)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1639
				vs->vs_checksum_errors++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1640
			else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1641
				vs->vs_read_errors++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1642
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1643
		if (type == ZIO_TYPE_WRITE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1644
			vs->vs_write_errors++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1645
		mutex_exit(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1646
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1647
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1648
	if (type == ZIO_TYPE_WRITE) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1649
		if (txg == 0 || vd->vdev_children != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1650
			return;
1807
35c8b566d7af 6410711 intent log blocks don't get invited to pool parties
bonwick
parents: 1775
diff changeset
  1651
		if (flags & ZIO_FLAG_SCRUB_THREAD) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1652
			ASSERT(flags & ZIO_FLAG_IO_REPAIR);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1653
			for (pvd = vd; pvd != NULL; pvd = pvd->vdev_parent)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1654
				vdev_dtl_dirty(&pvd->vdev_dtl_scrub, txg, 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1655
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1656
		if (!(flags & ZIO_FLAG_IO_REPAIR)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1657
			if (vdev_dtl_contains(&vd->vdev_dtl_map, txg, 1))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1658
				return;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1659
			vdev_dirty(vd->vdev_top, VDD_DTL, vd, txg);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1660
			for (pvd = vd; pvd != NULL; pvd = pvd->vdev_parent)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1661
				vdev_dtl_dirty(&pvd->vdev_dtl_map, txg, 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1662
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1663
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1664
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1665
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1666
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1667
vdev_scrub_stat_update(vdev_t *vd, pool_scrub_type_t type, boolean_t complete)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1668
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1669
	int c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1670
	vdev_stat_t *vs = &vd->vdev_stat;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1671
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1672
	for (c = 0; c < vd->vdev_children; c++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1673
		vdev_scrub_stat_update(vd->vdev_child[c], type, complete);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1674
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1675
	mutex_enter(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1676
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1677
	if (type == POOL_SCRUB_NONE) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1678
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1679
		 * Update completion and end time.  Leave everything else alone
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1680
		 * so we can report what happened during the previous scrub.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1681
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1682
		vs->vs_scrub_complete = complete;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1683
		vs->vs_scrub_end = gethrestime_sec();
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1684
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1685
		vs->vs_scrub_type = type;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1686
		vs->vs_scrub_complete = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1687
		vs->vs_scrub_examined = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1688
		vs->vs_scrub_repaired = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1689
		vs->vs_scrub_errors = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1690
		vs->vs_scrub_start = gethrestime_sec();
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1691
		vs->vs_scrub_end = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1692
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1693
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1694
	mutex_exit(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1695
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1696
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1697
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1698
 * Update the in-core space usage stats for this vdev and the root vdev.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1699
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1700
void
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1701
vdev_space_update(vdev_t *vd, int64_t space_delta, int64_t alloc_delta)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1702
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1703
	ASSERT(vd == vd->vdev_top);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1704
	int64_t dspace_delta = space_delta;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1705
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1706
	do {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1707
		if (vd->vdev_ms_count) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1708
			/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1709
			 * If this is a top-level vdev, apply the
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1710
			 * inverse of its psize-to-asize (ie. RAID-Z)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1711
			 * space-expansion factor.  We must calculate
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1712
			 * this here and not at the root vdev because
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1713
			 * the root vdev's psize-to-asize is simply the
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1714
			 * max of its childrens', thus not accurate
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1715
			 * enough for us.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1716
			 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1717
			ASSERT((dspace_delta & (SPA_MINBLOCKSIZE-1)) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1718
			dspace_delta = (dspace_delta >> SPA_MINBLOCKSHIFT) *
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1719
			    vd->vdev_deflate_ratio;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1720
		}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1721
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1722
		mutex_enter(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1723
		vd->vdev_stat.vs_space += space_delta;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1724
		vd->vdev_stat.vs_alloc += alloc_delta;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1725
		vd->vdev_stat.vs_dspace += dspace_delta;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1726
		mutex_exit(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1727
	} while ((vd = vd->vdev_parent) != NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1728
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1729
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1730
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1731
 * Various knobs to tune a vdev.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1732
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1733
static vdev_knob_t vdev_knob[] = {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1734
	{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1735
		"cache_size",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1736
		"size of the read-ahead cache",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1737
		0,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1738
		1ULL << 30,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1739
		10ULL << 20,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1740
		offsetof(struct vdev, vdev_cache.vc_size)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1741
	},
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1742
	{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1743
		"cache_bshift",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1744
		"log2 of cache blocksize",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1745
		SPA_MINBLOCKSHIFT,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1746
		SPA_MAXBLOCKSHIFT,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1747
		16,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1748
		offsetof(struct vdev, vdev_cache.vc_bshift)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1749
	},
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1750
	{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1751
		"cache_max",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1752
		"largest block size to cache",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1753
		0,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1754
		SPA_MAXBLOCKSIZE,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1755
		1ULL << 14,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1756
		offsetof(struct vdev, vdev_cache.vc_max)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1757
	},
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1758
	{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1759
		"min_pending",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1760
		"minimum pending I/Os to the disk",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1761
		1,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1762
		10000,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1763
		2,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1764
		offsetof(struct vdev, vdev_queue.vq_min_pending)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1765
	},
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1766
	{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1767
		"max_pending",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1768
		"maximum pending I/Os to the disk",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1769
		1,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1770
		10000,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1771
		35,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1772
		offsetof(struct vdev, vdev_queue.vq_max_pending)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1773
	},
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1774
	{
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1775
		"scrub_limit",
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1776
		"maximum scrub/resilver I/O queue",
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1777
		0,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1778
		10000,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1779
		70,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1780
		offsetof(struct vdev, vdev_queue.vq_scrub_limit)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1781
	},
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1782
	{
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1783
		"agg_limit",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1784
		"maximum size of aggregated I/Os",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1785
		0,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1786
		SPA_MAXBLOCKSIZE,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1787
		SPA_MAXBLOCKSIZE,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1788
		offsetof(struct vdev, vdev_queue.vq_agg_limit)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1789
	},
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1790
	{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1791
		"time_shift",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1792
		"deadline = pri + (lbolt >> time_shift)",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1793
		0,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1794
		63,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1795
		4,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1796
		offsetof(struct vdev, vdev_queue.vq_time_shift)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1797
	},
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1798
	{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1799
		"ramp_rate",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1800
		"exponential I/O issue ramp-up rate",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1801
		1,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1802
		10000,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1803
		2,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1804
		offsetof(struct vdev, vdev_queue.vq_ramp_rate)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1805
	},
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1806
};
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1807
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1808
vdev_knob_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1809
vdev_knob_next(vdev_knob_t *vk)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1810
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1811
	if (vk == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1812
		return (vdev_knob);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1813
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1814
	if (++vk == vdev_knob + sizeof (vdev_knob) / sizeof (vdev_knob_t))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1815
		return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1816
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1817
	return (vk);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1818
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1819
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1820
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1821
 * Mark a top-level vdev's config as dirty, placing it on the dirty list
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1822
 * so that it will be written out next time the vdev configuration is synced.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1823
 * If the root vdev is specified (vdev_top == NULL), dirty all top-level vdevs.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1824
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1825
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1826
vdev_config_dirty(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1827
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1828
	spa_t *spa = vd->vdev_spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1829
	vdev_t *rvd = spa->spa_root_vdev;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1830
	int c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1831
1601
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  1832
	/*
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  1833
	 * The dirty list is protected by the config lock.  The caller must
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  1834
	 * either hold the config lock as writer, or must be the sync thread
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  1835
	 * (which holds the lock as reader).  There's only one sync thread,
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  1836
	 * so this is sufficient to ensure mutual exclusion.
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  1837
	 */
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  1838
	ASSERT(spa_config_held(spa, RW_WRITER) ||
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  1839
	    dsl_pool_sync_context(spa_get_dsl(spa)));
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  1840
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1841
	if (vd == rvd) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1842
		for (c = 0; c < rvd->vdev_children; c++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1843
			vdev_config_dirty(rvd->vdev_child[c]);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1844
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1845
		ASSERT(vd == vd->vdev_top);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1846
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1847
		if (!list_link_active(&vd->vdev_dirty_node))
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1848
			list_insert_head(&spa->spa_dirty_list, vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1849
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1850
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1851
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1852
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1853
vdev_config_clean(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1854
{
1601
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  1855
	spa_t *spa = vd->vdev_spa;
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  1856
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  1857
	ASSERT(spa_config_held(spa, RW_WRITER) ||
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  1858
	    dsl_pool_sync_context(spa_get_dsl(spa)));
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  1859
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1860
	ASSERT(list_link_active(&vd->vdev_dirty_node));
1601
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  1861
	list_remove(&spa->spa_dirty_list, vd);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1862
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1863
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1864
void
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1865
vdev_propagate_state(vdev_t *vd)
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1866
{
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1867
	vdev_t *rvd = vd->vdev_spa->spa_root_vdev;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1868
	int degraded = 0, faulted = 0;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1869
	int corrupted = 0;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1870
	int c;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1871
	vdev_t *child;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1872
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1873
	for (c = 0; c < vd->vdev_children; c++) {
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1874
		child = vd->vdev_child[c];
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1875
		if (child->vdev_state <= VDEV_STATE_CANT_OPEN)
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1876
			faulted++;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1877
		else if (child->vdev_state == VDEV_STATE_DEGRADED)
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1878
			degraded++;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1879
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1880
		if (child->vdev_stat.vs_aux == VDEV_AUX_CORRUPT_DATA)
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1881
			corrupted++;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1882
	}
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1883
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1884
	vd->vdev_ops->vdev_op_state_change(vd, faulted, degraded);
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1885
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1886
	/*
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1887
	 * Root special: if there is a toplevel vdev that cannot be
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1888
	 * opened due to corrupted metadata, then propagate the root
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1889
	 * vdev's aux state as 'corrupt' rather than 'insufficient
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1890
	 * replicas'.
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1891
	 */
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1892
	if (corrupted && vd == rvd && rvd->vdev_state == VDEV_STATE_CANT_OPEN)
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1893
		vdev_set_state(rvd, B_FALSE, VDEV_STATE_CANT_OPEN,
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1894
		    VDEV_AUX_CORRUPT_DATA);
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1895
}
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1896
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1897
/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1898
 * Set a vdev's state.  If this is during an open, we don't update the parent
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1899
 * state, because we're in the process of opening children depth-first.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1900
 * Otherwise, we propagate the change to the parent.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1901
 *
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1902
 * If this routine places a device in a faulted state, an appropriate ereport is
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1903
 * generated.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1904
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1905
void
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1906
vdev_set_state(vdev_t *vd, boolean_t isopen, vdev_state_t state, vdev_aux_t aux)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1907
{
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1908
	uint64_t save_state;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1909
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1910
	if (state == vd->vdev_state) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1911
		vd->vdev_stat.vs_aux = aux;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1912
		return;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1913
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1914
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1915
	save_state = vd->vdev_state;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1916
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1917
	vd->vdev_state = state;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1918
	vd->vdev_stat.vs_aux = aux;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1919
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1920
	if (state == VDEV_STATE_CANT_OPEN) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1921
		/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1922
		 * If we fail to open a vdev during an import, we mark it as
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1923
		 * "not available", which signifies that it was never there to
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1924
		 * begin with.  Failure to open such a device is not considered
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1925
		 * an error.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1926
		 */
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1927
		if (vd->vdev_spa->spa_load_state == SPA_LOAD_IMPORT &&
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1928
		    vd->vdev_ops->vdev_op_leaf)
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1929
			vd->vdev_not_present = 1;
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1930
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1931
		/*
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1932
		 * Post the appropriate ereport.  If the 'prevstate' field is
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1933
		 * set to something other than VDEV_STATE_UNKNOWN, it indicates
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1934
		 * that this is part of a vdev_reopen().  In this case, we don't
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1935
		 * want to post the ereport if the device was already in the
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1936
		 * CANT_OPEN state beforehand.
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1937
		 */
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1938
		if (vd->vdev_prevstate != state && !vd->vdev_not_present &&
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1939
		    vd != vd->vdev_spa->spa_root_vdev) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1940
			const char *class;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1941
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1942
			switch (aux) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1943
			case VDEV_AUX_OPEN_FAILED:
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1944
				class = FM_EREPORT_ZFS_DEVICE_OPEN_FAILED;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1945
				break;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1946
			case VDEV_AUX_CORRUPT_DATA:
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1947
				class = FM_EREPORT_ZFS_DEVICE_CORRUPT_DATA;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1948
				break;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1949
			case VDEV_AUX_NO_REPLICAS:
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1950
				class = FM_EREPORT_ZFS_DEVICE_NO_REPLICAS;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1951
				break;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1952
			case VDEV_AUX_BAD_GUID_SUM:
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1953
				class = FM_EREPORT_ZFS_DEVICE_BAD_GUID_SUM;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1954
				break;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1955
			case VDEV_AUX_TOO_SMALL:
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1956
				class = FM_EREPORT_ZFS_DEVICE_TOO_SMALL;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1957
				break;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1958
			case VDEV_AUX_BAD_LABEL:
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1959
				class = FM_EREPORT_ZFS_DEVICE_BAD_LABEL;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1960
				break;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1961
			default:
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1962
				class = FM_EREPORT_ZFS_DEVICE_UNKNOWN;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1963
			}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1964
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1965
			zfs_ereport_post(class, vd->vdev_spa,
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1966
			    vd, NULL, save_state, 0);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1967
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1968
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1969
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1970
	if (isopen)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1971
		return;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1972
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1973
	if (vd->vdev_parent != NULL)
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  1974
		vdev_propagate_state(vd->vdev_parent);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1975
}