diff options
author | Alan Somers <[email protected]> | 2020-10-02 18:47:09 -0600 |
---|---|---|
committer | GitHub <[email protected]> | 2020-10-02 17:47:09 -0700 |
commit | a132c2b413de78981cd958974ad95d3f9cec9dea (patch) | |
tree | 458aeeea709d1e1ffd7398d3717146ad69c5a867 /lib | |
parent | 4d55ea811d4f5b832398f4e3b24c4da365956d62 (diff) |
Fix EIO after resuming receive of new dataset over an existing one
When resuming an interrupted ZFS send stream that creates a new dataset
with the same name as an existing dataset, if the existing dataset is
accessed after the failed receive, then after the subsequent successful
receive it will return EIO. This happens because nothing mounts the new
dataset, leaving the old, no longer valid dataset still mounted.
This commit fixes zfs receive to always unmount and remount the
destination, regardless of whether the stream is a new stream or a
resumed stream.
Sponsored by: Axcient
Reviewed-by: Brian Behlendorf <[email protected]>
Reviewed-by: Ryan Moeller <[email protected]>
Signed-off-by: Alan Somers <[email protected]>
External-issue: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=249579
Closes #10995
Closes #10999
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libzfs/libzfs_sendrecv.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/lib/libzfs/libzfs_sendrecv.c b/lib/libzfs/libzfs_sendrecv.c index b46a4f122..eb300f97c 100644 --- a/lib/libzfs/libzfs_sendrecv.c +++ b/lib/libzfs/libzfs_sendrecv.c @@ -4108,7 +4108,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, char errbuf[1024]; const char *chopprefix; boolean_t newfs = B_FALSE; - boolean_t stream_wantsnewfs; + boolean_t stream_wantsnewfs, stream_resumingnewfs; boolean_t newprops = B_FALSE; uint64_t read_bytes = 0; uint64_t errflags = 0; @@ -4329,6 +4329,8 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, DMU_BACKUP_FEATURE_EMBED_DATA; stream_wantsnewfs = (drrb->drr_fromguid == 0 || (drrb->drr_flags & DRR_FLAG_CLONE) || originsnap) && !resuming; + stream_resumingnewfs = (drrb->drr_fromguid == 0 || + (drrb->drr_flags & DRR_FLAG_CLONE) || originsnap) && resuming; if (stream_wantsnewfs) { /* @@ -4496,7 +4498,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, } if (!flags->dryrun && zhp->zfs_type == ZFS_TYPE_FILESYSTEM && - stream_wantsnewfs) { + (stream_wantsnewfs || stream_resumingnewfs)) { /* We can't do online recv in this case */ clp = changelist_gather(zhp, ZFS_PROP_NAME, 0, flags->forceunmount ? MS_FORCE : 0); |