Mercurial > illumos > illumos-gate
diff usr/src/uts/common/fs/zfs/spa.c @ 1732:9e3ae798af31
6280668 pluggable block allocation policy
6399301 initial read of space maps is super slow
6407365 large-sector disk support in ZFS
6407366 ADVANCE_NOLOCK gathers MOS
6407367 three-way deadlock between db_mtx, dbuf_hash[], and ms_lock
author | bonwick |
---|---|
date | Sun, 02 Apr 2006 00:47:06 -0800 |
parents | 0ab1193d47cb |
children | a7c3bc84e012 |
line wrap: on
line diff
--- a/usr/src/uts/common/fs/zfs/spa.c Sat Apr 01 21:50:51 2006 -0800 +++ b/usr/src/uts/common/fs/zfs/spa.c Sun Apr 02 00:47:06 2006 -0800 @@ -341,8 +341,7 @@ * If the vdev guid sum doesn't match the uberblock, we have an * incomplete configuration. */ - if (rvd->vdev_guid_sum != ub->ub_guid_sum && (mosconfig || - state == SPA_LOAD_IMPORT || state == SPA_LOAD_TRYIMPORT)) { + if (rvd->vdev_guid_sum != ub->ub_guid_sum && mosconfig) { vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN, VDEV_AUX_BAD_GUID_SUM); error = ENXIO; @@ -842,8 +841,10 @@ /* * Pass off the heavy lifting to spa_load(). + * Pass TRUE for mosconfig because the user-supplied config + * is actually the one to trust when doing an import. */ - error = spa_load(spa, config, SPA_LOAD_IMPORT, B_FALSE); + error = spa_load(spa, config, SPA_LOAD_IMPORT, B_TRUE); if (error) { spa_unload(spa); @@ -898,8 +899,10 @@ /* * Pass off the heavy lifting to spa_load(). + * Pass TRUE for mosconfig because the user-supplied config + * is actually the one to trust when doing an import. */ - (void) spa_load(spa, tryconfig, SPA_LOAD_TRYIMPORT, B_FALSE); + (void) spa_load(spa, tryconfig, SPA_LOAD_TRYIMPORT, B_TRUE); /* * If 'tryconfig' was at least parsable, return the current config. @@ -1163,7 +1166,11 @@ if (newvd->vdev_psize < vdev_get_rsize(oldvd)) return (spa_vdev_exit(spa, newrootvd, txg, EOVERFLOW)); - if (newvd->vdev_ashift != oldvd->vdev_ashift && oldvd->vdev_ashift != 0) + /* + * The new device cannot have a higher alignment requirement + * than the top-level vdev. + */ + if (newvd->vdev_ashift > oldvd->vdev_top->vdev_ashift) return (spa_vdev_exit(spa, newrootvd, txg, EDOM)); /* @@ -1228,8 +1235,7 @@ /* * Mark newvd's DTL dirty in this txg. */ - vdev_dirty(tvd, VDD_DTL, txg); - (void) txg_list_add(&tvd->vdev_dtl_list, newvd, txg); + vdev_dirty(tvd, VDD_DTL, newvd, txg); (void) spa_vdev_exit(spa, newrootvd, open_txg, 0); @@ -1356,12 +1362,11 @@ /* * If the device we just detached was smaller than the others, - * it may be possible to add metaslabs (i.e. grow the pool). We ignore - * the error here because the detach still succeeded - we just weren't - * able to reinitialize the metaslabs. This pool is in for a world of - * hurt, in any case. + * it may be possible to add metaslabs (i.e. grow the pool). + * vdev_metaslab_init() can't fail because the existing metaslabs + * are already in core, so there's nothing to read from disk. */ - (void) vdev_metaslab_init(tvd, txg); + VERIFY(vdev_metaslab_init(tvd, txg) == 0); vdev_config_dirty(tvd); @@ -1372,11 +1377,10 @@ * But first make sure we're not on any *other* txg's DTL list, * to prevent vd from being accessed after it's freed. */ - vdev_dirty(tvd, VDD_DTL, txg); - vd->vdev_detached = B_TRUE; for (t = 0; t < TXG_SIZE; t++) (void) txg_list_remove_this(&tvd->vdev_dtl_list, vd, t); - (void) txg_list_add(&tvd->vdev_dtl_list, vd, txg); + vd->vdev_detached = B_TRUE; + vdev_dirty(tvd, VDD_DTL, vd, txg); dprintf("detached %s in txg %llu\n", vd->vdev_path, txg); @@ -1798,10 +1802,13 @@ if (rvd->vdev_dtl_map.sm_space == 0) { /* * The pool-wide DTL is empty. - * If this is a resilver, there's nothing to do. + * If this is a resilver, there's nothing to do except + * check whether any in-progress replacements have completed. */ - if (type == POOL_SCRUB_RESILVER) + if (type == POOL_SCRUB_RESILVER) { type = POOL_SCRUB_NONE; + spa_async_request(spa, SPA_ASYNC_REPLACE_DONE); + } } else { /* * The pool-wide DTL is non-empty.