Linux-BTRFS Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH] Btrfs: send, allow clone operations within the same file
@ 2019-10-30 12:23 fdmanana
  2019-10-31 12:55 ` Josef Bacik
  2019-11-01 14:28 ` David Sterba
  0 siblings, 2 replies; 3+ messages in thread
From: fdmanana @ 2019-10-30 12:23 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

For send we currently skip clone operations when the source and destination
files are the same. This is so because clone didn't support this case in
its early days, but support for it was added back in May 2013 by commit
a96fbc72884fcb ("Btrfs: allow file data clone within a file"). This change
adds support for it.

Example:

  $ mkfs.btrfs -f /dev/sdd
  $ mount /dev/sdd /mnt/sdd

  $ xfs_io -f -c "pwrite -S 0xab -b 64K 0 64K" /mnt/sdd/foobar
  $ xfs_io -c "reflink /mnt/sdd/foobar 0 64K 64K" /mnt/sdd/foobar

  $ btrfs subvolume snapshot -r /mnt/sdd /mnt/sdd/snap

  $ mkfs.btrfs -f /dev/sde
  $ mount /dev/sde /mnt/sde

  $ btrfs send /mnt/sdd/snap | btrfs receive /mnt/sde

Without this change file foobar at the destination has a single 128Kb
extent:

  $ filefrag -v /mnt/sde/snap/foobar
  Filesystem type is: 9123683e
  File size of /mnt/sde/snap/foobar is 131072 (32 blocks of 4096 bytes)
   ext:     logical_offset:        physical_offset: length:   expected: flags:
     0:        0..      31:          0..        31:     32:             last,unknown_loc,delalloc,eof
  /mnt/sde/snap/foobar: 1 extent found

With this we get a single 64Kb extent that is shared at file offsets 0
and 64K, just like in the source filesystem:

  $ filefrag -v /mnt/sde/snap/foobar
  Filesystem type is: 9123683e
  File size of /mnt/sde/snap/foobar is 131072 (32 blocks of 4096 bytes)
   ext:     logical_offset:        physical_offset: length:   expected: flags:
     0:        0..      15:       3328..      3343:     16:             shared
     1:       16..      31:       3328..      3343:     16:       3344: last,shared,eof
  /mnt/sde/snap/foobar: 2 extents found

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 518ec1265a0c..1624df5e6aa6 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -1256,12 +1256,20 @@ static int __iterate_backrefs(u64 ino, u64 offset, u64 root, void *ctx_)
 	 */
 	if (found->root == bctx->sctx->send_root) {
 		/*
-		 * TODO for the moment we don't accept clones from the inode
-		 * that is currently send. We may change this when
-		 * BTRFS_IOC_CLONE_RANGE supports cloning from and to the same
-		 * file.
+		 * If the source inode was not yet processed we can't issue a
+		 * clone operation, as the source extent does not exist yet at
+		 * the destination of the stream.
 		 */
-		if (ino >= bctx->cur_objectid)
+		if (ino > bctx->cur_objectid)
+			return 0;
+		/*
+		 * We clone from the inode currently being sent as long as the
+		 * source extent is already processed, otherwise we could try
+		 * to clone from an extent that does not exist yet at the
+		 * destination of the stream.
+		 */
+		if (ino == bctx->cur_objectid &&
+		    offset >= bctx->sctx->cur_inode_next_write_offset)
 			return 0;
 	}
 
-- 
2.11.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Btrfs: send, allow clone operations within the same file
  2019-10-30 12:23 [PATCH] Btrfs: send, allow clone operations within the same file fdmanana
@ 2019-10-31 12:55 ` Josef Bacik
  2019-11-01 14:28 ` David Sterba
  1 sibling, 0 replies; 3+ messages in thread
From: Josef Bacik @ 2019-10-31 12:55 UTC (permalink / raw)
  To: fdmanana; +Cc: linux-btrfs

On Wed, Oct 30, 2019 at 12:23:11PM +0000, fdmanana@kernel.org wrote:
> From: Filipe Manana <fdmanana@suse.com>
> 
> For send we currently skip clone operations when the source and destination
> files are the same. This is so because clone didn't support this case in
> its early days, but support for it was added back in May 2013 by commit
> a96fbc72884fcb ("Btrfs: allow file data clone within a file"). This change
> adds support for it.
> 
> Example:
> 
>   $ mkfs.btrfs -f /dev/sdd
>   $ mount /dev/sdd /mnt/sdd
> 
>   $ xfs_io -f -c "pwrite -S 0xab -b 64K 0 64K" /mnt/sdd/foobar
>   $ xfs_io -c "reflink /mnt/sdd/foobar 0 64K 64K" /mnt/sdd/foobar
> 
>   $ btrfs subvolume snapshot -r /mnt/sdd /mnt/sdd/snap
> 
>   $ mkfs.btrfs -f /dev/sde
>   $ mount /dev/sde /mnt/sde
> 
>   $ btrfs send /mnt/sdd/snap | btrfs receive /mnt/sde
> 
> Without this change file foobar at the destination has a single 128Kb
> extent:
> 
>   $ filefrag -v /mnt/sde/snap/foobar
>   Filesystem type is: 9123683e
>   File size of /mnt/sde/snap/foobar is 131072 (32 blocks of 4096 bytes)
>    ext:     logical_offset:        physical_offset: length:   expected: flags:
>      0:        0..      31:          0..        31:     32:             last,unknown_loc,delalloc,eof
>   /mnt/sde/snap/foobar: 1 extent found
> 
> With this we get a single 64Kb extent that is shared at file offsets 0
> and 64K, just like in the source filesystem:
> 
>   $ filefrag -v /mnt/sde/snap/foobar
>   Filesystem type is: 9123683e
>   File size of /mnt/sde/snap/foobar is 131072 (32 blocks of 4096 bytes)
>    ext:     logical_offset:        physical_offset: length:   expected: flags:
>      0:        0..      15:       3328..      3343:     16:             shared
>      1:       16..      31:       3328..      3343:     16:       3344: last,shared,eof
>   /mnt/sde/snap/foobar: 2 extents found
> 
> Signed-off-by: Filipe Manana <fdmanana@suse.com>

Reviewed-by: Josef Bacik <josef@toxicpanda.com>

Thanks,

Josef

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Btrfs: send, allow clone operations within the same file
  2019-10-30 12:23 [PATCH] Btrfs: send, allow clone operations within the same file fdmanana
  2019-10-31 12:55 ` Josef Bacik
@ 2019-11-01 14:28 ` David Sterba
  1 sibling, 0 replies; 3+ messages in thread
From: David Sterba @ 2019-11-01 14:28 UTC (permalink / raw)
  To: fdmanana; +Cc: linux-btrfs

On Wed, Oct 30, 2019 at 12:23:11PM +0000, fdmanana@kernel.org wrote:
> From: Filipe Manana <fdmanana@suse.com>
> 
> For send we currently skip clone operations when the source and destination
> files are the same. This is so because clone didn't support this case in
> its early days, but support for it was added back in May 2013 by commit
> a96fbc72884fcb ("Btrfs: allow file data clone within a file"). This change
> adds support for it.
> 
> Example:
> 
>   $ mkfs.btrfs -f /dev/sdd
>   $ mount /dev/sdd /mnt/sdd
> 
>   $ xfs_io -f -c "pwrite -S 0xab -b 64K 0 64K" /mnt/sdd/foobar
>   $ xfs_io -c "reflink /mnt/sdd/foobar 0 64K 64K" /mnt/sdd/foobar
> 
>   $ btrfs subvolume snapshot -r /mnt/sdd /mnt/sdd/snap
> 
>   $ mkfs.btrfs -f /dev/sde
>   $ mount /dev/sde /mnt/sde
> 
>   $ btrfs send /mnt/sdd/snap | btrfs receive /mnt/sde
> 
> Without this change file foobar at the destination has a single 128Kb
> extent:
> 
>   $ filefrag -v /mnt/sde/snap/foobar
>   Filesystem type is: 9123683e
>   File size of /mnt/sde/snap/foobar is 131072 (32 blocks of 4096 bytes)
>    ext:     logical_offset:        physical_offset: length:   expected: flags:
>      0:        0..      31:          0..        31:     32:             last,unknown_loc,delalloc,eof
>   /mnt/sde/snap/foobar: 1 extent found
> 
> With this we get a single 64Kb extent that is shared at file offsets 0
> and 64K, just like in the source filesystem:
> 
>   $ filefrag -v /mnt/sde/snap/foobar
>   Filesystem type is: 9123683e
>   File size of /mnt/sde/snap/foobar is 131072 (32 blocks of 4096 bytes)
>    ext:     logical_offset:        physical_offset: length:   expected: flags:
>      0:        0..      15:       3328..      3343:     16:             shared
>      1:       16..      31:       3328..      3343:     16:       3344: last,shared,eof
>   /mnt/sde/snap/foobar: 2 extents found
> 
> Signed-off-by: Filipe Manana <fdmanana@suse.com>

Added to misc-next, thanks.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, back to index

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-30 12:23 [PATCH] Btrfs: send, allow clone operations within the same file fdmanana
2019-10-31 12:55 ` Josef Bacik
2019-11-01 14:28 ` David Sterba

Linux-BTRFS Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-btrfs/0 linux-btrfs/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-btrfs linux-btrfs/ https://lore.kernel.org/linux-btrfs \
		linux-btrfs@vger.kernel.org
	public-inbox-index linux-btrfs

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-btrfs


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git