Skip to content

Commit

Permalink
L2ARC: Stop rebuild before setting spa_final_txg
Browse files Browse the repository at this point in the history
Without doing that there is a race window on export when history
log write by completed rebuild dirties transaction beyond final,
triggering assertion.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: George Amanakis <gamanakis@gmail.com>
Signed-off-by: Alexander Motin <mav@FreeBSD.org>
Sponsored by: iXsystems, Inc.
Closes openzfs#16714
Closes openzfs#16782
  • Loading branch information
amotin authored and ixhamza committed Dec 2, 2024
1 parent b36b97a commit 0463f3d
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 3 deletions.
1 change: 1 addition & 0 deletions include/sys/arc.h
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ void l2arc_fini(void);
void l2arc_start(void);
void l2arc_stop(void);
void l2arc_spa_rebuild_start(spa_t *spa);
void l2arc_spa_rebuild_stop(spa_t *spa);

#ifndef _KERNEL
extern boolean_t arc_watch;
Expand Down
35 changes: 32 additions & 3 deletions module/zfs/arc.c
Original file line number Diff line number Diff line change
Expand Up @@ -9846,6 +9846,37 @@ l2arc_spa_rebuild_start(spa_t *spa)
}
}

void
l2arc_spa_rebuild_stop(spa_t *spa)
{
ASSERT(MUTEX_HELD(&spa_namespace_lock) ||
spa->spa_export_thread == curthread);

for (int i = 0; i < spa->spa_l2cache.sav_count; i++) {
l2arc_dev_t *dev =
l2arc_vdev_get(spa->spa_l2cache.sav_vdevs[i]);
if (dev == NULL)
continue;
mutex_enter(&l2arc_rebuild_thr_lock);
dev->l2ad_rebuild_cancel = B_TRUE;
mutex_exit(&l2arc_rebuild_thr_lock);
}
for (int i = 0; i < spa->spa_l2cache.sav_count; i++) {
l2arc_dev_t *dev =
l2arc_vdev_get(spa->spa_l2cache.sav_vdevs[i]);
if (dev == NULL)
continue;
mutex_enter(&l2arc_rebuild_thr_lock);
if (dev->l2ad_rebuild_began == B_TRUE) {
while (dev->l2ad_rebuild == B_TRUE) {
cv_wait(&l2arc_rebuild_thr_cv,
&l2arc_rebuild_thr_lock);
}
}
mutex_exit(&l2arc_rebuild_thr_lock);
}
}

/*
* Main entry point for L2ARC rebuilding.
*/
Expand All @@ -9854,12 +9885,12 @@ l2arc_dev_rebuild_thread(void *arg)
{
l2arc_dev_t *dev = arg;

VERIFY(!dev->l2ad_rebuild_cancel);
VERIFY(dev->l2ad_rebuild);
(void) l2arc_rebuild(dev);
mutex_enter(&l2arc_rebuild_thr_lock);
dev->l2ad_rebuild_began = B_FALSE;
dev->l2ad_rebuild = B_FALSE;
cv_signal(&l2arc_rebuild_thr_cv);
mutex_exit(&l2arc_rebuild_thr_lock);

thread_exit();
Expand Down Expand Up @@ -10010,8 +10041,6 @@ l2arc_rebuild(l2arc_dev_t *dev)
for (;;) {
mutex_enter(&l2arc_rebuild_thr_lock);
if (dev->l2ad_rebuild_cancel) {
dev->l2ad_rebuild = B_FALSE;
cv_signal(&l2arc_rebuild_thr_cv);
mutex_exit(&l2arc_rebuild_thr_lock);
err = SET_ERROR(ECANCELED);
goto out;
Expand Down
2 changes: 2 additions & 0 deletions module/zfs/spa.c
Original file line number Diff line number Diff line change
Expand Up @@ -2081,6 +2081,7 @@ spa_unload(spa_t *spa)
vdev_trim_stop_all(root_vdev, VDEV_TRIM_ACTIVE);
vdev_autotrim_stop_all(spa);
vdev_rebuild_stop_all(spa);
l2arc_spa_rebuild_stop(spa);
}
}

Expand Down Expand Up @@ -7115,6 +7116,7 @@ spa_export_common(const char *pool, int new_state, nvlist_t **oldconfig,
vdev_trim_stop_all(rvd, VDEV_TRIM_ACTIVE);
vdev_autotrim_stop_all(spa);
vdev_rebuild_stop_all(spa);
l2arc_spa_rebuild_stop(spa);

/*
* We want this to be reflected on every label,
Expand Down

0 comments on commit 0463f3d

Please sign in to comment.