Skip to content

Commit

Permalink
Skip spacemaps reading in case of pool readonly import
Browse files Browse the repository at this point in the history
The only zdb utility require to read metaslab-related data during
read-only pool import because of spacemaps validation. Add global
varialbe which will allow zdb read spacemaps in case of readonly
import mode.

Signed-off-by: Fedor Uporov <fuporov.vstack@gmail.com>
Closes openzfs#9095
  • Loading branch information
fuporovvStack committed Oct 26, 2021
1 parent 90b77a0 commit 2b56db3
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 2 deletions.
6 changes: 6 additions & 0 deletions cmd/zdb/zdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ extern int zfs_recover;
extern unsigned long zfs_arc_meta_min, zfs_arc_meta_limit;
extern int zfs_vdev_async_read_max_active;
extern boolean_t spa_load_verify_dryrun;
extern boolean_t spa_mode_readable_spacemaps;
extern int zfs_reconstruct_indirect_combinations_max;
extern int zfs_btree_verify_intensity;

Expand Down Expand Up @@ -8524,6 +8525,11 @@ main(int argc, char **argv)
*/
spa_load_verify_dryrun = B_TRUE;

/*
* ZDB should have ability to read spacemaps.
*/
spa_mode_readable_spacemaps = B_TRUE;

kernel_init(SPA_MODE_READ);

if (dump_all)
Expand Down
1 change: 1 addition & 0 deletions include/sys/spa_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ struct spa {
boolean_t spa_is_root; /* pool is root */
int spa_minref; /* num refs when first opened */
spa_mode_t spa_mode; /* SPA_MODE_{READ|WRITE} */
boolean_t spa_read_spacemaps; /* spacemaps available if ro */
spa_log_state_t spa_log_state; /* log state */
uint64_t spa_autoexpand; /* lun expansion on/off */
ddt_t *spa_ddt[ZIO_CHECKSUM_FUNCTIONS]; /* in-core DDTs */
Expand Down
6 changes: 4 additions & 2 deletions module/zfs/metaslab.c
Original file line number Diff line number Diff line change
Expand Up @@ -2661,7 +2661,8 @@ metaslab_init(metaslab_group_t *mg, uint64_t id, uint64_t object,

/*
* 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.
*
* Note:
* When called from vdev_expand(), we can't call into the DMU as
Expand All @@ -2670,7 +2671,8 @@ metaslab_init(metaslab_group_t *mg, uint64_t id, uint64_t object,
* that case, the object parameter is zero though, so we won't
* call into the DMU.
*/
if (object != 0) {
if (object != 0 && !(spa->spa_mode == SPA_MODE_READ &&
!spa->spa_read_spacemaps)) {
error = space_map_open(&ms->ms_sm, mos, object, ms->ms_start,
ms->ms_size, vd->vdev_ashift);

Expand Down
7 changes: 7 additions & 0 deletions module/zfs/spa.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,12 @@ boolean_t spa_create_process = B_TRUE; /* no process ==> no sysdc */
*/
boolean_t spa_load_verify_dryrun = B_FALSE;

/*
* Allow read spacemaps in case of readonly import (spa_mode == SPA_MODE_READ).
* This is used by zdb for spacemaps verification.
*/
boolean_t spa_mode_readable_spacemaps = B_FALSE;

/*
* This (illegal) pool name is used when temporarily importing a spa_t in order
* to get the vdev stats associated with the imported devices.
Expand Down Expand Up @@ -1242,6 +1248,7 @@ spa_activate(spa_t *spa, spa_mode_t mode)

spa->spa_state = POOL_STATE_ACTIVE;
spa->spa_mode = mode;
spa->spa_read_spacemaps = spa_mode_readable_spacemaps;

spa->spa_normal_class = metaslab_class_create(spa, zfs_metaslab_ops);
spa->spa_log_class = metaslab_class_create(spa, zfs_metaslab_ops);
Expand Down
6 changes: 6 additions & 0 deletions module/zfs/vdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -3142,6 +3142,12 @@ vdev_dtl_load(vdev_t *vd)
if (vd->vdev_ops->vdev_op_leaf && vd->vdev_dtl_object != 0) {
ASSERT(vdev_is_concrete(vd));

/*
* If the dtl cannot be sync'd there is no need to open it.
*/
if (spa->spa_mode == SPA_MODE_READ && !spa->spa_read_spacemaps)
return (0);

error = space_map_open(&vd->vdev_dtl_sm, mos,
vd->vdev_dtl_object, 0, -1ULL, 0);
if (error)
Expand Down

0 comments on commit 2b56db3

Please sign in to comment.