aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPawel Jakub Dawidek <[email protected]>2021-10-18 16:50:33 -0700
committerGitHub <[email protected]>2021-10-18 16:50:33 -0700
commita95c82bed84095d18375ef7aaacfb012ad52f13a (patch)
tree67d63b2dab768b9865ec29d748c486058b410d9a
parentfd778e44c88fd3215c8a7f5ec4989431ac02cd32 (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.c75
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;
}