aboutsummaryrefslogtreecommitdiffstats
path: root/module/zfs/dmu_object.c
diff options
context:
space:
mode:
authorPaul Dagnelie <[email protected]>2016-09-20 10:02:29 -0700
committerBrian Behlendorf <[email protected]>2018-07-30 09:27:49 -0700
commit21d48b5eac54ba7b2e4d8bf0d0e747082e0e8577 (patch)
tree06c38b83d34d34f8a22ff3a0c6ce16de00baafcf /module/zfs/dmu_object.c
parentb719768e35fdd6d4052546338453cee0713a1a3c (diff)
OpenZFS 9438 - Holes can lose birth time info if a block has a mix of birth times
As reported by https://github.com/zfsonlinux/zfs/issues/4996, there is yet another hole birth issue. In this one, if a block is entirely holes, but the birth times are not all the same, we lose that information by creating one hole with the current txg as its birth time. The ZoL PR's fix approach is incorrect. Ultimately, the problem here is that when you truncate and write a file in the same transaction group, the dbuf for the indirect block will be zeroed out to deal with the truncation, and then written for the write. During this process, we will lose hole birth time information for any holes in the range. In the case where a dnode is being freed, we need to determine whether the block should be converted to a higher-level hole in the zio pipeline, and if so do it when the dnode is being synced out. Porting Notes: * The DMU_OBJECT_END change in zfs_znode.c was already applied. * Added test cases from #5675 provided by @rincebrain for hole_birth issues. These test cases should be pushed upstream to OpenZFS. * Updated mk_files which is used by several rsend tests so the files created are a little more interesting and may contain holes. Authored by: Paul Dagnelie <[email protected]> Reviewed by: Matt Ahrens <[email protected]> Reviewed by: George Wilson <[email protected]> Approved by: Robert Mustacchi <[email protected]> Ported-by: Brian Behlendorf <[email protected]> OpenZFS-issue: https://www.illumos.org/issues/9438 OpenZFS-commit: https://github.com/openzfs/openzfs/commit/738e2a3c External-issue: DLPX-46861 Closes #7746
Diffstat (limited to 'module/zfs/dmu_object.c')
-rw-r--r--module/zfs/dmu_object.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/module/zfs/dmu_object.c b/module/zfs/dmu_object.c
index b9960782e..afee869b6 100644
--- a/module/zfs/dmu_object.c
+++ b/module/zfs/dmu_object.c
@@ -311,6 +311,10 @@ dmu_object_free(objset_t *os, uint64_t object, dmu_tx_t *tx)
return (err);
ASSERT(dn->dn_type != DMU_OT_NONE);
+ /*
+ * If we don't create this free range, we'll leak indirect blocks when
+ * we get to freeing the dnode in syncing context.
+ */
dnode_free_range(dn, 0, DMU_OBJECT_END, tx);
dnode_free(dn, tx);
dnode_rele(dn, FTAG);