Author: mav
Date: Fri Oct 14 07:36:32 2016
New Revision: 307288
URL: https://svnweb.freebsd.org/changeset/base/307288

Log:
  MFC r305339: MFV r305336: 7247 zfs receive of deduplicated stream fails
  
  This resolves two 'zfs recv' issues. First, when receiving into an
  existing filesystem, a snapshot created during the receive process is
  not added to the guid->dataset map for the stream, resulting in failed
  lookups for deduped streams when a WRITE_BYREF record refers to a
  snapshot received earlier in the stream. Second, the newly created
  snapshot was also not set properly, referencing the snapshot before the
  new receiving dataset rather than the existing filesystem.
  
  Closes #159
  
  Reviewed by: Matthew Ahrens <mahr...@delphix.com>
  Reviewed by: Dan Kimmel <dan.kim...@delphix.com>
  Author: Chris Williamson <chris.william...@delphix.com>
  
  openzfs/openzfs@b09697c8c18be68abfe538de9809938239402ae8

Modified:
  stable/11/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
==============================================================================
--- stable/11/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c Fri Oct 
14 07:35:43 2016        (r307287)
+++ stable/11/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c Fri Oct 
14 07:36:32 2016        (r307288)
@@ -3113,6 +3113,9 @@ dmu_recv_end_sync(void *arg, dmu_tx_t *t
                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);
 
@@ -3148,8 +3151,9 @@ dmu_recv_end_sync(void *arg, dmu_tx_t *t
                        (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;
        /*
         * Release the hold from dmu_recv_begin.  This must be done before
         * we return to open context, so that when we free the dataset's dnode,
@@ -3191,8 +3195,6 @@ static int dmu_recv_end_modified_blocks 
 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
@@ -3203,23 +3205,30 @@ dmu_recv_existing_end(dmu_recv_cookie_t 
        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);
@@ -3231,17 +3240,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.
  */
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to