usr/src/uts/common/fs/zfs/vdev_mirror.c
author eschrock
Tue, 05 Sep 2006 11:37:36 -0700
changeset 2676 5cee47eddab6
parent 2391 2fa3fd1db808
child 5329 33cb98223b2d
permissions -rw-r--r--
PSARC 2006/486 ZFS canmount property PSARC 2006/497 ZFS create time properties PSARC 2006/502 ZFS get all datasets PSARC 2006/504 ZFS user properties 6269805 properties should be set via an nvlist. 6281585 user defined properties 6349494 'zfs list' output annoying for even moderately long dataset names 6366244 'canmount' option for container-like functionality 6367103 create-time properties 6416639 RFE: provide zfs get -a 6437808 ZFS module version should match on-disk version 6454551 'zfs create -b blocksize filesystem' should fail. 6457478 unrecognized character in error message with 'zpool create -R' command 6457865 missing device name in the error message of 'zpool clear' command 6458571 zfs_ioc_set_prop() doesn't validate input 6458614 zfs ACL #defines should use prefix 6458638 get_configs() accesses bogus memory 6458678 zvol functions should be moved out of zfs_ioctl.h 6458683 zfs_cmd_t could use more cleanup 6458691 common routines to manage zfs_cmd_t nvlists 6460398 zpool import cores on zfs_prop_get 6461029 zpool status -x noexisting-pool has incorrect error message. 6461223 index translations should live with property definitions 6461424 zpool_unmount_datasets() has some busted logic 6461427 zfs_realloc() would be useful 6461757 'zpool status' can report the wrong number of persistent errors 6461784 recursive zfs_snapshot() leaks memory
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
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    38
typedef struct mirror_child {
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    39
	vdev_t		*mc_vd;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    40
	uint64_t	mc_offset;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    41
	int		mc_error;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    42
	short		mc_tried;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    43
	short		mc_skipped;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    44
} mirror_child_t;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    45
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
typedef struct mirror_map {
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    47
	int		mm_children;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    48
	int		mm_replacing;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    49
	int		mm_preferred;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    50
	int		mm_root;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    51
	mirror_child_t	mm_child[1];
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
} mirror_map_t;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
2391
2fa3fd1db808 6447377 ZFS prefetch is inconsistant
maybee
parents: 2082
diff changeset
    54
