Changeset View
Changeset View
Standalone View
Standalone View
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_indirect.c
Show First 20 Lines • Show All 1,141 Lines • ▼ Show 20 Lines | |||||
vdev_indirect_child_io_done(zio_t *zio) | vdev_indirect_child_io_done(zio_t *zio) | ||||
{ | { | ||||
zio_t *pio = zio->io_private; | zio_t *pio = zio->io_private; | ||||
mutex_enter(&pio->io_lock); | mutex_enter(&pio->io_lock); | ||||
pio->io_error = zio_worst_error(pio->io_error, zio->io_error); | pio->io_error = zio_worst_error(pio->io_error, zio->io_error); | ||||
mutex_exit(&pio->io_lock); | mutex_exit(&pio->io_lock); | ||||
#ifdef __FreeBSD__ | |||||
if (zio->io_abd != NULL) | |||||
#endif | |||||
abd_put(zio->io_abd); | abd_put(zio->io_abd); | ||||
} | } | ||||
/* | /* | ||||
* This is a callback for vdev_indirect_remap() which allocates an | * This is a callback for vdev_indirect_remap() which allocates an | ||||
* indirect_split_t for each split segment and adds it to iv_splits. | * indirect_split_t for each split segment and adds it to iv_splits. | ||||
*/ | */ | ||||
static void | static void | ||||
▲ Show 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | vdev_indirect_io_start(zio_t *zio) | ||||
indirect_vsd_t *iv = kmem_zalloc(sizeof (*iv), KM_SLEEP); | indirect_vsd_t *iv = kmem_zalloc(sizeof (*iv), KM_SLEEP); | ||||
list_create(&iv->iv_splits, | list_create(&iv->iv_splits, | ||||
sizeof (indirect_split_t), offsetof(indirect_split_t, is_node)); | sizeof (indirect_split_t), offsetof(indirect_split_t, is_node)); | ||||
zio->io_vsd = iv; | zio->io_vsd = iv; | ||||
zio->io_vsd_ops = &vdev_indirect_vsd_ops; | zio->io_vsd_ops = &vdev_indirect_vsd_ops; | ||||
ASSERT(spa_config_held(spa, SCL_ALL, RW_READER) != 0); | ASSERT(spa_config_held(spa, SCL_ALL, RW_READER) != 0); | ||||
#ifdef __FreeBSD__ | |||||
if (zio->io_type == ZIO_TYPE_WRITE) { | |||||
#else | |||||
if (zio->io_type != ZIO_TYPE_READ) { | if (zio->io_type != ZIO_TYPE_READ) { | ||||
ASSERT3U(zio->io_type, ==, ZIO_TYPE_WRITE); | ASSERT3U(zio->io_type, ==, ZIO_TYPE_WRITE); | ||||
#endif | |||||
/* | /* | ||||
* Note: this code can handle other kinds of writes, | * Note: this code can handle other kinds of writes, | ||||
* but we don't expect them. | * but we don't expect them. | ||||
*/ | */ | ||||
ASSERT((zio->io_flags & (ZIO_FLAG_SELF_HEAL | | ASSERT((zio->io_flags & (ZIO_FLAG_SELF_HEAL | | ||||
ZIO_FLAG_RESILVER | ZIO_FLAG_INDUCE_DAMAGE)) != 0); | ZIO_FLAG_RESILVER | ZIO_FLAG_INDUCE_DAMAGE)) != 0); | ||||
} | } | ||||
Show All 15 Lines | if (first->is_size == zio->io_size) { | ||||
* (which are not split) are handled identically to blocks | * (which are not split) are handled identically to blocks | ||||
* on non-indirect vdevs. This allows us to be less strict | * on non-indirect vdevs. This allows us to be less strict | ||||
* about performance in the general (but rare) case. | * about performance in the general (but rare) case. | ||||
*/ | */ | ||||
ASSERT0(first->is_split_offset); | ASSERT0(first->is_split_offset); | ||||
ASSERT3P(list_next(&iv->iv_splits, first), ==, NULL); | ASSERT3P(list_next(&iv->iv_splits, first), ==, NULL); | ||||
zio_nowait(zio_vdev_child_io(zio, zio->io_bp, | zio_nowait(zio_vdev_child_io(zio, zio->io_bp, | ||||
first->is_vdev, first->is_target_offset, | first->is_vdev, first->is_target_offset, | ||||
#ifdef __FreeBSD__ | |||||
zio->io_abd == NULL ? NULL : | |||||
#endif | |||||
abd_get_offset(zio->io_abd, 0), | abd_get_offset(zio->io_abd, 0), | ||||
zio->io_size, zio->io_type, zio->io_priority, 0, | zio->io_size, zio->io_type, zio->io_priority, 0, | ||||
vdev_indirect_child_io_done, zio)); | vdev_indirect_child_io_done, zio)); | ||||
} else { | } else { | ||||
iv->iv_split_block = B_TRUE; | iv->iv_split_block = B_TRUE; | ||||
if (zio->io_flags & (ZIO_FLAG_SCRUB | ZIO_FLAG_RESILVER)) { | if (zio->io_flags & (ZIO_FLAG_SCRUB | ZIO_FLAG_RESILVER)) { | ||||
/* | /* | ||||
* Read all copies. Note that for simplicity, | * Read all copies. Note that for simplicity, | ||||
Show All 10 Lines | if (zio->io_flags & (ZIO_FLAG_SCRUB | ZIO_FLAG_RESILVER)) { | ||||
* E.g. if it's a mirror, it will just read from a | * E.g. if it's a mirror, it will just read from a | ||||
* random (healthy) leaf vdev. We have to verify | * random (healthy) leaf vdev. We have to verify | ||||
* the checksum in vdev_indirect_io_done(). | * the checksum in vdev_indirect_io_done(). | ||||
*/ | */ | ||||
for (indirect_split_t *is = list_head(&iv->iv_splits); | for (indirect_split_t *is = list_head(&iv->iv_splits); | ||||
is != NULL; is = list_next(&iv->iv_splits, is)) { | is != NULL; is = list_next(&iv->iv_splits, is)) { | ||||
zio_nowait(zio_vdev_child_io(zio, NULL, | zio_nowait(zio_vdev_child_io(zio, NULL, | ||||
is->is_vdev, is->is_target_offset, | is->is_vdev, is->is_target_offset, | ||||
#ifdef __FreeBSD__ | |||||
zio->io_abd == NULL ? NULL : | |||||
#endif | |||||
abd_get_offset(zio->io_abd, | abd_get_offset(zio->io_abd, | ||||
is->is_split_offset), | is->is_split_offset), | ||||
is->is_size, zio->io_type, | is->is_size, zio->io_type, | ||||
zio->io_priority, 0, | zio->io_priority, 0, | ||||
vdev_indirect_child_io_done, zio)); | vdev_indirect_child_io_done, zio)); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 305 Lines • Show Last 20 Lines |