summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ioctl.h7
-rw-r--r--send-stream.c6
-rw-r--r--send-stream.h1
-rw-r--r--send.h1
4 files changed, 15 insertions, 0 deletions
diff --git a/ioctl.h b/ioctl.h
index d57afb2d..8c32a2a2 100644
--- a/ioctl.h
+++ b/ioctl.h
@@ -364,6 +364,13 @@ struct btrfs_ioctl_received_subvol_args {
__u64 reserved[16]; /* in */
};
+/*
+ * Caller doesn't want file data in the send stream, even if the
+ * search of clone sources doesn't find an extent. UPDATE_EXTENT
+ * commands will be sent instead of WRITE commands.
+ */
+#define BTRFS_SEND_FLAG_NO_FILE_DATA 0x1
+
struct btrfs_ioctl_send_args {
__s64 send_fd; /* in */
__u64 clone_sources_count; /* in */
diff --git a/send-stream.c b/send-stream.c
index 55fa7284..a3628e45 100644
--- a/send-stream.c
+++ b/send-stream.c
@@ -418,6 +418,12 @@ static int read_and_process_cmd(struct btrfs_send_stream *s)
TLV_GET_TIMESPEC(s, BTRFS_SEND_A_CTIME, &ct);
ret = s->ops->utimes(path, &at, &mt, &ct, s->user);
break;
+ case BTRFS_SEND_C_UPDATE_EXTENT:
+ TLV_GET_STRING(s, BTRFS_SEND_A_PATH, &path);
+ TLV_GET_U64(s, BTRFS_SEND_A_FILE_OFFSET, &offset);
+ TLV_GET_U64(s, BTRFS_SEND_A_SIZE, &tmp);
+ ret = s->ops->update_extent(path, offset, tmp, s->user);
+ break;
case BTRFS_SEND_C_END:
ret = 1;
break;
diff --git a/send-stream.h b/send-stream.h
index b69b7f16..9a17e32d 100644
--- a/send-stream.h
+++ b/send-stream.h
@@ -49,6 +49,7 @@ struct btrfs_send_ops {
int (*utimes)(const char *path, struct timespec *at,
struct timespec *mt, struct timespec *ct,
void *user);
+ int (*update_extent)(const char *path, u64 offset, u64 len, void *user);
};
int btrfs_read_and_process_send_stream(int fd,
diff --git a/send.h b/send.h
index 9934e948..48d425ae 100644
--- a/send.h
+++ b/send.h
@@ -86,6 +86,7 @@ enum btrfs_send_cmd {
BTRFS_SEND_C_UTIMES,
BTRFS_SEND_C_END,
+ BTRFS_SEND_C_UPDATE_EXTENT,
__BTRFS_SEND_C_MAX,
};
#define BTRFS_SEND_C_MAX (__BTRFS_SEND_C_MAX - 1)