mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-26 19:19:32 +03:00
Optionally skip zil_close during zvol_create_minor_impl
If there were no zil entries to replay, skip zil_close. zil_close waits for a transaction to sync. That can take several seconds, for example during pool import of a resilvering pool. Skipping zil_close can cut the time for "zpool import" from 2 hours to 45 seconds on a resilvering pool with a thousand zvols. Reviewed-by: Richard Yao <richard.yao@alumni.stonybrook.edu> Reviewed-by: Alexander Motin <mav@FreeBSD.org> Reviewed-by: Ryan Moeller <ryan@iXsystems.com> Sponsored-by: Axcient Closes #13999 Closes #14015
This commit is contained in:
parent
f224eddf92
commit
e197bb24f1
@ -539,10 +539,10 @@ extern zilog_t *zil_open(objset_t *os, zil_get_data_t *get_data,
|
|||||||
zil_sums_t *zil_sums);
|
zil_sums_t *zil_sums);
|
||||||
extern void zil_close(zilog_t *zilog);
|
extern void zil_close(zilog_t *zilog);
|
||||||
|
|
||||||
extern void zil_replay(objset_t *os, void *arg,
|
extern boolean_t zil_replay(objset_t *os, void *arg,
|
||||||
zil_replay_func_t *const replay_func[TX_MAX_TYPE]);
|
zil_replay_func_t *const replay_func[TX_MAX_TYPE]);
|
||||||
extern boolean_t zil_replaying(zilog_t *zilog, dmu_tx_t *tx);
|
extern boolean_t zil_replaying(zilog_t *zilog, dmu_tx_t *tx);
|
||||||
extern void zil_destroy(zilog_t *zilog, boolean_t keep_first);
|
extern boolean_t zil_destroy(zilog_t *zilog, boolean_t keep_first);
|
||||||
extern void zil_destroy_sync(zilog_t *zilog, dmu_tx_t *tx);
|
extern void zil_destroy_sync(zilog_t *zilog, dmu_tx_t *tx);
|
||||||
|
|
||||||
extern itx_t *zil_itx_create(uint64_t txtype, size_t lrsize);
|
extern itx_t *zil_itx_create(uint64_t txtype, size_t lrsize);
|
||||||
|
@ -1386,6 +1386,7 @@ zvol_os_create_minor(const char *name)
|
|||||||
uint64_t volsize;
|
uint64_t volsize;
|
||||||
uint64_t volmode, hash;
|
uint64_t volmode, hash;
|
||||||
int error;
|
int error;
|
||||||
|
bool replayed_zil = B_FALSE;
|
||||||
|
|
||||||
ZFS_LOG(1, "Creating ZVOL %s...", name);
|
ZFS_LOG(1, "Creating ZVOL %s...", name);
|
||||||
hash = zvol_name_hash(name);
|
hash = zvol_name_hash(name);
|
||||||
@ -1490,11 +1491,12 @@ zvol_os_create_minor(const char *name)
|
|||||||
zv->zv_zilog = zil_open(os, zvol_get_data, &zv->zv_kstat.dk_zil_sums);
|
zv->zv_zilog = zil_open(os, zvol_get_data, &zv->zv_kstat.dk_zil_sums);
|
||||||
if (spa_writeable(dmu_objset_spa(os))) {
|
if (spa_writeable(dmu_objset_spa(os))) {
|
||||||
if (zil_replay_disable)
|
if (zil_replay_disable)
|
||||||
zil_destroy(zv->zv_zilog, B_FALSE);
|
replayed_zil = zil_destroy(zv->zv_zilog, B_FALSE);
|
||||||
else
|
else
|
||||||
zil_replay(os, zv, zvol_replay_vector);
|
replayed_zil = zil_replay(os, zv, zvol_replay_vector);
|
||||||
}
|
}
|
||||||
zil_close(zv->zv_zilog);
|
if (replayed_zil)
|
||||||
|
zil_close(zv->zv_zilog);
|
||||||
zv->zv_zilog = NULL;
|
zv->zv_zilog = NULL;
|
||||||
|
|
||||||
/* TODO: prefetch for geom tasting */
|
/* TODO: prefetch for geom tasting */
|
||||||
|
@ -1279,6 +1279,7 @@ zvol_os_create_minor(const char *name)
|
|||||||
int error = 0;
|
int error = 0;
|
||||||
int idx;
|
int idx;
|
||||||
uint64_t hash = zvol_name_hash(name);
|
uint64_t hash = zvol_name_hash(name);
|
||||||
|
bool replayed_zil = B_FALSE;
|
||||||
|
|
||||||
if (zvol_inhibit_dev)
|
if (zvol_inhibit_dev)
|
||||||
return (0);
|
return (0);
|
||||||
@ -1420,11 +1421,12 @@ zvol_os_create_minor(const char *name)
|
|||||||
zv->zv_zilog = zil_open(os, zvol_get_data, &zv->zv_kstat.dk_zil_sums);
|
zv->zv_zilog = zil_open(os, zvol_get_data, &zv->zv_kstat.dk_zil_sums);
|
||||||
if (spa_writeable(dmu_objset_spa(os))) {
|
if (spa_writeable(dmu_objset_spa(os))) {
|
||||||
if (zil_replay_disable)
|
if (zil_replay_disable)
|
||||||
zil_destroy(zv->zv_zilog, B_FALSE);
|
replayed_zil = zil_destroy(zv->zv_zilog, B_FALSE);
|
||||||
else
|
else
|
||||||
zil_replay(os, zv, zvol_replay_vector);
|
replayed_zil = zil_replay(os, zv, zvol_replay_vector);
|
||||||
}
|
}
|
||||||
zil_close(zv->zv_zilog);
|
if (replayed_zil)
|
||||||
|
zil_close(zv->zv_zilog);
|
||||||
zv->zv_zilog = NULL;
|
zv->zv_zilog = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -887,8 +887,9 @@ zil_create(zilog_t *zilog)
|
|||||||
* txg_wait_synced() here either when keep_first is set, because both
|
* txg_wait_synced() here either when keep_first is set, because both
|
||||||
* zil_create() and zil_destroy() will wait for any in-progress destroys
|
* zil_create() and zil_destroy() will wait for any in-progress destroys
|
||||||
* to complete.
|
* to complete.
|
||||||
|
* Return B_TRUE if there were any entries to replay.
|
||||||
*/
|
*/
|
||||||
void
|
boolean_t
|
||||||
zil_destroy(zilog_t *zilog, boolean_t keep_first)
|
zil_destroy(zilog_t *zilog, boolean_t keep_first)
|
||||||
{
|
{
|
||||||
const zil_header_t *zh = zilog->zl_header;
|
const zil_header_t *zh = zilog->zl_header;
|
||||||
@ -904,7 +905,7 @@ zil_destroy(zilog_t *zilog, boolean_t keep_first)
|
|||||||
zilog->zl_old_header = *zh; /* debugging aid */
|
zilog->zl_old_header = *zh; /* debugging aid */
|
||||||
|
|
||||||
if (BP_IS_HOLE(&zh->zh_log))
|
if (BP_IS_HOLE(&zh->zh_log))
|
||||||
return;
|
return (B_FALSE);
|
||||||
|
|
||||||
tx = dmu_tx_create(zilog->zl_os);
|
tx = dmu_tx_create(zilog->zl_os);
|
||||||
VERIFY0(dmu_tx_assign(tx, TXG_WAIT));
|
VERIFY0(dmu_tx_assign(tx, TXG_WAIT));
|
||||||
@ -937,6 +938,8 @@ zil_destroy(zilog_t *zilog, boolean_t keep_first)
|
|||||||
mutex_exit(&zilog->zl_lock);
|
mutex_exit(&zilog->zl_lock);
|
||||||
|
|
||||||
dmu_tx_commit(tx);
|
dmu_tx_commit(tx);
|
||||||
|
|
||||||
|
return (B_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -3849,8 +3852,9 @@ zil_incr_blks(zilog_t *zilog, const blkptr_t *bp, void *arg, uint64_t claim_txg)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* If this dataset has a non-empty intent log, replay it and destroy it.
|
* If this dataset has a non-empty intent log, replay it and destroy it.
|
||||||
|
* Return B_TRUE if there were any entries to replay.
|
||||||
*/
|
*/
|
||||||
void
|
boolean_t
|
||||||
zil_replay(objset_t *os, void *arg,
|
zil_replay(objset_t *os, void *arg,
|
||||||
zil_replay_func_t *const replay_func[TX_MAX_TYPE])
|
zil_replay_func_t *const replay_func[TX_MAX_TYPE])
|
||||||
{
|
{
|
||||||
@ -3859,8 +3863,7 @@ zil_replay(objset_t *os, void *arg,
|
|||||||
zil_replay_arg_t zr;
|
zil_replay_arg_t zr;
|
||||||
|
|
||||||
if ((zh->zh_flags & ZIL_REPLAY_NEEDED) == 0) {
|
if ((zh->zh_flags & ZIL_REPLAY_NEEDED) == 0) {
|
||||||
zil_destroy(zilog, B_TRUE);
|
return (zil_destroy(zilog, B_TRUE));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
zr.zr_replay = replay_func;
|
zr.zr_replay = replay_func;
|
||||||
@ -3883,6 +3886,8 @@ zil_replay(objset_t *os, void *arg,
|
|||||||
zil_destroy(zilog, B_FALSE);
|
zil_destroy(zilog, B_FALSE);
|
||||||
txg_wait_synced(zilog->zl_dmu_pool, zilog->zl_destroy_txg);
|
txg_wait_synced(zilog->zl_dmu_pool, zilog->zl_destroy_txg);
|
||||||
zilog->zl_replay = B_FALSE;
|
zilog->zl_replay = B_FALSE;
|
||||||
|
|
||||||
|
return (B_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean_t
|
boolean_t
|
||||||
|
Loading…
Reference in New Issue
Block a user