diff options
author | George Melikov <[email protected]> | 2017-02-04 20:10:24 +0300 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2017-02-04 09:10:24 -0800 |
commit | 2e0e443ac40c7e825a02519a497328226bd866ff (patch) | |
tree | 40b32d221e46f670d1efe0925842330b542e4bda /module/zfs/dmu_send.c | |
parent | 57c6a9174d9e1d3844181267e34d9510b1250b4a (diff) |
OpenZFS 7247 - zfs receive of deduplicated stream fails
Authored by: Chris Williamson <[email protected]>
Reviewed by: Matthew Ahrens <[email protected]>
Reviewed by: Dan Kimmel <[email protected]>
Approved by: Robert Mustacchi <[email protected]>
Reviewed-by: loli10K <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Ported-by: George Melikov <[email protected]>
OpenZFS-issue: https://www.illumos.org/issues/7247
OpenZFS-commit: https://github.com/openzfs/openzfs/commit/2ad25b4
Closes #5689
Porting notes:
- tests/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_013_pos.ksh
renamed as zfs_receive_015_pos.ksh, zfs_receive_013_pos.ksh is now
used for OpenZFS test.
- libzfs_sendrecv.c: SMALLEST_POSSIBLE_MAX_DDT_MB is always used
for all 32-bit builds.
Diffstat (limited to 'module/zfs/dmu_send.c')
-rw-r--r-- | module/zfs/dmu_send.c | 44 |
1 files changed, 21 insertions, 23 deletions
diff --git a/module/zfs/dmu_send.c b/module/zfs/dmu_send.c index 6e117651b..6f17671ee 100644 --- a/module/zfs/dmu_send.c +++ b/module/zfs/dmu_send.c @@ -3230,6 +3230,9 @@ dmu_recv_end_sync(void *arg, dmu_tx_t *tx) dsl_dataset_phys(origin_head)->ds_flags &= ~DS_FLAG_INCONSISTENT; + drc->drc_newsnapobj = + dsl_dataset_phys(origin_head)->ds_prev_snap_obj; + dsl_dataset_rele(origin_head, FTAG); dsl_destroy_head_sync_impl(drc->drc_ds, tx); @@ -3265,8 +3268,9 @@ dmu_recv_end_sync(void *arg, dmu_tx_t *tx) (void) zap_remove(dp->dp_meta_objset, ds->ds_object, DS_FIELD_RESUME_TONAME, tx); } + drc->drc_newsnapobj = + dsl_dataset_phys(drc->drc_ds)->ds_prev_snap_obj; } - drc->drc_newsnapobj = dsl_dataset_phys(drc->drc_ds)->ds_prev_snap_obj; zvol_create_minors(dp->dp_spa, drc->drc_tofs, B_TRUE); /* * Release the hold from dmu_recv_begin. This must be done before @@ -3310,8 +3314,6 @@ static int dmu_recv_end_modified_blocks = 3; static int dmu_recv_existing_end(dmu_recv_cookie_t *drc) { - int error; - #ifdef _KERNEL /* * We will be destroying the ds; make sure its origin is unmounted if @@ -3322,23 +3324,30 @@ dmu_recv_existing_end(dmu_recv_cookie_t *drc) zfs_destroy_unmount_origin(name); #endif - error = dsl_sync_task(drc->drc_tofs, + return (dsl_sync_task(drc->drc_tofs, dmu_recv_end_check, dmu_recv_end_sync, drc, - dmu_recv_end_modified_blocks, ZFS_SPACE_CHECK_NORMAL); - - if (error != 0) - dmu_recv_cleanup_ds(drc); - return (error); + dmu_recv_end_modified_blocks, ZFS_SPACE_CHECK_NORMAL)); } static int dmu_recv_new_end(dmu_recv_cookie_t *drc) { + return (dsl_sync_task(drc->drc_tofs, + dmu_recv_end_check, dmu_recv_end_sync, drc, + dmu_recv_end_modified_blocks, ZFS_SPACE_CHECK_NORMAL)); +} + +int +dmu_recv_end(dmu_recv_cookie_t *drc, void *owner) +{ int error; - error = dsl_sync_task(drc->drc_tofs, - dmu_recv_end_check, dmu_recv_end_sync, drc, - dmu_recv_end_modified_blocks, ZFS_SPACE_CHECK_NORMAL); + drc->drc_owner = owner; + + if (drc->drc_newfs) + error = dmu_recv_new_end(drc); + else + error = dmu_recv_existing_end(drc); if (error != 0) { dmu_recv_cleanup_ds(drc); @@ -3350,17 +3359,6 @@ dmu_recv_new_end(dmu_recv_cookie_t *drc) return (error); } -int -dmu_recv_end(dmu_recv_cookie_t *drc, void *owner) -{ - drc->drc_owner = owner; - - if (drc->drc_newfs) - return (dmu_recv_new_end(drc)); - else - return (dmu_recv_existing_end(drc)); -} - /* * Return TRUE if this objset is currently being received into. */ |