diff options
author | Paul Dagnelie <[email protected]> | 2016-09-20 10:02:29 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2018-07-30 09:27:49 -0700 |
commit | 21d48b5eac54ba7b2e4d8bf0d0e747082e0e8577 (patch) | |
tree | 06c38b83d34d34f8a22ff3a0c6ce16de00baafcf /module/zfs/dmu_object.c | |
parent | b719768e35fdd6d4052546338453cee0713a1a3c (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.c | 4 |
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); |