Mercurial > illumos > illumos-gate
changeset 9846:6527c7b4a92e
6566744 vdev_open() should be done in parallel
author | Eric Taylor <Eric.Taylor@Sun.COM> |
---|---|
date | Thu, 11 Jun 2009 11:10:31 -0600 |
parents | 0d705da26956 |
children | 2f3ba86e857a |
files | usr/src/uts/common/fs/zfs/spa_misc.c usr/src/uts/common/fs/zfs/sys/vdev.h usr/src/uts/common/fs/zfs/sys/vdev_impl.h usr/src/uts/common/fs/zfs/vdev.c usr/src/uts/common/fs/zfs/vdev_label.c usr/src/uts/common/fs/zfs/vdev_mirror.c usr/src/uts/common/fs/zfs/vdev_raidz.c usr/src/uts/common/fs/zfs/vdev_root.c |
diffstat | 8 files changed, 65 insertions(+), 41 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/fs/zfs/spa_misc.c Thu Jun 11 05:00:01 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/spa_misc.c Thu Jun 11 11:10:31 2009 -0600 @@ -310,8 +310,12 @@ void spa_config_enter(spa_t *spa, int locks, void *tag, krw_t rw) { + int wlocks_held = 0; + for (int i = 0; i < SCL_LOCKS; i++) { spa_config_lock_t *scl = &spa->spa_config_lock[i]; + if (scl->scl_writer == curthread) + wlocks_held |= (1 << i); if (!(locks & (1 << i))) continue; mutex_enter(&scl->scl_lock); @@ -331,6 +335,7 @@ (void) refcount_add(&scl->scl_count, tag); mutex_exit(&scl->scl_lock); } + ASSERT(wlocks_held <= locks); } void
--- a/usr/src/uts/common/fs/zfs/sys/vdev.h Thu Jun 11 05:00:01 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/sys/vdev.h Thu Jun 11 11:10:31 2009 -0600 @@ -47,6 +47,7 @@ extern boolean_t zfs_nocacheflush; extern int vdev_open(vdev_t *); +extern void vdev_open_children(vdev_t *vd); extern int vdev_validate(vdev_t *); extern void vdev_close(vdev_t *); extern int vdev_create(vdev_t *, uint64_t txg, boolean_t isreplace);
--- a/usr/src/uts/common/fs/zfs/sys/vdev_impl.h Thu Jun 11 05:00:01 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/sys/vdev_impl.h Thu Jun 11 11:10:31 2009 -0600 @@ -127,6 +127,8 @@ space_map_t vdev_dtl[DTL_TYPES]; /* in-core dirty time logs */ vdev_stat_t vdev_stat; /* virtual device statistics */ boolean_t vdev_expanding; /* expand the vdev? */ + int vdev_open_error; /* error on last open */ + kthread_t *vdev_open_thread; /* thread opening children */ /* * Top-level vdev state.
--- a/usr/src/uts/common/fs/zfs/vdev.c Thu Jun 11 05:00:01 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/vdev.c Thu Jun 11 11:10:31 2009 -0600 @@ -993,6 +993,32 @@ return (NULL); } +static void +vdev_open_child(void *arg) +{ + vdev_t *vd = arg; + + vd->vdev_open_thread = curthread; + vd->vdev_open_error = vdev_open(vd); + vd->vdev_open_thread = NULL; +} + +void +vdev_open_children(vdev_t *vd) +{ + taskq_t *tq; + int children = vd->vdev_children; + + tq = taskq_create("vdev_open", children, minclsyspri, + children, children, TASKQ_PREPOPULATE); + + for (int c = 0; c < children; c++) + VERIFY(taskq_dispatch(tq, vdev_open_child, vd->vdev_child[c], + TQ_SLEEP) != NULL); + + taskq_destroy(tq); +} + /* * Prepare a virtual device for access. */ @@ -1005,8 +1031,8 @@ uint64_t asize, psize; uint64_t ashift = 0; - ASSERT(spa_config_held(spa, SCL_STATE_ALL, RW_WRITER) == SCL_STATE_ALL); - + ASSERT(vd->vdev_open_thread == curthread || + spa_config_held(spa, SCL_STATE_ALL, RW_WRITER) == SCL_STATE_ALL); ASSERT(vd->vdev_state == VDEV_STATE_CLOSED || vd->vdev_state == VDEV_STATE_CANT_OPEN || vd->vdev_state == VDEV_STATE_OFFLINE);
--- a/usr/src/uts/common/fs/zfs/vdev_label.c Thu Jun 11 05:00:01 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/vdev_label.c Thu Jun 11 11:10:31 2009 -0600 @@ -642,8 +642,8 @@ /* * Initialize uberblock template. */ - ub = zio_buf_alloc(VDEV_UBERBLOCK_SIZE(vd)); - bzero(ub, VDEV_UBERBLOCK_SIZE(vd)); + ub = zio_buf_alloc(VDEV_UBERBLOCK_RING); + bzero(ub, VDEV_UBERBLOCK_RING); *ub = spa->spa_uberblock; ub->ub_txg = 0; @@ -672,11 +672,9 @@ offsetof(vdev_label_t, vl_pad2), VDEV_PAD_SIZE, NULL, NULL, flags); - for (int n = 0; n < VDEV_UBERBLOCK_COUNT(vd); n++) { - vdev_label_write(zio, vd, l, ub, - VDEV_UBERBLOCK_OFFSET(vd, n), - VDEV_UBERBLOCK_SIZE(vd), NULL, NULL, flags); - } + vdev_label_write(zio, vd, l, ub, + offsetof(vdev_label_t, vl_uberblock), + VDEV_UBERBLOCK_RING, NULL, NULL, flags); } error = zio_wait(zio); @@ -688,7 +686,7 @@ nvlist_free(label); zio_buf_free(pad2, VDEV_PAD_SIZE); - zio_buf_free(ub, VDEV_UBERBLOCK_SIZE(vd)); + zio_buf_free(ub, VDEV_UBERBLOCK_RING); zio_buf_free(vp, sizeof (vdev_phys_t)); /*
--- a/usr/src/uts/common/fs/zfs/vdev_mirror.c Thu Jun 11 05:00:01 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/vdev_mirror.c Thu Jun 11 11:10:31 2009 -0600 @@ -124,21 +124,21 @@ 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 @@ 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]); }
--- a/usr/src/uts/common/fs/zfs/vdev_raidz.c Thu Jun 11 05:00:01 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/vdev_raidz.c Thu Jun 11 11:10:31 2009 -0600 @@ -559,9 +559,7 @@ static int vdev_raidz_open(vdev_t *vd, uint64_t *asize, uint64_t *ashift) { - vdev_t *cvd; uint64_t nparity = vd->vdev_nparity; - int c, error; int lasterror = 0; int numerrors = 0; @@ -573,11 +571,13 @@ return (EINVAL); } - for (c = 0; c < vd->vdev_children; c++) { - cvd = vd->vdev_child[c]; + vdev_open_children(vd); - if ((error = vdev_open(cvd)) != 0) { - lasterror = error; + 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; } @@ -599,9 +599,7 @@ static void vdev_raidz_close(vdev_t *vd) { - int c; - - for (c = 0; c < vd->vdev_children; c++) + for (int c = 0; c < vd->vdev_children; c++) vdev_close(vd->vdev_child[c]); }
--- a/usr/src/uts/common/fs/zfs/vdev_root.c Thu Jun 11 05:00:01 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/vdev_root.c Thu Jun 11 11:10:31 2009 -0600 @@ -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. */ @@ -52,7 +52,6 @@ static int vdev_root_open(vdev_t *vd, uint64_t *asize, uint64_t *ashift) { - int c; int lasterror = 0; int numerrors = 0; @@ -61,15 +60,14 @@ return (EINVAL); } - for (c = 0; c < vd->vdev_children; c++) { - vdev_t *cvd = vd->vdev_child[c]; - int error; + vdev_open_children(vd); - if ((error = vdev_open(cvd)) != 0 && - !cvd->vdev_islog) { - lasterror = error; + for (int c = 0; c < vd->vdev_children; c++) { + vdev_t *cvd = vd->vdev_child[c]; + + if (cvd->vdev_open_error && !cvd->vdev_islog) { + lasterror = cvd->vdev_open_error; numerrors++; - continue; } } @@ -87,9 +85,7 @@ static void vdev_root_close(vdev_t *vd) { - int c; - - for (c = 0; c < vd->vdev_children; c++) + for (int c = 0; c < vd->vdev_children; c++) vdev_close(vd->vdev_child[c]); }