aboutsummaryrefslogtreecommitdiffstats
path: root/module/zfs/dmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'module/zfs/dmu.c')
-rw-r--r--module/zfs/dmu.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/module/zfs/dmu.c b/module/zfs/dmu.c
index 1501ae804..3b7bbefc2 100644
--- a/module/zfs/dmu.c
+++ b/module/zfs/dmu.c
@@ -1472,7 +1472,19 @@ dmu_sync_done(zio_t *zio, arc_buf_t *buf, void *varg)
dr->dt.dl.dr_overridden_by = *zio->io_bp;
dr->dt.dl.dr_override_state = DR_OVERRIDDEN;
dr->dt.dl.dr_copies = zio->io_prop.zp_copies;
- if (BP_IS_HOLE(&dr->dt.dl.dr_overridden_by))
+
+ /*
+ * Old style holes are filled with all zeros, whereas
+ * new-style holes maintain their lsize, type, level,
+ * and birth time (see zio_write_compress). While we
+ * need to reset the BP_SET_LSIZE() call that happened
+ * in dmu_sync_ready for old style holes, we do *not*
+ * want to wipe out the information contained in new
+ * style holes. Thus, only zero out the block pointer if
+ * it's an old style hole.
+ */
+ if (BP_IS_HOLE(&dr->dt.dl.dr_overridden_by) &&
+ dr->dt.dl.dr_overridden_by.blk_birth == 0)
BP_ZERO(&dr->dt.dl.dr_overridden_by);
} else {
dr->dt.dl.dr_override_state = DR_NOT_OVERRIDDEN;