Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 14 Oct 2016 07:36:32 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r307288 - stable/11/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Message-ID:  <201610140736.u9E7aWfh069463@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <mahrens@delphix.com>
  Reviewed by: Dan Kimmel <dan.kimmel@delphix.com>
  Author: Chris Williamson <chris.williamson@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.
  */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201610140736.u9E7aWfh069463>