Skip to content

Commit

Permalink
ztest: Fix scratch object verification
Browse files Browse the repository at this point in the history
Make scratch object verification logic more robust to
decrease number of verification assertions triggering.

Remove reflow pause from verification logic and add
additional scratch object states. Implement verification
based on these new scratch states added.
  • Loading branch information
fuporovvStack committed Aug 1, 2023
1 parent fcaf638 commit 015644f
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 19 deletions.
63 changes: 50 additions & 13 deletions cmd/ztest.c
Original file line number Diff line number Diff line change
Expand Up @@ -3944,8 +3944,10 @@ static void
raidz_scratch_verify(void)
{
spa_t *spa;
uint64_t pause, offset;
uint64_t write_size, logical_size, offset;
raidz_reflow_scratch_state_t state;
vdev_raidz_expand_t *vre;
vdev_t *raidvd;

ASSERT(raidz_expand_max_offset_pause == 0);

Expand All @@ -3964,23 +3966,58 @@ raidz_scratch_verify(void)

ASSERT3U(RRSS_GET_OFFSET(&spa->spa_uberblock), !=, UINT64_MAX);

pause = ztest_scratch_state->zs_raidz_scratch_verify_pause;
mutex_enter(&ztest_vdev_lock);

spa_config_enter(spa, SCL_ALL, FTAG, RW_READER);

vre = spa->spa_raidz_expand;
raidvd = vdev_lookup_top(spa, vre->vre_vdev_id);
offset = RRSS_GET_OFFSET(&spa->spa_uberblock);
state = RRSS_GET_STATE(&spa->spa_uberblock);
write_size = P2ALIGN(VDEV_BOOT_SIZE, 1 << raidvd->vdev_ashift);
logical_size = write_size * raidvd->vdev_children;

if (pause < RAIDZ_EXPAND_PAUSE_SCRATCH_VALID) {
ASSERT3U(offset, ==, 0);
ASSERT3U(state, ==, RRSS_SCRATCH_NOT_IN_USE);
} else if (pause >= RAIDZ_EXPAND_PAUSE_SCRATCH_VALID &&
pause <= RAIDZ_EXPAND_PAUSE_SCRATCH_REFLOWED) {
ASSERT3U(offset, >=, pause);
ASSERT3U(state, ==, RRSS_SCRATCH_VALID);
} else {
ASSERT(pause <= RAIDZ_EXPAND_PAUSE_SCRATCH_NOT_IN_USE);
ASSERT3U(offset, >, pause);
ASSERT3U(state, ==, RRSS_SCRATCH_NOT_IN_USE);
switch (state) {
/*
* Initial state of reflow process. RAIDZ expansion was
* requested by user, but scratch object was not created.
*/
case RRSS_SCRATCH_NOT_IN_USE:
ASSERT3U(offset, ==, 0);
break;

/*
* Scratch object was synced and stored in boot area.
*/
case RRSS_SCRATCH_VALID:

/*
* Scratch object was synced back to raidz start offset,
* raidz is ready for sector by sector reflow process.
*/
case RRSS_SCRATCH_INVALID_SYNCED:

/*
* Scratch object was synced back to raidz start offset
* on zpool importing, raidz is ready for sector by sector
* reflow process.
*/
case RRSS_SCRATCH_INVALID_SYNCED_ON_IMPORT:
ASSERT3U(offset, ==, logical_size);
break;

/*
* Sector by sector reflow process started.
*/
case RRSS_SCRATCH_INVALID_SYNCED_REFLOW:
ASSERT3U(offset, >=, logical_size);
break;
}

spa_config_exit(spa, SCL_ALL, FTAG);

mutex_exit(&ztest_vdev_lock);

ztest_scratch_state->zs_raidz_scratch_verify_pause = 0;

spa_close(spa, FTAG);
Expand Down
3 changes: 3 additions & 0 deletions include/sys/uberblock_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ extern "C" {
typedef enum raidz_reflow_scratch_state {
RRSS_SCRATCH_NOT_IN_USE = 0,
RRSS_SCRATCH_VALID,
RRSS_SCRATCH_INVALID_SYNCED,
RRSS_SCRATCH_INVALID_SYNCED_ON_IMPORT,
RRSS_SCRATCH_INVALID_SYNCED_REFLOW
} raidz_reflow_scratch_state_t;

#define RRSS_GET_OFFSET(ub) \
Expand Down
3 changes: 1 addition & 2 deletions module/zfs/spa.c
Original file line number Diff line number Diff line change
Expand Up @@ -5034,8 +5034,7 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport)
* Before we do any zio_write's, complete the raidz expansion
* scratch space copying, if necessary.
*/
if (RRSS_GET_STATE(&spa->spa_uberblock) !=
RRSS_SCRATCH_NOT_IN_USE) {
if (RRSS_GET_STATE(&spa->spa_uberblock) == RRSS_SCRATCH_VALID) {
vdev_raidz_reflow_copy_scratch(spa);
}

Expand Down
2 changes: 1 addition & 1 deletion module/zfs/vdev_label.c
Original file line number Diff line number Diff line change
Expand Up @@ -1752,7 +1752,7 @@ vdev_uberblock_sync(zio_t *zio, uint64_t *good_writes,
* uberblock.
*/
int m = spa_multihost(vd->vdev_spa) ? MMP_BLOCKS_PER_LABEL : 0;
int n = (ub->ub_txg - RRSS_GET_STATE(ub)) %
int n = (ub->ub_txg - (RRSS_GET_STATE(ub) == RRSS_SCRATCH_VALID)) %
(VDEV_UBERBLOCK_COUNT(vd) - m);

/* Copy the uberblock_t into the ABD */
Expand Down
6 changes: 3 additions & 3 deletions module/zfs/vdev_raidz.c
Original file line number Diff line number Diff line change
Expand Up @@ -3504,7 +3504,7 @@ raidz_reflow_sync(void *arg, dmu_tx_t *tx)
(long long)vre->vre_offset_pertxg[txgoff],
(long long)vre->vre_failed_offset);
RAIDZ_REFLOW_SET(&spa->spa_uberblock,
RRSS_SCRATCH_NOT_IN_USE, new_offset);
RRSS_SCRATCH_INVALID_SYNCED_REFLOW, new_offset);
vre->vre_offset_pertxg[txgoff] = 0;
zfs_rangelock_exit(lr);

Expand Down Expand Up @@ -3965,7 +3965,7 @@ raidz_reflow_scratch_sync(void *arg, dmu_tx_t *tx)
* scratch space, we would lose the regular writes.
*/
RAIDZ_REFLOW_SET(&spa->spa_ubsync,
RRSS_SCRATCH_NOT_IN_USE, logical_size);
RRSS_SCRATCH_INVALID_SYNCED, logical_size);
spa->spa_ubsync.ub_timestamp++;
ASSERT0(vdev_uberblock_sync_list(&spa->spa_root_vdev, 1,
&spa->spa_ubsync, ZIO_FLAG_CONFIG_WRITER));
Expand Down Expand Up @@ -4067,7 +4067,7 @@ vdev_raidz_reflow_copy_scratch(spa_t *spa)
* Update uberblock.
*/
RAIDZ_REFLOW_SET(&spa->spa_ubsync,
RRSS_SCRATCH_NOT_IN_USE, logical_size);
RRSS_SCRATCH_INVALID_SYNCED_ON_IMPORT, logical_size);
spa->spa_ubsync.ub_timestamp++;
VERIFY0(vdev_uberblock_sync_list(&spa->spa_root_vdev, 1,
&spa->spa_ubsync, ZIO_FLAG_CONFIG_WRITER));
Expand Down

0 comments on commit 015644f

Please sign in to comment.