diff options
author | Chris Mason <chris.mason@fusionio.com> | 2012-08-07 16:25:13 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2012-10-01 15:19:00 -0400 |
commit | 74dd17fbe3d65829e75d84f00a9525b2ace93998 (patch) | |
tree | 84c7ffead9b44d2b7d73601aed5be7a5637e804b /fs/btrfs/ctree.c | |
parent | 6d85ed05e16e7ff747025c8374f23d7d81c98540 (diff) | |
download | linux-74dd17fbe3d65829e75d84f00a9525b2ace93998.tar.bz2 |
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.c | 5 |
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, struct btrfs_path *path, int *level, int root_level) { + BUG_ON(*level == 0); path->nodes[*level - 1] = read_node_slot(root, path->nodes[*level], path->slots[*level]); path->slots[*level - 1] = 0; @@ -5089,7 +5090,7 @@ static int tree_move_next_or_upnext(struct btrfs_root *root, path->slots[*level]++; - while (path->slots[*level] == nritems) { + while (path->slots[*level] >= nritems) { if (*level == root_level) return -1; @@ -5433,9 +5434,11 @@ int btrfs_compare_trees(struct btrfs_root *left_root, goto out; advance_right = ADVANCE; } else { + WARN_ON(!extent_buffer_uptodate(left_path->nodes[0])); ret = tree_compare_item(left_root, left_path, right_path, tmp_buf); if (ret) { + WARN_ON(!extent_buffer_uptodate(left_path->nodes[0])); ret = changed_cb(left_root, right_root, left_path, right_path, &left_key, |