提交 3d7806ec 编写于 作者: J Jan Schmidt

Btrfs: add btrfs_next_old_leaf

To make sense of the tree mod log, the backref walker not only needs
btrfs_search_old_slot, but it also called btrfs_next_leaf, which in turn was
calling btrfs_search_slot. This obviously didn't give the correct result.

This commit adds btrfs_next_old_leaf, a drop-in replacement for
btrfs_next_leaf with a time_seq parameter. If it is zero, it behaves exactly
like btrfs_next_leaf. If it is non-zero, it will use btrfs_search_old_slot
with this time_seq parameter.
Signed-off-by: NJan Schmidt <list.btrfs@jan-o-sch.net>
上级 a95236d9
...@@ -179,7 +179,8 @@ static int __add_prelim_ref(struct list_head *head, u64 root_id, ...@@ -179,7 +179,8 @@ static int __add_prelim_ref(struct list_head *head, u64 root_id,
static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
struct ulist *parents, int level, struct ulist *parents, int level,
struct btrfs_key *key, u64 wanted_disk_byte, struct btrfs_key *key, u64 time_seq,
u64 wanted_disk_byte,
const u64 *extent_item_pos) const u64 *extent_item_pos)
{ {
int ret; int ret;
...@@ -212,7 +213,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, ...@@ -212,7 +213,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
*/ */
while (1) { while (1) {
eie = NULL; eie = NULL;
ret = btrfs_next_leaf(root, path); ret = btrfs_next_old_leaf(root, path, time_seq);
if (ret < 0) if (ret < 0)
return ret; return ret;
if (ret) if (ret)
...@@ -297,7 +298,7 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, ...@@ -297,7 +298,7 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info,
if (level == 0) if (level == 0)
btrfs_item_key_to_cpu(eb, &key, path->slots[0]); btrfs_item_key_to_cpu(eb, &key, path->slots[0]);
ret = add_all_parents(root, path, parents, level, &key, ret = add_all_parents(root, path, parents, level, &key, time_seq,
ref->wanted_disk_byte, extent_item_pos); ref->wanted_disk_byte, extent_item_pos);
out: out:
btrfs_free_path(path); btrfs_free_path(path);
......
...@@ -5016,6 +5016,12 @@ int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path, ...@@ -5016,6 +5016,12 @@ int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path,
* returns < 0 on io errors. * returns < 0 on io errors.
*/ */
int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
{
return btrfs_next_old_leaf(root, path, 0);
}
int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path,
u64 time_seq)
{ {
int slot; int slot;
int level; int level;
...@@ -5041,7 +5047,10 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) ...@@ -5041,7 +5047,10 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
path->keep_locks = 1; path->keep_locks = 1;
path->leave_spinning = 1; path->leave_spinning = 1;
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); if (time_seq)
ret = btrfs_search_old_slot(root, &key, path, time_seq);
else
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
path->keep_locks = 0; path->keep_locks = 0;
if (ret < 0) if (ret < 0)
......
...@@ -2753,6 +2753,8 @@ static inline int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, ...@@ -2753,6 +2753,8 @@ static inline int btrfs_insert_empty_item(struct btrfs_trans_handle *trans,
} }
int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path); int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path);
int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path,
u64 time_seq);
static inline int btrfs_next_item(struct btrfs_root *root, struct btrfs_path *p) static inline int btrfs_next_item(struct btrfs_root *root, struct btrfs_path *p)
{ {
++p->slots[0]; ++p->slots[0];
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册