Skip to content

Commit

Permalink
Report holes when there are only metadata changes
Browse files Browse the repository at this point in the history
Update the dirty check in dmu_offset_next() such that dnode's
are only considered dirty for the purpose or reporting holes
when there are pending data blocks or frees to be synced.  This
ensures that when there are only metadata updates to be synced
(atime) that holes are reported.

Reviewed-by: Debabrata Banerjee <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes openzfs#6958 
Closes openzfs#8505
  • Loading branch information
behlendorf authored Mar 21, 2019
1 parent 066da71 commit ec4f9b8
Showing 1 changed file with 28 additions and 3 deletions.
31 changes: 28 additions & 3 deletions module/zfs/dmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -2366,14 +2366,39 @@ dmu_offset_next(objset_t *os, uint64_t object, boolean_t hole, uint64_t *off)
return (err);

/*
* Check if dnode is dirty
* Check if there are dirty data blocks or frees which have not been
* synced. Dirty spill and bonus blocks which are external to the
* object can ignored when reporting holes.
*/
mutex_enter(&dn->dn_mtx);
for (i = 0; i < TXG_SIZE; i++) {
if (multilist_link_active(&dn->dn_dirty_link[i])) {
clean = B_FALSE;
break;

if (dn->dn_free_ranges[i] != NULL) {
clean = B_FALSE;
break;
}

list_t *list = &dn->dn_dirty_records[i];
dbuf_dirty_record_t *dr;

for (dr = list_head(list); dr != NULL;
dr = list_next(list, dr)) {
dmu_buf_impl_t *db = dr->dr_dbuf;

if (db->db_blkid == DMU_SPILL_BLKID ||
db->db_blkid == DMU_BONUS_BLKID)
continue;

clean = B_FALSE;
break;
}
}

if (clean == B_FALSE)
break;
}
mutex_exit(&dn->dn_mtx);

/*
* If compatibility option is on, sync any current changes before
Expand Down

0 comments on commit ec4f9b8

Please sign in to comment.