Btrfs: Change the super to point to a tree of trees to enable persistent snapshots
Signed-off-by: Chris Mason <chris.mason@oracle.com>
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
new file mode 100644
index 0000000..0ab90cf
--- /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;
+}