Btrfs: subvolumes
Signed-off-by: Chris Mason <chris.mason@oracle.com>
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 760fdc9..ff69162 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -301,6 +301,12 @@
int ret = 0;
printk("read_fs_root looking for %Lu %Lu %u\n", location->objectid, location->offset, location->flags);
+ root = radix_tree_lookup(&fs_info->fs_roots_radix,
+ (unsigned long)location->objectid);
+ if (root) {
+printk("found %p in cache\n", root);
+ return root;
+ }
root = kmalloc(sizeof(*root), GFP_NOFS);
if (!root) {
printk("failed1\n");
@@ -349,7 +355,8 @@
insert:
printk("inserting %p\n", root);
root->ref_cows = 1;
- ret = radix_tree_insert(&fs_info->fs_roots_radix, (unsigned long)root,
+ ret = radix_tree_insert(&fs_info->fs_roots_radix,
+ (unsigned long)root->root_key.objectid,
root);
if (ret) {
printk("radix_tree_insert gives us %d\n", ret);
@@ -460,6 +467,20 @@
return 0;
}
+static int free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root)
+{
+ radix_tree_delete(&fs_info->fs_roots_radix,
+ (unsigned long)root->root_key.objectid);
+ if (root->inode)
+ iput(root->inode);
+ if (root->node)
+ brelse(root->node);
+ if (root->commit_root)
+ brelse(root->commit_root);
+ kfree(root);
+ return 0;
+}
+
int del_fs_roots(struct btrfs_fs_info *fs_info)
{
int ret;
@@ -472,19 +493,8 @@
ARRAY_SIZE(gang));
if (!ret)
break;
- for (i = 0; i < ret; i++) {
- radix_tree_delete(&fs_info->fs_roots_radix,
- (unsigned long)gang[i]);
- if (gang[i]->inode)
- iput(gang[i]->inode);
- else
- printk("no inode for root %p\n", gang[i]);
- if (gang[i]->node)
- brelse(gang[i]->node);
- if (gang[i]->commit_root)
- brelse(gang[i]->commit_root);
- kfree(gang[i]);
- }
+ for (i = 0; i < ret; i++)
+ free_fs_root(fs_info, gang[i]);
}
return 0;
}