usr/src/uts/common/fs/zfs/vdev_mirror.c
author ahrens
Fri, 10 Mar 2006 16:27:46 -0800
changeset 1596 2e2377ccbf85
parent 1544 938876158511
child 1732 9e3ae798af31
permissions -rw-r--r--
6395371 ASSERT in dmu_tx_count_free: blkid + i < dn->dn_phys->dn_nblkptr 6396359 infinite loop due to dangling dbufs (hang on unmount)
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
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
     5
 * Common Development and Distribution License (the "License").
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
     6
 * You may not use this file except in compliance with the License.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     7
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    11
 * and limitations under the License.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    12
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    18
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    19
 * CDDL HEADER END
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    20
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    21
/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
    22
 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    23
 * Use is subject to license terms.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    24
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    25
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    26
#pragma ident	"%Z%%M%	%I%	%E% SMI"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    27
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
#include <sys/zfs_context.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
#include <sys/spa.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
#include <sys/vdev_impl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
#include <sys/zio.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
#include <sys/fs/zfs.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    34
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
 * Virtual device vector for mirroring.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    36
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    38
typedef struct mirror_map {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    39
	int	mm_error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    40
	short	mm_tried;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    41
	short	mm_skipped;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    42
} mirror_map_t;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    43
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
static mirror_map_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    45
vdev_mirror_map_alloc(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
	zio->io_vsd = kmem_zalloc(zio->io_vd->vdev_children *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
	    sizeof (mirror_map_t), KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
	return (zio->io_vsd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    51
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
vdev_mirror_map_free(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    54
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
	kmem_free(zio->io_vsd,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
	    zio->io_vd->vdev_children * sizeof (mirror_map_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
	zio->io_vsd = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    60
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    61
vdev_mirror_open(vdev_t *vd, uint64_t *asize, uint64_t *ashift)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    62
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    63
	vdev_t *cvd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
	uint64_t c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    65
	int numerrors = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    66
	int ret, lasterror = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    67
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
	if (vd->vdev_children == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
		vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    70
		return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    71
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    72
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    73
	for (c = 0; c < vd->vdev_children; c++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    74
		cvd = vd->vdev_child[c];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    75
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    76
		if ((ret = vdev_open(cvd)) != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    77
			lasterror = ret;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    78
			numerrors++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    79
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    80
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    81
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    82
		*asize = MIN(*asize - 1, cvd->vdev_asize - 1) + 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    83
		*ashift = cvd->vdev_ashift;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    84
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    85
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    86
	if (numerrors == vd->vdev_children) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    87
		vd->vdev_stat.vs_aux = VDEV_AUX_NO_REPLICAS;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    88
		return (lasterror);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    89
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    90
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    91
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    92
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    93
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    94
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    95
vdev_mirror_close(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    96
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    97
	uint64_t c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    98
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    99
	for (c = 0; c < vd->vdev_children; c++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   100
		vdev_close(vd->vdev_child[c]);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   101
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   102
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   103
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   104
vdev_mirror_child_done(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   105
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   106
	mirror_map_t *mm = zio->io_private;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   107
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   108
	mm->mm_error = zio->io_error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   109
	mm->mm_tried = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   110
	mm->mm_skipped = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   111
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   112
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   113
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   114
vdev_mirror_scrub_done(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   115
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   116
	mirror_map_t *mm = zio->io_private;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   117
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   118
	if (zio->io_error == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   119
		zio_t *pio = zio->io_parent;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   120
		mutex_enter(&pio->io_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   121
		bcopy(zio->io_data, pio->io_data, pio->io_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   122
		mutex_exit(&pio->io_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   123
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   124
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   125
	zio_buf_free(zio->io_data, zio->io_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   126
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   127
	mm->mm_error = zio->io_error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   128
	mm->mm_tried = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   129
	mm->mm_skipped = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   130
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   131
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   132
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   133
 * Try to find a child whose DTL doesn't contain the block we want to read.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   134
 * If we can't, try the read on any vdev we haven't already tried.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   135
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   136
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   137
vdev_mirror_child_select(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   138
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   139
	mirror_map_t *mm = zio->io_vsd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   140
	vdev_t *vd = zio->io_vd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   141
	vdev_t *cvd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   142
	uint64_t txg = zio->io_txg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   143
	int i, c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   144
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   145
	ASSERT(zio->io_bp == NULL || zio->io_bp->blk_birth == txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   146
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   147
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   148
	 * Select the child we'd like to read from absent any errors.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   149
	 * The current policy is to alternate sides at 8M granularity.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   150
	 * XXX -- investigate other policies for read distribution.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   151
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   152
	c = (zio->io_offset >> (SPA_MAXBLOCKSHIFT + 6)) % vd->vdev_children;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   153
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   154
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   155
	 * If this is a replacing vdev, always try child 0 (the source) first.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   156
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   157
	if (vd->vdev_ops == &vdev_replacing_ops)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   158
		c = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   159
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   160
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   161
	 * Try to find a child whose DTL doesn't contain the block to read.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   162
	 * If a child is known to be completely inaccessible (indicated by
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   163
	 * vdev_is_dead() returning B_TRUE), don't even try.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   164
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   165
	for (i = 0; i < vd->vdev_children; i++, c++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   166
		if (c >= vd->vdev_children)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   167
			c = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   168
		if (mm[c].mm_tried || mm[c].mm_skipped)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   169
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   170
		cvd = vd->vdev_child[c];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   171
		if (vdev_is_dead(cvd)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   172
			mm[c].mm_error = ENXIO;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   173
			mm[c].mm_tried = 1;	/* don't even try */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   174
			mm[c].mm_skipped = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   175
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   176
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   177
		if (!vdev_dtl_contains(&cvd->vdev_dtl_map, txg, 1))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   178
			return (c);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   179
		mm[c].mm_error = ESTALE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   180
		mm[c].mm_skipped = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   181
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   182
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   183
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   184
	 * Every device is either missing or has this txg in its DTL.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   185
	 * If we don't have any sibling replicas to consult, look for
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   186
	 * any child we haven't already tried before giving up.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   187
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   188
	if (vd == vd->vdev_top || vd->vdev_parent->vdev_children <= 1) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   189
		for (c = 0; c < vd->vdev_children; c++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   190
			if (!mm[c].mm_tried)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   191
				return (c);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   192
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   193
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   194
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   195
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   196
	 * Every child failed.  There's no place left to look.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   197
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   198
	return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   199
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   200
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   201
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   202
vdev_mirror_io_start(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   203
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   204
	vdev_t *vd = zio->io_vd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   205
	mirror_map_t *mm;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   206
	int c, children;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   207
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   208
	mm = vdev_mirror_map_alloc(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   209
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   210
	if (zio->io_type == ZIO_TYPE_READ) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   211
		if ((zio->io_flags & ZIO_FLAG_SCRUB) &&
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   212
		    vd->vdev_ops != &vdev_replacing_ops) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   213
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   214
			 * For scrubbing reads we need to allocate a read
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   215
			 * buffer for each child and issue reads to all
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   216
			 * children.  If any child succeeds, it will copy its
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   217
			 * data into zio->io_data in vdev_mirror_scrub_done.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   218
			 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   219
			for (c = 0; c < vd->vdev_children; c++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   220
				zio_nowait(zio_vdev_child_io(zio, zio->io_bp,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   221
				    vd->vdev_child[c], zio->io_offset,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   222
				    zio_buf_alloc(zio->io_size), zio->io_size,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   223
				    zio->io_type, zio->io_priority,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   224
				    ZIO_FLAG_CANFAIL, vdev_mirror_scrub_done,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   225
				    &mm[c]));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   226
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   227
			zio_wait_children_done(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   228
			return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   229
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   230
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   231
		 * For normal reads just pick one child.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   232
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   233
		c = vdev_mirror_child_select(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   234
		children = (c >= 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   235
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   236
		ASSERT(zio->io_type == ZIO_TYPE_WRITE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   237
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   238
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   239
		 * If this is a resilvering I/O to a replacing vdev,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   240
		 * only the last child should be written -- unless the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   241
		 * first child happens to have a DTL entry here as well.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   242
		 * All other writes go to all children.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   243
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   244
		if ((zio->io_flags & ZIO_FLAG_RESILVER) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   245
		    vd->vdev_ops == &vdev_replacing_ops &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   246
		    !vdev_dtl_contains(&vd->vdev_child[0]->vdev_dtl_map,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   247
		    zio->io_txg, 1)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   248
			c = vd->vdev_children - 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   249
			children = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   250
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   251
			c = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   252
			children = vd->vdev_children;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   253
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   254
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   255
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   256
	while (children--) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   257
		zio_nowait(zio_vdev_child_io(zio, zio->io_bp,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   258
		    vd->vdev_child[c], zio->io_offset, zio->io_data,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   259
		    zio->io_size, zio->io_type, zio->io_priority,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   260
		    ZIO_FLAG_CANFAIL, vdev_mirror_child_done, &mm[c]));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   261
		c++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   262
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   263
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   264
	zio_wait_children_done(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   265
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   266
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   267
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   268
vdev_mirror_io_done(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   269
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   270
	vdev_t *vd = zio->io_vd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   271
	vdev_t *cvd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   272
	mirror_map_t *mm = zio->io_vsd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   273
	int c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   274
	int good_copies = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   275
	int unexpected_errors = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   276
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   277
	ASSERT(mm != NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   278
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   279
	zio->io_error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   280
	zio->io_numerrors = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   281
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   282
	for (c = 0; c < vd->vdev_children; c++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   283
		if (mm[c].mm_tried && mm[c].mm_error == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   284
			good_copies++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   285
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   286
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   287
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   288
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   289
		 * We preserve any EIOs because those may be worth retrying;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   290
		 * whereas ECKSUM and ENXIO are more likely to be persistent.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   291
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   292
		if (mm[c].mm_error) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   293
			if (zio->io_error != EIO)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   294
				zio->io_error = mm[c].mm_error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   295
			if (!mm[c].mm_skipped)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   296
				unexpected_errors++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   297
			zio->io_numerrors++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   298
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   299
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   300
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   301
	if (zio->io_type == ZIO_TYPE_WRITE) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   302
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   303
		 * XXX -- for now, treat partial writes as success.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   304
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   305
		/* XXPOLICY */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   306
		if (good_copies != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   307
			zio->io_error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   308
		ASSERT(mm != NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   309
		vdev_mirror_map_free(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   310
		zio_next_stage(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   311
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   312
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   313
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   314
	ASSERT(zio->io_type == ZIO_TYPE_READ);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   315
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   316
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   317
	 * If we don't have a good copy yet, keep trying other children.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   318
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   319
	/* XXPOLICY */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   320
	if (good_copies == 0 && (c = vdev_mirror_child_select(zio)) != -1) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   321
		ASSERT(c >= 0 && c < vd->vdev_children);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   322
		cvd = vd->vdev_child[c];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   323
		dprintf("%s: retrying i/o (err=%d) on child %s\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   324
		    vdev_description(zio->io_vd), zio->io_error,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   325
		    vdev_description(cvd));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   326
		zio->io_error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   327
		zio_vdev_io_redone(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   328
		zio_nowait(zio_vdev_child_io(zio, zio->io_bp, cvd,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   329
		    zio->io_offset, zio->io_data, zio->io_size,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   330
		    ZIO_TYPE_READ, zio->io_priority, ZIO_FLAG_CANFAIL,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   331
		    vdev_mirror_child_done, &mm[c]));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   332
		zio_wait_children_done(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   333
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   334
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   335
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   336
	/* XXPOLICY */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   337
	if (good_copies)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   338
		zio->io_error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   339
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   340
		ASSERT(zio->io_error != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   341
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   342
	if (good_copies && (spa_mode & FWRITE) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   343
	    (unexpected_errors || (zio->io_flags & ZIO_FLAG_RESILVER))) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   344
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   345
		 * Use the good data we have in hand to repair damaged children.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   346
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   347
		for (c = 0; c < vd->vdev_children; c++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   348
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   349
			 * Don't rewrite known good children.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   350
			 * Not only is it unnecessary, it could
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   351
			 * actually be harmful: if the system lost
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   352
			 * power while rewriting the only good copy,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   353
			 * there would be no good copies left!
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   354
			 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   355
			cvd = vd->vdev_child[c];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   356
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   357
			if (mm[c].mm_error == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   358
				if (mm[c].mm_tried)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   359
					continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   360
				if (!vdev_dtl_contains(&cvd->vdev_dtl_map,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   361
				    zio->io_txg, 1))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   362
					continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   363
				mm[c].mm_error = ESTALE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   364
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   365
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   366
			dprintf("%s resilvered %s @ 0x%llx error %d\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   367
			    vdev_description(vd),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   368
			    vdev_description(cvd),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   369
			    zio->io_offset, mm[c].mm_error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   370
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   371
			zio_nowait(zio_vdev_child_io(zio, zio->io_bp, cvd,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   372
			    zio->io_offset, zio->io_data, zio->io_size,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   373
			    ZIO_TYPE_WRITE, zio->io_priority,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   374
			    ZIO_FLAG_IO_REPAIR | ZIO_FLAG_CANFAIL |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   375
			    ZIO_FLAG_DONT_PROPAGATE, NULL, NULL));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   376
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   377
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   378
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   379
	vdev_mirror_map_free(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   380
	zio_next_stage(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   381
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   382
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   383
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   384
vdev_mirror_state_change(vdev_t *vd, int faulted, int degraded)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   385
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   386
	if (faulted == vd->vdev_children)
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   387
		vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   388
		    VDEV_AUX_NO_REPLICAS);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   389
	else if (degraded + faulted != 0)
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   390
		vdev_set_state(vd, B_FALSE, VDEV_STATE_DEGRADED, VDEV_AUX_NONE);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   391
	else
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   392
		vdev_set_state(vd, B_FALSE, VDEV_STATE_HEALTHY, VDEV_AUX_NONE);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   393
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   394
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   395
vdev_ops_t vdev_mirror_ops = {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   396
	vdev_mirror_open,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   397
	vdev_mirror_close,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   398
	vdev_default_asize,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   399
	vdev_mirror_io_start,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   400
	vdev_mirror_io_done,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   401
	vdev_mirror_state_change,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   402
	VDEV_TYPE_MIRROR,	/* name of this vdev type */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   403
	B_FALSE			/* not a leaf vdev */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   404
};
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   405
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   406
vdev_ops_t vdev_replacing_ops = {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   407
	vdev_mirror_open,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   408
	vdev_mirror_close,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   409
	vdev_default_asize,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   410
	vdev_mirror_io_start,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   411
	vdev_mirror_io_done,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   412
	vdev_mirror_state_change,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   413
	VDEV_TYPE_REPLACING,	/* name of this vdev type */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   414
	B_FALSE			/* not a leaf vdev */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   415
};