Skip to content

Commit 52249fe

Browse files
wcaallanjude
authored andcommitted
zfs: support force exporting pools
This is primarily of use when a pool has lost its disk, while the user doesn't care about any pending (or otherwise) transactions. Implement various control methods to make this feasible: - txg_wait can now take a NOSUSPEND flag, in which case the caller will be alerted if their txg can't be committed. This is primarily of interest for callers that would normally pass TXG_WAIT, but don't want to wait if the pool becomes suspended, which allows unwinding in some cases, specifically when one is attempting a non-forced export. Without this, the non-forced export would preclude a forced export by virtue of holding the namespace lock indefinitely. - txg_wait also returns failure for TXG_WAIT users if a pool is actually being force exported. Adjust most callers to tolerate this. - spa_config_enter_flags now takes a NOSUSPEND flag to the same effect. - DMU objset initiator which may be set on an objset being forcibly exported / unmounted. - SPA export initiator may be set on a pool being forcibly exported. - DMU send/recv now use an interruption mechanism which relies on the SPA export initiator being able to enumerate datasets and closing any send/recv streams, causing their EINTR paths to be invoked. - ZIO now has a cancel entry point, which tells all suspended zios to fail, and which suppresses the failures for non-CANFAIL users. - metaslab, etc. cleanup, which consists of simply throwing away any changes that were not able to be synced out. - Linux specific: introduce a new tunable, zfs_forced_export_unmount_enabled, which allows the filesystem to remain in a modified 'unmounted' state upon exiting zpl_umount_begin, to achieve parity with FreeBSD and illumos, which have VFS-level support for yanking filesystems out from under users. However, this only helps when the user is actively performing I/O, while not sitting on the filesystem. In particular, this allows test #3 below to pass on Linux. - Add basic logic to zpool to indicate a force-exporting pool, instead of crashing due to lack of config, etc. Add tests which cover the basic use cases: - Force export while a send is in progress - Force export while a recv is in progress - Force export while POSIX I/O is in progress This change modifies the libzfs ABI: - New ZPOOL_STATUS_FORCE_EXPORTING zpool_status_t enum value. - New field libzfs_force_export for libzfs_handle. Signed-off-by: Will Andrews <will@firepipe.net> Signed-off-by: Allan Jude <allan@klarasystems.com> Sponsored-by: Klara, Inc. Sponsored-by: Catalogics, Inc. Closes openzfs#3461 Signed-off-by: Allan Jude <allan@klarasystems.com>
1 parent ab15b1f commit 52249fe

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+1995
-392
lines changed

cmd/zpool/zpool_main.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ get_usage(zpool_help_t idx)
362362
case HELP_DETACH:
363363
return (gettext("\tdetach <pool> <device>\n"));
364364
case HELP_EXPORT:
365-
return (gettext("\texport [-af] <pool> ...\n"));
365+
return (gettext("\texport [-afF] <pool> ...\n"));
366366
case HELP_HISTORY:
367367
return (gettext("\thistory [-il] [<pool>] ...\n"));
368368
case HELP_IMPORT:
@@ -1864,7 +1864,7 @@ zpool_export_one(zpool_handle_t *zhp, void *data)
18641864
{
18651865
export_cbdata_t *cb = data;
18661866

1867-
if (zpool_disable_datasets(zhp, cb->force) != 0)
1867+
if (zpool_disable_datasets(zhp, cb->force || cb->hardforce) != 0)
18681868
return (1);
18691869

18701870
/* The history must be logged as part of the export */
@@ -1885,10 +1885,13 @@ zpool_export_one(zpool_handle_t *zhp, void *data)
18851885
*
18861886
* -a Export all pools
18871887
* -f Forcefully unmount datasets
1888+
* -F Forcefully export, dropping all outstanding dirty data
18881889
*
18891890
* Export the given pools. By default, the command will attempt to cleanly
18901891
* unmount any active datasets within the pool. If the '-f' flag is specified,
1891-
* then the datasets will be forcefully unmounted.
1892+
* then the datasets will be forcefully unmounted. If the '-F' flag is
1893+
* specified, the pool's dirty data, if any, will simply be dropped after a
1894+
* best-effort attempt to forcibly stop all activity.
18921895
*/
18931896
int
18941897
zpool_do_export(int argc, char **argv)

include/libzfs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,7 @@ typedef enum {
397397
ZPOOL_STATUS_NON_NATIVE_ASHIFT, /* (e.g. 512e dev with ashift of 9) */
398398
ZPOOL_STATUS_COMPATIBILITY_ERR, /* bad 'compatibility' property */
399399
ZPOOL_STATUS_INCOMPATIBLE_FEAT, /* feature set outside compatibility */
400+
ZPOOL_STATUS_FORCE_EXPORTING, /* pool is being force exported */
400401

401402
/*
402403
* Finally, the following indicates a healthy pool.

include/os/freebsd/spl/sys/thread.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,7 @@
3131

3232
#define getcomm() curthread->td_name
3333
#define getpid() curthread->td_tid
34+
#define thread_signal spl_kthread_signal
35+
extern int spl_kthread_signal(kthread_t *tsk, int sig);
36+
3437
#endif

include/os/linux/spl/sys/thread.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ typedef void (*thread_func_t)(void *);
5555
#func, arg, len, pp, state, pri)
5656
/* END CSTYLED */
5757

58+
#define thread_signal(t, s) spl_kthread_signal(t, s)
5859
#define thread_exit() __thread_exit()
5960
#define thread_join(t) VERIFY(0)
6061
#define curthread current
@@ -67,6 +68,7 @@ extern kthread_t *__thread_create(caddr_t stk, size_t stksize,
6768
extern void __thread_exit(void);
6869
extern struct task_struct *spl_kthread_create(int (*func)(void *),
6970
void *data, const char namefmt[], ...);
71+
extern int spl_kthread_signal(kthread_t *tsk, int sig);
7072

7173
extern proc_t p0;
7274

include/os/linux/zfs/sys/zfs_vfsops_os.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ struct zfsvfs {
101101
boolean_t z_utf8; /* utf8-only */
102102
int z_norm; /* normalization flags */
103103
boolean_t z_relatime; /* enable relatime mount option */
104-
boolean_t z_unmounted; /* unmounted */
104+
boolean_t z_unmounted; /* mount status */
105+
boolean_t z_force_unmounted; /* force-unmounted status */
105106
rrmlock_t z_teardown_lock;
106107
krwlock_t z_teardown_inactive_lock;
107108
list_t z_all_znodes; /* all znodes in the fs */

include/os/linux/zfs/sys/zfs_znode_impl.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,18 +82,33 @@ extern "C" {
8282
#define zhold(zp) VERIFY3P(igrab(ZTOI((zp))), !=, NULL)
8383
#define zrele(zp) iput(ZTOI((zp)))
8484

85+
#define zfsvfs_is_unmounted(zfsvfs) \
86+
((zfsvfs)->z_unmounted && (zfsvfs)->z_force_unmounted)
87+
8588
/* Called on entry to each ZFS inode and vfs operation. */
8689
#define ZFS_ENTER_ERROR(zfsvfs, error) \
8790
do { \
8891
ZFS_TEARDOWN_ENTER_READ(zfsvfs, FTAG); \
89-
if (unlikely((zfsvfs)->z_unmounted)) { \
92+
if (unlikely(zfsvfs_is_unmounted(zfsvfs))) { \
9093
ZFS_TEARDOWN_EXIT_READ(zfsvfs, FTAG); \
9194
return (error); \
9295
} \
9396
} while (0)
9497
#define ZFS_ENTER(zfsvfs) ZFS_ENTER_ERROR(zfsvfs, EIO)
9598
#define ZPL_ENTER(zfsvfs) ZFS_ENTER_ERROR(zfsvfs, -EIO)
9699

100+
/* ZFS_ENTER but ok with forced unmount having begun */
101+
#define _ZFS_ENTER_UNMOUNTOK(zfsvfs, error) \
102+
do { \
103+
rrm_enter_read(&(zfsvfs)->z_teardown_lock, FTAG); \
104+
if ((zfsvfs)->z_unmounted == B_TRUE) { \
105+
ZFS_EXIT(zfsvfs); \
106+
return (error); \
107+
} \
108+
} while (0)
109+
#define ZFS_ENTER_UNMOUNTOK(zfsvfs) _ZFS_ENTER_UNMOUNTOK(zfsvfs, EIO)
110+
#define ZPL_ENTER_UNMOUNTOK(zfsvfs) _ZFS_ENTER_UNMOUNTOK(zfsvfs, -EIO)
111+
97112
/* Must be called before exiting the operation. */
98113
#define ZFS_EXIT(zfsvfs) \
99114
do { \

include/sys/arc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ void l2arc_fini(void);
336336
void l2arc_start(void);
337337
void l2arc_stop(void);
338338
void l2arc_spa_rebuild_start(spa_t *spa);
339+
void l2arc_spa_rebuild_stop(spa_t *spa);
339340

340341
#ifndef _KERNEL
341342
extern boolean_t arc_watch;

include/sys/dmu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ typedef enum dmu_object_type {
276276
#define TXG_NOWAIT (0ULL)
277277
#define TXG_WAIT (1ULL<<0)
278278
#define TXG_NOTHROTTLE (1ULL<<1)
279+
#define TXG_NOSUSPEND (1ULL<<2)
279280

280281
void byteswap_uint64_array(void *buf, size_t size);
281282
void byteswap_uint32_array(void *buf, size_t size);

include/sys/dmu_impl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ typedef struct dmu_sendstatus {
241241
list_node_t dss_link;
242242
int dss_outfd;
243243
proc_t *dss_proc;
244+
kthread_t *dss_thread;
244245
offset_t *dss_off;
245246
uint64_t dss_blocks; /* blocks visited during the sending process */
246247
} dmu_sendstatus_t;

include/sys/dmu_objset.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ struct objset {
172172

173173
/* Protected by os_lock */
174174
kmutex_t os_lock;
175+
kthread_t *os_shutdown_initiator;
175176
multilist_t os_dirty_dnodes[TXG_SIZE];
176177
list_t os_dnodes;
177178
list_t os_downgraded_dbufs;
@@ -263,6 +264,10 @@ int dmu_fsname(const char *snapname, char *buf);
263264
void dmu_objset_evict_done(objset_t *os);
264265
void dmu_objset_willuse_space(objset_t *os, int64_t space, dmu_tx_t *tx);
265266

267+
int dmu_objset_shutdown_register(objset_t *os);
268+
boolean_t dmu_objset_exiting(objset_t *os);
269+
void dmu_objset_shutdown_unregister(objset_t *os);
270+
266271
void dmu_objset_init(void);
267272
void dmu_objset_fini(void);
268273

include/sys/dmu_recv.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ extern const char *recv_clone_name;
3939

4040
typedef struct dmu_recv_cookie {
4141
struct dsl_dataset *drc_ds;
42+
kthread_t *drc_initiator;
4243
struct dmu_replay_record *drc_drr_begin;
4344
struct drr_begin *drc_drrb;
4445
const char *drc_tofs;
@@ -55,6 +56,8 @@ typedef struct dmu_recv_cookie {
5556
nvlist_t *drc_keynvl;
5657
uint64_t drc_fromsnapobj;
5758
uint64_t drc_ivset_guid;
59+
unsigned int drc_flags;
60+
void *drc_rwa;
5861
void *drc_owner;
5962
cred_t *drc_cred;
6063
proc_t *drc_proc;
@@ -81,6 +84,7 @@ int dmu_recv_begin(char *, char *, dmu_replay_record_t *,
8184
boolean_t, boolean_t, nvlist_t *, nvlist_t *, char *,
8285
dmu_recv_cookie_t *, zfs_file_t *, offset_t *);
8386
int dmu_recv_stream(dmu_recv_cookie_t *, offset_t *);
87+
int dmu_recv_close(dsl_dataset_t *ds);
8488
int dmu_recv_end(dmu_recv_cookie_t *, void *);
8589
boolean_t dmu_objset_is_receiving(objset_t *);
8690

include/sys/dmu_send.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ int dmu_send_obj(const char *pool, uint64_t tosnap, uint64_t fromsnap,
6060
boolean_t embedok, boolean_t large_block_ok, boolean_t compressok,
6161
boolean_t rawok, boolean_t savedok, int outfd, offset_t *off,
6262
struct dmu_send_outparams *dso);
63+
int dmu_send_close(struct dsl_dataset *ds);
6364

6465
typedef int (*dmu_send_outfunc_t)(objset_t *os, void *buf, int len, void *arg);
6566
typedef struct dmu_send_outparams {

include/sys/dsl_dataset.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,8 @@ typedef struct dsl_dataset {
243243
kmutex_t ds_sendstream_lock;
244244
list_t ds_sendstreams;
245245

246+
void *ds_receiver; /* really a dmu_recv_cookie_t */
247+
246248
/*
247249
* When in the middle of a resumable receive, tracks how much
248250
* progress we have made.
@@ -317,7 +319,8 @@ typedef struct dsl_dataset_snapshot_arg {
317319
/* flags for holding the dataset */
318320
typedef enum ds_hold_flags {
319321
DS_HOLD_FLAG_NONE = 0 << 0,
320-
DS_HOLD_FLAG_DECRYPT = 1 << 0 /* needs access to encrypted data */
322+
DS_HOLD_FLAG_DECRYPT = 1 << 0, /* needs access to encrypted data */
323+
DS_HOLD_FLAG_MUST_BE_OPEN = 1 << 1, /* dataset must already be open */
321324
} ds_hold_flags_t;
322325

323326
int dsl_dataset_hold(struct dsl_pool *dp, const char *name, void *tag,
@@ -445,6 +448,8 @@ void dsl_dataset_long_hold(dsl_dataset_t *ds, void *tag);
445448
void dsl_dataset_long_rele(dsl_dataset_t *ds, void *tag);
446449
boolean_t dsl_dataset_long_held(dsl_dataset_t *ds);
447450

451+
int dsl_dataset_sendrecv_cancel_all(spa_t *spa);
452+
448453
int dsl_dataset_clone_swap_check_impl(dsl_dataset_t *clone,
449454
dsl_dataset_t *origin_head, boolean_t force, void *owner, dmu_tx_t *tx);
450455
void dsl_dataset_clone_swap_sync_impl(dsl_dataset_t *clone,

include/sys/dsl_scan.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ int dsl_scan(struct dsl_pool *, pool_scan_func_t);
172172
void dsl_scan_assess_vdev(struct dsl_pool *dp, vdev_t *vd);
173173
boolean_t dsl_scan_scrubbing(const struct dsl_pool *dp);
174174
int dsl_scrub_set_pause_resume(const struct dsl_pool *dp, pool_scrub_cmd_t cmd);
175-
void dsl_scan_restart_resilver(struct dsl_pool *, uint64_t txg);
175+
int dsl_scan_restart_resilver(struct dsl_pool *, uint64_t txg);
176176
boolean_t dsl_scan_resilvering(struct dsl_pool *dp);
177177
boolean_t dsl_scan_resilver_scheduled(struct dsl_pool *dp);
178178
boolean_t dsl_dataset_unstable(struct dsl_dataset *ds);

include/sys/metaslab.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ boolean_t metaslab_class_throttle_reserve(metaslab_class_t *, int, int,
111111
zio_t *, int);
112112
void metaslab_class_throttle_unreserve(metaslab_class_t *, int, int, zio_t *);
113113
void metaslab_class_evict_old(metaslab_class_t *, uint64_t);
114+
void metaslab_class_force_discard(metaslab_class_t *);
114115
uint64_t metaslab_class_get_alloc(metaslab_class_t *);
115116
uint64_t metaslab_class_get_space(metaslab_class_t *);
116117
uint64_t metaslab_class_get_dspace(metaslab_class_t *);

include/sys/spa.h

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -834,16 +834,13 @@ extern kmutex_t spa_namespace_lock;
834834
* SPA configuration functions in spa_config.c
835835
*/
836836

837-
#define SPA_CONFIG_UPDATE_POOL 0
838-
#define SPA_CONFIG_UPDATE_VDEVS 1
839-
840837
extern void spa_write_cachefile(spa_t *, boolean_t, boolean_t);
841838
extern void spa_config_load(void);
842839
extern nvlist_t *spa_all_configs(uint64_t *);
843840
extern void spa_config_set(spa_t *spa, nvlist_t *config);
844841
extern nvlist_t *spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg,
845842
int getstats);
846-
extern void spa_config_update(spa_t *spa, int what);
843+
extern int spa_config_update_pool(spa_t *spa);
847844
extern int spa_config_parse(spa_t *spa, vdev_t **vdp, nvlist_t *nv,
848845
vdev_t *parent, uint_t id, int atype);
849846

@@ -959,6 +956,13 @@ extern void spa_iostats_trim_add(spa_t *spa, trim_type_t type,
959956
uint64_t extents_written, uint64_t bytes_written,
960957
uint64_t extents_skipped, uint64_t bytes_skipped,
961958
uint64_t extents_failed, uint64_t bytes_failed);
959+
960+
/* Config lock handling flags */
961+
typedef enum {
962+
SCL_FLAG_TRYENTER = 1U << 0,
963+
SCL_FLAG_NOSUSPEND = 1U << 1,
964+
} spa_config_flag_t;
965+
962966
extern void spa_import_progress_add(spa_t *spa);
963967
extern void spa_import_progress_remove(uint64_t spa_guid);
964968
extern int spa_import_progress_set_mmp_check(uint64_t pool_guid,
@@ -970,6 +974,8 @@ extern int spa_import_progress_set_state(uint64_t pool_guid,
970974

971975
/* Pool configuration locks */
972976
extern int spa_config_tryenter(spa_t *spa, int locks, void *tag, krw_t rw);
977+
extern int spa_config_enter_flags(spa_t *spa, int locks, const void *tag,
978+
krw_t rw, spa_config_flag_t flags);
973979
extern void spa_config_enter(spa_t *spa, int locks, const void *tag, krw_t rw);
974980
extern void spa_config_exit(spa_t *spa, int locks, const void *tag);
975981
extern int spa_config_held(spa_t *spa, int locks, krw_t rw);
@@ -1018,6 +1024,7 @@ extern uint64_t spa_last_synced_txg(spa_t *spa);
10181024
extern uint64_t spa_first_txg(spa_t *spa);
10191025
extern uint64_t spa_syncing_txg(spa_t *spa);
10201026
extern uint64_t spa_final_dirty_txg(spa_t *spa);
1027+
extern void spa_verify_dirty_txg(spa_t *spa, uint64_t txg);
10211028
extern uint64_t spa_version(spa_t *spa);
10221029
extern pool_state_t spa_state(spa_t *spa);
10231030
extern spa_load_state_t spa_load_state(spa_t *spa);
@@ -1037,6 +1044,8 @@ extern metaslab_class_t *spa_dedup_class(spa_t *spa);
10371044
extern metaslab_class_t *spa_preferred_class(spa_t *spa, uint64_t size,
10381045
dmu_object_type_t objtype, uint_t level, uint_t special_smallblk);
10391046

1047+
extern void spa_evicting_os_lock(spa_t *);
1048+
extern void spa_evicting_os_unlock(spa_t *);
10401049
extern void spa_evicting_os_register(spa_t *, objset_t *os);
10411050
extern void spa_evicting_os_deregister(spa_t *, objset_t *os);
10421051
extern void spa_evicting_os_wait(spa_t *spa);
@@ -1127,6 +1136,10 @@ extern void spa_history_log_internal_dd(dsl_dir_t *dd, const char *operation,
11271136

11281137
extern const char *spa_state_to_name(spa_t *spa);
11291138

1139+
extern boolean_t spa_exiting_any(spa_t *spa);
1140+
extern boolean_t spa_exiting(spa_t *spa);
1141+
extern int spa_operation_interrupted(spa_t *spa);
1142+
11301143
/* error handling */
11311144
struct zbookmark_phys;
11321145
extern void spa_log_error(spa_t *spa, const zbookmark_phys_t *zb);

include/sys/spa_impl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ struct spa {
244244
kmutex_t spa_evicting_os_lock; /* Evicting objset list lock */
245245
list_t spa_evicting_os_list; /* Objsets being evicted. */
246246
kcondvar_t spa_evicting_os_cv; /* Objset Eviction Completion */
247+
kthread_t *spa_export_initiator; /* thread exporting the pool */
247248
txg_list_t spa_vdev_txg_list; /* per-txg dirty vdev list */
248249
vdev_t *spa_root_vdev; /* top-level vdev container */
249250
uint64_t spa_min_ashift; /* of vdevs in normal class */

include/sys/txg.h

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,27 @@ typedef struct txg_list {
6666
} txg_list_t;
6767

6868
struct dsl_pool;
69+
struct dmu_tx;
70+
71+
/*
72+
* TXG wait flags, used by txg_wait_synced_tx and callers to indicate
73+
* modifications to how they wish to wait for a txg.
74+
*/
75+
typedef enum {
76+
/* No special wait flags. */
77+
TXG_WAIT_F_NONE = 0,
78+
/* Reject the call with EINTR upon receiving a signal. */
79+
TXG_WAIT_F_SIGNAL = (1U << 0),
80+
/* Reject the call with EAGAIN upon suspension. */
81+
TXG_WAIT_F_NOSUSPEND = (1U << 1),
82+
/* Ignore errors and export anyway. */
83+
TXG_WAIT_F_FORCE_EXPORT = (1U << 2),
84+
} txg_wait_flag_t;
6985

7086
extern void txg_init(struct dsl_pool *dp, uint64_t txg);
7187
extern void txg_fini(struct dsl_pool *dp);
7288
extern void txg_sync_start(struct dsl_pool *dp);
73-
extern void txg_sync_stop(struct dsl_pool *dp);
89+
extern int txg_sync_stop(struct dsl_pool *dp, txg_wait_flag_t txg_how);
7490
extern uint64_t txg_hold_open(struct dsl_pool *dp, txg_handle_t *txghp);
7591
extern void txg_rele_to_quiesce(txg_handle_t *txghp);
7692
extern void txg_rele_to_sync(txg_handle_t *txghp);
@@ -84,14 +100,23 @@ extern void txg_kick(struct dsl_pool *dp, uint64_t txg);
84100
* Wait until the given transaction group has finished syncing.
85101
* Try to make this happen as soon as possible (eg. kick off any
86102
* necessary syncs immediately). If txg==0, wait for the currently open
87-
* txg to finish syncing.
103+
* txg to finish syncing. This may be interrupted due to an exiting pool.
104+
*
105+
* If desired, flags can be specified using txg_wait_synced_tx(), in case
106+
* the caller wants to be interruptible.
88107
*/
89108
extern void txg_wait_synced(struct dsl_pool *dp, uint64_t txg);
109+
extern int txg_wait_synced_tx(struct dsl_pool *dp, uint64_t txg,
110+
struct dmu_tx *tx, txg_wait_flag_t flags);
111+
extern int txg_wait_synced_flags(struct dsl_pool *dp, uint64_t txg,
112+
txg_wait_flag_t flags);
90113

91114
/*
92-
* Wait as above. Returns true if the thread was signaled while waiting.
115+
* Similar to a txg_wait_synced but it can be interrupted from a signal.
116+
* Returns B_TRUE if the thread was signaled while waiting.
93117
*/
94-
extern boolean_t txg_wait_synced_sig(struct dsl_pool *dp, uint64_t txg);
118+
#define txg_wait_synced_sig(dp, txg) \
119+
(txg_wait_synced_tx(dp, txg, NULL, TXG_WAIT_F_SIGNAL) == EINTR)
95120

96121
/*
97122
* Wait until the given transaction group, or one after it, is
@@ -102,6 +127,8 @@ extern boolean_t txg_wait_synced_sig(struct dsl_pool *dp, uint64_t txg);
102127
extern void txg_wait_open(struct dsl_pool *dp, uint64_t txg,
103128
boolean_t should_quiesce);
104129

130+
void txg_force_export(spa_t *spa);
131+
105132
/*
106133
* Returns TRUE if we are "backed up" waiting for the syncing
107134
* transaction to complete; otherwise returns FALSE.
@@ -113,6 +140,8 @@ extern boolean_t txg_sync_waiting(struct dsl_pool *dp);
113140

114141
extern void txg_verify(spa_t *spa, uint64_t txg);
115142

143+
extern void txg_completion_notify(struct dsl_pool *dp);
144+
116145
/*
117146
* Wait for pending commit callbacks of already-synced transactions to finish
118147
* processing.

include/sys/zfs_context.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ typedef pthread_t kthread_t;
228228
zk_thread_create(func, arg, stksize, state)
229229
#define thread_create(stk, stksize, func, arg, len, pp, state, pri) \
230230
zk_thread_create(func, arg, stksize, state)
231+
#define thread_signal(t, s) pthread_kill((pthread_t)t, s)
231232
#define thread_exit() pthread_exit(NULL)
232233
#define thread_join(t) pthread_join((pthread_t)(t), NULL)
233234

include/sys/zfs_refcount.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ typedef struct refcount {
6060

6161
/*
6262
* Note: zfs_refcount_t must be initialized with
63-
* refcount_create[_untracked]()
63+
* zfs_refcount_create[_untracked]()
6464
*/
6565

6666
void zfs_refcount_create(zfs_refcount_t *);

0 commit comments

Comments
 (0)