summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/root-tree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-05-08 19:26:18 +0200
committerChris Mason <chris.mason@oracle.com>2008-09-25 17:04:02 +0200
commitbf4ef67924d87b0addb32f084e83a9283496350e (patch)
tree2935d0395028d878e57df73e5fbd2182abc16c41 /fs/btrfs/root-tree.c
parentBtrfs: Add support for online device removal (diff)
downloadlinux-bf4ef67924d87b0addb32f084e83a9283496350e.tar.xz
linux-bf4ef67924d87b0addb32f084e83a9283496350e.zip
Btrfs: Properly find the root for snapshotted blocks during chunk relocation
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/root-tree.c')
-rw-r--r--fs/btrfs/root-tree.c46
1 files changed, 45 insertions, 1 deletions
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
index 08f19ec88092..8bf21ba0a43b 100644
--- a/fs/btrfs/root-tree.c
+++ b/fs/btrfs/root-tree.c
@@ -21,6 +21,51 @@
#include "disk-io.h"
#include "print-tree.h"
+/*
+ * returns 0 on finding something, 1 if no more roots are there
+ * and < 0 on error
+ */
+int btrfs_search_root(struct btrfs_root *root, u64 search_start,
+ u64 *found_objectid)
+{
+ struct btrfs_path *path;
+ struct btrfs_key search_key;
+ int ret;
+
+ root = root->fs_info->tree_root;
+ search_key.objectid = search_start;
+ search_key.type = (u8)-1;
+ search_key.offset = (u64)-1;
+
+ path = btrfs_alloc_path();
+ BUG_ON(!path);
+again:
+ ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
+ if (ret < 0)
+ goto out;
+ if (ret == 0) {
+ ret = 1;
+ goto out;
+ }
+ if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
+ ret = btrfs_next_leaf(root, path);
+ if (ret)
+ goto out;
+ }
+ btrfs_item_key_to_cpu(path->nodes[0], &search_key, path->slots[0]);
+ if (search_key.type != BTRFS_ROOT_ITEM_KEY) {
+ search_key.offset++;
+ btrfs_release_path(root, path);
+ goto again;
+ }
+ ret = 0;
+ *found_objectid = search_key.objectid;
+
+out:
+ btrfs_free_path(path);
+ return ret;
+}
+
int btrfs_find_last_root(struct btrfs_root *root, u64 objectid,
struct btrfs_root_item *item, struct btrfs_key *key)
{
@@ -55,7 +100,6 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid,
memcpy(key, &found_key, sizeof(found_key));
ret = 0;
out:
- btrfs_release_path(root, path);
btrfs_free_path(path);
return ret;
}