aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2014-11-18 17:29:04 -0500
committerBrian Behlendorf <[email protected]>2015-02-09 16:43:03 -0800
commit7fc8c33ede10f7104ca0e91d690d3ebb5236887b (patch)
tree452af234f8e3c6fc5f51b70da2a9ed2e7af3f578
parentbf5efb5c66ac30442bded92c3299db36fe21d92f (diff)
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 <[email protected]> Issue #2831
-rw-r--r--module/zfs/metaslab.c5
-rw-r--r--module/zfs/vdev.c6
2 files changed, 9 insertions, 2 deletions
diff --git a/module/zfs/metaslab.c b/module/zfs/metaslab.c
index f9eef272b..43d3b211e 100644
--- a/module/zfs/metaslab.c
+++ b/module/zfs/metaslab.c
@@ -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
- * 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,
ms->ms_size, vd->vdev_ashift, &ms->ms_lock);
diff --git a/module/zfs/vdev.c b/module/zfs/vdev.c
index 52198261e..834cc1a48 100644
--- a/module/zfs/vdev.c
+++ b/module/zfs/vdev.c
@@ -1906,6 +1906,12 @@ vdev_dtl_load(vdev_t *vd)
if (vd->vdev_ops->vdev_op_leaf && vd->vdev_dtl_object != 0) {
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,
vd->vdev_dtl_object, 0, -1ULL, 0, &vd->vdev_dtl_lock);
if (error)