aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-04-05 13:35:25 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-04-05 13:35:25 -0400
commit5be6f7f174146d91039a27ebb2f1b4ac599172b3 (patch)
tree2933d1e9e5cb50c4ca93f6e8c7e133d65a614461 /fs
parent7fcde0e3298c00ee18e2ae7f01c67f99133ef7be (diff)
Btrfs: dirindex optimizations
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/ctree.h3
-rw-r--r--fs/btrfs/dir-item.c5
-rw-r--r--fs/btrfs/disk-io.c6
-rw-r--r--fs/btrfs/inode-map.c48
-rw-r--r--fs/btrfs/super.c5
5 files changed, 50 insertions, 17 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 794f7e4f1c07..6d40758b893f 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -239,6 +239,7 @@ struct btrfs_fs_info {
239 struct radix_tree_root pinned_radix; 239 struct radix_tree_root pinned_radix;
240 u64 last_inode_alloc; 240 u64 last_inode_alloc;
241 u64 generation; 241 u64 generation;
242 u64 highest_inode;
242 struct btrfs_transaction *running_transaction; 243 struct btrfs_transaction *running_transaction;
243 struct btrfs_super_block *disk_super; 244 struct btrfs_super_block *disk_super;
244 struct buffer_head *sb_buffer; 245 struct buffer_head *sb_buffer;
@@ -970,6 +971,8 @@ int btrfs_insert_inode_map(struct btrfs_trans_handle *trans,
970int btrfs_lookup_inode_map(struct btrfs_trans_handle *trans, 971int btrfs_lookup_inode_map(struct btrfs_trans_handle *trans,
971 struct btrfs_root *root, struct btrfs_path *path, 972 struct btrfs_root *root, struct btrfs_path *path,
972 u64 objectid, int mod); 973 u64 objectid, int mod);
974int btrfs_find_highest_inode(struct btrfs_root *fs_root, u64 *objectid);
975
973/* inode-item.c */ 976/* inode-item.c */
974int btrfs_insert_inode(struct btrfs_trans_handle *trans, struct btrfs_root 977int btrfs_insert_inode(struct btrfs_trans_handle *trans, struct btrfs_root
975 *root, u64 objectid, struct btrfs_inode_item 978 *root, u64 objectid, struct btrfs_inode_item
diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c
index b1629a5d73c8..0ee9945fb1b0 100644
--- a/fs/btrfs/dir-item.c
+++ b/fs/btrfs/dir-item.c
@@ -92,6 +92,7 @@ int btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
92 int cow = mod != 0; 92 int cow = mod != 0;
93 struct btrfs_disk_key *found_key; 93 struct btrfs_disk_key *found_key;
94 struct btrfs_leaf *leaf; 94 struct btrfs_leaf *leaf;
95 u32 overflow;
95 96
96 key.objectid = dir; 97 key.objectid = dir;
97 key.flags = 0; 98 key.flags = 0;
@@ -119,8 +120,10 @@ int btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
119 if (btrfs_match_dir_item_name(root, path, name, name_len)) 120 if (btrfs_match_dir_item_name(root, path, name, name_len))
120 return 0; 121 return 0;
121 122
122 if (btrfs_disk_key_overflow(found_key) == 0) 123 overflow = btrfs_disk_key_overflow(found_key);
124 if (overflow == 0)
123 return 1; 125 return 1;
126 btrfs_set_key_overflow(&key, overflow - 1);
124 btrfs_release_path(root, path); 127 btrfs_release_path(root, path);
125 } 128 }
126 return 1; 129 return 1;
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index de9ee3aa0aad..5230554380d1 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -311,6 +311,7 @@ struct btrfs_root *open_ctree(struct super_block *sb)
311 fs_info->extent_root = extent_root; 311 fs_info->extent_root = extent_root;
312 fs_info->inode_root = inode_root; 312 fs_info->inode_root = inode_root;
313 fs_info->last_inode_alloc = 0; 313 fs_info->last_inode_alloc = 0;
314 fs_info->highest_inode = 0;
314 fs_info->sb = sb; 315 fs_info->sb = sb;
315 fs_info->btree_inode = new_inode(sb); 316 fs_info->btree_inode = new_inode(sb);
316 fs_info->btree_inode->i_ino = 1; 317 fs_info->btree_inode->i_ino = 1;
@@ -360,12 +361,15 @@ printk("failed2\n");
360 361
361 ret = find_and_setup_root(sb->s_blocksize, tree_root, fs_info, 362 ret = find_and_setup_root(sb->s_blocksize, tree_root, fs_info,
362 BTRFS_FS_TREE_OBJECTID, root); 363 BTRFS_FS_TREE_OBJECTID, root);
363 mutex_unlock(&fs_info->fs_mutex);
364 BUG_ON(ret); 364 BUG_ON(ret);
365 root->commit_root = root->node; 365 root->commit_root = root->node;
366 get_bh(root->node); 366 get_bh(root->node);
367 root->ref_cows = 1; 367 root->ref_cows = 1;
368 root->fs_info->generation = root->root_key.offset + 1; 368 root->fs_info->generation = root->root_key.offset + 1;
369 ret = btrfs_find_highest_inode(root, &root->fs_info->last_inode_alloc);
370 if (ret == 0)
371 fs_info->highest_inode = fs_info->last_inode_alloc;
372 mutex_unlock(&fs_info->fs_mutex);
369 return root; 373 return root;
370} 374}
371 375
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c
index 329edb42897e..f665221409ac 100644
--- a/fs/btrfs/inode-map.c
+++ b/fs/btrfs/inode-map.c
@@ -3,6 +3,37 @@
3#include "disk-io.h" 3#include "disk-io.h"
4#include "transaction.h" 4#include "transaction.h"
5 5
6int btrfs_find_highest_inode(struct btrfs_root *fs_root, u64 *objectid)
7{
8 struct btrfs_path *path;
9 int ret;
10 struct btrfs_leaf *l;
11 struct btrfs_root *root = fs_root->fs_info->inode_root;
12 struct btrfs_key search_key;
13 int slot;
14
15 path = btrfs_alloc_path();
16 BUG_ON(!path);
17
18 search_key.objectid = (u64)-1;
19 search_key.offset = (u64)-1;
20 ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
21 if (ret < 0)
22 goto error;
23 BUG_ON(ret == 0);
24 if (path->slots[0] > 0) {
25 slot = path->slots[0] - 1;
26 l = btrfs_buffer_leaf(path->nodes[0]);
27 *objectid = btrfs_disk_key_objectid(&l->items[slot].key);
28 } else {
29 *objectid = BTRFS_FIRST_FREE_OBJECTID;
30 }
31 ret = 0;
32error:
33 btrfs_free_path(path);
34 return ret;
35}
36
6/* 37/*
7 * walks the btree of allocated inodes and find a hole. 38 * walks the btree of allocated inodes and find a hole.
8 */ 39 */
@@ -28,21 +59,6 @@ int btrfs_find_free_objectid(struct btrfs_trans_handle *trans,
28 btrfs_set_key_type(&search_key, BTRFS_INODE_MAP_ITEM_KEY); 59 btrfs_set_key_type(&search_key, BTRFS_INODE_MAP_ITEM_KEY);
29 60
30 search_start = fs_root->fs_info->last_inode_alloc; 61 search_start = fs_root->fs_info->last_inode_alloc;
31 if (search_start == 0) {
32 struct btrfs_disk_key *last_key;
33 btrfs_init_path(path);
34 search_key.objectid = (u64)-1;
35 search_key.offset = (u64)-1;
36 ret = btrfs_search_slot(trans, root, &search_key, path, 0, 0);
37 if (ret < 0)
38 goto error;
39 BUG_ON(ret == 0);
40 if (path->slots[0] > 0)
41 path->slots[0]--;
42 l = btrfs_buffer_leaf(path->nodes[0]);
43 last_key = &l->items[path->slots[0]].key;
44 search_start = btrfs_disk_key_objectid(last_key);
45 }
46 search_start = max(search_start, BTRFS_FIRST_FREE_OBJECTID); 62 search_start = max(search_start, BTRFS_FIRST_FREE_OBJECTID);
47 search_key.objectid = search_start; 63 search_key.objectid = search_start;
48 search_key.offset = 0; 64 search_key.offset = 0;
@@ -129,6 +145,8 @@ int btrfs_insert_inode_map(struct btrfs_trans_handle *trans,
129 path->slots[0], struct btrfs_inode_map_item); 145 path->slots[0], struct btrfs_inode_map_item);
130 btrfs_cpu_key_to_disk(&inode_item->key, location); 146 btrfs_cpu_key_to_disk(&inode_item->key, location);
131 btrfs_mark_buffer_dirty(path->nodes[0]); 147 btrfs_mark_buffer_dirty(path->nodes[0]);
148 if (objectid > fs_root->fs_info->highest_inode)
149 fs_root->fs_info->highest_inode = objectid;
132out: 150out:
133 btrfs_release_path(inode_root, path); 151 btrfs_release_path(inode_root, path);
134 btrfs_free_path(path); 152 btrfs_free_path(path);
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 4fd2b168b2c4..d4ee78046b86 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -482,6 +482,11 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
482 item = leaf->items + slot; 482 item = leaf->items + slot;
483 if (btrfs_disk_key_objectid(&item->key) != key.objectid) 483 if (btrfs_disk_key_objectid(&item->key) != key.objectid)
484 break; 484 break;
485 if (btrfs_disk_key_offset(&item->key) >
486 root->fs_info->highest_inode) {
487printk("stopping at highest inode %Lu\n", root->fs_info->highest_inode);
488 break;
489 }
485 if (btrfs_disk_key_type(&item->key) != BTRFS_DIR_INDEX_KEY) 490 if (btrfs_disk_key_type(&item->key) != BTRFS_DIR_INDEX_KEY)
486 continue; 491 continue;
487 if (btrfs_disk_key_offset(&item->key) < filp->f_pos) 492 if (btrfs_disk_key_offset(&item->key) < filp->f_pos)