diff options
author | Finix1979 <[email protected]> | 2020-12-03 01:28:55 +0800 |
---|---|---|
committer | GitHub <[email protected]> | 2020-12-02 09:28:55 -0800 |
commit | ec50cd24ba6fd3656229dbbcb78a665197597c91 (patch) | |
tree | c633080432c41f999732e6430a16ce55948e78fd /module | |
parent | 95a78a035ae01b6ee79ac9ce6bad073bc3ebb3cf (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.c | 25 |
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); |