summaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2019-04-12 14:28:04 -0700
committerGitHub <[email protected]>2019-04-12 14:28:04 -0700
commitb92f5d9f8254f726298a6ab962719fc2b68350b1 (patch)
tree385746b3edf259ca9edc315f8d78739c24cdb894 /module
parent3fa93bb8d3f0c757814b96a98ce3334d132894f1 (diff)
Fix issue in receive_object() during reallocation
When receiving an object to a previously allocated interior slot the new object should be "allocated" by setting DMU_NEW_OBJECT, not "reallocated" with dnode_reallocate(). For resilience verify the slot is free as required in case the stream is malformed. Add a test case to generate more realistic incremental send streams that force reallocation to occur during the receive. Reviewed-by: Olaf Faaland <[email protected]> Reviewed-by: Tom Caputi <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Closes #8067 Closes #8614
Diffstat (limited to 'module')
-rw-r--r--module/zfs/dmu_recv.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/module/zfs/dmu_recv.c b/module/zfs/dmu_recv.c
index 6b9404754..0db307097 100644
--- a/module/zfs/dmu_recv.c
+++ b/module/zfs/dmu_recv.c
@@ -1253,7 +1253,12 @@ receive_object(struct receive_writer_arg *rwa, struct drr_object *drro,
* earlier in the stream.
*/
txg_wait_synced(dmu_objset_pool(rwa->os), 0);
- object = drro->drr_object;
+
+ if (dmu_object_info(rwa->os, drro->drr_object, NULL) != ENOENT)
+ return (SET_ERROR(EINVAL));
+
+ /* object was freed and we are about to allocate a new one */
+ object = DMU_NEW_OBJECT;
} else {
/* object is free and we are about to allocate a new one */
object = DMU_NEW_OBJECT;