usr/src/uts/common/fs/zfs/vdev.c
author ek110237
Wed, 25 Jun 2008 15:48:48 -0700
changeset 6959 f223e134ee61
parent 6643 3a34b0dbb107
child 6976 cae5f06df471
permissions -rw-r--r--
6700920 vdev_clear() needs some polishing 6719141 misspelling in status_callback() for I/O failure case
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
/*
6523
c1d2a7f04573 6616739 panic message ZFS: I/O failure (write on <unknown> is not very helpful
ek110237
parents: 5530
diff changeset
    23
 * Copyright 2008 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>
6643
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
    43
#include <sys/arc.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    45
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
 * Virtual device management.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
static vdev_ops_t *vdev_ops_table[] = {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
	&vdev_root_ops,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    51
	&vdev_raidz_ops,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
	&vdev_mirror_ops,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
	&vdev_replacing_ops,
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
    54
	&vdev_spare_ops,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
	&vdev_disk_ops,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
	&vdev_file_ops,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
	&vdev_missing_ops,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
	NULL
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
};
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    60
3697
5340a4d98e0b 6456888 zpool scrubbing leads to memory exhaustion and system hang
mishra
parents: 3377
diff changeset
    61
/* maximum scrub/resilver I/O queue */
5340a4d98e0b 6456888 zpool scrubbing leads to memory exhaustion and system hang
mishra
parents: 3377
diff changeset
    62
