aboutsummaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorFinix1979 <[email protected]>2020-12-03 01:28:55 +0800
committerGitHub <[email protected]>2020-12-02 09:28:55 -0800
commitec50cd24ba6fd3656229dbbcb78a665197597c91 (patch)
treec633080432c41f999732e6430a16ce55948e78fd /module
parent95a78a035ae01b6ee79ac9ce6bad073bc3ebb3cf (diff)
Avoid unneccessary zio allocation and wait
In function dmu_buf_hold_array_by_dnode, the usage of zio is only for the reading operation. Only create the zio and wait it in the reading scenario as a performance optimization. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Finix Yan <[email protected]> Closes #11251 Closes #11256
Diffstat (limited to 'module')
-rw-r--r--module/zfs/dmu.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/module/zfs/dmu.c b/module/zfs/dmu.c
index 14d864fbc..a8288a8b4 100644
--- a/module/zfs/dmu.c
+++ b/module/zfs/dmu.c
@@ -499,7 +499,7 @@ dmu_buf_hold_array_by_dnode(dnode_t *dn, uint64_t offset, uint64_t length,
uint64_t blkid, nblks, i;
uint32_t dbuf_flags;
int err;
- zio_t *zio;
+ zio_t *zio = NULL;
ASSERT(length <= DMU_MAX_ACCESS);
@@ -531,14 +531,17 @@ dmu_buf_hold_array_by_dnode(dnode_t *dn, uint64_t offset, uint64_t length,
}
dbp = kmem_zalloc(sizeof (dmu_buf_t *) * nblks, KM_SLEEP);
- zio = zio_root(dn->dn_objset->os_spa, NULL, NULL, ZIO_FLAG_CANFAIL);
+ if (read)
+ zio = zio_root(dn->dn_objset->os_spa, NULL, NULL,
+ ZIO_FLAG_CANFAIL);
blkid = dbuf_whichblock(dn, 0, offset);
for (i = 0; i < nblks; i++) {
dmu_buf_impl_t *db = dbuf_hold(dn, blkid + i, tag);
if (db == NULL) {
rw_exit(&dn->dn_struct_rwlock);
dmu_buf_rele_array(dbp, nblks, tag);
- zio_nowait(zio);
+ if (read)
+ zio_nowait(zio);
return (SET_ERROR(EIO));
}
@@ -555,15 +558,15 @@ dmu_buf_hold_array_by_dnode(dnode_t *dn, uint64_t offset, uint64_t length,
}
rw_exit(&dn->dn_struct_rwlock);
- /* wait for async i/o */
- err = zio_wait(zio);
- if (err) {
- dmu_buf_rele_array(dbp, nblks, tag);
- return (err);
- }
-
- /* wait for other io to complete */
if (read) {
+ /* wait for async read i/o */
+ err = zio_wait(zio);
+ if (err) {
+ dmu_buf_rele_array(dbp, nblks, tag);
+ return (err);
+ }
+
+ /* wait for other io to complete */
for (i = 0; i < nblks; i++) {
dmu_buf_impl_t *db = (dmu_buf_impl_t *)dbp[i];
mutex_enter(&db->db_mtx);