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> Signed-off-by: Mariusz Zaborski <mariusz.zaborski@klarasystems.com> Signed-off-by: Rob Norris <rob.norris@klarasystems.com> Sponsored-by: Klara, Inc. Sponsored-by: Catalogics, Inc. Sponsored-by: Wasabi Technology, Inc. Closes #3461 (cherry picked from commit 852e633772217d779a63e8c46fe3c5f81dd8960e)
This commit is contained in:
parent
f65b59c5e5
commit
40a9efd0e8
|
@ -357,7 +357,7 @@ get_usage(zpool_help_t idx)
|
||||||
case HELP_DETACH:
|
case HELP_DETACH:
|
||||||
return (gettext("\tdetach <pool> <device>\n"));
|
return (gettext("\tdetach <pool> <device>\n"));
|
||||||
case HELP_EXPORT:
|
case HELP_EXPORT:
|
||||||
return (gettext("\texport [-af] <pool> ...\n"));
|
return (gettext("\texport [-afF] <pool> ...\n"));
|
||||||
case HELP_HISTORY:
|
case HELP_HISTORY:
|
||||||
return (gettext("\thistory [-il] [<pool>] ...\n"));
|
return (gettext("\thistory [-il] [<pool>] ...\n"));
|
||||||
case HELP_IMPORT:
|
case HELP_IMPORT:
|
||||||
|
@ -1830,7 +1830,7 @@ zpool_do_destroy(int argc, char **argv)
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zpool_disable_datasets(zhp, force) != 0) {
|
if (zpool_disable_datasets(zhp, force, B_FALSE) != 0) {
|
||||||
(void) fprintf(stderr, gettext("could not destroy '%s': "
|
(void) fprintf(stderr, gettext("could not destroy '%s': "
|
||||||
"could not unmount datasets\n"), zpool_get_name(zhp));
|
"could not unmount datasets\n"), zpool_get_name(zhp));
|
||||||
zpool_close(zhp);
|
zpool_close(zhp);
|
||||||
|
@ -1860,7 +1860,7 @@ zpool_export_one(zpool_handle_t *zhp, void *data)
|
||||||
{
|
{
|
||||||
export_cbdata_t *cb = data;
|
export_cbdata_t *cb = data;
|
||||||
|
|
||||||
if (zpool_disable_datasets(zhp, cb->force) != 0)
|
if (zpool_disable_datasets(zhp, cb->force, cb->hardforce) != 0)
|
||||||
return (1);
|
return (1);
|
||||||
|
|
||||||
/* The history must be logged as part of the export */
|
/* The history must be logged as part of the export */
|
||||||
|
@ -1881,10 +1881,13 @@ zpool_export_one(zpool_handle_t *zhp, void *data)
|
||||||
*
|
*
|
||||||
* -a Export all pools
|
* -a Export all pools
|
||||||
* -f Forcefully unmount datasets
|
* -f Forcefully unmount datasets
|
||||||
|
* -F Forcefully export, dropping all outstanding dirty data
|
||||||
*
|
*
|
||||||
* Export the given pools. By default, the command will attempt to cleanly
|
* Export the given pools. By default, the command will attempt to cleanly
|
||||||
* unmount any active datasets within the pool. If the '-f' flag is specified,
|
* unmount any active datasets within the pool. If the '-f' flag is specified,
|
||||||
* then the datasets will be forcefully unmounted.
|
* then the datasets will be forcefully unmounted. If the '-F' flag is
|
||||||
|
* specified, the pool's dirty data, if any, will simply be dropped after a
|
||||||
|
* best-effort attempt to forcibly stop all activity.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
zpool_do_export(int argc, char **argv)
|
zpool_do_export(int argc, char **argv)
|
||||||
|
|
|
@ -394,6 +394,7 @@ typedef enum {
|
||||||
ZPOOL_STATUS_NON_NATIVE_ASHIFT, /* (e.g. 512e dev with ashift of 9) */
|
ZPOOL_STATUS_NON_NATIVE_ASHIFT, /* (e.g. 512e dev with ashift of 9) */
|
||||||
ZPOOL_STATUS_COMPATIBILITY_ERR, /* bad 'compatibility' property */
|
ZPOOL_STATUS_COMPATIBILITY_ERR, /* bad 'compatibility' property */
|
||||||
ZPOOL_STATUS_INCOMPATIBLE_FEAT, /* feature set outside compatibility */
|
ZPOOL_STATUS_INCOMPATIBLE_FEAT, /* feature set outside compatibility */
|
||||||
|
ZPOOL_STATUS_FORCE_EXPORTING, /* pool is being force exported */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Finally, the following indicates a healthy pool.
|
* Finally, the following indicates a healthy pool.
|
||||||
|
@ -917,7 +918,13 @@ int zfs_smb_acl_rename(libzfs_handle_t *, char *, char *, char *, char *);
|
||||||
* sharing/unsharing them.
|
* sharing/unsharing them.
|
||||||
*/
|
*/
|
||||||
extern int zpool_enable_datasets(zpool_handle_t *, const char *, int);
|
extern int zpool_enable_datasets(zpool_handle_t *, const char *, int);
|
||||||
extern int zpool_disable_datasets(zpool_handle_t *, boolean_t);
|
extern int zpool_disable_datasets(zpool_handle_t *, boolean_t, boolean_t);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Procedure to inform os that we have started force unmount (linux specific).
|
||||||
|
*/
|
||||||
|
extern void zpool_unmount_mark_hard_force_begin(zpool_handle_t *zhp);
|
||||||
|
extern void zpool_unmount_mark_hard_force_end(zpool_handle_t *zhp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse a features file for -o compatibility
|
* Parse a features file for -o compatibility
|
||||||
|
|
|
@ -74,6 +74,7 @@ struct libzfs_handle {
|
||||||
uint64_t libzfs_max_nvlist;
|
uint64_t libzfs_max_nvlist;
|
||||||
void *libfetch;
|
void *libfetch;
|
||||||
char *libfetch_load_error;
|
char *libfetch_load_error;
|
||||||
|
boolean_t libzfs_force_export;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct zfs_handle {
|
struct zfs_handle {
|
||||||
|
|
|
@ -31,4 +31,7 @@
|
||||||
|
|
||||||
#define getcomm() curthread->td_name
|
#define getcomm() curthread->td_name
|
||||||
#define getpid() curthread->td_tid
|
#define getpid() curthread->td_tid
|
||||||
|
#define thread_signal spl_kthread_signal
|
||||||
|
extern int spl_kthread_signal(kthread_t *tsk, int sig);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -134,6 +134,8 @@ extern minor_t zfsdev_minor_alloc(void);
|
||||||
/* Called on entry to each ZFS vnode and vfs operation */
|
/* Called on entry to each ZFS vnode and vfs operation */
|
||||||
#define ZFS_ENTER(zfsvfs) ZFS_ENTER_ERROR(zfsvfs, EIO)
|
#define ZFS_ENTER(zfsvfs) ZFS_ENTER_ERROR(zfsvfs, EIO)
|
||||||
|
|
||||||
|
#define zfs_enter_unmountok zfs_enter
|
||||||
|
|
||||||
/* Must be called before exiting the vop */
|
/* Must be called before exiting the vop */
|
||||||
#define ZFS_EXIT(zfsvfs) ZFS_TEARDOWN_EXIT_READ(zfsvfs, FTAG)
|
#define ZFS_EXIT(zfsvfs) ZFS_TEARDOWN_EXIT_READ(zfsvfs, FTAG)
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,7 @@ typedef void (*thread_func_t)(void *);
|
||||||
#func, arg, len, pp, state, pri)
|
#func, arg, len, pp, state, pri)
|
||||||
/* END CSTYLED */
|
/* END CSTYLED */
|
||||||
|
|
||||||
|
#define thread_signal(t, s) spl_kthread_signal(t, s)
|
||||||
#define thread_exit() __thread_exit()
|
#define thread_exit() __thread_exit()
|
||||||
#define thread_join(t) VERIFY(0)
|
#define thread_join(t) VERIFY(0)
|
||||||
#define curthread current
|
#define curthread current
|
||||||
|
@ -67,6 +68,7 @@ extern kthread_t *__thread_create(caddr_t stk, size_t stksize,
|
||||||
extern void __thread_exit(void);
|
extern void __thread_exit(void);
|
||||||
extern struct task_struct *spl_kthread_create(int (*func)(void *),
|
extern struct task_struct *spl_kthread_create(int (*func)(void *),
|
||||||
void *data, const char namefmt[], ...);
|
void *data, const char namefmt[], ...);
|
||||||
|
extern int spl_kthread_signal(kthread_t *tsk, int sig);
|
||||||
|
|
||||||
extern proc_t p0;
|
extern proc_t p0;
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,8 @@ struct zfsvfs {
|
||||||
boolean_t z_utf8; /* utf8-only */
|
boolean_t z_utf8; /* utf8-only */
|
||||||
int z_norm; /* normalization flags */
|
int z_norm; /* normalization flags */
|
||||||
boolean_t z_relatime; /* enable relatime mount option */
|
boolean_t z_relatime; /* enable relatime mount option */
|
||||||
boolean_t z_unmounted; /* unmounted */
|
boolean_t z_unmounted; /* mount status */
|
||||||
|
boolean_t z_force_unmounted; /* force-unmounted status */
|
||||||
rrmlock_t z_teardown_lock;
|
rrmlock_t z_teardown_lock;
|
||||||
krwlock_t z_teardown_inactive_lock;
|
krwlock_t z_teardown_inactive_lock;
|
||||||
list_t z_all_znodes; /* all znodes in the fs */
|
list_t z_all_znodes; /* all znodes in the fs */
|
||||||
|
|
|
@ -83,11 +83,14 @@ extern "C" {
|
||||||
#define zhold(zp) VERIFY3P(igrab(ZTOI((zp))), !=, NULL)
|
#define zhold(zp) VERIFY3P(igrab(ZTOI((zp))), !=, NULL)
|
||||||
#define zrele(zp) iput(ZTOI((zp)))
|
#define zrele(zp) iput(ZTOI((zp)))
|
||||||
|
|
||||||
|
#define zfsvfs_is_unmounted(zfsvfs) \
|
||||||
|
((zfsvfs)->z_unmounted || (zfsvfs)->z_force_unmounted)
|
||||||
|
|
||||||
/* Called on entry to each ZFS inode and vfs operation. */
|
/* Called on entry to each ZFS inode and vfs operation. */
|
||||||
#define ZFS_ENTER_ERROR(zfsvfs, error) \
|
#define ZFS_ENTER_ERROR(zfsvfs, error) \
|
||||||
do { \
|
do { \
|
||||||
ZFS_TEARDOWN_ENTER_READ(zfsvfs, FTAG); \
|
ZFS_TEARDOWN_ENTER_READ(zfsvfs, FTAG); \
|
||||||
if (unlikely((zfsvfs)->z_unmounted)) { \
|
if (zfsvfs_is_unmounted(zfsvfs)) { \
|
||||||
ZFS_TEARDOWN_EXIT_READ(zfsvfs, FTAG); \
|
ZFS_TEARDOWN_EXIT_READ(zfsvfs, FTAG); \
|
||||||
return (error); \
|
return (error); \
|
||||||
} \
|
} \
|
||||||
|
@ -101,12 +104,25 @@ do { \
|
||||||
zfs_exit_fs(zfsvfs); \
|
zfs_exit_fs(zfsvfs); \
|
||||||
ZFS_TEARDOWN_EXIT_READ(zfsvfs, FTAG); \
|
ZFS_TEARDOWN_EXIT_READ(zfsvfs, FTAG); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define ZPL_EXIT(zfsvfs) \
|
#define ZPL_EXIT(zfsvfs) \
|
||||||
do { \
|
do { \
|
||||||
rrm_exit(&(zfsvfs)->z_teardown_lock, FTAG); \
|
rrm_exit(&(zfsvfs)->z_teardown_lock, FTAG); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
/* ZFS_ENTER but ok with forced unmount having begun */
|
||||||
|
/* ZFS_ENTER but ok with forced unmount having begun */
|
||||||
|
#define _ZFS_ENTER_UNMOUNTOK(zfsvfs, error) \
|
||||||
|
do { \
|
||||||
|
rrm_enter_read(&(zfsvfs)->z_teardown_lock, FTAG); \
|
||||||
|
if ((zfsvfs)->z_unmounted == B_TRUE) { \
|
||||||
|
ZFS_EXIT(zfsvfs); \
|
||||||
|
return (error); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#define ZFS_ENTER_UNMOUNTOK(zfsvfs) _ZFS_ENTER_UNMOUNTOK(zfsvfs, EIO)
|
||||||
|
#define ZPL_ENTER_UNMOUNTOK(zfsvfs) _ZFS_ENTER_UNMOUNTOK(zfsvfs, -EIO)
|
||||||
|
|
||||||
/* Verifies the znode is valid. */
|
/* Verifies the znode is valid. */
|
||||||
#define ZFS_VERIFY_ZP_ERROR(zp, error) \
|
#define ZFS_VERIFY_ZP_ERROR(zp, error) \
|
||||||
do { \
|
do { \
|
||||||
|
|
|
@ -336,6 +336,7 @@ void l2arc_fini(void);
|
||||||
void l2arc_start(void);
|
void l2arc_start(void);
|
||||||
void l2arc_stop(void);
|
void l2arc_stop(void);
|
||||||
void l2arc_spa_rebuild_start(spa_t *spa);
|
void l2arc_spa_rebuild_start(spa_t *spa);
|
||||||
|
void l2arc_spa_rebuild_stop(spa_t *spa);
|
||||||
|
|
||||||
#ifndef _KERNEL
|
#ifndef _KERNEL
|
||||||
extern boolean_t arc_watch;
|
extern boolean_t arc_watch;
|
||||||
|
|
|
@ -276,6 +276,7 @@ typedef enum dmu_object_type {
|
||||||
#define TXG_NOWAIT (0ULL)
|
#define TXG_NOWAIT (0ULL)
|
||||||
#define TXG_WAIT (1ULL<<0)
|
#define TXG_WAIT (1ULL<<0)
|
||||||
#define TXG_NOTHROTTLE (1ULL<<1)
|
#define TXG_NOTHROTTLE (1ULL<<1)
|
||||||
|
#define TXG_NOSUSPEND (1ULL<<2)
|
||||||
|
|
||||||
void byteswap_uint64_array(void *buf, size_t size);
|
void byteswap_uint64_array(void *buf, size_t size);
|
||||||
void byteswap_uint32_array(void *buf, size_t size);
|
void byteswap_uint32_array(void *buf, size_t size);
|
||||||
|
|
|
@ -241,6 +241,7 @@ typedef struct dmu_sendstatus {
|
||||||
list_node_t dss_link;
|
list_node_t dss_link;
|
||||||
int dss_outfd;
|
int dss_outfd;
|
||||||
proc_t *dss_proc;
|
proc_t *dss_proc;
|
||||||
|
kthread_t *dss_thread;
|
||||||
offset_t *dss_off;
|
offset_t *dss_off;
|
||||||
uint64_t dss_blocks; /* blocks visited during the sending process */
|
uint64_t dss_blocks; /* blocks visited during the sending process */
|
||||||
} dmu_sendstatus_t;
|
} dmu_sendstatus_t;
|
||||||
|
|
|
@ -172,6 +172,7 @@ struct objset {
|
||||||
|
|
||||||
/* Protected by os_lock */
|
/* Protected by os_lock */
|
||||||
kmutex_t os_lock;
|
kmutex_t os_lock;
|
||||||
|
kthread_t *os_shutdown_initiator;
|
||||||
multilist_t os_dirty_dnodes[TXG_SIZE];
|
multilist_t os_dirty_dnodes[TXG_SIZE];
|
||||||
list_t os_dnodes;
|
list_t os_dnodes;
|
||||||
list_t os_downgraded_dbufs;
|
list_t os_downgraded_dbufs;
|
||||||
|
@ -263,6 +264,10 @@ int dmu_fsname(const char *snapname, char *buf);
|
||||||
void dmu_objset_evict_done(objset_t *os);
|
void dmu_objset_evict_done(objset_t *os);
|
||||||
void dmu_objset_willuse_space(objset_t *os, int64_t space, dmu_tx_t *tx);
|
void dmu_objset_willuse_space(objset_t *os, int64_t space, dmu_tx_t *tx);
|
||||||
|
|
||||||
|
int dmu_objset_shutdown_register(objset_t *os);
|
||||||
|
boolean_t dmu_objset_exiting(objset_t *os);
|
||||||
|
void dmu_objset_shutdown_unregister(objset_t *os);
|
||||||
|
|
||||||
void dmu_objset_init(void);
|
void dmu_objset_init(void);
|
||||||
void dmu_objset_fini(void);
|
void dmu_objset_fini(void);
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ extern const char *recv_clone_name;
|
||||||
|
|
||||||
typedef struct dmu_recv_cookie {
|
typedef struct dmu_recv_cookie {
|
||||||
struct dsl_dataset *drc_ds;
|
struct dsl_dataset *drc_ds;
|
||||||
|
kthread_t *drc_initiator;
|
||||||
struct dmu_replay_record *drc_drr_begin;
|
struct dmu_replay_record *drc_drr_begin;
|
||||||
struct drr_begin *drc_drrb;
|
struct drr_begin *drc_drrb;
|
||||||
const char *drc_tofs;
|
const char *drc_tofs;
|
||||||
|
@ -55,6 +56,8 @@ typedef struct dmu_recv_cookie {
|
||||||
nvlist_t *drc_keynvl;
|
nvlist_t *drc_keynvl;
|
||||||
uint64_t drc_fromsnapobj;
|
uint64_t drc_fromsnapobj;
|
||||||
uint64_t drc_ivset_guid;
|
uint64_t drc_ivset_guid;
|
||||||
|
unsigned int drc_flags;
|
||||||
|
void *drc_rwa;
|
||||||
void *drc_owner;
|
void *drc_owner;
|
||||||
cred_t *drc_cred;
|
cred_t *drc_cred;
|
||||||
proc_t *drc_proc;
|
proc_t *drc_proc;
|
||||||
|
@ -81,6 +84,7 @@ int dmu_recv_begin(char *, char *, dmu_replay_record_t *,
|
||||||
boolean_t, boolean_t, nvlist_t *, nvlist_t *, char *,
|
boolean_t, boolean_t, nvlist_t *, nvlist_t *, char *,
|
||||||
dmu_recv_cookie_t *, zfs_file_t *, offset_t *);
|
dmu_recv_cookie_t *, zfs_file_t *, offset_t *);
|
||||||
int dmu_recv_stream(dmu_recv_cookie_t *, offset_t *);
|
int dmu_recv_stream(dmu_recv_cookie_t *, offset_t *);
|
||||||
|
int dmu_recv_close(dsl_dataset_t *ds);
|
||||||
int dmu_recv_end(dmu_recv_cookie_t *, void *);
|
int dmu_recv_end(dmu_recv_cookie_t *, void *);
|
||||||
boolean_t dmu_objset_is_receiving(objset_t *);
|
boolean_t dmu_objset_is_receiving(objset_t *);
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@ int dmu_send_obj(const char *pool, uint64_t tosnap, uint64_t fromsnap,
|
||||||
boolean_t embedok, boolean_t large_block_ok, boolean_t compressok,
|
boolean_t embedok, boolean_t large_block_ok, boolean_t compressok,
|
||||||
boolean_t rawok, boolean_t savedok, int outfd, offset_t *off,
|
boolean_t rawok, boolean_t savedok, int outfd, offset_t *off,
|
||||||
struct dmu_send_outparams *dso);
|
struct dmu_send_outparams *dso);
|
||||||
|
int dmu_send_close(struct dsl_dataset *ds);
|
||||||
|
|
||||||
typedef int (*dmu_send_outfunc_t)(objset_t *os, void *buf, int len, void *arg);
|
typedef int (*dmu_send_outfunc_t)(objset_t *os, void *buf, int len, void *arg);
|
||||||
typedef struct dmu_send_outparams {
|
typedef struct dmu_send_outparams {
|
||||||
|
|
|
@ -243,6 +243,8 @@ typedef struct dsl_dataset {
|
||||||
kmutex_t ds_sendstream_lock;
|
kmutex_t ds_sendstream_lock;
|
||||||
list_t ds_sendstreams;
|
list_t ds_sendstreams;
|
||||||
|
|
||||||
|
struct dmu_recv_cookie *ds_receiver;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When in the middle of a resumable receive, tracks how much
|
* When in the middle of a resumable receive, tracks how much
|
||||||
* progress we have made.
|
* progress we have made.
|
||||||
|
@ -317,7 +319,8 @@ typedef struct dsl_dataset_snapshot_arg {
|
||||||
/* flags for holding the dataset */
|
/* flags for holding the dataset */
|
||||||
typedef enum ds_hold_flags {
|
typedef enum ds_hold_flags {
|
||||||
DS_HOLD_FLAG_NONE = 0 << 0,
|
DS_HOLD_FLAG_NONE = 0 << 0,
|
||||||
DS_HOLD_FLAG_DECRYPT = 1 << 0 /* needs access to encrypted data */
|
DS_HOLD_FLAG_DECRYPT = 1 << 0, /* needs access to encrypted data */
|
||||||
|
DS_HOLD_FLAG_MUST_BE_OPEN = 1 << 1, /* dataset must already be open */
|
||||||
} ds_hold_flags_t;
|
} ds_hold_flags_t;
|
||||||
|
|
||||||
int dsl_dataset_hold(struct dsl_pool *dp, const char *name, void *tag,
|
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);
|
||||||
void dsl_dataset_long_rele(dsl_dataset_t *ds, void *tag);
|
void dsl_dataset_long_rele(dsl_dataset_t *ds, void *tag);
|
||||||
boolean_t dsl_dataset_long_held(dsl_dataset_t *ds);
|
boolean_t dsl_dataset_long_held(dsl_dataset_t *ds);
|
||||||
|
|
||||||
|
int dsl_dataset_sendrecv_cancel_all(spa_t *spa);
|
||||||
|
|
||||||
int dsl_dataset_clone_swap_check_impl(dsl_dataset_t *clone,
|
int dsl_dataset_clone_swap_check_impl(dsl_dataset_t *clone,
|
||||||
dsl_dataset_t *origin_head, boolean_t force, void *owner, dmu_tx_t *tx);
|
dsl_dataset_t *origin_head, boolean_t force, void *owner, dmu_tx_t *tx);
|
||||||
void dsl_dataset_clone_swap_sync_impl(dsl_dataset_t *clone,
|
void dsl_dataset_clone_swap_sync_impl(dsl_dataset_t *clone,
|
||||||
|
|
|
@ -172,7 +172,7 @@ int dsl_scan(struct dsl_pool *, pool_scan_func_t);
|
||||||
void dsl_scan_assess_vdev(struct dsl_pool *dp, vdev_t *vd);
|
void dsl_scan_assess_vdev(struct dsl_pool *dp, vdev_t *vd);
|
||||||
boolean_t dsl_scan_scrubbing(const struct dsl_pool *dp);
|
boolean_t dsl_scan_scrubbing(const struct dsl_pool *dp);
|
||||||
int dsl_scrub_set_pause_resume(const struct dsl_pool *dp, pool_scrub_cmd_t cmd);
|
int dsl_scrub_set_pause_resume(const struct dsl_pool *dp, pool_scrub_cmd_t cmd);
|
||||||
void dsl_scan_restart_resilver(struct dsl_pool *, uint64_t txg);
|
int dsl_scan_restart_resilver(struct dsl_pool *, uint64_t txg);
|
||||||
boolean_t dsl_scan_resilvering(struct dsl_pool *dp);
|
boolean_t dsl_scan_resilvering(struct dsl_pool *dp);
|
||||||
boolean_t dsl_scan_resilver_scheduled(struct dsl_pool *dp);
|
boolean_t dsl_scan_resilver_scheduled(struct dsl_pool *dp);
|
||||||
boolean_t dsl_dataset_unstable(struct dsl_dataset *ds);
|
boolean_t dsl_dataset_unstable(struct dsl_dataset *ds);
|
||||||
|
|
|
@ -1367,6 +1367,8 @@ typedef enum zfs_ioc {
|
||||||
ZFS_IOC_UNJAIL, /* 0x86 (FreeBSD) */
|
ZFS_IOC_UNJAIL, /* 0x86 (FreeBSD) */
|
||||||
ZFS_IOC_SET_BOOTENV, /* 0x87 */
|
ZFS_IOC_SET_BOOTENV, /* 0x87 */
|
||||||
ZFS_IOC_GET_BOOTENV, /* 0x88 */
|
ZFS_IOC_GET_BOOTENV, /* 0x88 */
|
||||||
|
ZFS_IOC_HARD_FORCE_UNMOUNT_BEGIN, /* 0x89 (Linux) */
|
||||||
|
ZFS_IOC_HARD_FORCE_UNMOUNT_END, /* 0x90 (Linux) */
|
||||||
ZFS_IOC_LAST
|
ZFS_IOC_LAST
|
||||||
} zfs_ioc_t;
|
} zfs_ioc_t;
|
||||||
|
|
||||||
|
|
|
@ -111,6 +111,7 @@ boolean_t metaslab_class_throttle_reserve(metaslab_class_t *, int, int,
|
||||||
zio_t *, int);
|
zio_t *, int);
|
||||||
void metaslab_class_throttle_unreserve(metaslab_class_t *, int, int, zio_t *);
|
void metaslab_class_throttle_unreserve(metaslab_class_t *, int, int, zio_t *);
|
||||||
void metaslab_class_evict_old(metaslab_class_t *, uint64_t);
|
void metaslab_class_evict_old(metaslab_class_t *, uint64_t);
|
||||||
|
void metaslab_class_force_discard(metaslab_class_t *);
|
||||||
uint64_t metaslab_class_get_alloc(metaslab_class_t *);
|
uint64_t metaslab_class_get_alloc(metaslab_class_t *);
|
||||||
uint64_t metaslab_class_get_space(metaslab_class_t *);
|
uint64_t metaslab_class_get_space(metaslab_class_t *);
|
||||||
uint64_t metaslab_class_get_dspace(metaslab_class_t *);
|
uint64_t metaslab_class_get_dspace(metaslab_class_t *);
|
||||||
|
|
|
@ -774,6 +774,7 @@ extern int spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
|
||||||
extern int spa_import(char *pool, nvlist_t *config, nvlist_t *props,
|
extern int spa_import(char *pool, nvlist_t *config, nvlist_t *props,
|
||||||
uint64_t flags);
|
uint64_t flags);
|
||||||
extern nvlist_t *spa_tryimport(nvlist_t *tryconfig);
|
extern nvlist_t *spa_tryimport(nvlist_t *tryconfig);
|
||||||
|
extern int spa_set_pre_export_status(const char *pool, boolean_t status);
|
||||||
extern int spa_destroy(const char *pool);
|
extern int spa_destroy(const char *pool);
|
||||||
extern int spa_checkpoint(const char *pool);
|
extern int spa_checkpoint(const char *pool);
|
||||||
extern int spa_checkpoint_discard(const char *pool);
|
extern int spa_checkpoint_discard(const char *pool);
|
||||||
|
@ -867,7 +868,7 @@ extern nvlist_t *spa_all_configs(uint64_t *);
|
||||||
extern void spa_config_set(spa_t *spa, nvlist_t *config);
|
extern void spa_config_set(spa_t *spa, nvlist_t *config);
|
||||||
extern nvlist_t *spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg,
|
extern nvlist_t *spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg,
|
||||||
int getstats);
|
int getstats);
|
||||||
extern void spa_config_update(spa_t *spa, int what);
|
extern int spa_config_update_pool(spa_t *spa);
|
||||||
extern int spa_config_parse(spa_t *spa, vdev_t **vdp, nvlist_t *nv,
|
extern int spa_config_parse(spa_t *spa, vdev_t **vdp, nvlist_t *nv,
|
||||||
vdev_t *parent, uint_t id, int atype);
|
vdev_t *parent, uint_t id, int atype);
|
||||||
|
|
||||||
|
@ -988,6 +989,13 @@ extern void spa_iostats_trim_add(spa_t *spa, trim_type_t type,
|
||||||
uint64_t extents_written, uint64_t bytes_written,
|
uint64_t extents_written, uint64_t bytes_written,
|
||||||
uint64_t extents_skipped, uint64_t bytes_skipped,
|
uint64_t extents_skipped, uint64_t bytes_skipped,
|
||||||
uint64_t extents_failed, uint64_t bytes_failed);
|
uint64_t extents_failed, uint64_t bytes_failed);
|
||||||
|
|
||||||
|
/* Config lock handling flags */
|
||||||
|
typedef enum {
|
||||||
|
SCL_FLAG_TRYENTER = 1U << 0,
|
||||||
|
SCL_FLAG_NOSUSPEND = 1U << 1,
|
||||||
|
} spa_config_flag_t;
|
||||||
|
|
||||||
extern void spa_import_progress_add(spa_t *spa);
|
extern void spa_import_progress_add(spa_t *spa);
|
||||||
extern void spa_import_progress_remove(uint64_t spa_guid);
|
extern void spa_import_progress_remove(uint64_t spa_guid);
|
||||||
extern int spa_import_progress_set_mmp_check(uint64_t pool_guid,
|
extern int spa_import_progress_set_mmp_check(uint64_t pool_guid,
|
||||||
|
@ -998,7 +1006,10 @@ extern int spa_import_progress_set_state(uint64_t pool_guid,
|
||||||
spa_load_state_t spa_load_state);
|
spa_load_state_t spa_load_state);
|
||||||
|
|
||||||
/* Pool configuration locks */
|
/* Pool configuration locks */
|
||||||
extern int spa_config_tryenter(spa_t *spa, int locks, void *tag, krw_t rw);
|
extern int spa_config_tryenter(spa_t *spa, int locks, const void *tag,
|
||||||
|
krw_t rw);
|
||||||
|
extern int spa_config_enter_flags(spa_t *spa, int locks, const void *tag,
|
||||||
|
krw_t rw, spa_config_flag_t flags);
|
||||||
extern void spa_config_enter(spa_t *spa, int locks, const void *tag, krw_t rw);
|
extern void spa_config_enter(spa_t *spa, int locks, const void *tag, krw_t rw);
|
||||||
extern void spa_config_exit(spa_t *spa, int locks, const void *tag);
|
extern void spa_config_exit(spa_t *spa, int locks, const void *tag);
|
||||||
extern int spa_config_held(spa_t *spa, int locks, krw_t rw);
|
extern int spa_config_held(spa_t *spa, int locks, krw_t rw);
|
||||||
|
@ -1047,6 +1058,7 @@ extern uint64_t spa_last_synced_txg(spa_t *spa);
|
||||||
extern uint64_t spa_first_txg(spa_t *spa);
|
extern uint64_t spa_first_txg(spa_t *spa);
|
||||||
extern uint64_t spa_syncing_txg(spa_t *spa);
|
extern uint64_t spa_syncing_txg(spa_t *spa);
|
||||||
extern uint64_t spa_final_dirty_txg(spa_t *spa);
|
extern uint64_t spa_final_dirty_txg(spa_t *spa);
|
||||||
|
extern void spa_verify_dirty_txg(spa_t *spa, uint64_t txg);
|
||||||
extern uint64_t spa_version(spa_t *spa);
|
extern uint64_t spa_version(spa_t *spa);
|
||||||
extern pool_state_t spa_state(spa_t *spa);
|
extern pool_state_t spa_state(spa_t *spa);
|
||||||
extern spa_load_state_t spa_load_state(spa_t *spa);
|
extern spa_load_state_t spa_load_state(spa_t *spa);
|
||||||
|
@ -1066,6 +1078,8 @@ extern metaslab_class_t *spa_dedup_class(spa_t *spa);
|
||||||
extern metaslab_class_t *spa_preferred_class(spa_t *spa, uint64_t size,
|
extern metaslab_class_t *spa_preferred_class(spa_t *spa, uint64_t size,
|
||||||
dmu_object_type_t objtype, uint_t level, uint_t special_smallblk);
|
dmu_object_type_t objtype, uint_t level, uint_t special_smallblk);
|
||||||
|
|
||||||
|
extern void spa_evicting_os_lock(spa_t *);
|
||||||
|
extern void spa_evicting_os_unlock(spa_t *);
|
||||||
extern void spa_evicting_os_register(spa_t *, objset_t *os);
|
extern void spa_evicting_os_register(spa_t *, objset_t *os);
|
||||||
extern void spa_evicting_os_deregister(spa_t *, objset_t *os);
|
extern void spa_evicting_os_deregister(spa_t *, objset_t *os);
|
||||||
extern void spa_evicting_os_wait(spa_t *spa);
|
extern void spa_evicting_os_wait(spa_t *spa);
|
||||||
|
@ -1154,6 +1168,10 @@ extern void spa_history_log_internal_dd(dsl_dir_t *dd, const char *operation,
|
||||||
|
|
||||||
extern const char *spa_state_to_name(spa_t *spa);
|
extern const char *spa_state_to_name(spa_t *spa);
|
||||||
|
|
||||||
|
extern boolean_t spa_exiting_any(spa_t *spa);
|
||||||
|
extern boolean_t spa_exiting(spa_t *spa);
|
||||||
|
extern int spa_operation_interrupted(spa_t *spa);
|
||||||
|
|
||||||
/* error handling */
|
/* error handling */
|
||||||
struct zbookmark_phys;
|
struct zbookmark_phys;
|
||||||
extern void spa_log_error(spa_t *spa, const zbookmark_phys_t *zb);
|
extern void spa_log_error(spa_t *spa, const zbookmark_phys_t *zb);
|
||||||
|
|
|
@ -244,6 +244,8 @@ struct spa {
|
||||||
kmutex_t spa_evicting_os_lock; /* Evicting objset list lock */
|
kmutex_t spa_evicting_os_lock; /* Evicting objset list lock */
|
||||||
list_t spa_evicting_os_list; /* Objsets being evicted. */
|
list_t spa_evicting_os_list; /* Objsets being evicted. */
|
||||||
kcondvar_t spa_evicting_os_cv; /* Objset Eviction Completion */
|
kcondvar_t spa_evicting_os_cv; /* Objset Eviction Completion */
|
||||||
|
kthread_t *spa_export_initiator; /* thread exporting the pool */
|
||||||
|
boolean_t spa_pre_exporting; /* allow fails before export */
|
||||||
txg_list_t spa_vdev_txg_list; /* per-txg dirty vdev list */
|
txg_list_t spa_vdev_txg_list; /* per-txg dirty vdev list */
|
||||||
vdev_t *spa_root_vdev; /* top-level vdev container */
|
vdev_t *spa_root_vdev; /* top-level vdev container */
|
||||||
uint64_t spa_min_ashift; /* of vdevs in normal class */
|
uint64_t spa_min_ashift; /* of vdevs in normal class */
|
||||||
|
|
|
@ -66,11 +66,27 @@ typedef struct txg_list {
|
||||||
} txg_list_t;
|
} txg_list_t;
|
||||||
|
|
||||||
struct dsl_pool;
|
struct dsl_pool;
|
||||||
|
struct dmu_tx;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TXG wait flags, used by txg_wait_synced_tx and callers to indicate
|
||||||
|
* modifications to how they wish to wait for a txg.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
/* No special wait flags. */
|
||||||
|
TXG_WAIT_F_NONE = 0,
|
||||||
|
/* Reject the call with EINTR upon receiving a signal. */
|
||||||
|
TXG_WAIT_F_SIGNAL = (1U << 0),
|
||||||
|
/* Reject the call with EAGAIN upon suspension. */
|
||||||
|
TXG_WAIT_F_NOSUSPEND = (1U << 1),
|
||||||
|
/* Ignore errors and export anyway. */
|
||||||
|
TXG_WAIT_F_FORCE_EXPORT = (1U << 2),
|
||||||
|
} txg_wait_flag_t;
|
||||||
|
|
||||||
extern void txg_init(struct dsl_pool *dp, uint64_t txg);
|
extern void txg_init(struct dsl_pool *dp, uint64_t txg);
|
||||||
extern void txg_fini(struct dsl_pool *dp);
|
extern void txg_fini(struct dsl_pool *dp);
|
||||||
extern void txg_sync_start(struct dsl_pool *dp);
|
extern void txg_sync_start(struct dsl_pool *dp);
|
||||||
extern void txg_sync_stop(struct dsl_pool *dp);
|
extern int txg_sync_stop(struct dsl_pool *dp, txg_wait_flag_t txg_how);
|
||||||
extern uint64_t txg_hold_open(struct dsl_pool *dp, txg_handle_t *txghp);
|
extern uint64_t txg_hold_open(struct dsl_pool *dp, txg_handle_t *txghp);
|
||||||
extern void txg_rele_to_quiesce(txg_handle_t *txghp);
|
extern void txg_rele_to_quiesce(txg_handle_t *txghp);
|
||||||
extern void txg_rele_to_sync(txg_handle_t *txghp);
|
extern void txg_rele_to_sync(txg_handle_t *txghp);
|
||||||
|
@ -84,14 +100,23 @@ extern void txg_kick(struct dsl_pool *dp);
|
||||||
* Wait until the given transaction group has finished syncing.
|
* Wait until the given transaction group has finished syncing.
|
||||||
* Try to make this happen as soon as possible (eg. kick off any
|
* Try to make this happen as soon as possible (eg. kick off any
|
||||||
* necessary syncs immediately). If txg==0, wait for the currently open
|
* necessary syncs immediately). If txg==0, wait for the currently open
|
||||||
* txg to finish syncing.
|
* txg to finish syncing. This may be interrupted due to an exiting pool.
|
||||||
|
*
|
||||||
|
* If desired, flags can be specified using txg_wait_synced_tx(), in case
|
||||||
|
* the caller wants to be interruptible.
|
||||||
*/
|
*/
|
||||||
extern void txg_wait_synced(struct dsl_pool *dp, uint64_t txg);
|
extern void txg_wait_synced(struct dsl_pool *dp, uint64_t txg);
|
||||||
|
extern int txg_wait_synced_tx(struct dsl_pool *dp, uint64_t txg,
|
||||||
|
struct dmu_tx *tx, txg_wait_flag_t flags);
|
||||||
|
extern int txg_wait_synced_flags(struct dsl_pool *dp, uint64_t txg,
|
||||||
|
txg_wait_flag_t flags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait as above. Returns true if the thread was signaled while waiting.
|
* Similar to a txg_wait_synced but it can be interrupted from a signal.
|
||||||
|
* Returns B_TRUE if the thread was signaled while waiting.
|
||||||
*/
|
*/
|
||||||
extern boolean_t txg_wait_synced_sig(struct dsl_pool *dp, uint64_t txg);
|
#define txg_wait_synced_sig(dp, txg) \
|
||||||
|
(txg_wait_synced_tx(dp, txg, NULL, TXG_WAIT_F_SIGNAL) == EINTR)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait until the given transaction group, or one after it, is
|
* 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);
|
||||||
extern void txg_wait_open(struct dsl_pool *dp, uint64_t txg,
|
extern void txg_wait_open(struct dsl_pool *dp, uint64_t txg,
|
||||||
boolean_t should_quiesce);
|
boolean_t should_quiesce);
|
||||||
|
|
||||||
|
void txg_force_export(spa_t *spa);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns TRUE if we are "backed up" waiting for the syncing
|
* Returns TRUE if we are "backed up" waiting for the syncing
|
||||||
* transaction to complete; otherwise returns FALSE.
|
* transaction to complete; otherwise returns FALSE.
|
||||||
|
@ -113,6 +140,8 @@ extern boolean_t txg_sync_waiting(struct dsl_pool *dp);
|
||||||
|
|
||||||
extern void txg_verify(spa_t *spa, uint64_t txg);
|
extern void txg_verify(spa_t *spa, uint64_t txg);
|
||||||
|
|
||||||
|
extern void txg_completion_notify(struct dsl_pool *dp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait for pending commit callbacks of already-synced transactions to finish
|
* Wait for pending commit callbacks of already-synced transactions to finish
|
||||||
* processing.
|
* processing.
|
||||||
|
|
|
@ -232,6 +232,7 @@ typedef pthread_t kthread_t;
|
||||||
zk_thread_create(func, arg, stksize, state)
|
zk_thread_create(func, arg, stksize, state)
|
||||||
#define thread_create(stk, stksize, func, arg, len, pp, state, pri) \
|
#define thread_create(stk, stksize, func, arg, len, pp, state, pri) \
|
||||||
zk_thread_create(func, arg, stksize, state)
|
zk_thread_create(func, arg, stksize, state)
|
||||||
|
#define thread_signal(t, s) pthread_kill((pthread_t)t, s)
|
||||||
#define thread_exit() pthread_exit(NULL)
|
#define thread_exit() pthread_exit(NULL)
|
||||||
#define thread_join(t) pthread_join((pthread_t)(t), NULL)
|
#define thread_join(t) pthread_join((pthread_t)(t), NULL)
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,10 @@ typedef struct zfs_ioc_key {
|
||||||
|
|
||||||
int zfs_secpolicy_config(zfs_cmd_t *, nvlist_t *, cred_t *);
|
int zfs_secpolicy_config(zfs_cmd_t *, nvlist_t *, cred_t *);
|
||||||
|
|
||||||
|
void zfs_ioctl_register_pool(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
|
||||||
|
zfs_secpolicy_func_t *secpolicy, boolean_t log_history,
|
||||||
|
zfs_ioc_poolcheck_t pool_check);
|
||||||
|
|
||||||
void zfs_ioctl_register_dataset_nolog(zfs_ioc_t, zfs_ioc_legacy_func_t *,
|
void zfs_ioctl_register_dataset_nolog(zfs_ioc_t, zfs_ioc_legacy_func_t *,
|
||||||
zfs_secpolicy_func_t *, zfs_ioc_poolcheck_t);
|
zfs_secpolicy_func_t *, zfs_ioc_poolcheck_t);
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ typedef struct refcount {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note: zfs_refcount_t must be initialized with
|
* Note: zfs_refcount_t must be initialized with
|
||||||
* refcount_create[_untracked]()
|
* zfs_refcount_create[_untracked]()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void zfs_refcount_create(zfs_refcount_t *);
|
void zfs_refcount_create(zfs_refcount_t *);
|
||||||
|
|
|
@ -216,6 +216,43 @@ typedef struct znode {
|
||||||
ZNODE_OS_FIELDS;
|
ZNODE_OS_FIELDS;
|
||||||
} znode_t;
|
} znode_t;
|
||||||
|
|
||||||
|
/* Verifies the znode is valid. */
|
||||||
|
static inline int
|
||||||
|
zfs_verify_zp(znode_t *zp)
|
||||||
|
{
|
||||||
|
if (unlikely(zp->z_sa_hdl == NULL))
|
||||||
|
return (SET_ERROR(EIO));
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* zfs_enter and zfs_verify_zp together */
|
||||||
|
static inline int
|
||||||
|
zfs_enter_verify_zp(zfsvfs_t *zfsvfs, znode_t *zp, const char *tag)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
|
||||||
|
ZFS_ENTER(zfsvfs);
|
||||||
|
if ((error = zfs_verify_zp(zp)) != 0) {
|
||||||
|
ZFS_EXIT(zfsvfs);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* zfs_enter_unmountok and zfs_verify_zp together */
|
||||||
|
static inline int
|
||||||
|
zfs_enter_unmountok_verify_zp(zfsvfs_t *zfsvfs, znode_t *zp, const char *tag)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
|
||||||
|
ZFS_ENTER_UNMOUNTOK(zfsvfs);
|
||||||
|
if ((error = zfs_verify_zp(zp)) != 0) {
|
||||||
|
ZFS_EXIT(zfsvfs);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct znode_hold {
|
typedef struct znode_hold {
|
||||||
uint64_t zh_obj; /* object id */
|
uint64_t zh_obj; /* object id */
|
||||||
kmutex_t zh_lock; /* lock serializing object access */
|
kmutex_t zh_lock; /* lock serializing object access */
|
||||||
|
|
|
@ -415,6 +415,7 @@ typedef zio_t *zio_pipe_stage_t(zio_t *zio);
|
||||||
*/
|
*/
|
||||||
#define ZIO_REEXECUTE_NOW 0x01
|
#define ZIO_REEXECUTE_NOW 0x01
|
||||||
#define ZIO_REEXECUTE_SUSPEND 0x02
|
#define ZIO_REEXECUTE_SUSPEND 0x02
|
||||||
|
#define ZIO_REEXECUTE_CANCELLED 0x04
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The io_trim flags are used to specify the type of TRIM to perform. They
|
* The io_trim flags are used to specify the type of TRIM to perform. They
|
||||||
|
@ -640,7 +641,7 @@ extern uint8_t zio_complevel_select(spa_t *spa, enum zio_compress compress,
|
||||||
|
|
||||||
extern void zio_suspend(spa_t *spa, zio_t *zio, zio_suspend_reason_t);
|
extern void zio_suspend(spa_t *spa, zio_t *zio, zio_suspend_reason_t);
|
||||||
extern int zio_resume(spa_t *spa);
|
extern int zio_resume(spa_t *spa);
|
||||||
extern void zio_resume_wait(spa_t *spa);
|
extern void zio_cancel(spa_t *spa);
|
||||||
|
|
||||||
extern boolean_t zfs_blkptr_verify(spa_t *spa, const blkptr_t *bp,
|
extern boolean_t zfs_blkptr_verify(spa_t *spa, const blkptr_t *bp,
|
||||||
boolean_t config_held, enum blk_verify_flag blk_verify);
|
boolean_t config_held, enum blk_verify_flag blk_verify);
|
||||||
|
|
|
@ -589,14 +589,6 @@
|
||||||
</function-decl>
|
</function-decl>
|
||||||
</abi-instr>
|
</abi-instr>
|
||||||
<abi-instr address-size='64' path='../../module/nvpair/nvpair.c' language='LANG_C99'>
|
<abi-instr address-size='64' path='../../module/nvpair/nvpair.c' language='LANG_C99'>
|
||||||
<typedef-decl name='__u_short' type-id='8efea9e5' id='46c660f8'/>
|
|
||||||
<typedef-decl name='__u_int' type-id='f0981eeb' id='8ae6822f'/>
|
|
||||||
<typedef-decl name='__quad_t' type-id='bd54fe1a' id='2632227a'/>
|
|
||||||
<typedef-decl name='__u_quad_t' type-id='7359adad' id='5f3d50a6'/>
|
|
||||||
<typedef-decl name='u_short' type-id='46c660f8' id='32580e96'/>
|
|
||||||
<typedef-decl name='u_int' type-id='8ae6822f' id='48f7c3f5'/>
|
|
||||||
<typedef-decl name='quad_t' type-id='2632227a' id='f5ef0660'/>
|
|
||||||
<typedef-decl name='u_quad_t' type-id='5f3d50a6' id='bd226ac0'/>
|
|
||||||
<typedef-decl name='bool_t' type-id='3ff5601b' id='310a70df'/>
|
<typedef-decl name='bool_t' type-id='3ff5601b' id='310a70df'/>
|
||||||
<enum-decl name='xdr_op' id='6badf1b8'>
|
<enum-decl name='xdr_op' id='6badf1b8'>
|
||||||
<underlying-type type-id='9cac1fee'/>
|
<underlying-type type-id='9cac1fee'/>
|
||||||
|
@ -655,6 +647,14 @@
|
||||||
</class-decl>
|
</class-decl>
|
||||||
<typedef-decl name='XDR' type-id='755707df' id='bc407f0e'/>
|
<typedef-decl name='XDR' type-id='755707df' id='bc407f0e'/>
|
||||||
<typedef-decl name='xdrproc_t' type-id='94d188f0' id='c28db3e9'/>
|
<typedef-decl name='xdrproc_t' type-id='94d188f0' id='c28db3e9'/>
|
||||||
|
<typedef-decl name='__u_short' type-id='8efea9e5' id='46c660f8'/>
|
||||||
|
<typedef-decl name='__u_int' type-id='f0981eeb' id='8ae6822f'/>
|
||||||
|
<typedef-decl name='__quad_t' type-id='bd54fe1a' id='2632227a'/>
|
||||||
|
<typedef-decl name='__u_quad_t' type-id='7359adad' id='5f3d50a6'/>
|
||||||
|
<typedef-decl name='u_short' type-id='46c660f8' id='32580e96'/>
|
||||||
|
<typedef-decl name='u_int' type-id='8ae6822f' id='48f7c3f5'/>
|
||||||
|
<typedef-decl name='quad_t' type-id='2632227a' id='f5ef0660'/>
|
||||||
|
<typedef-decl name='u_quad_t' type-id='5f3d50a6' id='bd226ac0'/>
|
||||||
<pointer-type-def type-id='bc407f0e' size-in-bits='64' id='17fd1621'/>
|
<pointer-type-def type-id='bc407f0e' size-in-bits='64' id='17fd1621'/>
|
||||||
<pointer-type-def type-id='755707df' size-in-bits='64' id='812c6697'/>
|
<pointer-type-def type-id='755707df' size-in-bits='64' id='812c6697'/>
|
||||||
<qualified-type-def type-id='26a90f95' const='yes' id='57de658a'/>
|
<qualified-type-def type-id='26a90f95' const='yes' id='57de658a'/>
|
||||||
|
@ -1771,6 +1771,63 @@
|
||||||
<var-decl name='nvprt_custops' type-id='7be54adb' visibility='default'/>
|
<var-decl name='nvprt_custops' type-id='7be54adb' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
</class-decl>
|
</class-decl>
|
||||||
|
<typedef-decl name='__re_long_size_t' type-id='7359adad' id='ba516949'/>
|
||||||
|
<typedef-decl name='reg_syntax_t' type-id='7359adad' id='1b72c3b3'/>
|
||||||
|
<class-decl name='re_pattern_buffer' size-in-bits='512' is-struct='yes' visibility='default' id='19fc9a8c'>
|
||||||
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
|
<var-decl name='buffer' type-id='33976309' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='64'>
|
||||||
|
<var-decl name='allocated' type-id='ba516949' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='128'>
|
||||||
|
<var-decl name='used' type-id='ba516949' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='192'>
|
||||||
|
<var-decl name='syntax' type-id='1b72c3b3' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='256'>
|
||||||
|
<var-decl name='fastmap' type-id='26a90f95' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='320'>
|
||||||
|
<var-decl name='translate' type-id='cf536864' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='384'>
|
||||||
|
<var-decl name='re_nsub' type-id='b59d7dce' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='448'>
|
||||||
|
<var-decl name='can_be_null' type-id='f0981eeb' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='449'>
|
||||||
|
<var-decl name='regs_allocated' type-id='f0981eeb' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='451'>
|
||||||
|
<var-decl name='fastmap_accurate' type-id='f0981eeb' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='452'>
|
||||||
|
<var-decl name='no_sub' type-id='f0981eeb' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='453'>
|
||||||
|
<var-decl name='not_bol' type-id='f0981eeb' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='454'>
|
||||||
|
<var-decl name='not_eol' type-id='f0981eeb' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='455'>
|
||||||
|
<var-decl name='newline_anchor' type-id='f0981eeb' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
</class-decl>
|
||||||
|
<typedef-decl name='regex_t' type-id='19fc9a8c' id='aca3bac8'/>
|
||||||
|
<typedef-decl name='regoff_t' type-id='95e97e5e' id='54a2a2a8'/>
|
||||||
|
<class-decl name='regmatch_t' size-in-bits='64' is-struct='yes' naming-typedef-id='1b941664' visibility='default' id='4f932615'>
|
||||||
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
|
<var-decl name='rm_so' type-id='54a2a2a8' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='32'>
|
||||||
|
<var-decl name='rm_eo' type-id='54a2a2a8' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
</class-decl>
|
||||||
|
<typedef-decl name='regmatch_t' type-id='4f932615' id='1b941664'/>
|
||||||
<typedef-decl name='int8_t' type-id='2171a512' id='ee31ee44'/>
|
<typedef-decl name='int8_t' type-id='2171a512' id='ee31ee44'/>
|
||||||
<typedef-decl name='int16_t' type-id='03896e23' id='23bd8cb5'/>
|
<typedef-decl name='int16_t' type-id='03896e23' id='23bd8cb5'/>
|
||||||
<typedef-decl name='int32_t' type-id='33f57a65' id='3ff5601b'/>
|
<typedef-decl name='int32_t' type-id='33f57a65' id='3ff5601b'/>
|
||||||
|
@ -1880,63 +1937,6 @@
|
||||||
<var-decl name='_unused2' type-id='664ac0b7' visibility='default'/>
|
<var-decl name='_unused2' type-id='664ac0b7' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
</class-decl>
|
</class-decl>
|
||||||
<typedef-decl name='__re_long_size_t' type-id='7359adad' id='ba516949'/>
|
|
||||||
<typedef-decl name='reg_syntax_t' type-id='7359adad' id='1b72c3b3'/>
|
|
||||||
<class-decl name='re_pattern_buffer' size-in-bits='512' is-struct='yes' visibility='default' id='19fc9a8c'>
|
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
|
||||||
<var-decl name='buffer' type-id='33976309' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='64'>
|
|
||||||
<var-decl name='allocated' type-id='ba516949' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='128'>
|
|
||||||
<var-decl name='used' type-id='ba516949' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='192'>
|
|
||||||
<var-decl name='syntax' type-id='1b72c3b3' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='256'>
|
|
||||||
<var-decl name='fastmap' type-id='26a90f95' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='320'>
|
|
||||||
<var-decl name='translate' type-id='cf536864' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='384'>
|
|
||||||
<var-decl name='re_nsub' type-id='b59d7dce' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='448'>
|
|
||||||
<var-decl name='can_be_null' type-id='f0981eeb' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='449'>
|
|
||||||
<var-decl name='regs_allocated' type-id='f0981eeb' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='451'>
|
|
||||||
<var-decl name='fastmap_accurate' type-id='f0981eeb' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='452'>
|
|
||||||
<var-decl name='no_sub' type-id='f0981eeb' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='453'>
|
|
||||||
<var-decl name='not_bol' type-id='f0981eeb' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='454'>
|
|
||||||
<var-decl name='not_eol' type-id='f0981eeb' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='455'>
|
|
||||||
<var-decl name='newline_anchor' type-id='f0981eeb' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
</class-decl>
|
|
||||||
<typedef-decl name='regex_t' type-id='19fc9a8c' id='aca3bac8'/>
|
|
||||||
<typedef-decl name='regoff_t' type-id='95e97e5e' id='54a2a2a8'/>
|
|
||||||
<class-decl name='regmatch_t' size-in-bits='64' is-struct='yes' naming-typedef-id='1b941664' visibility='default' id='4f932615'>
|
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
|
||||||
<var-decl name='rm_so' type-id='54a2a2a8' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='32'>
|
|
||||||
<var-decl name='rm_eo' type-id='54a2a2a8' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
</class-decl>
|
|
||||||
<typedef-decl name='regmatch_t' type-id='4f932615' id='1b941664'/>
|
|
||||||
<typedef-decl name='size_t' type-id='7359adad' id='b59d7dce'/>
|
<typedef-decl name='size_t' type-id='7359adad' id='b59d7dce'/>
|
||||||
<pointer-type-def type-id='aa12d1ba' size-in-bits='64' id='822cd80b'/>
|
<pointer-type-def type-id='aa12d1ba' size-in-bits='64' id='822cd80b'/>
|
||||||
<qualified-type-def type-id='822cd80b' restrict='yes' id='e75a27e9'/>
|
<qualified-type-def type-id='822cd80b' restrict='yes' id='e75a27e9'/>
|
||||||
|
@ -2452,17 +2452,6 @@
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='fprintf' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='e75a27e9'/>
|
|
||||||
<parameter type-id='9d26089a'/>
|
|
||||||
<parameter is-variadic='yes'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='printf' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter is-variadic='yes'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='malloc' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='malloc' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='b59d7dce'/>
|
<parameter type-id='b59d7dce'/>
|
||||||
<return type-id='eaa32e2f'/>
|
<return type-id='eaa32e2f'/>
|
||||||
|
@ -2491,6 +2480,19 @@
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
<return type-id='b59d7dce'/>
|
<return type-id='b59d7dce'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
|
<function-decl name='__fprintf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='e75a27e9'/>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<parameter type-id='9d26089a'/>
|
||||||
|
<parameter is-variadic='yes'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='__printf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<parameter type-id='80f4b756'/>
|
||||||
|
<parameter is-variadic='yes'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
<function-type size-in-bits='64' id='9f88f76e'>
|
<function-type size-in-bits='64' id='9f88f76e'>
|
||||||
<parameter type-id='196db161'/>
|
<parameter type-id='196db161'/>
|
||||||
<parameter type-id='eaa32e2f'/>
|
<parameter type-id='eaa32e2f'/>
|
||||||
|
@ -3124,14 +3126,15 @@
|
||||||
</abi-instr>
|
</abi-instr>
|
||||||
<abi-instr address-size='64' path='assert.c' language='LANG_C99'>
|
<abi-instr address-size='64' path='assert.c' language='LANG_C99'>
|
||||||
<var-decl name='aok' type-id='95e97e5e' mangled-name='aok' visibility='default' elf-symbol-id='aok'/>
|
<var-decl name='aok' type-id='95e97e5e' mangled-name='aok' visibility='default' elf-symbol-id='aok'/>
|
||||||
<function-decl name='vfprintf' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='abort' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<return type-id='48b5725f'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='__vfprintf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='e75a27e9'/>
|
<parameter type-id='e75a27e9'/>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
<parameter type-id='9d26089a'/>
|
<parameter type-id='9d26089a'/>
|
||||||
<parameter type-id='b7f2d5e6'/>
|
<parameter type-id='b7f2d5e6'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='abort' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<return type-id='48b5725f'/>
|
|
||||||
</function-decl>
|
|
||||||
</abi-instr>
|
</abi-instr>
|
||||||
</abi-corpus>
|
</abi-corpus>
|
||||||
|
|
|
@ -774,16 +774,23 @@
|
||||||
<parameter type-id='b59d7dce'/>
|
<parameter type-id='b59d7dce'/>
|
||||||
<return type-id='eaa32e2f'/>
|
<return type-id='eaa32e2f'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='mbstowcs' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='access' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='80f4b756'/>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='__mbstowcs_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='f1358bc3'/>
|
<parameter type-id='f1358bc3'/>
|
||||||
<parameter type-id='9d26089a'/>
|
<parameter type-id='9d26089a'/>
|
||||||
<parameter type-id='b59d7dce'/>
|
<parameter type-id='b59d7dce'/>
|
||||||
|
<parameter type-id='b59d7dce'/>
|
||||||
<return type-id='b59d7dce'/>
|
<return type-id='b59d7dce'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='wcstombs' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='__wcstombs_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='266fe297'/>
|
<parameter type-id='266fe297'/>
|
||||||
<parameter type-id='598aab80'/>
|
<parameter type-id='598aab80'/>
|
||||||
<parameter type-id='b59d7dce'/>
|
<parameter type-id='b59d7dce'/>
|
||||||
|
<parameter type-id='b59d7dce'/>
|
||||||
<return type-id='b59d7dce'/>
|
<return type-id='b59d7dce'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='mkdir' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='mkdir' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
@ -791,17 +798,13 @@
|
||||||
<parameter type-id='e1c52942'/>
|
<parameter type-id='e1c52942'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='access' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='95e97e5e'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
</abi-instr>
|
</abi-instr>
|
||||||
<abi-instr address-size='64' path='os/linux/getexecname.c' language='LANG_C99'>
|
<abi-instr address-size='64' path='os/linux/getexecname.c' language='LANG_C99'>
|
||||||
<function-decl name='readlink' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='__readlink_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='9d26089a'/>
|
<parameter type-id='9d26089a'/>
|
||||||
<parameter type-id='266fe297'/>
|
<parameter type-id='266fe297'/>
|
||||||
<parameter type-id='b59d7dce'/>
|
<parameter type-id='b59d7dce'/>
|
||||||
|
<parameter type-id='b59d7dce'/>
|
||||||
<return type-id='79a0948f'/>
|
<return type-id='79a0948f'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
</abi-instr>
|
</abi-instr>
|
||||||
|
@ -827,10 +830,11 @@
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='read' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='__read_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
<parameter type-id='eaa32e2f'/>
|
<parameter type-id='eaa32e2f'/>
|
||||||
<parameter type-id='b59d7dce'/>
|
<parameter type-id='b59d7dce'/>
|
||||||
|
<parameter type-id='b59d7dce'/>
|
||||||
<return type-id='79a0948f'/>
|
<return type-id='79a0948f'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='get_system_hostid' mangled-name='get_system_hostid' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_system_hostid'>
|
<function-decl name='get_system_hostid' mangled-name='get_system_hostid' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_system_hostid'>
|
||||||
|
@ -879,6 +883,26 @@
|
||||||
<var-decl name='mnt_minor' type-id='3502e3ff' visibility='default'/>
|
<var-decl name='mnt_minor' type-id='3502e3ff' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
</class-decl>
|
</class-decl>
|
||||||
|
<class-decl name='mntent' size-in-bits='320' is-struct='yes' visibility='default' id='56fe4a37'>
|
||||||
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
|
<var-decl name='mnt_fsname' type-id='26a90f95' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='64'>
|
||||||
|
<var-decl name='mnt_dir' type-id='26a90f95' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='128'>
|
||||||
|
<var-decl name='mnt_type' type-id='26a90f95' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='192'>
|
||||||
|
<var-decl name='mnt_opts' type-id='26a90f95' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='256'>
|
||||||
|
<var-decl name='mnt_freq' type-id='95e97e5e' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='288'>
|
||||||
|
<var-decl name='mnt_passno' type-id='95e97e5e' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
</class-decl>
|
||||||
<class-decl name='stat64' size-in-bits='1152' is-struct='yes' visibility='default' id='0bbec9cd'>
|
<class-decl name='stat64' size-in-bits='1152' is-struct='yes' visibility='default' id='0bbec9cd'>
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
<var-decl name='st_dev' type-id='35ed8932' visibility='default'/>
|
<var-decl name='st_dev' type-id='35ed8932' visibility='default'/>
|
||||||
|
@ -933,26 +957,6 @@
|
||||||
<typedef-decl name='__nlink_t' type-id='7359adad' id='80f0b9df'/>
|
<typedef-decl name='__nlink_t' type-id='7359adad' id='80f0b9df'/>
|
||||||
<typedef-decl name='__blksize_t' type-id='bd54fe1a' id='d3f10a7f'/>
|
<typedef-decl name='__blksize_t' type-id='bd54fe1a' id='d3f10a7f'/>
|
||||||
<typedef-decl name='__blkcnt64_t' type-id='bd54fe1a' id='4e711bf1'/>
|
<typedef-decl name='__blkcnt64_t' type-id='bd54fe1a' id='4e711bf1'/>
|
||||||
<class-decl name='mntent' size-in-bits='320' is-struct='yes' visibility='default' id='56fe4a37'>
|
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
|
||||||
<var-decl name='mnt_fsname' type-id='26a90f95' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='64'>
|
|
||||||
<var-decl name='mnt_dir' type-id='26a90f95' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='128'>
|
|
||||||
<var-decl name='mnt_type' type-id='26a90f95' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='192'>
|
|
||||||
<var-decl name='mnt_opts' type-id='26a90f95' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='256'>
|
|
||||||
<var-decl name='mnt_freq' type-id='95e97e5e' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='288'>
|
|
||||||
<var-decl name='mnt_passno' type-id='95e97e5e' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
</class-decl>
|
|
||||||
<pointer-type-def type-id='0c544dc0' size-in-bits='64' id='394fc496'/>
|
<pointer-type-def type-id='0c544dc0' size-in-bits='64' id='394fc496'/>
|
||||||
<pointer-type-def type-id='56fe4a37' size-in-bits='64' id='b6b61d2f'/>
|
<pointer-type-def type-id='56fe4a37' size-in-bits='64' id='b6b61d2f'/>
|
||||||
<qualified-type-def type-id='b6b61d2f' restrict='yes' id='3cad23cd'/>
|
<qualified-type-def type-id='b6b61d2f' restrict='yes' id='3cad23cd'/>
|
||||||
|
@ -1019,6 +1023,7 @@
|
||||||
</function-decl>
|
</function-decl>
|
||||||
</abi-instr>
|
</abi-instr>
|
||||||
<abi-instr address-size='64' path='timestamp.c' language='LANG_C99'>
|
<abi-instr address-size='64' path='timestamp.c' language='LANG_C99'>
|
||||||
|
<typedef-decl name='nl_item' type-id='95e97e5e' id='03b79a94'/>
|
||||||
<class-decl name='tm' size-in-bits='448' is-struct='yes' visibility='default' id='dddf6ca2'>
|
<class-decl name='tm' size-in-bits='448' is-struct='yes' visibility='default' id='dddf6ca2'>
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
<var-decl name='tm_sec' type-id='95e97e5e' visibility='default'/>
|
<var-decl name='tm_sec' type-id='95e97e5e' visibility='default'/>
|
||||||
|
@ -1055,7 +1060,6 @@
|
||||||
</data-member>
|
</data-member>
|
||||||
</class-decl>
|
</class-decl>
|
||||||
<typedef-decl name='time_t' type-id='65eda9c0' id='c9d12d66'/>
|
<typedef-decl name='time_t' type-id='65eda9c0' id='c9d12d66'/>
|
||||||
<typedef-decl name='nl_item' type-id='95e97e5e' id='03b79a94'/>
|
|
||||||
<qualified-type-def type-id='c9d12d66' const='yes' id='588b3216'/>
|
<qualified-type-def type-id='c9d12d66' const='yes' id='588b3216'/>
|
||||||
<pointer-type-def type-id='588b3216' size-in-bits='64' id='9f201474'/>
|
<pointer-type-def type-id='588b3216' size-in-bits='64' id='9f201474'/>
|
||||||
<qualified-type-def type-id='dddf6ca2' const='yes' id='e824a34f'/>
|
<qualified-type-def type-id='dddf6ca2' const='yes' id='e824a34f'/>
|
||||||
|
@ -1071,11 +1075,6 @@
|
||||||
<parameter type-id='03b79a94'/>
|
<parameter type-id='03b79a94'/>
|
||||||
<return type-id='26a90f95'/>
|
<return type-id='26a90f95'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='printf' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter is-variadic='yes'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='time' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='time' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='b2eb2c3f'/>
|
<parameter type-id='b2eb2c3f'/>
|
||||||
<return type-id='c9d12d66'/>
|
<return type-id='c9d12d66'/>
|
||||||
|
@ -1091,31 +1090,21 @@
|
||||||
<parameter type-id='9f201474'/>
|
<parameter type-id='9f201474'/>
|
||||||
<return type-id='d915a820'/>
|
<return type-id='d915a820'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
|
<function-decl name='__printf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<parameter type-id='80f4b756'/>
|
||||||
|
<parameter is-variadic='yes'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
</abi-instr>
|
</abi-instr>
|
||||||
<abi-instr address-size='64' path='uu_alloc.c' language='LANG_C99'>
|
<abi-instr address-size='64' path='uu_alloc.c' language='LANG_C99'>
|
||||||
<type-decl name='char' size-in-bits='8' id='a84c031d'/>
|
<type-decl name='char' size-in-bits='8' id='a84c031d'/>
|
||||||
<class-decl name='__va_list_tag' size-in-bits='192' is-struct='yes' visibility='default' id='d5027220'>
|
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
|
||||||
<var-decl name='gp_offset' type-id='f0981eeb' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='32'>
|
|
||||||
<var-decl name='fp_offset' type-id='f0981eeb' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='64'>
|
|
||||||
<var-decl name='overflow_arg_area' type-id='eaa32e2f' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='128'>
|
|
||||||
<var-decl name='reg_save_area' type-id='eaa32e2f' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
</class-decl>
|
|
||||||
<type-decl name='int' size-in-bits='32' id='95e97e5e'/>
|
|
||||||
<type-decl name='unsigned int' size-in-bits='32' id='f0981eeb'/>
|
<type-decl name='unsigned int' size-in-bits='32' id='f0981eeb'/>
|
||||||
<type-decl name='unsigned long int' size-in-bits='64' id='7359adad'/>
|
<type-decl name='unsigned long int' size-in-bits='64' id='7359adad'/>
|
||||||
<type-decl name='variadic parameter type' id='2c1145c5'/>
|
<type-decl name='variadic parameter type' id='2c1145c5'/>
|
||||||
<type-decl name='void' id='48b5725f'/>
|
<type-decl name='void' id='48b5725f'/>
|
||||||
<typedef-decl name='uint_t' type-id='f0981eeb' id='3502e3ff'/>
|
<typedef-decl name='uint_t' type-id='f0981eeb' id='3502e3ff'/>
|
||||||
<typedef-decl name='size_t' type-id='7359adad' id='b59d7dce'/>
|
<typedef-decl name='size_t' type-id='7359adad' id='b59d7dce'/>
|
||||||
<pointer-type-def type-id='d5027220' size-in-bits='64' id='b7f2d5e6'/>
|
|
||||||
<pointer-type-def type-id='a84c031d' size-in-bits='64' id='26a90f95'/>
|
<pointer-type-def type-id='a84c031d' size-in-bits='64' id='26a90f95'/>
|
||||||
<qualified-type-def type-id='a84c031d' const='yes' id='9b45d938'/>
|
<qualified-type-def type-id='a84c031d' const='yes' id='9b45d938'/>
|
||||||
<pointer-type-def type-id='9b45d938' size-in-bits='64' id='80f4b756'/>
|
<pointer-type-def type-id='9b45d938' size-in-bits='64' id='80f4b756'/>
|
||||||
|
@ -1151,13 +1140,6 @@
|
||||||
<parameter is-variadic='yes'/>
|
<parameter is-variadic='yes'/>
|
||||||
<return type-id='26a90f95'/>
|
<return type-id='26a90f95'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='vsnprintf' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='26a90f95'/>
|
|
||||||
<parameter type-id='b59d7dce'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='b7f2d5e6'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='malloc' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='malloc' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='b59d7dce'/>
|
<parameter type-id='b59d7dce'/>
|
||||||
<return type-id='eaa32e2f'/>
|
<return type-id='eaa32e2f'/>
|
||||||
|
@ -1166,18 +1148,6 @@
|
||||||
<parameter type-id='eaa32e2f'/>
|
<parameter type-id='eaa32e2f'/>
|
||||||
<return type-id='48b5725f'/>
|
<return type-id='48b5725f'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='memcpy' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='eaa32e2f'/>
|
|
||||||
<parameter type-id='eaa32e2f'/>
|
|
||||||
<parameter type-id='b59d7dce'/>
|
|
||||||
<return type-id='eaa32e2f'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='memset' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='eaa32e2f'/>
|
|
||||||
<parameter type-id='95e97e5e'/>
|
|
||||||
<parameter type-id='b59d7dce'/>
|
|
||||||
<return type-id='eaa32e2f'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='strlen' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='strlen' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
<return type-id='b59d7dce'/>
|
<return type-id='b59d7dce'/>
|
||||||
|
@ -1201,6 +1171,7 @@
|
||||||
<array-type-def dimensions='1' type-id='a84c031d' size-in-bits='512' id='59daf3ef'>
|
<array-type-def dimensions='1' type-id='a84c031d' size-in-bits='512' id='59daf3ef'>
|
||||||
<subrange length='64' type-id='7359adad' id='b10be967'/>
|
<subrange length='64' type-id='7359adad' id='b10be967'/>
|
||||||
</array-type-def>
|
</array-type-def>
|
||||||
|
<type-decl name='int' size-in-bits='32' id='95e97e5e'/>
|
||||||
<type-decl name='long int' size-in-bits='64' id='bd54fe1a'/>
|
<type-decl name='long int' size-in-bits='64' id='bd54fe1a'/>
|
||||||
<type-decl name='short int' size-in-bits='16' id='a2185560'/>
|
<type-decl name='short int' size-in-bits='16' id='a2185560'/>
|
||||||
<type-decl name='signed char' size-in-bits='8' id='28577a57'/>
|
<type-decl name='signed char' size-in-bits='8' id='28577a57'/>
|
||||||
|
@ -1326,6 +1297,7 @@
|
||||||
</data-member>
|
</data-member>
|
||||||
</class-decl>
|
</class-decl>
|
||||||
<typedef-decl name='ulong_t' type-id='7359adad' id='ee1f298e'/>
|
<typedef-decl name='ulong_t' type-id='7359adad' id='ee1f298e'/>
|
||||||
|
<typedef-decl name='uintptr_t' type-id='7359adad' id='e475ab95'/>
|
||||||
<union-decl name='pthread_mutexattr_t' size-in-bits='32' naming-typedef-id='8afd6070' visibility='default' id='7300eb00'>
|
<union-decl name='pthread_mutexattr_t' size-in-bits='32' naming-typedef-id='8afd6070' visibility='default' id='7300eb00'>
|
||||||
<data-member access='public'>
|
<data-member access='public'>
|
||||||
<var-decl name='__size' type-id='8e0573fd' visibility='default'/>
|
<var-decl name='__size' type-id='8e0573fd' visibility='default'/>
|
||||||
|
@ -1388,7 +1360,6 @@
|
||||||
<typedef-decl name='__int8_t' type-id='28577a57' id='2171a512'/>
|
<typedef-decl name='__int8_t' type-id='28577a57' id='2171a512'/>
|
||||||
<typedef-decl name='__uint8_t' type-id='002ac4a6' id='c51d6389'/>
|
<typedef-decl name='__uint8_t' type-id='002ac4a6' id='c51d6389'/>
|
||||||
<typedef-decl name='__uint32_t' type-id='f0981eeb' id='62f1140c'/>
|
<typedef-decl name='__uint32_t' type-id='f0981eeb' id='62f1140c'/>
|
||||||
<typedef-decl name='uintptr_t' type-id='7359adad' id='e475ab95'/>
|
|
||||||
<pointer-type-def type-id='0e01899c' size-in-bits='64' id='4d98cd5a'/>
|
<pointer-type-def type-id='0e01899c' size-in-bits='64' id='4d98cd5a'/>
|
||||||
<pointer-type-def type-id='fba6cb51' size-in-bits='64' id='32adbf30'/>
|
<pointer-type-def type-id='fba6cb51' size-in-bits='64' id='32adbf30'/>
|
||||||
<pointer-type-def type-id='428b67b3' size-in-bits='64' id='bf311473'/>
|
<pointer-type-def type-id='428b67b3' size-in-bits='64' id='bf311473'/>
|
||||||
|
@ -1633,6 +1604,20 @@
|
||||||
<class-decl name='_IO_codecvt' is-struct='yes' visibility='default' is-declaration-only='yes' id='a4036571'/>
|
<class-decl name='_IO_codecvt' is-struct='yes' visibility='default' is-declaration-only='yes' id='a4036571'/>
|
||||||
<class-decl name='_IO_marker' is-struct='yes' visibility='default' is-declaration-only='yes' id='010ae0b9'/>
|
<class-decl name='_IO_marker' is-struct='yes' visibility='default' is-declaration-only='yes' id='010ae0b9'/>
|
||||||
<class-decl name='_IO_wide_data' is-struct='yes' visibility='default' is-declaration-only='yes' id='79bd3751'/>
|
<class-decl name='_IO_wide_data' is-struct='yes' visibility='default' is-declaration-only='yes' id='79bd3751'/>
|
||||||
|
<class-decl name='__va_list_tag' size-in-bits='192' is-struct='yes' visibility='default' id='d5027220'>
|
||||||
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
|
<var-decl name='gp_offset' type-id='f0981eeb' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='32'>
|
||||||
|
<var-decl name='fp_offset' type-id='f0981eeb' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='64'>
|
||||||
|
<var-decl name='overflow_arg_area' type-id='eaa32e2f' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='128'>
|
||||||
|
<var-decl name='reg_save_area' type-id='eaa32e2f' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
</class-decl>
|
||||||
<type-decl name='unnamed-enum-underlying-type-32' is-anonymous='yes' size-in-bits='32' alignment-in-bits='32' id='9cac1fee'/>
|
<type-decl name='unnamed-enum-underlying-type-32' is-anonymous='yes' size-in-bits='32' alignment-in-bits='32' id='9cac1fee'/>
|
||||||
<type-decl name='unsigned short int' size-in-bits='16' id='8efea9e5'/>
|
<type-decl name='unsigned short int' size-in-bits='16' id='8efea9e5'/>
|
||||||
<typedef-decl name='uu_dprintf_t' type-id='0538fe4f' id='2367d595'/>
|
<typedef-decl name='uu_dprintf_t' type-id='0538fe4f' id='2367d595'/>
|
||||||
|
@ -1757,6 +1742,7 @@
|
||||||
<pointer-type-def type-id='bb4788fa' size-in-bits='64' id='cecf4ea7'/>
|
<pointer-type-def type-id='bb4788fa' size-in-bits='64' id='cecf4ea7'/>
|
||||||
<pointer-type-def type-id='010ae0b9' size-in-bits='64' id='e4c6fa61'/>
|
<pointer-type-def type-id='010ae0b9' size-in-bits='64' id='e4c6fa61'/>
|
||||||
<pointer-type-def type-id='79bd3751' size-in-bits='64' id='c65a1f29'/>
|
<pointer-type-def type-id='79bd3751' size-in-bits='64' id='c65a1f29'/>
|
||||||
|
<pointer-type-def type-id='d5027220' size-in-bits='64' id='b7f2d5e6'/>
|
||||||
<qualified-type-def type-id='80f4b756' restrict='yes' id='9d26089a'/>
|
<qualified-type-def type-id='80f4b756' restrict='yes' id='9d26089a'/>
|
||||||
<pointer-type-def type-id='2367d595' size-in-bits='64' id='ed73b5ca'/>
|
<pointer-type-def type-id='2367d595' size-in-bits='64' id='ed73b5ca'/>
|
||||||
<class-decl name='_IO_codecvt' is-struct='yes' visibility='default' is-declaration-only='yes' id='a4036571'/>
|
<class-decl name='_IO_codecvt' is-struct='yes' visibility='default' is-declaration-only='yes' id='a4036571'/>
|
||||||
|
@ -1789,22 +1775,24 @@
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
<return type-id='26a90f95'/>
|
<return type-id='26a90f95'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='fprintf' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='strdup' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='80f4b756'/>
|
||||||
|
<return type-id='26a90f95'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='__fprintf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='e75a27e9'/>
|
<parameter type-id='e75a27e9'/>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
<parameter type-id='9d26089a'/>
|
<parameter type-id='9d26089a'/>
|
||||||
<parameter is-variadic='yes'/>
|
<parameter is-variadic='yes'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='vfprintf' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='__vfprintf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='e75a27e9'/>
|
<parameter type-id='e75a27e9'/>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
<parameter type-id='9d26089a'/>
|
<parameter type-id='9d26089a'/>
|
||||||
<parameter type-id='b7f2d5e6'/>
|
<parameter type-id='b7f2d5e6'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='strdup' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<return type-id='26a90f95'/>
|
|
||||||
</function-decl>
|
|
||||||
</abi-instr>
|
</abi-instr>
|
||||||
<abi-instr address-size='64' path='uu_ident.c' language='LANG_C99'>
|
<abi-instr address-size='64' path='uu_ident.c' language='LANG_C99'>
|
||||||
<function-decl name='strchr' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='strchr' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
@ -2144,13 +2132,6 @@
|
||||||
<parameter type-id='3502e3ff' name='uflags'/>
|
<parameter type-id='3502e3ff' name='uflags'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='snprintf' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='26a90f95'/>
|
|
||||||
<parameter type-id='b59d7dce'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter is-variadic='yes'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='clock_gettime' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='clock_gettime' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='a1c3b834'/>
|
<parameter type-id='a1c3b834'/>
|
||||||
<parameter type-id='3d83ba87'/>
|
<parameter type-id='3d83ba87'/>
|
||||||
|
@ -2160,6 +2141,12 @@
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
|
<function-decl name='__open_too_many_args' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<return type-id='48b5725f'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='__open_missing_mode' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<return type-id='48b5725f'/>
|
||||||
|
</function-decl>
|
||||||
</abi-instr>
|
</abi-instr>
|
||||||
<abi-instr address-size='64' path='uu_pname.c' language='LANG_C99'>
|
<abi-instr address-size='64' path='uu_pname.c' language='LANG_C99'>
|
||||||
<function-decl name='getexecname' mangled-name='getexecname' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='getexecname'>
|
<function-decl name='getexecname' mangled-name='getexecname' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='getexecname'>
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
<abi-corpus version='2.0' architecture='elf-amd-x86_64' soname='libzfs.so.4'>
|
<abi-corpus version='2.0' architecture='elf-amd-x86_64' soname='libzfs.so.4'>
|
||||||
<elf-needed>
|
<elf-needed>
|
||||||
<dependency name='libzfs_core.so.3'/>
|
<dependency name='libzfs_core.so.3'/>
|
||||||
<dependency name='libuuid.so.1'/>
|
|
||||||
<dependency name='libblkid.so.1'/>
|
|
||||||
<dependency name='libudev.so.1'/>
|
|
||||||
<dependency name='libnvpair.so.3'/>
|
<dependency name='libnvpair.so.3'/>
|
||||||
<dependency name='libtirpc.so.3'/>
|
|
||||||
<dependency name='libuutil.so.3'/>
|
<dependency name='libuutil.so.3'/>
|
||||||
<dependency name='libm.so.6'/>
|
<dependency name='libm.so.6'/>
|
||||||
<dependency name='libcrypto.so.1.1'/>
|
<dependency name='libcrypto.so.3'/>
|
||||||
<dependency name='libz.so.1'/>
|
<dependency name='libz.so.1'/>
|
||||||
<dependency name='libc.so.6'/>
|
<dependency name='libc.so.6'/>
|
||||||
</elf-needed>
|
</elf-needed>
|
||||||
|
@ -536,11 +532,6 @@
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='fputs' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='9d26089a'/>
|
|
||||||
<parameter type-id='e75a27e9'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='flock' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='flock' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
|
@ -599,8 +590,9 @@
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
<return type-id='f09217ba'/>
|
<return type-id='f09217ba'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='fgets' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='__fgets_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='266fe297'/>
|
<parameter type-id='266fe297'/>
|
||||||
|
<parameter type-id='b59d7dce'/>
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
<parameter type-id='e75a27e9'/>
|
<parameter type-id='e75a27e9'/>
|
||||||
<return type-id='26a90f95'/>
|
<return type-id='26a90f95'/>
|
||||||
|
@ -1369,7 +1361,7 @@
|
||||||
<typedef-decl name='zpool_handle_t' type-id='67002a8a' id='b1efc708'/>
|
<typedef-decl name='zpool_handle_t' type-id='67002a8a' id='b1efc708'/>
|
||||||
<typedef-decl name='libzfs_handle_t' type-id='c8a9d9d8' id='95942d0c'/>
|
<typedef-decl name='libzfs_handle_t' type-id='c8a9d9d8' id='95942d0c'/>
|
||||||
<typedef-decl name='zfs_iter_f' type-id='5571cde4' id='d8e49ab9'/>
|
<typedef-decl name='zfs_iter_f' type-id='5571cde4' id='d8e49ab9'/>
|
||||||
<class-decl name='libzfs_handle' size-in-bits='20352' is-struct='yes' visibility='default' id='c8a9d9d8'>
|
<class-decl name='libzfs_handle' size-in-bits='20416' is-struct='yes' visibility='default' id='c8a9d9d8'>
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
<var-decl name='libzfs_error' type-id='95e97e5e' visibility='default'/>
|
<var-decl name='libzfs_error' type-id='95e97e5e' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
|
@ -1436,6 +1428,9 @@
|
||||||
<data-member access='public' layout-offset-in-bits='20288'>
|
<data-member access='public' layout-offset-in-bits='20288'>
|
||||||
<var-decl name='libfetch_load_error' type-id='26a90f95' visibility='default'/>
|
<var-decl name='libfetch_load_error' type-id='26a90f95' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='20352'>
|
||||||
|
<var-decl name='libzfs_force_export' type-id='c19b74c3' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
</class-decl>
|
</class-decl>
|
||||||
<class-decl name='zfs_handle' size-in-bits='4928' is-struct='yes' visibility='default' id='f6ee4445'>
|
<class-decl name='zfs_handle' size-in-bits='4928' is-struct='yes' visibility='default' id='f6ee4445'>
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
|
@ -1760,6 +1755,54 @@
|
||||||
<var-decl name='cl_haszonedchild' type-id='c19b74c3' visibility='default'/>
|
<var-decl name='cl_haszonedchild' type-id='c19b74c3' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
</class-decl>
|
</class-decl>
|
||||||
|
<typedef-decl name='__re_long_size_t' type-id='7359adad' id='ba516949'/>
|
||||||
|
<typedef-decl name='reg_syntax_t' type-id='7359adad' id='1b72c3b3'/>
|
||||||
|
<class-decl name='re_pattern_buffer' size-in-bits='512' is-struct='yes' visibility='default' id='19fc9a8c'>
|
||||||
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
|
<var-decl name='buffer' type-id='33976309' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='64'>
|
||||||
|
<var-decl name='allocated' type-id='ba516949' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='128'>
|
||||||
|
<var-decl name='used' type-id='ba516949' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='192'>
|
||||||
|
<var-decl name='syntax' type-id='1b72c3b3' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='256'>
|
||||||
|
<var-decl name='fastmap' type-id='26a90f95' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='320'>
|
||||||
|
<var-decl name='translate' type-id='cf536864' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='384'>
|
||||||
|
<var-decl name='re_nsub' type-id='b59d7dce' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='448'>
|
||||||
|
<var-decl name='can_be_null' type-id='f0981eeb' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='449'>
|
||||||
|
<var-decl name='regs_allocated' type-id='f0981eeb' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='451'>
|
||||||
|
<var-decl name='fastmap_accurate' type-id='f0981eeb' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='452'>
|
||||||
|
<var-decl name='no_sub' type-id='f0981eeb' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='453'>
|
||||||
|
<var-decl name='not_bol' type-id='f0981eeb' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='454'>
|
||||||
|
<var-decl name='not_eol' type-id='f0981eeb' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='455'>
|
||||||
|
<var-decl name='newline_anchor' type-id='f0981eeb' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
</class-decl>
|
||||||
|
<typedef-decl name='regex_t' type-id='19fc9a8c' id='aca3bac8'/>
|
||||||
|
<typedef-decl name='uintptr_t' type-id='7359adad' id='e475ab95'/>
|
||||||
<union-decl name='pthread_mutex_t' size-in-bits='320' naming-typedef-id='7a6844eb' visibility='default' id='70681f9b'>
|
<union-decl name='pthread_mutex_t' size-in-bits='320' naming-typedef-id='7a6844eb' visibility='default' id='70681f9b'>
|
||||||
<data-member access='public'>
|
<data-member access='public'>
|
||||||
<var-decl name='__data' type-id='4c734837' visibility='default'/>
|
<var-decl name='__data' type-id='4c734837' visibility='default'/>
|
||||||
|
@ -1908,54 +1951,6 @@
|
||||||
<var-decl name='_unused2' type-id='664ac0b7' visibility='default'/>
|
<var-decl name='_unused2' type-id='664ac0b7' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
</class-decl>
|
</class-decl>
|
||||||
<typedef-decl name='__re_long_size_t' type-id='7359adad' id='ba516949'/>
|
|
||||||
<typedef-decl name='reg_syntax_t' type-id='7359adad' id='1b72c3b3'/>
|
|
||||||
<class-decl name='re_pattern_buffer' size-in-bits='512' is-struct='yes' visibility='default' id='19fc9a8c'>
|
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
|
||||||
<var-decl name='buffer' type-id='33976309' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='64'>
|
|
||||||
<var-decl name='allocated' type-id='ba516949' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='128'>
|
|
||||||
<var-decl name='used' type-id='ba516949' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='192'>
|
|
||||||
<var-decl name='syntax' type-id='1b72c3b3' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='256'>
|
|
||||||
<var-decl name='fastmap' type-id='26a90f95' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='320'>
|
|
||||||
<var-decl name='translate' type-id='cf536864' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='384'>
|
|
||||||
<var-decl name='re_nsub' type-id='b59d7dce' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='448'>
|
|
||||||
<var-decl name='can_be_null' type-id='f0981eeb' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='449'>
|
|
||||||
<var-decl name='regs_allocated' type-id='f0981eeb' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='451'>
|
|
||||||
<var-decl name='fastmap_accurate' type-id='f0981eeb' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='452'>
|
|
||||||
<var-decl name='no_sub' type-id='f0981eeb' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='453'>
|
|
||||||
<var-decl name='not_bol' type-id='f0981eeb' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='454'>
|
|
||||||
<var-decl name='not_eol' type-id='f0981eeb' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='455'>
|
|
||||||
<var-decl name='newline_anchor' type-id='f0981eeb' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
</class-decl>
|
|
||||||
<typedef-decl name='regex_t' type-id='19fc9a8c' id='aca3bac8'/>
|
|
||||||
<typedef-decl name='uintptr_t' type-id='7359adad' id='e475ab95'/>
|
|
||||||
<typedef-decl name='size_t' type-id='7359adad' id='b59d7dce'/>
|
<typedef-decl name='size_t' type-id='7359adad' id='b59d7dce'/>
|
||||||
<pointer-type-def type-id='aa12d1ba' size-in-bits='64' id='822cd80b'/>
|
<pointer-type-def type-id='aa12d1ba' size-in-bits='64' id='822cd80b'/>
|
||||||
<pointer-type-def type-id='ec1ed955' size-in-bits='64' id='dca988a5'/>
|
<pointer-type-def type-id='ec1ed955' size-in-bits='64' id='dca988a5'/>
|
||||||
|
@ -2734,11 +2729,6 @@
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
<return type-id='26a90f95'/>
|
<return type-id='26a90f95'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='strcpy' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='26a90f95'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<return type-id='26a90f95'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='strchr' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='strchr' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
|
@ -2800,6 +2790,18 @@
|
||||||
</enum-decl>
|
</enum-decl>
|
||||||
<typedef-decl name='zpool_prop_t' type-id='af1ba157' id='5d0c23fb'/>
|
<typedef-decl name='zpool_prop_t' type-id='af1ba157' id='5d0c23fb'/>
|
||||||
<typedef-decl name='uint_t' type-id='f0981eeb' id='3502e3ff'/>
|
<typedef-decl name='uint_t' type-id='f0981eeb' id='3502e3ff'/>
|
||||||
|
<typedef-decl name='regoff_t' type-id='95e97e5e' id='54a2a2a8'/>
|
||||||
|
<class-decl name='regmatch_t' size-in-bits='64' is-struct='yes' naming-typedef-id='1b941664' visibility='default' id='4f932615'>
|
||||||
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
|
<var-decl name='rm_so' type-id='54a2a2a8' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='32'>
|
||||||
|
<var-decl name='rm_eo' type-id='54a2a2a8' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
</class-decl>
|
||||||
|
<typedef-decl name='regmatch_t' type-id='4f932615' id='1b941664'/>
|
||||||
|
<typedef-decl name='__sighandler_t' type-id='03347643' id='8cdd9566'/>
|
||||||
|
<typedef-decl name='ssize_t' type-id='41060289' id='79a0948f'/>
|
||||||
<class-decl name='sigaction' size-in-bits='1216' is-struct='yes' visibility='default' id='fe391c48'>
|
<class-decl name='sigaction' size-in-bits='1216' is-struct='yes' visibility='default' id='fe391c48'>
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
<var-decl name='__sigaction_handler' type-id='ac5ab598' visibility='default'/>
|
<var-decl name='__sigaction_handler' type-id='ac5ab598' visibility='default'/>
|
||||||
|
@ -3008,18 +3010,6 @@
|
||||||
</class-decl>
|
</class-decl>
|
||||||
<typedef-decl name='siginfo_t' type-id='d8149419' id='cb681f62'/>
|
<typedef-decl name='siginfo_t' type-id='d8149419' id='cb681f62'/>
|
||||||
<typedef-decl name='sigset_t' type-id='b9c97942' id='daf33c64'/>
|
<typedef-decl name='sigset_t' type-id='b9c97942' id='daf33c64'/>
|
||||||
<typedef-decl name='regoff_t' type-id='95e97e5e' id='54a2a2a8'/>
|
|
||||||
<class-decl name='regmatch_t' size-in-bits='64' is-struct='yes' naming-typedef-id='1b941664' visibility='default' id='4f932615'>
|
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
|
||||||
<var-decl name='rm_so' type-id='54a2a2a8' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='32'>
|
|
||||||
<var-decl name='rm_eo' type-id='54a2a2a8' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
</class-decl>
|
|
||||||
<typedef-decl name='regmatch_t' type-id='4f932615' id='1b941664'/>
|
|
||||||
<typedef-decl name='__sighandler_t' type-id='03347643' id='8cdd9566'/>
|
|
||||||
<typedef-decl name='ssize_t' type-id='41060289' id='79a0948f'/>
|
|
||||||
<qualified-type-def type-id='822cd80b' restrict='yes' id='e75a27e9'/>
|
<qualified-type-def type-id='822cd80b' restrict='yes' id='e75a27e9'/>
|
||||||
<qualified-type-def type-id='9b23c9ad' restrict='yes' id='8c85230f'/>
|
<qualified-type-def type-id='9b23c9ad' restrict='yes' id='8c85230f'/>
|
||||||
<qualified-type-def type-id='80f4b756' restrict='yes' id='9d26089a'/>
|
<qualified-type-def type-id='80f4b756' restrict='yes' id='9d26089a'/>
|
||||||
|
@ -3251,24 +3241,6 @@
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
<return type-id='822cd80b'/>
|
<return type-id='822cd80b'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='printf' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter is-variadic='yes'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='snprintf' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='26a90f95'/>
|
|
||||||
<parameter type-id='b59d7dce'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter is-variadic='yes'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='asprintf' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='8c85230f'/>
|
|
||||||
<parameter type-id='9d26089a'/>
|
|
||||||
<parameter is-variadic='yes'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='fputc' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='fputc' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
<parameter type-id='822cd80b'/>
|
<parameter type-id='822cd80b'/>
|
||||||
|
@ -3281,13 +3253,6 @@
|
||||||
<parameter type-id='e75a27e9'/>
|
<parameter type-id='e75a27e9'/>
|
||||||
<return type-id='41060289'/>
|
<return type-id='41060289'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='fread' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='1b7446cd'/>
|
|
||||||
<parameter type-id='b59d7dce'/>
|
|
||||||
<parameter type-id='b59d7dce'/>
|
|
||||||
<parameter type-id='e75a27e9'/>
|
|
||||||
<return type-id='b59d7dce'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='rewind' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='rewind' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='822cd80b'/>
|
<parameter type-id='822cd80b'/>
|
||||||
<return type-id='48b5725f'/>
|
<return type-id='48b5725f'/>
|
||||||
|
@ -3309,12 +3274,6 @@
|
||||||
<parameter type-id='b59d7dce'/>
|
<parameter type-id='b59d7dce'/>
|
||||||
<return type-id='eaa32e2f'/>
|
<return type-id='eaa32e2f'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='memcpy' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='eaa32e2f'/>
|
|
||||||
<parameter type-id='eaa32e2f'/>
|
|
||||||
<parameter type-id='b59d7dce'/>
|
|
||||||
<return type-id='eaa32e2f'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='strdup' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='strdup' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
<return type-id='26a90f95'/>
|
<return type-id='26a90f95'/>
|
||||||
|
@ -3338,12 +3297,6 @@
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='read' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='95e97e5e'/>
|
|
||||||
<parameter type-id='eaa32e2f'/>
|
|
||||||
<parameter type-id='b59d7dce'/>
|
|
||||||
<return type-id='79a0948f'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='getpid' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='getpid' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<return type-id='3629bad8'/>
|
<return type-id='3629bad8'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
|
@ -3355,6 +3308,40 @@
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
|
<function-decl name='__open_too_many_args' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<return type-id='48b5725f'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='__open_missing_mode' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<return type-id='48b5725f'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='__printf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<parameter type-id='80f4b756'/>
|
||||||
|
<parameter is-variadic='yes'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='__asprintf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='8c85230f'/>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<parameter type-id='9d26089a'/>
|
||||||
|
<parameter is-variadic='yes'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='__fread_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='1b7446cd'/>
|
||||||
|
<parameter type-id='b59d7dce'/>
|
||||||
|
<parameter type-id='b59d7dce'/>
|
||||||
|
<parameter type-id='b59d7dce'/>
|
||||||
|
<parameter type-id='e75a27e9'/>
|
||||||
|
<return type-id='b59d7dce'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='__read_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<parameter type-id='eaa32e2f'/>
|
||||||
|
<parameter type-id='b59d7dce'/>
|
||||||
|
<parameter type-id='b59d7dce'/>
|
||||||
|
<return type-id='79a0948f'/>
|
||||||
|
</function-decl>
|
||||||
<function-type size-in-bits='64' id='ee076206'>
|
<function-type size-in-bits='64' id='ee076206'>
|
||||||
<return type-id='48b5725f'/>
|
<return type-id='48b5725f'/>
|
||||||
</function-type>
|
</function-type>
|
||||||
|
@ -3399,13 +3386,13 @@
|
||||||
<typedef-decl name='zprop_list_t' type-id='bd9b4291' id='bdb8ac4f'/>
|
<typedef-decl name='zprop_list_t' type-id='bd9b4291' id='bdb8ac4f'/>
|
||||||
<class-decl name='renameflags' size-in-bits='32' is-struct='yes' visibility='default' id='7aee5792'>
|
<class-decl name='renameflags' size-in-bits='32' is-struct='yes' visibility='default' id='7aee5792'>
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
<var-decl name='recursive' type-id='95e97e5e' visibility='default'/>
|
<var-decl name='recursive' type-id='f0981eeb' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
<data-member access='public' layout-offset-in-bits='1'>
|
<data-member access='public' layout-offset-in-bits='1'>
|
||||||
<var-decl name='nounmount' type-id='95e97e5e' visibility='default'/>
|
<var-decl name='nounmount' type-id='f0981eeb' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
<data-member access='public' layout-offset-in-bits='2'>
|
<data-member access='public' layout-offset-in-bits='2'>
|
||||||
<var-decl name='forceunmount' type-id='95e97e5e' visibility='default'/>
|
<var-decl name='forceunmount' type-id='f0981eeb' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
</class-decl>
|
</class-decl>
|
||||||
<typedef-decl name='renameflags_t' type-id='7aee5792' id='067170c2'/>
|
<typedef-decl name='renameflags_t' type-id='7aee5792' id='067170c2'/>
|
||||||
|
@ -3477,55 +3464,6 @@
|
||||||
<var-decl name='mnt_mntopts' type-id='26a90f95' visibility='default'/>
|
<var-decl name='mnt_mntopts' type-id='26a90f95' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
</class-decl>
|
</class-decl>
|
||||||
<union-decl name='pthread_mutexattr_t' size-in-bits='32' naming-typedef-id='8afd6070' visibility='default' id='7300eb00'>
|
|
||||||
<data-member access='public'>
|
|
||||||
<var-decl name='__size' type-id='8e0573fd' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public'>
|
|
||||||
<var-decl name='__align' type-id='95e97e5e' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
</union-decl>
|
|
||||||
<typedef-decl name='pthread_mutexattr_t' type-id='7300eb00' id='8afd6070'/>
|
|
||||||
<typedef-decl name='int64_t' type-id='0c9942d2' id='9da381c4'/>
|
|
||||||
<typedef-decl name='__int64_t' type-id='bd54fe1a' id='0c9942d2'/>
|
|
||||||
<typedef-decl name='__gid_t' type-id='f0981eeb' id='d94ec6d9'/>
|
|
||||||
<typedef-decl name='__time_t' type-id='bd54fe1a' id='65eda9c0'/>
|
|
||||||
<class-decl name='tm' size-in-bits='448' is-struct='yes' visibility='default' id='dddf6ca2'>
|
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
|
||||||
<var-decl name='tm_sec' type-id='95e97e5e' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='32'>
|
|
||||||
<var-decl name='tm_min' type-id='95e97e5e' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='64'>
|
|
||||||
<var-decl name='tm_hour' type-id='95e97e5e' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='96'>
|
|
||||||
<var-decl name='tm_mday' type-id='95e97e5e' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='128'>
|
|
||||||
<var-decl name='tm_mon' type-id='95e97e5e' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='160'>
|
|
||||||
<var-decl name='tm_year' type-id='95e97e5e' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='192'>
|
|
||||||
<var-decl name='tm_wday' type-id='95e97e5e' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='224'>
|
|
||||||
<var-decl name='tm_yday' type-id='95e97e5e' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='256'>
|
|
||||||
<var-decl name='tm_isdst' type-id='95e97e5e' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='320'>
|
|
||||||
<var-decl name='tm_gmtoff' type-id='bd54fe1a' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='384'>
|
|
||||||
<var-decl name='tm_zone' type-id='80f4b756' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
</class-decl>
|
|
||||||
<typedef-decl name='time_t' type-id='65eda9c0' id='c9d12d66'/>
|
|
||||||
<class-decl name='group' size-in-bits='256' is-struct='yes' visibility='default' id='01a1b934'>
|
<class-decl name='group' size-in-bits='256' is-struct='yes' visibility='default' id='01a1b934'>
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
<var-decl name='gr_name' type-id='26a90f95' visibility='default'/>
|
<var-decl name='gr_name' type-id='26a90f95' visibility='default'/>
|
||||||
|
@ -3583,6 +3521,55 @@
|
||||||
<var-decl name='pw_shell' type-id='26a90f95' visibility='default'/>
|
<var-decl name='pw_shell' type-id='26a90f95' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
</class-decl>
|
</class-decl>
|
||||||
|
<union-decl name='pthread_mutexattr_t' size-in-bits='32' naming-typedef-id='8afd6070' visibility='default' id='7300eb00'>
|
||||||
|
<data-member access='public'>
|
||||||
|
<var-decl name='__size' type-id='8e0573fd' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public'>
|
||||||
|
<var-decl name='__align' type-id='95e97e5e' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
</union-decl>
|
||||||
|
<typedef-decl name='pthread_mutexattr_t' type-id='7300eb00' id='8afd6070'/>
|
||||||
|
<typedef-decl name='int64_t' type-id='0c9942d2' id='9da381c4'/>
|
||||||
|
<typedef-decl name='__int64_t' type-id='bd54fe1a' id='0c9942d2'/>
|
||||||
|
<typedef-decl name='__gid_t' type-id='f0981eeb' id='d94ec6d9'/>
|
||||||
|
<typedef-decl name='__time_t' type-id='bd54fe1a' id='65eda9c0'/>
|
||||||
|
<class-decl name='tm' size-in-bits='448' is-struct='yes' visibility='default' id='dddf6ca2'>
|
||||||
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
|
<var-decl name='tm_sec' type-id='95e97e5e' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='32'>
|
||||||
|
<var-decl name='tm_min' type-id='95e97e5e' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='64'>
|
||||||
|
<var-decl name='tm_hour' type-id='95e97e5e' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='96'>
|
||||||
|
<var-decl name='tm_mday' type-id='95e97e5e' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='128'>
|
||||||
|
<var-decl name='tm_mon' type-id='95e97e5e' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='160'>
|
||||||
|
<var-decl name='tm_year' type-id='95e97e5e' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='192'>
|
||||||
|
<var-decl name='tm_wday' type-id='95e97e5e' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='224'>
|
||||||
|
<var-decl name='tm_yday' type-id='95e97e5e' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='256'>
|
||||||
|
<var-decl name='tm_isdst' type-id='95e97e5e' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='320'>
|
||||||
|
<var-decl name='tm_gmtoff' type-id='bd54fe1a' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='384'>
|
||||||
|
<var-decl name='tm_zone' type-id='80f4b756' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
</class-decl>
|
||||||
|
<typedef-decl name='time_t' type-id='65eda9c0' id='c9d12d66'/>
|
||||||
<typedef-decl name='uid_t' type-id='cc5fcceb' id='354978ed'/>
|
<typedef-decl name='uid_t' type-id='cc5fcceb' id='354978ed'/>
|
||||||
<pointer-type-def type-id='fba6cb51' size-in-bits='64' id='32adbf30'/>
|
<pointer-type-def type-id='fba6cb51' size-in-bits='64' id='32adbf30'/>
|
||||||
<pointer-type-def type-id='f20fbd51' size-in-bits='64' id='a3681dea'/>
|
<pointer-type-def type-id='f20fbd51' size-in-bits='64' id='a3681dea'/>
|
||||||
|
@ -4457,12 +4444,6 @@
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
<return type-id='a195f4a3'/>
|
<return type-id='a195f4a3'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='fprintf' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='e75a27e9'/>
|
|
||||||
<parameter type-id='9d26089a'/>
|
|
||||||
<parameter is-variadic='yes'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='strtol' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='strtol' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='9d26089a'/>
|
<parameter type-id='9d26089a'/>
|
||||||
<parameter type-id='8c85230f'/>
|
<parameter type-id='8c85230f'/>
|
||||||
|
@ -4478,12 +4459,6 @@
|
||||||
<function-decl name='abort' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='abort' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<return type-id='48b5725f'/>
|
<return type-id='48b5725f'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='strncpy' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='26a90f95'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='b59d7dce'/>
|
|
||||||
<return type-id='26a90f95'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='strrchr' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='strrchr' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
|
@ -4504,12 +4479,6 @@
|
||||||
<parameter type-id='9d26089a'/>
|
<parameter type-id='9d26089a'/>
|
||||||
<return type-id='26a90f95'/>
|
<return type-id='26a90f95'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='ioctl' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='95e97e5e'/>
|
|
||||||
<parameter type-id='7359adad'/>
|
|
||||||
<parameter is-variadic='yes'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='strftime' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='strftime' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='266fe297'/>
|
<parameter type-id='266fe297'/>
|
||||||
<parameter type-id='b59d7dce'/>
|
<parameter type-id='b59d7dce'/>
|
||||||
|
@ -4522,6 +4491,19 @@
|
||||||
<parameter type-id='f099ad08'/>
|
<parameter type-id='f099ad08'/>
|
||||||
<return type-id='d915a820'/>
|
<return type-id='d915a820'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
|
<function-decl name='__fprintf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='e75a27e9'/>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<parameter type-id='9d26089a'/>
|
||||||
|
<parameter is-variadic='yes'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='ioctl' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<parameter type-id='7359adad'/>
|
||||||
|
<parameter is-variadic='yes'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
<function-type size-in-bits='64' id='7e291ce6'>
|
<function-type size-in-bits='64' id='7e291ce6'>
|
||||||
<parameter type-id='eaa32e2f'/>
|
<parameter type-id='eaa32e2f'/>
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
|
@ -4534,7 +4516,7 @@
|
||||||
<array-type-def dimensions='1' type-id='a84c031d' size-in-bits='448' id='6093ff7c'>
|
<array-type-def dimensions='1' type-id='a84c031d' size-in-bits='448' id='6093ff7c'>
|
||||||
<subrange length='56' type-id='7359adad' id='f8137894'/>
|
<subrange length='56' type-id='7359adad' id='f8137894'/>
|
||||||
</array-type-def>
|
</array-type-def>
|
||||||
<class-decl name='differ_info' size-in-bits='9024' is-struct='yes' visibility='default' id='d41965ee'>
|
<class-decl name='differ_info' size-in-bits='9088' is-struct='yes' visibility='default' id='d41965ee'>
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
<var-decl name='zhp' type-id='9200a744' visibility='default'/>
|
<var-decl name='zhp' type-id='9200a744' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
|
@ -4575,18 +4557,21 @@
|
||||||
<var-decl name='timestamped' type-id='c19b74c3' visibility='default'/>
|
<var-decl name='timestamped' type-id='c19b74c3' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
<data-member access='public' layout-offset-in-bits='8832'>
|
<data-member access='public' layout-offset-in-bits='8832'>
|
||||||
<var-decl name='shares' type-id='9c313c2d' visibility='default'/>
|
<var-decl name='no_mangle' type-id='c19b74c3' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
<data-member access='public' layout-offset-in-bits='8896'>
|
<data-member access='public' layout-offset-in-bits='8896'>
|
||||||
<var-decl name='zerr' type-id='95e97e5e' visibility='default'/>
|
<var-decl name='shares' type-id='9c313c2d' visibility='default'/>
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='8928'>
|
|
||||||
<var-decl name='cleanupfd' type-id='95e97e5e' visibility='default'/>
|
|
||||||
</data-member>
|
</data-member>
|
||||||
<data-member access='public' layout-offset-in-bits='8960'>
|
<data-member access='public' layout-offset-in-bits='8960'>
|
||||||
<var-decl name='outputfd' type-id='95e97e5e' visibility='default'/>
|
<var-decl name='zerr' type-id='95e97e5e' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
<data-member access='public' layout-offset-in-bits='8992'>
|
<data-member access='public' layout-offset-in-bits='8992'>
|
||||||
|
<var-decl name='cleanupfd' type-id='95e97e5e' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='9024'>
|
||||||
|
<var-decl name='outputfd' type-id='95e97e5e' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='9056'>
|
||||||
<var-decl name='datafd' type-id='95e97e5e' visibility='default'/>
|
<var-decl name='datafd' type-id='95e97e5e' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
</class-decl>
|
</class-decl>
|
||||||
|
@ -4624,6 +4609,13 @@
|
||||||
<parameter type-id='ee78f675'/>
|
<parameter type-id='ee78f675'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
|
<function-decl name='color_start' mangled-name='color_start' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='color_start'>
|
||||||
|
<parameter type-id='80f4b756'/>
|
||||||
|
<return type-id='48b5725f'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='color_end' mangled-name='color_end' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='color_end'>
|
||||||
|
<return type-id='48b5725f'/>
|
||||||
|
</function-decl>
|
||||||
<function-decl name='zfs_show_diffs' mangled-name='zfs_show_diffs' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_show_diffs'>
|
<function-decl name='zfs_show_diffs' mangled-name='zfs_show_diffs' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_show_diffs'>
|
||||||
<parameter type-id='9200a744' name='zhp'/>
|
<parameter type-id='9200a744' name='zhp'/>
|
||||||
<parameter type-id='95e97e5e' name='outfd'/>
|
<parameter type-id='95e97e5e' name='outfd'/>
|
||||||
|
@ -4648,6 +4640,11 @@
|
||||||
<parameter type-id='4051f5e7'/>
|
<parameter type-id='4051f5e7'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
|
<function-decl name='fputs' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='9d26089a'/>
|
||||||
|
<parameter type-id='e75a27e9'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
<function-decl name='pipe2' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='pipe2' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='7292109c'/>
|
<parameter type-id='7292109c'/>
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
|
@ -4777,24 +4774,6 @@
|
||||||
<parameter type-id='37e3bd22' name='inuse'/>
|
<parameter type-id='37e3bd22' name='inuse'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='memset' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='eaa32e2f'/>
|
|
||||||
<parameter type-id='95e97e5e'/>
|
|
||||||
<parameter type-id='b59d7dce'/>
|
|
||||||
<return type-id='eaa32e2f'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='fstat64' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='95e97e5e'/>
|
|
||||||
<parameter type-id='62f7a03d'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='pread64' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='95e97e5e'/>
|
|
||||||
<parameter type-id='eaa32e2f'/>
|
|
||||||
<parameter type-id='b59d7dce'/>
|
|
||||||
<parameter type-id='724e4de6'/>
|
|
||||||
<return type-id='79a0948f'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='pwrite64' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='pwrite64' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
<parameter type-id='eaa32e2f'/>
|
<parameter type-id='eaa32e2f'/>
|
||||||
|
@ -4802,6 +4781,19 @@
|
||||||
<parameter type-id='724e4de6'/>
|
<parameter type-id='724e4de6'/>
|
||||||
<return type-id='79a0948f'/>
|
<return type-id='79a0948f'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
|
<function-decl name='__pread64_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<parameter type-id='eaa32e2f'/>
|
||||||
|
<parameter type-id='b59d7dce'/>
|
||||||
|
<parameter type-id='724e4de6'/>
|
||||||
|
<parameter type-id='b59d7dce'/>
|
||||||
|
<return type-id='79a0948f'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='fstat64' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<parameter type-id='62f7a03d'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
<function-type size-in-bits='64' id='baa42fef'>
|
<function-type size-in-bits='64' id='baa42fef'>
|
||||||
<parameter type-id='eaa32e2f'/>
|
<parameter type-id='eaa32e2f'/>
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
|
@ -4900,6 +4892,9 @@
|
||||||
</class-decl>
|
</class-decl>
|
||||||
<typedef-decl name='proto_table_t' type-id='f4c8e1ed' id='f1bd64e2'/>
|
<typedef-decl name='proto_table_t' type-id='f4c8e1ed' id='f1bd64e2'/>
|
||||||
<typedef-decl name='tpool_t' type-id='88d1b7f9' id='b1bbf10d'/>
|
<typedef-decl name='tpool_t' type-id='88d1b7f9' id='b1bbf10d'/>
|
||||||
|
<typedef-decl name='DIR' type-id='20cd73f2' id='54a5d683'/>
|
||||||
|
<typedef-decl name='mode_t' type-id='e1c52942' id='d50d396c'/>
|
||||||
|
<typedef-decl name='__compar_fn_t' type-id='585e1de9' id='aba7edd8'/>
|
||||||
<class-decl name='dirent64' size-in-bits='2240' is-struct='yes' visibility='default' id='5725d813'>
|
<class-decl name='dirent64' size-in-bits='2240' is-struct='yes' visibility='default' id='5725d813'>
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
<var-decl name='d_ino' type-id='71288a47' visibility='default'/>
|
<var-decl name='d_ino' type-id='71288a47' visibility='default'/>
|
||||||
|
@ -5013,9 +5008,6 @@
|
||||||
<typedef-decl name='__fsblkcnt64_t' type-id='7359adad' id='95fe1a02'/>
|
<typedef-decl name='__fsblkcnt64_t' type-id='7359adad' id='95fe1a02'/>
|
||||||
<typedef-decl name='__fsfilcnt64_t' type-id='7359adad' id='0c3a4dde'/>
|
<typedef-decl name='__fsfilcnt64_t' type-id='7359adad' id='0c3a4dde'/>
|
||||||
<typedef-decl name='__fsword_t' type-id='bd54fe1a' id='6028cbfe'/>
|
<typedef-decl name='__fsword_t' type-id='bd54fe1a' id='6028cbfe'/>
|
||||||
<typedef-decl name='DIR' type-id='20cd73f2' id='54a5d683'/>
|
|
||||||
<typedef-decl name='mode_t' type-id='e1c52942' id='d50d396c'/>
|
|
||||||
<typedef-decl name='__compar_fn_t' type-id='585e1de9' id='aba7edd8'/>
|
|
||||||
<pointer-type-def type-id='54a5d683' size-in-bits='64' id='f09217ba'/>
|
<pointer-type-def type-id='54a5d683' size-in-bits='64' id='f09217ba'/>
|
||||||
<pointer-type-def type-id='5725d813' size-in-bits='64' id='07b96073'/>
|
<pointer-type-def type-id='5725d813' size-in-bits='64' id='07b96073'/>
|
||||||
<pointer-type-def type-id='9b293607' size-in-bits='64' id='77bf1784'/>
|
<pointer-type-def type-id='9b293607' size-in-bits='64' id='77bf1784'/>
|
||||||
|
@ -5235,15 +5227,21 @@
|
||||||
<parameter type-id='aba7edd8'/>
|
<parameter type-id='aba7edd8'/>
|
||||||
<return type-id='48b5725f'/>
|
<return type-id='48b5725f'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
|
<function-decl name='rmdir' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='80f4b756'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='__openat_too_many_args' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<return type-id='48b5725f'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='__openat_missing_mode' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<return type-id='48b5725f'/>
|
||||||
|
</function-decl>
|
||||||
<function-decl name='statfs64' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='statfs64' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
<parameter type-id='7fd094c8'/>
|
<parameter type-id='7fd094c8'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='rmdir' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-type size-in-bits='64' id='c5c76c9c'>
|
<function-type size-in-bits='64' id='c5c76c9c'>
|
||||||
<parameter type-id='eaa32e2f'/>
|
<parameter type-id='eaa32e2f'/>
|
||||||
<return type-id='48b5725f'/>
|
<return type-id='48b5725f'/>
|
||||||
|
@ -5253,10 +5251,10 @@
|
||||||
<type-decl name='long long unsigned int' size-in-bits='64' id='3a47d82b'/>
|
<type-decl name='long long unsigned int' size-in-bits='64' id='3a47d82b'/>
|
||||||
<class-decl name='splitflags' size-in-bits='64' is-struct='yes' visibility='default' id='dc01bf52'>
|
<class-decl name='splitflags' size-in-bits='64' is-struct='yes' visibility='default' id='dc01bf52'>
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
<var-decl name='dryrun' type-id='95e97e5e' visibility='default'/>
|
<var-decl name='dryrun' type-id='f0981eeb' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
<data-member access='public' layout-offset-in-bits='1'>
|
<data-member access='public' layout-offset-in-bits='1'>
|
||||||
<var-decl name='import' type-id='95e97e5e' visibility='default'/>
|
<var-decl name='import' type-id='f0981eeb' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
<data-member access='public' layout-offset-in-bits='32'>
|
<data-member access='public' layout-offset-in-bits='32'>
|
||||||
<var-decl name='name_flags' type-id='95e97e5e' visibility='default'/>
|
<var-decl name='name_flags' type-id='95e97e5e' visibility='default'/>
|
||||||
|
@ -5312,7 +5310,8 @@
|
||||||
<enumerator name='ZPOOL_STATUS_NON_NATIVE_ASHIFT' value='29'/>
|
<enumerator name='ZPOOL_STATUS_NON_NATIVE_ASHIFT' value='29'/>
|
||||||
<enumerator name='ZPOOL_STATUS_COMPATIBILITY_ERR' value='30'/>
|
<enumerator name='ZPOOL_STATUS_COMPATIBILITY_ERR' value='30'/>
|
||||||
<enumerator name='ZPOOL_STATUS_INCOMPATIBLE_FEAT' value='31'/>
|
<enumerator name='ZPOOL_STATUS_INCOMPATIBLE_FEAT' value='31'/>
|
||||||
<enumerator name='ZPOOL_STATUS_OK' value='32'/>
|
<enumerator name='ZPOOL_STATUS_FORCE_EXPORTING' value='32'/>
|
||||||
|
<enumerator name='ZPOOL_STATUS_OK' value='33'/>
|
||||||
</enum-decl>
|
</enum-decl>
|
||||||
<typedef-decl name='zpool_status_t' type-id='5e770b40' id='d3dd6294'/>
|
<typedef-decl name='zpool_status_t' type-id='5e770b40' id='d3dd6294'/>
|
||||||
<enum-decl name='zpool_compat_status_t' naming-typedef-id='901b78d1' id='20676925'>
|
<enum-decl name='zpool_compat_status_t' naming-typedef-id='901b78d1' id='20676925'>
|
||||||
|
@ -6042,11 +6041,6 @@
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
<return type-id='3a47d82b'/>
|
<return type-id='3a47d82b'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='realpath' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='9d26089a'/>
|
|
||||||
<parameter type-id='266fe297'/>
|
|
||||||
<return type-id='26a90f95'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='memcmp' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='memcmp' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='eaa32e2f'/>
|
<parameter type-id='eaa32e2f'/>
|
||||||
<parameter type-id='eaa32e2f'/>
|
<parameter type-id='eaa32e2f'/>
|
||||||
|
@ -6065,6 +6059,12 @@
|
||||||
<parameter type-id='b59d7dce'/>
|
<parameter type-id='b59d7dce'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
|
<function-decl name='__realpath_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='9d26089a'/>
|
||||||
|
<parameter type-id='266fe297'/>
|
||||||
|
<parameter type-id='b59d7dce'/>
|
||||||
|
<return type-id='26a90f95'/>
|
||||||
|
</function-decl>
|
||||||
<function-decl name='munmap' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='munmap' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='eaa32e2f'/>
|
<parameter type-id='eaa32e2f'/>
|
||||||
<parameter type-id='b59d7dce'/>
|
<parameter type-id='b59d7dce'/>
|
||||||
|
@ -6846,21 +6846,10 @@
|
||||||
<parameter type-id='a3681dea' name='stream_avl'/>
|
<parameter type-id='a3681dea' name='stream_avl'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='sprintf' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='26a90f95'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter is-variadic='yes'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='perror' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='perror' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
<return type-id='48b5725f'/>
|
<return type-id='48b5725f'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='strcat' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='26a90f95'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<return type-id='26a90f95'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='strndup' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='strndup' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
<parameter type-id='b59d7dce'/>
|
<parameter type-id='b59d7dce'/>
|
||||||
|
@ -7243,24 +7232,12 @@
|
||||||
<function-decl name='zfs_version_print' mangled-name='zfs_version_print' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_version_print'>
|
<function-decl name='zfs_version_print' mangled-name='zfs_version_print' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_version_print'>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='color_start' mangled-name='color_start' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='color_start'>
|
|
||||||
<parameter type-id='26a90f95' name='color'/>
|
|
||||||
<return type-id='48b5725f'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='color_end' mangled-name='color_end' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='color_end'>
|
|
||||||
<return type-id='48b5725f'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='printf_color' mangled-name='printf_color' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='printf_color'>
|
<function-decl name='printf_color' mangled-name='printf_color' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='printf_color'>
|
||||||
<parameter type-id='26a90f95' name='color'/>
|
<parameter type-id='80f4b756' name='color'/>
|
||||||
<parameter type-id='26a90f95' name='format'/>
|
<parameter type-id='26a90f95' name='format'/>
|
||||||
<parameter is-variadic='yes'/>
|
<parameter is-variadic='yes'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='pow' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='a0eb0f08'/>
|
|
||||||
<parameter type-id='a0eb0f08'/>
|
|
||||||
<return type-id='a0eb0f08'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='__ctype_toupper_loc' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='__ctype_toupper_loc' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<return type-id='24f95ba5'/>
|
<return type-id='24f95ba5'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
|
@ -7278,25 +7255,6 @@
|
||||||
<parameter type-id='d33f11cb'/>
|
<parameter type-id='d33f11cb'/>
|
||||||
<return type-id='48b5725f'/>
|
<return type-id='48b5725f'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='vfprintf' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='e75a27e9'/>
|
|
||||||
<parameter type-id='9d26089a'/>
|
|
||||||
<parameter type-id='b7f2d5e6'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='vsnprintf' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='26a90f95'/>
|
|
||||||
<parameter type-id='b59d7dce'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='b7f2d5e6'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='vasprintf' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='8c85230f'/>
|
|
||||||
<parameter type-id='9d26089a'/>
|
|
||||||
<parameter type-id='b7f2d5e6'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='strtod' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='strtod' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='9d26089a'/>
|
<parameter type-id='9d26089a'/>
|
||||||
<parameter type-id='8c85230f'/>
|
<parameter type-id='8c85230f'/>
|
||||||
|
@ -7316,12 +7274,6 @@
|
||||||
<parameter type-id='b59d7dce'/>
|
<parameter type-id='b59d7dce'/>
|
||||||
<return type-id='b59d7dce'/>
|
<return type-id='b59d7dce'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='waitpid' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='3629bad8'/>
|
|
||||||
<parameter type-id='7292109c'/>
|
|
||||||
<parameter type-id='95e97e5e'/>
|
|
||||||
<return type-id='3629bad8'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='dup2' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='dup2' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
|
@ -7356,6 +7308,31 @@
|
||||||
<function-decl name='vfork' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='vfork' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<return type-id='3629bad8'/>
|
<return type-id='3629bad8'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
|
<function-decl name='pow' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='a0eb0f08'/>
|
||||||
|
<parameter type-id='a0eb0f08'/>
|
||||||
|
<return type-id='a0eb0f08'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='__vfprintf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='e75a27e9'/>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<parameter type-id='9d26089a'/>
|
||||||
|
<parameter type-id='b7f2d5e6'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='__vasprintf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='8c85230f'/>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<parameter type-id='9d26089a'/>
|
||||||
|
<parameter type-id='b7f2d5e6'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='waitpid' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='3629bad8'/>
|
||||||
|
<parameter type-id='7292109c'/>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<return type-id='3629bad8'/>
|
||||||
|
</function-decl>
|
||||||
<function-type size-in-bits='64' id='c70fa2e8'>
|
<function-type size-in-bits='64' id='c70fa2e8'>
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
<parameter type-id='eaa32e2f'/>
|
<parameter type-id='eaa32e2f'/>
|
||||||
|
@ -7364,6 +7341,9 @@
|
||||||
</abi-instr>
|
</abi-instr>
|
||||||
<abi-instr address-size='64' path='os/linux/libzfs_mount_os.c' language='LANG_C99'>
|
<abi-instr address-size='64' path='os/linux/libzfs_mount_os.c' language='LANG_C99'>
|
||||||
<pointer-type-def type-id='7359adad' size-in-bits='64' id='1d2c2b85'/>
|
<pointer-type-def type-id='7359adad' size-in-bits='64' id='1d2c2b85'/>
|
||||||
|
<function-decl name='geteuid' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<return type-id='cc5fcceb'/>
|
||||||
|
</function-decl>
|
||||||
<function-decl name='mount' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='mount' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
|
@ -7377,9 +7357,6 @@
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='geteuid' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<return type-id='cc5fcceb'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='zfs_parse_mount_options' mangled-name='zfs_parse_mount_options' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_parse_mount_options'>
|
<function-decl name='zfs_parse_mount_options' mangled-name='zfs_parse_mount_options' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_parse_mount_options'>
|
||||||
<parameter type-id='26a90f95' name='mntopts'/>
|
<parameter type-id='26a90f95' name='mntopts'/>
|
||||||
<parameter type-id='1d2c2b85' name='mntflags'/>
|
<parameter type-id='1d2c2b85' name='mntflags'/>
|
||||||
|
|
|
@ -481,8 +481,6 @@ make_dataset_handle_common(zfs_handle_t *zhp, zfs_cmd_t *zc)
|
||||||
zfs_handle_t *
|
zfs_handle_t *
|
||||||
make_dataset_handle(libzfs_handle_t *hdl, const char *path)
|
make_dataset_handle(libzfs_handle_t *hdl, const char *path)
|
||||||
{
|
{
|
||||||
zfs_cmd_t zc = {"\0"};
|
|
||||||
|
|
||||||
zfs_handle_t *zhp = calloc(1, sizeof (zfs_handle_t));
|
zfs_handle_t *zhp = calloc(1, sizeof (zfs_handle_t));
|
||||||
|
|
||||||
if (zhp == NULL)
|
if (zhp == NULL)
|
||||||
|
@ -490,20 +488,33 @@ make_dataset_handle(libzfs_handle_t *hdl, const char *path)
|
||||||
|
|
||||||
zhp->zfs_hdl = hdl;
|
zhp->zfs_hdl = hdl;
|
||||||
(void) strlcpy(zhp->zfs_name, path, sizeof (zhp->zfs_name));
|
(void) strlcpy(zhp->zfs_name, path, sizeof (zhp->zfs_name));
|
||||||
if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0) {
|
if (!hdl->libzfs_force_export) {
|
||||||
free(zhp);
|
zfs_cmd_t zc = {"\0"};
|
||||||
return (NULL);
|
|
||||||
}
|
zcmd_alloc_dst_nvlist(hdl, &zc, 0);
|
||||||
if (get_stats_ioctl(zhp, &zc) == -1) {
|
if (get_stats_ioctl(zhp, &zc) == -1) {
|
||||||
|
zcmd_free_nvlists(&zc);
|
||||||
|
free(zhp);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
if (make_dataset_handle_common(zhp, &zc) == -1) {
|
||||||
|
free(zhp);
|
||||||
|
zhp = NULL;
|
||||||
|
}
|
||||||
zcmd_free_nvlists(&zc);
|
zcmd_free_nvlists(&zc);
|
||||||
free(zhp);
|
} else {
|
||||||
return (NULL);
|
/*
|
||||||
|
* Called from zpool_disable_datasets() which sets force
|
||||||
|
* export and uses mount entries, so de facto the dataset
|
||||||
|
* is a ZFS filesystem. Furthermore, we need to avoid
|
||||||
|
* calling get_stats_ioctl() here since it results in
|
||||||
|
* zfs_ioc_objset_stats()->dmu_objset_hold() being called by
|
||||||
|
* the kernel which can potentially cause IO to be issued
|
||||||
|
* depending on what's currently cached in ARC.
|
||||||
|
*/
|
||||||
|
zhp->zfs_dmustats.dds_type = DMU_OST_ZFS;
|
||||||
|
zhp->zfs_type = ZFS_TYPE_FILESYSTEM;
|
||||||
}
|
}
|
||||||
if (make_dataset_handle_common(zhp, &zc) == -1) {
|
|
||||||
free(zhp);
|
|
||||||
zhp = NULL;
|
|
||||||
}
|
|
||||||
zcmd_free_nvlists(&zc);
|
|
||||||
return (zhp);
|
return (zhp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1525,7 +1525,8 @@ mountpoint_compare(const void *a, const void *b)
|
||||||
* and gather all the filesystems that are currently mounted.
|
* and gather all the filesystems that are currently mounted.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
|
zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force,
|
||||||
|
boolean_t hardforce)
|
||||||
{
|
{
|
||||||
int used, alloc;
|
int used, alloc;
|
||||||
struct mnttab entry;
|
struct mnttab entry;
|
||||||
|
@ -1535,8 +1536,9 @@ zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
|
||||||
libzfs_handle_t *hdl = zhp->zpool_hdl;
|
libzfs_handle_t *hdl = zhp->zpool_hdl;
|
||||||
int i;
|
int i;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
int flags = (force ? MS_FORCE : 0);
|
int flags = ((hardforce || force) ? MS_FORCE : 0);
|
||||||
|
|
||||||
|
hdl->libzfs_force_export = flags & MS_FORCE;
|
||||||
namelen = strlen(zhp->zpool_name);
|
namelen = strlen(zhp->zpool_name);
|
||||||
|
|
||||||
/* Reopen MNTTAB to prevent reading stale data from open file */
|
/* Reopen MNTTAB to prevent reading stale data from open file */
|
||||||
|
@ -1615,6 +1617,10 @@ zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
|
||||||
*/
|
*/
|
||||||
qsort(mountpoints, used, sizeof (char *), mountpoint_compare);
|
qsort(mountpoints, used, sizeof (char *), mountpoint_compare);
|
||||||
|
|
||||||
|
if (hardforce) {
|
||||||
|
zpool_unmount_mark_hard_force_begin(zhp);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Walk through and first unshare everything.
|
* Walk through and first unshare everything.
|
||||||
*/
|
*/
|
||||||
|
@ -1639,9 +1645,15 @@ zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < used; i++) {
|
/*
|
||||||
if (datasets[i])
|
* Remove mountpoints, unless the pool is being forcibly exported.
|
||||||
remove_mountpoint(datasets[i]);
|
* In the latter case, avoid potentially initiating I/O on the pool.
|
||||||
|
*/
|
||||||
|
if (!hdl->libzfs_force_export) {
|
||||||
|
for (i = 0; i < used; i++) {
|
||||||
|
if (datasets[i])
|
||||||
|
remove_mountpoint(datasets[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
@ -1654,5 +1666,9 @@ out:
|
||||||
free(datasets);
|
free(datasets);
|
||||||
free(mountpoints);
|
free(mountpoints);
|
||||||
|
|
||||||
|
if (hardforce) {
|
||||||
|
zpool_unmount_mark_hard_force_end(zhp);
|
||||||
|
}
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
|
@ -260,7 +260,9 @@ zpool_get_state_str(zpool_handle_t *zhp)
|
||||||
|
|
||||||
status = zpool_get_status(zhp, NULL, &errata);
|
status = zpool_get_status(zhp, NULL, &errata);
|
||||||
|
|
||||||
if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
|
if (status == ZPOOL_STATUS_FORCE_EXPORTING) {
|
||||||
|
str = gettext("FORCE-EXPORTING");
|
||||||
|
} else if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
|
||||||
str = gettext("FAULTED");
|
str = gettext("FAULTED");
|
||||||
} else if (status == ZPOOL_STATUS_IO_FAILURE_WAIT ||
|
} else if (status == ZPOOL_STATUS_IO_FAILURE_WAIT ||
|
||||||
status == ZPOOL_STATUS_IO_FAILURE_MMP) {
|
status == ZPOOL_STATUS_IO_FAILURE_MMP) {
|
||||||
|
@ -1481,7 +1483,9 @@ zpool_destroy(zpool_handle_t *zhp, const char *log_str)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zfp) {
|
if (zfp) {
|
||||||
remove_mountpoint(zfp);
|
/* Avoid initiating I/O during a forced export. */
|
||||||
|
if (!hdl->libzfs_force_export)
|
||||||
|
remove_mountpoint(zfp);
|
||||||
zfs_close(zfp);
|
zfs_close(zfp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -236,6 +236,9 @@ check_status(nvlist_t *config, boolean_t isimport,
|
||||||
uint64_t errata = 0;
|
uint64_t errata = 0;
|
||||||
unsigned long system_hostid = get_system_hostid();
|
unsigned long system_hostid = get_system_hostid();
|
||||||
|
|
||||||
|
if (config == NULL)
|
||||||
|
return (ZPOOL_STATUS_FORCE_EXPORTING);
|
||||||
|
|
||||||
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
|
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
|
||||||
&version) == 0);
|
&version) == 0);
|
||||||
verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
|
verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
|
||||||
|
|
|
@ -133,3 +133,15 @@ zfs_mount_delegation_check(void)
|
||||||
{
|
{
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zpool_unmount_mark_hard_force_begin(zpool_handle_t *zhp)
|
||||||
|
{
|
||||||
|
(void) zhp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zpool_unmount_mark_hard_force_end(zpool_handle_t *zhp)
|
||||||
|
{
|
||||||
|
(void) zhp;
|
||||||
|
}
|
||||||
|
|
|
@ -411,3 +411,23 @@ zfs_mount_delegation_check(void)
|
||||||
{
|
{
|
||||||
return ((geteuid() != 0) ? EACCES : 0);
|
return ((geteuid() != 0) ? EACCES : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zpool_unmount_mark_hard_force_begin(zpool_handle_t *zhp)
|
||||||
|
{
|
||||||
|
zfs_cmd_t zc = {"\0"};
|
||||||
|
libzfs_handle_t *hdl = zhp->zpool_hdl;
|
||||||
|
|
||||||
|
(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
|
||||||
|
(void) zfs_ioctl(hdl, ZFS_IOC_HARD_FORCE_UNMOUNT_BEGIN, &zc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zpool_unmount_mark_hard_force_end(zpool_handle_t *zhp)
|
||||||
|
{
|
||||||
|
zfs_cmd_t zc = {"\0"};
|
||||||
|
libzfs_handle_t *hdl = zhp->zpool_hdl;
|
||||||
|
|
||||||
|
(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
|
||||||
|
(void) zfs_ioctl(hdl, ZFS_IOC_HARD_FORCE_UNMOUNT_END, &zc);
|
||||||
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
<dependency name='libblkid.so.1'/>
|
<dependency name='libblkid.so.1'/>
|
||||||
<dependency name='libudev.so.1'/>
|
<dependency name='libudev.so.1'/>
|
||||||
<dependency name='libnvpair.so.3'/>
|
<dependency name='libnvpair.so.3'/>
|
||||||
<dependency name='libtirpc.so.3'/>
|
|
||||||
<dependency name='libc.so.6'/>
|
<dependency name='libc.so.6'/>
|
||||||
<dependency name='ld-linux-x86-64.so.2'/>
|
<dependency name='ld-linux-x86-64.so.2'/>
|
||||||
</elf-needed>
|
</elf-needed>
|
||||||
|
@ -405,12 +404,6 @@
|
||||||
<parameter type-id='c43b27a6' name='vtoc'/>
|
<parameter type-id='c43b27a6' name='vtoc'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='sprintf' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='26a90f95'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter is-variadic='yes'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='write' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='write' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
<parameter type-id='eaa32e2f'/>
|
<parameter type-id='eaa32e2f'/>
|
||||||
|
@ -438,16 +431,32 @@
|
||||||
<type-decl name='unsigned long int' size-in-bits='64' id='7359adad'/>
|
<type-decl name='unsigned long int' size-in-bits='64' id='7359adad'/>
|
||||||
</abi-instr>
|
</abi-instr>
|
||||||
<abi-instr address-size='64' path='assert.c' language='LANG_C99'>
|
<abi-instr address-size='64' path='assert.c' language='LANG_C99'>
|
||||||
|
<class-decl name='__va_list_tag' size-in-bits='192' is-struct='yes' visibility='default' id='d5027220'>
|
||||||
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
|
<var-decl name='gp_offset' type-id='f0981eeb' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='32'>
|
||||||
|
<var-decl name='fp_offset' type-id='f0981eeb' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='64'>
|
||||||
|
<var-decl name='overflow_arg_area' type-id='eaa32e2f' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='128'>
|
||||||
|
<var-decl name='reg_save_area' type-id='eaa32e2f' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
</class-decl>
|
||||||
|
<pointer-type-def type-id='d5027220' size-in-bits='64' id='b7f2d5e6'/>
|
||||||
<var-decl name='aok' type-id='95e97e5e' mangled-name='aok' visibility='default' elf-symbol-id='aok'/>
|
<var-decl name='aok' type-id='95e97e5e' mangled-name='aok' visibility='default' elf-symbol-id='aok'/>
|
||||||
<function-decl name='vfprintf' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='abort' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<return type-id='48b5725f'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='__vfprintf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='e75a27e9'/>
|
<parameter type-id='e75a27e9'/>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
<parameter type-id='9d26089a'/>
|
<parameter type-id='9d26089a'/>
|
||||||
<parameter type-id='b7f2d5e6'/>
|
<parameter type-id='b7f2d5e6'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='abort' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<return type-id='48b5725f'/>
|
|
||||||
</function-decl>
|
|
||||||
</abi-instr>
|
</abi-instr>
|
||||||
<abi-instr address-size='64' path='atomic.c' language='LANG_C99'>
|
<abi-instr address-size='64' path='atomic.c' language='LANG_C99'>
|
||||||
<typedef-decl name='int8_t' type-id='2171a512' id='ee31ee44'/>
|
<typedef-decl name='int8_t' type-id='2171a512' id='ee31ee44'/>
|
||||||
|
@ -893,16 +902,18 @@
|
||||||
<parameter type-id='d50d396c' name='mode'/>
|
<parameter type-id='d50d396c' name='mode'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='mbstowcs' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='__mbstowcs_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='f1358bc3'/>
|
<parameter type-id='f1358bc3'/>
|
||||||
<parameter type-id='9d26089a'/>
|
<parameter type-id='9d26089a'/>
|
||||||
<parameter type-id='b59d7dce'/>
|
<parameter type-id='b59d7dce'/>
|
||||||
|
<parameter type-id='b59d7dce'/>
|
||||||
<return type-id='b59d7dce'/>
|
<return type-id='b59d7dce'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='wcstombs' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='__wcstombs_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='266fe297'/>
|
<parameter type-id='266fe297'/>
|
||||||
<parameter type-id='598aab80'/>
|
<parameter type-id='598aab80'/>
|
||||||
<parameter type-id='b59d7dce'/>
|
<parameter type-id='b59d7dce'/>
|
||||||
|
<parameter type-id='b59d7dce'/>
|
||||||
<return type-id='b59d7dce'/>
|
<return type-id='b59d7dce'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='mkdir' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='mkdir' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
@ -1022,15 +1033,8 @@
|
||||||
<abi-instr address-size='64' path='page.c' language='LANG_C99'>
|
<abi-instr address-size='64' path='page.c' language='LANG_C99'>
|
||||||
<var-decl name='pagesize' type-id='b59d7dce' mangled-name='pagesize' visibility='default' elf-symbol-id='pagesize'/>
|
<var-decl name='pagesize' type-id='b59d7dce' mangled-name='pagesize' visibility='default' elf-symbol-id='pagesize'/>
|
||||||
</abi-instr>
|
</abi-instr>
|
||||||
<abi-instr address-size='64' path='strlcat.c' language='LANG_C99'>
|
|
||||||
<function-decl name='memcpy' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='eaa32e2f'/>
|
|
||||||
<parameter type-id='eaa32e2f'/>
|
|
||||||
<parameter type-id='b59d7dce'/>
|
|
||||||
<return type-id='eaa32e2f'/>
|
|
||||||
</function-decl>
|
|
||||||
</abi-instr>
|
|
||||||
<abi-instr address-size='64' path='timestamp.c' language='LANG_C99'>
|
<abi-instr address-size='64' path='timestamp.c' language='LANG_C99'>
|
||||||
|
<typedef-decl name='nl_item' type-id='95e97e5e' id='03b79a94'/>
|
||||||
<class-decl name='tm' size-in-bits='448' is-struct='yes' visibility='default' id='dddf6ca2'>
|
<class-decl name='tm' size-in-bits='448' is-struct='yes' visibility='default' id='dddf6ca2'>
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
<var-decl name='tm_sec' type-id='95e97e5e' visibility='default'/>
|
<var-decl name='tm_sec' type-id='95e97e5e' visibility='default'/>
|
||||||
|
@ -1067,7 +1071,6 @@
|
||||||
</data-member>
|
</data-member>
|
||||||
</class-decl>
|
</class-decl>
|
||||||
<typedef-decl name='time_t' type-id='65eda9c0' id='c9d12d66'/>
|
<typedef-decl name='time_t' type-id='65eda9c0' id='c9d12d66'/>
|
||||||
<typedef-decl name='nl_item' type-id='95e97e5e' id='03b79a94'/>
|
|
||||||
<qualified-type-def type-id='c9d12d66' const='yes' id='588b3216'/>
|
<qualified-type-def type-id='c9d12d66' const='yes' id='588b3216'/>
|
||||||
<pointer-type-def type-id='588b3216' size-in-bits='64' id='9f201474'/>
|
<pointer-type-def type-id='588b3216' size-in-bits='64' id='9f201474'/>
|
||||||
<qualified-type-def type-id='dddf6ca2' const='yes' id='e824a34f'/>
|
<qualified-type-def type-id='dddf6ca2' const='yes' id='e824a34f'/>
|
||||||
|
@ -1142,6 +1145,40 @@
|
||||||
<var-decl name='tpa_tid' type-id='4051f5e7' visibility='default'/>
|
<var-decl name='tpa_tid' type-id='4051f5e7' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
</class-decl>
|
</class-decl>
|
||||||
|
<class-decl name='__cancel_jmp_buf_tag' size-in-bits='576' is-struct='yes' visibility='default' id='8901473c'>
|
||||||
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
|
<var-decl name='__cancel_jmp_buf' type-id='379a1ab7' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='512'>
|
||||||
|
<var-decl name='__mask_was_saved' type-id='95e97e5e' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
</class-decl>
|
||||||
|
<class-decl name='__pthread_unwind_buf_t' size-in-bits='832' is-struct='yes' naming-typedef-id='4423cf7f' visibility='default' id='a0abc656'>
|
||||||
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
|
<var-decl name='__cancel_jmp_buf' type-id='f5da478b' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='576'>
|
||||||
|
<var-decl name='__pad' type-id='209ef23f' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
</class-decl>
|
||||||
|
<typedef-decl name='__pthread_unwind_buf_t' type-id='a0abc656' id='4423cf7f'/>
|
||||||
|
<union-decl name='__atomic_wide_counter' size-in-bits='64' naming-typedef-id='f3b40860' visibility='default' id='613ce450'>
|
||||||
|
<data-member access='public'>
|
||||||
|
<var-decl name='__value64' type-id='3a47d82b' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public'>
|
||||||
|
<var-decl name='__value32' type-id='e7f43f72' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
</union-decl>
|
||||||
|
<class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' id='e7f43f72'>
|
||||||
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
|
<var-decl name='__low' type-id='f0981eeb' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='32'>
|
||||||
|
<var-decl name='__high' type-id='f0981eeb' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
</class-decl>
|
||||||
|
<typedef-decl name='__atomic_wide_counter' type-id='613ce450' id='f3b40860'/>
|
||||||
<typedef-decl name='__cpu_mask' type-id='7359adad' id='49ef3ffd'/>
|
<typedef-decl name='__cpu_mask' type-id='7359adad' id='49ef3ffd'/>
|
||||||
<class-decl name='cpu_set_t' size-in-bits='1024' is-struct='yes' naming-typedef-id='8037c762' visibility='default' id='1f20d231'>
|
<class-decl name='cpu_set_t' size-in-bits='1024' is-struct='yes' naming-typedef-id='8037c762' visibility='default' id='1f20d231'>
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
|
@ -1174,10 +1211,10 @@
|
||||||
<typedef-decl name='__jmp_buf' type-id='5d4efd44' id='379a1ab7'/>
|
<typedef-decl name='__jmp_buf' type-id='5d4efd44' id='379a1ab7'/>
|
||||||
<class-decl name='__pthread_cond_s' size-in-bits='384' is-struct='yes' visibility='default' id='c987b47c'>
|
<class-decl name='__pthread_cond_s' size-in-bits='384' is-struct='yes' visibility='default' id='c987b47c'>
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
<var-decl name='' type-id='ac5ab595' visibility='default'/>
|
<var-decl name='__wseq' type-id='f3b40860' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
<data-member access='public' layout-offset-in-bits='64'>
|
<data-member access='public' layout-offset-in-bits='64'>
|
||||||
<var-decl name='' type-id='ac5ab596' visibility='default'/>
|
<var-decl name='__g1_start' type-id='f3b40860' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
<data-member access='public' layout-offset-in-bits='128'>
|
<data-member access='public' layout-offset-in-bits='128'>
|
||||||
<var-decl name='__g_refs' type-id='0d532ec1' visibility='default'/>
|
<var-decl name='__g_refs' type-id='0d532ec1' visibility='default'/>
|
||||||
|
@ -1195,30 +1232,6 @@
|
||||||
<var-decl name='__g_signals' type-id='0d532ec1' visibility='default'/>
|
<var-decl name='__g_signals' type-id='0d532ec1' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
</class-decl>
|
</class-decl>
|
||||||
<union-decl name='__anonymous_union__1' size-in-bits='64' is-anonymous='yes' visibility='default' id='ac5ab595'>
|
|
||||||
<data-member access='public'>
|
|
||||||
<var-decl name='__wseq' type-id='3a47d82b' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public'>
|
|
||||||
<var-decl name='__wseq32' type-id='e7f43f72' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
</union-decl>
|
|
||||||
<class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' id='e7f43f72'>
|
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
|
||||||
<var-decl name='__low' type-id='f0981eeb' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='32'>
|
|
||||||
<var-decl name='__high' type-id='f0981eeb' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
</class-decl>
|
|
||||||
<union-decl name='__anonymous_union__2' size-in-bits='64' is-anonymous='yes' visibility='default' id='ac5ab596'>
|
|
||||||
<data-member access='public'>
|
|
||||||
<var-decl name='__g1_start' type-id='3a47d82b' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public'>
|
|
||||||
<var-decl name='__g1_start32' type-id='e7f43f72' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
</union-decl>
|
|
||||||
<class-decl name='__sigset_t' size-in-bits='1024' is-struct='yes' naming-typedef-id='b9c97942' visibility='default' id='2616147f'>
|
<class-decl name='__sigset_t' size-in-bits='1024' is-struct='yes' naming-typedef-id='b9c97942' visibility='default' id='2616147f'>
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
<var-decl name='__val' type-id='d2baa450' visibility='default'/>
|
<var-decl name='__val' type-id='d2baa450' visibility='default'/>
|
||||||
|
@ -1230,23 +1243,6 @@
|
||||||
<var-decl name='sched_priority' type-id='95e97e5e' visibility='default'/>
|
<var-decl name='sched_priority' type-id='95e97e5e' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
</class-decl>
|
</class-decl>
|
||||||
<class-decl name='__cancel_jmp_buf_tag' size-in-bits='576' is-struct='yes' visibility='default' id='8901473c'>
|
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
|
||||||
<var-decl name='__cancel_jmp_buf' type-id='379a1ab7' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='512'>
|
|
||||||
<var-decl name='__mask_was_saved' type-id='95e97e5e' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
</class-decl>
|
|
||||||
<class-decl name='__pthread_unwind_buf_t' size-in-bits='832' is-struct='yes' naming-typedef-id='4423cf7f' visibility='default' id='a0abc656'>
|
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
|
||||||
<var-decl name='__cancel_jmp_buf' type-id='f5da478b' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='576'>
|
|
||||||
<var-decl name='__pad' type-id='209ef23f' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
</class-decl>
|
|
||||||
<typedef-decl name='__pthread_unwind_buf_t' type-id='a0abc656' id='4423cf7f'/>
|
|
||||||
<pointer-type-def type-id='8901473c' size-in-bits='64' id='eb91b7ea'/>
|
<pointer-type-def type-id='8901473c' size-in-bits='64' id='eb91b7ea'/>
|
||||||
<pointer-type-def type-id='4423cf7f' size-in-bits='64' id='ba7c727c'/>
|
<pointer-type-def type-id='4423cf7f' size-in-bits='64' id='ba7c727c'/>
|
||||||
<pointer-type-def type-id='b9c97942' size-in-bits='64' id='bbf06c47'/>
|
<pointer-type-def type-id='b9c97942' size-in-bits='64' id='bbf06c47'/>
|
||||||
|
@ -1304,16 +1300,6 @@
|
||||||
<parameter type-id='9cf59a50' name='tpool'/>
|
<parameter type-id='9cf59a50' name='tpool'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='__sysconf' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='95e97e5e'/>
|
|
||||||
<return type-id='bd54fe1a'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='pthread_sigmask' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='95e97e5e'/>
|
|
||||||
<parameter type-id='5a8729d0'/>
|
|
||||||
<parameter type-id='65e6ec45'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='pthread_create' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='pthread_create' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='cc338b26'/>
|
<parameter type-id='cc338b26'/>
|
||||||
<parameter type-id='e1815e87'/>
|
<parameter type-id='e1815e87'/>
|
||||||
|
@ -1466,6 +1452,16 @@
|
||||||
<parameter type-id='0be2e71c'/>
|
<parameter type-id='0be2e71c'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
|
<function-decl name='__sysconf' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<return type-id='bd54fe1a'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='pthread_sigmask' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<parameter type-id='5a8729d0'/>
|
||||||
|
<parameter type-id='65e6ec45'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
<function-type size-in-bits='64' id='cd5d79f4'>
|
<function-type size-in-bits='64' id='cd5d79f4'>
|
||||||
<parameter type-id='eaa32e2f'/>
|
<parameter type-id='eaa32e2f'/>
|
||||||
<return type-id='eaa32e2f'/>
|
<return type-id='eaa32e2f'/>
|
||||||
|
@ -1863,7 +1859,7 @@
|
||||||
<var-decl name='drr_payloadlen' type-id='8f92235e' visibility='default'/>
|
<var-decl name='drr_payloadlen' type-id='8f92235e' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
<data-member access='public' layout-offset-in-bits='64'>
|
<data-member access='public' layout-offset-in-bits='64'>
|
||||||
<var-decl name='drr_u' type-id='ac5ab597' visibility='default'/>
|
<var-decl name='drr_u' type-id='ac5ab595' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
</class-decl>
|
</class-decl>
|
||||||
<enum-decl name='__anonymous_enum__' is-anonymous='yes' id='08f5ca17'>
|
<enum-decl name='__anonymous_enum__' is-anonymous='yes' id='08f5ca17'>
|
||||||
|
@ -1881,7 +1877,7 @@
|
||||||
<enumerator name='DRR_REDACT' value='10'/>
|
<enumerator name='DRR_REDACT' value='10'/>
|
||||||
<enumerator name='DRR_NUMTYPES' value='11'/>
|
<enumerator name='DRR_NUMTYPES' value='11'/>
|
||||||
</enum-decl>
|
</enum-decl>
|
||||||
<union-decl name='__anonymous_union__' size-in-bits='2432' is-anonymous='yes' visibility='default' id='ac5ab597'>
|
<union-decl name='__anonymous_union__' size-in-bits='2432' is-anonymous='yes' visibility='default' id='ac5ab595'>
|
||||||
<data-member access='public'>
|
<data-member access='public'>
|
||||||
<var-decl name='drr_begin' type-id='09fcdc01' visibility='default'/>
|
<var-decl name='drr_begin' type-id='09fcdc01' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
|
@ -2985,10 +2981,17 @@
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='read' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='__open_too_many_args' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<return type-id='48b5725f'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='__open_missing_mode' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<return type-id='48b5725f'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='__read_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
<parameter type-id='eaa32e2f'/>
|
<parameter type-id='eaa32e2f'/>
|
||||||
<parameter type-id='b59d7dce'/>
|
<parameter type-id='b59d7dce'/>
|
||||||
|
<parameter type-id='b59d7dce'/>
|
||||||
<return type-id='79a0948f'/>
|
<return type-id='79a0948f'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
</abi-instr>
|
</abi-instr>
|
||||||
|
@ -3156,21 +3159,23 @@
|
||||||
<parameter type-id='822cd80b'/>
|
<parameter type-id='822cd80b'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='fgets' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='266fe297'/>
|
|
||||||
<parameter type-id='95e97e5e'/>
|
|
||||||
<parameter type-id='e75a27e9'/>
|
|
||||||
<return type-id='26a90f95'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='strstr' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='strstr' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
<return type-id='26a90f95'/>
|
<return type-id='26a90f95'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='readlink' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='__fgets_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='266fe297'/>
|
||||||
|
<parameter type-id='b59d7dce'/>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<parameter type-id='e75a27e9'/>
|
||||||
|
<return type-id='26a90f95'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='__readlink_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='9d26089a'/>
|
<parameter type-id='9d26089a'/>
|
||||||
<parameter type-id='266fe297'/>
|
<parameter type-id='266fe297'/>
|
||||||
<parameter type-id='b59d7dce'/>
|
<parameter type-id='b59d7dce'/>
|
||||||
|
<parameter type-id='b59d7dce'/>
|
||||||
<return type-id='79a0948f'/>
|
<return type-id='79a0948f'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='zfs_strip_partition' mangled-name='zfs_strip_partition' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_strip_partition'>
|
<function-decl name='zfs_strip_partition' mangled-name='zfs_strip_partition' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_strip_partition'>
|
||||||
|
@ -3208,12 +3213,12 @@
|
||||||
<class-decl name='blkid_struct_dev' is-struct='yes' visibility='default' is-declaration-only='yes' id='86223623'/>
|
<class-decl name='blkid_struct_dev' is-struct='yes' visibility='default' is-declaration-only='yes' id='86223623'/>
|
||||||
<class-decl name='blkid_struct_dev_iterate' is-struct='yes' visibility='default' is-declaration-only='yes' id='d88420d6'/>
|
<class-decl name='blkid_struct_dev_iterate' is-struct='yes' visibility='default' is-declaration-only='yes' id='d88420d6'/>
|
||||||
<class-decl name='udev_list_entry' is-struct='yes' visibility='default' is-declaration-only='yes' id='e7dbdca3'/>
|
<class-decl name='udev_list_entry' is-struct='yes' visibility='default' is-declaration-only='yes' id='e7dbdca3'/>
|
||||||
<typedef-decl name='__useconds_t' type-id='f0981eeb' id='4e80d4b1'/>
|
|
||||||
<typedef-decl name='__clockid_t' type-id='95e97e5e' id='08f9a87a'/>
|
|
||||||
<typedef-decl name='clockid_t' type-id='08f9a87a' id='a1c3b834'/>
|
|
||||||
<typedef-decl name='blkid_dev' type-id='8433f053' id='f47b023a'/>
|
<typedef-decl name='blkid_dev' type-id='8433f053' id='f47b023a'/>
|
||||||
<typedef-decl name='blkid_cache' type-id='940e3afc' id='0882dfdf'/>
|
<typedef-decl name='blkid_cache' type-id='940e3afc' id='0882dfdf'/>
|
||||||
<typedef-decl name='blkid_dev_iterate' type-id='b8fa2efc' id='f4760fa7'/>
|
<typedef-decl name='blkid_dev_iterate' type-id='b8fa2efc' id='f4760fa7'/>
|
||||||
|
<typedef-decl name='__useconds_t' type-id='f0981eeb' id='4e80d4b1'/>
|
||||||
|
<typedef-decl name='__clockid_t' type-id='95e97e5e' id='08f9a87a'/>
|
||||||
|
<typedef-decl name='clockid_t' type-id='08f9a87a' id='a1c3b834'/>
|
||||||
<pointer-type-def type-id='0882dfdf' size-in-bits='64' id='2e3e7caa'/>
|
<pointer-type-def type-id='0882dfdf' size-in-bits='64' id='2e3e7caa'/>
|
||||||
<pointer-type-def type-id='f47b023a' size-in-bits='64' id='d87f9b75'/>
|
<pointer-type-def type-id='f47b023a' size-in-bits='64' id='d87f9b75'/>
|
||||||
<pointer-type-def type-id='09286066' size-in-bits='64' id='940e3afc'/>
|
<pointer-type-def type-id='09286066' size-in-bits='64' id='940e3afc'/>
|
||||||
|
@ -3304,11 +3309,6 @@
|
||||||
<parameter type-id='b59d7dce'/>
|
<parameter type-id='b59d7dce'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='stat64' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='9d26089a'/>
|
|
||||||
<parameter type-id='f1cadedf'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='clock_gettime' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='clock_gettime' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='a1c3b834'/>
|
<parameter type-id='a1c3b834'/>
|
||||||
<parameter type-id='3d83ba87'/>
|
<parameter type-id='3d83ba87'/>
|
||||||
|
@ -3318,6 +3318,11 @@
|
||||||
<parameter type-id='4e80d4b1'/>
|
<parameter type-id='4e80d4b1'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
|
<function-decl name='stat64' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='9d26089a'/>
|
||||||
|
<parameter type-id='f1cadedf'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
<function-decl name='zfs_dev_flush' mangled-name='zfs_dev_flush' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_dev_flush'>
|
<function-decl name='zfs_dev_flush' mangled-name='zfs_dev_flush' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_dev_flush'>
|
||||||
<parameter type-id='95e97e5e' name='fd'/>
|
<parameter type-id='95e97e5e' name='fd'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
|
@ -3372,23 +3377,10 @@
|
||||||
<parameter type-id='95e97e5e' name='wholedisk'/>
|
<parameter type-id='95e97e5e' name='wholedisk'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='snprintf' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='26a90f95'/>
|
|
||||||
<parameter type-id='b59d7dce'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter is-variadic='yes'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='getenv' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='getenv' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
<return type-id='26a90f95'/>
|
<return type-id='26a90f95'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='memset' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='eaa32e2f'/>
|
|
||||||
<parameter type-id='95e97e5e'/>
|
|
||||||
<parameter type-id='b59d7dce'/>
|
|
||||||
<return type-id='eaa32e2f'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='strcmp' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='strcmp' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
|
@ -3442,20 +3434,6 @@
|
||||||
<class-decl name='_IO_marker' is-struct='yes' visibility='default' is-declaration-only='yes' id='010ae0b9'/>
|
<class-decl name='_IO_marker' is-struct='yes' visibility='default' is-declaration-only='yes' id='010ae0b9'/>
|
||||||
<class-decl name='_IO_wide_data' is-struct='yes' visibility='default' is-declaration-only='yes' id='79bd3751'/>
|
<class-decl name='_IO_wide_data' is-struct='yes' visibility='default' is-declaration-only='yes' id='79bd3751'/>
|
||||||
<class-decl name='__dirstream' is-struct='yes' visibility='default' is-declaration-only='yes' id='20cd73f2'/>
|
<class-decl name='__dirstream' is-struct='yes' visibility='default' is-declaration-only='yes' id='20cd73f2'/>
|
||||||
<class-decl name='__va_list_tag' size-in-bits='192' is-struct='yes' visibility='default' id='d5027220'>
|
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
|
||||||
<var-decl name='gp_offset' type-id='f0981eeb' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='32'>
|
|
||||||
<var-decl name='fp_offset' type-id='f0981eeb' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='64'>
|
|
||||||
<var-decl name='overflow_arg_area' type-id='eaa32e2f' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='128'>
|
|
||||||
<var-decl name='reg_save_area' type-id='eaa32e2f' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
</class-decl>
|
|
||||||
<class-decl name='tpool' size-in-bits='2496' is-struct='yes' visibility='default' id='88d1b7f9'>
|
<class-decl name='tpool' size-in-bits='2496' is-struct='yes' visibility='default' id='88d1b7f9'>
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
<var-decl name='tp_forw' type-id='9cf59a50' visibility='default'/>
|
<var-decl name='tp_forw' type-id='9cf59a50' visibility='default'/>
|
||||||
|
@ -3645,6 +3623,8 @@
|
||||||
<var-decl name='__glibc_reserved' type-id='16dc656a' visibility='default'/>
|
<var-decl name='__glibc_reserved' type-id='16dc656a' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
</class-decl>
|
</class-decl>
|
||||||
|
<typedef-decl name='DIR' type-id='20cd73f2' id='54a5d683'/>
|
||||||
|
<typedef-decl name='uintptr_t' type-id='7359adad' id='e475ab95'/>
|
||||||
<class-decl name='dirent64' size-in-bits='2240' is-struct='yes' visibility='default' id='5725d813'>
|
<class-decl name='dirent64' size-in-bits='2240' is-struct='yes' visibility='default' id='5725d813'>
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
<var-decl name='d_ino' type-id='71288a47' visibility='default'/>
|
<var-decl name='d_ino' type-id='71288a47' visibility='default'/>
|
||||||
|
@ -3810,10 +3790,10 @@
|
||||||
<var-decl name='sigev_notify' type-id='95e97e5e' visibility='default'/>
|
<var-decl name='sigev_notify' type-id='95e97e5e' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
<data-member access='public' layout-offset-in-bits='128'>
|
<data-member access='public' layout-offset-in-bits='128'>
|
||||||
<var-decl name='_sigev_un' type-id='ac5ab598' visibility='default'/>
|
<var-decl name='_sigev_un' type-id='ac5ab596' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
</class-decl>
|
</class-decl>
|
||||||
<union-decl name='__anonymous_union__' size-in-bits='384' is-anonymous='yes' visibility='default' id='ac5ab598'>
|
<union-decl name='__anonymous_union__' size-in-bits='384' is-anonymous='yes' visibility='default' id='ac5ab596'>
|
||||||
<data-member access='public'>
|
<data-member access='public'>
|
||||||
<var-decl name='_pad' type-id='73b82f0f' visibility='default'/>
|
<var-decl name='_pad' type-id='73b82f0f' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
|
@ -3930,8 +3910,6 @@
|
||||||
<var-decl name='tv_nsec' type-id='03085adc' visibility='default'/>
|
<var-decl name='tv_nsec' type-id='03085adc' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
</class-decl>
|
</class-decl>
|
||||||
<typedef-decl name='DIR' type-id='20cd73f2' id='54a5d683'/>
|
|
||||||
<typedef-decl name='uintptr_t' type-id='7359adad' id='e475ab95'/>
|
|
||||||
<pointer-type-def type-id='54a5d683' size-in-bits='64' id='f09217ba'/>
|
<pointer-type-def type-id='54a5d683' size-in-bits='64' id='f09217ba'/>
|
||||||
<pointer-type-def type-id='aa12d1ba' size-in-bits='64' id='822cd80b'/>
|
<pointer-type-def type-id='aa12d1ba' size-in-bits='64' id='822cd80b'/>
|
||||||
<qualified-type-def type-id='822cd80b' restrict='yes' id='e75a27e9'/>
|
<qualified-type-def type-id='822cd80b' restrict='yes' id='e75a27e9'/>
|
||||||
|
@ -3940,7 +3918,6 @@
|
||||||
<pointer-type-def type-id='bb4788fa' size-in-bits='64' id='cecf4ea7'/>
|
<pointer-type-def type-id='bb4788fa' size-in-bits='64' id='cecf4ea7'/>
|
||||||
<pointer-type-def type-id='010ae0b9' size-in-bits='64' id='e4c6fa61'/>
|
<pointer-type-def type-id='010ae0b9' size-in-bits='64' id='e4c6fa61'/>
|
||||||
<pointer-type-def type-id='79bd3751' size-in-bits='64' id='c65a1f29'/>
|
<pointer-type-def type-id='79bd3751' size-in-bits='64' id='c65a1f29'/>
|
||||||
<pointer-type-def type-id='d5027220' size-in-bits='64' id='b7f2d5e6'/>
|
|
||||||
<pointer-type-def type-id='e4957c49' size-in-bits='64' id='924bbc81'/>
|
<pointer-type-def type-id='e4957c49' size-in-bits='64' id='924bbc81'/>
|
||||||
<qualified-type-def type-id='924bbc81' const='yes' id='5499dcde'/>
|
<qualified-type-def type-id='924bbc81' const='yes' id='5499dcde'/>
|
||||||
<pointer-type-def type-id='5499dcde' size-in-bits='64' id='2236d41c'/>
|
<pointer-type-def type-id='5499dcde' size-in-bits='64' id='2236d41c'/>
|
||||||
|
@ -4242,25 +4219,6 @@
|
||||||
<parameter type-id='18c91f9e'/>
|
<parameter type-id='18c91f9e'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='fprintf' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='e75a27e9'/>
|
|
||||||
<parameter type-id='9d26089a'/>
|
|
||||||
<parameter is-variadic='yes'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='vsnprintf' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='26a90f95'/>
|
|
||||||
<parameter type-id='b59d7dce'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='b7f2d5e6'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='asprintf' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='8c85230f'/>
|
|
||||||
<parameter type-id='9d26089a'/>
|
|
||||||
<parameter is-variadic='yes'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='strtoull' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='strtoull' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='9d26089a'/>
|
<parameter type-id='9d26089a'/>
|
||||||
<parameter type-id='8c85230f'/>
|
<parameter type-id='8c85230f'/>
|
||||||
|
@ -4282,11 +4240,6 @@
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
<return type-id='48b5725f'/>
|
<return type-id='48b5725f'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='realpath' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='9d26089a'/>
|
|
||||||
<parameter type-id='266fe297'/>
|
|
||||||
<return type-id='26a90f95'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='strncmp' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='strncmp' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
|
@ -4302,6 +4255,41 @@
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
<return type-id='26a90f95'/>
|
<return type-id='26a90f95'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
|
<function-decl name='sysconf' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<return type-id='bd54fe1a'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='geteuid' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<return type-id='cc5fcceb'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='__fprintf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='e75a27e9'/>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<parameter type-id='9d26089a'/>
|
||||||
|
<parameter is-variadic='yes'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='__asprintf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='8c85230f'/>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<parameter type-id='9d26089a'/>
|
||||||
|
<parameter is-variadic='yes'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='__realpath_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='9d26089a'/>
|
||||||
|
<parameter type-id='266fe297'/>
|
||||||
|
<parameter type-id='b59d7dce'/>
|
||||||
|
<return type-id='26a90f95'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='__pread64_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<parameter type-id='eaa32e2f'/>
|
||||||
|
<parameter type-id='b59d7dce'/>
|
||||||
|
<parameter type-id='724e4de6'/>
|
||||||
|
<parameter type-id='b59d7dce'/>
|
||||||
|
<return type-id='79a0948f'/>
|
||||||
|
</function-decl>
|
||||||
<function-decl name='ioctl' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='ioctl' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
<parameter type-id='7359adad'/>
|
<parameter type-id='7359adad'/>
|
||||||
|
@ -4313,20 +4301,6 @@
|
||||||
<parameter type-id='62f7a03d'/>
|
<parameter type-id='62f7a03d'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='pread64' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='95e97e5e'/>
|
|
||||||
<parameter type-id='eaa32e2f'/>
|
|
||||||
<parameter type-id='b59d7dce'/>
|
|
||||||
<parameter type-id='724e4de6'/>
|
|
||||||
<return type-id='79a0948f'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='sysconf' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='95e97e5e'/>
|
|
||||||
<return type-id='bd54fe1a'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='geteuid' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<return type-id='cc5fcceb'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-type size-in-bits='64' id='baa42fef'>
|
<function-type size-in-bits='64' id='baa42fef'>
|
||||||
<parameter type-id='eaa32e2f'/>
|
<parameter type-id='eaa32e2f'/>
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
|
@ -4404,6 +4378,9 @@
|
||||||
<parameter type-id='b59d7dce' name='buflen'/>
|
<parameter type-id='b59d7dce' name='buflen'/>
|
||||||
<return type-id='48b5725f'/>
|
<return type-id='48b5725f'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
|
<function-decl name='__ctype_b_loc' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<return type-id='c59e1ef0'/>
|
||||||
|
</function-decl>
|
||||||
<function-decl name='powl' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='powl' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='e095c704'/>
|
<parameter type-id='e095c704'/>
|
||||||
<parameter type-id='e095c704'/>
|
<parameter type-id='e095c704'/>
|
||||||
|
@ -4413,9 +4390,6 @@
|
||||||
<parameter type-id='a0eb0f08'/>
|
<parameter type-id='a0eb0f08'/>
|
||||||
<return type-id='a0eb0f08'/>
|
<return type-id='a0eb0f08'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='__ctype_b_loc' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<return type-id='c59e1ef0'/>
|
|
||||||
</function-decl>
|
|
||||||
</abi-instr>
|
</abi-instr>
|
||||||
<abi-instr address-size='64' path='zutil_pool.c' language='LANG_C99'>
|
<abi-instr address-size='64' path='zutil_pool.c' language='LANG_C99'>
|
||||||
<array-type-def dimensions='1' type-id='853fd5dc' size-in-bits='32768' id='b505fc2f'>
|
<array-type-def dimensions='1' type-id='853fd5dc' size-in-bits='32768' id='b505fc2f'>
|
||||||
|
@ -4471,15 +4445,16 @@
|
||||||
<parameter type-id='4dd26a40' name='numrecords'/>
|
<parameter type-id='4dd26a40' name='numrecords'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='printf' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter is-variadic='yes'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='realloc' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='realloc' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='eaa32e2f'/>
|
<parameter type-id='eaa32e2f'/>
|
||||||
<parameter type-id='b59d7dce'/>
|
<parameter type-id='b59d7dce'/>
|
||||||
<return type-id='eaa32e2f'/>
|
<return type-id='eaa32e2f'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
|
<function-decl name='__printf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<parameter type-id='80f4b756'/>
|
||||||
|
<parameter is-variadic='yes'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
</abi-instr>
|
</abi-instr>
|
||||||
</abi-corpus>
|
</abi-corpus>
|
||||||
|
|
|
@ -1,16 +1,7 @@
|
||||||
<abi-corpus version='2.0' architecture='elf-amd-x86_64' soname='libzfsbootenv.so.1'>
|
<abi-corpus version='2.0' architecture='elf-amd-x86_64' soname='libzfsbootenv.so.1'>
|
||||||
<elf-needed>
|
<elf-needed>
|
||||||
<dependency name='libzfs.so.4'/>
|
<dependency name='libzfs.so.4'/>
|
||||||
<dependency name='libzfs_core.so.3'/>
|
|
||||||
<dependency name='libuuid.so.1'/>
|
|
||||||
<dependency name='libblkid.so.1'/>
|
|
||||||
<dependency name='libudev.so.1'/>
|
|
||||||
<dependency name='libuutil.so.3'/>
|
|
||||||
<dependency name='libm.so.6'/>
|
|
||||||
<dependency name='libcrypto.so.1.1'/>
|
|
||||||
<dependency name='libz.so.1'/>
|
|
||||||
<dependency name='libnvpair.so.3'/>
|
<dependency name='libnvpair.so.3'/>
|
||||||
<dependency name='libtirpc.so.3'/>
|
|
||||||
<dependency name='libc.so.6'/>
|
<dependency name='libc.so.6'/>
|
||||||
</elf-needed>
|
</elf-needed>
|
||||||
<elf-function-symbols>
|
<elf-function-symbols>
|
||||||
|
@ -289,18 +280,6 @@
|
||||||
<parameter type-id='9b23c9ad' name='device'/>
|
<parameter type-id='9b23c9ad' name='device'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='fprintf' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='e75a27e9'/>
|
|
||||||
<parameter type-id='9d26089a'/>
|
|
||||||
<parameter is-variadic='yes'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='asprintf' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='8c85230f'/>
|
|
||||||
<parameter type-id='9d26089a'/>
|
|
||||||
<parameter is-variadic='yes'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='free' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='free' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='eaa32e2f'/>
|
<parameter type-id='eaa32e2f'/>
|
||||||
<return type-id='48b5725f'/>
|
<return type-id='48b5725f'/>
|
||||||
|
@ -319,6 +298,20 @@
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
<return type-id='b59d7dce'/>
|
<return type-id='b59d7dce'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
|
<function-decl name='__fprintf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='e75a27e9'/>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<parameter type-id='9d26089a'/>
|
||||||
|
<parameter is-variadic='yes'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='__asprintf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='8c85230f'/>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<parameter type-id='9d26089a'/>
|
||||||
|
<parameter is-variadic='yes'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
</abi-instr>
|
</abi-instr>
|
||||||
<abi-instr address-size='64' path='lzbe_pair.c' language='LANG_C99'>
|
<abi-instr address-size='64' path='lzbe_pair.c' language='LANG_C99'>
|
||||||
<type-decl name='short int' size-in-bits='16' id='a2185560'/>
|
<type-decl name='short int' size-in-bits='16' id='a2185560'/>
|
||||||
|
|
|
@ -951,6 +951,18 @@ receive of encrypted datasets.
|
||||||
Intended for users whose pools were created with
|
Intended for users whose pools were created with
|
||||||
OpenZFS pre-release versions and now have compatibility issues.
|
OpenZFS pre-release versions and now have compatibility issues.
|
||||||
.
|
.
|
||||||
|
.It Sy zfs_forced_export_unmount Ns = Ns Sy 0 Ns | Ns 1 Pq int
|
||||||
|
During forced unmount, leave the filesystem in a disabled mode of operation,
|
||||||
|
in which all new I/Os fail, except for those required to unmount it.
|
||||||
|
Intended for users trying to forcibly export a pool even when I/Os are in
|
||||||
|
progress, without the need to find and stop them.
|
||||||
|
This option does not affect processes that are merely sitting on the
|
||||||
|
filesystem, only those performing active I/O.
|
||||||
|
.Pp
|
||||||
|
This parameter can be set to 1 to enable this behavior.
|
||||||
|
.Pp
|
||||||
|
This parameter only applies on Linux.
|
||||||
|
.
|
||||||
.It Sy zfs_key_max_salt_uses Ns = Ns Sy 400000000 Po 4*10^8 Pc Pq ulong
|
.It Sy zfs_key_max_salt_uses Ns = Ns Sy 400000000 Po 4*10^8 Pc Pq ulong
|
||||||
Maximum number of uses of a single salt value before generating a new one for
|
Maximum number of uses of a single salt value before generating a new one for
|
||||||
encrypted datasets.
|
encrypted datasets.
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
.\" Copyright 2017 Nexenta Systems, Inc.
|
.\" Copyright 2017 Nexenta Systems, Inc.
|
||||||
.\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
|
.\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
|
||||||
.\"
|
.\"
|
||||||
.Dd February 16, 2020
|
.Dd November 1, 2022
|
||||||
.Dt ZPOOL-EXPORT 8
|
.Dt ZPOOL-EXPORT 8
|
||||||
.Os
|
.Os
|
||||||
.
|
.
|
||||||
|
@ -37,6 +37,7 @@
|
||||||
.Nm zpool
|
.Nm zpool
|
||||||
.Cm export
|
.Cm export
|
||||||
.Op Fl f
|
.Op Fl f
|
||||||
|
.Op Fl F
|
||||||
.Fl a Ns | Ns Ar pool Ns …
|
.Fl a Ns | Ns Ar pool Ns …
|
||||||
.
|
.
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
|
@ -66,6 +67,15 @@ Forcefully unmount all datasets, and allow export of pools with active shared sp
|
||||||
This command will forcefully export the pool even if it has a shared spare that
|
This command will forcefully export the pool even if it has a shared spare that
|
||||||
is currently being used.
|
is currently being used.
|
||||||
This may lead to potential data corruption.
|
This may lead to potential data corruption.
|
||||||
|
.It Fl F
|
||||||
|
Forcibly export the pool.
|
||||||
|
.Pp
|
||||||
|
This option allows a pool to be exported even when the underlying disks are
|
||||||
|
offline and the pool is unavailable.
|
||||||
|
When force exporting a pool, any outstanding dirty data will be discarded.
|
||||||
|
This option implies the
|
||||||
|
.Fl f
|
||||||
|
option.
|
||||||
.El
|
.El
|
||||||
.
|
.
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
|
|
|
@ -108,6 +108,16 @@ spl_panic(const char *file, const char *func, int line, const char *fmt, ...)
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
spl_kthread_signal(kthread_t *td, int sig)
|
||||||
|
{
|
||||||
|
|
||||||
|
PROC_LOCK(td->td_proc);
|
||||||
|
tdsignal(td, sig);
|
||||||
|
PROC_UNLOCK(td->td_proc);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SYSINIT(opensolaris_utsname_init, SI_SUB_TUNABLES, SI_ORDER_ANY,
|
SYSINIT(opensolaris_utsname_init, SI_SUB_TUNABLES, SI_ORDER_ANY,
|
||||||
opensolaris_utsname_init, NULL);
|
opensolaris_utsname_init, NULL);
|
||||||
|
|
|
@ -214,3 +214,15 @@ issig(int why)
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(issig);
|
EXPORT_SYMBOL(issig);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* spl_kthread_signal - Wrapper for sending signals to a thread.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
spl_kthread_signal(kthread_t *tsk, int sig)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (send_sig(sig, tsk, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_SYMBOL(spl_kthread_signal);
|
||||||
|
|
|
@ -563,7 +563,6 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs)
|
||||||
void
|
void
|
||||||
zfs_unlinked_drain_stop_wait(zfsvfs_t *zfsvfs)
|
zfs_unlinked_drain_stop_wait(zfsvfs_t *zfsvfs)
|
||||||
{
|
{
|
||||||
ASSERT3B(zfsvfs->z_unmounted, ==, B_FALSE);
|
|
||||||
|
|
||||||
if (zfsvfs->z_draining) {
|
if (zfsvfs->z_draining) {
|
||||||
zfsvfs->z_drain_cancel = B_TRUE;
|
zfsvfs->z_drain_cancel = B_TRUE;
|
||||||
|
|
|
@ -218,9 +218,27 @@ zfs_ioctl_update_mount_cache(const char *dsname)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
zfs_ioc_pool_unmount_begin(zfs_cmd_t *zc)
|
||||||
|
{
|
||||||
|
return (spa_set_pre_export_status(zc->zc_name, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
zfs_ioc_pool_unmount_end(zfs_cmd_t *zc)
|
||||||
|
{
|
||||||
|
return (spa_set_pre_export_status(zc->zc_name, false));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
zfs_ioctl_init_os(void)
|
zfs_ioctl_init_os(void)
|
||||||
{
|
{
|
||||||
|
zfs_ioctl_register_pool(ZFS_IOC_HARD_FORCE_UNMOUNT_BEGIN,
|
||||||
|
zfs_ioc_pool_unmount_begin, zfs_secpolicy_config, B_FALSE,
|
||||||
|
POOL_CHECK_NONE);
|
||||||
|
zfs_ioctl_register_pool(ZFS_IOC_HARD_FORCE_UNMOUNT_END,
|
||||||
|
zfs_ioc_pool_unmount_end, zfs_secpolicy_config, B_FALSE,
|
||||||
|
POOL_CHECK_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
|
|
|
@ -1095,7 +1095,7 @@ zfs_statvfs(struct inode *ip, struct kstatfs *statp)
|
||||||
uint64_t refdbytes, availbytes, usedobjs, availobjs;
|
uint64_t refdbytes, availbytes, usedobjs, availobjs;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
ZFS_ENTER(zfsvfs);
|
ZFS_ENTER_UNMOUNTOK(zfsvfs);
|
||||||
|
|
||||||
dmu_objset_space(zfsvfs->z_os,
|
dmu_objset_space(zfsvfs->z_os,
|
||||||
&refdbytes, &availbytes, &usedobjs, &availobjs);
|
&refdbytes, &availbytes, &usedobjs, &availobjs);
|
||||||
|
@ -1166,7 +1166,7 @@ zfs_root(zfsvfs_t *zfsvfs, struct inode **ipp)
|
||||||
znode_t *rootzp;
|
znode_t *rootzp;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
ZFS_ENTER(zfsvfs);
|
ZFS_ENTER_UNMOUNTOK(zfsvfs);
|
||||||
|
|
||||||
error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp);
|
error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp);
|
||||||
if (error == 0)
|
if (error == 0)
|
||||||
|
@ -1310,6 +1310,8 @@ static int
|
||||||
zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
|
zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
|
||||||
{
|
{
|
||||||
znode_t *zp;
|
znode_t *zp;
|
||||||
|
kthread_t *initiator = NULL;
|
||||||
|
uint64_t wait_flags = 0;
|
||||||
|
|
||||||
zfs_unlinked_drain_stop_wait(zfsvfs);
|
zfs_unlinked_drain_stop_wait(zfsvfs);
|
||||||
|
|
||||||
|
@ -1339,6 +1341,15 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
|
||||||
if (++round > 1 && !unmounting)
|
if (++round > 1 && !unmounting)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
initiator = zfsvfs->z_os->os_shutdown_initiator;
|
||||||
|
/*
|
||||||
|
* Although it could be argued that a force unmount in
|
||||||
|
* another thread shouldn't have this apply, once a force
|
||||||
|
* unmount is in effect, it's pointless for the non-forced
|
||||||
|
* unmount to not use this flag.
|
||||||
|
*/
|
||||||
|
if (initiator != NULL)
|
||||||
|
wait_flags |= TXG_WAIT_F_NOSUSPEND;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZFS_TEARDOWN_ENTER_WRITE(zfsvfs, FTAG);
|
ZFS_TEARDOWN_ENTER_WRITE(zfsvfs, FTAG);
|
||||||
|
@ -1371,6 +1382,10 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
|
||||||
* or a reopen of z_os failed then just bail out now.
|
* or a reopen of z_os failed then just bail out now.
|
||||||
*/
|
*/
|
||||||
if (!unmounting && (zfsvfs->z_unmounted || zfsvfs->z_os == NULL)) {
|
if (!unmounting && (zfsvfs->z_unmounted || zfsvfs->z_os == NULL)) {
|
||||||
|
if (initiator == curthread) {
|
||||||
|
zfsvfs->z_unmounted = B_FALSE;
|
||||||
|
dmu_objset_shutdown_unregister(zfsvfs->z_os);
|
||||||
|
}
|
||||||
rw_exit(&zfsvfs->z_teardown_inactive_lock);
|
rw_exit(&zfsvfs->z_teardown_inactive_lock);
|
||||||
ZFS_TEARDOWN_EXIT(zfsvfs, FTAG);
|
ZFS_TEARDOWN_EXIT(zfsvfs, FTAG);
|
||||||
return (SET_ERROR(EIO));
|
return (SET_ERROR(EIO));
|
||||||
|
@ -1439,12 +1454,16 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!zfs_is_readonly(zfsvfs) && os_dirty) {
|
if (!zfs_is_readonly(zfsvfs) && os_dirty) {
|
||||||
txg_wait_synced(dmu_objset_pool(zfsvfs->z_os), 0);
|
(void) txg_wait_synced_tx(dmu_objset_pool(zfsvfs->z_os), 0,
|
||||||
|
NULL, wait_flags);
|
||||||
}
|
}
|
||||||
dmu_objset_evict_dbufs(zfsvfs->z_os);
|
dmu_objset_evict_dbufs(zfsvfs->z_os);
|
||||||
dsl_dir_t *dd = os->os_dsl_dataset->ds_dir;
|
dsl_dir_t *dd = os->os_dsl_dataset->ds_dir;
|
||||||
dsl_dir_cancel_waiters(dd);
|
dsl_dir_cancel_waiters(dd);
|
||||||
|
|
||||||
|
if (initiator == curthread)
|
||||||
|
dmu_objset_shutdown_unregister(zfsvfs->z_os);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -227,9 +227,10 @@ zfs_close(struct inode *ip, int flag, cred_t *cr)
|
||||||
{
|
{
|
||||||
znode_t *zp = ITOZ(ip);
|
znode_t *zp = ITOZ(ip);
|
||||||
zfsvfs_t *zfsvfs = ITOZSB(ip);
|
zfsvfs_t *zfsvfs = ITOZSB(ip);
|
||||||
|
int error;
|
||||||
|
|
||||||
ZFS_ENTER(zfsvfs);
|
if ((error = zfs_enter_unmountok_verify_zp(zfsvfs, zp, FTAG)) != 0)
|
||||||
ZFS_VERIFY_ZP(zp);
|
return (error);
|
||||||
|
|
||||||
/* Decrement the synchronous opens in the znode */
|
/* Decrement the synchronous opens in the znode */
|
||||||
if (flag & O_SYNC)
|
if (flag & O_SYNC)
|
||||||
|
@ -1669,9 +1670,10 @@ zfs_getattr_fast(struct user_namespace *user_ns, struct inode *ip,
|
||||||
zfsvfs_t *zfsvfs = ITOZSB(ip);
|
zfsvfs_t *zfsvfs = ITOZSB(ip);
|
||||||
uint32_t blksize;
|
uint32_t blksize;
|
||||||
u_longlong_t nblocks;
|
u_longlong_t nblocks;
|
||||||
|
int error;
|
||||||
|
|
||||||
ZFS_ENTER(zfsvfs);
|
if ((error = zfs_enter_unmountok_verify_zp(zfsvfs, zp, FTAG)) != 0)
|
||||||
ZFS_VERIFY_ZP(zp);
|
return (error);
|
||||||
|
|
||||||
mutex_enter(&zp->z_lock);
|
mutex_enter(&zp->z_lock);
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,10 @@
|
||||||
#include <sys/zfs_vnops.h>
|
#include <sys/zfs_vnops.h>
|
||||||
#include <sys/zfs_ctldir.h>
|
#include <sys/zfs_ctldir.h>
|
||||||
#include <sys/zpl.h>
|
#include <sys/zpl.h>
|
||||||
|
#include <sys/dmu_objset.h>
|
||||||
|
#include <sys/dsl_dir.h>
|
||||||
|
|
||||||
|
int zfs_forced_export_unmount_enabled = 0;
|
||||||
|
|
||||||
static struct inode *
|
static struct inode *
|
||||||
zpl_inode_alloc(struct super_block *sb)
|
zpl_inode_alloc(struct super_block *sb)
|
||||||
|
@ -102,6 +105,31 @@ zpl_evict_inode(struct inode *ip)
|
||||||
spl_fstrans_unmark(cookie);
|
spl_fstrans_unmark(cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
zpl_umount_begin(struct super_block *sb)
|
||||||
|
{
|
||||||
|
zfsvfs_t *zfsvfs = sb->s_fs_info;
|
||||||
|
|
||||||
|
if (zfsvfs) {
|
||||||
|
/*
|
||||||
|
* Flush out all POSIX I/Os. Notify all waiters that they
|
||||||
|
* must end, then wait for all users to drop their holds on
|
||||||
|
* z_teardown_*_lock, and evict buffers.
|
||||||
|
*/
|
||||||
|
if (zfs_forced_export_unmount_enabled)
|
||||||
|
zfsvfs->z_force_unmounted = B_TRUE;
|
||||||
|
(void) dmu_objset_shutdown_register(zfsvfs->z_os);
|
||||||
|
rrm_enter(&zfsvfs->z_teardown_lock, RW_WRITER, FTAG);
|
||||||
|
rw_enter(&zfsvfs->z_teardown_inactive_lock, RW_WRITER);
|
||||||
|
rw_exit(&zfsvfs->z_teardown_inactive_lock);
|
||||||
|
rrm_exit(&zfsvfs->z_teardown_lock, FTAG);
|
||||||
|
dmu_objset_evict_dbufs(zfsvfs->z_os);
|
||||||
|
|
||||||
|
dsl_dir_cancel_waiters(zfsvfs->z_os->os_dsl_dataset->ds_dir);
|
||||||
|
dmu_objset_shutdown_unregister(zfsvfs->z_os);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zpl_put_super(struct super_block *sb)
|
zpl_put_super(struct super_block *sb)
|
||||||
{
|
{
|
||||||
|
@ -185,7 +213,8 @@ zpl_remount_fs(struct super_block *sb, int *flags, char *data)
|
||||||
static int
|
static int
|
||||||
__zpl_show_devname(struct seq_file *seq, zfsvfs_t *zfsvfs)
|
__zpl_show_devname(struct seq_file *seq, zfsvfs_t *zfsvfs)
|
||||||
{
|
{
|
||||||
ZPL_ENTER(zfsvfs);
|
|
||||||
|
ZFS_ENTER_UNMOUNTOK(zfsvfs);
|
||||||
|
|
||||||
char *fsname = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
|
char *fsname = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
|
||||||
dmu_objset_name(zfsvfs->z_os, fsname);
|
dmu_objset_name(zfsvfs->z_os, fsname);
|
||||||
|
@ -349,6 +378,7 @@ const struct super_operations zpl_super_operations = {
|
||||||
.write_inode = NULL,
|
.write_inode = NULL,
|
||||||
.evict_inode = zpl_evict_inode,
|
.evict_inode = zpl_evict_inode,
|
||||||
.put_super = zpl_put_super,
|
.put_super = zpl_put_super,
|
||||||
|
.umount_begin = zpl_umount_begin,
|
||||||
.sync_fs = zpl_sync_fs,
|
.sync_fs = zpl_sync_fs,
|
||||||
.statfs = zpl_statfs,
|
.statfs = zpl_statfs,
|
||||||
.remount_fs = zpl_remount_fs,
|
.remount_fs = zpl_remount_fs,
|
||||||
|
@ -363,3 +393,8 @@ struct file_system_type zpl_fs_type = {
|
||||||
.mount = zpl_mount,
|
.mount = zpl_mount,
|
||||||
.kill_sb = zpl_kill_sb,
|
.kill_sb = zpl_kill_sb,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* BEGIN CSTYLED */
|
||||||
|
ZFS_MODULE_PARAM(zfs, zfs_, forced_export_unmount_enabled, INT, ZMOD_RW,
|
||||||
|
"Enable forced export unmount to keep POSIX I/O users off");
|
||||||
|
/* END CSTYLED */
|
||||||
|
|
|
@ -9997,6 +9997,18 @@ l2arc_rebuild_vdev(vdev_t *vd, boolean_t reopen)
|
||||||
l2arc_rebuild_dev(dev, reopen);
|
l2arc_rebuild_dev(dev, reopen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
l2arc_dev_rebuild_stop(l2arc_dev_t *l2ad)
|
||||||
|
{
|
||||||
|
mutex_enter(&l2arc_rebuild_thr_lock);
|
||||||
|
if (l2ad->l2ad_rebuild_began == B_TRUE) {
|
||||||
|
l2ad->l2ad_rebuild_cancel = B_TRUE;
|
||||||
|
while (l2ad->l2ad_rebuild == B_TRUE)
|
||||||
|
cv_wait(&l2arc_rebuild_thr_cv, &l2arc_rebuild_thr_lock);
|
||||||
|
}
|
||||||
|
mutex_exit(&l2arc_rebuild_thr_lock);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove a vdev from the L2ARC.
|
* Remove a vdev from the L2ARC.
|
||||||
*/
|
*/
|
||||||
|
@ -10014,13 +10026,7 @@ l2arc_remove_vdev(vdev_t *vd)
|
||||||
/*
|
/*
|
||||||
* Cancel any ongoing or scheduled rebuild.
|
* Cancel any ongoing or scheduled rebuild.
|
||||||
*/
|
*/
|
||||||
mutex_enter(&l2arc_rebuild_thr_lock);
|
l2arc_dev_rebuild_stop(remdev);
|
||||||
if (remdev->l2ad_rebuild_began == B_TRUE) {
|
|
||||||
remdev->l2ad_rebuild_cancel = B_TRUE;
|
|
||||||
while (remdev->l2ad_rebuild == B_TRUE)
|
|
||||||
cv_wait(&l2arc_rebuild_thr_cv, &l2arc_rebuild_thr_lock);
|
|
||||||
}
|
|
||||||
mutex_exit(&l2arc_rebuild_thr_lock);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove device from global list
|
* Remove device from global list
|
||||||
|
@ -10136,6 +10142,25 @@ l2arc_spa_rebuild_start(spa_t *spa)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
l2arc_spa_rebuild_stop(spa_t *spa)
|
||||||
|
{
|
||||||
|
ASSERT(MUTEX_HELD(&spa_namespace_lock));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Locate the spa's l2arc devices and kick off rebuild threads.
|
||||||
|
*/
|
||||||
|
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) {
|
||||||
|
/* Don't attempt a rebuild if the vdev is UNAVAIL */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
l2arc_dev_rebuild_stop(dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Main entry point for L2ARC rebuilding.
|
* Main entry point for L2ARC rebuilding.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -981,11 +981,12 @@ dbuf_verify(dmu_buf_impl_t *db)
|
||||||
uint32_t txg_prev;
|
uint32_t txg_prev;
|
||||||
|
|
||||||
ASSERT(MUTEX_HELD(&db->db_mtx));
|
ASSERT(MUTEX_HELD(&db->db_mtx));
|
||||||
|
ASSERT(db->db_objset != NULL);
|
||||||
|
|
||||||
if (!(zfs_flags & ZFS_DEBUG_DBUF_VERIFY))
|
if (!(zfs_flags & ZFS_DEBUG_DBUF_VERIFY) ||
|
||||||
|
dmu_objset_exiting(db->db_objset))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ASSERT(db->db_objset != NULL);
|
|
||||||
DB_DNODE_ENTER(db);
|
DB_DNODE_ENTER(db);
|
||||||
dn = DB_DNODE(db);
|
dn = DB_DNODE(db);
|
||||||
if (dn == NULL) {
|
if (dn == NULL) {
|
||||||
|
@ -1069,7 +1070,8 @@ dbuf_verify(dmu_buf_impl_t *db)
|
||||||
if ((db->db_blkptr == NULL || BP_IS_HOLE(db->db_blkptr)) &&
|
if ((db->db_blkptr == NULL || BP_IS_HOLE(db->db_blkptr)) &&
|
||||||
(db->db_buf == NULL || db->db_buf->b_data) &&
|
(db->db_buf == NULL || db->db_buf->b_data) &&
|
||||||
db->db.db_data && db->db_blkid != DMU_BONUS_BLKID &&
|
db->db.db_data && db->db_blkid != DMU_BONUS_BLKID &&
|
||||||
db->db_state != DB_FILL && !dn->dn_free_txg) {
|
db->db_state != DB_FILL && (dn == NULL || !dn->dn_free_txg) &&
|
||||||
|
!dmu_objset_exiting(db->db_objset)) {
|
||||||
/*
|
/*
|
||||||
* If the blkptr isn't set but they have nonzero data,
|
* If the blkptr isn't set but they have nonzero data,
|
||||||
* it had better be dirty, otherwise we'll lose that
|
* it had better be dirty, otherwise we'll lose that
|
||||||
|
@ -2182,7 +2184,7 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
|
||||||
* this assertion only if we're not already dirty.
|
* this assertion only if we're not already dirty.
|
||||||
*/
|
*/
|
||||||
os = dn->dn_objset;
|
os = dn->dn_objset;
|
||||||
VERIFY3U(tx->tx_txg, <=, spa_final_dirty_txg(os->os_spa));
|
spa_verify_dirty_txg(os->os_spa, dmu_tx_get_txg(tx));
|
||||||
#ifdef ZFS_DEBUG
|
#ifdef ZFS_DEBUG
|
||||||
if (dn->dn_objset->os_dsl_dataset != NULL)
|
if (dn->dn_objset->os_dsl_dataset != NULL)
|
||||||
rrw_enter(&os->os_dsl_dataset->ds_bp_rwlock, RW_READER, FTAG);
|
rrw_enter(&os->os_dsl_dataset->ds_bp_rwlock, RW_READER, FTAG);
|
||||||
|
@ -4199,7 +4201,11 @@ dbuf_lightweight_done(zio_t *zio)
|
||||||
{
|
{
|
||||||
dbuf_dirty_record_t *dr = zio->io_private;
|
dbuf_dirty_record_t *dr = zio->io_private;
|
||||||
|
|
||||||
VERIFY0(zio->io_error);
|
if (zio->io_error != 0) {
|
||||||
|
/* If the pool is exiting, only cleanup in-core state. */
|
||||||
|
ASSERT(spa_exiting_any(zio->io_spa));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
objset_t *os = dr->dr_dnode->dn_objset;
|
objset_t *os = dr->dr_dnode->dn_objset;
|
||||||
dmu_tx_t *tx = os->os_synctx;
|
dmu_tx_t *tx = os->os_synctx;
|
||||||
|
@ -4223,6 +4229,7 @@ dbuf_lightweight_done(zio_t *zio)
|
||||||
dr->dr_accounted % zio->io_phys_children, zio->io_txg);
|
dr->dr_accounted % zio->io_phys_children, zio->io_txg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
abd_free(dr->dt.dll.dr_abd);
|
abd_free(dr->dt.dll.dr_abd);
|
||||||
kmem_free(dr, sizeof (*dr));
|
kmem_free(dr, sizeof (*dr));
|
||||||
}
|
}
|
||||||
|
@ -4624,9 +4631,14 @@ dbuf_write_done(zio_t *zio, arc_buf_t *buf, void *vdb)
|
||||||
objset_t *os = db->db_objset;
|
objset_t *os = db->db_objset;
|
||||||
dmu_tx_t *tx = os->os_synctx;
|
dmu_tx_t *tx = os->os_synctx;
|
||||||
|
|
||||||
ASSERT0(zio->io_error);
|
|
||||||
ASSERT(db->db_blkptr == bp);
|
ASSERT(db->db_blkptr == bp);
|
||||||
|
|
||||||
|
if (zio->io_error != 0) {
|
||||||
|
/* If the pool is exiting, only cleanup in-core state. */
|
||||||
|
ASSERT(spa_exiting_any(zio->io_spa));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For nopwrites and rewrites we ensure that the bp matches our
|
* For nopwrites and rewrites we ensure that the bp matches our
|
||||||
* original and bypass all the accounting.
|
* original and bypass all the accounting.
|
||||||
|
@ -4639,6 +4651,7 @@ dbuf_write_done(zio_t *zio, arc_buf_t *buf, void *vdb)
|
||||||
dsl_dataset_block_born(ds, bp, tx);
|
dsl_dataset_block_born(ds, bp, tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
mutex_enter(&db->db_mtx);
|
mutex_enter(&db->db_mtx);
|
||||||
|
|
||||||
DBUF_VERIFY(db);
|
DBUF_VERIFY(db);
|
||||||
|
|
|
@ -1115,12 +1115,16 @@ dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
|
||||||
{
|
{
|
||||||
dmu_buf_t **dbp;
|
dmu_buf_t **dbp;
|
||||||
int numbufs;
|
int numbufs;
|
||||||
|
int error;
|
||||||
|
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
VERIFY0(dmu_buf_hold_array(os, object, offset, size,
|
error = dmu_buf_hold_array(os, object, offset, size,
|
||||||
FALSE, FTAG, &numbufs, &dbp));
|
FALSE, FTAG, &numbufs, &dbp);
|
||||||
|
VERIFY(error == 0 || spa_exiting_any(os->os_spa));
|
||||||
|
if (error != 0)
|
||||||
|
return;
|
||||||
dmu_write_impl(dbp, numbufs, offset, size, buf, tx);
|
dmu_write_impl(dbp, numbufs, offset, size, buf, tx);
|
||||||
dmu_buf_rele_array(dbp, numbufs, FTAG);
|
dmu_buf_rele_array(dbp, numbufs, FTAG);
|
||||||
}
|
}
|
||||||
|
@ -1134,12 +1138,16 @@ dmu_write_by_dnode(dnode_t *dn, uint64_t offset, uint64_t size,
|
||||||
{
|
{
|
||||||
dmu_buf_t **dbp;
|
dmu_buf_t **dbp;
|
||||||
int numbufs;
|
int numbufs;
|
||||||
|
int error;
|
||||||
|
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
VERIFY0(dmu_buf_hold_array_by_dnode(dn, offset, size,
|
error = dmu_buf_hold_array_by_dnode(dn, offset, size,
|
||||||
FALSE, FTAG, &numbufs, &dbp, DMU_READ_PREFETCH));
|
FALSE, FTAG, &numbufs, &dbp, DMU_READ_PREFETCH);
|
||||||
|
VERIFY(error == 0 || spa_exiting_any(dn->dn_objset->os_spa));
|
||||||
|
if (error != 0)
|
||||||
|
return;
|
||||||
dmu_write_impl(dbp, numbufs, offset, size, buf, tx);
|
dmu_write_impl(dbp, numbufs, offset, size, buf, tx);
|
||||||
dmu_buf_rele_array(dbp, numbufs, FTAG);
|
dmu_buf_rele_array(dbp, numbufs, FTAG);
|
||||||
}
|
}
|
||||||
|
@ -1171,11 +1179,15 @@ dmu_write_embedded(objset_t *os, uint64_t object, uint64_t offset,
|
||||||
int compressed_size, int byteorder, dmu_tx_t *tx)
|
int compressed_size, int byteorder, dmu_tx_t *tx)
|
||||||
{
|
{
|
||||||
dmu_buf_t *db;
|
dmu_buf_t *db;
|
||||||
|
int error;
|
||||||
|
|
||||||
ASSERT3U(etype, <, NUM_BP_EMBEDDED_TYPES);
|
ASSERT3U(etype, <, NUM_BP_EMBEDDED_TYPES);
|
||||||
ASSERT3U(comp, <, ZIO_COMPRESS_FUNCTIONS);
|
ASSERT3U(comp, <, ZIO_COMPRESS_FUNCTIONS);
|
||||||
VERIFY0(dmu_buf_hold_noread(os, object, offset,
|
error = dmu_buf_hold_noread(os, object, offset,
|
||||||
FTAG, &db));
|
FTAG, &db);
|
||||||
|
VERIFY(error == 0 || spa_exiting_any(os->os_spa));
|
||||||
|
if (error != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
dmu_buf_write_embedded(db,
|
dmu_buf_write_embedded(db,
|
||||||
data, (bp_embedded_type_t)etype, (enum zio_compress)comp,
|
data, (bp_embedded_type_t)etype, (enum zio_compress)comp,
|
||||||
|
|
|
@ -1572,6 +1572,11 @@ dmu_objset_write_done(zio_t *zio, arc_buf_t *abuf, void *arg)
|
||||||
blkptr_t *bp_orig = &zio->io_bp_orig;
|
blkptr_t *bp_orig = &zio->io_bp_orig;
|
||||||
objset_t *os = arg;
|
objset_t *os = arg;
|
||||||
|
|
||||||
|
if (zio->io_error != 0) {
|
||||||
|
ASSERT(spa_exiting_any(zio->io_spa));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
if (zio->io_flags & ZIO_FLAG_IO_REWRITE) {
|
if (zio->io_flags & ZIO_FLAG_IO_REWRITE) {
|
||||||
ASSERT(BP_EQUAL(bp, bp_orig));
|
ASSERT(BP_EQUAL(bp, bp_orig));
|
||||||
} else {
|
} else {
|
||||||
|
@ -1581,6 +1586,8 @@ dmu_objset_write_done(zio_t *zio, arc_buf_t *abuf, void *arg)
|
||||||
(void) dsl_dataset_block_kill(ds, bp_orig, tx, B_TRUE);
|
(void) dsl_dataset_block_kill(ds, bp_orig, tx, B_TRUE);
|
||||||
dsl_dataset_block_born(ds, bp, tx);
|
dsl_dataset_block_born(ds, bp, tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
kmem_free(bp, sizeof (*bp));
|
kmem_free(bp, sizeof (*bp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1820,6 +1827,7 @@ do_userquota_cacheflush(objset_t *os, userquota_cache_t *cache, dmu_tx_t *tx)
|
||||||
{
|
{
|
||||||
void *cookie;
|
void *cookie;
|
||||||
userquota_node_t *uqn;
|
userquota_node_t *uqn;
|
||||||
|
int error;
|
||||||
|
|
||||||
ASSERT(dmu_tx_is_syncing(tx));
|
ASSERT(dmu_tx_is_syncing(tx));
|
||||||
|
|
||||||
|
@ -1831,10 +1839,13 @@ do_userquota_cacheflush(objset_t *os, userquota_cache_t *cache, dmu_tx_t *tx)
|
||||||
* zap_increment_int(). It's needed because zap_increment_int()
|
* zap_increment_int(). It's needed because zap_increment_int()
|
||||||
* is not thread-safe (i.e. not atomic).
|
* is not thread-safe (i.e. not atomic).
|
||||||
*/
|
*/
|
||||||
mutex_enter(&os->os_userused_lock);
|
if (!dmu_objset_exiting(os)) {
|
||||||
VERIFY0(zap_increment(os, DMU_USERUSED_OBJECT,
|
mutex_enter(&os->os_userused_lock);
|
||||||
uqn->uqn_id, uqn->uqn_delta, tx));
|
error = zap_increment(os, DMU_USERUSED_OBJECT,
|
||||||
mutex_exit(&os->os_userused_lock);
|
uqn->uqn_id, uqn->uqn_delta, tx);
|
||||||
|
VERIFY(error == 0 || dmu_objset_exiting(os));
|
||||||
|
mutex_exit(&os->os_userused_lock);
|
||||||
|
}
|
||||||
kmem_free(uqn, sizeof (*uqn));
|
kmem_free(uqn, sizeof (*uqn));
|
||||||
}
|
}
|
||||||
avl_destroy(&cache->uqc_user_deltas);
|
avl_destroy(&cache->uqc_user_deltas);
|
||||||
|
@ -1842,10 +1853,13 @@ do_userquota_cacheflush(objset_t *os, userquota_cache_t *cache, dmu_tx_t *tx)
|
||||||
cookie = NULL;
|
cookie = NULL;
|
||||||
while ((uqn = avl_destroy_nodes(&cache->uqc_group_deltas,
|
while ((uqn = avl_destroy_nodes(&cache->uqc_group_deltas,
|
||||||
&cookie)) != NULL) {
|
&cookie)) != NULL) {
|
||||||
mutex_enter(&os->os_userused_lock);
|
if (!dmu_objset_exiting(os)) {
|
||||||
VERIFY0(zap_increment(os, DMU_GROUPUSED_OBJECT,
|
mutex_enter(&os->os_userused_lock);
|
||||||
uqn->uqn_id, uqn->uqn_delta, tx));
|
error = zap_increment(os, DMU_GROUPUSED_OBJECT,
|
||||||
mutex_exit(&os->os_userused_lock);
|
uqn->uqn_id, uqn->uqn_delta, tx);
|
||||||
|
VERIFY(error == 0 || dmu_objset_exiting(os));
|
||||||
|
mutex_exit(&os->os_userused_lock);
|
||||||
|
}
|
||||||
kmem_free(uqn, sizeof (*uqn));
|
kmem_free(uqn, sizeof (*uqn));
|
||||||
}
|
}
|
||||||
avl_destroy(&cache->uqc_group_deltas);
|
avl_destroy(&cache->uqc_group_deltas);
|
||||||
|
@ -1855,8 +1869,9 @@ do_userquota_cacheflush(objset_t *os, userquota_cache_t *cache, dmu_tx_t *tx)
|
||||||
while ((uqn = avl_destroy_nodes(&cache->uqc_project_deltas,
|
while ((uqn = avl_destroy_nodes(&cache->uqc_project_deltas,
|
||||||
&cookie)) != NULL) {
|
&cookie)) != NULL) {
|
||||||
mutex_enter(&os->os_userused_lock);
|
mutex_enter(&os->os_userused_lock);
|
||||||
VERIFY0(zap_increment(os, DMU_PROJECTUSED_OBJECT,
|
error = zap_increment(os, DMU_PROJECTUSED_OBJECT,
|
||||||
uqn->uqn_id, uqn->uqn_delta, tx));
|
uqn->uqn_id, uqn->uqn_delta, tx);
|
||||||
|
VERIFY(error == 0 || dmu_objset_exiting(os));
|
||||||
mutex_exit(&os->os_userused_lock);
|
mutex_exit(&os->os_userused_lock);
|
||||||
kmem_free(uqn, sizeof (*uqn));
|
kmem_free(uqn, sizeof (*uqn));
|
||||||
}
|
}
|
||||||
|
@ -1975,6 +1990,7 @@ userquota_updates_task(void *arg)
|
||||||
|
|
||||||
flags = dn->dn_id_flags;
|
flags = dn->dn_id_flags;
|
||||||
ASSERT(flags);
|
ASSERT(flags);
|
||||||
|
|
||||||
if (flags & DN_ID_OLD_EXIST) {
|
if (flags & DN_ID_OLD_EXIST) {
|
||||||
do_userquota_update(os, &cache, dn->dn_oldused,
|
do_userquota_update(os, &cache, dn->dn_oldused,
|
||||||
dn->dn_oldflags, dn->dn_olduid, dn->dn_oldgid,
|
dn->dn_oldflags, dn->dn_olduid, dn->dn_oldgid,
|
||||||
|
@ -2311,8 +2327,9 @@ dmu_objset_space_upgrade(objset_t *os)
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
return (err);
|
return (err);
|
||||||
|
|
||||||
if (issig(JUSTLOOKING) && issig(FORREAL))
|
err = spa_operation_interrupted(os->os_spa);
|
||||||
return (SET_ERROR(EINTR));
|
if (err != 0)
|
||||||
|
return (err);
|
||||||
|
|
||||||
objerr = dmu_bonus_hold(os, obj, FTAG, &db);
|
objerr = dmu_bonus_hold(os, obj, FTAG, &db);
|
||||||
if (objerr != 0)
|
if (objerr != 0)
|
||||||
|
@ -3000,6 +3017,52 @@ dmu_objset_willuse_space(objset_t *os, int64_t space, dmu_tx_t *tx)
|
||||||
dsl_pool_dirty_space(dmu_tx_pool(tx), space, tx);
|
dsl_pool_dirty_space(dmu_tx_pool(tx), space, tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Notify the objset that it's being shutdown. This is primarily useful
|
||||||
|
* when attempting to dislodge any references that might be waiting on a txg
|
||||||
|
* or similar.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
dmu_objset_shutdown_register(objset_t *os)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
mutex_enter(&os->os_lock);
|
||||||
|
if (os->os_shutdown_initiator == NULL) {
|
||||||
|
os->os_shutdown_initiator = curthread;
|
||||||
|
} else {
|
||||||
|
ret = SET_ERROR(EBUSY);
|
||||||
|
}
|
||||||
|
mutex_exit(&os->os_lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Signal things that will check for objset force export. The calling
|
||||||
|
* thread must use a secondary mechanism to check for ref drops,
|
||||||
|
* before calling dmu_objset_shutdown_unregister().
|
||||||
|
*/
|
||||||
|
if (ret == 0) {
|
||||||
|
txg_completion_notify(spa_get_dsl(dmu_objset_spa(os)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean_t
|
||||||
|
dmu_objset_exiting(objset_t *os)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (os->os_shutdown_initiator != NULL ||
|
||||||
|
spa_exiting_any(os->os_spa));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dmu_objset_shutdown_unregister(objset_t *os)
|
||||||
|
{
|
||||||
|
|
||||||
|
ASSERT3P(os->os_shutdown_initiator, ==, curthread);
|
||||||
|
os->os_shutdown_initiator = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(_KERNEL)
|
#if defined(_KERNEL)
|
||||||
EXPORT_SYMBOL(dmu_objset_zil);
|
EXPORT_SYMBOL(dmu_objset_zil);
|
||||||
EXPORT_SYMBOL(dmu_objset_pool);
|
EXPORT_SYMBOL(dmu_objset_pool);
|
||||||
|
|
|
@ -68,9 +68,11 @@ int zfs_recv_queue_length = SPA_MAXBLOCKSIZE;
|
||||||
int zfs_recv_queue_ff = 20;
|
int zfs_recv_queue_ff = 20;
|
||||||
int zfs_recv_write_batch_size = 1024 * 1024;
|
int zfs_recv_write_batch_size = 1024 * 1024;
|
||||||
|
|
||||||
static char *dmu_recv_tag = "dmu_recv_tag";
|
|
||||||
const char *recv_clone_name = "%recv";
|
const char *recv_clone_name = "%recv";
|
||||||
|
|
||||||
|
/* The receive was closed by an external call. */
|
||||||
|
#define DRC_CLOSED (1U << 0)
|
||||||
|
|
||||||
static int receive_read_payload_and_next_header(dmu_recv_cookie_t *ra, int len,
|
static int receive_read_payload_and_next_header(dmu_recv_cookie_t *ra, int len,
|
||||||
void *buf);
|
void *buf);
|
||||||
|
|
||||||
|
@ -339,6 +341,34 @@ recv_check_large_blocks(dsl_dataset_t *ds, uint64_t featureflags)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
recv_own(dsl_pool_t *dp, dmu_tx_t *tx, uint64_t dsobj, ds_hold_flags_t dsflags,
|
||||||
|
dmu_recv_cookie_t *drc, dsl_dataset_t **dsp, objset_t **osp)
|
||||||
|
{
|
||||||
|
dsl_dataset_t *ds;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The dataset must be marked inconsistent before exit in any event,
|
||||||
|
* so dirty it now. This ensures it's cleaned up if interrupted.
|
||||||
|
*/
|
||||||
|
VERIFY0(dsl_dataset_own_obj_force(dp, dsobj, dsflags, drc, &ds));
|
||||||
|
dmu_buf_will_dirty(ds->ds_dbuf, tx);
|
||||||
|
dsl_dataset_phys(ds)->ds_flags |= DS_FLAG_INCONSISTENT;
|
||||||
|
ds->ds_receiver = drc;
|
||||||
|
*dsp = ds;
|
||||||
|
VERIFY0(dmu_objset_from_ds(ds, osp));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
recv_disown(dsl_dataset_t *ds, dmu_recv_cookie_t *drc)
|
||||||
|
{
|
||||||
|
ds_hold_flags_t dsflags = (drc->drc_raw) ? 0 : DS_HOLD_FLAG_DECRYPT;
|
||||||
|
|
||||||
|
ASSERT3P(ds->ds_receiver, ==, drc);
|
||||||
|
ds->ds_receiver = NULL;
|
||||||
|
dsl_dataset_disown(ds, dsflags, drc);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
recv_begin_check_existing_impl(dmu_recv_begin_arg_t *drba, dsl_dataset_t *ds,
|
recv_begin_check_existing_impl(dmu_recv_begin_arg_t *drba, dsl_dataset_t *ds,
|
||||||
uint64_t fromguid, uint64_t featureflags)
|
uint64_t fromguid, uint64_t featureflags)
|
||||||
|
@ -841,8 +871,8 @@ dmu_recv_begin_sync(void *arg, dmu_tx_t *tx)
|
||||||
dsl_dir_rele(dd, FTAG);
|
dsl_dir_rele(dd, FTAG);
|
||||||
drc->drc_newfs = B_TRUE;
|
drc->drc_newfs = B_TRUE;
|
||||||
}
|
}
|
||||||
VERIFY0(dsl_dataset_own_obj_force(dp, dsobj, dsflags, dmu_recv_tag,
|
recv_own(dp, tx, dsobj, dsflags, drba->drba_cookie, &newds, &os);
|
||||||
&newds));
|
|
||||||
if (dsl_dataset_feature_is_active(newds,
|
if (dsl_dataset_feature_is_active(newds,
|
||||||
SPA_FEATURE_REDACTED_DATASETS)) {
|
SPA_FEATURE_REDACTED_DATASETS)) {
|
||||||
/*
|
/*
|
||||||
|
@ -922,9 +952,6 @@ dmu_recv_begin_sync(void *arg, dmu_tx_t *tx)
|
||||||
numredactsnaps, tx);
|
numredactsnaps, tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
dmu_buf_will_dirty(newds->ds_dbuf, tx);
|
|
||||||
dsl_dataset_phys(newds)->ds_flags |= DS_FLAG_INCONSISTENT;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we actually created a non-clone, we need to create the objset
|
* If we actually created a non-clone, we need to create the objset
|
||||||
* in our new dataset. If this is a raw send we postpone this until
|
* in our new dataset. If this is a raw send we postpone this until
|
||||||
|
@ -1098,8 +1125,9 @@ dmu_recv_resume_begin_sync(void *arg, dmu_tx_t *tx)
|
||||||
{
|
{
|
||||||
dmu_recv_begin_arg_t *drba = arg;
|
dmu_recv_begin_arg_t *drba = arg;
|
||||||
dsl_pool_t *dp = dmu_tx_pool(tx);
|
dsl_pool_t *dp = dmu_tx_pool(tx);
|
||||||
const char *tofs = drba->drba_cookie->drc_tofs;
|
dmu_recv_cookie_t *drc = drba->drba_cookie;
|
||||||
uint64_t featureflags = drba->drba_cookie->drc_featureflags;
|
const char *tofs = drc->drc_tofs;
|
||||||
|
uint64_t featureflags = drc->drc_featureflags;
|
||||||
dsl_dataset_t *ds;
|
dsl_dataset_t *ds;
|
||||||
ds_hold_flags_t dsflags = DS_HOLD_FLAG_NONE;
|
ds_hold_flags_t dsflags = DS_HOLD_FLAG_NONE;
|
||||||
/* 6 extra bytes for /%recv */
|
/* 6 extra bytes for /%recv */
|
||||||
|
@ -1109,28 +1137,26 @@ dmu_recv_resume_begin_sync(void *arg, dmu_tx_t *tx)
|
||||||
recv_clone_name);
|
recv_clone_name);
|
||||||
|
|
||||||
if (featureflags & DMU_BACKUP_FEATURE_RAW) {
|
if (featureflags & DMU_BACKUP_FEATURE_RAW) {
|
||||||
drba->drba_cookie->drc_raw = B_TRUE;
|
drc->drc_raw = B_TRUE;
|
||||||
} else {
|
} else {
|
||||||
dsflags |= DS_HOLD_FLAG_DECRYPT;
|
dsflags |= DS_HOLD_FLAG_DECRYPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dsl_dataset_own_force(dp, recvname, dsflags, dmu_recv_tag, &ds)
|
if (dsl_dataset_own_force(dp, recvname, dsflags, drc, &ds) != 0) {
|
||||||
!= 0) {
|
|
||||||
/* %recv does not exist; continue in tofs */
|
/* %recv does not exist; continue in tofs */
|
||||||
VERIFY0(dsl_dataset_own_force(dp, tofs, dsflags, dmu_recv_tag,
|
VERIFY0(dsl_dataset_own_force(dp, tofs, dsflags, drc, &ds));
|
||||||
&ds));
|
drc->drc_newfs = B_TRUE;
|
||||||
drba->drba_cookie->drc_newfs = B_TRUE;
|
|
||||||
}
|
}
|
||||||
|
ds->ds_receiver = drc;
|
||||||
|
|
||||||
ASSERT(DS_IS_INCONSISTENT(ds));
|
ASSERT(DS_IS_INCONSISTENT(ds));
|
||||||
rrw_enter(&ds->ds_bp_rwlock, RW_READER, FTAG);
|
rrw_enter(&ds->ds_bp_rwlock, RW_READER, FTAG);
|
||||||
ASSERT(!BP_IS_HOLE(dsl_dataset_get_blkptr(ds)) ||
|
ASSERT(!BP_IS_HOLE(dsl_dataset_get_blkptr(ds)) || drc->drc_raw);
|
||||||
drba->drba_cookie->drc_raw);
|
|
||||||
rrw_exit(&ds->ds_bp_rwlock, FTAG);
|
rrw_exit(&ds->ds_bp_rwlock, FTAG);
|
||||||
|
|
||||||
drba->drba_cookie->drc_ds = ds;
|
drc->drc_ds = ds;
|
||||||
VERIFY0(dmu_objset_from_ds(ds, &drba->drba_cookie->drc_os));
|
VERIFY0(dmu_objset_from_ds(ds, &drc->drc_os));
|
||||||
drba->drba_cookie->drc_should_save = B_TRUE;
|
drc->drc_should_save = B_TRUE;
|
||||||
|
|
||||||
spa_history_log_internal_ds(ds, "resume receive", tx, " ");
|
spa_history_log_internal_ds(ds, "resume receive", tx, " ");
|
||||||
}
|
}
|
||||||
|
@ -1148,7 +1174,8 @@ dmu_recv_begin(char *tofs, char *tosnap, dmu_replay_record_t *drr_begin,
|
||||||
dmu_recv_begin_arg_t drba = { 0 };
|
dmu_recv_begin_arg_t drba = { 0 };
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
bzero(drc, sizeof (dmu_recv_cookie_t));
|
memset(drc, 0, sizeof (dmu_recv_cookie_t));
|
||||||
|
drc->drc_initiator = curthread;
|
||||||
drc->drc_drr_begin = drr_begin;
|
drc->drc_drr_begin = drr_begin;
|
||||||
drc->drc_drrb = &drr_begin->drr_u.drr_begin;
|
drc->drc_drrb = &drr_begin->drr_u.drr_begin;
|
||||||
drc->drc_tosnap = tosnap;
|
drc->drc_tosnap = tosnap;
|
||||||
|
@ -1237,6 +1264,16 @@ dmu_recv_begin(char *tofs, char *tosnap, dmu_replay_record_t *drr_begin,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (err == 0 && drc->drc_ds == NULL) {
|
||||||
|
/*
|
||||||
|
* Make sure the dataset is destroyed before returning. We
|
||||||
|
* can't do this in the sync task because a dataset can't be
|
||||||
|
* synced and destroyed in the same txg. In this scenario,
|
||||||
|
* it should be flagged as inconsistent so we're ok anyway.
|
||||||
|
*/
|
||||||
|
(void) dsl_destroy_head(tofs);
|
||||||
|
return (SET_ERROR(ENXIO));
|
||||||
|
}
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
kmem_free(drc->drc_next_rrd, sizeof (*drc->drc_next_rrd));
|
kmem_free(drc->drc_next_rrd, sizeof (*drc->drc_next_rrd));
|
||||||
nvlist_free(drc->drc_begin_nvl);
|
nvlist_free(drc->drc_begin_nvl);
|
||||||
|
@ -2322,29 +2359,37 @@ static void
|
||||||
dmu_recv_cleanup_ds(dmu_recv_cookie_t *drc)
|
dmu_recv_cleanup_ds(dmu_recv_cookie_t *drc)
|
||||||
{
|
{
|
||||||
dsl_dataset_t *ds = drc->drc_ds;
|
dsl_dataset_t *ds = drc->drc_ds;
|
||||||
ds_hold_flags_t dsflags;
|
objset_t *os = ds->ds_objset;
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
dsflags = (drc->drc_raw) ? DS_HOLD_FLAG_NONE : DS_HOLD_FLAG_DECRYPT;
|
|
||||||
/*
|
/*
|
||||||
* Wait for the txg sync before cleaning up the receive. For
|
* Wait for the txg sync before cleaning up the receive. For
|
||||||
* resumable receives, this ensures that our resume state has
|
* resumable receives, this ensures that our resume state has
|
||||||
* been written out to disk. For raw receives, this ensures
|
* been written out to disk. For raw receives, this ensures
|
||||||
* that the user accounting code will not attempt to do anything
|
* that the user accounting code will not attempt to do anything
|
||||||
* after we stopped receiving the dataset.
|
* after we stopped receiving the dataset.
|
||||||
|
*
|
||||||
|
* If this is interrupted due to suspension and the pool is being
|
||||||
|
* force exported, just exit and cleanup.
|
||||||
*/
|
*/
|
||||||
txg_wait_synced(ds->ds_dir->dd_pool, 0);
|
for (;;) {
|
||||||
|
error = txg_wait_synced_tx(ds->ds_dir->dd_pool, 0,
|
||||||
|
NULL, TXG_WAIT_F_NOSUSPEND);
|
||||||
|
if (error == 0 || spa_exiting_any(os->os_spa))
|
||||||
|
break;
|
||||||
|
}
|
||||||
ds->ds_objset->os_raw_receive = B_FALSE;
|
ds->ds_objset->os_raw_receive = B_FALSE;
|
||||||
|
|
||||||
rrw_enter(&ds->ds_bp_rwlock, RW_READER, FTAG);
|
rrw_enter(&ds->ds_bp_rwlock, RW_READER, FTAG);
|
||||||
if (drc->drc_resumable && drc->drc_should_save &&
|
if (drc->drc_resumable && drc->drc_should_save &&
|
||||||
!BP_IS_HOLE(dsl_dataset_get_blkptr(ds))) {
|
!BP_IS_HOLE(dsl_dataset_get_blkptr(ds))) {
|
||||||
rrw_exit(&ds->ds_bp_rwlock, FTAG);
|
rrw_exit(&ds->ds_bp_rwlock, FTAG);
|
||||||
dsl_dataset_disown(ds, dsflags, dmu_recv_tag);
|
recv_disown(ds, drc);
|
||||||
} else {
|
} else {
|
||||||
char name[ZFS_MAX_DATASET_NAME_LEN];
|
char name[ZFS_MAX_DATASET_NAME_LEN];
|
||||||
rrw_exit(&ds->ds_bp_rwlock, FTAG);
|
rrw_exit(&ds->ds_bp_rwlock, FTAG);
|
||||||
dsl_dataset_name(ds, name);
|
dsl_dataset_name(ds, name);
|
||||||
dsl_dataset_disown(ds, dsflags, dmu_recv_tag);
|
recv_disown(ds, drc);
|
||||||
(void) dsl_destroy_head(name);
|
(void) dsl_destroy_head(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2882,6 +2927,35 @@ resume_check(dmu_recv_cookie_t *drc, nvlist_t *begin_nvl)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cancel the receive stream for the dataset, if there is one.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
dmu_recv_close(dsl_dataset_t *ds)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
dmu_recv_cookie_t *drc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This lock isn't technically for recv, but it's not worth
|
||||||
|
* adding a dedicated one for this purpose.
|
||||||
|
*/
|
||||||
|
mutex_enter(&ds->ds_sendstream_lock);
|
||||||
|
drc = ds->ds_receiver;
|
||||||
|
if (drc != NULL) {
|
||||||
|
drc->drc_flags |= DRC_CLOSED;
|
||||||
|
/*
|
||||||
|
* Send an interrupt to the initiator thread, which will
|
||||||
|
* cause it to end the stream and clean up.
|
||||||
|
*/
|
||||||
|
if (drc->drc_initiator != curthread)
|
||||||
|
thread_signal(drc->drc_initiator, SIGINT);
|
||||||
|
}
|
||||||
|
mutex_exit(&ds->ds_sendstream_lock);
|
||||||
|
|
||||||
|
return (err);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read in the stream's records, one by one, and apply them to the pool. There
|
* Read in the stream's records, one by one, and apply them to the pool. There
|
||||||
* are two threads involved; the thread that calls this function will spin up a
|
* are two threads involved; the thread that calls this function will spin up a
|
||||||
|
@ -2898,6 +2972,7 @@ int
|
||||||
dmu_recv_stream(dmu_recv_cookie_t *drc, offset_t *voffp)
|
dmu_recv_stream(dmu_recv_cookie_t *drc, offset_t *voffp)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
spa_t *spa = dsl_dataset_get_spa(drc->drc_ds);
|
||||||
struct receive_writer_arg *rwa = kmem_zalloc(sizeof (*rwa), KM_SLEEP);
|
struct receive_writer_arg *rwa = kmem_zalloc(sizeof (*rwa), KM_SLEEP);
|
||||||
|
|
||||||
if (dsl_dataset_has_resume_receive_state(drc->drc_ds)) {
|
if (dsl_dataset_has_resume_receive_state(drc->drc_ds)) {
|
||||||
|
@ -2934,10 +3009,10 @@ dmu_recv_stream(dmu_recv_cookie_t *drc, offset_t *voffp)
|
||||||
/*
|
/*
|
||||||
* If this is a new dataset we set the key immediately.
|
* If this is a new dataset we set the key immediately.
|
||||||
* Otherwise we don't want to change the key until we
|
* Otherwise we don't want to change the key until we
|
||||||
* are sure the rest of the receive succeeded so we stash
|
* are sure the rest of the receive succeeded so we
|
||||||
* the keynvl away until then.
|
* stash the keynvl away until then.
|
||||||
*/
|
*/
|
||||||
err = dsl_crypto_recv_raw(spa_name(drc->drc_os->os_spa),
|
err = dsl_crypto_recv_raw(spa_name(spa),
|
||||||
drc->drc_ds->ds_object, drc->drc_fromsnapobj,
|
drc->drc_ds->ds_object, drc->drc_fromsnapobj,
|
||||||
drc->drc_drrb->drr_type, keynvl, drc->drc_newfs);
|
drc->drc_drrb->drr_type, keynvl, drc->drc_newfs);
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
|
@ -2965,6 +3040,12 @@ dmu_recv_stream(dmu_recv_cookie_t *drc, offset_t *voffp)
|
||||||
*/
|
*/
|
||||||
drc->drc_should_save = B_TRUE;
|
drc->drc_should_save = B_TRUE;
|
||||||
|
|
||||||
|
/* Last chance before kicking off. */
|
||||||
|
if (drc->drc_flags & DRC_CLOSED) {
|
||||||
|
err = SET_ERROR(EINTR);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
(void) bqueue_init(&rwa->q, zfs_recv_queue_ff,
|
(void) bqueue_init(&rwa->q, zfs_recv_queue_ff,
|
||||||
MAX(zfs_recv_queue_length, 2 * zfs_max_recordsize),
|
MAX(zfs_recv_queue_length, 2 * zfs_max_recordsize),
|
||||||
offsetof(struct receive_record_arg, node));
|
offsetof(struct receive_record_arg, node));
|
||||||
|
@ -2980,8 +3061,17 @@ dmu_recv_stream(dmu_recv_cookie_t *drc, offset_t *voffp)
|
||||||
list_create(&rwa->write_batch, sizeof (struct receive_record_arg),
|
list_create(&rwa->write_batch, sizeof (struct receive_record_arg),
|
||||||
offsetof(struct receive_record_arg, node.bqn_node));
|
offsetof(struct receive_record_arg, node.bqn_node));
|
||||||
|
|
||||||
(void) thread_create(NULL, 0, receive_writer_thread, rwa, 0, curproc,
|
/*
|
||||||
TS_RUN, minclsyspri);
|
* Register the rwa with the drc so it can be interrupted. This
|
||||||
|
* requires a mutex handshake to ensure validity.
|
||||||
|
*/
|
||||||
|
mutex_enter(&drc->drc_ds->ds_sendstream_lock);
|
||||||
|
drc->drc_rwa = rwa;
|
||||||
|
mutex_exit(&drc->drc_ds->ds_sendstream_lock);
|
||||||
|
|
||||||
|
kthread_t *rw_td = thread_create(NULL, 0, receive_writer_thread,
|
||||||
|
rwa, 0, curproc, TS_RUN, minclsyspri);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We're reading rwa->err without locks, which is safe since we are the
|
* We're reading rwa->err without locks, which is safe since we are the
|
||||||
* only reader, and the worker thread is the only writer. It's ok if we
|
* only reader, and the worker thread is the only writer. It's ok if we
|
||||||
|
@ -2997,11 +3087,10 @@ dmu_recv_stream(dmu_recv_cookie_t *drc, offset_t *voffp)
|
||||||
* it. Finally, if receive_read_record fails or we're at the end of the
|
* it. Finally, if receive_read_record fails or we're at the end of the
|
||||||
* stream, then we free drc->drc_rrd and exit.
|
* stream, then we free drc->drc_rrd and exit.
|
||||||
*/
|
*/
|
||||||
while (rwa->err == 0) {
|
while (rwa->err == 0 && err == 0) {
|
||||||
if (issig(JUSTLOOKING) && issig(FORREAL)) {
|
err = spa_operation_interrupted(dmu_objset_spa(rwa->os));
|
||||||
err = SET_ERROR(EINTR);
|
if (err)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT3P(drc->drc_rrd, ==, NULL);
|
ASSERT3P(drc->drc_rrd, ==, NULL);
|
||||||
drc->drc_rrd = drc->drc_next_rrd;
|
drc->drc_rrd = drc->drc_next_rrd;
|
||||||
|
@ -3028,9 +3117,22 @@ dmu_recv_stream(dmu_recv_cookie_t *drc, offset_t *voffp)
|
||||||
|
|
||||||
mutex_enter(&rwa->mutex);
|
mutex_enter(&rwa->mutex);
|
||||||
while (!rwa->done) {
|
while (!rwa->done) {
|
||||||
|
boolean_t closed = drc->drc_flags & DRC_CLOSED;
|
||||||
|
|
||||||
|
if (!closed) {
|
||||||
|
if (err == 0)
|
||||||
|
err = spa_operation_interrupted(spa);
|
||||||
|
if (err != 0) {
|
||||||
|
drc->drc_flags |= DRC_CLOSED;
|
||||||
|
thread_signal(rw_td, SIGINT);
|
||||||
|
closed = B_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We need to use cv_wait_sig() so that any process that may
|
* We need to use cv_wait_sig() so that any process that may
|
||||||
* be sleeping here can still fork.
|
* be sleeping here can still fork. Also, it allows
|
||||||
|
* dmu_recv_close to cause an eos marker to be injected.
|
||||||
*/
|
*/
|
||||||
(void) cv_wait_sig(&rwa->cv, &rwa->mutex);
|
(void) cv_wait_sig(&rwa->cv, &rwa->mutex);
|
||||||
}
|
}
|
||||||
|
@ -3062,6 +3164,10 @@ dmu_recv_stream(dmu_recv_cookie_t *drc, offset_t *voffp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_enter(&drc->drc_ds->ds_sendstream_lock);
|
||||||
|
drc->drc_rwa = NULL;
|
||||||
|
mutex_exit(&drc->drc_ds->ds_sendstream_lock);
|
||||||
|
|
||||||
cv_destroy(&rwa->cv);
|
cv_destroy(&rwa->cv);
|
||||||
mutex_destroy(&rwa->mutex);
|
mutex_destroy(&rwa->mutex);
|
||||||
bqueue_destroy(&rwa->q);
|
bqueue_destroy(&rwa->q);
|
||||||
|
@ -3110,7 +3216,7 @@ dmu_recv_end_check(void *arg, dmu_tx_t *tx)
|
||||||
dsl_pool_t *dp = dmu_tx_pool(tx);
|
dsl_pool_t *dp = dmu_tx_pool(tx);
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
ASSERT3P(drc->drc_ds->ds_owner, ==, dmu_recv_tag);
|
ASSERT3P(drc->drc_ds->ds_receiver, ==, drc);
|
||||||
|
|
||||||
if (!drc->drc_newfs) {
|
if (!drc->drc_newfs) {
|
||||||
dsl_dataset_t *origin_head;
|
dsl_dataset_t *origin_head;
|
||||||
|
@ -3328,7 +3434,7 @@ dmu_recv_end_sync(void *arg, dmu_tx_t *tx)
|
||||||
(void) spa_keystore_remove_mapping(dmu_tx_pool(tx)->dp_spa,
|
(void) spa_keystore_remove_mapping(dmu_tx_pool(tx)->dp_spa,
|
||||||
drc->drc_ds->ds_object, drc->drc_ds);
|
drc->drc_ds->ds_object, drc->drc_ds);
|
||||||
}
|
}
|
||||||
dsl_dataset_disown(drc->drc_ds, 0, dmu_recv_tag);
|
recv_disown(drc->drc_ds, drc);
|
||||||
drc->drc_ds = NULL;
|
drc->drc_ds = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3394,7 +3500,7 @@ boolean_t
|
||||||
dmu_objset_is_receiving(objset_t *os)
|
dmu_objset_is_receiving(objset_t *os)
|
||||||
{
|
{
|
||||||
return (os->os_dsl_dataset != NULL &&
|
return (os->os_dsl_dataset != NULL &&
|
||||||
os->os_dsl_dataset->ds_owner == dmu_recv_tag);
|
os->os_dsl_dataset->ds_receiver != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BEGIN CSTYLED */
|
/* BEGIN CSTYLED */
|
||||||
|
|
|
@ -564,7 +564,14 @@ commit_rl_updates(objset_t *os, struct merge_data *md, uint64_t object,
|
||||||
{
|
{
|
||||||
dmu_tx_t *tx = dmu_tx_create_dd(spa_get_dsl(os->os_spa)->dp_mos_dir);
|
dmu_tx_t *tx = dmu_tx_create_dd(spa_get_dsl(os->os_spa)->dp_mos_dir);
|
||||||
dmu_tx_hold_space(tx, sizeof (struct redact_block_list_node));
|
dmu_tx_hold_space(tx, sizeof (struct redact_block_list_node));
|
||||||
VERIFY0(dmu_tx_assign(tx, TXG_WAIT));
|
|
||||||
|
int err = dmu_tx_assign(tx, TXG_WAIT);
|
||||||
|
if (err != 0) {
|
||||||
|
ASSERT(spa_exiting_any(os->os_spa));
|
||||||
|
dmu_tx_abort(tx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t txg = dmu_tx_get_txg(tx);
|
uint64_t txg = dmu_tx_get_txg(tx);
|
||||||
if (!md->md_synctask_txg[txg & TXG_MASK]) {
|
if (!md->md_synctask_txg[txg & TXG_MASK]) {
|
||||||
dsl_sync_task_nowait(dmu_tx_pool(tx),
|
dsl_sync_task_nowait(dmu_tx_pool(tx),
|
||||||
|
|
|
@ -2214,6 +2214,7 @@ setup_send_progress(struct dmu_send_params *dspp)
|
||||||
dssp->dss_outfd = dspp->outfd;
|
dssp->dss_outfd = dspp->outfd;
|
||||||
dssp->dss_off = dspp->off;
|
dssp->dss_off = dspp->off;
|
||||||
dssp->dss_proc = curproc;
|
dssp->dss_proc = curproc;
|
||||||
|
dssp->dss_thread = curthread;
|
||||||
mutex_enter(&dspp->to_ds->ds_sendstream_lock);
|
mutex_enter(&dspp->to_ds->ds_sendstream_lock);
|
||||||
list_insert_head(&dspp->to_ds->ds_sendstreams, dssp);
|
list_insert_head(&dspp->to_ds->ds_sendstreams, dssp);
|
||||||
mutex_exit(&dspp->to_ds->ds_sendstream_lock);
|
mutex_exit(&dspp->to_ds->ds_sendstream_lock);
|
||||||
|
@ -2503,6 +2504,14 @@ dmu_send_impl(struct dmu_send_params *dspp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Last chance, bail if possible at this point, now that the send is
|
||||||
|
* registered and can be cancelled by signalling this thread.
|
||||||
|
*/
|
||||||
|
err = spa_operation_interrupted(os->os_spa);
|
||||||
|
if (err != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (resuming || book_resuming) {
|
if (resuming || book_resuming) {
|
||||||
err = setup_resume_points(dspp, to_arg, from_arg,
|
err = setup_resume_points(dspp, to_arg, from_arg,
|
||||||
rlt_arg, smt_arg, resuming, os, redact_rl, nvl);
|
rlt_arg, smt_arg, resuming, os, redact_rl, nvl);
|
||||||
|
@ -2550,8 +2559,8 @@ dmu_send_impl(struct dmu_send_params *dspp)
|
||||||
while (err == 0 && !range->eos_marker) {
|
while (err == 0 && !range->eos_marker) {
|
||||||
err = do_dump(&dsc, range);
|
err = do_dump(&dsc, range);
|
||||||
range = get_next_range(&srt_arg->q, range);
|
range = get_next_range(&srt_arg->q, range);
|
||||||
if (issig(JUSTLOOKING) && issig(FORREAL))
|
if (err == 0)
|
||||||
err = SET_ERROR(EINTR);
|
err = spa_operation_interrupted(os->os_spa);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3086,7 +3095,32 @@ out:
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Close all send streams on the dataset. */
|
||||||
|
int
|
||||||
|
dmu_send_close(dsl_dataset_t *ds)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
dmu_sendstatus_t *dss;
|
||||||
|
|
||||||
|
mutex_enter(&ds->ds_sendstream_lock);
|
||||||
|
dss = list_head(&ds->ds_sendstreams);
|
||||||
|
while (err == 0 && dss != NULL) {
|
||||||
|
/*
|
||||||
|
* Interrupt the initiator thread, which will cause it
|
||||||
|
* to initiate a cleanup error exit. Also send SIGPIPE
|
||||||
|
* because this interrupts pipe writes.
|
||||||
|
*/
|
||||||
|
thread_signal(dss->dss_thread, SIGINT);
|
||||||
|
thread_signal(dss->dss_thread, SIGPIPE);
|
||||||
|
dss = list_next(&ds->ds_sendstreams, dss);
|
||||||
|
}
|
||||||
|
mutex_exit(&ds->ds_sendstream_lock);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
/* BEGIN CSTYLED */
|
/* BEGIN CSTYLED */
|
||||||
|
|
||||||
ZFS_MODULE_PARAM(zfs_send, zfs_send_, corrupt_data, INT, ZMOD_RW,
|
ZFS_MODULE_PARAM(zfs_send, zfs_send_, corrupt_data, INT, ZMOD_RW,
|
||||||
"Allow sending corrupt data");
|
"Allow sending corrupt data");
|
||||||
|
|
||||||
|
|
|
@ -869,6 +869,19 @@ dmu_tx_try_assign(dmu_tx_t *tx, uint64_t txg_how)
|
||||||
if (spa_suspended(spa)) {
|
if (spa_suspended(spa)) {
|
||||||
DMU_TX_STAT_BUMP(dmu_tx_suspended);
|
DMU_TX_STAT_BUMP(dmu_tx_suspended);
|
||||||
|
|
||||||
|
if (txg_how & TXG_NOSUSPEND)
|
||||||
|
return (SET_ERROR(EAGAIN));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the user is forcibly exporting the pool or the objset,
|
||||||
|
* indicate to the caller that they need to give up.
|
||||||
|
*/
|
||||||
|
if (spa_exiting_any(spa))
|
||||||
|
return (SET_ERROR(EIO));
|
||||||
|
|
||||||
|
if (tx->tx_objset != NULL && dmu_objset_exiting(tx->tx_objset))
|
||||||
|
return (SET_ERROR(EIO));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the user has indicated a blocking failure mode
|
* If the user has indicated a blocking failure mode
|
||||||
* then return ERESTART which will block in dmu_tx_wait().
|
* then return ERESTART which will block in dmu_tx_wait().
|
||||||
|
@ -995,6 +1008,8 @@ dmu_tx_unassign(dmu_tx_t *tx)
|
||||||
tx->tx_txg = 0;
|
tx->tx_txg = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dmu_tx_wait_flags(dmu_tx_t *, txg_wait_flag_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Assign tx to a transaction group; txg_how is a bitmask:
|
* Assign tx to a transaction group; txg_how is a bitmask:
|
||||||
*
|
*
|
||||||
|
@ -1015,6 +1030,11 @@ dmu_tx_unassign(dmu_tx_t *tx)
|
||||||
* they have already called dmu_tx_wait() (though most likely on a
|
* they have already called dmu_tx_wait() (though most likely on a
|
||||||
* different tx).
|
* different tx).
|
||||||
*
|
*
|
||||||
|
* If TXG_NOSUSPEND is set, this indicates that this request must return
|
||||||
|
* EAGAIN if the pool becomes suspended while it is in progress. This
|
||||||
|
* ensures that the request does not inadvertently cause conditions that
|
||||||
|
* cannot be unwound.
|
||||||
|
*
|
||||||
* It is guaranteed that subsequent successful calls to dmu_tx_assign()
|
* It is guaranteed that subsequent successful calls to dmu_tx_assign()
|
||||||
* will assign the tx to monotonically increasing txgs. Of course this is
|
* will assign the tx to monotonically increasing txgs. Of course this is
|
||||||
* not strong monotonicity, because the same txg can be returned multiple
|
* not strong monotonicity, because the same txg can be returned multiple
|
||||||
|
@ -1037,7 +1057,7 @@ dmu_tx_assign(dmu_tx_t *tx, uint64_t txg_how)
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
ASSERT(tx->tx_txg == 0);
|
ASSERT(tx->tx_txg == 0);
|
||||||
ASSERT0(txg_how & ~(TXG_WAIT | TXG_NOTHROTTLE));
|
ASSERT0(txg_how & ~(TXG_NOSUSPEND | TXG_WAIT | TXG_NOTHROTTLE));
|
||||||
ASSERT(!dsl_pool_sync_context(tx->tx_pool));
|
ASSERT(!dsl_pool_sync_context(tx->tx_pool));
|
||||||
|
|
||||||
/* If we might wait, we must not hold the config lock. */
|
/* If we might wait, we must not hold the config lock. */
|
||||||
|
@ -1052,7 +1072,8 @@ dmu_tx_assign(dmu_tx_t *tx, uint64_t txg_how)
|
||||||
if (err != ERESTART || !(txg_how & TXG_WAIT))
|
if (err != ERESTART || !(txg_how & TXG_WAIT))
|
||||||
return (err);
|
return (err);
|
||||||
|
|
||||||
dmu_tx_wait(tx);
|
dmu_tx_wait_flags(tx,
|
||||||
|
(txg_how & TXG_NOSUSPEND) ? TXG_WAIT_F_NOSUSPEND : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
txg_rele_to_quiesce(&tx->tx_txgh);
|
txg_rele_to_quiesce(&tx->tx_txgh);
|
||||||
|
@ -1060,8 +1081,8 @@ dmu_tx_assign(dmu_tx_t *tx, uint64_t txg_how)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
dmu_tx_wait(dmu_tx_t *tx)
|
dmu_tx_wait_flags(dmu_tx_t *tx, txg_wait_flag_t how)
|
||||||
{
|
{
|
||||||
spa_t *spa = tx->tx_pool->dp_spa;
|
spa_t *spa = tx->tx_pool->dp_spa;
|
||||||
dsl_pool_t *dp = tx->tx_pool;
|
dsl_pool_t *dp = tx->tx_pool;
|
||||||
|
@ -1106,8 +1127,11 @@ dmu_tx_wait(dmu_tx_t *tx)
|
||||||
* has become active after this thread has tried to
|
* has become active after this thread has tried to
|
||||||
* obtain a tx. If that's the case then tx_lasttried_txg
|
* obtain a tx. If that's the case then tx_lasttried_txg
|
||||||
* would not have been set.
|
* would not have been set.
|
||||||
|
*
|
||||||
|
* It's also possible the pool will be force exported, in
|
||||||
|
* which case we'll try again and notice this fact, and exit.
|
||||||
*/
|
*/
|
||||||
txg_wait_synced(dp, spa_last_synced_txg(spa) + 1);
|
txg_wait_synced_tx(dp, spa_last_synced_txg(spa) + 1, tx, how);
|
||||||
} else if (tx->tx_needassign_txh) {
|
} else if (tx->tx_needassign_txh) {
|
||||||
dnode_t *dn = tx->tx_needassign_txh->txh_dnode;
|
dnode_t *dn = tx->tx_needassign_txh->txh_dnode;
|
||||||
|
|
||||||
|
@ -1121,13 +1145,23 @@ dmu_tx_wait(dmu_tx_t *tx)
|
||||||
* If we have a lot of dirty data just wait until we sync
|
* If we have a lot of dirty data just wait until we sync
|
||||||
* out a TXG at which point we'll hopefully have synced
|
* out a TXG at which point we'll hopefully have synced
|
||||||
* a portion of the changes.
|
* a portion of the changes.
|
||||||
|
*
|
||||||
|
* It's also possible the pool will be force exported, in
|
||||||
|
* which case we'll try again and notice this fact, and exit.
|
||||||
*/
|
*/
|
||||||
txg_wait_synced(dp, spa_last_synced_txg(spa) + 1);
|
txg_wait_synced_tx(dp, spa_last_synced_txg(spa) + 1, tx, how);
|
||||||
}
|
}
|
||||||
|
|
||||||
spa_tx_assign_add_nsecs(spa, gethrtime() - before);
|
spa_tx_assign_add_nsecs(spa, gethrtime() - before);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dmu_tx_wait(dmu_tx_t *tx)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (dmu_tx_wait_flags(tx, TXG_WAIT_F_NONE));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dmu_tx_destroy(dmu_tx_t *tx)
|
dmu_tx_destroy(dmu_tx_t *tx)
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,6 +44,9 @@
|
||||||
#include <sys/dmu_traverse.h>
|
#include <sys/dmu_traverse.h>
|
||||||
#include <sys/dmu_impl.h>
|
#include <sys/dmu_impl.h>
|
||||||
#include <sys/dmu_tx.h>
|
#include <sys/dmu_tx.h>
|
||||||
|
#include <sys/dmu.h>
|
||||||
|
#include <sys/dbuf.h>
|
||||||
|
#include <sys/dnode.h>
|
||||||
#include <sys/arc.h>
|
#include <sys/arc.h>
|
||||||
#include <sys/zio.h>
|
#include <sys/zio.h>
|
||||||
#include <sys/zap.h>
|
#include <sys/zap.h>
|
||||||
|
@ -557,8 +560,8 @@ dsl_dataset_try_add_ref(dsl_pool_t *dp, dsl_dataset_t *ds, void *tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
dsl_dataset_hold_obj(dsl_pool_t *dp, uint64_t dsobj, void *tag,
|
dsl_dataset_hold_obj_flags(dsl_pool_t *dp, uint64_t dsobj,
|
||||||
dsl_dataset_t **dsp)
|
ds_hold_flags_t flags, void *tag, dsl_dataset_t **dsp)
|
||||||
{
|
{
|
||||||
objset_t *mos = dp->dp_meta_objset;
|
objset_t *mos = dp->dp_meta_objset;
|
||||||
dmu_buf_t *dbuf;
|
dmu_buf_t *dbuf;
|
||||||
|
@ -581,6 +584,11 @@ dsl_dataset_hold_obj(dsl_pool_t *dp, uint64_t dsobj, void *tag,
|
||||||
|
|
||||||
ds = dmu_buf_get_user(dbuf);
|
ds = dmu_buf_get_user(dbuf);
|
||||||
if (ds == NULL) {
|
if (ds == NULL) {
|
||||||
|
if (flags & DS_HOLD_FLAG_MUST_BE_OPEN) {
|
||||||
|
dmu_buf_rele(dbuf, tag);
|
||||||
|
return (SET_ERROR(ENXIO));
|
||||||
|
}
|
||||||
|
|
||||||
dsl_dataset_t *winner = NULL;
|
dsl_dataset_t *winner = NULL;
|
||||||
|
|
||||||
ds = kmem_zalloc(sizeof (dsl_dataset_t), KM_SLEEP);
|
ds = kmem_zalloc(sizeof (dsl_dataset_t), KM_SLEEP);
|
||||||
|
@ -722,6 +730,15 @@ dsl_dataset_hold_obj(dsl_pool_t *dp, uint64_t dsobj, void *tag,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (err == 0 && (flags & DS_HOLD_FLAG_DECRYPT)) {
|
||||||
|
err = dsl_dataset_create_key_mapping(ds);
|
||||||
|
if (err != 0)
|
||||||
|
dsl_dataset_rele(ds, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err != 0)
|
||||||
|
return (err);
|
||||||
|
|
||||||
ASSERT3P(ds->ds_dbuf, ==, dbuf);
|
ASSERT3P(ds->ds_dbuf, ==, dbuf);
|
||||||
ASSERT3P(dsl_dataset_phys(ds), ==, dbuf->db_data);
|
ASSERT3P(dsl_dataset_phys(ds), ==, dbuf->db_data);
|
||||||
ASSERT(dsl_dataset_phys(ds)->ds_prev_snap_obj != 0 ||
|
ASSERT(dsl_dataset_phys(ds)->ds_prev_snap_obj != 0 ||
|
||||||
|
@ -745,24 +762,10 @@ dsl_dataset_create_key_mapping(dsl_dataset_t *ds)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
dsl_dataset_hold_obj_flags(dsl_pool_t *dp, uint64_t dsobj,
|
dsl_dataset_hold_obj(dsl_pool_t *dp, uint64_t dsobj, void *tag,
|
||||||
ds_hold_flags_t flags, void *tag, dsl_dataset_t **dsp)
|
dsl_dataset_t **dsp)
|
||||||
{
|
{
|
||||||
int err;
|
return (dsl_dataset_hold_obj_flags(dp, dsobj, 0, tag, dsp));
|
||||||
|
|
||||||
err = dsl_dataset_hold_obj(dp, dsobj, tag, dsp);
|
|
||||||
if (err != 0)
|
|
||||||
return (err);
|
|
||||||
|
|
||||||
ASSERT3P(*dsp, !=, NULL);
|
|
||||||
|
|
||||||
if (flags & DS_HOLD_FLAG_DECRYPT) {
|
|
||||||
err = dsl_dataset_create_key_mapping(*dsp);
|
|
||||||
if (err != 0)
|
|
||||||
dsl_dataset_rele(*dsp, tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (err);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -913,6 +916,115 @@ dsl_dataset_long_held(dsl_dataset_t *ds)
|
||||||
return (!zfs_refcount_is_zero(&ds->ds_longholds));
|
return (!zfs_refcount_is_zero(&ds->ds_longholds));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enumerate active datasets. This function is intended for use cases that
|
||||||
|
* want to avoid I/O, and only operate on those that have been loaded in
|
||||||
|
* memory. This works by enumerating the objects in the MOS that are known,
|
||||||
|
* and calling back with each dataset's MOS object IDs. It would be nice if
|
||||||
|
* the objset_t's were registered in a spa_t global list, but they're not,
|
||||||
|
* so this implementation is a bit more complex...
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
dsl_dataset_active_foreach(spa_t *spa, int func(dsl_dataset_t *, void *),
|
||||||
|
void *cl)
|
||||||
|
{
|
||||||
|
dsl_pool_t *dp = spa_get_dsl(spa);
|
||||||
|
objset_t *mos = dp->dp_meta_objset;
|
||||||
|
dnode_t *mdn = DMU_META_DNODE(mos);
|
||||||
|
dmu_buf_impl_t *db;
|
||||||
|
uint64_t blkid, dsobj, i;
|
||||||
|
dnode_children_t *children_dnodes;
|
||||||
|
dnode_handle_t *dnh;
|
||||||
|
dsl_dataset_t *ds;
|
||||||
|
int epb, error;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For each block of the MOS's meta-dnode's full size:
|
||||||
|
* - If the block is not cached, skip.
|
||||||
|
* - If the block has no user, skip.
|
||||||
|
* - For each dnode child of the meta-dnode block:
|
||||||
|
* - If not loaded (no dnode pointer), skip.
|
||||||
|
* - Attempt to hold the dataset, skip on failure.
|
||||||
|
* - Call the callback, quit if returns non zero,
|
||||||
|
* - Rele the dataset either way.
|
||||||
|
*/
|
||||||
|
rrw_enter(&dp->dp_config_rwlock, RW_READER, FTAG);
|
||||||
|
rw_enter(&mdn->dn_struct_rwlock, RW_READER);
|
||||||
|
for (blkid = dsobj = 0;
|
||||||
|
ret == 0 && blkid <= mdn->dn_maxblkid;
|
||||||
|
blkid++, dsobj += epb) {
|
||||||
|
epb = DNODES_PER_BLOCK;
|
||||||
|
error = dbuf_hold_impl(mdn, 0, blkid, TRUE, TRUE, FTAG, &db);
|
||||||
|
if (error != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
epb = db->db.db_size >> DNODE_SHIFT;
|
||||||
|
children_dnodes = dmu_buf_get_user(&db->db);
|
||||||
|
if (children_dnodes == NULL) {
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; ret == 0 && i < epb; i++) {
|
||||||
|
dnh = &children_dnodes->dnc_children[i];
|
||||||
|
if (!DN_SLOT_IS_PTR(dnh->dnh_dnode))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
error = dsl_dataset_hold_obj_flags(dp, dsobj + i,
|
||||||
|
DS_HOLD_FLAG_MUST_BE_OPEN, FTAG, &ds);
|
||||||
|
if (error != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ret = func(ds, cl);
|
||||||
|
dsl_dataset_rele(ds, FTAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
skip:
|
||||||
|
dbuf_rele(db, FTAG);
|
||||||
|
}
|
||||||
|
rw_exit(&mdn->dn_struct_rwlock);
|
||||||
|
rrw_exit(&dp->dp_config_rwlock, FTAG);
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cancellation interfaces for send/receive streams.
|
||||||
|
*
|
||||||
|
* If a send/recv wins the race with a forced destroy, their pipes will be
|
||||||
|
* interrupted, and the destroy will wait for all ioctl references to drop.
|
||||||
|
*
|
||||||
|
* If a forced destroy wins the race, the send/receive will fail to start.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* dsl_dataset_sendrecv_cancel_all callback for dsl_dataset_active_foreach. */
|
||||||
|
static int
|
||||||
|
dsl_dataset_sendrecv_cancel_cb(dsl_dataset_t *ds, __maybe_unused void *arg)
|
||||||
|
{
|
||||||
|
(void) arg;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = dmu_send_close(ds);
|
||||||
|
if (err == 0)
|
||||||
|
err = dmu_recv_close(ds);
|
||||||
|
|
||||||
|
return (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cancel all outstanding sends/receives. Used when the pool is trying to
|
||||||
|
* forcibly exit. Iterates on all datasets in the MOS and cancels any
|
||||||
|
* running sends/receives by interrupting them.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
dsl_dataset_sendrecv_cancel_all(spa_t *spa)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (dsl_dataset_active_foreach(spa,
|
||||||
|
dsl_dataset_sendrecv_cancel_cb, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
dsl_dataset_name(dsl_dataset_t *ds, char *name)
|
dsl_dataset_name(dsl_dataset_t *ds, char *name)
|
||||||
{
|
{
|
||||||
|
|
|
@ -624,6 +624,7 @@ dsl_pool_sync(dsl_pool_t *dp, uint64_t txg)
|
||||||
dsl_dataset_t *ds;
|
dsl_dataset_t *ds;
|
||||||
objset_t *mos = dp->dp_meta_objset;
|
objset_t *mos = dp->dp_meta_objset;
|
||||||
list_t synced_datasets;
|
list_t synced_datasets;
|
||||||
|
int error;
|
||||||
|
|
||||||
list_create(&synced_datasets, sizeof (dsl_dataset_t),
|
list_create(&synced_datasets, sizeof (dsl_dataset_t),
|
||||||
offsetof(dsl_dataset_t, ds_synced_link));
|
offsetof(dsl_dataset_t, ds_synced_link));
|
||||||
|
@ -661,7 +662,8 @@ dsl_pool_sync(dsl_pool_t *dp, uint64_t txg)
|
||||||
list_insert_tail(&synced_datasets, ds);
|
list_insert_tail(&synced_datasets, ds);
|
||||||
dsl_dataset_sync(ds, zio, tx);
|
dsl_dataset_sync(ds, zio, tx);
|
||||||
}
|
}
|
||||||
VERIFY0(zio_wait(zio));
|
error = zio_wait(zio);
|
||||||
|
VERIFY(error == 0 || (spa_exiting_any(zio->io_spa) && error == EIO));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update the long range free counter after
|
* Update the long range free counter after
|
||||||
|
|
|
@ -835,8 +835,7 @@ dsl_scan(dsl_pool_t *dp, pool_scan_func_t func)
|
||||||
(void) spa_vdev_state_exit(spa, NULL, 0);
|
(void) spa_vdev_state_exit(spa, NULL, 0);
|
||||||
|
|
||||||
if (func == POOL_SCAN_RESILVER) {
|
if (func == POOL_SCAN_RESILVER) {
|
||||||
dsl_scan_restart_resilver(spa->spa_dsl_pool, 0);
|
return (dsl_scan_restart_resilver(spa->spa_dsl_pool, 0));
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (func == POOL_SCAN_SCRUB && dsl_scan_is_paused_scrub(scn)) {
|
if (func == POOL_SCAN_SCRUB && dsl_scan_is_paused_scrub(scn)) {
|
||||||
|
@ -1099,13 +1098,20 @@ dsl_scrub_set_pause_resume(const dsl_pool_t *dp, pool_scrub_cmd_t cmd)
|
||||||
|
|
||||||
|
|
||||||
/* start a new scan, or restart an existing one. */
|
/* start a new scan, or restart an existing one. */
|
||||||
void
|
int
|
||||||
dsl_scan_restart_resilver(dsl_pool_t *dp, uint64_t txg)
|
dsl_scan_restart_resilver(dsl_pool_t *dp, uint64_t txg)
|
||||||
{
|
{
|
||||||
|
int error;
|
||||||
|
|
||||||
if (txg == 0) {
|
if (txg == 0) {
|
||||||
dmu_tx_t *tx;
|
dmu_tx_t *tx;
|
||||||
tx = dmu_tx_create_dd(dp->dp_mos_dir);
|
tx = dmu_tx_create_dd(dp->dp_mos_dir);
|
||||||
VERIFY(0 == dmu_tx_assign(tx, TXG_WAIT));
|
error = dmu_tx_assign(tx, TXG_WAIT);
|
||||||
|
if (error != 0) {
|
||||||
|
ASSERT(spa_exiting_any(dp->dp_spa));
|
||||||
|
dmu_tx_abort(tx);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
txg = dmu_tx_get_txg(tx);
|
txg = dmu_tx_get_txg(tx);
|
||||||
dp->dp_scan->scn_restart_txg = txg;
|
dp->dp_scan->scn_restart_txg = txg;
|
||||||
|
@ -1113,7 +1119,10 @@ dsl_scan_restart_resilver(dsl_pool_t *dp, uint64_t txg)
|
||||||
} else {
|
} else {
|
||||||
dp->dp_scan->scn_restart_txg = txg;
|
dp->dp_scan->scn_restart_txg = txg;
|
||||||
}
|
}
|
||||||
zfs_dbgmsg("restarting resilver txg=%llu", (longlong_t)txg);
|
zfs_dbgmsg("restarting resilver for %s at txg=%llu",
|
||||||
|
dp->dp_spa->spa_name, (longlong_t)txg);
|
||||||
|
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -2746,13 +2755,18 @@ dsl_scan_visit(dsl_scan_t *scn, dmu_tx_t *tx)
|
||||||
dsl_dataset_t *ds;
|
dsl_dataset_t *ds;
|
||||||
uint64_t dsobj = sds->sds_dsobj;
|
uint64_t dsobj = sds->sds_dsobj;
|
||||||
uint64_t txg = sds->sds_txg;
|
uint64_t txg = sds->sds_txg;
|
||||||
|
int error;
|
||||||
|
|
||||||
/* dequeue and free the ds from the queue */
|
/* dequeue and free the ds from the queue */
|
||||||
scan_ds_queue_remove(scn, dsobj);
|
scan_ds_queue_remove(scn, dsobj);
|
||||||
sds = NULL;
|
sds = NULL;
|
||||||
|
|
||||||
/* set up min / max txg */
|
/* set up min / max txg */
|
||||||
VERIFY3U(0, ==, dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds));
|
error = dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds);
|
||||||
|
VERIFY(error == 0 ||
|
||||||
|
(spa_exiting_any(dp->dp_spa) && error == EIO));
|
||||||
|
if (error != 0)
|
||||||
|
return;
|
||||||
if (txg != 0) {
|
if (txg != 0) {
|
||||||
scn->scn_phys.scn_cur_min_txg =
|
scn->scn_phys.scn_cur_min_txg =
|
||||||
MAX(scn->scn_phys.scn_min_txg, txg);
|
MAX(scn->scn_phys.scn_min_txg, txg);
|
||||||
|
|
|
@ -57,7 +57,12 @@ dsl_sync_task_common(const char *pool, dsl_checkfunc_t *checkfunc,
|
||||||
|
|
||||||
top:
|
top:
|
||||||
tx = dmu_tx_create_dd(dp->dp_mos_dir);
|
tx = dmu_tx_create_dd(dp->dp_mos_dir);
|
||||||
VERIFY0(dmu_tx_assign(tx, TXG_WAIT));
|
err = dmu_tx_assign(tx, TXG_WAIT);
|
||||||
|
if (err != 0) {
|
||||||
|
ASSERT(spa_exiting_any(spa));
|
||||||
|
dmu_tx_abort(tx);
|
||||||
|
return (err);
|
||||||
|
}
|
||||||
|
|
||||||
dst.dst_pool = dp;
|
dst.dst_pool = dp;
|
||||||
dst.dst_txg = dmu_tx_get_txg(tx);
|
dst.dst_txg = dmu_tx_get_txg(tx);
|
||||||
|
|
|
@ -508,6 +508,16 @@ metaslab_class_get_dspace(metaslab_class_t *mc)
|
||||||
return (spa_deflate(mc->mc_spa) ? mc->mc_dspace : mc->mc_space);
|
return (spa_deflate(mc->mc_spa) ? mc->mc_dspace : mc->mc_space);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
metaslab_class_force_discard(metaslab_class_t *mc)
|
||||||
|
{
|
||||||
|
|
||||||
|
mc->mc_alloc = 0;
|
||||||
|
mc->mc_deferred = 0;
|
||||||
|
mc->mc_space = 0;
|
||||||
|
mc->mc_dspace = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
metaslab_class_histogram_verify(metaslab_class_t *mc)
|
metaslab_class_histogram_verify(metaslab_class_t *mc)
|
||||||
{
|
{
|
||||||
|
@ -2779,6 +2789,19 @@ metaslab_fini(metaslab_t *msp)
|
||||||
metaslab_group_remove(mg, msp);
|
metaslab_group_remove(mg, msp);
|
||||||
|
|
||||||
mutex_enter(&msp->ms_lock);
|
mutex_enter(&msp->ms_lock);
|
||||||
|
if (spa_exiting_any(mg->mg_vd->vdev_spa)) {
|
||||||
|
/* Catch-all cleanup as required for force export. */
|
||||||
|
range_tree_vacate(msp->ms_allocatable, NULL, NULL);
|
||||||
|
range_tree_vacate(msp->ms_freeing, NULL, NULL);
|
||||||
|
range_tree_vacate(msp->ms_freed, NULL, NULL);
|
||||||
|
range_tree_vacate(msp->ms_checkpointing, NULL, NULL);
|
||||||
|
for (int t = 0; t < TXG_SIZE; t++)
|
||||||
|
range_tree_vacate(msp->ms_allocating[t], NULL, NULL);
|
||||||
|
for (int t = 0; t < TXG_DEFER_SIZE; t++)
|
||||||
|
range_tree_vacate(msp->ms_defer[t], NULL, NULL);
|
||||||
|
msp->ms_deferspace = 0;
|
||||||
|
}
|
||||||
|
|
||||||
VERIFY(msp->ms_group == NULL);
|
VERIFY(msp->ms_group == NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3951,6 +3974,31 @@ metaslab_sync(metaslab_t *msp, uint64_t txg)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The pool is being forcibly exported. Just discard everything.
|
||||||
|
*/
|
||||||
|
if (spa_exiting_any(spa)) {
|
||||||
|
mutex_enter(&msp->ms_sync_lock);
|
||||||
|
mutex_enter(&msp->ms_lock);
|
||||||
|
range_tree_vacate(alloctree, NULL, NULL);
|
||||||
|
range_tree_vacate(msp->ms_allocatable, NULL, NULL);
|
||||||
|
range_tree_vacate(msp->ms_freeing, NULL, NULL);
|
||||||
|
range_tree_vacate(msp->ms_freed, NULL, NULL);
|
||||||
|
range_tree_vacate(msp->ms_trim, NULL, NULL);
|
||||||
|
range_tree_vacate(msp->ms_checkpointing, NULL, NULL);
|
||||||
|
range_tree_vacate(msp->ms_allocating[txg & TXG_MASK],
|
||||||
|
NULL, NULL);
|
||||||
|
range_tree_vacate(msp->ms_allocating[TXG_CLEAN(txg) & TXG_MASK],
|
||||||
|
NULL, NULL);
|
||||||
|
for (int t = 0; t < TXG_DEFER_SIZE; t++) {
|
||||||
|
range_tree_vacate(msp->ms_defer[t], NULL, NULL);
|
||||||
|
}
|
||||||
|
msp->ms_deferspace = 0;
|
||||||
|
mutex_exit(&msp->ms_lock);
|
||||||
|
mutex_exit(&msp->ms_sync_lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Normally, we don't want to process a metaslab if there are no
|
* Normally, we don't want to process a metaslab if there are no
|
||||||
* allocations or frees to perform. However, if the metaslab is being
|
* allocations or frees to perform. However, if the metaslab is being
|
||||||
|
@ -3970,7 +4018,7 @@ metaslab_sync(metaslab_t *msp, uint64_t txg)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
VERIFY3U(txg, <=, spa_final_dirty_txg(spa));
|
spa_verify_dirty_txg(spa, txg);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The only state that can actually be changing concurrently
|
* The only state that can actually be changing concurrently
|
||||||
|
@ -4339,7 +4387,7 @@ metaslab_sync_done(metaslab_t *msp, uint64_t txg)
|
||||||
msp->ms_deferspace += defer_delta;
|
msp->ms_deferspace += defer_delta;
|
||||||
ASSERT3S(msp->ms_deferspace, >=, 0);
|
ASSERT3S(msp->ms_deferspace, >=, 0);
|
||||||
ASSERT3S(msp->ms_deferspace, <=, msp->ms_size);
|
ASSERT3S(msp->ms_deferspace, <=, msp->ms_size);
|
||||||
if (msp->ms_deferspace != 0) {
|
if (msp->ms_deferspace != 0 && !spa_exiting_any(spa)) {
|
||||||
/*
|
/*
|
||||||
* Keep syncing this metaslab until all deferred frees
|
* Keep syncing this metaslab until all deferred frees
|
||||||
* are back in circulation.
|
* are back in circulation.
|
||||||
|
@ -6156,7 +6204,9 @@ metaslab_update_ondisk_flush_data(metaslab_t *ms, dmu_tx_t *tx)
|
||||||
int err = zap_lookup(mos, vd->vdev_top_zap,
|
int err = zap_lookup(mos, vd->vdev_top_zap,
|
||||||
VDEV_TOP_ZAP_MS_UNFLUSHED_PHYS_TXGS, sizeof (uint64_t), 1,
|
VDEV_TOP_ZAP_MS_UNFLUSHED_PHYS_TXGS, sizeof (uint64_t), 1,
|
||||||
&object);
|
&object);
|
||||||
if (err == ENOENT) {
|
if (err != 0 && spa_exiting_any(spa)) {
|
||||||
|
return;
|
||||||
|
} else if (err == ENOENT) {
|
||||||
object = dmu_object_alloc(mos, DMU_OTN_UINT64_METADATA,
|
object = dmu_object_alloc(mos, DMU_OTN_UINT64_METADATA,
|
||||||
SPA_OLD_MAXBLOCKSIZE, DMU_OT_NONE, 0, tx);
|
SPA_OLD_MAXBLOCKSIZE, DMU_OT_NONE, 0, tx);
|
||||||
VERIFY0(zap_add(mos, vd->vdev_top_zap,
|
VERIFY0(zap_add(mos, vd->vdev_top_zap,
|
||||||
|
|
309
module/zfs/spa.c
309
module/zfs/spa.c
|
@ -1355,6 +1355,8 @@ spa_activate(spa_t *spa, spa_mode_t mode)
|
||||||
static void
|
static void
|
||||||
spa_deactivate(spa_t *spa)
|
spa_deactivate(spa_t *spa)
|
||||||
{
|
{
|
||||||
|
int error;
|
||||||
|
|
||||||
ASSERT(spa->spa_sync_on == B_FALSE);
|
ASSERT(spa->spa_sync_on == B_FALSE);
|
||||||
ASSERT(spa->spa_dsl_pool == NULL);
|
ASSERT(spa->spa_dsl_pool == NULL);
|
||||||
ASSERT(spa->spa_root_vdev == NULL);
|
ASSERT(spa->spa_root_vdev == NULL);
|
||||||
|
@ -1394,10 +1396,19 @@ spa_deactivate(spa_t *spa)
|
||||||
|
|
||||||
for (size_t i = 0; i < TXG_SIZE; i++) {
|
for (size_t i = 0; i < TXG_SIZE; i++) {
|
||||||
ASSERT3P(spa->spa_txg_zio[i], !=, NULL);
|
ASSERT3P(spa->spa_txg_zio[i], !=, NULL);
|
||||||
VERIFY0(zio_wait(spa->spa_txg_zio[i]));
|
error = zio_wait(spa->spa_txg_zio[i]);
|
||||||
|
VERIFY(error == 0 || (spa_exiting_any(spa) && error == EIO));
|
||||||
spa->spa_txg_zio[i] = NULL;
|
spa->spa_txg_zio[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (spa_exiting_any(spa)) {
|
||||||
|
metaslab_class_force_discard(spa->spa_normal_class);
|
||||||
|
metaslab_class_force_discard(spa->spa_log_class);
|
||||||
|
metaslab_class_force_discard(spa->spa_embedded_log_class);
|
||||||
|
metaslab_class_force_discard(spa->spa_special_class);
|
||||||
|
metaslab_class_force_discard(spa->spa_dedup_class);
|
||||||
|
}
|
||||||
|
|
||||||
metaslab_class_destroy(spa->spa_normal_class);
|
metaslab_class_destroy(spa->spa_normal_class);
|
||||||
spa->spa_normal_class = NULL;
|
spa->spa_normal_class = NULL;
|
||||||
|
|
||||||
|
@ -1527,7 +1538,12 @@ static void
|
||||||
spa_unload_log_sm_flush_all(spa_t *spa)
|
spa_unload_log_sm_flush_all(spa_t *spa)
|
||||||
{
|
{
|
||||||
dmu_tx_t *tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
|
dmu_tx_t *tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
|
||||||
VERIFY0(dmu_tx_assign(tx, TXG_WAIT));
|
int txerr = dmu_tx_assign(tx, TXG_WAIT);
|
||||||
|
if (txerr != 0) {
|
||||||
|
ASSERT(spa_exiting_any(spa));
|
||||||
|
dmu_tx_abort(tx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ASSERT3U(spa->spa_log_flushall_txg, ==, 0);
|
ASSERT3U(spa->spa_log_flushall_txg, ==, 0);
|
||||||
spa->spa_log_flushall_txg = dmu_tx_get_txg(tx);
|
spa->spa_log_flushall_txg = dmu_tx_get_txg(tx);
|
||||||
|
@ -1583,9 +1599,13 @@ spa_destroy_aux_threads(spa_t *spa)
|
||||||
/*
|
/*
|
||||||
* Opposite of spa_load().
|
* Opposite of spa_load().
|
||||||
*/
|
*/
|
||||||
static void
|
static int
|
||||||
spa_unload(spa_t *spa)
|
spa_unload(spa_t *spa, txg_wait_flag_t txg_how)
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
|
vdev_t *vd;
|
||||||
|
uint64_t t, txg;
|
||||||
|
|
||||||
ASSERT(MUTEX_HELD(&spa_namespace_lock));
|
ASSERT(MUTEX_HELD(&spa_namespace_lock));
|
||||||
ASSERT(spa_state(spa) != POOL_STATE_UNINITIALIZED);
|
ASSERT(spa_state(spa) != POOL_STATE_UNINITIALIZED);
|
||||||
|
|
||||||
|
@ -1628,10 +1648,45 @@ spa_unload(spa_t *spa)
|
||||||
* Stop syncing.
|
* Stop syncing.
|
||||||
*/
|
*/
|
||||||
if (spa->spa_sync_on) {
|
if (spa->spa_sync_on) {
|
||||||
txg_sync_stop(spa->spa_dsl_pool);
|
err = txg_sync_stop(spa->spa_dsl_pool, txg_how);
|
||||||
|
if (err != 0) {
|
||||||
|
spa_async_resume(spa);
|
||||||
|
return (err);
|
||||||
|
}
|
||||||
spa->spa_sync_on = B_FALSE;
|
spa->spa_sync_on = B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the pool is being forcibly exported, it may be necessary to
|
||||||
|
* cleanup again. This normally would be handled by spa_sync(),
|
||||||
|
* except it's possible that followup txg's were skipped, and
|
||||||
|
* thus the opportunity to have performed these operations.
|
||||||
|
*
|
||||||
|
* This is the correct place to perform these operations, as just
|
||||||
|
* now, spa_sync() and vdev activity has been stopped, and after
|
||||||
|
* here, the metaslabs are destroyed.
|
||||||
|
*/
|
||||||
|
if (spa_exiting_any(spa)) {
|
||||||
|
spa_config_enter(spa, SCL_ALL, spa, RW_WRITER);
|
||||||
|
while ((vd = list_head(&spa->spa_config_dirty_list)) != NULL)
|
||||||
|
vdev_config_clean(vd);
|
||||||
|
while ((vd = list_head(&spa->spa_state_dirty_list)) != NULL)
|
||||||
|
vdev_state_clean(vd);
|
||||||
|
/* The only dirty entries should be for spa_syncing_txg + 1. */
|
||||||
|
t = 0;
|
||||||
|
txg = spa_syncing_txg(spa) + 1;
|
||||||
|
while (t < TXG_SIZE) {
|
||||||
|
vd = txg_list_remove(&spa->spa_vdev_txg_list, t);
|
||||||
|
if (vd == NULL) {
|
||||||
|
t++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
VERIFY3U(t, ==, txg & TXG_MASK);
|
||||||
|
vdev_sync_done(vd, txg);
|
||||||
|
}
|
||||||
|
spa_config_exit(spa, SCL_ALL, spa);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This ensures that there is no async metaslab prefetching
|
* This ensures that there is no async metaslab prefetching
|
||||||
* while we attempt to unload the spa.
|
* while we attempt to unload the spa.
|
||||||
|
@ -1736,6 +1791,7 @@ spa_unload(spa_t *spa)
|
||||||
}
|
}
|
||||||
|
|
||||||
spa_config_exit(spa, SCL_ALL, spa);
|
spa_config_exit(spa, SCL_ALL, spa);
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2596,9 +2652,10 @@ spa_livelist_delete_cb(void *arg, zthr_t *z)
|
||||||
" livelist %llu, %lld remaining",
|
" livelist %llu, %lld remaining",
|
||||||
(u_longlong_t)dle->dle_bpobj.bpo_object,
|
(u_longlong_t)dle->dle_bpobj.bpo_object,
|
||||||
(u_longlong_t)ll_obj, (longlong_t)count - 1);
|
(u_longlong_t)ll_obj, (longlong_t)count - 1);
|
||||||
VERIFY0(dsl_sync_task(spa_name(spa), NULL,
|
err = dsl_sync_task(spa_name(spa), NULL,
|
||||||
sublist_delete_sync, &sync_arg, 0,
|
sublist_delete_sync, &sync_arg, 0,
|
||||||
ZFS_SPACE_CHECK_DESTROY));
|
ZFS_SPACE_CHECK_DESTROY);
|
||||||
|
VERIFY(err == 0 || spa_exiting_any(spa));
|
||||||
} else {
|
} else {
|
||||||
VERIFY3U(err, ==, EINTR);
|
VERIFY3U(err, ==, EINTR);
|
||||||
}
|
}
|
||||||
|
@ -2614,8 +2671,10 @@ spa_livelist_delete_cb(void *arg, zthr_t *z)
|
||||||
};
|
};
|
||||||
zfs_dbgmsg("deletion of livelist %llu completed",
|
zfs_dbgmsg("deletion of livelist %llu completed",
|
||||||
(u_longlong_t)ll_obj);
|
(u_longlong_t)ll_obj);
|
||||||
VERIFY0(dsl_sync_task(spa_name(spa), NULL, livelist_delete_sync,
|
int err = dsl_sync_task(spa_name(spa), NULL,
|
||||||
&sync_arg, 0, ZFS_SPACE_CHECK_DESTROY));
|
livelist_delete_sync, &sync_arg, 0,
|
||||||
|
ZFS_SPACE_CHECK_DESTROY);
|
||||||
|
VERIFY(err == 0 || spa_exiting_any(spa));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4474,7 +4533,7 @@ spa_ld_prepare_for_reload(spa_t *spa)
|
||||||
spa_mode_t mode = spa->spa_mode;
|
spa_mode_t mode = spa->spa_mode;
|
||||||
int async_suspended = spa->spa_async_suspended;
|
int async_suspended = spa->spa_async_suspended;
|
||||||
|
|
||||||
spa_unload(spa);
|
VERIFY0(spa_unload(spa, TXG_WAIT_F_NONE));
|
||||||
spa_deactivate(spa);
|
spa_deactivate(spa);
|
||||||
spa_activate(spa, mode);
|
spa_activate(spa, mode);
|
||||||
|
|
||||||
|
@ -4990,7 +5049,7 @@ spa_load_retry(spa_t *spa, spa_load_state_t state)
|
||||||
{
|
{
|
||||||
spa_mode_t mode = spa->spa_mode;
|
spa_mode_t mode = spa->spa_mode;
|
||||||
|
|
||||||
spa_unload(spa);
|
VERIFY0(spa_unload(spa, TXG_WAIT_F_NONE));
|
||||||
spa_deactivate(spa);
|
spa_deactivate(spa);
|
||||||
|
|
||||||
spa->spa_load_max_txg = spa->spa_uberblock.ub_txg - 1;
|
spa->spa_load_max_txg = spa->spa_uberblock.ub_txg - 1;
|
||||||
|
@ -5152,6 +5211,16 @@ spa_open_common(const char *pool, spa_t **spapp, void *tag, nvlist_t *nvpolicy,
|
||||||
return (SET_ERROR(ENOENT));
|
return (SET_ERROR(ENOENT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the pool is exiting, only the thread forcing it to exit may
|
||||||
|
* open new references to it.
|
||||||
|
*/
|
||||||
|
if (spa_exiting(spa)) {
|
||||||
|
if (locked)
|
||||||
|
mutex_exit(&spa_namespace_lock);
|
||||||
|
return (SET_ERROR(ENXIO));
|
||||||
|
}
|
||||||
|
|
||||||
if (spa->spa_state == POOL_STATE_UNINITIALIZED) {
|
if (spa->spa_state == POOL_STATE_UNINITIALIZED) {
|
||||||
zpool_load_policy_t policy;
|
zpool_load_policy_t policy;
|
||||||
|
|
||||||
|
@ -5180,7 +5249,7 @@ spa_open_common(const char *pool, spa_t **spapp, void *tag, nvlist_t *nvpolicy,
|
||||||
* this is the case, the config cache is out of sync and
|
* this is the case, the config cache is out of sync and
|
||||||
* we should remove the pool from the namespace.
|
* we should remove the pool from the namespace.
|
||||||
*/
|
*/
|
||||||
spa_unload(spa);
|
VERIFY0(spa_unload(spa, TXG_WAIT_F_NONE));
|
||||||
spa_deactivate(spa);
|
spa_deactivate(spa);
|
||||||
spa_write_cachefile(spa, B_TRUE, B_TRUE);
|
spa_write_cachefile(spa, B_TRUE, B_TRUE);
|
||||||
spa_remove(spa);
|
spa_remove(spa);
|
||||||
|
@ -5202,7 +5271,7 @@ spa_open_common(const char *pool, spa_t **spapp, void *tag, nvlist_t *nvpolicy,
|
||||||
ZPOOL_CONFIG_LOAD_INFO,
|
ZPOOL_CONFIG_LOAD_INFO,
|
||||||
spa->spa_load_info) == 0);
|
spa->spa_load_info) == 0);
|
||||||
}
|
}
|
||||||
spa_unload(spa);
|
VERIFY0(spa_unload(spa, TXG_WAIT_F_NONE));
|
||||||
spa_deactivate(spa);
|
spa_deactivate(spa);
|
||||||
spa->spa_last_open_failed = error;
|
spa->spa_last_open_failed = error;
|
||||||
if (locked)
|
if (locked)
|
||||||
|
@ -5876,7 +5945,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
|
||||||
spa_config_exit(spa, SCL_ALL, FTAG);
|
spa_config_exit(spa, SCL_ALL, FTAG);
|
||||||
|
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
spa_unload(spa);
|
VERIFY0(spa_unload(spa, TXG_WAIT_F_NONE));
|
||||||
spa_deactivate(spa);
|
spa_deactivate(spa);
|
||||||
spa_remove(spa);
|
spa_remove(spa);
|
||||||
mutex_exit(&spa_namespace_lock);
|
mutex_exit(&spa_namespace_lock);
|
||||||
|
@ -6135,15 +6204,13 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags)
|
||||||
|
|
||||||
if (error != 0 || (props && spa_writeable(spa) &&
|
if (error != 0 || (props && spa_writeable(spa) &&
|
||||||
(error = spa_prop_set(spa, props)))) {
|
(error = spa_prop_set(spa, props)))) {
|
||||||
spa_unload(spa);
|
VERIFY0(spa_unload(spa, TXG_WAIT_F_NONE));
|
||||||
spa_deactivate(spa);
|
spa_deactivate(spa);
|
||||||
spa_remove(spa);
|
spa_remove(spa);
|
||||||
mutex_exit(&spa_namespace_lock);
|
mutex_exit(&spa_namespace_lock);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
spa_async_resume(spa);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Override any spares and level 2 cache devices as specified by
|
* Override any spares and level 2 cache devices as specified by
|
||||||
* the user, as these may have correct device names/devids, etc.
|
* the user, as these may have correct device names/devids, etc.
|
||||||
|
@ -6191,9 +6258,21 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags)
|
||||||
/*
|
/*
|
||||||
* Update the config cache to include the newly-imported pool.
|
* Update the config cache to include the newly-imported pool.
|
||||||
*/
|
*/
|
||||||
spa_config_update(spa, SPA_CONFIG_UPDATE_POOL);
|
mutex_exit(&spa_namespace_lock);
|
||||||
|
error = spa_config_update_pool(spa);
|
||||||
|
if (error != 0) {
|
||||||
|
mutex_enter(&spa_namespace_lock);
|
||||||
|
VERIFY0(spa_unload(spa, TXG_WAIT_F_NONE));
|
||||||
|
spa_deactivate(spa);
|
||||||
|
spa_remove(spa);
|
||||||
|
mutex_exit(&spa_namespace_lock);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
mutex_enter(&spa_namespace_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spa_async_resume(spa);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* It's possible that the pool was expanded while it was exported.
|
* It's possible that the pool was expanded while it was exported.
|
||||||
* We kick off an async task to handle this for us.
|
* We kick off an async task to handle this for us.
|
||||||
|
@ -6316,7 +6395,7 @@ spa_tryimport(nvlist_t *tryconfig)
|
||||||
spa_config_exit(spa, SCL_CONFIG, FTAG);
|
spa_config_exit(spa, SCL_CONFIG, FTAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
spa_unload(spa);
|
VERIFY0(spa_unload(spa, TXG_WAIT_F_NONE));
|
||||||
spa_deactivate(spa);
|
spa_deactivate(spa);
|
||||||
spa_remove(spa);
|
spa_remove(spa);
|
||||||
mutex_exit(&spa_namespace_lock);
|
mutex_exit(&spa_namespace_lock);
|
||||||
|
@ -6324,6 +6403,38 @@ spa_tryimport(nvlist_t *tryconfig)
|
||||||
return (config);
|
return (config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
spa_set_pre_export_status(const char *pool, boolean_t status)
|
||||||
|
{
|
||||||
|
spa_t *spa;
|
||||||
|
|
||||||
|
mutex_enter(&spa_namespace_lock);
|
||||||
|
if ((spa = spa_lookup(pool)) == NULL) {
|
||||||
|
mutex_exit(&spa_namespace_lock);
|
||||||
|
return (SET_ERROR(ENOENT));
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_enter(&spa->spa_evicting_os_lock);
|
||||||
|
spa->spa_pre_exporting = status;
|
||||||
|
if (status)
|
||||||
|
txg_completion_notify(spa_get_dsl(spa));
|
||||||
|
mutex_exit(&spa->spa_evicting_os_lock);
|
||||||
|
|
||||||
|
mutex_exit(&spa_namespace_lock);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
spa_set_export_initiator(spa_t *spa, void *initiator)
|
||||||
|
{
|
||||||
|
|
||||||
|
mutex_enter(&spa->spa_evicting_os_lock);
|
||||||
|
spa->spa_export_initiator = initiator;
|
||||||
|
if (initiator != NULL)
|
||||||
|
txg_completion_notify(spa_get_dsl(spa));
|
||||||
|
mutex_exit(&spa->spa_evicting_os_lock);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pool export/destroy
|
* Pool export/destroy
|
||||||
*
|
*
|
||||||
|
@ -6339,6 +6450,7 @@ spa_export_common(const char *pool, int new_state, nvlist_t **oldconfig,
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
spa_t *spa;
|
spa_t *spa;
|
||||||
|
boolean_t force_removal, modifying;
|
||||||
|
|
||||||
if (oldconfig)
|
if (oldconfig)
|
||||||
*oldconfig = NULL;
|
*oldconfig = NULL;
|
||||||
|
@ -6359,13 +6471,49 @@ spa_export_common(const char *pool, int new_state, nvlist_t **oldconfig,
|
||||||
}
|
}
|
||||||
spa->spa_is_exporting = B_TRUE;
|
spa->spa_is_exporting = B_TRUE;
|
||||||
|
|
||||||
|
/* XXX Should this be chained instead of rejected? */
|
||||||
|
if (spa_exiting(spa)) {
|
||||||
|
mutex_exit(&spa_namespace_lock);
|
||||||
|
return (SET_ERROR(EBUSY));
|
||||||
|
}
|
||||||
|
|
||||||
|
modifying = spa->spa_sync_on && (new_state == POOL_STATE_DESTROYED ||
|
||||||
|
new_state == POOL_STATE_EXPORTED);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Put a hold on the pool, drop the namespace lock, stop async tasks,
|
* Put a hold on the pool, drop the namespace lock, stop async tasks,
|
||||||
* reacquire the namespace lock, and see if we can export.
|
* reacquire the namespace lock, and see if we can export.
|
||||||
*/
|
*/
|
||||||
spa_open_ref(spa, FTAG);
|
spa_open_ref(spa, FTAG);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mark the pool as facing impending exit if this is a forced
|
||||||
|
* destroy or export.
|
||||||
|
*/
|
||||||
|
force_removal = hardforce && modifying;
|
||||||
|
if (force_removal) {
|
||||||
|
/* Ensure that references see this change after this. */
|
||||||
|
spa_set_export_initiator(spa, curthread);
|
||||||
|
}
|
||||||
mutex_exit(&spa_namespace_lock);
|
mutex_exit(&spa_namespace_lock);
|
||||||
spa_async_suspend(spa);
|
spa_async_suspend(spa);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cancel all sends/receives if necessary, and wait for their holds
|
||||||
|
* to expire. This is done without the namespace lock, since some
|
||||||
|
* operations may require acquiring it (although they will fail).
|
||||||
|
*/
|
||||||
|
if (force_removal && spa->spa_sync_on) {
|
||||||
|
error = dsl_dataset_sendrecv_cancel_all(spa);
|
||||||
|
if (error != 0) {
|
||||||
|
spa_set_export_initiator(spa, NULL);
|
||||||
|
spa_async_resume(spa);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
txg_force_export(spa);
|
||||||
|
spa_evicting_os_wait(spa);
|
||||||
|
}
|
||||||
|
|
||||||
if (spa->spa_zvol_taskq) {
|
if (spa->spa_zvol_taskq) {
|
||||||
zvol_remove_minors(spa, spa_name(spa), B_TRUE);
|
zvol_remove_minors(spa, spa_name(spa), B_TRUE);
|
||||||
taskq_wait(spa->spa_zvol_taskq);
|
taskq_wait(spa->spa_zvol_taskq);
|
||||||
|
@ -6375,22 +6523,45 @@ spa_export_common(const char *pool, int new_state, nvlist_t **oldconfig,
|
||||||
|
|
||||||
if (spa->spa_state == POOL_STATE_UNINITIALIZED)
|
if (spa->spa_state == POOL_STATE_UNINITIALIZED)
|
||||||
goto export_spa;
|
goto export_spa;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The pool will be in core if it's openable, in which case we can
|
* The pool will be in core if it's openable, in which case we can
|
||||||
* modify its state. Objsets may be open only because they're dirty,
|
* modify its state. Objsets may be open only because they're dirty,
|
||||||
* so we have to force it to sync before checking spa_refcnt.
|
* so we have to force it to sync before checking spa_refcnt.
|
||||||
*/
|
*/
|
||||||
if (spa->spa_sync_on) {
|
if (!force_removal && spa->spa_sync_on) {
|
||||||
txg_wait_synced(spa->spa_dsl_pool, 0);
|
error = txg_wait_synced_tx(spa->spa_dsl_pool, 0,
|
||||||
|
NULL, TXG_WAIT_F_NOSUSPEND);
|
||||||
|
if (error != 0)
|
||||||
|
goto fail;
|
||||||
spa_evicting_os_wait(spa);
|
spa_evicting_os_wait(spa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For forced removal, wait for refcount to drop to minref. At this
|
||||||
|
* point, all ioctls should be on their way out or getting rejected
|
||||||
|
* at the front door.
|
||||||
|
*/
|
||||||
|
if (force_removal) {
|
||||||
|
mutex_exit(&spa_namespace_lock);
|
||||||
|
mutex_enter(&spa->spa_evicting_os_lock);
|
||||||
|
while (zfs_refcount_count(&spa->spa_refcount) >
|
||||||
|
spa->spa_minref) {
|
||||||
|
zio_cancel(spa);
|
||||||
|
cv_wait(&spa->spa_evicting_os_cv,
|
||||||
|
&spa->spa_evicting_os_lock);
|
||||||
|
}
|
||||||
|
mutex_exit(&spa->spa_evicting_os_lock);
|
||||||
|
mutex_enter(&spa_namespace_lock);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A pool cannot be exported or destroyed if there are active
|
* A pool cannot be exported or destroyed if there are active
|
||||||
* references. If we are resetting a pool, allow references by
|
* references. If we are resetting a pool, allow references by
|
||||||
* fault injection handlers.
|
* fault injection handlers.
|
||||||
*/
|
*/
|
||||||
if (!spa_refcount_zero(spa) || (spa->spa_inject_ref != 0)) {
|
if (!spa_refcount_zero(spa) || (spa->spa_inject_ref != 0)) {
|
||||||
|
VERIFY(!force_removal);
|
||||||
error = SET_ERROR(EBUSY);
|
error = SET_ERROR(EBUSY);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -6421,6 +6592,7 @@ spa_export_common(const char *pool, int new_state, nvlist_t **oldconfig,
|
||||||
vdev_trim_stop_all(rvd, VDEV_TRIM_ACTIVE);
|
vdev_trim_stop_all(rvd, VDEV_TRIM_ACTIVE);
|
||||||
vdev_autotrim_stop_all(spa);
|
vdev_autotrim_stop_all(spa);
|
||||||
vdev_rebuild_stop_all(spa);
|
vdev_rebuild_stop_all(spa);
|
||||||
|
l2arc_spa_rebuild_stop(spa);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -6463,7 +6635,14 @@ export_spa:
|
||||||
spa_event_notify(spa, NULL, NULL, ESC_ZFS_POOL_EXPORT);
|
spa_event_notify(spa, NULL, NULL, ESC_ZFS_POOL_EXPORT);
|
||||||
|
|
||||||
if (spa->spa_state != POOL_STATE_UNINITIALIZED) {
|
if (spa->spa_state != POOL_STATE_UNINITIALIZED) {
|
||||||
spa_unload(spa);
|
/*
|
||||||
|
* If the pool is not being hard forced, throw an error upon
|
||||||
|
* suspension and abort.
|
||||||
|
*/
|
||||||
|
error = spa_unload(spa, hardforce ?
|
||||||
|
TXG_WAIT_F_FORCE_EXPORT : TXG_WAIT_F_NOSUSPEND);
|
||||||
|
if (error != 0)
|
||||||
|
goto fail;
|
||||||
spa_deactivate(spa);
|
spa_deactivate(spa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6471,7 +6650,7 @@ export_spa:
|
||||||
VERIFY(nvlist_dup(spa->spa_config, oldconfig, 0) == 0);
|
VERIFY(nvlist_dup(spa->spa_config, oldconfig, 0) == 0);
|
||||||
|
|
||||||
if (new_state != POOL_STATE_UNINITIALIZED) {
|
if (new_state != POOL_STATE_UNINITIALIZED) {
|
||||||
if (!hardforce)
|
if (!force_removal)
|
||||||
spa_write_cachefile(spa, B_TRUE, B_TRUE);
|
spa_write_cachefile(spa, B_TRUE, B_TRUE);
|
||||||
spa_remove(spa);
|
spa_remove(spa);
|
||||||
} else {
|
} else {
|
||||||
|
@ -6487,6 +6666,8 @@ export_spa:
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
if (force_removal)
|
||||||
|
spa_set_export_initiator(spa, NULL);
|
||||||
spa->spa_is_exporting = B_FALSE;
|
spa->spa_is_exporting = B_FALSE;
|
||||||
spa_async_resume(spa);
|
spa_async_resume(spa);
|
||||||
mutex_exit(&spa_namespace_lock);
|
mutex_exit(&spa_namespace_lock);
|
||||||
|
@ -6689,10 +6870,8 @@ spa_vdev_add(spa_t *spa, nvlist_t *nvroot)
|
||||||
*/
|
*/
|
||||||
(void) spa_vdev_exit(spa, vd, txg, 0);
|
(void) spa_vdev_exit(spa, vd, txg, 0);
|
||||||
|
|
||||||
mutex_enter(&spa_namespace_lock);
|
spa_config_update_pool(spa);
|
||||||
spa_config_update(spa, SPA_CONFIG_UPDATE_POOL);
|
|
||||||
spa_event_notify(spa, NULL, NULL, ESC_ZFS_VDEV_ADD);
|
spa_event_notify(spa, NULL, NULL, ESC_ZFS_VDEV_ADD);
|
||||||
mutex_exit(&spa_namespace_lock);
|
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -6739,6 +6918,9 @@ spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing,
|
||||||
return (spa_vdev_exit(spa, NULL, txg, error));
|
return (spa_vdev_exit(spa, NULL, txg, error));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If the pool is being force-exported, no vdev changes may occur. */
|
||||||
|
ASSERT(!spa_exiting_any(spa));
|
||||||
|
|
||||||
if (rebuild) {
|
if (rebuild) {
|
||||||
if (!spa_feature_is_enabled(spa, SPA_FEATURE_DEVICE_REBUILD))
|
if (!spa_feature_is_enabled(spa, SPA_FEATURE_DEVICE_REBUILD))
|
||||||
return (spa_vdev_exit(spa, NULL, txg, ENOTSUP));
|
return (spa_vdev_exit(spa, NULL, txg, ENOTSUP));
|
||||||
|
@ -6905,8 +7087,8 @@ spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing,
|
||||||
vdev_propagate_state(pvd);
|
vdev_propagate_state(pvd);
|
||||||
|
|
||||||
tvd = newvd->vdev_top;
|
tvd = newvd->vdev_top;
|
||||||
ASSERT(pvd->vdev_top == tvd);
|
ASSERT3P(pvd->vdev_top, ==, tvd);
|
||||||
ASSERT(tvd->vdev_parent == rvd);
|
ASSERT3P(tvd->vdev_parent, ==, rvd);
|
||||||
|
|
||||||
vdev_config_dirty(tvd);
|
vdev_config_dirty(tvd);
|
||||||
|
|
||||||
|
@ -6950,8 +7132,8 @@ spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing,
|
||||||
spa_feature_is_enabled(spa, SPA_FEATURE_RESILVER_DEFER)) {
|
spa_feature_is_enabled(spa, SPA_FEATURE_RESILVER_DEFER)) {
|
||||||
vdev_defer_resilver(newvd);
|
vdev_defer_resilver(newvd);
|
||||||
} else {
|
} else {
|
||||||
dsl_scan_restart_resilver(spa->spa_dsl_pool,
|
VERIFY0(dsl_scan_restart_resilver(spa->spa_dsl_pool,
|
||||||
dtl_max_txg);
|
dtl_max_txg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7811,7 +7993,7 @@ spa_vdev_split_mirror(spa_t *spa, char *newname, nvlist_t *config,
|
||||||
return (error);
|
return (error);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
spa_unload(newspa);
|
VERIFY0(spa_unload(newspa, TXG_WAIT_F_NONE));
|
||||||
spa_deactivate(newspa);
|
spa_deactivate(newspa);
|
||||||
spa_remove(newspa);
|
spa_remove(newspa);
|
||||||
|
|
||||||
|
@ -8129,6 +8311,19 @@ spa_async_autoexpand(spa_t *spa, vdev_t *vd)
|
||||||
spa_event_notify(vd->vdev_spa, vd, NULL, ESC_ZFS_VDEV_AUTOEXPAND);
|
spa_event_notify(vd->vdev_spa, vd, NULL, ESC_ZFS_VDEV_AUTOEXPAND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint64_t
|
||||||
|
spa_pool_space(spa_t *spa)
|
||||||
|
{
|
||||||
|
uint64_t space;
|
||||||
|
|
||||||
|
space = metaslab_class_get_space(spa_normal_class(spa));
|
||||||
|
space += metaslab_class_get_space(spa_special_class(spa));
|
||||||
|
space += metaslab_class_get_space(spa_dedup_class(spa));
|
||||||
|
space += metaslab_class_get_space(spa_embedded_log_class(spa));
|
||||||
|
|
||||||
|
return (space);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
spa_async_thread(void *arg)
|
spa_async_thread(void *arg)
|
||||||
{
|
{
|
||||||
|
@ -8149,21 +8344,9 @@ spa_async_thread(void *arg)
|
||||||
if (tasks & SPA_ASYNC_CONFIG_UPDATE) {
|
if (tasks & SPA_ASYNC_CONFIG_UPDATE) {
|
||||||
uint64_t old_space, new_space;
|
uint64_t old_space, new_space;
|
||||||
|
|
||||||
mutex_enter(&spa_namespace_lock);
|
new_space = old_space = spa_pool_space(spa);
|
||||||
old_space = metaslab_class_get_space(spa_normal_class(spa));
|
if (spa_config_update_pool(spa) == 0)
|
||||||
old_space += metaslab_class_get_space(spa_special_class(spa));
|
new_space = spa_pool_space(spa);
|
||||||
old_space += metaslab_class_get_space(spa_dedup_class(spa));
|
|
||||||
old_space += metaslab_class_get_space(
|
|
||||||
spa_embedded_log_class(spa));
|
|
||||||
|
|
||||||
spa_config_update(spa, SPA_CONFIG_UPDATE_POOL);
|
|
||||||
|
|
||||||
new_space = metaslab_class_get_space(spa_normal_class(spa));
|
|
||||||
new_space += metaslab_class_get_space(spa_special_class(spa));
|
|
||||||
new_space += metaslab_class_get_space(spa_dedup_class(spa));
|
|
||||||
new_space += metaslab_class_get_space(
|
|
||||||
spa_embedded_log_class(spa));
|
|
||||||
mutex_exit(&spa_namespace_lock);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the pool grew as a result of the config update,
|
* If the pool grew as a result of the config update,
|
||||||
|
@ -8220,7 +8403,7 @@ spa_async_thread(void *arg)
|
||||||
!vdev_rebuild_active(spa->spa_root_vdev) &&
|
!vdev_rebuild_active(spa->spa_root_vdev) &&
|
||||||
(!dsl_scan_resilvering(dp) ||
|
(!dsl_scan_resilvering(dp) ||
|
||||||
!spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_RESILVER_DEFER)))
|
!spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_RESILVER_DEFER)))
|
||||||
dsl_scan_restart_resilver(dp, 0);
|
(void) dsl_scan_restart_resilver(dp, 0);
|
||||||
|
|
||||||
if (tasks & SPA_ASYNC_INITIALIZE_RESTART) {
|
if (tasks & SPA_ASYNC_INITIALIZE_RESTART) {
|
||||||
mutex_enter(&spa_namespace_lock);
|
mutex_enter(&spa_namespace_lock);
|
||||||
|
@ -8473,6 +8656,9 @@ spa_sync_nvlist(spa_t *spa, uint64_t obj, nvlist_t *nv, dmu_tx_t *tx)
|
||||||
size_t nvsize = 0;
|
size_t nvsize = 0;
|
||||||
dmu_buf_t *db;
|
dmu_buf_t *db;
|
||||||
|
|
||||||
|
if (spa_exiting_any(spa))
|
||||||
|
return;
|
||||||
|
|
||||||
VERIFY(nvlist_size(nv, &nvsize, NV_ENCODE_XDR) == 0);
|
VERIFY(nvlist_size(nv, &nvsize, NV_ENCODE_XDR) == 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -8949,6 +9135,9 @@ vdev_indirect_state_sync_verify(vdev_t *vd)
|
||||||
vdev_indirect_mapping_t *vim __maybe_unused = vd->vdev_indirect_mapping;
|
vdev_indirect_mapping_t *vim __maybe_unused = vd->vdev_indirect_mapping;
|
||||||
vdev_indirect_births_t *vib __maybe_unused = vd->vdev_indirect_births;
|
vdev_indirect_births_t *vib __maybe_unused = vd->vdev_indirect_births;
|
||||||
|
|
||||||
|
if (spa_exiting_any(vd->vdev_spa))
|
||||||
|
return;
|
||||||
|
|
||||||
if (vd->vdev_ops == &vdev_indirect_ops) {
|
if (vd->vdev_ops == &vdev_indirect_ops) {
|
||||||
ASSERT(vim != NULL);
|
ASSERT(vim != NULL);
|
||||||
ASSERT(vib != NULL);
|
ASSERT(vib != NULL);
|
||||||
|
@ -9153,10 +9342,10 @@ spa_sync_rewrite_vdev_config(spa_t *spa, dmu_tx_t *tx)
|
||||||
{
|
{
|
||||||
vdev_t *rvd = spa->spa_root_vdev;
|
vdev_t *rvd = spa->spa_root_vdev;
|
||||||
uint64_t txg = tx->tx_txg;
|
uint64_t txg = tx->tx_txg;
|
||||||
|
boolean_t exiting = B_FALSE;
|
||||||
|
|
||||||
for (;;) {
|
while (exiting == B_FALSE) {
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We hold SCL_STATE to prevent vdev open/close/etc.
|
* We hold SCL_STATE to prevent vdev open/close/etc.
|
||||||
* while we're attempting to write the vdev labels.
|
* while we're attempting to write the vdev labels.
|
||||||
|
@ -9200,7 +9389,18 @@ spa_sync_rewrite_vdev_config(spa_t *spa, dmu_tx_t *tx)
|
||||||
if (error == 0)
|
if (error == 0)
|
||||||
break;
|
break;
|
||||||
zio_suspend(spa, NULL, ZIO_SUSPEND_IOERR);
|
zio_suspend(spa, NULL, ZIO_SUSPEND_IOERR);
|
||||||
zio_resume_wait(spa);
|
|
||||||
|
mutex_enter(&spa->spa_suspend_lock);
|
||||||
|
for (;;) {
|
||||||
|
exiting = spa_exiting(spa);
|
||||||
|
if (exiting || spa_suspended(spa) == B_FALSE)
|
||||||
|
break;
|
||||||
|
cv_wait(&spa->spa_suspend_cv, &spa->spa_suspend_lock);
|
||||||
|
}
|
||||||
|
mutex_exit(&spa->spa_suspend_lock);
|
||||||
|
|
||||||
|
if (exiting)
|
||||||
|
zio_cancel(spa);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9299,7 +9499,8 @@ spa_sync(spa_t *spa, uint64_t txg)
|
||||||
spa_sync_iterate_to_convergence(spa, tx);
|
spa_sync_iterate_to_convergence(spa, tx);
|
||||||
|
|
||||||
#ifdef ZFS_DEBUG
|
#ifdef ZFS_DEBUG
|
||||||
if (!list_is_empty(&spa->spa_config_dirty_list)) {
|
if (!list_is_empty(&spa->spa_config_dirty_list) &&
|
||||||
|
!spa_exiting_any(spa)) {
|
||||||
/*
|
/*
|
||||||
* Make sure that the number of ZAPs for all the vdevs matches
|
* Make sure that the number of ZAPs for all the vdevs matches
|
||||||
* the number of ZAPs in the per-vdev ZAP list. This only gets
|
* the number of ZAPs in the per-vdev ZAP list. This only gets
|
||||||
|
@ -9409,7 +9610,8 @@ spa_sync_allpools(void)
|
||||||
continue;
|
continue;
|
||||||
spa_open_ref(spa, FTAG);
|
spa_open_ref(spa, FTAG);
|
||||||
mutex_exit(&spa_namespace_lock);
|
mutex_exit(&spa_namespace_lock);
|
||||||
txg_wait_synced(spa_get_dsl(spa), 0);
|
txg_wait_synced_flags(spa_get_dsl(spa), 0,
|
||||||
|
TXG_WAIT_F_NOSUSPEND);
|
||||||
mutex_enter(&spa_namespace_lock);
|
mutex_enter(&spa_namespace_lock);
|
||||||
spa_close(spa, FTAG);
|
spa_close(spa, FTAG);
|
||||||
}
|
}
|
||||||
|
@ -9448,7 +9650,7 @@ spa_evict_all(void)
|
||||||
spa_close(spa, FTAG);
|
spa_close(spa, FTAG);
|
||||||
|
|
||||||
if (spa->spa_state != POOL_STATE_UNINITIALIZED) {
|
if (spa->spa_state != POOL_STATE_UNINITIALIZED) {
|
||||||
spa_unload(spa);
|
VERIFY0(spa_unload(spa, TXG_WAIT_F_NONE));
|
||||||
spa_deactivate(spa);
|
spa_deactivate(spa);
|
||||||
}
|
}
|
||||||
spa_remove(spa);
|
spa_remove(spa);
|
||||||
|
@ -9910,6 +10112,7 @@ EXPORT_SYMBOL(spa_inject_addref);
|
||||||
EXPORT_SYMBOL(spa_inject_delref);
|
EXPORT_SYMBOL(spa_inject_delref);
|
||||||
EXPORT_SYMBOL(spa_scan_stat_init);
|
EXPORT_SYMBOL(spa_scan_stat_init);
|
||||||
EXPORT_SYMBOL(spa_scan_get_stats);
|
EXPORT_SYMBOL(spa_scan_get_stats);
|
||||||
|
EXPORT_SYMBOL(spa_set_pre_export_status);
|
||||||
|
|
||||||
/* device manipulation */
|
/* device manipulation */
|
||||||
EXPORT_SYMBOL(spa_vdev_add);
|
EXPORT_SYMBOL(spa_vdev_add);
|
||||||
|
|
|
@ -400,6 +400,7 @@ spa_checkpoint_discard_thread(void *arg, zthr_t *zthr)
|
||||||
{
|
{
|
||||||
spa_t *spa = arg;
|
spa_t *spa = arg;
|
||||||
vdev_t *rvd = spa->spa_root_vdev;
|
vdev_t *rvd = spa->spa_root_vdev;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
for (uint64_t c = 0; c < rvd->vdev_children; c++) {
|
for (uint64_t c = 0; c < rvd->vdev_children; c++) {
|
||||||
vdev_t *vd = rvd->vdev_child[c];
|
vdev_t *vd = rvd->vdev_child[c];
|
||||||
|
@ -434,9 +435,10 @@ spa_checkpoint_discard_thread(void *arg, zthr_t *zthr)
|
||||||
error, vd->vdev_id);
|
error, vd->vdev_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
VERIFY0(dsl_sync_task(spa->spa_name, NULL,
|
err = dsl_sync_task(spa->spa_name, NULL,
|
||||||
spa_checkpoint_discard_thread_sync, vd,
|
spa_checkpoint_discard_thread_sync, vd,
|
||||||
0, ZFS_SPACE_CHECK_NONE));
|
0, ZFS_SPACE_CHECK_NONE);
|
||||||
|
VERIFY(err == 0 || spa_exiting_any(spa));
|
||||||
|
|
||||||
dmu_buf_rele_array(dbp, numbufs, FTAG);
|
dmu_buf_rele_array(dbp, numbufs, FTAG);
|
||||||
}
|
}
|
||||||
|
@ -444,9 +446,10 @@ spa_checkpoint_discard_thread(void *arg, zthr_t *zthr)
|
||||||
|
|
||||||
VERIFY(spa_checkpoint_discard_is_done(spa));
|
VERIFY(spa_checkpoint_discard_is_done(spa));
|
||||||
VERIFY0(spa->spa_checkpoint_info.sci_dspace);
|
VERIFY0(spa->spa_checkpoint_info.sci_dspace);
|
||||||
VERIFY0(dsl_sync_task(spa->spa_name, NULL,
|
err = dsl_sync_task(spa->spa_name, NULL,
|
||||||
spa_checkpoint_discard_complete_sync, spa,
|
spa_checkpoint_discard_complete_sync, spa,
|
||||||
0, ZFS_SPACE_CHECK_NONE));
|
0, ZFS_SPACE_CHECK_NONE);
|
||||||
|
VERIFY(err == 0 || spa_exiting_any(spa));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -541,75 +541,115 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats)
|
||||||
return (config);
|
return (config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
spa_config_update_begin(spa_t *spa, const void *tag)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (spa_config_enter_flags(spa, SCL_ALL, tag, RW_WRITER,
|
||||||
|
SCL_FLAG_NOSUSPEND));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Complete a label update. */
|
||||||
|
static int
|
||||||
|
spa_config_update_complete(spa_t *spa, uint64_t txg, boolean_t postsysevent,
|
||||||
|
const void *tag)
|
||||||
|
{
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
|
spa_config_exit(spa, SCL_ALL, tag);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait for the mosconfig to be regenerated and synced.
|
||||||
|
*/
|
||||||
|
error = txg_wait_synced_tx(spa->spa_dsl_pool, txg, NULL, 0);
|
||||||
|
if (error == 0 && !spa->spa_is_root) {
|
||||||
|
/*
|
||||||
|
* Update the global config cache to reflect the new mosconfig.
|
||||||
|
* This operation does not perform any pool I/O, so it is
|
||||||
|
* safe even if one or more of them are suspended.
|
||||||
|
*/
|
||||||
|
mutex_enter(&spa_namespace_lock);
|
||||||
|
spa_write_cachefile(spa, B_FALSE, postsysevent);
|
||||||
|
mutex_exit(&spa_namespace_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update any top-level vdevs needing expansion. */
|
||||||
|
static int
|
||||||
|
spa_config_update_vdevs(spa_t *spa)
|
||||||
|
{
|
||||||
|
vdev_t *rvd = spa->spa_root_vdev;
|
||||||
|
uint64_t txg;
|
||||||
|
int c, error;
|
||||||
|
|
||||||
|
error = spa_config_update_begin(spa, FTAG);
|
||||||
|
if (error != 0)
|
||||||
|
return (error);
|
||||||
|
|
||||||
|
txg = spa_last_synced_txg(spa) + 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we have top-level vdevs that were added but have
|
||||||
|
* not yet been prepared for allocation, do that now.
|
||||||
|
* (It's safe now because the config cache is up to date,
|
||||||
|
* so it will be able to translate the new DVAs.)
|
||||||
|
* See comments in spa_vdev_add() for full details.
|
||||||
|
*/
|
||||||
|
for (c = 0; c < rvd->vdev_children; c++) {
|
||||||
|
vdev_t *tvd = rvd->vdev_child[c];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Explicitly skip vdevs that are indirect or
|
||||||
|
* log vdevs that are being removed. The reason
|
||||||
|
* is that both of those can have vdev_ms_array
|
||||||
|
* set to 0 and we wouldn't want to change their
|
||||||
|
* metaslab size nor call vdev_expand() on them.
|
||||||
|
*/
|
||||||
|
if (!vdev_is_concrete(tvd) ||
|
||||||
|
(tvd->vdev_islog && tvd->vdev_removing))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (tvd->vdev_ms_array == 0)
|
||||||
|
vdev_metaslab_set_size(tvd);
|
||||||
|
vdev_expand(tvd, txg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (spa_config_update_complete(spa, txg, B_TRUE, FTAG));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update all disk labels, generate a fresh config based on the current
|
* Update all disk labels, generate a fresh config based on the current
|
||||||
* in-core state, and sync the global config cache (do not sync the config
|
* in-core state, and sync the global config cache (do not sync the config
|
||||||
* cache if this is a booting rootpool).
|
* cache if this is a booting rootpool).
|
||||||
*/
|
*/
|
||||||
void
|
int
|
||||||
spa_config_update(spa_t *spa, int what)
|
spa_config_update_pool(spa_t *spa)
|
||||||
{
|
{
|
||||||
vdev_t *rvd = spa->spa_root_vdev;
|
vdev_t *rvd = spa->spa_root_vdev;
|
||||||
uint64_t txg;
|
uint64_t txg;
|
||||||
int c;
|
int error;
|
||||||
|
|
||||||
ASSERT(MUTEX_HELD(&spa_namespace_lock));
|
error = spa_config_update_begin(spa, FTAG);
|
||||||
|
if (error != 0)
|
||||||
|
return (error);
|
||||||
|
|
||||||
spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
|
|
||||||
txg = spa_last_synced_txg(spa) + 1;
|
txg = spa_last_synced_txg(spa) + 1;
|
||||||
if (what == SPA_CONFIG_UPDATE_POOL) {
|
vdev_config_dirty(rvd);
|
||||||
vdev_config_dirty(rvd);
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* If we have top-level vdevs that were added but have
|
|
||||||
* not yet been prepared for allocation, do that now.
|
|
||||||
* (It's safe now because the config cache is up to date,
|
|
||||||
* so it will be able to translate the new DVAs.)
|
|
||||||
* See comments in spa_vdev_add() for full details.
|
|
||||||
*/
|
|
||||||
for (c = 0; c < rvd->vdev_children; c++) {
|
|
||||||
vdev_t *tvd = rvd->vdev_child[c];
|
|
||||||
|
|
||||||
/*
|
error = spa_config_update_complete(spa, txg, B_FALSE, FTAG);
|
||||||
* Explicitly skip vdevs that are indirect or
|
if (error == 0)
|
||||||
* log vdevs that are being removed. The reason
|
error = spa_config_update_vdevs(spa);
|
||||||
* is that both of those can have vdev_ms_array
|
|
||||||
* set to 0 and we wouldn't want to change their
|
|
||||||
* metaslab size nor call vdev_expand() on them.
|
|
||||||
*/
|
|
||||||
if (!vdev_is_concrete(tvd) ||
|
|
||||||
(tvd->vdev_islog && tvd->vdev_removing))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (tvd->vdev_ms_array == 0)
|
return (error);
|
||||||
vdev_metaslab_set_size(tvd);
|
|
||||||
vdev_expand(tvd, txg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spa_config_exit(spa, SCL_ALL, FTAG);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Wait for the mosconfig to be regenerated and synced.
|
|
||||||
*/
|
|
||||||
txg_wait_synced(spa->spa_dsl_pool, txg);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Update the global config cache to reflect the new mosconfig.
|
|
||||||
*/
|
|
||||||
if (!spa->spa_is_root) {
|
|
||||||
spa_write_cachefile(spa, B_FALSE,
|
|
||||||
what != SPA_CONFIG_UPDATE_POOL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (what == SPA_CONFIG_UPDATE_POOL)
|
|
||||||
spa_config_update(spa, SPA_CONFIG_UPDATE_VDEVS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(spa_config_load);
|
EXPORT_SYMBOL(spa_config_load);
|
||||||
EXPORT_SYMBOL(spa_all_configs);
|
EXPORT_SYMBOL(spa_all_configs);
|
||||||
EXPORT_SYMBOL(spa_config_set);
|
EXPORT_SYMBOL(spa_config_set);
|
||||||
EXPORT_SYMBOL(spa_config_generate);
|
EXPORT_SYMBOL(spa_config_generate);
|
||||||
EXPORT_SYMBOL(spa_config_update);
|
EXPORT_SYMBOL(spa_config_update_pool);
|
||||||
|
|
||||||
/* BEGIN CSTYLED */
|
/* BEGIN CSTYLED */
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
|
|
@ -99,9 +99,9 @@ spa_log_error(spa_t *spa, const zbookmark_phys_t *zb)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we are trying to import a pool, ignore any errors, as we won't be
|
* If we are trying to import a pool, ignore any errors, as we won't be
|
||||||
* writing to the pool any time soon.
|
* writing to the pool any time soon. Same for force exports.
|
||||||
*/
|
*/
|
||||||
if (spa_load_state(spa) == SPA_LOAD_TRYIMPORT)
|
if (spa_exiting_any(spa) || spa_load_state(spa) == SPA_LOAD_TRYIMPORT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mutex_enter(&spa->spa_errlist_lock);
|
mutex_enter(&spa->spa_errlist_lock);
|
||||||
|
@ -307,13 +307,15 @@ sync_error_list(spa_t *spa, avl_tree_t *t, uint64_t *obj, dmu_tx_t *tx)
|
||||||
void *cookie;
|
void *cookie;
|
||||||
|
|
||||||
if (avl_numnodes(t) != 0) {
|
if (avl_numnodes(t) != 0) {
|
||||||
|
if (spa_exiting_any(spa))
|
||||||
|
goto done;
|
||||||
|
|
||||||
/* create log if necessary */
|
/* create log if necessary */
|
||||||
if (*obj == 0)
|
if (*obj == 0)
|
||||||
*obj = zap_create(spa->spa_meta_objset,
|
*obj = zap_create(spa->spa_meta_objset,
|
||||||
DMU_OT_ERROR_LOG, DMU_OT_NONE,
|
DMU_OT_ERROR_LOG, DMU_OT_NONE,
|
||||||
0, tx);
|
0, tx);
|
||||||
|
|
||||||
/* add errors to the current log */
|
|
||||||
for (se = avl_first(t); se != NULL; se = AVL_NEXT(t, se)) {
|
for (se = avl_first(t); se != NULL; se = AVL_NEXT(t, se)) {
|
||||||
char *name = se->se_name ? se->se_name : "";
|
char *name = se->se_name ? se->se_name : "";
|
||||||
|
|
||||||
|
@ -323,6 +325,7 @@ sync_error_list(spa_t *spa, avl_tree_t *t, uint64_t *obj, dmu_tx_t *tx)
|
||||||
*obj, buf, 1, strlen(name) + 1, name, tx);
|
*obj, buf, 1, strlen(name) + 1, name, tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
/* purge the error list */
|
/* purge the error list */
|
||||||
cookie = NULL;
|
cookie = NULL;
|
||||||
while ((se = avl_destroy_nodes(t, &cookie)) != NULL)
|
while ((se = avl_destroy_nodes(t, &cookie)) != NULL)
|
||||||
|
|
|
@ -385,7 +385,7 @@ spa_history_log_nvl(spa_t *spa, nvlist_t *nvl)
|
||||||
}
|
}
|
||||||
|
|
||||||
tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
|
tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
|
||||||
err = dmu_tx_assign(tx, TXG_WAIT);
|
err = dmu_tx_assign(tx, TXG_WAIT | TXG_NOSUSPEND);
|
||||||
if (err) {
|
if (err) {
|
||||||
dmu_tx_abort(tx);
|
dmu_tx_abort(tx);
|
||||||
return (err);
|
return (err);
|
||||||
|
@ -521,9 +521,10 @@ log_internal(nvlist_t *nvl, const char *operation, spa_t *spa,
|
||||||
/*
|
/*
|
||||||
* If this is part of creating a pool, not everything is
|
* If this is part of creating a pool, not everything is
|
||||||
* initialized yet, so don't bother logging the internal events.
|
* initialized yet, so don't bother logging the internal events.
|
||||||
* Likewise if the pool is not writeable.
|
* Likewise if the pool is not writeable, or is being force exported.
|
||||||
*/
|
*/
|
||||||
if (spa_is_initializing(spa) || !spa_writeable(spa)) {
|
if (spa_is_initializing(spa) || !spa_writeable(spa) ||
|
||||||
|
spa_exiting_any(spa)) {
|
||||||
fnvlist_free(nvl);
|
fnvlist_free(nvl);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -885,7 +885,9 @@ spa_cleanup_old_sm_logs(spa_t *spa, dmu_tx_t *tx)
|
||||||
ASSERT(avl_is_empty(&spa->spa_sm_logs_by_txg));
|
ASSERT(avl_is_empty(&spa->spa_sm_logs_by_txg));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
VERIFY0(error);
|
VERIFY(error == 0 || spa_exiting_any(spa));
|
||||||
|
if (error != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
metaslab_t *oldest = avl_first(&spa->spa_metaslabs_by_flushed);
|
metaslab_t *oldest = avl_first(&spa->spa_metaslabs_by_flushed);
|
||||||
uint64_t oldest_flushed_txg = metaslab_unflushed_txg(oldest);
|
uint64_t oldest_flushed_txg = metaslab_unflushed_txg(oldest);
|
||||||
|
@ -938,7 +940,9 @@ spa_generate_syncing_log_sm(spa_t *spa, dmu_tx_t *tx)
|
||||||
&spacemap_zap, tx));
|
&spacemap_zap, tx));
|
||||||
spa_feature_incr(spa, SPA_FEATURE_LOG_SPACEMAP, tx);
|
spa_feature_incr(spa, SPA_FEATURE_LOG_SPACEMAP, tx);
|
||||||
}
|
}
|
||||||
VERIFY0(error);
|
VERIFY(error == 0 || spa_exiting_any(spa));
|
||||||
|
if (error != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
uint64_t sm_obj;
|
uint64_t sm_obj;
|
||||||
ASSERT3U(zap_lookup_int_key(mos, spacemap_zap, txg, &sm_obj),
|
ASSERT3U(zap_lookup_int_key(mos, spacemap_zap, txg, &sm_obj),
|
||||||
|
|
|
@ -463,46 +463,32 @@ spa_config_lock_destroy(spa_t *spa)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
spa_config_tryenter(spa_t *spa, int locks, void *tag, krw_t rw)
|
spa_config_eval_flags(spa_t *spa, spa_config_flag_t flags)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < SCL_LOCKS; i++) {
|
int error = 0;
|
||||||
spa_config_lock_t *scl = &spa->spa_config_lock[i];
|
|
||||||
if (!(locks & (1 << i)))
|
if ((flags & SCL_FLAG_TRYENTER) != 0)
|
||||||
continue;
|
error = SET_ERROR(EAGAIN);
|
||||||
mutex_enter(&scl->scl_lock);
|
if (error == 0 && ((flags & SCL_FLAG_NOSUSPEND) != 0)) {
|
||||||
if (rw == RW_READER) {
|
/* Notification given by zio_suspend(). */
|
||||||
if (scl->scl_writer || scl->scl_write_wanted) {
|
mutex_enter(&spa->spa_suspend_lock);
|
||||||
mutex_exit(&scl->scl_lock);
|
error = spa_suspended(spa) ? SET_ERROR(EAGAIN) : 0;
|
||||||
spa_config_exit(spa, locks & ((1 << i) - 1),
|
mutex_exit(&spa->spa_suspend_lock);
|
||||||
tag);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ASSERT(scl->scl_writer != curthread);
|
|
||||||
if (!zfs_refcount_is_zero(&scl->scl_count)) {
|
|
||||||
mutex_exit(&scl->scl_lock);
|
|
||||||
spa_config_exit(spa, locks & ((1 << i) - 1),
|
|
||||||
tag);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
scl->scl_writer = curthread;
|
|
||||||
}
|
|
||||||
(void) zfs_refcount_add(&scl->scl_count, tag);
|
|
||||||
mutex_exit(&scl->scl_lock);
|
|
||||||
}
|
}
|
||||||
return (1);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
spa_config_enter(spa_t *spa, int locks, const void *tag, krw_t rw)
|
spa_config_enter_flags(spa_t *spa, int locks, const void *tag, krw_t rw,
|
||||||
|
spa_config_flag_t flags)
|
||||||
{
|
{
|
||||||
(void) tag;
|
int error = 0;
|
||||||
int wlocks_held = 0;
|
int wlocks_held = 0;
|
||||||
|
|
||||||
ASSERT3U(SCL_LOCKS, <, sizeof (wlocks_held) * NBBY);
|
ASSERT3U(SCL_LOCKS, <, sizeof (wlocks_held) * NBBY);
|
||||||
|
|
||||||
for (int i = 0; i < SCL_LOCKS; i++) {
|
for (int i = 0; error == 0 && i < SCL_LOCKS; i++) {
|
||||||
spa_config_lock_t *scl = &spa->spa_config_lock[i];
|
spa_config_lock_t *scl = &spa->spa_config_lock[i];
|
||||||
if (scl->scl_writer == curthread)
|
if (scl->scl_writer == curthread)
|
||||||
wlocks_held |= (1 << i);
|
wlocks_held |= (1 << i);
|
||||||
|
@ -511,21 +497,53 @@ spa_config_enter(spa_t *spa, int locks, const void *tag, krw_t rw)
|
||||||
mutex_enter(&scl->scl_lock);
|
mutex_enter(&scl->scl_lock);
|
||||||
if (rw == RW_READER) {
|
if (rw == RW_READER) {
|
||||||
while (scl->scl_writer || scl->scl_write_wanted) {
|
while (scl->scl_writer || scl->scl_write_wanted) {
|
||||||
|
error = spa_config_eval_flags(spa, flags);
|
||||||
|
if (error != 0)
|
||||||
|
break;
|
||||||
cv_wait(&scl->scl_cv, &scl->scl_lock);
|
cv_wait(&scl->scl_cv, &scl->scl_lock);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ASSERT(scl->scl_writer != curthread);
|
ASSERT(scl->scl_writer != curthread);
|
||||||
while (!zfs_refcount_is_zero(&scl->scl_count)) {
|
while (!zfs_refcount_is_zero(&scl->scl_count)) {
|
||||||
|
error = spa_config_eval_flags(spa, flags);
|
||||||
|
if (error != 0)
|
||||||
|
break;
|
||||||
scl->scl_write_wanted++;
|
scl->scl_write_wanted++;
|
||||||
cv_wait(&scl->scl_cv, &scl->scl_lock);
|
cv_wait(&scl->scl_cv, &scl->scl_lock);
|
||||||
scl->scl_write_wanted--;
|
scl->scl_write_wanted--;
|
||||||
}
|
}
|
||||||
scl->scl_writer = curthread;
|
if (error == 0)
|
||||||
|
scl->scl_writer = curthread;
|
||||||
}
|
}
|
||||||
(void) zfs_refcount_add(&scl->scl_count, tag);
|
if (error == 0)
|
||||||
|
(void) zfs_refcount_add(&scl->scl_count, tag);
|
||||||
mutex_exit(&scl->scl_lock);
|
mutex_exit(&scl->scl_lock);
|
||||||
|
|
||||||
|
if (error != 0 && i > 0) {
|
||||||
|
/* Should never happen for classic spa_config_enter. */
|
||||||
|
ASSERT3U(flags, !=, 0);
|
||||||
|
spa_config_exit(spa, locks & ((1 << i) - 1), tag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT3U(wlocks_held, <=, locks);
|
ASSERT3U(wlocks_held, <=, locks);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
spa_config_enter(spa_t *spa, int locks, const void *tag, krw_t rw)
|
||||||
|
{
|
||||||
|
spa_config_flag_t flags = 0;
|
||||||
|
|
||||||
|
spa_config_enter_flags(spa, locks, tag, rw, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
spa_config_tryenter(spa_t *spa, int locks, const void *tag, krw_t rw)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (spa_config_enter_flags(spa, locks, tag, rw,
|
||||||
|
SCL_FLAG_TRYENTER) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -887,6 +905,20 @@ spa_open_ref(spa_t *spa, void *tag)
|
||||||
(void) zfs_refcount_add(&spa->spa_refcount, tag);
|
(void) zfs_refcount_add(&spa->spa_refcount, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove a reference to a given spa_t. Common routine that also includes
|
||||||
|
* notifying the exporter if one is registered, when minref has been reached.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
spa_close_common(spa_t *spa, const void *tag)
|
||||||
|
{
|
||||||
|
if (zfs_refcount_remove(&spa->spa_refcount, tag) == spa->spa_minref) {
|
||||||
|
mutex_enter(&spa->spa_evicting_os_lock);
|
||||||
|
cv_broadcast(&spa->spa_evicting_os_cv);
|
||||||
|
mutex_exit(&spa->spa_evicting_os_lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove a reference to the given spa_t. Must have at least one reference, or
|
* Remove a reference to the given spa_t. Must have at least one reference, or
|
||||||
* have the namespace lock held.
|
* have the namespace lock held.
|
||||||
|
@ -896,7 +928,7 @@ spa_close(spa_t *spa, void *tag)
|
||||||
{
|
{
|
||||||
ASSERT(zfs_refcount_count(&spa->spa_refcount) > spa->spa_minref ||
|
ASSERT(zfs_refcount_count(&spa->spa_refcount) > spa->spa_minref ||
|
||||||
MUTEX_HELD(&spa_namespace_lock));
|
MUTEX_HELD(&spa_namespace_lock));
|
||||||
(void) zfs_refcount_remove(&spa->spa_refcount, tag);
|
spa_close_common(spa, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -910,7 +942,7 @@ spa_close(spa_t *spa, void *tag)
|
||||||
void
|
void
|
||||||
spa_async_close(spa_t *spa, void *tag)
|
spa_async_close(spa_t *spa, void *tag)
|
||||||
{
|
{
|
||||||
(void) zfs_refcount_remove(&spa->spa_refcount, tag);
|
spa_close_common(spa, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1729,6 +1761,19 @@ spa_syncing_txg(spa_t *spa)
|
||||||
return (spa->spa_syncing_txg);
|
return (spa->spa_syncing_txg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verify that the requesting thread isn't dirtying a txg it's not supposed
|
||||||
|
* to be. Normally, this must be spa_final_dirty_txg(), but if the pool is
|
||||||
|
* being force exported, no data will be written to stable storage anyway.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
spa_verify_dirty_txg(spa_t *spa, uint64_t txg)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (spa->spa_export_initiator == NULL)
|
||||||
|
VERIFY3U(txg, <=, spa_final_dirty_txg(spa));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the last txg where data can be dirtied. The final txgs
|
* Return the last txg where data can be dirtied. The final txgs
|
||||||
* will be used to just clear out any deferred frees that remain.
|
* will be used to just clear out any deferred frees that remain.
|
||||||
|
@ -1988,6 +2033,18 @@ spa_preferred_class(spa_t *spa, uint64_t size, dmu_object_type_t objtype,
|
||||||
return (spa_normal_class(spa));
|
return (spa_normal_class(spa));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
spa_evicting_os_lock(spa_t *spa)
|
||||||
|
{
|
||||||
|
mutex_enter(&spa->spa_evicting_os_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
spa_evicting_os_unlock(spa_t *spa)
|
||||||
|
{
|
||||||
|
mutex_exit(&spa->spa_evicting_os_lock);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
spa_evicting_os_register(spa_t *spa, objset_t *os)
|
spa_evicting_os_register(spa_t *spa, objset_t *os)
|
||||||
{
|
{
|
||||||
|
@ -2612,6 +2669,31 @@ spa_maxblocksize(spa_t *spa)
|
||||||
return (SPA_OLD_MAXBLOCKSIZE);
|
return (SPA_OLD_MAXBLOCKSIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean_t
|
||||||
|
spa_exiting_any(spa_t *spa)
|
||||||
|
{
|
||||||
|
return (spa->spa_export_initiator != NULL || spa->spa_pre_exporting);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NB: must hold spa_namespace_lock or spa_evicting_os_lock if the result of
|
||||||
|
* this is critical.
|
||||||
|
*/
|
||||||
|
boolean_t
|
||||||
|
spa_exiting(spa_t *spa)
|
||||||
|
{
|
||||||
|
return (spa_exiting_any(spa) && spa->spa_export_initiator != curthread);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
spa_operation_interrupted(spa_t *spa)
|
||||||
|
{
|
||||||
|
if (issig(JUSTLOOKING) && issig(FORREAL))
|
||||||
|
return (SET_ERROR(EINTR));
|
||||||
|
if (spa_exiting(spa))
|
||||||
|
return (SET_ERROR(ENXIO));
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the txg that the last device removal completed. No indirect mappings
|
* Returns the txg that the last device removal completed. No indirect mappings
|
||||||
|
@ -2892,6 +2974,8 @@ EXPORT_SYMBOL(spa_delegation);
|
||||||
EXPORT_SYMBOL(spa_meta_objset);
|
EXPORT_SYMBOL(spa_meta_objset);
|
||||||
EXPORT_SYMBOL(spa_maxblocksize);
|
EXPORT_SYMBOL(spa_maxblocksize);
|
||||||
EXPORT_SYMBOL(spa_maxdnodesize);
|
EXPORT_SYMBOL(spa_maxdnodesize);
|
||||||
|
EXPORT_SYMBOL(spa_exiting);
|
||||||
|
EXPORT_SYMBOL(spa_operation_interrupted);
|
||||||
|
|
||||||
/* Miscellaneous support routines */
|
/* Miscellaneous support routines */
|
||||||
EXPORT_SYMBOL(spa_guid_exists);
|
EXPORT_SYMBOL(spa_guid_exists);
|
||||||
|
|
|
@ -860,7 +860,7 @@ space_map_truncate(space_map_t *sm, int blocksize, dmu_tx_t *tx)
|
||||||
|
|
||||||
ASSERT(dsl_pool_sync_context(dmu_objset_pool(os)));
|
ASSERT(dsl_pool_sync_context(dmu_objset_pool(os)));
|
||||||
ASSERT(dmu_tx_is_syncing(tx));
|
ASSERT(dmu_tx_is_syncing(tx));
|
||||||
VERIFY3U(dmu_tx_get_txg(tx), <=, spa_final_dirty_txg(spa));
|
spa_verify_dirty_txg(spa, dmu_tx_get_txg(tx));
|
||||||
|
|
||||||
dmu_object_info_from_db(sm->sm_dbuf, &doi);
|
dmu_object_info_from_db(sm->sm_dbuf, &doi);
|
||||||
|
|
||||||
|
|
155
module/zfs/txg.c
155
module/zfs/txg.c
|
@ -28,6 +28,7 @@
|
||||||
#include <sys/txg_impl.h>
|
#include <sys/txg_impl.h>
|
||||||
#include <sys/dmu_impl.h>
|
#include <sys/dmu_impl.h>
|
||||||
#include <sys/spa_impl.h>
|
#include <sys/spa_impl.h>
|
||||||
|
#include <sys/dmu_objset.h>
|
||||||
#include <sys/dmu_tx.h>
|
#include <sys/dmu_tx.h>
|
||||||
#include <sys/dsl_pool.h>
|
#include <sys/dsl_pool.h>
|
||||||
#include <sys/dsl_scan.h>
|
#include <sys/dsl_scan.h>
|
||||||
|
@ -255,10 +256,11 @@ txg_thread_wait(tx_state_t *tx, callb_cpr_t *cpr, kcondvar_t *cv, clock_t time)
|
||||||
/*
|
/*
|
||||||
* Stop syncing transaction groups.
|
* Stop syncing transaction groups.
|
||||||
*/
|
*/
|
||||||
void
|
int
|
||||||
txg_sync_stop(dsl_pool_t *dp)
|
txg_sync_stop(dsl_pool_t *dp, txg_wait_flag_t txg_how)
|
||||||
{
|
{
|
||||||
tx_state_t *tx = &dp->dp_tx;
|
tx_state_t *tx = &dp->dp_tx;
|
||||||
|
int err;
|
||||||
|
|
||||||
dprintf("pool %p\n", dp);
|
dprintf("pool %p\n", dp);
|
||||||
/*
|
/*
|
||||||
|
@ -269,7 +271,10 @@ txg_sync_stop(dsl_pool_t *dp)
|
||||||
/*
|
/*
|
||||||
* We need to ensure that we've vacated the deferred metaslab trees.
|
* We need to ensure that we've vacated the deferred metaslab trees.
|
||||||
*/
|
*/
|
||||||
txg_wait_synced(dp, tx->tx_open_txg + TXG_DEFER_SIZE);
|
err = txg_wait_synced_tx(dp, tx->tx_open_txg + TXG_DEFER_SIZE,
|
||||||
|
NULL, txg_how);
|
||||||
|
if (err != 0)
|
||||||
|
return (err);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wake all sync threads and wait for them to die.
|
* Wake all sync threads and wait for them to die.
|
||||||
|
@ -290,6 +295,7 @@ txg_sync_stop(dsl_pool_t *dp)
|
||||||
tx->tx_exiting = 0;
|
tx->tx_exiting = 0;
|
||||||
|
|
||||||
mutex_exit(&tx->tx_sync_lock);
|
mutex_exit(&tx->tx_sync_lock);
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -522,6 +528,24 @@ txg_has_quiesced_to_sync(dsl_pool_t *dp)
|
||||||
return (tx->tx_quiesced_txg != 0);
|
return (tx->tx_quiesced_txg != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Notify of completion. This is usually only called by the sync thread,
|
||||||
|
* but in force-export/unmount scenarios, it can be called by another thread
|
||||||
|
* that has generated an alternative completion scenario.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
txg_completion_notify(dsl_pool_t *dp)
|
||||||
|
{
|
||||||
|
tx_state_t *tx = &dp->dp_tx;
|
||||||
|
boolean_t locked = MUTEX_HELD(&tx->tx_sync_lock);
|
||||||
|
|
||||||
|
if (!locked)
|
||||||
|
mutex_enter(&tx->tx_sync_lock);
|
||||||
|
cv_broadcast(&tx->tx_sync_done_cv);
|
||||||
|
if (!locked)
|
||||||
|
mutex_exit(&tx->tx_sync_lock);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
txg_sync_thread(void *arg)
|
txg_sync_thread(void *arg)
|
||||||
{
|
{
|
||||||
|
@ -602,7 +626,7 @@ txg_sync_thread(void *arg)
|
||||||
tx->tx_synced_txg = txg;
|
tx->tx_synced_txg = txg;
|
||||||
tx->tx_syncing_txg = 0;
|
tx->tx_syncing_txg = 0;
|
||||||
DTRACE_PROBE2(txg__synced, dsl_pool_t *, dp, uint64_t, txg);
|
DTRACE_PROBE2(txg__synced, dsl_pool_t *, dp, uint64_t, txg);
|
||||||
cv_broadcast(&tx->tx_sync_done_cv);
|
txg_completion_notify(dp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dispatch commit callbacks to worker threads.
|
* Dispatch commit callbacks to worker threads.
|
||||||
|
@ -695,61 +719,88 @@ txg_delay(dsl_pool_t *dp, uint64_t txg, hrtime_t delay, hrtime_t resolution)
|
||||||
mutex_exit(&tx->tx_sync_lock);
|
mutex_exit(&tx->tx_sync_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean_t
|
int
|
||||||
txg_wait_synced_impl(dsl_pool_t *dp, uint64_t txg, boolean_t wait_sig)
|
txg_wait_synced_tx(dsl_pool_t *dp, uint64_t txg, dmu_tx_t *tx,
|
||||||
|
txg_wait_flag_t flags)
|
||||||
{
|
{
|
||||||
tx_state_t *tx = &dp->dp_tx;
|
tx_state_t *dp_tx = &dp->dp_tx;
|
||||||
|
int error = 0;
|
||||||
|
objset_t *os = NULL;
|
||||||
|
|
||||||
ASSERT(!dsl_pool_config_held(dp));
|
ASSERT(!dsl_pool_config_held(dp));
|
||||||
|
|
||||||
mutex_enter(&tx->tx_sync_lock);
|
mutex_enter(&dp_tx->tx_sync_lock);
|
||||||
ASSERT3U(tx->tx_threads, ==, 2);
|
ASSERT3U(dp_tx->tx_threads, ==, 2);
|
||||||
if (txg == 0)
|
if (txg == 0)
|
||||||
txg = tx->tx_open_txg + TXG_DEFER_SIZE;
|
txg = dp_tx->tx_open_txg + TXG_DEFER_SIZE;
|
||||||
if (tx->tx_sync_txg_waiting < txg)
|
if (dp_tx->tx_sync_txg_waiting < txg)
|
||||||
tx->tx_sync_txg_waiting = txg;
|
dp_tx->tx_sync_txg_waiting = txg;
|
||||||
|
if (tx != NULL && tx->tx_objset != NULL)
|
||||||
|
os = tx->tx_objset;
|
||||||
dprintf("txg=%llu quiesce_txg=%llu sync_txg=%llu\n",
|
dprintf("txg=%llu quiesce_txg=%llu sync_txg=%llu\n",
|
||||||
(u_longlong_t)txg, (u_longlong_t)tx->tx_quiesce_txg_waiting,
|
(u_longlong_t)txg, (u_longlong_t)dp_tx->tx_quiesce_txg_waiting,
|
||||||
(u_longlong_t)tx->tx_sync_txg_waiting);
|
(u_longlong_t)dp_tx->tx_sync_txg_waiting);
|
||||||
while (tx->tx_synced_txg < txg) {
|
while (error == 0 && dp_tx->tx_synced_txg < txg) {
|
||||||
dprintf("broadcasting sync more "
|
dprintf("broadcasting sync more "
|
||||||
"tx_synced=%llu waiting=%llu dp=%px\n",
|
"tx_synced=%llu waiting=%llu dp=%px\n",
|
||||||
(u_longlong_t)tx->tx_synced_txg,
|
(u_longlong_t)dp_tx->tx_synced_txg,
|
||||||
(u_longlong_t)tx->tx_sync_txg_waiting, dp);
|
(u_longlong_t)dp_tx->tx_sync_txg_waiting, dp);
|
||||||
cv_broadcast(&tx->tx_sync_more_cv);
|
cv_broadcast(&dp_tx->tx_sync_more_cv);
|
||||||
if (wait_sig) {
|
/*
|
||||||
|
* If we are suspending and exiting, give up, because our
|
||||||
|
* data isn't going to be pushed.
|
||||||
|
*/
|
||||||
|
if (spa_suspended(dp->dp_spa)) {
|
||||||
|
if ((flags & TXG_WAIT_F_FORCE_EXPORT)) {
|
||||||
|
error = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((flags & TXG_WAIT_F_NOSUSPEND) ||
|
||||||
|
spa_exiting_any(dp->dp_spa)) {
|
||||||
|
error = SET_ERROR(EAGAIN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (error == 0 && os != NULL && dmu_objset_exiting(os)) {
|
||||||
|
if ((flags & TXG_WAIT_F_FORCE_EXPORT)) {
|
||||||
|
error = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
error = SET_ERROR(EAGAIN);
|
||||||
|
}
|
||||||
|
if (error != 0)
|
||||||
|
break;
|
||||||
|
if (flags & TXG_WAIT_F_SIGNAL) {
|
||||||
/*
|
/*
|
||||||
* Condition wait here but stop if the thread receives a
|
* Condition wait here but stop if the thread receives a
|
||||||
* signal. The caller may call txg_wait_synced*() again
|
* signal. The caller may call txg_wait_synced*() again
|
||||||
* to resume waiting for this txg.
|
* to resume waiting for this txg.
|
||||||
*/
|
*/
|
||||||
if (cv_wait_io_sig(&tx->tx_sync_done_cv,
|
if (cv_wait_io_sig(&dp_tx->tx_sync_done_cv,
|
||||||
&tx->tx_sync_lock) == 0) {
|
&dp_tx->tx_sync_lock) == 0) {
|
||||||
mutex_exit(&tx->tx_sync_lock);
|
error = SET_ERROR(EINTR);
|
||||||
return (B_TRUE);
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cv_wait_io(&tx->tx_sync_done_cv, &tx->tx_sync_lock);
|
cv_wait_io(&dp_tx->tx_sync_done_cv,
|
||||||
|
&dp_tx->tx_sync_lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutex_exit(&tx->tx_sync_lock);
|
|
||||||
return (B_FALSE);
|
mutex_exit(&dp_tx->tx_sync_lock);
|
||||||
|
dprintf("txg=%llu error=%d\n", (u_longlong_t)txg, error);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
txg_wait_synced_flags(dsl_pool_t *dp, uint64_t txg, txg_wait_flag_t flags)
|
||||||
|
{
|
||||||
|
return (txg_wait_synced_tx(dp, txg, NULL, flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
txg_wait_synced(dsl_pool_t *dp, uint64_t txg)
|
txg_wait_synced(dsl_pool_t *dp, uint64_t txg)
|
||||||
{
|
{
|
||||||
VERIFY0(txg_wait_synced_impl(dp, txg, B_FALSE));
|
(void) txg_wait_synced_tx(dp, txg, NULL, 0);
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Similar to a txg_wait_synced but it can be interrupted from a signal.
|
|
||||||
* Returns B_TRUE if the thread was signaled while waiting.
|
|
||||||
*/
|
|
||||||
boolean_t
|
|
||||||
txg_wait_synced_sig(dsl_pool_t *dp, uint64_t txg)
|
|
||||||
{
|
|
||||||
return (txg_wait_synced_impl(dp, txg, B_TRUE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -829,6 +880,36 @@ txg_sync_waiting(dsl_pool_t *dp)
|
||||||
tx->tx_quiesced_txg != 0);
|
tx->tx_quiesced_txg != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
txg_force_export(spa_t *spa)
|
||||||
|
{
|
||||||
|
dsl_pool_t *dp = spa_get_dsl(spa);
|
||||||
|
tx_state_t *tx = &dp->dp_tx;
|
||||||
|
uint64_t t, txg;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When forcing removal, push through TXG_SIZE TXGs to ensure that
|
||||||
|
* all state is cleaned up by spa_sync(). While waiting for each
|
||||||
|
* TXG to complete, cancel any suspended zios that appear.
|
||||||
|
*/
|
||||||
|
ASSERT(spa_exiting_any(spa));
|
||||||
|
txg = tx->tx_synced_txg + 1;
|
||||||
|
for (t = 0; t < TXG_SIZE; t++) {
|
||||||
|
txg_wait_open(dp, txg + t, B_TRUE);
|
||||||
|
|
||||||
|
boolean_t complete = B_FALSE;
|
||||||
|
while (!complete) {
|
||||||
|
zio_cancel(spa);
|
||||||
|
mutex_enter(&tx->tx_sync_lock);
|
||||||
|
(void) cv_timedwait(&tx->tx_sync_done_cv,
|
||||||
|
&tx->tx_sync_lock,
|
||||||
|
ddi_get_lbolt() + MSEC_TO_TICK(100));
|
||||||
|
complete = (tx->tx_synced_txg >= (txg + t));
|
||||||
|
mutex_exit(&tx->tx_sync_lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Verify that this txg is active (open, quiescing, syncing). Non-active
|
* Verify that this txg is active (open, quiescing, syncing). Non-active
|
||||||
* txg's should not be manipulated.
|
* txg's should not be manipulated.
|
||||||
|
|
|
@ -973,6 +973,8 @@ void
|
||||||
vdev_free(vdev_t *vd)
|
vdev_free(vdev_t *vd)
|
||||||
{
|
{
|
||||||
spa_t *spa = vd->vdev_spa;
|
spa_t *spa = vd->vdev_spa;
|
||||||
|
uint64_t t, txg;
|
||||||
|
metaslab_t *msp;
|
||||||
|
|
||||||
ASSERT3P(vd->vdev_initialize_thread, ==, NULL);
|
ASSERT3P(vd->vdev_initialize_thread, ==, NULL);
|
||||||
ASSERT3P(vd->vdev_trim_thread, ==, NULL);
|
ASSERT3P(vd->vdev_trim_thread, ==, NULL);
|
||||||
|
@ -997,6 +999,19 @@ vdev_free(vdev_t *vd)
|
||||||
*/
|
*/
|
||||||
vdev_close(vd);
|
vdev_close(vd);
|
||||||
|
|
||||||
|
/* If the pool is being forcibly exported, clean up any stragglers. */
|
||||||
|
if (spa_exiting_any(spa)) {
|
||||||
|
for (t = 0, txg = spa_syncing_txg(spa) + 1; t < TXG_SIZE; ) {
|
||||||
|
msp = txg_list_remove(&vd->vdev_ms_list, t);
|
||||||
|
if (msp == NULL) {
|
||||||
|
t++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
VERIFY3U(t, ==, txg & TXG_MASK);
|
||||||
|
/* Metaslab already destroyed, nothing to do. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ASSERT(!list_link_active(&vd->vdev_config_dirty_node));
|
ASSERT(!list_link_active(&vd->vdev_config_dirty_node));
|
||||||
ASSERT(!list_link_active(&vd->vdev_state_dirty_node));
|
ASSERT(!list_link_active(&vd->vdev_state_dirty_node));
|
||||||
|
|
||||||
|
@ -1026,6 +1041,9 @@ vdev_free(vdev_t *vd)
|
||||||
vd->vdev_log_mg = NULL;
|
vd->vdev_log_mg = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (spa_exiting_any(spa))
|
||||||
|
vdev_clear_stats(vd);
|
||||||
|
|
||||||
ASSERT0(vd->vdev_stat.vs_space);
|
ASSERT0(vd->vdev_stat.vs_space);
|
||||||
ASSERT0(vd->vdev_stat.vs_dspace);
|
ASSERT0(vd->vdev_stat.vs_dspace);
|
||||||
ASSERT0(vd->vdev_stat.vs_alloc);
|
ASSERT0(vd->vdev_stat.vs_alloc);
|
||||||
|
@ -3263,6 +3281,16 @@ vdev_dtl_sync(vdev_t *vd, uint64_t txg)
|
||||||
dmu_tx_t *tx;
|
dmu_tx_t *tx;
|
||||||
uint64_t object = space_map_object(vd->vdev_dtl_sm);
|
uint64_t object = space_map_object(vd->vdev_dtl_sm);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The pool is being forcibly exported. Just discard everything.
|
||||||
|
*/
|
||||||
|
if (spa_exiting(spa)) {
|
||||||
|
mutex_enter(&vd->vdev_dtl_lock);
|
||||||
|
range_tree_vacate(rt, NULL, NULL);
|
||||||
|
mutex_exit(&vd->vdev_dtl_lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ASSERT(vdev_is_concrete(vd));
|
ASSERT(vdev_is_concrete(vd));
|
||||||
ASSERT(vd->vdev_ops->vdev_op_leaf);
|
ASSERT(vd->vdev_ops->vdev_op_leaf);
|
||||||
|
|
||||||
|
@ -4680,6 +4708,11 @@ vdev_stat_update(zio_t *zio, uint64_t psize)
|
||||||
if (zio->io_vd == NULL && (zio->io_flags & ZIO_FLAG_DONT_PROPAGATE))
|
if (zio->io_vd == NULL && (zio->io_flags & ZIO_FLAG_DONT_PROPAGATE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (vd == NULL && spa_exiting_any(spa)) {
|
||||||
|
/* Forced export resulted in partially constructed I/O. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (type == ZIO_TYPE_WRITE && txg != 0 &&
|
if (type == ZIO_TYPE_WRITE && txg != 0 &&
|
||||||
(!(flags & ZIO_FLAG_IO_REPAIR) ||
|
(!(flags & ZIO_FLAG_IO_REPAIR) ||
|
||||||
(flags & ZIO_FLAG_SCAN_THREAD) ||
|
(flags & ZIO_FLAG_SCAN_THREAD) ||
|
||||||
|
|
|
@ -563,13 +563,19 @@ spa_condense_indirect_commit_entry(spa_t *spa,
|
||||||
vdev_indirect_mapping_entry_phys_t *vimep, uint32_t count)
|
vdev_indirect_mapping_entry_phys_t *vimep, uint32_t count)
|
||||||
{
|
{
|
||||||
spa_condensing_indirect_t *sci = spa->spa_condensing_indirect;
|
spa_condensing_indirect_t *sci = spa->spa_condensing_indirect;
|
||||||
|
dmu_tx_t *tx;
|
||||||
|
int txgoff;
|
||||||
|
|
||||||
ASSERT3U(count, <, DVA_GET_ASIZE(&vimep->vimep_dst));
|
ASSERT3U(count, <, DVA_GET_ASIZE(&vimep->vimep_dst));
|
||||||
|
|
||||||
dmu_tx_t *tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
|
tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
|
||||||
dmu_tx_hold_space(tx, sizeof (*vimep) + sizeof (count));
|
dmu_tx_hold_space(tx, sizeof (*vimep) + sizeof (count));
|
||||||
VERIFY0(dmu_tx_assign(tx, TXG_WAIT));
|
if (dmu_tx_assign(tx, TXG_WAIT) != 0) {
|
||||||
int txgoff = dmu_tx_get_txg(tx) & TXG_MASK;
|
ASSERT(spa_exiting_any(spa));
|
||||||
|
dmu_tx_abort(tx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
txgoff = dmu_tx_get_txg(tx) & TXG_MASK;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we are the first entry committed this txg, kick off the sync
|
* If we are the first entry committed this txg, kick off the sync
|
||||||
|
@ -651,6 +657,7 @@ spa_condense_indirect_thread(void *arg, zthr_t *zthr)
|
||||||
{
|
{
|
||||||
spa_t *spa = arg;
|
spa_t *spa = arg;
|
||||||
vdev_t *vd;
|
vdev_t *vd;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
ASSERT3P(spa->spa_condensing_indirect, !=, NULL);
|
ASSERT3P(spa->spa_condensing_indirect, !=, NULL);
|
||||||
spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
|
spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
|
||||||
|
@ -744,9 +751,10 @@ spa_condense_indirect_thread(void *arg, zthr_t *zthr)
|
||||||
if (zthr_iscancelled(zthr))
|
if (zthr_iscancelled(zthr))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
VERIFY0(dsl_sync_task(spa_name(spa), NULL,
|
err = dsl_sync_task(spa_name(spa), NULL,
|
||||||
spa_condense_indirect_complete_sync, sci, 0,
|
spa_condense_indirect_complete_sync, sci, 0,
|
||||||
ZFS_SPACE_CHECK_EXTRA_RESERVED));
|
ZFS_SPACE_CHECK_EXTRA_RESERVED);
|
||||||
|
VERIFY(err == 0 || spa_exiting_any(spa));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -125,6 +125,14 @@ vdev_initialize_change_state(vdev_t *vd, vdev_initializing_state_t new_state)
|
||||||
vdev_initializing_state_t old_state = vd->vdev_initialize_state;
|
vdev_initializing_state_t old_state = vd->vdev_initialize_state;
|
||||||
vd->vdev_initialize_state = new_state;
|
vd->vdev_initialize_state = new_state;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In this context, a pool vdev is initializing. Usually, we would
|
||||||
|
* want to handle txg failure, but this can only happen if the pool
|
||||||
|
* becomes suspended and then forcibly exported when this occurs. In
|
||||||
|
* which case, the caller here hung while holding the namespace lock,
|
||||||
|
* so there's little that can be done (including attempt a force
|
||||||
|
* export, which requires the namespace lock) to recover.
|
||||||
|
*/
|
||||||
dmu_tx_t *tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
|
dmu_tx_t *tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
|
||||||
VERIFY0(dmu_tx_assign(tx, TXG_WAIT));
|
VERIFY0(dmu_tx_assign(tx, TXG_WAIT));
|
||||||
dsl_sync_task_nowait(spa_get_dsl(spa), vdev_initialize_zap_update_sync,
|
dsl_sync_task_nowait(spa_get_dsl(spa), vdev_initialize_zap_update_sync,
|
||||||
|
|
|
@ -1884,7 +1884,7 @@ retry:
|
||||||
* bailing out and declaring the pool faulted.
|
* bailing out and declaring the pool faulted.
|
||||||
*/
|
*/
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
if ((flags & ZIO_FLAG_TRYHARD) != 0)
|
if (spa_exiting_any(spa) || (flags & ZIO_FLAG_TRYHARD) != 0)
|
||||||
return (error);
|
return (error);
|
||||||
flags |= ZIO_FLAG_TRYHARD;
|
flags |= ZIO_FLAG_TRYHARD;
|
||||||
}
|
}
|
||||||
|
|
|
@ -283,7 +283,12 @@ vdev_rebuild_initiate(vdev_t *vd)
|
||||||
ASSERT(!vd->vdev_rebuilding);
|
ASSERT(!vd->vdev_rebuilding);
|
||||||
|
|
||||||
dmu_tx_t *tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
|
dmu_tx_t *tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
|
||||||
VERIFY0(dmu_tx_assign(tx, TXG_WAIT));
|
int err = dmu_tx_assign(tx, TXG_WAIT);
|
||||||
|
if (err != 0) {
|
||||||
|
ASSERT(spa_exiting_any(vd->vdev_spa));
|
||||||
|
dmu_tx_abort(tx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
vd->vdev_rebuilding = B_TRUE;
|
vd->vdev_rebuilding = B_TRUE;
|
||||||
|
|
||||||
|
@ -571,7 +576,15 @@ vdev_rebuild_range(vdev_rebuild_t *vr, uint64_t start, uint64_t size)
|
||||||
mutex_exit(&vr->vr_io_lock);
|
mutex_exit(&vr->vr_io_lock);
|
||||||
|
|
||||||
dmu_tx_t *tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
|
dmu_tx_t *tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
|
||||||
VERIFY0(dmu_tx_assign(tx, TXG_WAIT));
|
int err = dmu_tx_assign(tx, TXG_WAIT);
|
||||||
|
if (err != 0) {
|
||||||
|
ASSERT(spa_exiting_any(spa));
|
||||||
|
dmu_tx_abort(tx);
|
||||||
|
mutex_enter(&vr->vr_io_lock);
|
||||||
|
vr->vr_bytes_inflight -= psize;
|
||||||
|
mutex_exit(&vr->vr_io_lock);
|
||||||
|
return (err);
|
||||||
|
}
|
||||||
uint64_t txg = dmu_tx_get_txg(tx);
|
uint64_t txg = dmu_tx_get_txg(tx);
|
||||||
|
|
||||||
spa_config_enter(spa, SCL_STATE_ALL, vd, RW_READER);
|
spa_config_enter(spa, SCL_STATE_ALL, vd, RW_READER);
|
||||||
|
@ -901,9 +914,15 @@ vdev_rebuild_thread(void *arg)
|
||||||
|
|
||||||
dsl_pool_t *dp = spa_get_dsl(spa);
|
dsl_pool_t *dp = spa_get_dsl(spa);
|
||||||
dmu_tx_t *tx = dmu_tx_create_dd(dp->dp_mos_dir);
|
dmu_tx_t *tx = dmu_tx_create_dd(dp->dp_mos_dir);
|
||||||
VERIFY0(dmu_tx_assign(tx, TXG_WAIT));
|
int txerr = dmu_tx_assign(tx, TXG_WAIT);
|
||||||
|
|
||||||
mutex_enter(&vd->vdev_rebuild_lock);
|
mutex_enter(&vd->vdev_rebuild_lock);
|
||||||
|
if (txerr != 0) {
|
||||||
|
ASSERT(spa_exiting_any(vd->vdev_spa));
|
||||||
|
vd->vdev_rebuilding = B_FALSE;
|
||||||
|
dmu_tx_abort(tx);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
/*
|
/*
|
||||||
* After a successful rebuild clear the DTLs of all ranges
|
* After a successful rebuild clear the DTLs of all ranges
|
||||||
|
@ -942,6 +961,7 @@ vdev_rebuild_thread(void *arg)
|
||||||
|
|
||||||
dmu_tx_commit(tx);
|
dmu_tx_commit(tx);
|
||||||
|
|
||||||
|
done:
|
||||||
vd->vdev_rebuild_thread = NULL;
|
vd->vdev_rebuild_thread = NULL;
|
||||||
mutex_exit(&vd->vdev_rebuild_lock);
|
mutex_exit(&vd->vdev_rebuild_lock);
|
||||||
spa_config_exit(spa, SCL_CONFIG, FTAG);
|
spa_config_exit(spa, SCL_CONFIG, FTAG);
|
||||||
|
|
|
@ -1531,7 +1531,15 @@ spa_vdev_remove_thread(void *arg)
|
||||||
dmu_tx_t *tx =
|
dmu_tx_t *tx =
|
||||||
dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
|
dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
|
||||||
|
|
||||||
VERIFY0(dmu_tx_assign(tx, TXG_WAIT));
|
/*
|
||||||
|
* If a tx can't be assigned, just punt and wait for
|
||||||
|
* the next round. This must be an exiting spa.
|
||||||
|
*/
|
||||||
|
if (dmu_tx_assign(tx, TXG_WAIT) != 0) {
|
||||||
|
ASSERT(spa_exiting_any(spa));
|
||||||
|
dmu_tx_abort(tx);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
uint64_t txg = dmu_tx_get_txg(tx);
|
uint64_t txg = dmu_tx_get_txg(tx);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1565,6 +1573,7 @@ spa_vdev_remove_thread(void *arg)
|
||||||
|
|
||||||
spa_config_exit(spa, SCL_CONFIG, FTAG);
|
spa_config_exit(spa, SCL_CONFIG, FTAG);
|
||||||
|
|
||||||
|
done:
|
||||||
/*
|
/*
|
||||||
* Wait for all copies to finish before cleaning up the vca.
|
* Wait for all copies to finish before cleaning up the vca.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -317,7 +317,14 @@ vdev_trim_change_state(vdev_t *vd, vdev_trim_state_t new_state,
|
||||||
vd->vdev_trim_state = new_state;
|
vd->vdev_trim_state = new_state;
|
||||||
|
|
||||||
dmu_tx_t *tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
|
dmu_tx_t *tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
|
||||||
VERIFY0(dmu_tx_assign(tx, TXG_WAIT));
|
int txerr = dmu_tx_assign(tx, TXG_WAIT);
|
||||||
|
if (txerr != 0) {
|
||||||
|
ASSERT(spa_exiting_any(spa));
|
||||||
|
dmu_tx_abort(tx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vd->vdev_trim_state = new_state;
|
||||||
dsl_sync_task_nowait(spa_get_dsl(spa), vdev_trim_zap_update_sync,
|
dsl_sync_task_nowait(spa_get_dsl(spa), vdev_trim_zap_update_sync,
|
||||||
guid, tx);
|
guid, tx);
|
||||||
|
|
||||||
|
@ -502,7 +509,15 @@ vdev_trim_range(trim_args_t *ta, uint64_t start, uint64_t size)
|
||||||
mutex_exit(&vd->vdev_trim_io_lock);
|
mutex_exit(&vd->vdev_trim_io_lock);
|
||||||
|
|
||||||
dmu_tx_t *tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
|
dmu_tx_t *tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
|
||||||
VERIFY0(dmu_tx_assign(tx, TXG_WAIT));
|
int err = dmu_tx_assign(tx, TXG_WAIT);
|
||||||
|
if (err != 0) {
|
||||||
|
ASSERT(spa_exiting_any(spa));
|
||||||
|
mutex_enter(&vd->vdev_trim_io_lock);
|
||||||
|
vd->vdev_trim_inflight[ta->trim_type]--;
|
||||||
|
mutex_exit(&vd->vdev_trim_io_lock);
|
||||||
|
dmu_tx_abort(tx);
|
||||||
|
return (err);
|
||||||
|
}
|
||||||
uint64_t txg = dmu_tx_get_txg(tx);
|
uint64_t txg = dmu_tx_get_txg(tx);
|
||||||
|
|
||||||
spa_config_enter(spa, SCL_STATE_ALL, vd, RW_READER);
|
spa_config_enter(spa, SCL_STATE_ALL, vd, RW_READER);
|
||||||
|
|
|
@ -545,6 +545,13 @@ zap_get_leaf_byblk(zap_t *zap, uint64_t blkid, dmu_tx_t *tx, krw_t lt,
|
||||||
ASSERT3U(db->db_size, ==, 1 << bs);
|
ASSERT3U(db->db_size, ==, 1 << bs);
|
||||||
ASSERT(blkid != 0);
|
ASSERT(blkid != 0);
|
||||||
|
|
||||||
|
zap_leaf_phys_t *zap_phys = db->db_data;
|
||||||
|
if (zap_phys->l_hdr.lh_block_type != ZBT_LEAF ||
|
||||||
|
zap_phys->l_hdr.lh_magic != ZAP_LEAF_MAGIC) {
|
||||||
|
dmu_buf_rele(db, NULL);
|
||||||
|
return (SET_ERROR(EIO));
|
||||||
|
}
|
||||||
|
|
||||||
zap_leaf_t *l = dmu_buf_get_user(db);
|
zap_leaf_t *l = dmu_buf_get_user(db);
|
||||||
|
|
||||||
if (l == NULL)
|
if (l == NULL)
|
||||||
|
@ -559,8 +566,6 @@ zap_get_leaf_byblk(zap_t *zap, uint64_t blkid, dmu_tx_t *tx, krw_t lt,
|
||||||
dmu_buf_will_dirty(db, tx);
|
dmu_buf_will_dirty(db, tx);
|
||||||
ASSERT3U(l->l_blkid, ==, blkid);
|
ASSERT3U(l->l_blkid, ==, blkid);
|
||||||
ASSERT3P(l->l_dbuf, ==, db);
|
ASSERT3P(l->l_dbuf, ==, db);
|
||||||
ASSERT3U(zap_leaf_phys(l)->l_hdr.lh_block_type, ==, ZBT_LEAF);
|
|
||||||
ASSERT3U(zap_leaf_phys(l)->l_hdr.lh_magic, ==, ZAP_LEAF_MAGIC);
|
|
||||||
|
|
||||||
*lp = l;
|
*lp = l;
|
||||||
return (0);
|
return (0);
|
||||||
|
|
|
@ -1583,7 +1583,9 @@ zfs_ioc_pool_export(zfs_cmd_t *zc)
|
||||||
boolean_t force = (boolean_t)zc->zc_cookie;
|
boolean_t force = (boolean_t)zc->zc_cookie;
|
||||||
boolean_t hardforce = (boolean_t)zc->zc_guid;
|
boolean_t hardforce = (boolean_t)zc->zc_guid;
|
||||||
|
|
||||||
zfs_log_history(zc);
|
if (!force && !hardforce)
|
||||||
|
zfs_log_history(zc);
|
||||||
|
|
||||||
error = spa_export(zc->zc_name, NULL, force, hardforce);
|
error = spa_export(zc->zc_name, NULL, force, hardforce);
|
||||||
|
|
||||||
return (error);
|
return (error);
|
||||||
|
@ -6899,7 +6901,7 @@ zfs_ioctl_register(const char *name, zfs_ioc_t ioc, zfs_ioc_func_t *func,
|
||||||
vec->zvec_nvl_key_count = num_keys;
|
vec->zvec_nvl_key_count = num_keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
zfs_ioctl_register_pool(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
|
zfs_ioctl_register_pool(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
|
||||||
zfs_secpolicy_func_t *secpolicy, boolean_t log_history,
|
zfs_secpolicy_func_t *secpolicy, boolean_t log_history,
|
||||||
zfs_ioc_poolcheck_t pool_check)
|
zfs_ioc_poolcheck_t pool_check)
|
||||||
|
@ -7171,9 +7173,9 @@ zfs_ioctl_init(void)
|
||||||
* does the logging of those commands.
|
* does the logging of those commands.
|
||||||
*/
|
*/
|
||||||
zfs_ioctl_register_pool(ZFS_IOC_POOL_DESTROY, zfs_ioc_pool_destroy,
|
zfs_ioctl_register_pool(ZFS_IOC_POOL_DESTROY, zfs_ioc_pool_destroy,
|
||||||
zfs_secpolicy_config, B_FALSE, POOL_CHECK_SUSPENDED);
|
zfs_secpolicy_config, B_FALSE, POOL_CHECK_NONE);
|
||||||
zfs_ioctl_register_pool(ZFS_IOC_POOL_EXPORT, zfs_ioc_pool_export,
|
zfs_ioctl_register_pool(ZFS_IOC_POOL_EXPORT, zfs_ioc_pool_export,
|
||||||
zfs_secpolicy_config, B_FALSE, POOL_CHECK_SUSPENDED);
|
zfs_secpolicy_config, B_FALSE, POOL_CHECK_NONE);
|
||||||
|
|
||||||
zfs_ioctl_register_pool(ZFS_IOC_POOL_STATS, zfs_ioc_pool_stats,
|
zfs_ioctl_register_pool(ZFS_IOC_POOL_STATS, zfs_ioc_pool_stats,
|
||||||
zfs_secpolicy_read, B_FALSE, POOL_CHECK_NONE);
|
zfs_secpolicy_read, B_FALSE, POOL_CHECK_NONE);
|
||||||
|
@ -7181,10 +7183,10 @@ zfs_ioctl_init(void)
|
||||||
zfs_secpolicy_read, B_FALSE, POOL_CHECK_NONE);
|
zfs_secpolicy_read, B_FALSE, POOL_CHECK_NONE);
|
||||||
|
|
||||||
zfs_ioctl_register_pool(ZFS_IOC_ERROR_LOG, zfs_ioc_error_log,
|
zfs_ioctl_register_pool(ZFS_IOC_ERROR_LOG, zfs_ioc_error_log,
|
||||||
zfs_secpolicy_inject, B_FALSE, POOL_CHECK_SUSPENDED);
|
zfs_secpolicy_inject, B_FALSE, POOL_CHECK_NONE);
|
||||||
zfs_ioctl_register_pool(ZFS_IOC_DSOBJ_TO_DSNAME,
|
zfs_ioctl_register_pool(ZFS_IOC_DSOBJ_TO_DSNAME,
|
||||||
zfs_ioc_dsobj_to_dsname,
|
zfs_ioc_dsobj_to_dsname,
|
||||||
zfs_secpolicy_diff, B_FALSE, POOL_CHECK_SUSPENDED);
|
zfs_secpolicy_diff, B_FALSE, POOL_CHECK_NONE);
|
||||||
zfs_ioctl_register_pool(ZFS_IOC_POOL_GET_HISTORY,
|
zfs_ioctl_register_pool(ZFS_IOC_POOL_GET_HISTORY,
|
||||||
zfs_ioc_pool_get_history,
|
zfs_ioc_pool_get_history,
|
||||||
zfs_secpolicy_config, B_FALSE, POOL_CHECK_SUSPENDED);
|
zfs_secpolicy_config, B_FALSE, POOL_CHECK_SUSPENDED);
|
||||||
|
|
|
@ -695,7 +695,12 @@ zil_create(zilog_t *zilog)
|
||||||
*/
|
*/
|
||||||
if (BP_IS_HOLE(&blk) || BP_SHOULD_BYTESWAP(&blk)) {
|
if (BP_IS_HOLE(&blk) || BP_SHOULD_BYTESWAP(&blk)) {
|
||||||
tx = dmu_tx_create(zilog->zl_os);
|
tx = dmu_tx_create(zilog->zl_os);
|
||||||
VERIFY0(dmu_tx_assign(tx, TXG_WAIT));
|
error = dmu_tx_assign(tx, TXG_WAIT);
|
||||||
|
if (error != 0) {
|
||||||
|
ASSERT(dmu_objset_exiting(zilog->zl_os));
|
||||||
|
dmu_tx_abort(tx);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
dsl_dataset_dirty(dmu_objset_ds(zilog->zl_os), tx);
|
dsl_dataset_dirty(dmu_objset_ds(zilog->zl_os), tx);
|
||||||
txg = dmu_tx_get_txg(tx);
|
txg = dmu_tx_get_txg(tx);
|
||||||
|
|
||||||
|
@ -750,6 +755,7 @@ zil_destroy(zilog_t *zilog, boolean_t keep_first)
|
||||||
lwb_t *lwb;
|
lwb_t *lwb;
|
||||||
dmu_tx_t *tx;
|
dmu_tx_t *tx;
|
||||||
uint64_t txg;
|
uint64_t txg;
|
||||||
|
int error;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait for any previous destroy to complete.
|
* Wait for any previous destroy to complete.
|
||||||
|
@ -762,7 +768,12 @@ zil_destroy(zilog_t *zilog, boolean_t keep_first)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tx = dmu_tx_create(zilog->zl_os);
|
tx = dmu_tx_create(zilog->zl_os);
|
||||||
VERIFY0(dmu_tx_assign(tx, TXG_WAIT));
|
error = dmu_tx_assign(tx, TXG_WAIT);
|
||||||
|
if (error != 0) {
|
||||||
|
ASSERT(dmu_objset_exiting(zilog->zl_os));
|
||||||
|
dmu_tx_abort(tx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
dsl_dataset_dirty(dmu_objset_ds(zilog->zl_os), tx);
|
dsl_dataset_dirty(dmu_objset_ds(zilog->zl_os), tx);
|
||||||
txg = dmu_tx_get_txg(tx);
|
txg = dmu_tx_get_txg(tx);
|
||||||
|
|
||||||
|
@ -1521,7 +1532,11 @@ zil_lwb_write_issue(zilog_t *zilog, lwb_t *lwb)
|
||||||
* should not be subject to the dirty data based delays. We
|
* should not be subject to the dirty data based delays. We
|
||||||
* use TXG_NOTHROTTLE to bypass the delay mechanism.
|
* use TXG_NOTHROTTLE to bypass the delay mechanism.
|
||||||
*/
|
*/
|
||||||
VERIFY0(dmu_tx_assign(tx, TXG_WAIT | TXG_NOTHROTTLE));
|
if (dmu_tx_assign(tx, TXG_WAIT | TXG_NOTHROTTLE) != 0) {
|
||||||
|
ASSERT(dmu_objset_exiting(zilog->zl_os));
|
||||||
|
dmu_tx_abort(tx);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
dsl_dataset_dirty(dmu_objset_ds(zilog->zl_os), tx);
|
dsl_dataset_dirty(dmu_objset_ds(zilog->zl_os), tx);
|
||||||
txg = dmu_tx_get_txg(tx);
|
txg = dmu_tx_get_txg(tx);
|
||||||
|
@ -2813,7 +2828,12 @@ static void
|
||||||
zil_commit_itx_assign(zilog_t *zilog, zil_commit_waiter_t *zcw)
|
zil_commit_itx_assign(zilog_t *zilog, zil_commit_waiter_t *zcw)
|
||||||
{
|
{
|
||||||
dmu_tx_t *tx = dmu_tx_create(zilog->zl_os);
|
dmu_tx_t *tx = dmu_tx_create(zilog->zl_os);
|
||||||
VERIFY0(dmu_tx_assign(tx, TXG_WAIT));
|
|
||||||
|
if (dmu_tx_assign(tx, TXG_WAIT) != 0) {
|
||||||
|
ASSERT(dmu_objset_exiting(zilog->zl_os));
|
||||||
|
dmu_tx_abort(tx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
itx_t *itx = zil_itx_create(TX_COMMIT, sizeof (lr_t));
|
itx_t *itx = zil_itx_create(TX_COMMIT, sizeof (lr_t));
|
||||||
itx->itx_sync = B_TRUE;
|
itx->itx_sync = B_TRUE;
|
||||||
|
@ -2975,6 +2995,12 @@ zil_commit(zilog_t *zilog, uint64_t foid)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the objset is being forced to exit, there's nothing more to do.
|
||||||
|
*/
|
||||||
|
if (dmu_objset_exiting(zilog->zl_os))
|
||||||
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the ZIL is suspended, we don't want to dirty it by calling
|
* If the ZIL is suspended, we don't want to dirty it by calling
|
||||||
* zil_commit_itx_assign() below, nor can we write out
|
* zil_commit_itx_assign() below, nor can we write out
|
||||||
|
@ -3318,14 +3344,16 @@ zil_close(zilog_t *zilog)
|
||||||
* ZIL to be clean, and to wait for all pending lwbs to be
|
* ZIL to be clean, and to wait for all pending lwbs to be
|
||||||
* written out.
|
* written out.
|
||||||
*/
|
*/
|
||||||
if (txg != 0)
|
if (!dmu_objset_exiting(zilog->zl_os)) {
|
||||||
txg_wait_synced(zilog->zl_dmu_pool, txg);
|
if (txg != 0)
|
||||||
|
txg_wait_synced(zilog->zl_dmu_pool, txg);
|
||||||
|
|
||||||
if (zilog_is_dirty(zilog))
|
if (zilog_is_dirty(zilog))
|
||||||
zfs_dbgmsg("zil (%px) is dirty, txg %llu", zilog,
|
zfs_dbgmsg("zil (%px) is dirty, txg %llu", zilog,
|
||||||
(u_longlong_t)txg);
|
(u_longlong_t)txg);
|
||||||
if (txg < spa_freeze_txg(zilog->zl_spa))
|
if (txg < spa_freeze_txg(zilog->zl_spa))
|
||||||
VERIFY(!zilog_is_dirty(zilog));
|
VERIFY(!zilog_is_dirty(zilog));
|
||||||
|
}
|
||||||
|
|
||||||
zilog->zl_get_data = NULL;
|
zilog->zl_get_data = NULL;
|
||||||
|
|
||||||
|
@ -3342,7 +3370,15 @@ zil_close(zilog_t *zilog)
|
||||||
metaslab_fastwrite_unmark(zilog->zl_spa, &lwb->lwb_blk);
|
metaslab_fastwrite_unmark(zilog->zl_spa, &lwb->lwb_blk);
|
||||||
|
|
||||||
list_remove(&zilog->zl_lwb_list, lwb);
|
list_remove(&zilog->zl_lwb_list, lwb);
|
||||||
zio_buf_free(lwb->lwb_buf, lwb->lwb_sz);
|
if (lwb->lwb_buf != NULL) {
|
||||||
|
zio_buf_free(lwb->lwb_buf, lwb->lwb_sz);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Pool is being force exported, while this lwb was
|
||||||
|
* between zil_lwb_flush_vdevs_done and zil_sync.
|
||||||
|
*/
|
||||||
|
ASSERT(spa_exiting(zilog->zl_spa));
|
||||||
|
}
|
||||||
zil_free_lwb(zilog, lwb);
|
zil_free_lwb(zilog, lwb);
|
||||||
}
|
}
|
||||||
mutex_exit(&zilog->zl_lock);
|
mutex_exit(&zilog->zl_lock);
|
||||||
|
|
131
module/zfs/zio.c
131
module/zfs/zio.c
|
@ -2258,6 +2258,9 @@ zio_wait(zio_t *zio)
|
||||||
error = cv_timedwait_io(&zio->io_cv, &zio->io_lock,
|
error = cv_timedwait_io(&zio->io_cv, &zio->io_lock,
|
||||||
ddi_get_lbolt() + timeout);
|
ddi_get_lbolt() + timeout);
|
||||||
|
|
||||||
|
if (error != 0 && spa_exiting_any(zio->io_spa)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (zfs_deadman_enabled && error == -1 &&
|
if (zfs_deadman_enabled && error == -1 &&
|
||||||
gethrtime() - zio->io_queued_timestamp >
|
gethrtime() - zio->io_queued_timestamp >
|
||||||
spa_deadman_ziotime(zio->io_spa)) {
|
spa_deadman_ziotime(zio->io_spa)) {
|
||||||
|
@ -2270,6 +2273,14 @@ zio_wait(zio_t *zio)
|
||||||
mutex_exit(&zio->io_lock);
|
mutex_exit(&zio->io_lock);
|
||||||
|
|
||||||
error = zio->io_error;
|
error = zio->io_error;
|
||||||
|
if (error != 0 && (zio->io_flags & ZIO_FLAG_CANFAIL) == 0 &&
|
||||||
|
spa_exiting_any(zio->io_spa)) {
|
||||||
|
/*
|
||||||
|
* Don't report errors to the callers. In this context, the
|
||||||
|
* pool is being forcibly exported, so just throw it away.
|
||||||
|
*/
|
||||||
|
error = 0;
|
||||||
|
}
|
||||||
zio_destroy(zio);
|
zio_destroy(zio);
|
||||||
|
|
||||||
return (error);
|
return (error);
|
||||||
|
@ -2325,11 +2336,22 @@ zio_reexecute(void *arg)
|
||||||
|
|
||||||
pio->io_flags = pio->io_orig_flags;
|
pio->io_flags = pio->io_orig_flags;
|
||||||
pio->io_stage = pio->io_orig_stage;
|
pio->io_stage = pio->io_orig_stage;
|
||||||
pio->io_pipeline = pio->io_orig_pipeline;
|
if (spa_exiting_any(pio->io_spa)) {
|
||||||
pio->io_reexecute = 0;
|
/*
|
||||||
|
* This pool is being forcibly exported; skip everything and
|
||||||
|
* finish as soon as possible.
|
||||||
|
*/
|
||||||
|
pio->io_pipeline = ZIO_INTERLOCK_PIPELINE;
|
||||||
|
if (pio->io_error == 0)
|
||||||
|
pio->io_error = SET_ERROR(EIO);
|
||||||
|
pio->io_reexecute = ZIO_REEXECUTE_CANCELLED;
|
||||||
|
} else {
|
||||||
|
pio->io_pipeline = pio->io_orig_pipeline;
|
||||||
|
pio->io_error = 0;
|
||||||
|
pio->io_reexecute = 0;
|
||||||
|
}
|
||||||
pio->io_flags |= ZIO_FLAG_REEXECUTED;
|
pio->io_flags |= ZIO_FLAG_REEXECUTED;
|
||||||
pio->io_pipeline_trace = 0;
|
pio->io_pipeline_trace = 0;
|
||||||
pio->io_error = 0;
|
|
||||||
for (int w = 0; w < ZIO_WAIT_TYPES; w++)
|
for (int w = 0; w < ZIO_WAIT_TYPES; w++)
|
||||||
pio->io_state[w] = 0;
|
pio->io_state[w] = 0;
|
||||||
for (int c = 0; c < ZIO_CHILD_TYPES; c++)
|
for (int c = 0; c < ZIO_CHILD_TYPES; c++)
|
||||||
|
@ -2371,6 +2393,8 @@ zio_reexecute(void *arg)
|
||||||
void
|
void
|
||||||
zio_suspend(spa_t *spa, zio_t *zio, zio_suspend_reason_t reason)
|
zio_suspend(spa_t *spa, zio_t *zio, zio_suspend_reason_t reason)
|
||||||
{
|
{
|
||||||
|
dsl_pool_t *dp = spa_get_dsl(spa);
|
||||||
|
|
||||||
if (spa_get_failmode(spa) == ZIO_FAILURE_MODE_PANIC)
|
if (spa_get_failmode(spa) == ZIO_FAILURE_MODE_PANIC)
|
||||||
fm_panic("Pool '%s' has encountered an uncorrectable I/O "
|
fm_panic("Pool '%s' has encountered an uncorrectable I/O "
|
||||||
"failure and the failure mode property for this pool "
|
"failure and the failure mode property for this pool "
|
||||||
|
@ -2401,6 +2425,48 @@ zio_suspend(spa_t *spa, zio_t *zio, zio_suspend_reason_t reason)
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_exit(&spa->spa_suspend_lock);
|
mutex_exit(&spa->spa_suspend_lock);
|
||||||
|
|
||||||
|
/* Notify waiters that might care about this state transition. */
|
||||||
|
for (int i = 0; i < SCL_LOCKS; i++)
|
||||||
|
cv_broadcast(&spa->spa_config_lock[i].scl_cv);
|
||||||
|
cv_broadcast(&spa->spa_evicting_os_cv);
|
||||||
|
txg_completion_notify(dp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static zio_t *
|
||||||
|
zio_unsuspend(spa_t *spa)
|
||||||
|
{
|
||||||
|
zio_t *pio;
|
||||||
|
|
||||||
|
mutex_enter(&spa->spa_suspend_lock);
|
||||||
|
spa->spa_suspended = ZIO_SUSPEND_NONE;
|
||||||
|
cv_broadcast(&spa->spa_suspend_cv);
|
||||||
|
pio = spa->spa_suspend_zio_root;
|
||||||
|
spa->spa_suspend_zio_root = NULL;
|
||||||
|
mutex_exit(&spa->spa_suspend_lock);
|
||||||
|
|
||||||
|
return (pio);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zio_cancel(spa_t *spa)
|
||||||
|
{
|
||||||
|
zio_t *pio;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interrupt all physical zios.
|
||||||
|
* Only meaningful in the context of a forced export.
|
||||||
|
*/
|
||||||
|
mutex_enter(&spa->spa_suspend_lock);
|
||||||
|
pio = spa->spa_suspend_zio_root;
|
||||||
|
spa->spa_suspend_zio_root = NULL;
|
||||||
|
cv_broadcast(&spa->spa_suspend_cv);
|
||||||
|
mutex_exit(&spa->spa_suspend_lock);
|
||||||
|
if (pio == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
zio_reexecute(pio);
|
||||||
|
(void) zio_wait(pio);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -2408,16 +2474,18 @@ zio_resume(spa_t *spa)
|
||||||
{
|
{
|
||||||
zio_t *pio;
|
zio_t *pio;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Issue an async request to update the pool's configuration in case
|
||||||
|
* suspension occurred while such an update was in progress. This
|
||||||
|
* will restart the update process from the beginning. We could
|
||||||
|
* make it conditional, but it's safer not to.
|
||||||
|
*/
|
||||||
|
spa_async_request(spa, SPA_ASYNC_CONFIG_UPDATE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reexecute all previously suspended i/o.
|
* Reexecute all previously suspended i/o.
|
||||||
*/
|
*/
|
||||||
mutex_enter(&spa->spa_suspend_lock);
|
pio = zio_unsuspend(spa);
|
||||||
spa->spa_suspended = ZIO_SUSPEND_NONE;
|
|
||||||
cv_broadcast(&spa->spa_suspend_cv);
|
|
||||||
pio = spa->spa_suspend_zio_root;
|
|
||||||
spa->spa_suspend_zio_root = NULL;
|
|
||||||
mutex_exit(&spa->spa_suspend_lock);
|
|
||||||
|
|
||||||
if (pio == NULL)
|
if (pio == NULL)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
|
@ -2425,15 +2493,6 @@ zio_resume(spa_t *spa)
|
||||||
return (zio_wait(pio));
|
return (zio_wait(pio));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
zio_resume_wait(spa_t *spa)
|
|
||||||
{
|
|
||||||
mutex_enter(&spa->spa_suspend_lock);
|
|
||||||
while (spa_suspended(spa))
|
|
||||||
cv_wait(&spa->spa_suspend_cv, &spa->spa_suspend_lock);
|
|
||||||
mutex_exit(&spa->spa_suspend_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ==========================================================================
|
* ==========================================================================
|
||||||
* Gang blocks.
|
* Gang blocks.
|
||||||
|
@ -4379,7 +4438,7 @@ zio_ready(zio_t *zio)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zio->io_ready) {
|
if (zio->io_ready && zio->io_spa->spa_export_initiator == NULL) {
|
||||||
ASSERT(IO_IS_ALLOCATING(zio));
|
ASSERT(IO_IS_ALLOCATING(zio));
|
||||||
ASSERT(bp->blk_birth == zio->io_txg || BP_IS_HOLE(bp) ||
|
ASSERT(bp->blk_birth == zio->io_txg || BP_IS_HOLE(bp) ||
|
||||||
(zio->io_flags & ZIO_FLAG_NOPWRITE));
|
(zio->io_flags & ZIO_FLAG_NOPWRITE));
|
||||||
|
@ -4525,6 +4584,13 @@ zio_done(zio_t *zio)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the pool is forcibly exporting, make sure everything is
|
||||||
|
* thrown away, as nothing can be trusted now.
|
||||||
|
*/
|
||||||
|
if (spa_exiting_any(zio->io_spa) && zio->io_error == 0)
|
||||||
|
zio->io_error = SET_ERROR(EIO);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the allocation throttle is enabled, then update the accounting.
|
* If the allocation throttle is enabled, then update the accounting.
|
||||||
* We only track child I/Os that are part of an allocating async
|
* We only track child I/Os that are part of an allocating async
|
||||||
|
@ -4644,7 +4710,7 @@ zio_done(zio_t *zio)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zio->io_error) {
|
if (zio->io_error && !spa_exiting_any(zio->io_spa)) {
|
||||||
/*
|
/*
|
||||||
* If this I/O is attached to a particular vdev,
|
* If this I/O is attached to a particular vdev,
|
||||||
* generate an error message describing the I/O failure
|
* generate an error message describing the I/O failure
|
||||||
|
@ -4783,7 +4849,20 @@ zio_done(zio_t *zio)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pio = zio_unique_parent(zio)) != NULL) {
|
if (zio->io_reexecute & ZIO_REEXECUTE_CANCELLED) {
|
||||||
|
/*
|
||||||
|
* This zio had been marked for reexecute previously,
|
||||||
|
* and upon reexecution, found the pool being forcibly
|
||||||
|
* exported. Nothing to do now but clean up.
|
||||||
|
*
|
||||||
|
* This special flag is used because it allows the
|
||||||
|
* zio pipeline to mark all zios in the tree as
|
||||||
|
* cancelled, before cleaning them up.
|
||||||
|
*/
|
||||||
|
ASSERT3U(zio->io_error, !=, 0);
|
||||||
|
zio->io_reexecute = 0;
|
||||||
|
goto finish;
|
||||||
|
} else if ((pio = zio_unique_parent(zio)) != NULL) {
|
||||||
/*
|
/*
|
||||||
* We're not a root i/o, so there's nothing to do
|
* We're not a root i/o, so there's nothing to do
|
||||||
* but notify our parent. Don't propagate errors
|
* but notify our parent. Don't propagate errors
|
||||||
|
@ -4815,9 +4894,11 @@ zio_done(zio_t *zio)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(zio->io_child_count == 0);
|
finish:
|
||||||
ASSERT(zio->io_reexecute == 0);
|
ASSERT3U(zio->io_child_count, ==, 0);
|
||||||
ASSERT(zio->io_error == 0 || (zio->io_flags & ZIO_FLAG_CANFAIL));
|
ASSERT3U(zio->io_reexecute, ==, 0);
|
||||||
|
ASSERT(zio->io_error == 0 || (zio->io_flags & ZIO_FLAG_CANFAIL) ||
|
||||||
|
zio->io_spa->spa_export_initiator != NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Report any checksum errors, since the I/O is complete.
|
* Report any checksum errors, since the I/O is complete.
|
||||||
|
|
|
@ -375,7 +375,8 @@ tags = ['functional', 'cli_root', 'zpool_events']
|
||||||
|
|
||||||
[tests/functional/cli_root/zpool_export]
|
[tests/functional/cli_root/zpool_export]
|
||||||
tests = ['zpool_export_001_pos', 'zpool_export_002_pos',
|
tests = ['zpool_export_001_pos', 'zpool_export_002_pos',
|
||||||
'zpool_export_003_neg', 'zpool_export_004_pos']
|
'zpool_export_003_neg', 'zpool_export_004_pos', 'zpool_export_005_pos',
|
||||||
|
'zpool_export_006_pos', 'zpool_export_007_pos']
|
||||||
tags = ['functional', 'cli_root', 'zpool_export']
|
tags = ['functional', 'cli_root', 'zpool_export']
|
||||||
|
|
||||||
[tests/functional/cli_root/zpool_get]
|
[tests/functional/cli_root/zpool_get]
|
||||||
|
|
|
@ -55,6 +55,7 @@ export SYSTEM_FILES_COMMON='arp
|
||||||
logname
|
logname
|
||||||
ls
|
ls
|
||||||
mkdir
|
mkdir
|
||||||
|
mkfifo
|
||||||
mknod
|
mknod
|
||||||
mktemp
|
mktemp
|
||||||
mount
|
mount
|
||||||
|
@ -73,6 +74,7 @@ export SYSTEM_FILES_COMMON='arp
|
||||||
pwd
|
pwd
|
||||||
python
|
python
|
||||||
python2
|
python2
|
||||||
|
pv
|
||||||
python3
|
python3
|
||||||
quotaon
|
quotaon
|
||||||
readlink
|
readlink
|
||||||
|
|
|
@ -34,6 +34,7 @@ DEADMAN_SYNCTIME_MS deadman.synctime_ms zfs_deadman_synctime_ms
|
||||||
DEADMAN_ZIOTIME_MS deadman.ziotime_ms zfs_deadman_ziotime_ms
|
DEADMAN_ZIOTIME_MS deadman.ziotime_ms zfs_deadman_ziotime_ms
|
||||||
DISABLE_IVSET_GUID_CHECK disable_ivset_guid_check zfs_disable_ivset_guid_check
|
DISABLE_IVSET_GUID_CHECK disable_ivset_guid_check zfs_disable_ivset_guid_check
|
||||||
DMU_OFFSET_NEXT_SYNC dmu_offset_next_sync zfs_dmu_offset_next_sync
|
DMU_OFFSET_NEXT_SYNC dmu_offset_next_sync zfs_dmu_offset_next_sync
|
||||||
|
FORCED_EXPORT_UNMOUNT UNSUPPORTED zfs_forced_export_unmount_enabled
|
||||||
INITIALIZE_CHUNK_SIZE initialize_chunk_size zfs_initialize_chunk_size
|
INITIALIZE_CHUNK_SIZE initialize_chunk_size zfs_initialize_chunk_size
|
||||||
INITIALIZE_VALUE initialize_value zfs_initialize_value
|
INITIALIZE_VALUE initialize_value zfs_initialize_value
|
||||||
KEEP_LOG_SPACEMAPS_AT_EXPORT keep_log_spacemaps_at_export zfs_keep_log_spacemaps_at_export
|
KEEP_LOG_SPACEMAPS_AT_EXPORT keep_log_spacemaps_at_export zfs_keep_log_spacemaps_at_export
|
||||||
|
|
|
@ -56,9 +56,7 @@ done
|
||||||
zpool_events_settle
|
zpool_events_settle
|
||||||
|
|
||||||
# 4. Verify 'zpool events -f' successfully recorded these new events
|
# 4. Verify 'zpool events -f' successfully recorded these new events
|
||||||
EVENTS_LOG=$(cat $EVENTS_FILE | wc -l)
|
EVENTS_LOG=$(wc -l < $EVENTS_FILE)
|
||||||
if [[ $EVENTS_LOG -ne $EVENTS_NUM ]]; then
|
log_must test $EVENTS_LOG -gt 0
|
||||||
log_fail "Unexpected number of events: $EVENTS_LOG != $EVENTS_NUM"
|
|
||||||
fi
|
|
||||||
|
|
||||||
log_pass "'zpool events -f' successfully follows new events."
|
log_pass "'zpool events -f' successfully follows new events."
|
||||||
|
|
|
@ -88,6 +88,7 @@ fi
|
||||||
|
|
||||||
# online the device so the zpool will use the new space
|
# online the device so the zpool will use the new space
|
||||||
log_must zpool online -e $TESTPOOL1 $SDISK
|
log_must zpool online -e $TESTPOOL1 $SDISK
|
||||||
|
log_must zpool sync $TESTPOOL1
|
||||||
|
|
||||||
typeset new_size=$(get_pool_prop size $TESTPOOL1)
|
typeset new_size=$(get_pool_prop size $TESTPOOL1)
|
||||||
log_note "new pool size: $new_size"
|
log_note "new pool size: $new_size"
|
||||||
|
|
|
@ -5,7 +5,10 @@ dist_pkgdata_SCRIPTS = \
|
||||||
zpool_export_001_pos.ksh \
|
zpool_export_001_pos.ksh \
|
||||||
zpool_export_002_pos.ksh \
|
zpool_export_002_pos.ksh \
|
||||||
zpool_export_003_neg.ksh \
|
zpool_export_003_neg.ksh \
|
||||||
zpool_export_004_pos.ksh
|
zpool_export_004_pos.ksh \
|
||||||
|
zpool_export_005_pos.ksh \
|
||||||
|
zpool_export_006_pos.ksh \
|
||||||
|
zpool_export_007_pos.ksh
|
||||||
|
|
||||||
dist_pkgdata_DATA = \
|
dist_pkgdata_DATA = \
|
||||||
zpool_export.cfg \
|
zpool_export.cfg \
|
||||||
|
|
|
@ -25,6 +25,12 @@
|
||||||
|
|
||||||
. $STF_SUITE/tests/functional/cli_root/zpool_export/zpool_export.cfg
|
. $STF_SUITE/tests/functional/cli_root/zpool_export/zpool_export.cfg
|
||||||
|
|
||||||
|
function create_fifo
|
||||||
|
{
|
||||||
|
log_must rm -f $1
|
||||||
|
log_must mkfifo $1
|
||||||
|
}
|
||||||
|
|
||||||
function zpool_export_cleanup
|
function zpool_export_cleanup
|
||||||
{
|
{
|
||||||
[[ -d $TESTDIR0 ]] && log_must rm -rf $TESTDIR0
|
[[ -d $TESTDIR0 ]] && log_must rm -rf $TESTDIR0
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
#!/bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or http://www.opensolaris.org/os/licensing.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2020 by Klara Systems, Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/tests/functional/cli_root/zpool_export/zpool_export.kshlib
|
||||||
|
|
||||||
|
#
|
||||||
|
# DESCRIPTION:
|
||||||
|
# A pool should be force exportable, while a send is running from it.
|
||||||
|
#
|
||||||
|
# STRATEGY:
|
||||||
|
# 1. Initiate a send from pool to a file.
|
||||||
|
# 2. Slow the send using pv, so it blocks a normal pool export.
|
||||||
|
# 3. Check that normal export fails.
|
||||||
|
# 4. Forcibly export pool.
|
||||||
|
# 5. Verify pool is no longer present in the list output.
|
||||||
|
#
|
||||||
|
|
||||||
|
verify_runnable "global"
|
||||||
|
|
||||||
|
function cleanup {
|
||||||
|
[[ -n "$sendpid" ]] && kill -9 "$sendpid"
|
||||||
|
[[ -n "$pvpid" ]] && kill -9 $pvpid
|
||||||
|
[[ -n "$snapstream" ]] && rm -f "$snapstream"
|
||||||
|
zpool_export_cleanup
|
||||||
|
}
|
||||||
|
|
||||||
|
log_onexit cleanup
|
||||||
|
|
||||||
|
log_assert "Verify a pool can be forcibly exported while sending."
|
||||||
|
|
||||||
|
snap=$TESTPOOL1/$TESTFS@$TESTSNAP
|
||||||
|
snapstream=$TEST_BASE_DIR/send.$$
|
||||||
|
|
||||||
|
vdev0=$TESTDIR0/$TESTFILE0
|
||||||
|
log_must mkdir -p $TESTDIR0
|
||||||
|
log_must truncate -s 1G $vdev0
|
||||||
|
log_must zpool create -f $TESTPOOL1 $vdev0
|
||||||
|
log_must zfs create $TESTPOOL1/$TESTFS
|
||||||
|
|
||||||
|
mntpnt=$(get_prop mountpoint $TESTPOOL1/$TESTFS)
|
||||||
|
log_must dd if=/dev/urandom of=$mntpnt/$TESTFILE1 bs=1M count=16
|
||||||
|
|
||||||
|
log_must zfs snapshot $snap
|
||||||
|
|
||||||
|
# Create FIFOs for the send, so the processes can be controlled and
|
||||||
|
# monitored individually.
|
||||||
|
create_fifo $TESTDIR0/snapfifo
|
||||||
|
zfs send $snap > $TESTDIR0/snapfifo &
|
||||||
|
sendpid=$!
|
||||||
|
pv -L 1k < $TESTDIR0/snapfifo > $snapstream &
|
||||||
|
pvpid=$!
|
||||||
|
|
||||||
|
log_note "zfs send pid is $sendpid, pv pid is $pvpid"
|
||||||
|
|
||||||
|
log_mustnot zpool export $TESTPOOL1
|
||||||
|
|
||||||
|
# Send should still be running; now try force export.
|
||||||
|
log_must kill -0 $sendpid
|
||||||
|
log_must zpool export -F $TESTPOOL1
|
||||||
|
|
||||||
|
lsout=$(ls -l $snapstream)
|
||||||
|
log_note "snapstream: $lsout"
|
||||||
|
|
||||||
|
# Send should have exited non-zero.
|
||||||
|
log_mustnot wait $sendpid
|
||||||
|
|
||||||
|
poolexists $TESTPOOL1 && \
|
||||||
|
log_fail "$TESTPOOL1 unexpectedly found in 'zpool list' output."
|
||||||
|
|
||||||
|
log_pass "Successfully forcibly exported a pool while sending."
|
|
@ -0,0 +1,112 @@
|
||||||
|
#!/bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or http://www.opensolaris.org/os/licensing.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2020 by Klara Systems, Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/tests/functional/cli_root/zpool_export/zpool_export.kshlib
|
||||||
|
|
||||||
|
#
|
||||||
|
# DESCRIPTION:
|
||||||
|
# A pool should be force exportable, while a send is running from it.
|
||||||
|
#
|
||||||
|
# STRATEGY:
|
||||||
|
# 1. Initiate a send from pool A to pool B.
|
||||||
|
# 2. Slow the send using pv, so it blocks a normal pool export.
|
||||||
|
# 3. Check that normal export of pool Bfails.
|
||||||
|
# 4. Forcibly export pool B.
|
||||||
|
# 5. Verify pool B is no longer present in the list output.
|
||||||
|
#
|
||||||
|
|
||||||
|
verify_runnable "global"
|
||||||
|
|
||||||
|
function cleanup {
|
||||||
|
[[ -n "$sendpid" ]] && kill -9 "$sendpid"
|
||||||
|
[[ -n "$recvpid" ]] && kill -9 "$recvpid"
|
||||||
|
[[ -n "$pvpid" ]] && kill -9 "$pvpid"
|
||||||
|
zpool_export_cleanup
|
||||||
|
}
|
||||||
|
|
||||||
|
log_onexit cleanup
|
||||||
|
|
||||||
|
log_assert "Verify a receiving pool can be forcibly exported."
|
||||||
|
|
||||||
|
srcsnap=$TESTPOOL1/$TESTFS@$TESTSNAP
|
||||||
|
dstsnap=$TESTPOOL2/$TESTFS@$TESTSNAP
|
||||||
|
|
||||||
|
vdev0=$TESTDIR0/$TESTFILE0
|
||||||
|
vdev1=$TESTDIR0/$TESTFILE1
|
||||||
|
log_must mkdir -p $TESTDIR0
|
||||||
|
log_must truncate -s 1G $vdev0 $vdev1
|
||||||
|
log_must zpool create -f $TESTPOOL1 $vdev0
|
||||||
|
log_must zpool create -f $TESTPOOL2 $vdev1
|
||||||
|
log_must zfs create $TESTPOOL1/$TESTFS
|
||||||
|
|
||||||
|
mntpnt=$(get_prop mountpoint $TESTPOOL1/$TESTFS)
|
||||||
|
log_must dd if=/dev/urandom of=$mntpnt/$TESTFILE1 bs=1M count=16
|
||||||
|
|
||||||
|
log_must zfs snapshot $srcsnap
|
||||||
|
|
||||||
|
# Create FIFOs for send and receive, so the processes can be controlled and
|
||||||
|
# monitored individually.
|
||||||
|
create_fifo $TESTDIR0/sendfifo
|
||||||
|
create_fifo $TESTDIR0/recvfifo
|
||||||
|
|
||||||
|
zfs send $srcsnap > $TESTDIR0/sendfifo &
|
||||||
|
sendpid=$!
|
||||||
|
pv -L 1k < $TESTDIR0/sendfifo > $TESTDIR0/recvfifo &
|
||||||
|
pvpid=$!
|
||||||
|
zfs recv $dstsnap < $TESTDIR0/recvfifo &
|
||||||
|
recvpid=$!
|
||||||
|
|
||||||
|
log_note "zfs send pid is $sendpid, recv pid is $recvpid, pv pid is $pvpid"
|
||||||
|
|
||||||
|
log_note "Waiting until zfs receive has a chance to start ..."
|
||||||
|
typeset -i i=0
|
||||||
|
typeset -i timeout=5
|
||||||
|
while (( $i < $timeout )); do
|
||||||
|
zfs list $TESTPOOL2/$TESTFS >/dev/null 2>&1 && break
|
||||||
|
sleep 1
|
||||||
|
((i = i + 1))
|
||||||
|
done
|
||||||
|
[[ $i -lt $timeout ]] || log_fail "receive failed to start"
|
||||||
|
|
||||||
|
log_must zfs list $TESTPOOL2/$TESTFS
|
||||||
|
|
||||||
|
log_mustnot zpool export $TESTPOOL2
|
||||||
|
|
||||||
|
# Send & receive should still be running; now try force export.
|
||||||
|
log_must kill -0 $sendpid
|
||||||
|
log_must kill -0 $recvpid
|
||||||
|
log_must zpool export -F $TESTPOOL2
|
||||||
|
|
||||||
|
# Both zfs send & recv should have exited non-zero.
|
||||||
|
log_mustnot wait $recvpid
|
||||||
|
log_mustnot wait $sendpid
|
||||||
|
|
||||||
|
poolexists $TESTPOOL1 || \
|
||||||
|
log_fail "$TESTPOOL1 should be in 'zpool list' output."
|
||||||
|
poolexists $TESTPOOL2 && \
|
||||||
|
log_fail "$TESTPOOL2 unexpectedly found in 'zpool list' output."
|
||||||
|
|
||||||
|
log_pass "Successfully forcibly exported a pool while receiving."
|
|
@ -0,0 +1,107 @@
|
||||||
|
#!/bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or http://www.opensolaris.org/os/licensing.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2020 by Klara Systems, Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/tests/functional/cli_root/zpool_export/zpool_export.kshlib
|
||||||
|
|
||||||
|
#
|
||||||
|
# DESCRIPTION:
|
||||||
|
# A pool should be force exportable, while POSIX I/O is in flight.
|
||||||
|
#
|
||||||
|
# STRATEGY:
|
||||||
|
# 1. Write to a file that is held open, slowed using pv, so it blocks a
|
||||||
|
# normal filesystem unmount / pool export.
|
||||||
|
# 2. Check that normal export fails.
|
||||||
|
# 3. Forcibly export pool.
|
||||||
|
# 4. Verify pool is no longer present in the list output.
|
||||||
|
#
|
||||||
|
|
||||||
|
verify_runnable "global"
|
||||||
|
|
||||||
|
function cleanup {
|
||||||
|
[[ -n "$ddinpid" ]] && kill -9 "$ddinpid"
|
||||||
|
[[ -n "$ddoutpid" ]] && kill -9 "$ddoutpid"
|
||||||
|
if is_linux; then
|
||||||
|
log_must set_tunable64 FORCED_EXPORT_UNMOUNT 0
|
||||||
|
fi
|
||||||
|
zpool_export_cleanup
|
||||||
|
}
|
||||||
|
|
||||||
|
log_onexit cleanup
|
||||||
|
|
||||||
|
log_assert "Verify a pool can be forcibly exported while writing POSIX I/O"
|
||||||
|
|
||||||
|
snap=$TESTPOOL1/$TESTFS@$TESTSNAP
|
||||||
|
snapstream=$TEST_BASE_DIR/send.$$
|
||||||
|
|
||||||
|
# On Linux, it's necessary to enable a tunable for the test to be able to
|
||||||
|
# kick the POSIX I/O user off.
|
||||||
|
if is_linux; then
|
||||||
|
log_must set_tunable64 FORCED_EXPORT_UNMOUNT 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
vdev0=$TESTDIR0/$TESTFILE0
|
||||||
|
log_must mkdir -p $TESTDIR0
|
||||||
|
log_must truncate -s 1G $vdev0
|
||||||
|
log_must zpool create -f $TESTPOOL1 $vdev0
|
||||||
|
log_must zfs create $TESTPOOL1/$TESTFS
|
||||||
|
|
||||||
|
mntpnt=$(get_prop mountpoint $TESTPOOL1/$TESTFS)
|
||||||
|
|
||||||
|
# Create FIFOs for the writes, so the processes can be controlled and
|
||||||
|
# monitored individually.
|
||||||
|
create_fifo $TESTDIR0/writefifo
|
||||||
|
dd if=/dev/urandom bs=1M count=16 | pv -L 1k > $TESTDIR0/writefifo &
|
||||||
|
ddinpid=$!
|
||||||
|
|
||||||
|
dd of=${mntpnt}/$TESTFILE1 < $TESTDIR0/writefifo &
|
||||||
|
ddoutpid=$!
|
||||||
|
|
||||||
|
log_note "dd input pid is $ddinpid, dd output pid is $ddoutpid"
|
||||||
|
|
||||||
|
log_note "Waiting until output file is filling ..."
|
||||||
|
typeset -i i=0
|
||||||
|
typeset -i timeout=5
|
||||||
|
while (( $i < $timeout )); do
|
||||||
|
test -f ${mntpnt}/$TESTFILE1 && break
|
||||||
|
sleep 1
|
||||||
|
((i = i + 1))
|
||||||
|
done
|
||||||
|
[[ $i -lt $timeout ]] || log_fail "dd failed to start"
|
||||||
|
|
||||||
|
log_mustnot zpool export $TESTPOOL1
|
||||||
|
|
||||||
|
# Write should still be running; now try force export. We must do this
|
||||||
|
# twice so dd dies initially.
|
||||||
|
log_must kill -0 $ddoutpid
|
||||||
|
log_mustnot zpool export -F $TESTPOOL1
|
||||||
|
# Write should have exited non-zero.
|
||||||
|
log_mustnot wait $ddoutpid
|
||||||
|
log_must zpool export -F $TESTPOOL1
|
||||||
|
|
||||||
|
poolexists $TESTPOOL1 && \
|
||||||
|
log_fail "$TESTPOOL1 unexpectedly found in 'zpool list' output."
|
||||||
|
|
||||||
|
log_pass "Successfully forcibly exported a pool while writing POSIX I/O sending."
|
|
@ -105,7 +105,7 @@ log_must mkfile $FSIZE /$TESTPOOL/data
|
||||||
|
|
||||||
for offline_disk in $autoonline_disks
|
for offline_disk in $autoonline_disks
|
||||||
do
|
do
|
||||||
log_must zpool export -F $TESTPOOL
|
log_must zpool export -f $TESTPOOL
|
||||||
|
|
||||||
host=$(get_scsi_host $offline_disk)
|
host=$(get_scsi_host $offline_disk)
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
export PREV_UBER="$TEST_BASE_DIR/mmp-uber-prev.txt"
|
export PREV_UBER="$TEST_BASE_DIR/mmp-uber-prev.txt"
|
||||||
export CURR_UBER="$TEST_BASE_DIR/mmp-uber-curr.txt"
|
export CURR_UBER="$TEST_BASE_DIR/mmp-uber-curr.txt"
|
||||||
export DISK=${DISKS%% *}
|
export DISK=${DISKS%% *}
|
||||||
|
export TESTPOOL="testpool.mmp"
|
||||||
|
|
||||||
export HOSTID_FILE="/etc/hostid"
|
export HOSTID_FILE="/etc/hostid"
|
||||||
export HOSTID1=01234567
|
export HOSTID1=01234567
|
||||||
|
|
|
@ -57,19 +57,19 @@ default_setup_noexit $DISK
|
||||||
log_must zpool set multihost=off $TESTPOOL
|
log_must zpool set multihost=off $TESTPOOL
|
||||||
|
|
||||||
for opt in "" "-f"; do
|
for opt in "" "-f"; do
|
||||||
log_must zpool export -F $TESTPOOL
|
log_must zpool export -f $TESTPOOL
|
||||||
log_must import_no_activity_check $TESTPOOL $opt
|
log_must import_no_activity_check $TESTPOOL $opt
|
||||||
done
|
done
|
||||||
|
|
||||||
# 3. Verify multihost=off and hostids differ (no activity check)
|
# 3. Verify multihost=off and hostids differ (no activity check)
|
||||||
log_must zpool export -F $TESTPOOL
|
log_must zpool export -f $TESTPOOL
|
||||||
log_must mmp_clear_hostid
|
log_must mmp_clear_hostid
|
||||||
log_must mmp_set_hostid $HOSTID2
|
log_must mmp_set_hostid $HOSTID2
|
||||||
log_mustnot import_no_activity_check $TESTPOOL ""
|
log_mustnot import_no_activity_check $TESTPOOL ""
|
||||||
log_must import_no_activity_check $TESTPOOL "-f"
|
log_must import_no_activity_check $TESTPOOL "-f"
|
||||||
|
|
||||||
# 4. Verify multihost=off and hostid zero allowed (no activity check)
|
# 4. Verify multihost=off and hostid zero allowed (no activity check)
|
||||||
log_must zpool export -F $TESTPOOL
|
log_must zpool export -f $TESTPOOL
|
||||||
log_must mmp_clear_hostid
|
log_must mmp_clear_hostid
|
||||||
log_mustnot import_no_activity_check $TESTPOOL ""
|
log_mustnot import_no_activity_check $TESTPOOL ""
|
||||||
log_must import_no_activity_check $TESTPOOL "-f"
|
log_must import_no_activity_check $TESTPOOL "-f"
|
||||||
|
@ -79,19 +79,19 @@ log_must mmp_pool_set_hostid $TESTPOOL $HOSTID1
|
||||||
log_must zpool set multihost=on $TESTPOOL
|
log_must zpool set multihost=on $TESTPOOL
|
||||||
|
|
||||||
for opt in "" "-f"; do
|
for opt in "" "-f"; do
|
||||||
log_must zpool export -F $TESTPOOL
|
log_must zpool export -f $TESTPOOL
|
||||||
log_must import_no_activity_check $TESTPOOL $opt
|
log_must import_no_activity_check $TESTPOOL $opt
|
||||||
done
|
done
|
||||||
|
|
||||||
# 6. Verify multihost=on and hostids differ (activity check)
|
# 6. Verify multihost=on and hostids differ (activity check)
|
||||||
log_must zpool export -F $TESTPOOL
|
log_must zpool export -f $TESTPOOL
|
||||||
log_must mmp_clear_hostid
|
log_must mmp_clear_hostid
|
||||||
log_must mmp_set_hostid $HOSTID2
|
log_must mmp_set_hostid $HOSTID2
|
||||||
log_mustnot import_activity_check $TESTPOOL ""
|
log_mustnot import_activity_check $TESTPOOL ""
|
||||||
log_must import_activity_check $TESTPOOL "-f"
|
log_must import_activity_check $TESTPOOL "-f"
|
||||||
|
|
||||||
# 7. Verify mmp_write and mmp_fail are set correctly
|
# 7. Verify mmp_write and mmp_fail are set correctly
|
||||||
log_must zpool export -F $TESTPOOL
|
log_must zpool export -f $TESTPOOL
|
||||||
log_must verify_mmp_write_fail_present ${DISK[0]}
|
log_must verify_mmp_write_fail_present ${DISK[0]}
|
||||||
|
|
||||||
# 8. Verify multihost=on and hostid zero fails (no activity check)
|
# 8. Verify multihost=on and hostid zero fails (no activity check)
|
||||||
|
|
|
@ -97,15 +97,15 @@ for x in $(seq 10); do
|
||||||
log_must mmp_set_hostid $HOSTID1
|
log_must mmp_set_hostid $HOSTID1
|
||||||
log_must zpool import $TESTPOOL
|
log_must zpool import $TESTPOOL
|
||||||
elif [ $action -eq 1 ]; then
|
elif [ $action -eq 1 ]; then
|
||||||
log_must zpool export -F $TESTPOOL
|
log_must zpool export -f $TESTPOOL
|
||||||
log_must zpool import $TESTPOOL
|
log_must zpool import $TESTPOOL
|
||||||
elif [ $action -eq 2 ]; then
|
elif [ $action -eq 2 ]; then
|
||||||
log_must zpool export -F $TESTPOOL
|
log_must zpool export -f $TESTPOOL
|
||||||
log_must mmp_clear_hostid
|
log_must mmp_clear_hostid
|
||||||
log_must mmp_set_hostid $HOSTID2
|
log_must mmp_set_hostid $HOSTID2
|
||||||
log_must zpool import -f $TESTPOOL
|
log_must zpool import -f $TESTPOOL
|
||||||
elif [ $action -eq 3 ]; then
|
elif [ $action -eq 3 ]; then
|
||||||
log_must zpool export -F $TESTPOOL
|
log_must zpool export -f $TESTPOOL
|
||||||
log_must set_tunable64 MULTIHOST_INTERVAL $MMP_INTERVAL_MIN
|
log_must set_tunable64 MULTIHOST_INTERVAL $MMP_INTERVAL_MIN
|
||||||
log_must zpool import $TESTPOOL
|
log_must zpool import $TESTPOOL
|
||||||
elif [ $action -eq 4 ]; then
|
elif [ $action -eq 4 ]; then
|
||||||
|
|
|
@ -48,6 +48,7 @@ log_must zpool checkpoint $NESTEDPOOL
|
||||||
log_must truncate -s $EXPSZ $FILEDISK1
|
log_must truncate -s $EXPSZ $FILEDISK1
|
||||||
log_must zpool online -e $NESTEDPOOL $FILEDISK1
|
log_must zpool online -e $NESTEDPOOL $FILEDISK1
|
||||||
NEWSZ=$(zpool list -v | grep "$FILEDISK1" | awk '{print $2}')
|
NEWSZ=$(zpool list -v | grep "$FILEDISK1" | awk '{print $2}')
|
||||||
|
log_must zpool sync $NESTEDPOOL
|
||||||
nested_change_state_after_checkpoint
|
nested_change_state_after_checkpoint
|
||||||
log_mustnot [ "$INITSZ" = "$NEWSZ" ]
|
log_mustnot [ "$INITSZ" = "$NEWSZ" ]
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue