Skip to content

Commit 468d22d

Browse files
robnbehlendorf
authored andcommitted
txg_wait_synced_flags: add TXG_WAIT_SUSPEND flag to not wait if pool suspended
This allows a caller to request a wait for txg sync, with an appropriate error return if the pool is suspended or becomes suspended during the wait. To support this, txg_wait_kick() is added to signal the sync condvar, which wakes up the waiters, causing them to loop and reconsider their wait conditions again. zio_suspend() now calls this to trigger the break if the pool suspends while waiting. Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc. Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Alexander Motin <[email protected]> Reviewed-by: Paul Dagnelie <[email protected]> Signed-off-by: Rob Norris <[email protected]> Closes #17355
1 parent 8487945 commit 468d22d

File tree

3 files changed

+31
-1
lines changed

3 files changed

+31
-1
lines changed

include/sys/txg.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
*/
2626
/*
2727
* Copyright (c) 2012, 2017 by Delphix. All rights reserved.
28+
* Copyright (c) 2025, Klara, Inc.
2829
*/
2930

3031
#ifndef _SYS_TXG_H
@@ -78,6 +79,9 @@ typedef enum {
7879

7980
/* If a signal arrives while waiting, abort and return EINTR */
8081
TXG_WAIT_SIGNAL = (1 << 0),
82+
83+
/* If the pool suspends while waiting, abort and return ESHUTDOWN. */
84+
TXG_WAIT_SUSPEND = (1 << 1),
8185
} txg_wait_flag_t;
8286

8387
struct dsl_pool;
@@ -111,6 +115,11 @@ extern int txg_wait_synced_flags(struct dsl_pool *dp, uint64_t txg,
111115
*/
112116
extern void txg_wait_synced(struct dsl_pool *dp, uint64_t txg);
113117

118+
/*
119+
* Wake all threads waiting in txg_wait_synced_flags() so they can reevaluate.
120+
*/
121+
extern void txg_wait_kick(struct dsl_pool *dp);
122+
114123
/*
115124
* Wait until the given transaction group, or one after it, is
116125
* the open transaction group. Try to make this happen as soon

module/zfs/txg.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
2424
* Portions Copyright 2011 Martin Matuska
2525
* Copyright (c) 2012, 2019 by Delphix. All rights reserved.
26+
* Copyright (c) 2025, Klara, Inc.
2627
*/
2728

2829
#include <sys/zfs_context.h>
@@ -705,7 +706,7 @@ txg_wait_synced_flags(dsl_pool_t *dp, uint64_t txg, txg_wait_flag_t flags)
705706
int error = 0;
706707
tx_state_t *tx = &dp->dp_tx;
707708

708-
ASSERT0(flags & ~TXG_WAIT_SIGNAL);
709+
ASSERT0(flags & ~(TXG_WAIT_SIGNAL | TXG_WAIT_SUSPEND));
709710
ASSERT(!dsl_pool_config_held(dp));
710711

711712
mutex_enter(&tx->tx_sync_lock);
@@ -723,6 +724,15 @@ txg_wait_synced_flags(dsl_pool_t *dp, uint64_t txg, txg_wait_flag_t flags)
723724
* else interesting happens, we'll set an error and break out.
724725
*/
725726
while (tx->tx_synced_txg < txg) {
727+
if ((flags & TXG_WAIT_SUSPEND) && spa_suspended(dp->dp_spa)) {
728+
/*
729+
* Pool suspended and the caller does not want to
730+
* block; inform them immediately.
731+
*/
732+
error = SET_ERROR(ESHUTDOWN);
733+
break;
734+
}
735+
726736
dprintf("broadcasting sync more "
727737
"tx_synced=%llu waiting=%llu dp=%px\n",
728738
(u_longlong_t)tx->tx_synced_txg,
@@ -756,6 +766,15 @@ txg_wait_synced(dsl_pool_t *dp, uint64_t txg)
756766
VERIFY0(txg_wait_synced_flags(dp, txg, TXG_WAIT_NONE));
757767
}
758768

769+
void
770+
txg_wait_kick(dsl_pool_t *dp)
771+
{
772+
tx_state_t *tx = &dp->dp_tx;
773+
mutex_enter(&tx->tx_sync_lock);
774+
cv_broadcast(&tx->tx_sync_done_cv);
775+
mutex_exit(&tx->tx_sync_lock);
776+
}
777+
759778
/*
760779
* Wait for the specified open transaction group. Set should_quiesce
761780
* when the current open txg should be quiesced immediately.

module/zfs/zio.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2714,6 +2714,8 @@ zio_suspend(spa_t *spa, zio_t *zio, zio_suspend_reason_t reason)
27142714
}
27152715

27162716
mutex_exit(&spa->spa_suspend_lock);
2717+
2718+
txg_wait_kick(spa->spa_dsl_pool);
27172719
}
27182720

27192721
int

0 commit comments

Comments
 (0)