Skip to content

Commit 0ca82c5

Browse files
authored
L2ARC: Stop rebuild before setting spa_final_txg
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 <[email protected]> Reviewed-by: George Amanakis <[email protected]> Signed-off-by: Alexander Motin <[email protected]> Sponsored by: iXsystems, Inc. Closes #16714 Closes #16782
1 parent 5346889 commit 0ca82c5

File tree

3 files changed

+35
-3
lines changed

3 files changed

+35
-3
lines changed

include/sys/arc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ void l2arc_fini(void);
347347
void l2arc_start(void);
348348
void l2arc_stop(void);
349349
void l2arc_spa_rebuild_start(spa_t *spa);
350+
void l2arc_spa_rebuild_stop(spa_t *spa);
350351

351352
#ifndef _KERNEL
352353
extern boolean_t arc_watch;

module/zfs/arc.c

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9846,6 +9846,37 @@ l2arc_spa_rebuild_start(spa_t *spa)
98469846
}
98479847
}
98489848

9849+
void
9850+
l2arc_spa_rebuild_stop(spa_t *spa)
9851+
{
9852+
ASSERT(MUTEX_HELD(&spa_namespace_lock) ||
9853+
spa->spa_export_thread == curthread);
9854+
9855+
for (int i = 0; i < spa->spa_l2cache.sav_count; i++) {
9856+
l2arc_dev_t *dev =
9857+
l2arc_vdev_get(spa->spa_l2cache.sav_vdevs[i]);
9858+
if (dev == NULL)
9859+
continue;
9860+
mutex_enter(&l2arc_rebuild_thr_lock);
9861+
dev->l2ad_rebuild_cancel = B_TRUE;
9862+
mutex_exit(&l2arc_rebuild_thr_lock);
9863+
}
9864+
for (int i = 0; i < spa->spa_l2cache.sav_count; i++) {
9865+
l2arc_dev_t *dev =
9866+
l2arc_vdev_get(spa->spa_l2cache.sav_vdevs[i]);
9867+
if (dev == NULL)
9868+
continue;
9869+
mutex_enter(&l2arc_rebuild_thr_lock);
9870+
if (dev->l2ad_rebuild_began == B_TRUE) {
9871+
while (dev->l2ad_rebuild == B_TRUE) {
9872+
cv_wait(&l2arc_rebuild_thr_cv,
9873+
&l2arc_rebuild_thr_lock);
9874+
}
9875+
}
9876+
mutex_exit(&l2arc_rebuild_thr_lock);
9877+
}
9878+
}
9879+
98499880
/*
98509881
* Main entry point for L2ARC rebuilding.
98519882
*/
@@ -9854,12 +9885,12 @@ l2arc_dev_rebuild_thread(void *arg)
98549885
{
98559886
l2arc_dev_t *dev = arg;
98569887

9857-
VERIFY(!dev->l2ad_rebuild_cancel);
98589888
VERIFY(dev->l2ad_rebuild);
98599889
(void) l2arc_rebuild(dev);
98609890
mutex_enter(&l2arc_rebuild_thr_lock);
98619891
dev->l2ad_rebuild_began = B_FALSE;
98629892
dev->l2ad_rebuild = B_FALSE;
9893+
cv_signal(&l2arc_rebuild_thr_cv);
98639894
mutex_exit(&l2arc_rebuild_thr_lock);
98649895

98659896
thread_exit();
@@ -10010,8 +10041,6 @@ l2arc_rebuild(l2arc_dev_t *dev)
1001010041
for (;;) {
1001110042
mutex_enter(&l2arc_rebuild_thr_lock);
1001210043
if (dev->l2ad_rebuild_cancel) {
10013-
dev->l2ad_rebuild = B_FALSE;
10014-
cv_signal(&l2arc_rebuild_thr_cv);
1001510044
mutex_exit(&l2arc_rebuild_thr_lock);
1001610045
err = SET_ERROR(ECANCELED);
1001710046
goto out;

module/zfs/spa.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2081,6 +2081,7 @@ spa_unload(spa_t *spa)
20812081
vdev_trim_stop_all(root_vdev, VDEV_TRIM_ACTIVE);
20822082
vdev_autotrim_stop_all(spa);
20832083
vdev_rebuild_stop_all(spa);
2084+
l2arc_spa_rebuild_stop(spa);
20842085
}
20852086
}
20862087

@@ -7115,6 +7116,7 @@ spa_export_common(const char *pool, int new_state, nvlist_t **oldconfig,
71157116
vdev_trim_stop_all(rvd, VDEV_TRIM_ACTIVE);
71167117
vdev_autotrim_stop_all(spa);
71177118
vdev_rebuild_stop_all(spa);
7119+
l2arc_spa_rebuild_stop(spa);
71187120

71197121
/*
71207122
* We want this to be reflected on every label,

0 commit comments

Comments
 (0)