linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Btrfs: fix clone to deal with holes when NO_HOLES feature is enabled
@ 2014-05-31  1:16 Filipe David Borba Manana
  2014-05-31 14:12 ` [PATCH v2] " Filipe David Borba Manana
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Filipe David Borba Manana @ 2014-05-31  1:16 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Filipe David Borba Manana

If the NO_HOLES feature is enabled holes don't have file extent items in
the btree that represent them anymore. This made the clone operation
ignore the gaps that exist between consecutive file extent items and
therefore not create the holes at the destination.

A test case for xfstests follows.

Signed-off-by: Filipe David Borba Manana <fdmanana@gmail.com>
---
 fs/btrfs/ioctl.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index ecf56af..bf34b7a 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -3009,6 +3009,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
 	int no_quota;
 	u64 len = olen_aligned;
 	u64 last_disko = 0;
+	u64 last_dest_end = (u64)-1;
 
 	ret = -ENOMEM;
 	buf = vmalloc(btrfs_level_size(root, 0));
@@ -3077,6 +3078,7 @@ process_slot:
 			u64 datao = 0, datal = 0;
 			u8 comp;
 			u64 endoff;
+			u64 drop_start;
 
 			extent = btrfs_item_ptr(leaf, slot,
 						struct btrfs_file_extent_item);
@@ -3125,6 +3127,16 @@ process_slot:
 				new_key.offset = destoff;
 
 			/*
+			 * Deal with a hole that doesn't have an extent item
+			 * that represents it (NO_HOLES feature enabled).
+			 */
+			if (last_dest_end != (u64)-1 &&
+			    new_key.offset != last_dest_end)
+				drop_start = last_dest_end;
+			else
+				drop_start = new_key.offset;
+
+			/*
 			 * 1 - adjusting old extent (we may have to split it)
 			 * 1 - add new extent
 			 * 1 - inode update
@@ -3153,7 +3165,7 @@ process_slot:
 				}
 
 				ret = btrfs_drop_extents(trans, root, inode,
-							 new_key.offset,
+							 drop_start,
 							 new_key.offset + datal,
 							 1);
 				if (ret) {
@@ -3254,7 +3266,7 @@ process_slot:
 				aligned_end = ALIGN(new_key.offset + datal,
 						    root->sectorsize);
 				ret = btrfs_drop_extents(trans, root, inode,
-							 new_key.offset,
+							 drop_start,
 							 aligned_end,
 							 1);
 				if (ret) {
@@ -3301,6 +3313,7 @@ process_slot:
 			 * but shouldn't round up the file size
 			 */
 			endoff = new_key.offset + datal;
+			last_dest_end = endoff;
 			if (endoff > destoff+olen)
 				endoff = destoff+olen;
 			if (endoff > inode->i_size)
-- 
1.9.1


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

end of thread, other threads:[~2014-06-04  8:25 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-31  1:16 [PATCH] Btrfs: fix clone to deal with holes when NO_HOLES feature is enabled Filipe David Borba Manana
2014-05-31 14:12 ` [PATCH v2] " Filipe David Borba Manana
2014-05-31 16:20 ` [PATCH v3] " Filipe David Borba Manana
2014-06-01  0:50 ` [PATCH v4] " Filipe David Borba Manana
2014-06-04  8:25   ` Liu Bo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).