int zfs_scrub_limit = 70;
5340a4d98e0b 6456888 zpool scrubbing leads to memory exhaustion and system hang
mishra
parents: 3377
diff changeset
    63
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    65
 * Given a vdev type, return the appropriate ops vector.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    66
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    67
static vdev_ops_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
vdev_getops(const char *type)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    70
	vdev_ops_t *ops, **opspp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    71
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    72
	for (opspp = vdev_ops_table; (ops = *opspp) != NULL; opspp++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    73
		if (strcmp(ops->vdev_op_type, type) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    74
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    75
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    76
	return (ops);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    77
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    78
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    79
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    80
 * Default asize function: return the MAX of psize with the asize of
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    81
 * all children.  This is what's used by anything other than RAID-Z.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    82
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    83
uint64_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    84
vdev_default_asize(vdev_t *vd, uint64_t psize)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    85
{
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
    86
	uint64_t asize = P2ROUNDUP(psize, 1ULL << vd->vdev_top->vdev_ashift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    87
	uint64_t csize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    88
	uint64_t c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    89
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    90
	for (c = 0; c < vd->vdev_children; c++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    91
		csize = vdev_psize_to_asize(vd->vdev_child[c], psize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    92
		asize = MAX(asize, csize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    93
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    94
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    95
	return (asize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    96
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    97
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
    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
 * 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
   100
 * 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
   101
 * 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
   102
 *
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
 * 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
   104
 *			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
   105
 * 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
   106
 *	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
   107
 *	    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
   108
 *	    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
   109
 *	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
   110
 */
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
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
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
   113
{
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
	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
   115
	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
   116
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
	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
   118
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
	/*
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
	 * 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
   121
	 */
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
	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
   123
		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
   124
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 = 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
   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
	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
   128
		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
   129
		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
   130
	}
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
   131
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
   132
	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
   133
}
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
   134
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   135
vdev_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   136
vdev_lookup_top(spa_t *spa, uint64_t vdev)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   137
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   138
	vdev_t *rvd = spa->spa_root_vdev;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   139
5530
4ed96167d864 6354519 stack overflow in zfs due to zio pipeline
bonwick
parents: 5450
diff changeset
   140
	ASSERT(spa_config_held(spa, RW_READER) ||
4ed96167d864 6354519 stack overflow in zfs due to zio pipeline
bonwick
parents: 5450
diff changeset
   141
	    curthread == spa->spa_scrub_thread);
4ed96167d864 6354519 stack overflow in zfs due to zio pipeline
bonwick
parents: 5450
diff changeset
   142
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   143
	if (vdev < rvd->vdev_children)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   144
		return (rvd->vdev_child[vdev]);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   145
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   146
	return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   147
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   148
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   149
vdev_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   150
vdev_lookup_by_guid(vdev_t *vd, uint64_t guid)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   151
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   152
	int c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   153
	vdev_t *mvd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   154
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   155
	if (vd->vdev_guid == guid)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   156
		return (vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   157
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   158
	for (c = 0; c < vd->vdev_children; c++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   159
		if ((mvd = vdev_lookup_by_guid(vd->vdev_child[c], guid)) !=
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   160
		    NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   161
			return (mvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   162
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   163
	return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   164
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   165
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   166
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   167
vdev_add_child(vdev_t *pvd, vdev_t *cvd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   168
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   169
	size_t oldsize, newsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   170
	uint64_t id = cvd->vdev_id;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   171
	vdev_t **newchild;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   172
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   173
	ASSERT(spa_config_held(cvd->vdev_spa, RW_WRITER));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   174
	ASSERT(cvd->vdev_parent == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   175
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   176
	cvd->vdev_parent = pvd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   177
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   178
	if (pvd == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   179
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   180
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   181
	ASSERT(id >= pvd->vdev_children || pvd->vdev_child[id] == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   182
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   183
	oldsize = pvd->vdev_children * sizeof (vdev_t *);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   184
	pvd->vdev_children = MAX(pvd->vdev_children, id + 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   185
	newsize = pvd->vdev_children * sizeof (vdev_t *);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   186
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   187
	newchild = kmem_zalloc(newsize, KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   188
	if (pvd->vdev_child != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   189
		bcopy(pvd->vdev_child, newchild, oldsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   190
		kmem_free(pvd->vdev_child, oldsize);
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
	pvd->vdev_child = newchild;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   194
	pvd->vdev_child[id] = cvd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   195
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   196
	cvd->vdev_top = (pvd->vdev_top ? pvd->vdev_top: cvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   197
	ASSERT(cvd->vdev_top->vdev_parent->vdev_parent == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   198
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   199
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   200
	 * Walk up all ancestors to update guid sum.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   201
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   202
	for (; pvd != NULL; pvd = pvd->vdev_parent)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   203
		pvd->vdev_guid_sum += cvd->vdev_guid_sum;
3697
5340a4d98e0b 6456888 zpool scrubbing leads to memory exhaustion and system hang
mishra
parents: 3377
diff changeset
   204
5340a4d98e0b 6456888 zpool scrubbing leads to memory exhaustion and system hang
mishra
parents: 3377
diff changeset
   205
	if (cvd->vdev_ops->vdev_op_leaf)
5340a4d98e0b 6456888 zpool scrubbing leads to memory exhaustion and system hang
mishra
parents: 3377
diff changeset
   206
		cvd->vdev_spa->spa_scrub_maxinflight += zfs_scrub_limit;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   207
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   208
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   209
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   210
vdev_remove_child(vdev_t *pvd, vdev_t *cvd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   211
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   212
	int c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   213
	uint_t id = cvd->vdev_id;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   214
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   215
	ASSERT(cvd->vdev_parent == pvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   216
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   217
	if (pvd == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   218
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   219
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   220
	ASSERT(id < pvd->vdev_children);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   221
	ASSERT(pvd->vdev_child[id] == cvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   222
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   223
	pvd->vdev_child[id] = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   224
	cvd->vdev_parent = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   225
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   226
	for (c = 0; c < pvd->vdev_children; c++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   227
		if (pvd->vdev_child[c])
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   228
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   229
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   230
	if (c == pvd->vdev_children) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   231
		kmem_free(pvd->vdev_child, c * sizeof (vdev_t *));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   232
		pvd->vdev_child = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   233
		pvd->vdev_children = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   234
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   235
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   236
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   237
	 * Walk up all ancestors to update guid sum.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   238
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   239
	for (; pvd != NULL; pvd = pvd->vdev_parent)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   240
		pvd->vdev_guid_sum -= cvd->vdev_guid_sum;
3697
5340a4d98e0b 6456888 zpool scrubbing leads to memory exhaustion and system hang
mishra
parents: 3377
diff changeset
   241
5340a4d98e0b 6456888 zpool scrubbing leads to memory exhaustion and system hang
mishra
parents: 3377
diff changeset
   242
	if (cvd->vdev_ops->vdev_op_leaf)
5340a4d98e0b 6456888 zpool scrubbing leads to memory exhaustion and system hang
mishra
parents: 3377
diff changeset
   243
		cvd->vdev_spa->spa_scrub_maxinflight -= zfs_scrub_limit;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   244
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   245
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   246
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   247
 * Remove any holes in the child array.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   248
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   249
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   250
vdev_compact_children(vdev_t *pvd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   251
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   252
	vdev_t **newchild, *cvd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   253
	int oldc = pvd->vdev_children;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   254
	int newc, c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   255
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   256
	ASSERT(spa_config_held(pvd->vdev_spa, RW_WRITER));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   257
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   258
	for (c = newc = 0; c < oldc; c++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   259
		if (pvd->vdev_child[c])
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   260
			newc++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   261
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   262
	newchild = kmem_alloc(newc * sizeof (vdev_t *), KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   263
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   264
	for (c = newc = 0; c < oldc; c++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   265
		if ((cvd = pvd->vdev_child[c]) != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   266
			newchild[newc] = cvd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   267
			cvd->vdev_id = newc++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   268
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   269
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   270
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   271
	kmem_free(pvd->vdev_child, oldc * sizeof (vdev_t *));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   272
	pvd->vdev_child = newchild;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   273
	pvd->vdev_children = newc;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   274
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   275
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   276
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   277
 * Allocate and minimally initialize a vdev_t.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   278
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   279
static vdev_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   280
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
   281
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   282
	vdev_t *vd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   283
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   284
	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
   285
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   286
	if (spa->spa_root_vdev == NULL) {
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   287
		ASSERT(ops == &vdev_root_ops);
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   288
		spa->spa_root_vdev = vd;
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   289
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   290
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   291
	if (guid == 0) {
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   292
		if (spa->spa_root_vdev == vd) {
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
			 * 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
   295
			 * which must be unique among all pools.
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   296
			 */
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   297
			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
   298
				guid = spa_get_random(-1ULL);
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   299
		} else {
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   300
			/*
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   301
			 * 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
   302
			 */
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   303
			while (guid == 0 ||
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   304
			    spa_guid_exists(spa_guid(spa), guid))
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   305
				guid = spa_get_random(-1ULL);
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   306
		}
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   307
		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
   308
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   309
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   310
	vd->vdev_spa = spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   311
	vd->vdev_id = id;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   312
	vd->vdev_guid = guid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   313
	vd->vdev_guid_sum = guid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   314
	vd->vdev_ops = ops;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   315
	vd->vdev_state = VDEV_STATE_CLOSED;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   316
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   317
	mutex_init(&vd->vdev_dtl_lock, NULL, MUTEX_DEFAULT, NULL);
2856
6f4d5ee1906a 6463348 ZFS code could be more portable
nd150628
parents: 2391
diff changeset
   318
	mutex_init(&vd->vdev_stat_lock, NULL, MUTEX_DEFAULT, NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   319
	space_map_create(&vd->vdev_dtl_map, 0, -1ULL, 0, &vd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   320
	space_map_create(&vd->vdev_dtl_scrub, 0, -1ULL, 0, &vd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   321
	txg_list_create(&vd->vdev_ms_list,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   322
	    offsetof(struct metaslab, ms_txg_node));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   323
	txg_list_create(&vd->vdev_dtl_list,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   324
	    offsetof(struct vdev, vdev_dtl_node));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   325
	vd->vdev_stat.vs_timestamp = gethrtime();
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   326
	vdev_queue_init(vd);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   327
	vdev_cache_init(vd);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   328
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   329
	return (vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   330
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   331
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   332
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   333
 * Allocate a new vdev.  The 'alloctype' is used to control whether we are
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   334
 * creating a new vdev or loading an existing one - the behavior is slightly
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   335
 * different for each case.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   336
 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   337
int
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   338
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
   339
    int alloctype)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   340
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   341
	vdev_ops_t *ops;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   342
	char *type;
4527
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   343
	uint64_t guid = 0, islog, nparity;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   344
	vdev_t *vd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   345
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   346
	ASSERT(spa_config_held(spa, RW_WRITER));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   347
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   348
	if (nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) != 0)
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   349
		return (EINVAL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   350
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   351
	if ((ops = vdev_getops(type)) == NULL)
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   352
		return (EINVAL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   353
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   354
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   355
	 * If this is a load, get the vdev guid from the nvlist.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   356
	 * Otherwise, vdev_alloc_common() will generate one for us.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   357
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   358
	if (alloctype == VDEV_ALLOC_LOAD) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   359
		uint64_t label_id;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   360
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   361
		if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID, &label_id) ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   362
		    label_id != id)
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   363
			return (EINVAL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   364
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   365
		if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) != 0)
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   366
			return (EINVAL);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   367
	} else if (alloctype == VDEV_ALLOC_SPARE) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   368
		if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   369
			return (EINVAL);
5450
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
   370
	} else if (alloctype == VDEV_ALLOC_L2CACHE) {
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
   371
		if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) != 0)
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
   372
			return (EINVAL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   373
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   374
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   375
	/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   376
	 * The first allocated vdev must be of type 'root'.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   377
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   378
	if (ops != &vdev_root_ops && spa->spa_root_vdev == NULL)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   379
		return (EINVAL);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   380
4527
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   381
	/*
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   382
	 * Determine whether we're a log vdev.
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   383
	 */
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   384
	islog = 0;
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   385
	(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG, &islog);
5094
71a3e95fb9e2 PSARC 2007/342 Enhanced ZFS Pool Properties
lling
parents: 4944
diff changeset
   386
	if (islog && spa_version(spa) < SPA_VERSION_SLOGS)
4527
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   387
		return (ENOTSUP);
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   388
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   389
	/*
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   390
	 * Set the nparity property for RAID-Z vdevs.
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   391
	 */
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   392
	nparity = -1ULL;
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   393
	if (ops == &vdev_raidz_ops) {
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   394
		if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NPARITY,
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   395
		    &nparity) == 0) {
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   396
			/*
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   397
			 * Currently, we can only support 2 parity devices.
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   398
			 */
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   399
			if (nparity == 0 || nparity > 2)
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   400
				return (EINVAL);
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   401
			/*
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   402
			 * Older versions can only support 1 parity device.
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   403
			 */
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   404
			if (nparity == 2 &&
4577
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4527
diff changeset
   405
			    spa_version(spa) < SPA_VERSION_RAID6)
4527
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   406
				return (ENOTSUP);
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   407
		} else {
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   408
			/*
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   409
			 * We require the parity to be specified for SPAs that
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   410
			 * support multiple parity levels.
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   411
			 */
4577
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4527
diff changeset
   412
			if (spa_version(spa) >= SPA_VERSION_RAID6)
4527
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   413
				return (EINVAL);
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   414
			/*
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   415
			 * Otherwise, we default to 1 parity device for RAID-Z.
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   416
			 */
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   417
			nparity = 1;
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   418
		}
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   419
	} else {
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   420
		nparity = 0;
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   421
	}
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   422
	ASSERT(nparity != -1ULL);
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   423
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   424
	vd = vdev_alloc_common(spa, id, guid, ops);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   425
4527
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   426
	vd->vdev_islog = islog;
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   427
	vd->vdev_nparity = nparity;
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   428
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   429
	if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &vd->vdev_path) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   430
		vd->vdev_path = spa_strdup(vd->vdev_path);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   431
	if (nvlist_lookup_string(nv, ZPOOL_CONFIG_DEVID, &vd->vdev_devid) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   432
		vd->vdev_devid = spa_strdup(vd->vdev_devid);
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   433
	if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PHYS_PATH,
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   434
	    &vd->vdev_physpath) == 0)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   435
		vd->vdev_physpath = spa_strdup(vd->vdev_physpath);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   436
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   437
	/*
1171
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   438
	 * 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
   439
	 * as -1.
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   440
	 */
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   441
	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   442
	    &vd->vdev_wholedisk) != 0)
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   443
		vd->vdev_wholedisk = -1ULL;
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   444
b501e9f31cab 6344272 re-think how whole disks are stored
eschrock
parents: 789
diff changeset
   445
	/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   446
	 * 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
   447
	 * was not present at the time of import.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   448
	 */
6643
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
   449
	if (!spa->spa_import_faulted)
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
   450
		(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
   451
		    &vd->vdev_not_present);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   452
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   453
	/*
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   454
	 * Get the alignment requirement.
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   455
	 */
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   456
	(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ASHIFT, &vd->vdev_ashift);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   457
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   458
	/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   459
	 * If we're a top-level vdev, try to load the allocation parameters.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   460
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   461
	if (parent && !parent->vdev_parent && alloctype == VDEV_ALLOC_LOAD) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   462
		(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_METASLAB_ARRAY,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   463
		    &vd->vdev_ms_array);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   464
		(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_METASLAB_SHIFT,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   465
		    &vd->vdev_ms_shift);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   466
		(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ASIZE,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   467
		    &vd->vdev_asize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   468
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   469
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   470
	/*
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   471
	 * If we're a leaf vdev, try to load the DTL object and other state.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   472
	 */
6643
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
   473
	if (vd->vdev_ops->vdev_op_leaf &&
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
   474
	    (alloctype == VDEV_ALLOC_LOAD || alloctype == VDEV_ALLOC_L2CACHE)) {
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
   475
		if (alloctype == VDEV_ALLOC_LOAD) {
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
   476
			(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_DTL,
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
   477
			    &vd->vdev_dtl.smo_object);
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
   478
			(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_UNSPARE,
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
   479
			    &vd->vdev_unspare);
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
   480
		}
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   481
		(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_OFFLINE,
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   482
		    &vd->vdev_offline);
6643
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
   483
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   484
		/*
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   485
		 * When importing a pool, we want to ignore the persistent fault
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   486
		 * state, as the diagnosis made on another system may not be
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   487
		 * valid in the current context.
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   488
		 */
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   489
		if (spa->spa_load_state == SPA_LOAD_OPEN) {
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   490
			(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_FAULTED,
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   491
			    &vd->vdev_faulted);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   492
			(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_DEGRADED,
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   493
			    &vd->vdev_degraded);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   494
			(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_REMOVED,
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   495
			    &vd->vdev_removed);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   496
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   497
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   498
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   499
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   500
	 * Add ourselves to the parent's list of children.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   501
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   502
	vdev_add_child(parent, vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   503
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   504
	*vdp = vd;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   505
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   506
	return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   507
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   508
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   509
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   510
vdev_free(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   511
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   512
	int c;
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   513
	spa_t *spa = vd->vdev_spa;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   514
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   515
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   516
	 * vdev_free() implies closing the vdev first.  This is simpler than
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   517
	 * trying to ensure complicated semantics for all callers.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   518
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   519
	vdev_close(vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   520
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   521
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   522
	ASSERT(!list_link_active(&vd->vdev_dirty_node));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   523
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   524
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   525
	 * Free all children.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   526
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   527
	for (c = 0; c < vd->vdev_children; c++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   528
		vdev_free(vd->vdev_child[c]);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   529
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   530
	ASSERT(vd->vdev_child == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   531
	ASSERT(vd->vdev_guid_sum == vd->vdev_guid);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   532
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   533
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   534
	 * Discard allocation state.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   535
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   536
	if (vd == vd->vdev_top)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   537
		vdev_metaslab_fini(vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   538
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   539
	ASSERT3U(vd->vdev_stat.vs_space, ==, 0);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   540
	ASSERT3U(vd->vdev_stat.vs_dspace, ==, 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   541
	ASSERT3U(vd->vdev_stat.vs_alloc, ==, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   542
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   543
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   544
	 * Remove this vdev from its parent's child list.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   545
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   546
	vdev_remove_child(vd->vdev_parent, vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   547
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   548
	ASSERT(vd->vdev_parent == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   549
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   550
	/*
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   551
	 * Clean up vdev structure.
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   552
	 */
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   553
	vdev_queue_fini(vd);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   554
	vdev_cache_fini(vd);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   555
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   556
	if (vd->vdev_path)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   557
		spa_strfree(vd->vdev_path);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   558
	if (vd->vdev_devid)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   559
		spa_strfree(vd->vdev_devid);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   560
	if (vd->vdev_physpath)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   561
		spa_strfree(vd->vdev_physpath);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   562
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   563
	if (vd->vdev_isspare)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   564
		spa_spare_remove(vd);
5450
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
   565
	if (vd->vdev_isl2cache)
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
   566
		spa_l2cache_remove(vd);
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   567
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   568
	txg_list_destroy(&vd->vdev_ms_list);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   569
	txg_list_destroy(&vd->vdev_dtl_list);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   570
	mutex_enter(&vd->vdev_dtl_lock);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   571
	space_map_unload(&vd->vdev_dtl_map);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   572
	space_map_destroy(&vd->vdev_dtl_map);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   573
	space_map_vacate(&vd->vdev_dtl_scrub, NULL, NULL);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   574
	space_map_destroy(&vd->vdev_dtl_scrub);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   575
	mutex_exit(&vd->vdev_dtl_lock);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   576
	mutex_destroy(&vd->vdev_dtl_lock);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   577
	mutex_destroy(&vd->vdev_stat_lock);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   578
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   579
	if (vd == spa->spa_root_vdev)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   580
		spa->spa_root_vdev = NULL;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   581
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   582
	kmem_free(vd, sizeof (vdev_t));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   583
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   584
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   585
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   586
 * Transfer top-level vdev state from svd to tvd.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   587
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   588
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   589
vdev_top_transfer(vdev_t *svd, vdev_t *tvd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   590
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   591
	spa_t *spa = svd->vdev_spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   592
	metaslab_t *msp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   593
	vdev_t *vd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   594
	int t;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   595
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   596
	ASSERT(tvd == tvd->vdev_top);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   597
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   598
	tvd->vdev_ms_array = svd->vdev_ms_array;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   599
	tvd->vdev_ms_shift = svd->vdev_ms_shift;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   600
	tvd->vdev_ms_count = svd->vdev_ms_count;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   601
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   602
	svd->vdev_ms_array = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   603
	svd->vdev_ms_shift = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   604
	svd->vdev_ms_count = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   605
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   606
	tvd->vdev_mg = svd->vdev_mg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   607
	tvd->vdev_ms = svd->vdev_ms;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   608
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   609
	svd->vdev_mg = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   610
	svd->vdev_ms = NULL;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   611
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   612
	if (tvd->vdev_mg != NULL)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   613
		tvd->vdev_mg->mg_vd = tvd;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   614
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   615
	tvd->vdev_stat.vs_alloc = svd->vdev_stat.vs_alloc;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   616
	tvd->vdev_stat.vs_space = svd->vdev_stat.vs_space;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   617
	tvd->vdev_stat.vs_dspace = svd->vdev_stat.vs_dspace;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   618
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   619
	svd->vdev_stat.vs_alloc = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   620
	svd->vdev_stat.vs_space = 0;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   621
	svd->vdev_stat.vs_dspace = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   622
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   623
	for (t = 0; t < TXG_SIZE; t++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   624
		while ((msp = txg_list_remove(&svd->vdev_ms_list, t)) != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   625
			(void) txg_list_add(&tvd->vdev_ms_list, msp, t);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   626
		while ((vd = txg_list_remove(&svd->vdev_dtl_list, t)) != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   627
			(void) txg_list_add(&tvd->vdev_dtl_list, vd, t);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   628
		if (txg_list_remove_this(&spa->spa_vdev_txg_list, svd, t))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   629
			(void) txg_list_add(&spa->spa_vdev_txg_list, tvd, t);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   630
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   631
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   632
	if (list_link_active(&svd->vdev_dirty_node)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   633
		vdev_config_clean(svd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   634
		vdev_config_dirty(tvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   635
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   636
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   637
	tvd->vdev_deflate_ratio = svd->vdev_deflate_ratio;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   638
	svd->vdev_deflate_ratio = 0;
4527
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   639
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   640
	tvd->vdev_islog = svd->vdev_islog;
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   641
	svd->vdev_islog = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   642
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   643
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   644
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   645
vdev_top_update(vdev_t *tvd, vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   646
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   647
	int c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   648
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   649
	if (vd == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   650
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   651
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   652
	vd->vdev_top = tvd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   653
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   654
	for (c = 0; c < vd->vdev_children; c++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   655
		vdev_top_update(tvd, vd->vdev_child[c]);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   656
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   657
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   658
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   659
 * Add a mirror/replacing vdev above an existing vdev.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   660
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   661
vdev_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   662
vdev_add_parent(vdev_t *cvd, vdev_ops_t *ops)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   663
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   664
	spa_t *spa = cvd->vdev_spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   665
	vdev_t *pvd = cvd->vdev_parent;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   666
	vdev_t *mvd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   667
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   668
	ASSERT(spa_config_held(spa, RW_WRITER));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   669
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   670
	mvd = vdev_alloc_common(spa, cvd->vdev_id, 0, ops);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   671
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   672
	mvd->vdev_asize = cvd->vdev_asize;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   673
	mvd->vdev_ashift = cvd->vdev_ashift;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   674
	mvd->vdev_state = cvd->vdev_state;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   675
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   676
	vdev_remove_child(pvd, cvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   677
	vdev_add_child(pvd, mvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   678
	cvd->vdev_id = mvd->vdev_children;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   679
	vdev_add_child(mvd, cvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   680
	vdev_top_update(cvd->vdev_top, cvd->vdev_top);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   681
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   682
	if (mvd == mvd->vdev_top)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   683
		vdev_top_transfer(cvd, mvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   684
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   685
	return (mvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   686
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   687
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   688
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   689
 * Remove a 1-way mirror/replacing vdev from the tree.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   690
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   691
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   692
vdev_remove_parent(vdev_t *cvd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   693
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   694
	vdev_t *mvd = cvd->vdev_parent;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   695
	vdev_t *pvd = mvd->vdev_parent;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   696
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   697
	ASSERT(spa_config_held(cvd->vdev_spa, RW_WRITER));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   698
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   699
	ASSERT(mvd->vdev_children == 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   700
	ASSERT(mvd->vdev_ops == &vdev_mirror_ops ||
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   701
	    mvd->vdev_ops == &vdev_replacing_ops ||
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   702
	    mvd->vdev_ops == &vdev_spare_ops);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   703
	cvd->vdev_ashift = mvd->vdev_ashift;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   704
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   705
	vdev_remove_child(mvd, cvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   706
	vdev_remove_child(pvd, mvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   707
	cvd->vdev_id = mvd->vdev_id;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   708
	vdev_add_child(pvd, cvd);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   709
	/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   710
	 * 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
   711
	 * vdev GUID to match the old toplevel vdev.  Otherwise, we could have
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   712
	 * 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
   713
	 * think we have two toplevel vdevs, instead of a different version of
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   714
	 * the same toplevel vdev.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   715
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   716
	if (cvd->vdev_top == cvd) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   717
		pvd->vdev_guid_sum -= cvd->vdev_guid;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   718
		cvd->vdev_guid_sum -= cvd->vdev_guid;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   719
		cvd->vdev_guid = mvd->vdev_guid;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   720
		cvd->vdev_guid_sum += mvd->vdev_guid;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   721
		pvd->vdev_guid_sum += cvd->vdev_guid;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   722
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   723
	vdev_top_update(cvd->vdev_top, cvd->vdev_top);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   724
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   725
	if (cvd == cvd->vdev_top)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   726
		vdev_top_transfer(mvd, cvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   727
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   728
	ASSERT(mvd->vdev_children == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   729
	vdev_free(mvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   730
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   731
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   732
int
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   733
vdev_metaslab_init(vdev_t *vd, uint64_t txg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   734
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   735
	spa_t *spa = vd->vdev_spa;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   736
	objset_t *mos = spa->spa_meta_objset;
4527
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   737
	metaslab_class_t *mc;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   738
	uint64_t m;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   739
	uint64_t oldc = vd->vdev_ms_count;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   740
	uint64_t newc = vd->vdev_asize >> vd->vdev_ms_shift;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   741
	metaslab_t **mspp;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   742
	int error;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   743
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   744
	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
   745
		return (0);
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   746
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   747
	dprintf("%s oldc %llu newc %llu\n", vdev_description(vd), oldc, newc);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   748
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   749
	ASSERT(oldc <= newc);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   750
4527
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   751
	if (vd->vdev_islog)
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   752
		mc = spa->spa_log_class;
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   753
	else
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   754
		mc = spa->spa_normal_class;
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
   755
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   756
	if (vd->vdev_mg == NULL)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   757
		vd->vdev_mg = metaslab_group_create(mc, vd);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   758
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   759
	mspp = kmem_zalloc(newc * sizeof (*mspp), KM_SLEEP);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   760
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   761
	if (oldc != 0) {
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   762
		bcopy(vd->vdev_ms, mspp, oldc * sizeof (*mspp));
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   763
		kmem_free(vd->vdev_ms, oldc * sizeof (*mspp));
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   764
	}
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   765
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   766
	vd->vdev_ms = mspp;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   767
	vd->vdev_ms_count = newc;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   768
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   769
	for (m = oldc; m < newc; m++) {
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   770
		space_map_obj_t smo = { 0, 0, 0 };
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   771
		if (txg == 0) {
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   772
			uint64_t object = 0;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   773
			error = dmu_read(mos, vd->vdev_ms_array,
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   774
			    m * sizeof (uint64_t), sizeof (uint64_t), &object);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   775
			if (error)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   776
				return (error);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   777
			if (object != 0) {
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   778
				dmu_buf_t *db;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   779
				error = dmu_bonus_hold(mos, object, FTAG, &db);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   780
				if (error)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   781
					return (error);
4944
96d96f8de974 6569719 panic dangling dbufs (dn=ffffffff28814d30, dbuf=ffffffff20756008)
maybee
parents: 4808
diff changeset
   782
				ASSERT3U(db->db_size, >=, sizeof (smo));
96d96f8de974 6569719 panic dangling dbufs (dn=ffffffff28814d30, dbuf=ffffffff20756008)
maybee
parents: 4808
diff changeset
   783
				bcopy(db->db_data, &smo, sizeof (smo));
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   784
				ASSERT3U(smo.smo_object, ==, object);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   785
				dmu_buf_rele(db, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   786
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   787
		}
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   788
		vd->vdev_ms[m] = metaslab_init(vd->vdev_mg, &smo,
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   789
		    m << vd->vdev_ms_shift, 1ULL << vd->vdev_ms_shift, txg);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   790
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   791
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   792
	return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   793
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   794
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   795
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   796
vdev_metaslab_fini(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   797
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   798
	uint64_t m;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   799
	uint64_t count = vd->vdev_ms_count;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   800
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   801
	if (vd->vdev_ms != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   802
		for (m = 0; m < count; m++)
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   803
			if (vd->vdev_ms[m] != NULL)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   804
				metaslab_fini(vd->vdev_ms[m]);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   805
		kmem_free(vd->vdev_ms, count * sizeof (metaslab_t *));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   806
		vd->vdev_ms = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   807
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   808
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   809
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   810
int
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   811
vdev_probe(vdev_t *vd)
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   812
{
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   813
	if (vd == NULL)
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   814
		return (EINVAL);
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   815
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   816
	/*
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   817
	 * Right now we only support status checks on the leaf vdevs.
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   818
	 */
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   819
	if (vd->vdev_ops->vdev_op_leaf)
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   820
		return (vd->vdev_ops->vdev_op_probe(vd));
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   821
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   822
	return (0);
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   823
}
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   824
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   825
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   826
 * Prepare a virtual device for access.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   827
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   828
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   829
vdev_open(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   830
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   831
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   832
	int c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   833
	uint64_t osize = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   834
	uint64_t asize, psize;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   835
	uint64_t ashift = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   836
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   837
	ASSERT(vd->vdev_state == VDEV_STATE_CLOSED ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   838
	    vd->vdev_state == VDEV_STATE_CANT_OPEN ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   839
	    vd->vdev_state == VDEV_STATE_OFFLINE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   840
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   841
	if (vd->vdev_fault_mode == VDEV_FAULT_COUNT)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   842
		vd->vdev_fault_arg >>= 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   843
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   844
		vd->vdev_fault_mode = VDEV_FAULT_NONE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   845
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   846
	vd->vdev_stat.vs_aux = VDEV_AUX_NONE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   847
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   848
	if (!vd->vdev_removed && vd->vdev_faulted) {
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   849
		ASSERT(vd->vdev_children == 0);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   850
		vdev_set_state(vd, B_TRUE, VDEV_STATE_FAULTED,
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   851
		    VDEV_AUX_ERR_EXCEEDED);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   852
		return (ENXIO);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   853
	} else if (vd->vdev_offline) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   854
		ASSERT(vd->vdev_children == 0);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   855
		vdev_set_state(vd, B_TRUE, VDEV_STATE_OFFLINE, VDEV_AUX_NONE);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   856
		return (ENXIO);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   857
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   858
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   859
	error = vd->vdev_ops->vdev_op_open(vd, &osize, &ashift);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   860
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   861
	if (zio_injection_enabled && error == 0)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   862
		error = zio_handle_device_injection(vd, ENXIO);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   863
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   864
	if (error) {
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   865
		if (vd->vdev_removed &&
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   866
		    vd->vdev_stat.vs_aux != VDEV_AUX_OPEN_FAILED)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   867
			vd->vdev_removed = B_FALSE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   868
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   869
		vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   870
		    vd->vdev_stat.vs_aux);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   871
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   872
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   873
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   874
	vd->vdev_removed = B_FALSE;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   875
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   876
	if (vd->vdev_degraded) {
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   877
		ASSERT(vd->vdev_children == 0);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   878
		vdev_set_state(vd, B_TRUE, VDEV_STATE_DEGRADED,
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   879
		    VDEV_AUX_ERR_EXCEEDED);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   880
	} else {
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   881
		vd->vdev_state = VDEV_STATE_HEALTHY;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   882
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   883
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   884
	for (c = 0; c < vd->vdev_children; c++)
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   885
		if (vd->vdev_child[c]->vdev_state != VDEV_STATE_HEALTHY) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   886
			vdev_set_state(vd, B_TRUE, VDEV_STATE_DEGRADED,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   887
			    VDEV_AUX_NONE);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   888
			break;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   889
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   890
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   891
	osize = P2ALIGN(osize, (uint64_t)sizeof (vdev_label_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   892
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   893
	if (vd->vdev_children == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   894
		if (osize < SPA_MINDEVSIZE) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   895
			vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   896
			    VDEV_AUX_TOO_SMALL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   897
			return (EOVERFLOW);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   898
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   899
		psize = osize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   900
		asize = osize - (VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   901
	} else {
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   902
		if (vd->vdev_parent != NULL && osize < SPA_MINDEVSIZE -
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   903
		    (VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE)) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   904
			vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   905
			    VDEV_AUX_TOO_SMALL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   906
			return (EOVERFLOW);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   907
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   908
		psize = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   909
		asize = osize;
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
	vd->vdev_psize = psize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   913
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   914
	if (vd->vdev_asize == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   915
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   916
		 * This is the first-ever open, so use the computed values.
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   917
		 * For testing purposes, a higher ashift can be requested.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   918
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   919
		vd->vdev_asize = asize;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   920
		vd->vdev_ashift = MAX(ashift, vd->vdev_ashift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   921
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   922
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   923
		 * Make sure the alignment requirement hasn't increased.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   924
		 */
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
   925
		if (ashift > vd->vdev_top->vdev_ashift) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   926
			vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   927
			    VDEV_AUX_BAD_LABEL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   928
			return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   929
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   930
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   931
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   932
		 * Make sure the device hasn't shrunk.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   933
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   934
		if (asize < vd->vdev_asize) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   935
			vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   936
			    VDEV_AUX_BAD_LABEL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   937
			return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   938
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   939
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   940
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   941
		 * If all children are healthy and the asize has increased,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   942
		 * then we've experienced dynamic LUN growth.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   943
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   944
		if (vd->vdev_state == VDEV_STATE_HEALTHY &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   945
		    asize > vd->vdev_asize) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   946
			vd->vdev_asize = asize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   947
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   948
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   949
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
   950
	/*
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   951
	 * Ensure we can issue some IO before declaring the
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   952
	 * vdev open for business.
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   953
	 */
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   954
	error = vdev_probe(vd);
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   955
	if (error) {
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   956
		vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   957
		    VDEV_AUX_OPEN_FAILED);
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   958
		return (error);
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   959
	}
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   960
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
   961
	/*
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   962
	 * If this is a top-level vdev, compute the raidz-deflation
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   963
	 * 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
   964
	 * current "typical" blocksize.  Even if SPA_MAXBLOCKSIZE
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   965
	 * changes, this algorithm must never change, or we will
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   966
	 * inconsistently account for existing bp's.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   967
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   968
	if (vd->vdev_top == vd) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   969
		vd->vdev_deflate_ratio = (1<<17) /
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   970
		    (vdev_psize_to_asize(vd, 1<<17) >> SPA_MINBLOCKSHIFT);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   971
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   972
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   973
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   974
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   975
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   976
/*
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   977
 * 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
   978
 * contents.  This needs to be done before vdev_load() so that we don't
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
   979
 * inadvertently do repair I/Os to the wrong device.
1986
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
 * 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
   982
 * 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
   983
 * /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
   984
 * 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
   985
 */
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   986
int
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   987
vdev_validate(vdev_t *vd)
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
	spa_t *spa = vd->vdev_spa;
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   990
	int c;
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   991
	nvlist_t *label;
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   992
	uint64_t guid;
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   993
	uint64_t state;
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   994
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   995
	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
   996
		if (vdev_validate(vd->vdev_child[c]) != 0)
4070
4390ea390a1e 6386594 zdb message should be clearer when failing for lack of permissions
mc142369
parents: 3697
diff changeset
   997
			return (EBADF);
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   998
2174
73de7a781492 6433717 offline devices should not be marked persistently unavailble
eschrock
parents: 2082
diff changeset
   999
	/*
73de7a781492 6433717 offline devices should not be marked persistently unavailble
eschrock
parents: 2082
diff changeset
  1000
	 * 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
  1001
	 * 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
  1002
	 * overwrite the previous state.
73de7a781492 6433717 offline devices should not be marked persistently unavailble
eschrock
parents: 2082
diff changeset
  1003
	 */
73de7a781492 6433717 offline devices should not be marked persistently unavailble
eschrock
parents: 2082
diff changeset
  1004
	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
  1005
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1006
		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
  1007
			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
  1008
			    VDEV_AUX_BAD_LABEL);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1009
			return (0);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1010
		}
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1011
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1012
		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
  1013
		    &guid) != 0 || guid != spa_guid(spa)) {
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1014
			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
  1015
			    VDEV_AUX_CORRUPT_DATA);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1016
			nvlist_free(label);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1017
			return (0);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1018
		}
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1019
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1020
		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
  1021
		    &guid) != 0 || guid != vd->vdev_guid) {
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1022
			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
  1023
			    VDEV_AUX_CORRUPT_DATA);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1024
			nvlist_free(label);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1025
			return (0);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1026
		}
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1027
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1028
		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
  1029
		    &state) != 0) {
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1030
			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
  1031
			    VDEV_AUX_CORRUPT_DATA);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1032
			nvlist_free(label);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1033
			return (0);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1034
		}
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1035
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1036
		nvlist_free(label);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1037
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1038
		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
  1039
		    state != POOL_STATE_ACTIVE)
4070
4390ea390a1e 6386594 zdb message should be clearer when failing for lack of permissions
mc142369
parents: 3697
diff changeset
  1040
			return (EBADF);
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1041
	}
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1042
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1043
	/*
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1044
	 * 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
  1045
	 * 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
  1046
	 */
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1047
	if (vd->vdev_not_present)
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1048
		vd->vdev_not_present = 0;
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1049
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1050
	return (0);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1051
}
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1052
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1053
/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1054
 * Close a virtual device.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1055
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1056
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1057
vdev_close(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1058
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1059
	vd->vdev_ops->vdev_op_close(vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1060
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1061
	vdev_cache_purge(vd);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1062
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1063
	/*
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1064
	 * 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
  1065
	 * 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
  1066
	 * it's still faulted.
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1067
	 */
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1068
	vd->vdev_prevstate = vd->vdev_state;
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1069
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1070
	if (vd->vdev_offline)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1071
		vd->vdev_state = VDEV_STATE_OFFLINE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1072
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1073
		vd->vdev_state = VDEV_STATE_CLOSED;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1074
	vd->vdev_stat.vs_aux = VDEV_AUX_NONE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1075
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1076
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1077
void
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1078
vdev_reopen(vdev_t *vd)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1079
{
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1080
	spa_t *spa = vd->vdev_spa;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1081
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1082
	ASSERT(spa_config_held(spa, RW_WRITER));
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1083
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1084
	vdev_close(vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1085
	(void) vdev_open(vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1086
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1087
	/*
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3059
diff changeset
  1088
	 * Call vdev_validate() here to make sure we have the same device.
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3059
diff changeset
  1089
	 * Otherwise, a device with an invalid label could be successfully
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3059
diff changeset
  1090
	 * opened in response to vdev_reopen().
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3059
diff changeset
  1091
	 */
6643
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1092
	if (vd->vdev_aux) {
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1093
		(void) vdev_validate_aux(vd);
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1094
		if (!vdev_is_dead(vd) &&
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1095
		    !l2arc_vdev_present(vd)) {
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1096
			uint64_t size = vdev_get_rsize(vd);
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1097
			l2arc_add_vdev(spa, vd,
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1098
			    VDEV_LABEL_START_SIZE,
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1099
			    size - VDEV_LABEL_START_SIZE);
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1100
		}
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1101
	} else {
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1102
		(void) vdev_validate(vd);
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1103
	}
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3059
diff changeset
  1104
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3059
diff changeset
  1105
	/*
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1106
	 * Reassess parent vdev's health.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1107
	 */
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1108
	vdev_propagate_state(vd);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1109
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1110
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1111
int
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1112
vdev_create(vdev_t *vd, uint64_t txg, boolean_t isreplacing)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1113
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1114
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1115
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1116
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1117
	 * Normally, partial opens (e.g. of a mirror) are allowed.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1118
	 * For a create, however, we want to fail the request if
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1119
	 * there are any components we can't open.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1120
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1121
	error = vdev_open(vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1122
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1123
	if (error || vd->vdev_state != VDEV_STATE_HEALTHY) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1124
		vdev_close(vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1125
		return (error ? error : ENXIO);
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
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1129
	 * Recursively initialize all labels.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1130
	 */
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3059
diff changeset
  1131
	if ((error = vdev_label_init(vd, txg, isreplacing ?
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3059
diff changeset
  1132
	    VDEV_LABEL_REPLACE : VDEV_LABEL_CREATE)) != 0) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1133
		vdev_close(vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1134
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1135
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1136
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1137
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1138
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1139
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1140
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1141
 * The is the latter half of vdev_create().  It is distinct because it
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1142
 * involves initiating transactions in order to do metaslab creation.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1143
 * 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
  1144
 * if anything fails; this is much harder if we have pending transactions.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1145
 */
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1146
void
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1147
vdev_init(vdev_t *vd, uint64_t txg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1148
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1149
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1150
	 * Aim for roughly 200 metaslabs per vdev.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1151
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1152
	vd->vdev_ms_shift = highbit(vd->vdev_asize / 200);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1153
	vd->vdev_ms_shift = MAX(vd->vdev_ms_shift, SPA_MAXBLOCKSHIFT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1154
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1155
	/*
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1156
	 * 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
  1157
	 * there's nothing to read when creating all new metaslabs.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1158
	 */
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1159
	VERIFY(vdev_metaslab_init(vd, txg) == 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1160
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1161
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1162
void
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1163
vdev_dirty(vdev_t *vd, int flags, void *arg, uint64_t txg)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1164
{
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1165
	ASSERT(vd == vd->vdev_top);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1166
	ASSERT(ISP2(flags));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1167
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1168
	if (flags & VDD_METASLAB)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1169
		(void) txg_list_add(&vd->vdev_ms_list, arg, txg);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1170
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1171
	if (flags & VDD_DTL)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1172
		(void) txg_list_add(&vd->vdev_dtl_list, arg, txg);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1173
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1174
	(void) txg_list_add(&vd->vdev_spa->spa_vdev_txg_list, vd, txg);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1175
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1176
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1177
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1178
vdev_dtl_dirty(space_map_t *sm, uint64_t txg, uint64_t size)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1179
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1180
	mutex_enter(sm->sm_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1181
	if (!space_map_contains(sm, txg, size))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1182
		space_map_add(sm, txg, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1183
	mutex_exit(sm->sm_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1184
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1185
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1186
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1187
vdev_dtl_contains(space_map_t *sm, uint64_t txg, uint64_t size)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1188
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1189
	int dirty;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1190
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1191
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1192
	 * Quick test without the lock -- covers the common case that
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1193
	 * there are no dirty time segments.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1194
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1195
	if (sm->sm_space == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1196
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1197
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1198
	mutex_enter(sm->sm_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1199
	dirty = space_map_contains(sm, txg, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1200
	mutex_exit(sm->sm_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1201
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1202
	return (dirty);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1203
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1204
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1205
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1206
 * Reassess DTLs after a config change or scrub completion.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1207
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1208
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1209
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
  1210
{
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1211
	spa_t *spa = vd->vdev_spa;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1212
	int c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1213
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1214
	ASSERT(spa_config_held(spa, RW_WRITER));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1215
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1216
	if (vd->vdev_children == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1217
		mutex_enter(&vd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1218
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1219
		 * We're successfully scrubbed everything up to scrub_txg.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1220
		 * Therefore, excise all old DTLs up to that point, then
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1221
		 * fold in the DTLs for everything we couldn't scrub.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1222
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1223
		if (scrub_txg != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1224
			space_map_excise(&vd->vdev_dtl_map, 0, scrub_txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1225
			space_map_union(&vd->vdev_dtl_map, &vd->vdev_dtl_scrub);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1226
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1227
		if (scrub_done)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1228
			space_map_vacate(&vd->vdev_dtl_scrub, NULL, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1229
		mutex_exit(&vd->vdev_dtl_lock);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1230
		if (txg != 0)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1231
			vdev_dirty(vd->vdev_top, VDD_DTL, vd, txg);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1232
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1233
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1234
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1235
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1236
	 * Make sure the DTLs are always correct under the scrub lock.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1237
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1238
	if (vd == spa->spa_root_vdev)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1239
		mutex_enter(&spa->spa_scrub_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1240
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1241
	mutex_enter(&vd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1242
	space_map_vacate(&vd->vdev_dtl_map, NULL, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1243
	space_map_vacate(&vd->vdev_dtl_scrub, NULL, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1244
	mutex_exit(&vd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1245
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1246
	for (c = 0; c < vd->vdev_children; c++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1247
		vdev_t *cvd = vd->vdev_child[c];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1248
		vdev_dtl_reassess(cvd, txg, scrub_txg, scrub_done);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1249
		mutex_enter(&vd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1250
		space_map_union(&vd->vdev_dtl_map, &cvd->vdev_dtl_map);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1251
		space_map_union(&vd->vdev_dtl_scrub, &cvd->vdev_dtl_scrub);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1252
		mutex_exit(&vd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1253
	}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1254
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1255
	if (vd == spa->spa_root_vdev)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1256
		mutex_exit(&spa->spa_scrub_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1257
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1258
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1259
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1260
vdev_dtl_load(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1261
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1262
	spa_t *spa = vd->vdev_spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1263
	space_map_obj_t *smo = &vd->vdev_dtl;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1264
	objset_t *mos = spa->spa_meta_objset;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1265
	dmu_buf_t *db;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1266
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1267
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1268
	ASSERT(vd->vdev_children == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1269
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1270
	if (smo->smo_object == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1271
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1272
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1273
	if ((error = dmu_bonus_hold(mos, smo->smo_object, FTAG, &db)) != 0)
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1274
		return (error);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1275
4944
96d96f8de974 6569719 panic dangling dbufs (dn=ffffffff28814d30, dbuf=ffffffff20756008)
maybee
parents: 4808
diff changeset
  1276
	ASSERT3U(db->db_size, >=, sizeof (*smo));
96d96f8de974 6569719 panic dangling dbufs (dn=ffffffff28814d30, dbuf=ffffffff20756008)
maybee
parents: 4808
diff changeset
  1277
	bcopy(db->db_data, smo, sizeof (*smo));
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1278
	dmu_buf_rele(db, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1279
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1280
	mutex_enter(&vd->vdev_dtl_lock);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1281
	error = space_map_load(&vd->vdev_dtl_map, NULL, SM_ALLOC, smo, mos);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1282
	mutex_exit(&vd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1283
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1284
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1285
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1286
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1287
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1288
vdev_dtl_sync(vdev_t *vd, uint64_t txg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1289
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1290
	spa_t *spa = vd->vdev_spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1291
	space_map_obj_t *smo = &vd->vdev_dtl;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1292
	space_map_t *sm = &vd->vdev_dtl_map;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1293
	objset_t *mos = spa->spa_meta_objset;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1294
	space_map_t smsync;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1295
	kmutex_t smlock;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1296
	dmu_buf_t *db;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1297
	dmu_tx_t *tx;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1298
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1299
	dprintf("%s in txg %llu pass %d\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1300
	    vdev_description(vd), (u_longlong_t)txg, spa_sync_pass(spa));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1301
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1302
	tx = dmu_tx_create_assigned(spa->spa_dsl_pool, txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1303
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1304
	if (vd->vdev_detached) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1305
		if (smo->smo_object != 0) {
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1306
			int err = dmu_object_free(mos, smo->smo_object, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1307
			ASSERT3U(err, ==, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1308
			smo->smo_object = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1309
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1310
		dmu_tx_commit(tx);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1311
		dprintf("detach %s committed in txg %llu\n",
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1312
		    vdev_description(vd), txg);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1313
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1314
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1315
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1316
	if (smo->smo_object == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1317
		ASSERT(smo->smo_objsize == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1318
		ASSERT(smo->smo_alloc == 0);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1319
		smo->smo_object = dmu_object_alloc(mos,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1320
		    DMU_OT_SPACE_MAP, 1 << SPACE_MAP_BLOCKSHIFT,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1321
		    DMU_OT_SPACE_MAP_HEADER, sizeof (*smo), tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1322
		ASSERT(smo->smo_object != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1323
		vdev_config_dirty(vd->vdev_top);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1324
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1325
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1326
	mutex_init(&smlock, NULL, MUTEX_DEFAULT, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1327
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1328
	space_map_create(&smsync, sm->sm_start, sm->sm_size, sm->sm_shift,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1329
	    &smlock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1330
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1331
	mutex_enter(&smlock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1332
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1333
	mutex_enter(&vd->vdev_dtl_lock);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1334
	space_map_walk(sm, space_map_add, &smsync);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1335
	mutex_exit(&vd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1336
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1337
	space_map_truncate(smo, mos, tx);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1338
	space_map_sync(&smsync, SM_ALLOC, smo, mos, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1339
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1340
	space_map_destroy(&smsync);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1341
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1342
	mutex_exit(&smlock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1343
	mutex_destroy(&smlock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1344
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1345
	VERIFY(0 == dmu_bonus_hold(mos, smo->smo_object, FTAG, &db));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1346
	dmu_buf_will_dirty(db, tx);
4944
96d96f8de974 6569719 panic dangling dbufs (dn=ffffffff28814d30, dbuf=ffffffff20756008)
maybee
parents: 4808
diff changeset
  1347
	ASSERT3U(db->db_size, >=, sizeof (*smo));
96d96f8de974 6569719 panic dangling dbufs (dn=ffffffff28814d30, dbuf=ffffffff20756008)
maybee
parents: 4808
diff changeset
  1348
	bcopy(smo, db->db_data, sizeof (*smo));
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1349
	dmu_buf_rele(db, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1350
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1351
	dmu_tx_commit(tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1352
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1353
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1354
void
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1355
vdev_load(vdev_t *vd)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1356
{
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1357
	int c;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1358
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1359
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1360
	 * Recursively load all children.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1361
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1362
	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
  1363
		vdev_load(vd->vdev_child[c]);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1364
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1365
	/*
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1366
	 * If this is a top-level vdev, initialize its metaslabs.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1367
	 */
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1368
	if (vd == vd->vdev_top &&
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1369
	    (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
  1370
	    vdev_metaslab_init(vd, 0) != 0))
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1371
		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
  1372
		    VDEV_AUX_CORRUPT_DATA);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1373
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1374
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1375
	 * If this is a leaf vdev, load its DTL.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1376
	 */
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  1377
	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
  1378
		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
  1379
		    VDEV_AUX_CORRUPT_DATA);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1380
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1381
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1382
/*
5450
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  1383
 * The special vdev case is used for hot spares and l2cache devices.  Its
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  1384
 * sole purpose it to set the vdev state for the associated vdev.  To do this,
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  1385
 * we make sure that we can open the underlying device, then try to read the
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  1386
 * label, and make sure that the label is sane and that it hasn't been
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  1387
 * repurposed to another pool.
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1388
 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1389
int
5450
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  1390
vdev_validate_aux(vdev_t *vd)
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1391
{
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1392
	nvlist_t *label;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1393
	uint64_t guid, version;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1394
	uint64_t state;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1395
6643
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1396
	if (vdev_is_dead(vd))
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1397
		return (0);
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1398
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1399
	if ((label = vdev_label_read_config(vd)) == NULL) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1400
		vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1401
		    VDEV_AUX_CORRUPT_DATA);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1402
		return (-1);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1403
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1404
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1405
	if (nvlist_lookup_uint64(label, ZPOOL_CONFIG_VERSION, &version) != 0 ||
4577
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4527
diff changeset
  1406
	    version > SPA_VERSION ||
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1407
	    nvlist_lookup_uint64(label, ZPOOL_CONFIG_GUID, &guid) != 0 ||
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1408
	    guid != vd->vdev_guid ||
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1409
	    nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_STATE, &state) != 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1410
		vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1411
		    VDEV_AUX_CORRUPT_DATA);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1412
		nvlist_free(label);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1413
		return (-1);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1414
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1415
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1416
	/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1417
	 * 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
  1418
	 * 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
  1419
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1420
	nvlist_free(label);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1421
	return (0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1422
}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1423
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1424
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1425
vdev_sync_done(vdev_t *vd, uint64_t txg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1426
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1427
	metaslab_t *msp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1428
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1429
	dprintf("%s txg %llu\n", vdev_description(vd), txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1430
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1431
	while (msp = txg_list_remove(&vd->vdev_ms_list, TXG_CLEAN(txg)))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1432
		metaslab_sync_done(msp, txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1433
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1434
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1435
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1436
vdev_sync(vdev_t *vd, uint64_t txg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1437
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1438
	spa_t *spa = vd->vdev_spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1439
	vdev_t *lvd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1440
	metaslab_t *msp;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1441
	dmu_tx_t *tx;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1442
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1443
	dprintf("%s txg %llu pass %d\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1444
	    vdev_description(vd), (u_longlong_t)txg, spa_sync_pass(spa));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1445
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1446
	if (vd->vdev_ms_array == 0 && vd->vdev_ms_shift != 0) {
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1447
		ASSERT(vd == vd->vdev_top);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1448
		tx = dmu_tx_create_assigned(spa->spa_dsl_pool, txg);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1449
		vd->vdev_ms_array = dmu_object_alloc(spa->spa_meta_objset,
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1450
		    DMU_OT_OBJECT_ARRAY, 0, DMU_OT_NONE, 0, tx);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1451
		ASSERT(vd->vdev_ms_array != 0);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1452
		vdev_config_dirty(vd);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1453
		dmu_tx_commit(tx);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1454
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1455
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1456
	while ((msp = txg_list_remove(&vd->vdev_ms_list, txg)) != NULL) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1457
		metaslab_sync(msp, txg);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1458
		(void) txg_list_add(&vd->vdev_ms_list, msp, TXG_CLEAN(txg));
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1459
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1460
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1461
	while ((lvd = txg_list_remove(&vd->vdev_dtl_list, txg)) != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1462
		vdev_dtl_sync(lvd, txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1463
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1464
	(void) txg_list_add(&spa->spa_vdev_txg_list, vd, TXG_CLEAN(txg));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1465
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1466
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1467
uint64_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1468
vdev_psize_to_asize(vdev_t *vd, uint64_t psize)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1469
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1470
	return (vd->vdev_ops->vdev_op_asize(vd, psize));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1471
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1472
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1473
const char *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1474
vdev_description(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1475
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1476
	if (vd == NULL || vd->vdev_ops == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1477
		return ("<unknown>");
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1478
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1479
	if (vd->vdev_path != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1480
		return (vd->vdev_path);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1481
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1482
	if (vd->vdev_parent == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1483
		return (spa_name(vd->vdev_spa));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1484
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1485
	return (vd->vdev_ops->vdev_op_type);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1486
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1487
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1488
/*
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1489
 * Mark the given vdev faulted.  A faulted vdev behaves as if the device could
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1490
 * not be opened, and no I/O is attempted.
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1491
 */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1492
int
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1493
vdev_fault(spa_t *spa, uint64_t guid)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1494
{
6643
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1495
	vdev_t *vd;
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1496
	uint64_t txg;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1497
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1498
	/*
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1499
	 * Disregard a vdev fault request if the pool has
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1500
	 * experienced a complete failure.
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1501
	 *
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1502
	 * XXX - We do this here so that we don't hold the
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1503
	 * spa_namespace_lock in the event that we can't get
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1504
	 * the RW_WRITER spa_config_lock.
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1505
	 */
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1506
	if (spa_state(spa) == POOL_STATE_IO_FAILURE)
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1507
		return (EIO);
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1508
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1509
	txg = spa_vdev_enter(spa);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1510
6643
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1511
	if ((vd = spa_lookup_by_guid(spa, guid, B_TRUE)) == NULL)
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1512
		return (spa_vdev_exit(spa, NULL, txg, ENODEV));
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1513
	if (!vd->vdev_ops->vdev_op_leaf)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1514
		return (spa_vdev_exit(spa, NULL, txg, ENOTSUP));
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1515
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1516
	/*
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1517
	 * Faulted state takes precedence over degraded.
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1518
	 */
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1519
	vd->vdev_faulted = 1ULL;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1520
	vd->vdev_degraded = 0ULL;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1521
	vdev_set_state(vd, B_FALSE, VDEV_STATE_FAULTED,
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1522
	    VDEV_AUX_ERR_EXCEEDED);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1523
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1524
	/*
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1525
	 * If marking the vdev as faulted cause the toplevel vdev to become
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1526
	 * unavailable, then back off and simply mark the vdev as degraded
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1527
	 * instead.
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1528
	 */
6643
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1529
	if (vdev_is_dead(vd->vdev_top) && vd->vdev_aux == NULL) {
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1530
		vd->vdev_degraded = 1ULL;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1531
		vd->vdev_faulted = 0ULL;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1532
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1533
		/*
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1534
		 * If we reopen the device and it's not dead, only then do we
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1535
		 * mark it degraded.
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1536
		 */
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1537
		vdev_reopen(vd);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1538
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1539
		if (vdev_readable(vd)) {
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1540
			vdev_set_state(vd, B_FALSE, VDEV_STATE_DEGRADED,
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1541
			    VDEV_AUX_ERR_EXCEEDED);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1542
		}
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1543
	}
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1544
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1545
	vdev_config_dirty(vd->vdev_top);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1546
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1547
	(void) spa_vdev_exit(spa, NULL, txg, 0);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1548
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1549
	return (0);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1550
}
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1551
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1552
/*
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1553
 * Mark the given vdev degraded.  A degraded vdev is purely an indication to the
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1554
 * user that something is wrong.  The vdev continues to operate as normal as far
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1555
 * as I/O is concerned.
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1556
 */
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1557
int
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1558
vdev_degrade(spa_t *spa, uint64_t guid)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1559
{
6643
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1560
	vdev_t *vd;
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1561
	uint64_t txg;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1562
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1563
	/*
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1564
	 * Disregard a vdev fault request if the pool has
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1565
	 * experienced a complete failure.
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1566
	 *
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1567
	 * XXX - We do this here so that we don't hold the
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1568
	 * spa_namespace_lock in the event that we can't get
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1569
	 * the RW_WRITER spa_config_lock.
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1570
	 */
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1571
	if (spa_state(spa) == POOL_STATE_IO_FAILURE)
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1572
		return (EIO);
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1573
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1574
	txg = spa_vdev_enter(spa);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1575
6643
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1576
	if ((vd = spa_lookup_by_guid(spa, guid, B_TRUE)) == NULL)
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1577
		return (spa_vdev_exit(spa, NULL, txg, ENODEV));
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1578
	if (!vd->vdev_ops->vdev_op_leaf)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1579
		return (spa_vdev_exit(spa, NULL, txg, ENOTSUP));
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1580
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1581
	/*
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1582
	 * If the vdev is already faulted, then don't do anything.
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1583
	 */
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1584
	if (vd->vdev_faulted || vd->vdev_degraded) {
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1585
		(void) spa_vdev_exit(spa, NULL, txg, 0);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1586
		return (0);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1587
	}
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1588
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1589
	vd->vdev_degraded = 1ULL;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1590
	if (!vdev_is_dead(vd))
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1591
		vdev_set_state(vd, B_FALSE, VDEV_STATE_DEGRADED,
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1592
		    VDEV_AUX_ERR_EXCEEDED);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1593
	vdev_config_dirty(vd->vdev_top);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1594
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1595
	(void) spa_vdev_exit(spa, NULL, txg, 0);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1596
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1597
	return (0);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1598
}
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1599
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1600
/*
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1601
 * Online the given vdev.  If 'unspare' is set, it implies two things.  First,
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1602
 * any attached spare device should be detached when the device finishes
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1603
 * resilvering.  Second, the online should be treated like a 'test' online case,
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1604
 * so no FMA events are generated if the device fails to open.
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1605
 */
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1606
int
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1607
vdev_online(spa_t *spa, uint64_t guid, uint64_t flags,
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1608
    vdev_state_t *newstate)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1609
{
6643
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1610
	vdev_t *vd;
1485
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1611
	uint64_t txg;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1612
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1613
	/*
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1614
	 * Disregard a vdev fault request if the pool has
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1615
	 * experienced a complete failure.
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1616
	 *
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1617
	 * XXX - We do this here so that we don't hold the
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1618
	 * spa_namespace_lock in the event that we can't get
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1619
	 * the RW_WRITER spa_config_lock.
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1620
	 */
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1621
	if (spa_state(spa) == POOL_STATE_IO_FAILURE)
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1622
		return (EIO);
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1623
1485
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1624
	txg = spa_vdev_enter(spa);
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1625
6643
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1626
	if ((vd = spa_lookup_by_guid(spa, guid, B_TRUE)) == NULL)
1485
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1627
		return (spa_vdev_exit(spa, NULL, txg, ENODEV));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1628
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1629
	if (!vd->vdev_ops->vdev_op_leaf)
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1630
		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
  1631
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1632
	vd->vdev_offline = B_FALSE;
1485
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1633
	vd->vdev_tmpoffline = B_FALSE;
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1634
	vd->vdev_checkremove = (flags & ZFS_ONLINE_CHECKREMOVE) ?
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1635
	    B_TRUE : B_FALSE;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1636
	vd->vdev_forcefault = (flags & ZFS_ONLINE_FORCEFAULT) ?
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1637
	    B_TRUE : B_FALSE;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1638
	vdev_reopen(vd->vdev_top);
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1639
	vd->vdev_checkremove = vd->vdev_forcefault = B_FALSE;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1640
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1641
	if (newstate)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1642
		*newstate = vd->vdev_state;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1643
	if ((flags & ZFS_ONLINE_UNSPARE) &&
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1644
	    !vdev_is_dead(vd) && vd->vdev_parent &&
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1645
	    vd->vdev_parent->vdev_ops == &vdev_spare_ops &&
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1646
	    vd->vdev_parent->vdev_child[0] == vd)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1647
		vd->vdev_unspare = B_TRUE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1648
1485
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1649
	vdev_config_dirty(vd->vdev_top);
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1650
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1651
	(void) spa_vdev_exit(spa, NULL, txg, 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1652
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1653
	/*
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1654
	 * Must hold spa_namespace_lock in order to post resilver sysevent
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1655
	 * w/pool name.
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1656
	 */
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1657
	mutex_enter(&spa_namespace_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1658
	VERIFY(spa_scrub(spa, POOL_SCRUB_RESILVER, B_TRUE) == 0);
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1659
	mutex_exit(&spa_namespace_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1660
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1661
	return (0);
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
int
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1665
vdev_offline(spa_t *spa, uint64_t guid, uint64_t flags)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1666
{
6643
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1667
	vdev_t *vd;
1485
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1668
	uint64_t txg;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1669
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1670
	/*
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1671
	 * Disregard a vdev fault request if the pool has
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1672
	 * experienced a complete failure.
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1673
	 *
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1674
	 * XXX - We do this here so that we don't hold the
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1675
	 * spa_namespace_lock in the event that we can't get
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1676
	 * the RW_WRITER spa_config_lock.
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1677
	 */
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1678
	if (spa_state(spa) == POOL_STATE_IO_FAILURE)
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1679
		return (EIO);
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1680
1485
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1681
	txg = spa_vdev_enter(spa);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1682
6643
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1683
	if ((vd = spa_lookup_by_guid(spa, guid, B_TRUE)) == NULL)
1485
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1684
		return (spa_vdev_exit(spa, NULL, txg, ENODEV));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1685
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1686
	if (!vd->vdev_ops->vdev_op_leaf)
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1687
		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
  1688
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1689
	/*
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1690
	 * If the device isn't already offline, try to offline it.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1691
	 */
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1692
	if (!vd->vdev_offline) {
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1693
		/*
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1694
		 * If this device's top-level vdev has a non-empty DTL,
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1695
		 * don't allow the device to be offlined.
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1696
		 *
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1697
		 * XXX -- make this more precise by allowing the offline
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1698
		 * as long as the remaining devices don't have any DTL holes.
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1699
		 */
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1700
		if (vd->vdev_top->vdev_dtl_map.sm_space != 0)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1701
			return (spa_vdev_exit(spa, NULL, txg, EBUSY));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1702
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1703
		/*
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1704
		 * Offline this device and reopen its top-level vdev.
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1705
		 * If this action results in the top-level vdev becoming
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1706
		 * unusable, undo it and fail the request.
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1707
		 */
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1708
		vd->vdev_offline = B_TRUE;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1709
		vdev_reopen(vd->vdev_top);
6643
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  1710
		if (vdev_is_dead(vd->vdev_top) && vd->vdev_aux == NULL) {
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1711
			vd->vdev_offline = B_FALSE;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1712
			vdev_reopen(vd->vdev_top);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1713
			return (spa_vdev_exit(spa, NULL, txg, EBUSY));
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1714
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1715
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1716
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1717
	vd->vdev_tmpoffline = (flags & ZFS_OFFLINE_TEMPORARY) ?
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1718
	    B_TRUE : B_FALSE;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1719
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1720
	vdev_config_dirty(vd->vdev_top);
1485
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1721
e971e58d18f6 6322005 support for persistent offline
lling
parents: 1199
diff changeset
  1722
	return (spa_vdev_exit(spa, NULL, txg, 0));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1723
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1724
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1725
/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1726
 * Clear the error counts associated with this vdev.  Unlike vdev_online() and
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1727
 * vdev_offline(), we assume the spa config is locked.  We also clear all
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1728
 * children.  If 'vd' is NULL, then the user wants to clear all vdevs.
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1729
 * If reopen is specified then attempt to reopen the vdev if the vdev is
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1730
 * faulted or degraded.
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1731
 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1732
void
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1733
vdev_clear(spa_t *spa, vdev_t *vd, boolean_t reopen_wanted)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1734
{
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1735
	int c;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1736
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1737
	if (vd == NULL)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1738
		vd = spa->spa_root_vdev;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1739
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1740
	vd->vdev_stat.vs_read_errors = 0;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1741
	vd->vdev_stat.vs_write_errors = 0;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1742
	vd->vdev_stat.vs_checksum_errors = 0;
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1743
	vd->vdev_is_failing = B_FALSE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1744
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  1745
	for (c = 0; c < vd->vdev_children; c++)
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1746
		vdev_clear(spa, vd->vdev_child[c], reopen_wanted);
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1747
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1748
	/*
6959
f223e134ee61 6700920 vdev_clear() needs some polishing
ek110237
parents: 6643
diff changeset
  1749
	 * If we're in the FAULTED state or have experienced failed I/O, then
f223e134ee61 6700920 vdev_clear() needs some polishing
ek110237
parents: 6643
diff changeset
  1750
	 * clear the persistent state and attempt to reopen the device.  We
f223e134ee61 6700920 vdev_clear() needs some polishing
ek110237
parents: 6643
diff changeset
  1751
	 * also mark the vdev config dirty, so that the new faulted state is
f223e134ee61 6700920 vdev_clear() needs some polishing
ek110237
parents: 6643
diff changeset
  1752
	 * written out to disk.
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1753
	 */
6959
f223e134ee61 6700920 vdev_clear() needs some polishing
ek110237
parents: 6643
diff changeset
  1754
	if (reopen_wanted && (vd->vdev_faulted || vd->vdev_degraded ||
f223e134ee61 6700920 vdev_clear() needs some polishing
ek110237
parents: 6643
diff changeset
  1755
	    vd->vdev_stat.vs_aux == VDEV_AUX_IO_FAILURE)) {
f223e134ee61 6700920 vdev_clear() needs some polishing
ek110237
parents: 6643
diff changeset
  1756
		boolean_t resilver = (vd->vdev_faulted || vd->vdev_degraded);
f223e134ee61 6700920 vdev_clear() needs some polishing
ek110237
parents: 6643
diff changeset
  1757
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1758
		vd->vdev_faulted = vd->vdev_degraded = 0;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1759
		vdev_reopen(vd);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1760
		vdev_config_dirty(vd->vdev_top);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1761
6959
f223e134ee61 6700920 vdev_clear() needs some polishing
ek110237
parents: 6643
diff changeset
  1762
		if (resilver && vd->vdev_aux == NULL && !vdev_is_dead(vd))
4808
63629eaeb41a 6498144 ::kmastat could be even easier to read
ek110237
parents: 4577
diff changeset
  1763
			spa_async_request(spa, SPA_ASYNC_RESILVER);
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1764
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1765
		spa_event_notify(spa, vd, ESC_ZFS_VDEV_CLEAR);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  1766
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1767
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1768
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1769
int
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1770
vdev_readable(vdev_t *vd)
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1771
{
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1772
	/* XXPOLICY */
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1773
	return (!vdev_is_dead(vd));
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1774
}
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1775
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1776
int
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1777
vdev_writeable(vdev_t *vd)
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1778
{
5369
27c1235ef9a4 6621355 panic in vdev_disk_io_start when trying to write to a faulted device
gw25295
parents: 5329
diff changeset
  1779
	return (!vdev_is_dead(vd) && !vd->vdev_is_failing);
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1780
}
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1781
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1782
int
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1783
vdev_is_dead(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1784
{
6523
c1d2a7f04573 6616739 panic message ZFS: I/O failure (write on <unknown> is not very helpful
ek110237
parents: 5530
diff changeset
  1785
	/*
c1d2a7f04573 6616739 panic message ZFS: I/O failure (write on <unknown> is not very helpful
ek110237
parents: 5530
diff changeset
  1786
	 * If the vdev experienced I/O failures, then the vdev is marked
c1d2a7f04573 6616739 panic message ZFS: I/O failure (write on <unknown> is not very helpful
ek110237
parents: 5530
diff changeset
  1787
	 * as faulted (VDEV_STATE_FAULTED) for status output and FMA; however,
c1d2a7f04573 6616739 panic message ZFS: I/O failure (write on <unknown> is not very helpful
ek110237
parents: 5530
diff changeset
  1788
	 * we need to allow access to the vdev for resumed I/Os (see
c1d2a7f04573 6616739 panic message ZFS: I/O failure (write on <unknown> is not very helpful
ek110237
parents: 5530
diff changeset
  1789
	 * zio_vdev_resume_io() ).
c1d2a7f04573 6616739 panic message ZFS: I/O failure (write on <unknown> is not very helpful
ek110237
parents: 5530
diff changeset
  1790
	 */
c1d2a7f04573 6616739 panic message ZFS: I/O failure (write on <unknown> is not very helpful
ek110237
parents: 5530
diff changeset
  1791
	return (vd->vdev_state < VDEV_STATE_DEGRADED &&
c1d2a7f04573 6616739 panic message ZFS: I/O failure (write on <unknown> is not very helpful
ek110237
parents: 5530
diff changeset
  1792
	    vd->vdev_stat.vs_aux != VDEV_AUX_IO_FAILURE);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1793
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1794
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1795
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1796
vdev_error_inject(vdev_t *vd, zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1797
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1798
	int error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1799
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1800
	if (vd->vdev_fault_mode == VDEV_FAULT_NONE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1801
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1802
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1803
	if (((1ULL << zio->io_type) & vd->vdev_fault_mask) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1804
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1805
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1806
	switch (vd->vdev_fault_mode) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1807
	case VDEV_FAULT_RANDOM:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1808
		if (spa_get_random(vd->vdev_fault_arg) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1809
			error = EIO;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1810
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1811
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1812
	case VDEV_FAULT_COUNT:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1813
		if ((int64_t)--vd->vdev_fault_arg <= 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1814
			vd->vdev_fault_mode = VDEV_FAULT_NONE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1815
		error = EIO;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1816
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1817
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1818
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1819
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1820
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1821
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1822
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1823
 * Get statistics for the given vdev.
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_get_stats(vdev_t *vd, vdev_stat_t *vs)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1827
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1828
	vdev_t *rvd = vd->vdev_spa->spa_root_vdev;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1829
	int c, t;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1830
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1831
	mutex_enter(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1832
	bcopy(&vd->vdev_stat, vs, sizeof (*vs));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1833
	vs->vs_timestamp = gethrtime() - vs->vs_timestamp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1834
	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
  1835
	vs->vs_rsize = vdev_get_rsize(vd);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1836
	mutex_exit(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1837
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1838
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1839
	 * If we're getting stats on the root vdev, aggregate the I/O counts
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1840
	 * over all top-level vdevs (i.e. the direct children of the root).
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1841
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1842
	if (vd == rvd) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1843
		for (c = 0; c < rvd->vdev_children; c++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1844
			vdev_t *cvd = rvd->vdev_child[c];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1845
			vdev_stat_t *cvs = &cvd->vdev_stat;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1846
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1847
			mutex_enter(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1848
			for (t = 0; t < ZIO_TYPES; t++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1849
				vs->vs_ops[t] += cvs->vs_ops[t];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1850
				vs->vs_bytes[t] += cvs->vs_bytes[t];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1851
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1852
			vs->vs_read_errors += cvs->vs_read_errors;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1853
			vs->vs_write_errors += cvs->vs_write_errors;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1854
			vs->vs_checksum_errors += cvs->vs_checksum_errors;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1855
			vs->vs_scrub_examined += cvs->vs_scrub_examined;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1856
			vs->vs_scrub_errors += cvs->vs_scrub_errors;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1857
			mutex_exit(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1858
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1859
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1860
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1861
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1862
void
5450
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  1863
vdev_clear_stats(vdev_t *vd)
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  1864
{
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  1865
	mutex_enter(&vd->vdev_stat_lock);
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  1866
	vd->vdev_stat.vs_space = 0;
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  1867
	vd->vdev_stat.vs_dspace = 0;
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  1868
	vd->vdev_stat.vs_alloc = 0;
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  1869
	mutex_exit(&vd->vdev_stat_lock);
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  1870
}
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  1871
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  1872
void
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1873
vdev_stat_update(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1874
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1875
	vdev_t *vd = zio->io_vd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1876
	vdev_t *pvd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1877
	uint64_t txg = zio->io_txg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1878
	vdev_stat_t *vs = &vd->vdev_stat;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1879
	zio_type_t type = zio->io_type;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1880
	int flags = zio->io_flags;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1881
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1882
	if (zio->io_error == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1883
		if (!(flags & ZIO_FLAG_IO_BYPASS)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1884
			mutex_enter(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1885
			vs->vs_ops[type]++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1886
			vs->vs_bytes[type] += zio->io_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1887
			mutex_exit(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1888
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1889
		if ((flags & ZIO_FLAG_IO_REPAIR) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1890
		    zio->io_delegate_list == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1891
			mutex_enter(&vd->vdev_stat_lock);
1807
35c8b566d7af 6410711 intent log blocks don't get invited to pool parties
bonwick
parents: 1775
diff changeset
  1892
			if (flags & ZIO_FLAG_SCRUB_THREAD)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1893
				vs->vs_scrub_repaired += zio->io_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1894
			else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1895
				vs->vs_self_healed += zio->io_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1896
			mutex_exit(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1897
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1898
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1899
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1900
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1901
	if (flags & ZIO_FLAG_SPECULATIVE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1902
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1903
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  1904
	if (vdev_readable(vd)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1905
		mutex_enter(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1906
		if (type == ZIO_TYPE_READ) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1907
			if (zio->io_error == ECKSUM)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1908
				vs->vs_checksum_errors++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1909
			else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1910
				vs->vs_read_errors++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1911
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1912
		if (type == ZIO_TYPE_WRITE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1913
			vs->vs_write_errors++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1914
		mutex_exit(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1915
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1916
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1917
	if (type == ZIO_TYPE_WRITE) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1918
		if (txg == 0 || vd->vdev_children != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1919
			return;
1807
35c8b566d7af 6410711 intent log blocks don't get invited to pool parties
bonwick
parents: 1775
diff changeset
  1920
		if (flags & ZIO_FLAG_SCRUB_THREAD) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1921
			ASSERT(flags & ZIO_FLAG_IO_REPAIR);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1922
			for (pvd = vd; pvd != NULL; pvd = pvd->vdev_parent)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1923
				vdev_dtl_dirty(&pvd->vdev_dtl_scrub, txg, 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1924
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1925
		if (!(flags & ZIO_FLAG_IO_REPAIR)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1926
			if (vdev_dtl_contains(&vd->vdev_dtl_map, txg, 1))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1927
				return;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  1928
			vdev_dirty(vd->vdev_top, VDD_DTL, vd, txg);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1929
			for (pvd = vd; pvd != NULL; pvd = pvd->vdev_parent)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1930
				vdev_dtl_dirty(&pvd->vdev_dtl_map, txg, 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1931
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1932
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1933
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1934
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1935
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1936
vdev_scrub_stat_update(vdev_t *vd, pool_scrub_type_t type, boolean_t complete)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1937
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1938
	int c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1939
	vdev_stat_t *vs = &vd->vdev_stat;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1940
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1941
	for (c = 0; c < vd->vdev_children; c++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1942
		vdev_scrub_stat_update(vd->vdev_child[c], type, complete);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1943
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1944
	mutex_enter(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1945
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1946
	if (type == POOL_SCRUB_NONE) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1947
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1948
		 * Update completion and end time.  Leave everything else alone
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1949
		 * so we can report what happened during the previous scrub.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1950
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1951
		vs->vs_scrub_complete = complete;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1952
		vs->vs_scrub_end = gethrestime_sec();
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1953
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1954
		vs->vs_scrub_type = type;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1955
		vs->vs_scrub_complete = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1956
		vs->vs_scrub_examined = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1957
		vs->vs_scrub_repaired = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1958
		vs->vs_scrub_errors = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1959
		vs->vs_scrub_start = gethrestime_sec();
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1960
		vs->vs_scrub_end = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1961
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1962
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1963
	mutex_exit(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1964
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1965
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1966
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1967
 * Update the in-core space usage stats for this vdev and the root vdev.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1968
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1969
void
5450
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  1970
vdev_space_update(vdev_t *vd, int64_t space_delta, int64_t alloc_delta,
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  1971
    boolean_t update_root)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1972
{
4527
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
  1973
	int64_t dspace_delta = space_delta;
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
  1974
	spa_t *spa = vd->vdev_spa;
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
  1975
	vdev_t *rvd = spa->spa_root_vdev;
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
  1976
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1977
	ASSERT(vd == vd->vdev_top);
4527
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
  1978
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
  1979
	/*
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
  1980
	 * Apply the inverse of the psize-to-asize (ie. RAID-Z) space-expansion
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
  1981
	 * factor.  We must calculate this here and not at the root vdev
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
  1982
	 * because the root vdev's psize-to-asize is simply the max of its
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
  1983
	 * childrens', thus not accurate enough for us.
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
  1984
	 */
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
  1985
	ASSERT((dspace_delta & (SPA_MINBLOCKSIZE-1)) == 0);
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
  1986
	dspace_delta = (dspace_delta >> SPA_MINBLOCKSHIFT) *
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
  1987
	    vd->vdev_deflate_ratio;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1988
4527
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
  1989
	mutex_enter(&vd->vdev_stat_lock);
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
  1990
	vd->vdev_stat.vs_space += space_delta;
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
  1991
	vd->vdev_stat.vs_alloc += alloc_delta;
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
  1992
	vd->vdev_stat.vs_dspace += dspace_delta;
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
  1993
	mutex_exit(&vd->vdev_stat_lock);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1994
5450
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  1995
	if (update_root) {
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  1996
		ASSERT(rvd == vd->vdev_parent);
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  1997
		ASSERT(vd->vdev_ms_count != 0);
4527
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
  1998
5450
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  1999
		/*
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  2000
		 * Don't count non-normal (e.g. intent log) space as part of
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  2001
		 * the pool's capacity.
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  2002
		 */
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  2003
		if (vd->vdev_mg->mg_class != spa->spa_normal_class)
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  2004
			return;
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  2005
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  2006
		mutex_enter(&rvd->vdev_stat_lock);
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  2007
		rvd->vdev_stat.vs_space += space_delta;
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  2008
		rvd->vdev_stat.vs_alloc += alloc_delta;
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  2009
		rvd->vdev_stat.vs_dspace += dspace_delta;
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  2010
		mutex_exit(&rvd->vdev_stat_lock);
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5369
diff changeset
  2011
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2012
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2013
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2014
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2015
 * Mark a top-level vdev's config as dirty, placing it on the dirty list
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2016
 * so that it will be written out next time the vdev configuration is synced.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2017
 * If the root vdev is specified (vdev_top == NULL), dirty all top-level vdevs.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2018
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2019
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2020
vdev_config_dirty(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2021
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2022
	spa_t *spa = vd->vdev_spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2023
	vdev_t *rvd = spa->spa_root_vdev;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2024
	int c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2025
1601
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  2026
	/*
6643
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2027
	 * If this is an aux vdev (as with l2cache devices), then we update the
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2028
	 * vdev config manually and set the sync flag.
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2029
	 */
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2030
	if (vd->vdev_aux != NULL) {
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2031
		spa_aux_vdev_t *sav = vd->vdev_aux;
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2032
		nvlist_t **aux;
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2033
		uint_t naux;
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2034
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2035
		for (c = 0; c < sav->sav_count; c++) {
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2036
			if (sav->sav_vdevs[c] == vd)
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2037
				break;
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2038
		}
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2039
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2040
		ASSERT(c < sav->sav_count);
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2041
		sav->sav_sync = B_TRUE;
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2042
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2043
		VERIFY(nvlist_lookup_nvlist_array(sav->sav_config,
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2044
		    ZPOOL_CONFIG_L2CACHE, &aux, &naux) == 0);
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2045
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2046
		ASSERT(c < naux);
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2047
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2048
		/*
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2049
		 * Setting the nvlist in the middle if the array is a little
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2050
		 * sketchy, but it will work.
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2051
		 */
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2052
		nvlist_free(aux[c]);
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2053
		aux[c] = vdev_config_generate(spa, vd, B_TRUE, B_FALSE, B_TRUE);
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2054
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2055
		return;
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2056
	}
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2057
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2058
	/*
1601
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  2059
	 * 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
  2060
	 * 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
  2061
	 * (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
  2062
	 * 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
  2063
	 */
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  2064
	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
  2065
	    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
  2066
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2067
	if (vd == rvd) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2068
		for (c = 0; c < rvd->vdev_children; c++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2069
			vdev_config_dirty(rvd->vdev_child[c]);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2070
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2071
		ASSERT(vd == vd->vdev_top);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2072
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  2073
		if (!list_link_active(&vd->vdev_dirty_node))
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2074
			list_insert_head(&spa->spa_dirty_list, vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2075
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2076
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2077
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2078
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2079
vdev_config_clean(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2080
{
1601
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  2081
	spa_t *spa = vd->vdev_spa;
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  2082
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  2083
	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
  2084
	    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
  2085
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1631
diff changeset
  2086
	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
  2087
	list_remove(&spa->spa_dirty_list, vd);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2088
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2089
6523
c1d2a7f04573 6616739 panic message ZFS: I/O failure (write on <unknown> is not very helpful
ek110237
parents: 5530
diff changeset
  2090
/*
c1d2a7f04573 6616739 panic message ZFS: I/O failure (write on <unknown> is not very helpful
ek110237
parents: 5530
diff changeset
  2091
 * Propagate vdev state up from children to parent.
c1d2a7f04573 6616739 panic message ZFS: I/O failure (write on <unknown> is not very helpful
ek110237
parents: 5530
diff changeset
  2092
 */
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  2093
void
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  2094
vdev_propagate_state(vdev_t *vd)
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  2095
{
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  2096
	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
  2097
	int degraded = 0, faulted = 0;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  2098
	int corrupted = 0;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  2099
	int c;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  2100
	vdev_t *child;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  2101
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2102
	if (vd->vdev_children > 0) {
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2103
		for (c = 0; c < vd->vdev_children; c++) {
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2104
			child = vd->vdev_child[c];
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  2105
			if (vdev_is_dead(child) && !vdev_readable(child))
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2106
				faulted++;
6523
c1d2a7f04573 6616739 panic message ZFS: I/O failure (write on <unknown> is not very helpful
ek110237
parents: 5530
diff changeset
  2107
			else if (child->vdev_stat.vs_aux == VDEV_AUX_IO_FAILURE)
c1d2a7f04573 6616739 panic message ZFS: I/O failure (write on <unknown> is not very helpful
ek110237
parents: 5530
diff changeset
  2108
				faulted++;
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  2109
			else if (child->vdev_state <= VDEV_STATE_DEGRADED)
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2110
				degraded++;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2111
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2112
			if (child->vdev_stat.vs_aux == VDEV_AUX_CORRUPT_DATA)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2113
				corrupted++;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2114
		}
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  2115
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2116
		vd->vdev_ops->vdev_op_state_change(vd, faulted, degraded);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2117
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2118
		/*
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2119
		 * Root special: if there is a toplevel vdev that cannot be
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2120
		 * opened due to corrupted metadata, then propagate the root
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2121
		 * vdev's aux state as 'corrupt' rather than 'insufficient
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2122
		 * replicas'.
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2123
		 */
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2124
		if (corrupted && vd == rvd &&
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2125
		    rvd->vdev_state == VDEV_STATE_CANT_OPEN)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2126
			vdev_set_state(rvd, B_FALSE, VDEV_STATE_CANT_OPEN,
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2127
			    VDEV_AUX_CORRUPT_DATA);
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  2128
	}
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  2129
4527
5d5b6ba91b17 PSARC 2007/171 ZFS Separate Intent Log
perrin
parents: 4451
diff changeset
  2130
	if (vd->vdev_parent && !vd->vdev_islog)
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2131
		vdev_propagate_state(vd->vdev_parent);
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  2132
}
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
  2133
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2134
/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2135
 * 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
  2136
 * state, because we're in the process of opening children depth-first.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2137
 * Otherwise, we propagate the change to the parent.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2138
 *
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2139
 * 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
  2140
 * generated.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2141
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2142
void
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2143
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
  2144
{
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  2145
	uint64_t save_state;
6643
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2146
	spa_t *spa = vd->vdev_spa;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2147
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2148
	if (state == vd->vdev_state) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2149
		vd->vdev_stat.vs_aux = aux;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2150
		return;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2151
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2152
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  2153
	save_state = vd->vdev_state;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2154
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2155
	vd->vdev_state = state;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2156
	vd->vdev_stat.vs_aux = aux;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2157
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2158
	/*
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2159
	 * If we are setting the vdev state to anything but an open state, then
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2160
	 * always close the underlying device.  Otherwise, we keep accessible
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2161
	 * but invalid devices open forever.  We don't call vdev_close() itself,
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2162
	 * because that implies some extra checks (offline, etc) that we don't
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2163
	 * want here.  This is limited to leaf devices, because otherwise
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2164
	 * closing the device will affect other children.
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2165
	 */
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 5094
diff changeset
  2166
	if (!vdev_readable(vd) && vd->vdev_ops->vdev_op_leaf)
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2167
		vd->vdev_ops->vdev_op_close(vd);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2168
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2169
	if (vd->vdev_removed &&
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2170
	    state == VDEV_STATE_CANT_OPEN &&
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2171
	    (aux == VDEV_AUX_OPEN_FAILED || vd->vdev_checkremove)) {
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2172
		/*
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2173
		 * If the previous state is set to VDEV_STATE_REMOVED, then this
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2174
		 * device was previously marked removed and someone attempted to
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2175
		 * reopen it.  If this failed due to a nonexistent device, then
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2176
		 * keep the device in the REMOVED state.  We also let this be if
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2177
		 * it is one of our special test online cases, which is only
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2178
		 * attempting to online the device and shouldn't generate an FMA
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2179
		 * fault.
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2180
		 */
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2181
		vd->vdev_state = VDEV_STATE_REMOVED;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2182
		vd->vdev_stat.vs_aux = VDEV_AUX_NONE;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2183
	} else if (state == VDEV_STATE_REMOVED) {
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2184
		/*
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2185
		 * Indicate to the ZFS DE that this device has been removed, and
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2186
		 * any recent errors should be ignored.
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2187
		 */
6643
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2188
		zfs_post_remove(spa, vd);
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2189
		vd->vdev_removed = B_TRUE;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2190
	} else if (state == VDEV_STATE_CANT_OPEN) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2191
		/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2192
		 * 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
  2193
		 * "not available", which signifies that it was never there to
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2194
		 * begin with.  Failure to open such a device is not considered
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2195
		 * an error.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2196
		 */
6643
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2197
		if (spa->spa_load_state == SPA_LOAD_IMPORT &&
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2198
		    !spa->spa_import_faulted &&
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  2199
		    vd->vdev_ops->vdev_op_leaf)
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  2200
			vd->vdev_not_present = 1;
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  2201
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  2202
		/*
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  2203
		 * 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
  2204
		 * 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
  2205
		 * 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
  2206
		 * 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
  2207
		 * CANT_OPEN state beforehand.
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2208
		 *
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2209
		 * If the 'checkremove' flag is set, then this is an attempt to
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2210
		 * online the device in response to an insertion event.  If we
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2211
		 * hit this case, then we have detected an insertion event for a
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2212
		 * faulted or offline device that wasn't in the removed state.
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2213
		 * In this scenario, we don't post an ereport because we are
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2214
		 * about to replace the device, or attempt an online with
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2215
		 * vdev_forcefault, which will generate the fault for us.
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
  2216
		 */
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2217
		if ((vd->vdev_prevstate != state || vd->vdev_forcefault) &&
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2218
		    !vd->vdev_not_present && !vd->vdev_checkremove &&
6643
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2219
		    vd != spa->spa_root_vdev) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2220
			const char *class;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2221
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2222
			switch (aux) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2223
			case VDEV_AUX_OPEN_FAILED:
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2224
				class = FM_EREPORT_ZFS_DEVICE_OPEN_FAILED;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2225
				break;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2226
			case VDEV_AUX_CORRUPT_DATA:
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2227
				class = FM_EREPORT_ZFS_DEVICE_CORRUPT_DATA;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2228
				break;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2229
			case VDEV_AUX_NO_REPLICAS:
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2230
				class = FM_EREPORT_ZFS_DEVICE_NO_REPLICAS;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2231
				break;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2232
			case VDEV_AUX_BAD_GUID_SUM:
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2233
				class = FM_EREPORT_ZFS_DEVICE_BAD_GUID_SUM;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2234
				break;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2235
			case VDEV_AUX_TOO_SMALL:
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2236
				class = FM_EREPORT_ZFS_DEVICE_TOO_SMALL;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2237
				break;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2238
			case VDEV_AUX_BAD_LABEL:
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2239
				class = FM_EREPORT_ZFS_DEVICE_BAD_LABEL;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2240
				break;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2241
			default:
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2242
				class = FM_EREPORT_ZFS_DEVICE_UNKNOWN;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2243
			}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2244
6643
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6523
diff changeset
  2245
			zfs_ereport_post(class, spa, vd, NULL, save_state, 0);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2246
		}
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2247
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2248
		/* Erase any notion of persistent removed state */
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2249
		vd->vdev_removed = B_FALSE;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2250
	} else {
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2251
		vd->vdev_removed = B_FALSE;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2252
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1485
diff changeset
  2253
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2254
	if (!isopen)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4070
diff changeset
  2255
		vdev_propagate_state(vd);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2256
}