Commit 4692cf58 authored by Jan Schmidt's avatar Jan Schmidt

Btrfs: new backref walking code

The old backref iteration code could only safely be used on commit roots.
Besides this limitation, it had bugs in finding the roots for these
references. This commit replaces large parts of it by btrfs_find_all_roots()
which a) really finds all roots and the correct roots, b) works correctly
under heavy file system load, c) considers delayed refs.
Signed-off-by: default avatarJan Schmidt <list.btrfs@jan-o-sch.net>
parent 8da6d581
This diff is collapsed.
...@@ -2976,7 +2976,7 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root, ...@@ -2976,7 +2976,7 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root,
{ {
int ret = 0; int ret = 0;
int size; int size;
u64 extent_offset; u64 extent_item_pos;
struct btrfs_ioctl_logical_ino_args *loi; struct btrfs_ioctl_logical_ino_args *loi;
struct btrfs_data_container *inodes = NULL; struct btrfs_data_container *inodes = NULL;
struct btrfs_path *path = NULL; struct btrfs_path *path = NULL;
...@@ -3007,15 +3007,17 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root, ...@@ -3007,15 +3007,17 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root,
} }
ret = extent_from_logical(root->fs_info, loi->logical, path, &key); ret = extent_from_logical(root->fs_info, loi->logical, path, &key);
btrfs_release_path(path);
if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK) if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK)
ret = -ENOENT; ret = -ENOENT;
if (ret < 0) if (ret < 0)
goto out; goto out;
extent_offset = loi->logical - key.objectid; extent_item_pos = loi->logical - key.objectid;
ret = iterate_extent_inodes(root->fs_info, path, key.objectid, ret = iterate_extent_inodes(root->fs_info, path, key.objectid,
extent_offset, build_ino_list, inodes); extent_item_pos, build_ino_list,
inodes);
if (ret < 0) if (ret < 0)
goto out; goto out;
......
...@@ -309,7 +309,7 @@ static void scrub_print_warning(const char *errstr, struct scrub_bio *sbio, ...@@ -309,7 +309,7 @@ static void scrub_print_warning(const char *errstr, struct scrub_bio *sbio,
u8 ref_level; u8 ref_level;
unsigned long ptr = 0; unsigned long ptr = 0;
const int bufsize = 4096; const int bufsize = 4096;
u64 extent_offset; u64 extent_item_pos;
path = btrfs_alloc_path(); path = btrfs_alloc_path();
...@@ -329,12 +329,13 @@ static void scrub_print_warning(const char *errstr, struct scrub_bio *sbio, ...@@ -329,12 +329,13 @@ static void scrub_print_warning(const char *errstr, struct scrub_bio *sbio,
if (ret < 0) if (ret < 0)
goto out; goto out;
extent_offset = swarn.logical - found_key.objectid; extent_item_pos = swarn.logical - found_key.objectid;
swarn.extent_item_size = found_key.offset; swarn.extent_item_size = found_key.offset;
eb = path->nodes[0]; eb = path->nodes[0];
ei = btrfs_item_ptr(eb, path->slots[0], struct btrfs_extent_item); ei = btrfs_item_ptr(eb, path->slots[0], struct btrfs_extent_item);
item_size = btrfs_item_size_nr(eb, path->slots[0]); item_size = btrfs_item_size_nr(eb, path->slots[0]);
btrfs_release_path(path);
if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK) { if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
do { do {
...@@ -351,7 +352,7 @@ static void scrub_print_warning(const char *errstr, struct scrub_bio *sbio, ...@@ -351,7 +352,7 @@ static void scrub_print_warning(const char *errstr, struct scrub_bio *sbio,
} else { } else {
swarn.path = path; swarn.path = path;
iterate_extent_inodes(fs_info, path, found_key.objectid, iterate_extent_inodes(fs_info, path, found_key.objectid,
extent_offset, extent_item_pos,
scrub_print_warning_inode, &swarn); scrub_print_warning_inode, &swarn);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment