aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@fusionio.com>2012-08-07 16:25:13 -0400
committerChris Mason <chris.mason@fusionio.com>2012-10-01 15:19:00 -0400
commit74dd17fbe3d65829e75d84f00a9525b2ace93998 (patch)
tree84c7ffead9b44d2b7d73601aed5be7a5637e804b /fs/btrfs/ctree.c
parent6d85ed05e16e7ff747025c8374f23d7d81c98540 (diff)
Btrfs: fix btrfs send for inline items and compression
The btrfs send code was assuming the offset of the file item into the extent translated to bytes on disk. If we're compressed, this isn't true, and so it was off into extents owned by other files. It was also improperly handling inline extents. This solves a crash where we may have gone past the end of the file extent item by not testing early enough for an inline extent. It also solves problems where we have a whole between the end of the inline item and the start of the full extent. Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r--fs/btrfs/ctree.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 6d183f60d63a..fcc8c21a6233 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -5073,6 +5073,7 @@ static void tree_move_down(struct btrfs_root *root,
5073 struct btrfs_path *path, 5073 struct btrfs_path *path,
5074 int *level, int root_level) 5074 int *level, int root_level)
5075{ 5075{
5076 BUG_ON(*level == 0);
5076 path->nodes[*level - 1] = read_node_slot(root, path->nodes[*level], 5077 path->nodes[*level - 1] = read_node_slot(root, path->nodes[*level],
5077 path->slots[*level]); 5078 path->slots[*level]);
5078 path->slots[*level - 1] = 0; 5079 path->slots[*level - 1] = 0;
@@ -5089,7 +5090,7 @@ static int tree_move_next_or_upnext(struct btrfs_root *root,
5089 5090
5090 path->slots[*level]++; 5091 path->slots[*level]++;
5091 5092
5092 while (path->slots[*level] == nritems) { 5093 while (path->slots[*level] >= nritems) {
5093 if (*level == root_level) 5094 if (*level == root_level)
5094 return -1; 5095 return -1;
5095 5096
@@ -5433,9 +5434,11 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
5433 goto out; 5434 goto out;
5434 advance_right = ADVANCE; 5435 advance_right = ADVANCE;
5435 } else { 5436 } else {
5437 WARN_ON(!extent_buffer_uptodate(left_path->nodes[0]));
5436 ret = tree_compare_item(left_root, left_path, 5438 ret = tree_compare_item(left_root, left_path,
5437 right_path, tmp_buf); 5439 right_path, tmp_buf);
5438 if (ret) { 5440 if (ret) {
5441 WARN_ON(!extent_buffer_uptodate(left_path->nodes[0]));
5439 ret = changed_cb(left_root, right_root, 5442 ret = changed_cb(left_root, right_root,
5440 left_path, right_path, 5443 left_path, right_path,
5441 &left_key, 5444 &left_key,