diff options
author | Pawel Jakub Dawidek <[email protected]> | 2021-10-18 16:50:33 -0700 |
---|---|---|
committer | GitHub <[email protected]> | 2021-10-18 16:50:33 -0700 |
commit | a95c82bed84095d18375ef7aaacfb012ad52f13a (patch) | |
tree | 67d63b2dab768b9865ec29d748c486058b410d9a | |
parent | fd778e44c88fd3215c8a7f5ec4989431ac02cd32 (diff) |
Remove code duplication
Remove code duplication by moving code responsible for partial block
zeroing to a separate function: dnode_partial_zero().
Reviewed-by: Brian Behlendorf <[email protected]>
Reviewed-by: Ryan Moeller <[email protected]>
Signed-off-by: Pawel Jakub Dawidek <[email protected]>
Closes #12627
-rw-r--r-- | module/zfs/dnode.c | 75 |
1 files changed, 33 insertions, 42 deletions
diff --git a/module/zfs/dnode.c b/module/zfs/dnode.c index 7f741542c..900240479 100644 --- a/module/zfs/dnode.c +++ b/module/zfs/dnode.c @@ -2037,10 +2037,40 @@ dnode_set_dirtyctx(dnode_t *dn, dmu_tx_t *tx, void *tag) } } +static void +dnode_partial_zero(dnode_t *dn, uint64_t off, uint64_t blkoff, uint64_t len, + dmu_tx_t *tx) +{ + dmu_buf_impl_t *db; + int res; + + rw_enter(&dn->dn_struct_rwlock, RW_READER); + res = dbuf_hold_impl(dn, 0, dbuf_whichblock(dn, 0, off), TRUE, FALSE, + FTAG, &db); + rw_exit(&dn->dn_struct_rwlock); + if (res == 0) { + db_lock_type_t dblt; + boolean_t dirty; + + dblt = dmu_buf_lock_parent(db, RW_READER, FTAG); + /* don't dirty if not on disk and not dirty */ + dirty = !list_is_empty(&db->db_dirty_records) || + (db->db_blkptr && !BP_IS_HOLE(db->db_blkptr)); + dmu_buf_unlock_parent(db, dblt, FTAG); + if (dirty) { + caddr_t data; + + dmu_buf_will_dirty(&db->db, tx); + data = db->db.db_data; + bzero(data + blkoff, len); + } + dbuf_rele(db, FTAG); + } +} + void dnode_free_range(dnode_t *dn, uint64_t off, uint64_t len, dmu_tx_t *tx) { - dmu_buf_impl_t *db; uint64_t blkoff, blkid, nblks; int blksz, blkshift, head, tail; int trunc = FALSE; @@ -2089,31 +2119,10 @@ dnode_free_range(dnode_t *dn, uint64_t off, uint64_t len, dmu_tx_t *tx) } /* zero out any partial block data at the start of the range */ if (head) { - int res; ASSERT3U(blkoff + head, ==, blksz); if (len < head) head = len; - rw_enter(&dn->dn_struct_rwlock, RW_READER); - res = dbuf_hold_impl(dn, 0, dbuf_whichblock(dn, 0, off), - TRUE, FALSE, FTAG, &db); - rw_exit(&dn->dn_struct_rwlock); - if (res == 0) { - caddr_t data; - boolean_t dirty; - - db_lock_type_t dblt = dmu_buf_lock_parent(db, RW_READER, - FTAG); - /* don't dirty if it isn't on disk and isn't dirty */ - dirty = !list_is_empty(&db->db_dirty_records) || - (db->db_blkptr && !BP_IS_HOLE(db->db_blkptr)); - dmu_buf_unlock_parent(db, dblt, FTAG); - if (dirty) { - dmu_buf_will_dirty(&db->db, tx); - data = db->db.db_data; - bzero(data + blkoff, head); - } - dbuf_rele(db, FTAG); - } + dnode_partial_zero(dn, off, blkoff, head, tx); off += head; len -= head; } @@ -2135,27 +2144,9 @@ dnode_free_range(dnode_t *dn, uint64_t off, uint64_t len, dmu_tx_t *tx) ASSERT0(P2PHASE(off, blksz)); /* zero out any partial block data at the end of the range */ if (tail) { - int res; if (len < tail) tail = len; - rw_enter(&dn->dn_struct_rwlock, RW_READER); - res = dbuf_hold_impl(dn, 0, dbuf_whichblock(dn, 0, off+len), - TRUE, FALSE, FTAG, &db); - rw_exit(&dn->dn_struct_rwlock); - if (res == 0) { - boolean_t dirty; - /* don't dirty if not on disk and not dirty */ - db_lock_type_t type = dmu_buf_lock_parent(db, RW_READER, - FTAG); - dirty = !list_is_empty(&db->db_dirty_records) || - (db->db_blkptr && !BP_IS_HOLE(db->db_blkptr)); - dmu_buf_unlock_parent(db, type, FTAG); - if (dirty) { - dmu_buf_will_dirty(&db->db, tx); - bzero(db->db.db_data, tail); - } - dbuf_rele(db, FTAG); - } + dnode_partial_zero(dn, off + len, 0, tail, tx); len -= tail; } |