Skip to content

Commit

Permalink
FreeBSD PR kern/172259: Fixes zfs receive errors
Browse files Browse the repository at this point in the history
FreeBSD PR kern/172259: Fixes zfs receive errors caused by snapshot
replication being processed in a random order instead of creation
order.

Eliminates needless filesystem renames caused by removed parent
snapshots which subsequently causes many more errors.

PR:		kern/172259
Submitted by:	Steven Hartland
Reviewed by:	pjd (mentor)
Approved by:	pjd (mentor)
MFC after:	2 weeks

References:
  freebsd/freebsd-src@4995789

Porting notes:

Minor whitespace fixes were made to conform with style requirements:

lib/libzfs/libzfs_sendrecv.c: 2269: indent by spaces instead of tabs
lib/libzfs/libzfs_sendrecv.c: 2270: indent by spaces instead of tabs

Ported-by: Richard Yao <ryao@gentoo.org>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Issue openzfs#2729
  • Loading branch information
smh authored and ryao committed Nov 29, 2014
1 parent a7e675d commit 9356141
Showing 1 changed file with 29 additions and 2 deletions.
31 changes: 29 additions & 2 deletions lib/libzfs/libzfs_sendrecv.c
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,7 @@ send_iterate_fs(zfs_handle_t *zhp, void *arg)
sd->parent_fromsnap_guid = 0;
VERIFY(0 == nvlist_alloc(&sd->parent_snaps, NV_UNIQUE_NAME, 0));
VERIFY(0 == nvlist_alloc(&sd->snapprops, NV_UNIQUE_NAME, 0));
(void) zfs_iter_snapshots(zhp, B_FALSE, send_iterate_snap, sd);
(void) zfs_iter_snapshots_sorted(zhp, send_iterate_snap, sd);
VERIFY(0 == nvlist_add_nvlist(nvfs, "snaps", sd->parent_snaps));
VERIFY(0 == nvlist_add_nvlist(nvfs, "snapprops", sd->snapprops));
nvlist_free(sd->parent_snaps);
Expand Down Expand Up @@ -1942,11 +1942,12 @@ recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
recvflags_t *flags, nvlist_t *stream_nv, avl_tree_t *stream_avl,
nvlist_t *renamed)
{
nvlist_t *local_nv;
nvlist_t *local_nv, *deleted = NULL;
avl_tree_t *local_avl;
nvpair_t *fselem, *nextfselem;
char *fromsnap;
char newname[ZFS_MAXNAMELEN];
char guidname[32];
int error;
boolean_t needagain, progress, recursive;
char *s1, *s2;
Expand All @@ -1962,6 +1963,8 @@ recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
again:
needagain = progress = B_FALSE;

VERIFY(0 == nvlist_alloc(&deleted, NV_UNIQUE_NAME, 0));

if ((error = gather_nvlist(hdl, tofs, fromsnap, NULL,
recursive, &local_nv, &local_avl)) != 0)
return (error);
Expand Down Expand Up @@ -2076,6 +2079,8 @@ recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
needagain = B_TRUE;
else
progress = B_TRUE;
sprintf(guidname, "%lu", thisguid);
nvlist_add_boolean(deleted, guidname);
continue;
}

Expand Down Expand Up @@ -2131,6 +2136,8 @@ recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
needagain = B_TRUE;
else
progress = B_TRUE;
sprintf(guidname, "%lu", parent_fromsnap_guid);
nvlist_add_boolean(deleted, guidname);
continue;
}

Expand All @@ -2152,6 +2159,24 @@ recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
s1 = strrchr(fsname, '/');
s2 = strrchr(stream_fsname, '/');

/*
* Check if we're going to rename based on parent guid change
* and the current parent guid was also deleted. If it was then
* rename will fail and is likely unneeded, so avoid this and
* force an early retry to determine the new
* parent_fromsnap_guid.
*/
if (stream_parent_fromsnap_guid != 0 &&
parent_fromsnap_guid != 0 &&
stream_parent_fromsnap_guid != parent_fromsnap_guid) {
sprintf(guidname, "%lu", parent_fromsnap_guid);
if (nvlist_exists(deleted, guidname)) {
progress = B_TRUE;
needagain = B_TRUE;
goto doagain;
}
}

/*
* Check for rename. If the exact receive path is specified, it
* does not count as a rename, but we still need to check the
Expand Down Expand Up @@ -2206,8 +2231,10 @@ recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
}
}

doagain:
fsavl_destroy(local_avl);
nvlist_free(local_nv);
nvlist_free(deleted);

if (needagain && progress) {
/* do another pass to fix up temporary names */
Expand Down

0 comments on commit 9356141

Please sign in to comment.