Btrfs: add btrfs_next_old_leaf
authorJan Schmidt <list.btrfs@jan-o-sch.net>
Mon, 11 Jun 2012 06:29:29 +0000 (08:29 +0200)
committerJan Schmidt <list.btrfs@jan-o-sch.net>
Thu, 14 Jun 2012 16:52:09 +0000 (18:52 +0200)
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: Jan Schmidt <list.btrfs@jan-o-sch.net>
fs/btrfs/backref.c
fs/btrfs/ctree.c
fs/btrfs/ctree.h

index 579131de1b3b2fec513308efcfab0a0c8d138d78..8f7d1237b7a018db7c170f648df3b4d76c663023 100644 (file)
@@ -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,
                                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)
 {
        int ret;
@@ -212,7 +213,7 @@ add_parent:
         */
        while (1) {
                eie = NULL;
-               ret = btrfs_next_leaf(root, path);
+               ret = btrfs_next_old_leaf(root, path, time_seq);
                if (ret < 0)
                        return ret;
                if (ret)
@@ -297,7 +298,7 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info,
        if (level == 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);
 out:
        btrfs_free_path(path);
index 50d7c99ddce77fe1fb1469275c46af8058c9c6b4..cb76b2a1b9080f28220099d52b98e156afa07704 100644 (file)
@@ -5016,6 +5016,12 @@ next:
  * returns < 0 on io errors.
  */
 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 level;
@@ -5041,7 +5047,10 @@ again:
        path->keep_locks = 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;
 
        if (ret < 0)
index 0151ca1ac65715f38cd7ca49609effa879ea7d81..db15e9e7b91cf9b4a6c38367ca0bc08b0d86f795 100644 (file)
@@ -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_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)
 {
        ++p->slots[0];