fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The contents of this file are subject to the terms of the
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Common Development and Distribution License (the "License").
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * You may not use this file except in compliance with the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the License for the specific language governing permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and limitations under the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When distributing Covered Code, include this CDDL HEADER in each
fa9e4066f08beec538e775443c5be79dd423fcabahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If applicable, add the following below this CDDL HEADER, with the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fields enclosed by brackets "[]" replaced with your own identifying
fa9e4066f08beec538e775443c5be79dd423fcabahrens * information: Portions Copyright [yyyy] [name of copyright owner]
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER END
dcba9f3fbefe06ad19972b4de0351924601e5767George Wilson * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Use is subject to license terms.
0f7643c7376dd69a08acbfc9d1d7d548b10c846aGeorge Wilson * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Virtual device vector for mirroring.
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick kmem_free(mm, offsetof(mirror_map_t, mm_child[mm->mm_children]));
22fe2c8844be88ebae6478ca1b0b92c8ec2aef54Jonathan Adamsstatic const zio_vsd_ops_t vdev_mirror_vsd_ops = {
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm mm = kmem_zalloc(offsetof(mirror_map_t, mm_child[c]), KM_SLEEP);
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm * Check the other, lower-index DVAs to see if they're on
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm * the same vdev as the child we picked. If they are, use
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm * them since they are likely to have been allocated from
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm * the primary metaslab in use at the time, and hence are
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm * more likely to have locality with single-copy data.
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm mc->mc_vd = vdev_lookup_top(spa, DVA_GET_VDEV(&dva[c]));
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm mm = kmem_zalloc(offsetof(mirror_map_t, mm_child[c]), KM_SLEEP);
99653d4ee642c6528e88224f12409a5f23060994eschrock mm->mm_replacing = (vd->vdev_ops == &vdev_replacing_ops ||
4263d13f00c9691fa14620eff82abef795be0693George Wilsonvdev_mirror_open(vdev_t *vd, uint64_t *asize, uint64_t *max_asize,
4263d13f00c9691fa14620eff82abef795be0693George Wilson *max_asize = MIN(*max_asize - 1, cvd->vdev_max_asize - 1) + 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
0f7643c7376dd69a08acbfc9d1d7d548b10c846aGeorge Wilson while ((pio = zio_walk_parents(zio, &zl)) != NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Try to find a child whose DTL doesn't contain the block we want to read.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If we can't, try the read on any vdev we haven't already tried.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ASSERT(zio->io_bp == NULL || BP_PHYSICAL_BIRTH(zio->io_bp) == txg);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Try to find a child whose DTL doesn't contain the block to read.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If a child is known to be completely inaccessible (indicated by
0a4e9518a44f226be6d39383330b5b1792d2f184gw * vdev_readable() returning B_FALSE), don't even try.
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm for (i = 0, c = mm->mm_preferred; i < mm->mm_children; i++, c++) {
8ad4d6dd86f5bc65fb3afa566c8133f3bac21648Jeff Bonwick if (!vdev_dtl_contains(mc->mc_vd, DTL_MISSING, txg, 1))
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (c);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Every device is either missing or has this txg in its DTL.
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm * Look for any child we haven't already tried before giving up.
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm return (c);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Every child failed. There's no place left to look.
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm if ((zio->io_flags & ZIO_FLAG_SCRUB) && !mm->mm_replacing) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens * For scrubbing reads we need to allocate a read
fa9e4066f08beec538e775443c5be79dd423fcabahrens * buffer for each child and issue reads to all
fa9e4066f08beec538e775443c5be79dd423fcabahrens * children. If any child succeeds, it will copy its
fa9e4066f08beec538e775443c5be79dd423fcabahrens * data into zio->io_data in vdev_mirror_scrub_done.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * For normal reads just pick one child.
8ad4d6dd86f5bc65fb3afa566c8133f3bac21648Jeff Bonwick * Writes go to all children.
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick mc->mc_vd, mc->mc_offset, zio->io_data, zio->io_size,
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick error[s] = zio_worst_error(error[s], mc->mc_error);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * XXX -- for now, treat partial writes as success.
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * Now that we support write reallocation, it would be better
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * to treat partial failure as real failure unless there are
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * no non-degraded top-level vdevs left, and not update DTLs
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * if we intend to reallocate.
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* XXPOLICY */
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * Always require at least one good copy.
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * For ditto blocks (io_vd == NULL), require
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * all copies to be good.
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * XXX -- for replacing vdevs, there's no great answer.
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * If the old device is really dead, we may not even
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * be able to access it -- so we only want to
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * require good writes to the new device. But if
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * the new device turns out to be flaky, we want
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * to be able to detach it -- which requires all
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * writes to the old device to have succeeded.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If we don't have a good copy yet, keep trying other children.
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* XXPOLICY */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (good_copies == 0 && (c = vdev_mirror_child_select(zio)) != -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* XXPOLICY */
8ad4d6dd86f5bc65fb3afa566c8133f3bac21648Jeff Bonwick if (good_copies && spa_writeable(zio->io_spa) &&
d80c45e0f58fa434ba37259ea2e2b12e0380c19abonwick ((zio->io_flags & ZIO_FLAG_SCRUB) && mm->mm_replacing))) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Use the good data we have in hand to repair damaged children.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Don't rewrite known good children.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Not only is it unnecessary, it could
fa9e4066f08beec538e775443c5be79dd423fcabahrens * actually be harmful: if the system lost
fa9e4066f08beec538e775443c5be79dd423fcabahrens * power while rewriting the only good copy,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * there would be no good copies left!
fa9e4066f08beec538e775443c5be79dd423fcabahrensvdev_mirror_state_change(vdev_t *vd, int faulted, int degraded)
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock vdev_set_state(vd, B_FALSE, VDEV_STATE_DEGRADED, VDEV_AUX_NONE);