diff options
author | Brian Behlendorf <[email protected]> | 2019-04-12 14:28:04 -0700 |
---|---|---|
committer | GitHub <[email protected]> | 2019-04-12 14:28:04 -0700 |
commit | b92f5d9f8254f726298a6ab962719fc2b68350b1 (patch) | |
tree | 385746b3edf259ca9edc315f8d78739c24cdb894 /module | |
parent | 3fa93bb8d3f0c757814b96a98ce3334d132894f1 (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.c | 7 |
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; |