summaryrefslogtreecommitdiff
path: root/fs/btrfs/root-tree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-03-13 16:47:54 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-03-13 16:47:54 -0400
commit3768f3689fc76ecea17414936dff7a02746a4355 (patch)
tree0494b12e3ba0be0a25f122922e205bc91d88957b /fs/btrfs/root-tree.c
parenteaee50e881b88766d9a781c54c4142456cf5e527 (diff)
downloadlwn-3768f3689fc76ecea17414936dff7a02746a4355.tar.gz
lwn-3768f3689fc76ecea17414936dff7a02746a4355.zip
Btrfs: Change the super to point to a tree of trees to enable persistent snapshots
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/root-tree.c')
-rw-r--r--fs/btrfs/root-tree.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
new file mode 100644
index 000000000000..0ab90cfea98f
--- /dev/null
+++ b/fs/btrfs/root-tree.c
@@ -0,0 +1,88 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "kerncompat.h"
+#include "radix-tree.h"
+#include "ctree.h"
+#include "disk-io.h"
+#include "print-tree.h"
+
+int btrfs_find_last_root(struct btrfs_root *root, u64 objectid,
+ struct btrfs_root_item *item, struct btrfs_key *key)
+{
+ struct btrfs_path path;
+ struct btrfs_key search_key;
+ struct btrfs_leaf *l;
+ int ret;
+ int slot;
+
+ search_key.objectid = objectid;
+ search_key.flags = (u32)-1;
+ search_key.offset = (u32)-1;
+
+ btrfs_init_path(&path);
+ ret = btrfs_search_slot(root, &search_key, &path, 0, 0);
+ if (ret < 0)
+ goto out;
+ BUG_ON(ret == 0);
+ l = &path.nodes[0]->leaf;
+ BUG_ON(path.slots[0] == 0);
+ slot = path.slots[0] - 1;
+ if (btrfs_key_objectid(&l->items[slot].key) != objectid) {
+ ret = 1;
+ goto out;
+ }
+ memcpy(item, l->data + btrfs_item_offset(l->items + slot),
+ sizeof(*item));
+ btrfs_disk_key_to_cpu(key, &l->items[slot].key);
+ btrfs_release_path(root, &path);
+ ret = 0;
+out:
+ return ret;
+}
+
+int btrfs_update_root(struct btrfs_root *root, struct btrfs_key *key,
+ struct btrfs_root_item *item)
+{
+ struct btrfs_path path;
+ struct btrfs_leaf *l;
+ int ret;
+ int slot;
+
+ btrfs_init_path(&path);
+ ret = btrfs_search_slot(root, key, &path, 0, 1);
+ if (ret < 0)
+ goto out;
+ BUG_ON(ret != 0);
+ l = &path.nodes[0]->leaf;
+ slot = path.slots[0];
+ memcpy(l->data + btrfs_item_offset(l->items + slot), item,
+ sizeof(*item));
+out:
+ btrfs_release_path(root, &path);
+ return ret;
+}
+
+int btrfs_insert_root(struct btrfs_root *root, struct btrfs_key *key,
+ struct btrfs_root_item *item)
+{
+ int ret;
+ ret = btrfs_insert_item(root, key, item, sizeof(*item));
+ BUG_ON(ret);
+ return ret;
+}
+
+int btrfs_del_root(struct btrfs_root *root, struct btrfs_key *key)
+{
+ struct btrfs_path path;
+ int ret;
+
+ btrfs_init_path(&path);
+ ret = btrfs_search_slot(root, key, &path, -1, 1);
+ if (ret < 0)
+ goto out;
+ BUG_ON(ret != 0);
+ ret = btrfs_del_item(root, &path);
+out:
+ btrfs_release_path(root, &path);
+ return ret;
+}