ZIL: Avoid dbuf_read() before dmu_sync().
In most cases dmu_sync() works with dirty records directly and does not need actual data. The only exception is dmu_sync_late_arrival(). To save some CPU time use dmu_buf_hold_noread*() in z*_get_data() and explicitly call dbuf_read() in dmu_sync_late_arrival(). There is also a chance that by that time TXG will already be synced and we won't have to do it at all. Reviewed-by: Brian Atkinson <batkinson@lanl.gov> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Alexander Motin <mav@FreeBSD.org> Sponsored by: iXsystems, Inc. Closes #15153
This commit is contained in:
parent
8ce2eba9e6
commit
bdb7df4245
|
@ -572,11 +572,15 @@ int dmu_buf_hold(objset_t *os, uint64_t object, uint64_t offset,
|
||||||
int dmu_buf_hold_array(objset_t *os, uint64_t object, uint64_t offset,
|
int dmu_buf_hold_array(objset_t *os, uint64_t object, uint64_t offset,
|
||||||
uint64_t length, int read, const void *tag, int *numbufsp,
|
uint64_t length, int read, const void *tag, int *numbufsp,
|
||||||
dmu_buf_t ***dbpp);
|
dmu_buf_t ***dbpp);
|
||||||
|
int dmu_buf_hold_noread(objset_t *os, uint64_t object, uint64_t offset,
|
||||||
|
const void *tag, dmu_buf_t **dbp);
|
||||||
int dmu_buf_hold_by_dnode(dnode_t *dn, uint64_t offset,
|
int dmu_buf_hold_by_dnode(dnode_t *dn, uint64_t offset,
|
||||||
const void *tag, dmu_buf_t **dbp, int flags);
|
const void *tag, dmu_buf_t **dbp, int flags);
|
||||||
int dmu_buf_hold_array_by_dnode(dnode_t *dn, uint64_t offset,
|
int dmu_buf_hold_array_by_dnode(dnode_t *dn, uint64_t offset,
|
||||||
uint64_t length, boolean_t read, const void *tag, int *numbufsp,
|
uint64_t length, boolean_t read, const void *tag, int *numbufsp,
|
||||||
dmu_buf_t ***dbpp, uint32_t flags);
|
dmu_buf_t ***dbpp, uint32_t flags);
|
||||||
|
int dmu_buf_hold_noread_by_dnode(dnode_t *dn, uint64_t offset, const void *tag,
|
||||||
|
dmu_buf_t **dbp);
|
||||||
/*
|
/*
|
||||||
* Add a reference to a dmu buffer that has already been held via
|
* Add a reference to a dmu buffer that has already been held via
|
||||||
* dmu_buf_hold() in the current context.
|
* dmu_buf_hold() in the current context.
|
||||||
|
|
|
@ -247,8 +247,6 @@ typedef struct dmu_sendstatus {
|
||||||
|
|
||||||
void dmu_object_zapify(objset_t *, uint64_t, dmu_object_type_t, dmu_tx_t *);
|
void dmu_object_zapify(objset_t *, uint64_t, dmu_object_type_t, dmu_tx_t *);
|
||||||
void dmu_object_free_zapified(objset_t *, uint64_t, dmu_tx_t *);
|
void dmu_object_free_zapified(objset_t *, uint64_t, dmu_tx_t *);
|
||||||
int dmu_buf_hold_noread(objset_t *, uint64_t, uint64_t,
|
|
||||||
const void *, dmu_buf_t **);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,7 +165,7 @@ dmu_object_byteswap_info_t dmu_ot_byteswap[DMU_BSWAP_NUMFUNCS] = {
|
||||||
{ zfs_acl_byteswap, "acl" }
|
{ zfs_acl_byteswap, "acl" }
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
int
|
||||||
dmu_buf_hold_noread_by_dnode(dnode_t *dn, uint64_t offset,
|
dmu_buf_hold_noread_by_dnode(dnode_t *dn, uint64_t offset,
|
||||||
const void *tag, dmu_buf_t **dbp)
|
const void *tag, dmu_buf_t **dbp)
|
||||||
{
|
{
|
||||||
|
@ -185,6 +185,7 @@ dmu_buf_hold_noread_by_dnode(dnode_t *dn, uint64_t offset,
|
||||||
*dbp = &db->db;
|
*dbp = &db->db;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
dmu_buf_hold_noread(objset_t *os, uint64_t object, uint64_t offset,
|
dmu_buf_hold_noread(objset_t *os, uint64_t object, uint64_t offset,
|
||||||
const void *tag, dmu_buf_t **dbp)
|
const void *tag, dmu_buf_t **dbp)
|
||||||
|
@ -1672,6 +1673,12 @@ dmu_sync_late_arrival(zio_t *pio, objset_t *os, dmu_sync_cb_t *done, zgd_t *zgd,
|
||||||
{
|
{
|
||||||
dmu_sync_arg_t *dsa;
|
dmu_sync_arg_t *dsa;
|
||||||
dmu_tx_t *tx;
|
dmu_tx_t *tx;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
error = dbuf_read((dmu_buf_impl_t *)zgd->zgd_db, NULL,
|
||||||
|
DB_RF_CANFAIL | DB_RF_NOPREFETCH);
|
||||||
|
if (error != 0)
|
||||||
|
return (error);
|
||||||
|
|
||||||
tx = dmu_tx_create(os);
|
tx = dmu_tx_create(os);
|
||||||
dmu_tx_hold_space(tx, zgd->zgd_db->db_size);
|
dmu_tx_hold_space(tx, zgd->zgd_db->db_size);
|
||||||
|
|
|
@ -917,8 +917,8 @@ zfs_get_data(void *arg, uint64_t gen, lr_write_t *lr, char *buf,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (error == 0)
|
if (error == 0)
|
||||||
error = dmu_buf_hold(os, object, offset, zgd, &db,
|
error = dmu_buf_hold_noread(os, object, offset, zgd,
|
||||||
DMU_READ_NO_PREFETCH);
|
&db);
|
||||||
|
|
||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
blkptr_t *bp = &lr->lr_blkptr;
|
blkptr_t *bp = &lr->lr_blkptr;
|
||||||
|
|
|
@ -727,8 +727,8 @@ zvol_get_data(void *arg, uint64_t arg2, lr_write_t *lr, char *buf,
|
||||||
offset = P2ALIGN_TYPED(offset, size, uint64_t);
|
offset = P2ALIGN_TYPED(offset, size, uint64_t);
|
||||||
zgd->zgd_lr = zfs_rangelock_enter(&zv->zv_rangelock, offset,
|
zgd->zgd_lr = zfs_rangelock_enter(&zv->zv_rangelock, offset,
|
||||||
size, RL_READER);
|
size, RL_READER);
|
||||||
error = dmu_buf_hold_by_dnode(zv->zv_dn, offset, zgd, &db,
|
error = dmu_buf_hold_noread_by_dnode(zv->zv_dn, offset, zgd,
|
||||||
DMU_READ_NO_PREFETCH);
|
&db);
|
||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
blkptr_t *bp = &lr->lr_blkptr;
|
blkptr_t *bp = &lr->lr_blkptr;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue