return 0;
 }
 
+/*
+ * Execute search and call btrfs_previous_item to traverse backwards if the item
+ * was not found.
+ *
+ * Return 0 if found, 1 if not found and < 0 if error.
+ */
+int btrfs_search_backwards(struct btrfs_root *root, struct btrfs_key *key,
+                          struct btrfs_path *path)
+{
+       int ret;
+
+       ret = btrfs_search_slot(NULL, root, key, path, 0, 0);
+       if (ret > 0)
+               ret = btrfs_previous_item(root, path, key->objectid, key->type);
+
+       if (ret == 0)
+               btrfs_item_key_to_cpu(path->nodes[0], key, path->slots[0]);
+
+       return ret;
+}
+
 /*
  * adjust the pointers going up the tree, starting at level
  * making sure the right key of each node is points to 'key'.
 
 int btrfs_prev_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);
+
+int btrfs_search_backwards(struct btrfs_root *root, struct btrfs_key *key,
+                          struct btrfs_path *path);
+
 static inline int btrfs_next_old_item(struct btrfs_root *root,
                                      struct btrfs_path *p, u64 time_seq)
 {
 
        key.offset = (u64)-1;
 
        while (1) {
-               ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+               ret = btrfs_search_backwards(root, &key, path);
                if (ret < 0)
                        goto out;
                else if (ret > 0) {
-                       ret = btrfs_previous_item(root, path, dirid,
-                                                 BTRFS_INODE_REF_KEY);
-                       if (ret < 0)
-                               goto out;
-                       else if (ret > 0) {
-                               ret = -ENOENT;
-                               goto out;
-                       }
+                       ret = -ENOENT;
+                       goto out;
                }
 
                l = path->nodes[0];
                slot = path->slots[0];
-               btrfs_item_key_to_cpu(l, &key, slot);
 
                iref = btrfs_item_ptr(l, slot, struct btrfs_inode_ref);
                len = btrfs_inode_ref_name_len(l, iref);
                key.type = BTRFS_INODE_REF_KEY;
                key.offset = (u64)-1;
                while (1) {
-                       ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
-                       if (ret < 0) {
+                       ret = btrfs_search_backwards(root, &key, path);
+                       if (ret < 0)
+                               goto out_put;
+                       else if (ret > 0) {
+                               ret = -ENOENT;
                                goto out_put;
-                       } else if (ret > 0) {
-                               ret = btrfs_previous_item(root, path, dirid,
-                                                         BTRFS_INODE_REF_KEY);
-                               if (ret < 0) {
-                                       goto out_put;
-                               } else if (ret > 0) {
-                                       ret = -ENOENT;
-                                       goto out_put;
-                               }
                        }
 
                        leaf = path->nodes[0];
                        slot = path->slots[0];
-                       btrfs_item_key_to_cpu(leaf, &key, slot);
 
                        iref = btrfs_item_ptr(leaf, slot, struct btrfs_inode_ref);
                        len = btrfs_inode_ref_name_len(leaf, iref);
 
                key.type = BTRFS_ROOT_BACKREF_KEY;
                key.offset = (u64)-1;
 
-               ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+               ret = btrfs_search_backwards(root, &key, path);
                if (ret < 0) {
                        goto err;
                } else if (ret > 0) {
-                       ret = btrfs_previous_item(root, path, subvol_objectid,
-                                                 BTRFS_ROOT_BACKREF_KEY);
-                       if (ret < 0) {
-                               goto err;
-                       } else if (ret > 0) {
-                               ret = -ENOENT;
-                               goto err;
-                       }
+                       ret = -ENOENT;
+                       goto err;
                }
 
-               btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
                subvol_objectid = key.offset;
 
                root_ref = btrfs_item_ptr(path->nodes[0], path->slots[0],
                        key.type = BTRFS_INODE_REF_KEY;
                        key.offset = (u64)-1;
 
-                       ret = btrfs_search_slot(NULL, fs_root, &key, path, 0, 0);
+                       ret = btrfs_search_backwards(fs_root, &key, path);
                        if (ret < 0) {
                                goto err;
                        } else if (ret > 0) {
-                               ret = btrfs_previous_item(fs_root, path, dirid,
-                                                         BTRFS_INODE_REF_KEY);
-                               if (ret < 0) {
-                                       goto err;
-                               } else if (ret > 0) {
-                                       ret = -ENOENT;
-                                       goto err;
-                               }
+                               ret = -ENOENT;
+                               goto err;
                        }
 
-                       btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
                        dirid = key.offset;
 
                        inode_ref = btrfs_item_ptr(path->nodes[0],
 
        key.offset = search_start;
        key.type = BTRFS_DEV_EXTENT_KEY;
 
-       ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+       ret = btrfs_search_backwards(root, &key, path);
        if (ret < 0)
                goto out;
-       if (ret > 0) {
-               ret = btrfs_previous_item(root, path, key.objectid, key.type);
-               if (ret < 0)
-                       goto out;
-       }
 
        while (1) {
                l = path->nodes[0];