summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndriy Gapon <[email protected]>2014-05-15 11:42:19 +0300
committerBrian Behlendorf <[email protected]>2014-10-02 16:52:02 -0700
commit057485504e3a4502c265813ab58e9ec8ffc2a3be (patch)
tree1747f3269b22e4d01864836e423f8f749420b148
parent7509a3d29963882a0c7fa9e703085c3a6a2ced65 (diff)
zfs send -p send properties only for snapshots that are actually sent
... as opposed to sending properties of all snapshots of the relevant filesystem. The previous behavior results in properties being set on all snapshots on the receiving side, which is quite slow. Behavior of zfs send -R is not changed. References: http://thread.gmane.org/gmane.comp.file-systems.openzfs.devel/346 Ported-by: Richard Yao <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Issue #2729 Issue #2210
-rw-r--r--lib/libzfs/libzfs_sendrecv.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/lib/libzfs/libzfs_sendrecv.c b/lib/libzfs/libzfs_sendrecv.c
index 3b4acc956..ef5747f64 100644
--- a/lib/libzfs/libzfs_sendrecv.c
+++ b/lib/libzfs/libzfs_sendrecv.c
@@ -577,6 +577,8 @@ typedef struct send_data {
const char *fromsnap;
const char *tosnap;
boolean_t recursive;
+ boolean_t seenfrom;
+ boolean_t seento;
/*
* The header nvlist is of the following format:
@@ -611,20 +613,39 @@ send_iterate_snap(zfs_handle_t *zhp, void *arg)
uint64_t guid = zhp->zfs_dmustats.dds_guid;
char *snapname;
nvlist_t *nv;
+ boolean_t isfromsnap, istosnap;
snapname = strrchr(zhp->zfs_name, '@')+1;
+ isfromsnap = (sd->fromsnap != NULL &&
+ strcmp(sd->fromsnap, snapname) == 0);
+ istosnap = (sd->tosnap != NULL && (strcmp(sd->tosnap, snapname) == 0));
- VERIFY(0 == nvlist_add_uint64(sd->parent_snaps, snapname, guid));
/*
* NB: if there is no fromsnap here (it's a newly created fs in
* an incremental replication), we will substitute the tosnap.
*/
- if ((sd->fromsnap && strcmp(snapname, sd->fromsnap) == 0) ||
- (sd->parent_fromsnap_guid == 0 && sd->tosnap &&
- strcmp(snapname, sd->tosnap) == 0)) {
+ if (isfromsnap || (sd->parent_fromsnap_guid == 0 && istosnap)) {
sd->parent_fromsnap_guid = guid;
}
+ if (!sd->recursive) {
+ if (!sd->seenfrom && isfromsnap) {
+ sd->seenfrom = B_TRUE;
+ zfs_close(zhp);
+ return (0);
+ }
+
+ if (sd->seento || !sd->seenfrom) {
+ zfs_close(zhp);
+ return (0);
+ }
+
+ if (istosnap)
+ sd->seento = B_TRUE;
+ }
+
+ VERIFY(0 == nvlist_add_uint64(sd->parent_snaps, snapname, guid));
+
VERIFY(0 == nvlist_alloc(&nv, NV_UNIQUE_NAME, 0));
send_iterate_prop(zhp, nv);
VERIFY(0 == nvlist_add_nvlist(sd->snapprops, snapname, nv));