aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorTom Caputi <[email protected]>2018-01-19 04:19:47 -0500
committerBrian Behlendorf <[email protected]>2018-02-02 11:43:11 -0800
commit047116ac76526d869e3f347afb5d81cc2b156fdf (patch)
tree8307d677ee02803b9341d3a7536e27cc71910194 /include
parentd53bd7f5244a1cd0009d2f90d3ec9df22352fbb3 (diff)
Raw sends must be able to decrease nlevels
Currently, when a raw zfs send file includes a DRR_OBJECT record that would decrease the number of levels of an existing object, the object is reallocated with dmu_object_reclaim() which creates the new dnode using the old object's nlevels. For non-raw sends this doesn't really matter, but raw sends require that nlevels on the receive side match that of the send side so that the checksum-of-MAC tree can be properly maintained. This patch corrects the issue by freeing the object completely before allocating it again in this case. This patch also corrects several issues with dnode_hold_impl() and related functions that prevented dnodes (particularly multi-slot dnodes) from being reallocated properly due to the fact that existing dnodes were not being fully cleaned up when they were freed. This patch adds a test to make sure that zfs recv functions properly with incremental streams containing dnodes of different sizes. Reviewed by: Matthew Ahrens <[email protected]> Reviewed-by: Jorgen Lundman <[email protected]> Signed-off-by: Tom Caputi <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Closes #6821 Closes #6864
Diffstat (limited to 'include')
-rw-r--r--include/sys/dnode.h6
1 files changed, 6 insertions, 0 deletions
diff --git a/include/sys/dnode.h b/include/sys/dnode.h
index a2bef9d2c..691fd443a 100644
--- a/include/sys/dnode.h
+++ b/include/sys/dnode.h
@@ -424,6 +424,7 @@ int dnode_next_offset(dnode_t *dn, int flags, uint64_t *off,
int minlvl, uint64_t blkfill, uint64_t txg);
void dnode_evict_dbufs(dnode_t *dn);
void dnode_evict_bonus(dnode_t *dn);
+void dnode_free_interior_slots(dnode_t *dn);
#define DNODE_IS_CACHEABLE(_dn) \
((_dn)->dn_objset->os_primary_cache == ZFS_CACHE_ALL || \
@@ -518,6 +519,11 @@ typedef struct dnode_stats {
*/
kstat_named_t dnode_hold_free_txg;
/*
+ * Number of times dnode_free_interior_slots() needed to retry
+ * acquiring a slot zrl lock due to contention.
+ */
+ kstat_named_t dnode_free_interior_lock_retry;
+ /*
* Number of new dnodes allocated by dnode_allocate().
*/
kstat_named_t dnode_allocate;