summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQu Wenruo <quwenruo@cn.fujitsu.com>2016-06-01 16:29:43 +0800
committerDavid Sterba <dsterba@suse.com>2016-06-07 18:15:19 +0200
commitdb6f9251e509107755c7014e7358469409a0d5fe (patch)
tree61cdb6363f1f16339371c1c6b5a3ae7b6228d164
parent0c621b519d531600655f179f1ebf62c0dd95e478 (diff)
btrfs-progs: convert: Insert needed holes for superblock migration
New convert doesn't insert holes for superblock migration range. Unlike the old design, which only relocates 4K (superblock size) to other places. In the new design, to make sure convert can handle different page sizes and align chunks bytenr, we relocate the whole 64K range. And if there is only a 4K used block inside 64K superblock migration range, it will make converted the fs have discontiguous file extents. This patch will fix it by inserting needed holes to avoid such discontinuous error. Reported-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com> Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--btrfs-convert.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/btrfs-convert.c b/btrfs-convert.c
index 7cac304b..beec5d7d 100644
--- a/btrfs-convert.c
+++ b/btrfs-convert.c
@@ -1384,6 +1384,8 @@ static int migrate_one_reserved_range(struct btrfs_trans_handle *trans,
{
u64 cur_off = start;
u64 cur_len = len;
+ u64 hole_start = start;
+ u64 hole_len;
struct cache_extent *cache;
struct btrfs_key key;
struct extent_buffer *eb;
@@ -1435,9 +1437,23 @@ static int migrate_one_reserved_range(struct btrfs_trans_handle *trans,
ret = csum_disk_extent(trans, root, key.objectid,
key.offset);
+ /* Don't forget to insert hole */
+ hole_len = cur_off - hole_start;
+ if (hole_len) {
+ ret = btrfs_record_file_extent(trans, root, ino, inode,
+ hole_start, 0, hole_len);
+ if (ret < 0)
+ break;
+ }
+
cur_off += key.offset;
+ hole_start = cur_off;
cur_len = start + len - cur_off;
}
+ /* Last hole */
+ if (start + len - hole_start > 0)
+ ret = btrfs_record_file_extent(trans, root, ino, inode,
+ hole_start, 0, start + len - hole_start);
return ret;
}