diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-04-05 13:35:25 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-04-05 13:35:25 -0400 |
commit | 5be6f7f174146d91039a27ebb2f1b4ac599172b3 (patch) | |
tree | 2933d1e9e5cb50c4ca93f6e8c7e133d65a614461 /fs | |
parent | 7fcde0e3298c00ee18e2ae7f01c67f99133ef7be (diff) |
Btrfs: dirindex optimizations
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/ctree.h | 3 | ||||
-rw-r--r-- | fs/btrfs/dir-item.c | 5 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 6 | ||||
-rw-r--r-- | fs/btrfs/inode-map.c | 48 | ||||
-rw-r--r-- | fs/btrfs/super.c | 5 |
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, | |||
970 | int btrfs_lookup_inode_map(struct btrfs_trans_handle *trans, | 971 | int 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); |
974 | int btrfs_find_highest_inode(struct btrfs_root *fs_root, u64 *objectid); | ||
975 | |||
973 | /* inode-item.c */ | 976 | /* inode-item.c */ |
974 | int btrfs_insert_inode(struct btrfs_trans_handle *trans, struct btrfs_root | 977 | int 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 | ||
6 | int 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; | ||
32 | error: | ||
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; | ||
132 | out: | 150 | out: |
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) { | ||
487 | printk("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) |