aboutsummaryrefslogtreecommitdiffstats
path: root/uts/common/fs/zfs/dsl_synctask.c
diff options
context:
space:
mode:
Diffstat (limited to 'uts/common/fs/zfs/dsl_synctask.c')
-rw-r--r--uts/common/fs/zfs/dsl_synctask.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/uts/common/fs/zfs/dsl_synctask.c b/uts/common/fs/zfs/dsl_synctask.c
index 7014581d0e47..a78b4cb030cf 100644
--- a/uts/common/fs/zfs/dsl_synctask.c
+++ b/uts/common/fs/zfs/dsl_synctask.c
@@ -41,7 +41,7 @@ dsl_null_checkfunc(void *arg, dmu_tx_t *tx)
static int
dsl_sync_task_common(const char *pool, dsl_checkfunc_t *checkfunc,
- dsl_syncfunc_t *syncfunc, void *arg,
+ dsl_syncfunc_t *syncfunc, dsl_sigfunc_t *sigfunc, void *arg,
int blocks_modified, zfs_space_check_t space_check, boolean_t early)
{
spa_t *spa;
@@ -85,6 +85,11 @@ top:
dmu_tx_commit(tx);
+ if (sigfunc != NULL && txg_wait_synced_sig(dp, dst.dst_txg)) {
+ /* current contract is to call func once */
+ sigfunc(arg, tx);
+ sigfunc = NULL; /* in case of an EAGAIN retry */
+ }
txg_wait_synced(dp, dst.dst_txg);
if (dst.dst_error == EAGAIN) {
@@ -124,7 +129,7 @@ dsl_sync_task(const char *pool, dsl_checkfunc_t *checkfunc,
dsl_syncfunc_t *syncfunc, void *arg,
int blocks_modified, zfs_space_check_t space_check)
{
- return (dsl_sync_task_common(pool, checkfunc, syncfunc, arg,
+ return (dsl_sync_task_common(pool, checkfunc, syncfunc, NULL, arg,
blocks_modified, space_check, B_FALSE));
}
@@ -146,10 +151,23 @@ dsl_early_sync_task(const char *pool, dsl_checkfunc_t *checkfunc,
dsl_syncfunc_t *syncfunc, void *arg,
int blocks_modified, zfs_space_check_t space_check)
{
- return (dsl_sync_task_common(pool, checkfunc, syncfunc, arg,
+ return (dsl_sync_task_common(pool, checkfunc, syncfunc, NULL, arg,
blocks_modified, space_check, B_TRUE));
}
+/*
+ * A standard synctask that can be interrupted from a signal. The sigfunc
+ * is called once if a signal occurred while waiting for the task to sync.
+ */
+int
+dsl_sync_task_sig(const char *pool, dsl_checkfunc_t *checkfunc,
+ dsl_syncfunc_t *syncfunc, dsl_sigfunc_t *sigfunc, void *arg,
+ int blocks_modified, zfs_space_check_t space_check)
+{
+ return (dsl_sync_task_common(pool, checkfunc, syncfunc, sigfunc, arg,
+ blocks_modified, space_check, B_FALSE));
+}
+
static void
dsl_sync_task_nowait_common(dsl_pool_t *dp, dsl_syncfunc_t *syncfunc, void *arg,
int blocks_modified, zfs_space_check_t space_check, dmu_tx_t *tx,