diff options
author | Tom Caputi <[email protected]> | 2019-03-13 13:52:01 -0400 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2019-03-13 10:52:01 -0700 |
commit | 369aa501d11f4d21d4732b58d749259ad811a10a (patch) | |
tree | 747a00e61b8ae4348cccaa0cd234b39383898f57 /include/sys/dnode.h | |
parent | 146bdc414c7ad5b93417569bff6737d57860ff14 (diff) |
Fix handling of maxblkid for raw sends
Currently, the receive code can create an unreadable dataset from
a correct raw send stream. This is because it is currently
impossible to set maxblkid to a lower value without freeing the
associated object. This means truncating files on the send side
to a non-0 size could result in corruption. This patch solves this
issue by adding a new 'force' flag to dnode_new_blkid() which will
allow the raw receive code to force the DMU to accept the provided
maxblkid even if it is a lower value than the existing one.
For testing purposes the send_encrypted_files.ksh test has been
extended to include a variety of truncated files and multiple
snapshots. It also now leverages the xattrtest command to help
ensure raw receives correctly handle xattrs.
Reviewed-by: Paul Dagnelie <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Reviewed-by: Matt Ahrens <[email protected]>
Signed-off-by: Tom Caputi <[email protected]>
Closes #8168
Closes #8487
Diffstat (limited to 'include/sys/dnode.h')
-rw-r--r-- | include/sys/dnode.h | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/include/sys/dnode.h b/include/sys/dnode.h index 48ef927d4..6355aaa50 100644 --- a/include/sys/dnode.h +++ b/include/sys/dnode.h @@ -372,6 +372,12 @@ struct dnode { }; /* + * We use this (otherwise unused) bit to indicate if the value of + * dn_next_maxblkid[txgoff] is valid to use in dnode_sync(). + */ +#define DMU_NEXT_MAXBLKID_SET (1ULL << 63) + +/* * Adds a level of indirection between the dbuf and the dnode to avoid * iterating descendent dbufs in dnode_move(). Handles are not allocated * individually, but as an array of child dnodes in dnode_hold_impl(). @@ -423,7 +429,8 @@ int dnode_set_nlevels(dnode_t *dn, int nlevels, dmu_tx_t *tx); int dnode_set_blksz(dnode_t *dn, uint64_t size, int ibs, dmu_tx_t *tx); void dnode_free_range(dnode_t *dn, uint64_t off, uint64_t len, dmu_tx_t *tx); void dnode_diduse_space(dnode_t *dn, int64_t space); -void dnode_new_blkid(dnode_t *dn, uint64_t blkid, dmu_tx_t *tx, boolean_t); +void dnode_new_blkid(dnode_t *dn, uint64_t blkid, dmu_tx_t *tx, + boolean_t have_read, boolean_t force); uint64_t dnode_block_freed(dnode_t *dn, uint64_t blkid); void dnode_init(void); void dnode_fini(void); |