Don't read space maps during import for readonly pools

Normally when importing a pool the space maps for all top level
vdevs are read from disk.  The space maps will be required latter
when an allocation is performed and free blocks need to be located.

However, if the pool is imported readonly then we are guaranteed
that no allocations can occur.  In this case the space maps need
not be loaded..   A similar argument can be made for the DTLs
(dirty time logs).

Because a pool import will fail if the space maps cannot be read.
The ability to safely ignore them makes it more likely that a
damaged pool can be imported readonly to recover its contents.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Issue #2831
This commit is contained in:
Brian Behlendorf 2014-11-18 17:29:04 -05:00
parent bf5efb5c66
commit 7fc8c33ede
2 changed files with 9 additions and 2 deletions

View File

@ -1255,9 +1255,10 @@ metaslab_init(metaslab_group_t *mg, uint64_t id, uint64_t object, uint64_t txg,
/* /*
* We only open space map objects that already exist. All others * We only open space map objects that already exist. All others
* will be opened when we finally allocate an object for it. * will be opened when we finally allocate an object for it. For
* readonly pools there is no need to open the space map object.
*/ */
if (object != 0) { if (object != 0 && spa_writeable(vd->vdev_spa)) {
error = space_map_open(&ms->ms_sm, mos, object, ms->ms_start, error = space_map_open(&ms->ms_sm, mos, object, ms->ms_start,
ms->ms_size, vd->vdev_ashift, &ms->ms_lock); ms->ms_size, vd->vdev_ashift, &ms->ms_lock);

View File

@ -1906,6 +1906,12 @@ vdev_dtl_load(vdev_t *vd)
if (vd->vdev_ops->vdev_op_leaf && vd->vdev_dtl_object != 0) { if (vd->vdev_ops->vdev_op_leaf && vd->vdev_dtl_object != 0) {
ASSERT(!vd->vdev_ishole); ASSERT(!vd->vdev_ishole);
/*
* If the dtl cannot be sync'd there is no need to open it.
*/
if (!spa_writeable(spa))
return (0);
error = space_map_open(&vd->vdev_dtl_sm, mos, error = space_map_open(&vd->vdev_dtl_sm, mos,
vd->vdev_dtl_object, 0, -1ULL, 0, &vd->vdev_dtl_lock); vd->vdev_dtl_object, 0, -1ULL, 0, &vd->vdev_dtl_lock);
if (error) if (error)