int vdev_mirror_shift = 21;
2fa3fd1db808 6447377 ZFS prefetch is inconsistant
maybee
parents: 2082
diff changeset
    55
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
static mirror_map_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
vdev_mirror_map_alloc(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
{
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    59
	mirror_map_t *mm = NULL;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    60
	mirror_child_t *mc;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    61
	vdev_t *vd = zio->io_vd;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    62
	int c, d;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    63
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    64
	if (vd == NULL) {
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    65
		dva_t *dva = zio->io_bp->blk_dva;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    66
		spa_t *spa = zio->io_spa;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    67
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    68
		c = BP_GET_NDVAS(zio->io_bp);
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    69
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    70
		mm = kmem_zalloc(offsetof(mirror_map_t, mm_child[c]), KM_SLEEP);
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    71
		mm->mm_children = c;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    72
		mm->mm_replacing = B_FALSE;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    73
		mm->mm_preferred = spa_get_random(c);
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    74
		mm->mm_root = B_TRUE;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    75
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    76
		/*
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    77
		 * Check the other, lower-index DVAs to see if they're on
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    78
		 * the same vdev as the child we picked.  If they are, use
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    79
		 * them since they are likely to have been allocated from
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    80
		 * the primary metaslab in use at the time, and hence are
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    81
		 * more likely to have locality with single-copy data.
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    82
		 */
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    83
		for (c = mm->mm_preferred, d = c - 1; d >= 0; d--) {
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    84
			if (DVA_GET_VDEV(&dva[d]) == DVA_GET_VDEV(&dva[c]))
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    85
				mm->mm_preferred = d;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    86
		}
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    87
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    88
		for (c = 0; c < mm->mm_children; c++) {
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    89
			mc = &mm->mm_child[c];
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1807
diff changeset
    90
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    91
			mc->mc_vd = vdev_lookup_top(spa, DVA_GET_VDEV(&dva[c]));
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    92
			mc->mc_offset = DVA_GET_OFFSET(&dva[c]);
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    93
		}
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    94
	} else {
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    95
		c = vd->vdev_children;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    96
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    97
		mm = kmem_zalloc(offsetof(mirror_map_t, mm_child[c]), KM_SLEEP);
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
    98
		mm->mm_children = c;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1807
diff changeset
    99
		mm->mm_replacing = (vd->vdev_ops == &vdev_replacing_ops ||
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1807
diff changeset
   100
		    vd->vdev_ops == &vdev_spare_ops);
2391
2fa3fd1db808 6447377 ZFS prefetch is inconsistant
maybee
parents: 2082
diff changeset
   101
		mm->mm_preferred = mm->mm_replacing ? 0 :
2fa3fd1db808 6447377 ZFS prefetch is inconsistant
maybee
parents: 2082
diff changeset
   102
		    (zio->io_offset >> vdev_mirror_shift) % c;
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   103
		mm->mm_root = B_FALSE;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   104
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   105
		for (c = 0; c < mm->mm_children; c++) {
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   106
			mc = &mm->mm_child[c];
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   107
			mc->mc_vd = vd->vdev_child[c];
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   108
			mc->mc_offset = zio->io_offset;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   109
		}
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   110
	}
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   111
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   112
	zio->io_vsd = mm;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   113
	return (mm);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   114
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   115
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   116
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   117
vdev_mirror_map_free(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   118
{
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   119
	mirror_map_t *mm = zio->io_vsd;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   120
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   121
	kmem_free(mm, offsetof(mirror_map_t, mm_child[mm->mm_children]));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   122
	zio->io_vsd = NULL;
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
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   126
vdev_mirror_open(vdev_t *vd, uint64_t *asize, uint64_t *ashift)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   127
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   128
	vdev_t *cvd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   129
	uint64_t c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   130
	int numerrors = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   131
	int ret, lasterror = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   132
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   133
	if (vd->vdev_children == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   134
		vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   135
		return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   136
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   137
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   138
	for (c = 0; c < vd->vdev_children; c++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   139
		cvd = vd->vdev_child[c];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   140
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   141
		if ((ret = vdev_open(cvd)) != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   142
			lasterror = ret;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   143
			numerrors++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   144
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   145
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   146
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   147
		*asize = MIN(*asize - 1, cvd->vdev_asize - 1) + 1;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   148
		*ashift = MAX(*ashift, cvd->vdev_ashift);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   149
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   150
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   151
	if (numerrors == vd->vdev_children) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   152
		vd->vdev_stat.vs_aux = VDEV_AUX_NO_REPLICAS;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   153
		return (lasterror);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   154
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   155
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   156
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   157
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   158
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   159
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   160
vdev_mirror_close(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   161
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   162
	uint64_t c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   163
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   164
	for (c = 0; c < vd->vdev_children; c++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   165
		vdev_close(vd->vdev_child[c]);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   166
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   167
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   168
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   169
vdev_mirror_child_done(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   170
{
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   171
	mirror_child_t *mc = zio->io_private;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   172
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   173
	mc->mc_error = zio->io_error;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   174
	mc->mc_tried = 1;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   175
	mc->mc_skipped = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   176
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   177
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   178
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   179
vdev_mirror_scrub_done(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   180
{
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   181
	mirror_child_t *mc = zio->io_private;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   182
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   183
	if (zio->io_error == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   184
		zio_t *pio = zio->io_parent;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   185
		mutex_enter(&pio->io_lock);
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   186
		ASSERT3U(zio->io_size, >=, pio->io_size);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   187
		bcopy(zio->io_data, pio->io_data, pio->io_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   188
		mutex_exit(&pio->io_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   189
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   190
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   191
	zio_buf_free(zio->io_data, zio->io_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   192
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   193
	mc->mc_error = zio->io_error;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   194
	mc->mc_tried = 1;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   195
	mc->mc_skipped = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   196
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   197
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   198
static void
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   199
vdev_mirror_repair_done(zio_t *zio)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   200
{
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   201
	ASSERT(zio->io_private == zio->io_parent);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   202
	vdev_mirror_map_free(zio->io_private);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   203
}
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   204
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   205
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   206
 * 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
   207
 * If we can't, try the read on any vdev we haven't already tried.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   208
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   209
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   210
vdev_mirror_child_select(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   211
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   212
	mirror_map_t *mm = zio->io_vsd;
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   213
	mirror_child_t *mc;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   214
	uint64_t txg = zio->io_txg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   215
	int i, c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   216
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   217
	ASSERT(zio->io_bp == NULL || zio->io_bp->blk_birth == txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   218
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   219
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   220
	 * Try to find a child whose DTL doesn't contain the block to read.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   221
	 * If a child is known to be completely inaccessible (indicated by
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   222
	 * vdev_is_dead() returning B_TRUE), don't even try.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   223
	 */
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   224
	for (i = 0, c = mm->mm_preferred; i < mm->mm_children; i++, c++) {
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   225
		if (c >= mm->mm_children)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   226
			c = 0;
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   227
		mc = &mm->mm_child[c];
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   228
		if (mc->mc_tried || mc->mc_skipped)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   229
			continue;
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   230
		if (vdev_is_dead(mc->mc_vd)) {
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   231
			mc->mc_error = ENXIO;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   232
			mc->mc_tried = 1;	/* don't even try */
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   233
			mc->mc_skipped = 1;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   234
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   235
		}
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   236
		if (!vdev_dtl_contains(&mc->mc_vd->vdev_dtl_map, txg, 1))
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   237
			return (c);
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   238
		mc->mc_error = ESTALE;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   239
		mc->mc_skipped = 1;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   240
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   241
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   242
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   243
	 * Every device is either missing or has this txg in its DTL.
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   244
	 * Look for any child we haven't already tried before giving up.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   245
	 */
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   246
	for (c = 0; c < mm->mm_children; c++)
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   247
		if (!mm->mm_child[c].mc_tried)
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   248
			return (c);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   249
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   250
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   251
	 * Every child failed.  There's no place left to look.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   252
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   253
	return (-1);
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
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   257
vdev_mirror_io_start(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   258
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   259
	mirror_map_t *mm;
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   260
	mirror_child_t *mc;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   261
	int c, children;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   262
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   263
	mm = vdev_mirror_map_alloc(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   264
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   265
	if (zio->io_type == ZIO_TYPE_READ) {
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   266
		if ((zio->io_flags & ZIO_FLAG_SCRUB) && !mm->mm_replacing) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   267
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   268
			 * For scrubbing reads we need to allocate a read
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   269
			 * buffer for each child and issue reads to all
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   270
			 * children.  If any child succeeds, it will copy its
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   271
			 * data into zio->io_data in vdev_mirror_scrub_done.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   272
			 */
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   273
			for (c = 0; c < mm->mm_children; c++) {
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   274
				mc = &mm->mm_child[c];
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   275
				zio_nowait(zio_vdev_child_io(zio, zio->io_bp,
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   276
				    mc->mc_vd, mc->mc_offset,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   277
				    zio_buf_alloc(zio->io_size), zio->io_size,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   278
				    zio->io_type, zio->io_priority,
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   279
				    ZIO_FLAG_CANFAIL,
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   280
				    vdev_mirror_scrub_done, mc));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   281
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   282
			zio_wait_children_done(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   283
			return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   284
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   285
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   286
		 * For normal reads just pick one child.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   287
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   288
		c = vdev_mirror_child_select(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   289
		children = (c >= 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   290
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   291
		ASSERT(zio->io_type == ZIO_TYPE_WRITE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   292
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   293
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   294
		 * If this is a resilvering I/O to a replacing vdev,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   295
		 * only the last child should be written -- unless the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   296
		 * first child happens to have a DTL entry here as well.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   297
		 * All other writes go to all children.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   298
		 */
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   299
		if ((zio->io_flags & ZIO_FLAG_RESILVER) && mm->mm_replacing &&
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   300
		    !vdev_dtl_contains(&mm->mm_child[0].mc_vd->vdev_dtl_map,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   301
		    zio->io_txg, 1)) {
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   302
			c = mm->mm_children - 1;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   303
			children = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   304
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   305
			c = 0;
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   306
			children = mm->mm_children;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   307
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   308
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   309
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   310
	while (children--) {
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   311
		mc = &mm->mm_child[c];
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   312
		zio_nowait(zio_vdev_child_io(zio, zio->io_bp,
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   313
		    mc->mc_vd, mc->mc_offset,
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   314
		    zio->io_data, zio->io_size, zio->io_type, zio->io_priority,
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   315
		    ZIO_FLAG_CANFAIL, vdev_mirror_child_done, mc));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   316
		c++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   317
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   318
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   319
	zio_wait_children_done(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   320
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   321
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   322
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   323
vdev_mirror_io_done(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   324
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   325
	mirror_map_t *mm = zio->io_vsd;
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   326
	mirror_child_t *mc;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   327
	int c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   328
	int good_copies = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   329
	int unexpected_errors = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   330
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   331
	zio->io_error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   332
	zio->io_numerrors = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   333
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   334
	for (c = 0; c < mm->mm_children; c++) {
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   335
		mc = &mm->mm_child[c];
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   336
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   337
		if (mc->mc_tried && mc->mc_error == 0) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   338
			good_copies++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   339
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   340
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   341
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   342
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   343
		 * We preserve any EIOs because those may be worth retrying;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   344
		 * whereas ECKSUM and ENXIO are more likely to be persistent.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   345
		 */
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   346
		if (mc->mc_error) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   347
			if (zio->io_error != EIO)
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   348
				zio->io_error = mc->mc_error;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   349
			if (!mc->mc_skipped)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   350
				unexpected_errors++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   351
			zio->io_numerrors++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   352
		}
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 (zio->io_type == ZIO_TYPE_WRITE) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   356
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   357
		 * XXX -- for now, treat partial writes as success.
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   358
		 * XXX -- For a replacing vdev, we need to make sure the
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   359
		 *	  new child succeeds.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   360
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   361
		/* XXPOLICY */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   362
		if (good_copies != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   363
			zio->io_error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   364
		vdev_mirror_map_free(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   365
		zio_next_stage(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   366
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   367
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   368
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   369
	ASSERT(zio->io_type == ZIO_TYPE_READ);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   370
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   371
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   372
	 * If we don't have a good copy yet, keep trying other children.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   373
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   374
	/* XXPOLICY */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   375
	if (good_copies == 0 && (c = vdev_mirror_child_select(zio)) != -1) {
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   376
		ASSERT(c >= 0 && c < mm->mm_children);
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   377
		mc = &mm->mm_child[c];
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   378
		dprintf("retrying i/o (err=%d) on child %s\n",
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   379
		    zio->io_error, vdev_description(mc->mc_vd));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   380
		zio->io_error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   381
		zio_vdev_io_redone(zio);
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   382
		zio_nowait(zio_vdev_child_io(zio, zio->io_bp,
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   383
		    mc->mc_vd, mc->mc_offset, zio->io_data, zio->io_size,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   384
		    ZIO_TYPE_READ, zio->io_priority, ZIO_FLAG_CANFAIL,
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   385
		    vdev_mirror_child_done, mc));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   386
		zio_wait_children_done(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   387
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   388
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   389
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   390
	/* XXPOLICY */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   391
	if (good_copies)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   392
		zio->io_error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   393
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   394
		ASSERT(zio->io_error != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   395
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   396
	if (good_copies && (spa_mode & FWRITE) &&
1807
35c8b566d7af 6410711 intent log blocks don't get invited to pool parties
bonwick
parents: 1775
diff changeset
   397
	    (unexpected_errors ||
35c8b566d7af 6410711 intent log blocks don't get invited to pool parties
bonwick
parents: 1775
diff changeset
   398
	    (zio->io_flags & ZIO_FLAG_RESILVER) ||
35c8b566d7af 6410711 intent log blocks don't get invited to pool parties
bonwick
parents: 1775
diff changeset
   399
	    ((zio->io_flags & ZIO_FLAG_SCRUB) && mm->mm_replacing))) {
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   400
		zio_t *rio;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   401
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   402
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   403
		 * Use the good data we have in hand to repair damaged children.
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   404
		 *
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   405
		 * We issue all repair I/Os as children of 'rio' to arrange
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   406
		 * that vdev_mirror_map_free(zio) will be invoked after all
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   407
		 * repairs complete, but before we advance to the next stage.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   408
		 */
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   409
		rio = zio_null(zio, zio->io_spa,
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   410
		    vdev_mirror_repair_done, zio, ZIO_FLAG_CANFAIL);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   411
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   412
		for (c = 0; c < mm->mm_children; c++) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   413
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   414
			 * Don't rewrite known good children.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   415
			 * Not only is it unnecessary, it could
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   416
			 * actually be harmful: if the system lost
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   417
			 * power while rewriting the only good copy,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   418
			 * there would be no good copies left!
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   419
			 */
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   420
			mc = &mm->mm_child[c];
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   421
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   422
			if (mc->mc_error == 0) {
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   423
				if (mc->mc_tried)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   424
					continue;
1807
35c8b566d7af 6410711 intent log blocks don't get invited to pool parties
bonwick
parents: 1775
diff changeset
   425
				if (!(zio->io_flags & ZIO_FLAG_SCRUB) &&
35c8b566d7af 6410711 intent log blocks don't get invited to pool parties
bonwick
parents: 1775
diff changeset
   426
				    !vdev_dtl_contains(&mc->mc_vd->vdev_dtl_map,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   427
				    zio->io_txg, 1))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   428
					continue;
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   429
				mc->mc_error = ESTALE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   430
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   431
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   432
			dprintf("resilvered %s @ 0x%llx error %d\n",
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   433
			    vdev_description(mc->mc_vd), mc->mc_offset,
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   434
			    mc->mc_error);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   435
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   436
			zio_nowait(zio_vdev_child_io(rio, zio->io_bp, mc->mc_vd,
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1732
diff changeset
   437
			    mc->mc_offset, zio->io_data, zio->io_size,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   438
			    ZIO_TYPE_WRITE, zio->io_priority,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   439
			    ZIO_FLAG_IO_REPAIR | ZIO_FLAG_CANFAIL |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   440
			    ZIO_FLAG_DONT_PROPAGATE, NULL, NULL));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   441
		}
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   442
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   443
		zio_nowait(rio);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   444
		zio_wait_children_done(zio);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   445
		return;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   446
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   447
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   448
	vdev_mirror_map_free(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   449
	zio_next_stage(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   450
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   451
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   452
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   453
vdev_mirror_state_change(vdev_t *vd, int faulted, int degraded)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   454
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   455
	if (faulted == vd->vdev_children)
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   456
		vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   457
		    VDEV_AUX_NO_REPLICAS);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   458
	else if (degraded + faulted != 0)
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   459
		vdev_set_state(vd, B_FALSE, VDEV_STATE_DEGRADED, VDEV_AUX_NONE);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   460
	else
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   461
		vdev_set_state(vd, B_FALSE, VDEV_STATE_HEALTHY, VDEV_AUX_NONE);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   462
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   463
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   464
vdev_ops_t vdev_mirror_ops = {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   465
	vdev_mirror_open,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   466
	vdev_mirror_close,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   467
	vdev_default_asize,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   468
	vdev_mirror_io_start,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   469
	vdev_mirror_io_done,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   470
	vdev_mirror_state_change,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   471
	VDEV_TYPE_MIRROR,	/* name of this vdev type */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   472
	B_FALSE			/* not a leaf vdev */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   473
};
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   474
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   475
vdev_ops_t vdev_replacing_ops = {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   476
	vdev_mirror_open,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   477
	vdev_mirror_close,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   478
	vdev_default_asize,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   479
	vdev_mirror_io_start,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   480
	vdev_mirror_io_done,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   481
	vdev_mirror_state_change,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   482
	VDEV_TYPE_REPLACING,	/* name of this vdev type */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   483
	B_FALSE			/* not a leaf vdev */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   484
};
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1807
diff changeset
   485
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1807
diff changeset
   486
vdev_ops_t vdev_spare_ops = {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1807
diff changeset
   487
	vdev_mirror_open,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1807
diff changeset
   488
	vdev_mirror_close,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1807
diff changeset
   489
	vdev_default_asize,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1807
diff changeset
   490
	vdev_mirror_io_start,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1807
diff changeset
   491
	vdev_mirror_io_done,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1807
diff changeset
   492
	vdev_mirror_state_change,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1807
diff changeset
   493
	VDEV_TYPE_SPARE,	/* name of this vdev type */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1807
diff changeset
   494
	B_FALSE			/* not a leaf vdev */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1807
diff changeset
   495
};