aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/send.c24
-rw-r--r--include/uapi/linux/btrfs.h20
2 files changed, 33 insertions, 11 deletions
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index c85e7c6b4598..e0c69a106c77 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4529,9 +4529,11 @@ static int send_subvol(struct send_ctx *sctx)
4529{ 4529{
4530 int ret; 4530 int ret;
4531 4531
4532 ret = send_header(sctx); 4532 if (!(sctx->flags & BTRFS_SEND_FLAG_OMIT_STREAM_HEADER)) {
4533 if (ret < 0) 4533 ret = send_header(sctx);
4534 goto out; 4534 if (ret < 0)
4535 goto out;
4536 }
4535 4537
4536 ret = send_subvol_begin(sctx); 4538 ret = send_subvol_begin(sctx);
4537 if (ret < 0) 4539 if (ret < 0)
@@ -4593,7 +4595,7 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_)
4593 goto out; 4595 goto out;
4594 } 4596 }
4595 4597
4596 if (arg->flags & ~BTRFS_SEND_FLAG_NO_FILE_DATA) { 4598 if (arg->flags & ~BTRFS_SEND_FLAG_MASK) {
4597 ret = -EINVAL; 4599 ret = -EINVAL;
4598 goto out; 4600 goto out;
4599 } 4601 }
@@ -4704,12 +4706,14 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_)
4704 if (ret < 0) 4706 if (ret < 0)
4705 goto out; 4707 goto out;
4706 4708
4707 ret = begin_cmd(sctx, BTRFS_SEND_C_END); 4709 if (!(sctx->flags & BTRFS_SEND_FLAG_OMIT_END_CMD)) {
4708 if (ret < 0) 4710 ret = begin_cmd(sctx, BTRFS_SEND_C_END);
4709 goto out; 4711 if (ret < 0)
4710 ret = send_cmd(sctx); 4712 goto out;
4711 if (ret < 0) 4713 ret = send_cmd(sctx);
4712 goto out; 4714 if (ret < 0)
4715 goto out;
4716 }
4713 4717
4714out: 4718out:
4715 kfree(arg); 4719 kfree(arg);
diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h
index fa3a5f9338fc..5e39e859a848 100644
--- a/include/uapi/linux/btrfs.h
+++ b/include/uapi/linux/btrfs.h
@@ -412,7 +412,25 @@ struct btrfs_ioctl_received_subvol_args {
412 * search of clone sources doesn't find an extent. UPDATE_EXTENT 412 * search of clone sources doesn't find an extent. UPDATE_EXTENT
413 * commands will be sent instead of WRITE commands. 413 * commands will be sent instead of WRITE commands.
414 */ 414 */
415#define BTRFS_SEND_FLAG_NO_FILE_DATA 0x1 415#define BTRFS_SEND_FLAG_NO_FILE_DATA 0x1
416
417/*
418 * Do not add the leading stream header. Used when multiple snapshots
419 * are sent back to back.
420 */
421#define BTRFS_SEND_FLAG_OMIT_STREAM_HEADER 0x2
422
423/*
424 * Omit the command at the end of the stream that indicated the end
425 * of the stream. This option is used when multiple snapshots are
426 * sent back to back.
427 */
428#define BTRFS_SEND_FLAG_OMIT_END_CMD 0x4
429
430#define BTRFS_SEND_FLAG_MASK \
431 (BTRFS_SEND_FLAG_NO_FILE_DATA | \
432 BTRFS_SEND_FLAG_OMIT_STREAM_HEADER | \
433 BTRFS_SEND_FLAG_OMIT_END_CMD)
416 434
417struct btrfs_ioctl_send_args { 435struct btrfs_ioctl_send_args {
418 __s64 send_fd; /* in */ 436 __s64 send_fd; /* in */