Add AUTHORS to master branch
[zfs.git] / module / zfs / vdev_mirror.c
index c4629ff..836386d 100644 (file)
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -124,21 +124,21 @@ vdev_mirror_map_alloc(zio_t *zio)
 static int
 vdev_mirror_open(vdev_t *vd, uint64_t *asize, uint64_t *ashift)
 {
-       vdev_t *cvd;
-       uint64_t c;
        int numerrors = 0;
-       int ret, lasterror = 0;
+       int lasterror = 0;
 
        if (vd->vdev_children == 0) {
                vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL;
                return (EINVAL);
        }
 
-       for (c = 0; c < vd->vdev_children; c++) {
-               cvd = vd->vdev_child[c];
+       vdev_open_children(vd);
 
-               if ((ret = vdev_open(cvd)) != 0) {
-                       lasterror = ret;
+       for (int c = 0; c < vd->vdev_children; c++) {
+               vdev_t *cvd = vd->vdev_child[c];
+
+               if (cvd->vdev_open_error) {
+                       lasterror = cvd->vdev_open_error;
                        numerrors++;
                        continue;
                }
@@ -158,9 +158,7 @@ vdev_mirror_open(vdev_t *vd, uint64_t *asize, uint64_t *ashift)
 static void
 vdev_mirror_close(vdev_t *vd)
 {
-       uint64_t c;
-
-       for (c = 0; c < vd->vdev_children; c++)
+       for (int c = 0; c < vd->vdev_children; c++)
                vdev_close(vd->vdev_child[c]);
 }
 
@@ -180,11 +178,16 @@ vdev_mirror_scrub_done(zio_t *zio)
        mirror_child_t *mc = zio->io_private;
 
        if (zio->io_error == 0) {
-               zio_t *pio = zio->io_parent;
-               mutex_enter(&pio->io_lock);
-               ASSERT3U(zio->io_size, >=, pio->io_size);
-               bcopy(zio->io_data, pio->io_data, pio->io_size);
-               mutex_exit(&pio->io_lock);
+               zio_t *pio;
+
+               mutex_enter(&zio->io_lock);
+               while ((pio = zio_walk_parents(zio)) != NULL) {
+                       mutex_enter(&pio->io_lock);
+                       ASSERT3U(zio->io_size, >=, pio->io_size);
+                       bcopy(zio->io_data, pio->io_data, pio->io_size);
+                       mutex_exit(&pio->io_lock);
+               }
+               mutex_exit(&zio->io_lock);
        }
 
        zio_buf_free(zio->io_data, zio->io_size);
@@ -225,7 +228,7 @@ vdev_mirror_child_select(zio_t *zio)
                        mc->mc_skipped = 1;
                        continue;
                }
-               if (!vdev_dtl_contains(&mc->mc_vd->vdev_dtl_map, txg, 1))
+               if (!vdev_dtl_contains(mc->mc_vd, DTL_MISSING, txg, 1))
                        return (c);
                mc->mc_error = ESTALE;
                mc->mc_skipped = 1;
@@ -282,20 +285,10 @@ vdev_mirror_io_start(zio_t *zio)
                ASSERT(zio->io_type == ZIO_TYPE_WRITE);
 
                /*
-                * If this is a resilvering I/O to a replacing vdev,
-                * only the last child should be written -- unless the
-                * first child happens to have a DTL entry here as well.
-                * All other writes go to all children.
+                * Writes go to all children.
                 */
-               if ((zio->io_flags & ZIO_FLAG_RESILVER) && mm->mm_replacing &&
-                   !vdev_dtl_contains(&mm->mm_child[0].mc_vd->vdev_dtl_map,
-                   zio->io_txg, 1)) {
-                       c = mm->mm_children - 1;
-                       children = 1;
-               } else {
-                       c = 0;
-                       children = mm->mm_children;
-               }
+               c = 0;
+               children = mm->mm_children;
        }
 
        while (children--) {
@@ -398,7 +391,7 @@ vdev_mirror_io_done(zio_t *zio)
                ASSERT(zio->io_error != 0);
        }
 
-       if (good_copies && (spa_mode & FWRITE) &&
+       if (good_copies && spa_writeable(zio->io_spa) &&
            (unexpected_errors ||
            (zio->io_flags & ZIO_FLAG_RESILVER) ||
            ((zio->io_flags & ZIO_FLAG_SCRUB) && mm->mm_replacing))) {
@@ -419,7 +412,7 @@ vdev_mirror_io_done(zio_t *zio)
                                if (mc->mc_tried)
                                        continue;
                                if (!(zio->io_flags & ZIO_FLAG_SCRUB) &&
-                                   !vdev_dtl_contains(&mc->mc_vd->vdev_dtl_map,
+                                   !vdev_dtl_contains(mc->mc_vd, DTL_PARTIAL,
                                    zio->io_txg, 1))
                                        continue;
                                mc->mc_error = ESTALE;
@@ -429,7 +422,8 @@ vdev_mirror_io_done(zio_t *zio)
                            mc->mc_vd, mc->mc_offset,
                            zio->io_data, zio->io_size,
                            ZIO_TYPE_WRITE, zio->io_priority,
-                           ZIO_FLAG_IO_REPAIR, NULL, NULL));
+                           ZIO_FLAG_IO_REPAIR | (unexpected_errors ?
+                           ZIO_FLAG_SELF_HEAL : 0), NULL, NULL));
                }
        }
 }