From: Brian Behlendorf Date: Wed, 18 Feb 2009 21:09:32 +0000 (-0800) Subject: Merge commit 'refs/top-bases/gcc-c90' into gcc-c90 X-Git-Tag: zfs-0.4.4~12^2~48^2~2^2^2~9^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3b17164f715e3c0cd5205f2e001dc4ad1398f658;p=zfs Merge commit 'refs/top-bases/gcc-c90' into gcc-c90 Conflicts: module/zfs/vdev.c module/zfs/zio.c --- 3b17164f715e3c0cd5205f2e001dc4ad1398f658 diff --cc module/zfs/vdev.c index 6999a33c3,2554f96a9..f01a8a373 --- a/module/zfs/vdev.c +++ b/module/zfs/vdev.c @@@ -871,46 -877,78 +878,79 @@@ vdev_probe_done(zio_t *zio * but the first (which we leave alone in case it contains a VTOC). */ zio_t * - vdev_probe(vdev_t *vd, zio_t *pio) + vdev_probe(vdev_t *vd, zio_t *zio) { spa_t *spa = vd->vdev_spa; - vdev_probe_stats_t *vps; - zio_t *zio; + vdev_probe_stats_t *vps = NULL; + zio_t *pio; + int l; - vps = kmem_zalloc(sizeof (*vps), KM_SLEEP); + ASSERT(vd->vdev_ops->vdev_op_leaf); + + /* + * Don't probe the probe. + */ + if (zio && (zio->io_flags & ZIO_FLAG_PROBE)) + return (NULL); - vps->vps_flags = ZIO_FLAG_CANFAIL | ZIO_FLAG_PROBE | - ZIO_FLAG_DONT_CACHE | ZIO_FLAG_DONT_AGGREGATE | ZIO_FLAG_DONT_RETRY; + /* + * To prevent 'probe storms' when a device fails, we create + * just one probe i/o at a time. All zios that want to probe + * this vdev will become parents of the probe io. + */ + mutex_enter(&vd->vdev_probe_lock); - if (spa_config_held(spa, SCL_ZIO, RW_WRITER)) { - /* - * vdev_cant_read and vdev_cant_write can only transition - * from TRUE to FALSE when we have the SCL_ZIO lock as writer; - * otherwise they can only transition from FALSE to TRUE. - * This ensures that any zio looking at these values can - * assume that failures persist for the life of the I/O. - * That's important because when a device has intermittent - * connectivity problems, we want to ensure that they're - * ascribed to the device (ENXIO) and not the zio (EIO). - * - * Since we hold SCL_ZIO as writer here, clear both values - * so the probe can reevaluate from first principles. - */ - vps->vps_flags |= ZIO_FLAG_CONFIG_WRITER; - vd->vdev_cant_read = B_FALSE; - vd->vdev_cant_write = B_FALSE; + if ((pio = vd->vdev_probe_zio) == NULL) { + vps = kmem_zalloc(sizeof (*vps), KM_SLEEP); + + vps->vps_flags = ZIO_FLAG_CANFAIL | ZIO_FLAG_PROBE | + ZIO_FLAG_DONT_CACHE | ZIO_FLAG_DONT_AGGREGATE | + ZIO_FLAG_DONT_RETRY; + + if (spa_config_held(spa, SCL_ZIO, RW_WRITER)) { + /* + * vdev_cant_read and vdev_cant_write can only + * transition from TRUE to FALSE when we have the + * SCL_ZIO lock as writer; otherwise they can only + * transition from FALSE to TRUE. This ensures that + * any zio looking at these values can assume that + * failures persist for the life of the I/O. That's + * important because when a device has intermittent + * connectivity problems, we want to ensure that + * they're ascribed to the device (ENXIO) and not + * the zio (EIO). + * + * Since we hold SCL_ZIO as writer here, clear both + * values so the probe can reevaluate from first + * principles. + */ + vps->vps_flags |= ZIO_FLAG_CONFIG_WRITER; + vd->vdev_cant_read = B_FALSE; + vd->vdev_cant_write = B_FALSE; + } + + vd->vdev_probe_zio = pio = zio_null(NULL, spa, vd, + vdev_probe_done, vps, + vps->vps_flags | ZIO_FLAG_DONT_PROPAGATE); + + if (zio != NULL) { + vd->vdev_probe_wanted = B_TRUE; + spa_async_request(spa, SPA_ASYNC_PROBE); + } } - ASSERT(vd->vdev_ops->vdev_op_leaf); + if (zio != NULL) + zio_add_child(zio, pio); - zio = zio_null(pio, spa, vdev_probe_done, vps, vps->vps_flags); + mutex_exit(&vd->vdev_probe_lock); - vps->vps_root = zio; - vps->vps_vd = vd; + if (vps == NULL) { + ASSERT(zio != NULL); + return (NULL); + } - for (int l = 1; l < VDEV_LABELS; l++) { + for (l = 1; l < VDEV_LABELS; l++) { - zio_nowait(zio_read_phys(zio, vd, + zio_nowait(zio_read_phys(pio, vd, vdev_label_offset(vd->vdev_psize, l, offsetof(vdev_label_t, vl_pad)), VDEV_SKIP_SIZE, zio_buf_alloc(VDEV_SKIP_SIZE), diff --cc module/zfs/zio.c index b8394540b,a669ad64a..d8aaa3fce --- a/module/zfs/zio.c +++ b/module/zfs/zio.c @@@ -1046,15 -1114,19 +1115,20 @@@ zio_nowait(zio_t *zio static void zio_reexecute(zio_t *pio) { - zio_t *zio, *zio_next; - int c; + zio_t *cio, *cio_next; ++ int c, w; + + ASSERT(pio->io_child_type == ZIO_CHILD_LOGICAL); + ASSERT(pio->io_orig_stage == ZIO_STAGE_OPEN); pio->io_flags = pio->io_orig_flags; pio->io_stage = pio->io_orig_stage; pio->io_pipeline = pio->io_orig_pipeline; pio->io_reexecute = 0; pio->io_error = 0; - for (int w = 0; w < ZIO_WAIT_TYPES; w++) ++ for (w = 0; w < ZIO_WAIT_TYPES; w++) + pio->io_state[w] = 0; - for (int c = 0; c < ZIO_CHILD_TYPES; c++) + for (c = 0; c < ZIO_CHILD_TYPES; c++) pio->io_child_error[c] = 0; if (IO_IS_ALLOCATING(pio)) { @@@ -1356,10 -1427,10 +1431,11 @@@ zio_gang_tree_assemble_done(zio_t *zio zio_t *lio = zio->io_logical; zio_gang_node_t *gn = zio->io_private; blkptr_t *bp = zio->io_bp; + zio_t *pio = zio_unique_parent(zio); + int g; - ASSERT(zio->io_parent == lio); - ASSERT(zio->io_child == NULL); + ASSERT(pio == lio); + ASSERT(zio_walk_children(zio) == NULL); if (zio->io_error) return; @@@ -2111,7 -2125,7 +2133,8 @@@ zio_done(zio_t *zio blkptr_t *bp = zio->io_bp; vdev_t *vd = zio->io_vd; uint64_t psize = zio->io_size; + zio_t *pio, *pio_next; + int c, w; /* * If our of children haven't all completed,