aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-04-02 10:50:19 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-04-02 10:50:19 -0400
commit2c90e5d658424bc71b111eb5a972240d5d06fe86 (patch)
treef46b830654af0f67ef1691353fe4d79943a05465 /fs
parentd6025579531b7ea170ba283b171ff7a6bf7d0e12 (diff)
Btrfs: still corruption hunting
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/bit-radix.c7
-rw-r--r--fs/btrfs/btrfs_inode.h14
-rw-r--r--fs/btrfs/ctree.c42
-rw-r--r--fs/btrfs/ctree.h3
-rw-r--r--fs/btrfs/disk-io.c84
-rw-r--r--fs/btrfs/disk-io.h4
-rw-r--r--fs/btrfs/extent-tree.c18
-rw-r--r--fs/btrfs/super.c146
-rw-r--r--fs/btrfs/transaction.c39
-rw-r--r--fs/btrfs/transaction.h3
10 files changed, 265 insertions, 95 deletions
diff --git a/fs/btrfs/bit-radix.c b/fs/btrfs/bit-radix.c
index 845422368f48..a50a1c44eabd 100644
--- a/fs/btrfs/bit-radix.c
+++ b/fs/btrfs/bit-radix.c
@@ -4,6 +4,7 @@
4#define BIT_ARRAY_BYTES 256 4#define BIT_ARRAY_BYTES 256
5#define BIT_RADIX_BITS_PER_ARRAY ((BIT_ARRAY_BYTES - sizeof(unsigned long)) * 8) 5#define BIT_RADIX_BITS_PER_ARRAY ((BIT_ARRAY_BYTES - sizeof(unsigned long)) * 8)
6 6
7extern struct kmem_cache *btrfs_bit_radix_cachep;
7int set_radix_bit(struct radix_tree_root *radix, unsigned long bit) 8int set_radix_bit(struct radix_tree_root *radix, unsigned long bit)
8{ 9{
9 unsigned long *bits; 10 unsigned long *bits;
@@ -16,7 +17,7 @@ int set_radix_bit(struct radix_tree_root *radix, unsigned long bit)
16 17
17 bits = radix_tree_lookup(radix, slot); 18 bits = radix_tree_lookup(radix, slot);
18 if (!bits) { 19 if (!bits) {
19 bits = kmalloc(BIT_ARRAY_BYTES, GFP_NOFS); 20 bits = kmem_cache_alloc(btrfs_bit_radix_cachep, GFP_NOFS);
20 if (!bits) 21 if (!bits)
21 return -ENOMEM; 22 return -ENOMEM;
22 memset(bits + 1, 0, BIT_ARRAY_BYTES - sizeof(unsigned long)); 23 memset(bits + 1, 0, BIT_ARRAY_BYTES - sizeof(unsigned long));
@@ -68,12 +69,10 @@ int clear_radix_bit(struct radix_tree_root *radix, unsigned long bit)
68 break; 69 break;
69 } 70 }
70 } 71 }
71
72 if (empty) { 72 if (empty) {
73 bits = radix_tree_delete(radix, slot); 73 bits = radix_tree_delete(radix, slot);
74 synchronize_rcu();
75 BUG_ON(!bits); 74 BUG_ON(!bits);
76 kfree(bits); 75 kmem_cache_free(btrfs_bit_radix_cachep, bits);
77 } 76 }
78#endif 77#endif
79 return 0; 78 return 0;
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
new file mode 100644
index 000000000000..e159841650a4
--- /dev/null
+++ b/fs/btrfs/btrfs_inode.h
@@ -0,0 +1,14 @@
1#ifndef __BTRFS_I__
2#define __BTRFS_I__
3
4struct btrfs_inode {
5 u32 magic;
6 struct inode vfs_inode;
7 u32 magic2;
8};
9static inline struct btrfs_inode *BTRFS_I(struct inode *inode)
10{
11 return container_of(inode, struct btrfs_inode, vfs_inode);
12}
13
14#endif
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index a0dfa2d6cb9b..453ce835209a 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -16,6 +16,16 @@ static int balance_node_right(struct btrfs_trans_handle *trans, struct
16static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, 16static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
17 struct btrfs_path *path, int level, int slot); 17 struct btrfs_path *path, int level, int slot);
18 18
19struct btrfs_path *btrfs_alloc_path(void)
20{
21 return kmem_cache_alloc(btrfs_path_cachep, GFP_NOFS);
22}
23
24void btrfs_free_path(struct btrfs_path *p)
25{
26 kmem_cache_free(btrfs_path_cachep, p);
27}
28
19inline void btrfs_init_path(struct btrfs_path *p) 29inline void btrfs_init_path(struct btrfs_path *p)
20{ 30{
21 memset(p, 0, sizeof(*p)); 31 memset(p, 0, sizeof(*p));
@@ -47,17 +57,18 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
47 } 57 }
48 cow = btrfs_alloc_free_block(trans, root); 58 cow = btrfs_alloc_free_block(trans, root);
49 cow_node = btrfs_buffer_node(cow); 59 cow_node = btrfs_buffer_node(cow);
60 if (buf->b_size != root->blocksize || cow->b_size != root->blocksize)
61 WARN_ON(1);
50 memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize); 62 memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize);
51 btrfs_set_header_blocknr(&cow_node->header, cow->b_blocknr); 63 btrfs_set_header_blocknr(&cow_node->header, cow->b_blocknr);
52 btrfs_set_header_generation(&cow_node->header, trans->transid); 64 btrfs_set_header_generation(&cow_node->header, trans->transid);
53 *cow_ret = cow;
54 btrfs_mark_buffer_dirty(cow);
55 btrfs_inc_ref(trans, root, buf); 65 btrfs_inc_ref(trans, root, buf);
56 if (buf == root->node) { 66 if (buf == root->node) {
57 root->node = cow; 67 root->node = cow;
58 get_bh(cow); 68 get_bh(cow);
59 if (buf != root->commit_root) 69 if (buf != root->commit_root) {
60 btrfs_free_extent(trans, root, buf->b_blocknr, 1, 1); 70 btrfs_free_extent(trans, root, buf->b_blocknr, 1, 1);
71 }
61 btrfs_block_release(root, buf); 72 btrfs_block_release(root, buf);
62 } else { 73 } else {
63 btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot, 74 btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot,
@@ -66,6 +77,7 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
66 btrfs_free_extent(trans, root, buf->b_blocknr, 1, 1); 77 btrfs_free_extent(trans, root, buf->b_blocknr, 1, 1);
67 } 78 }
68 btrfs_block_release(root, buf); 79 btrfs_block_release(root, buf);
80 *cow_ret = cow;
69 return 0; 81 return 0;
70} 82}
71 83
@@ -477,9 +489,12 @@ again:
477 p->slots[level + 1], 489 p->slots[level + 1],
478 &cow_buf); 490 &cow_buf);
479 b = cow_buf; 491 b = cow_buf;
492 c = btrfs_buffer_node(b);
480 } 493 }
481 BUG_ON(!cow && ins_len); 494 BUG_ON(!cow && ins_len);
482 c = btrfs_buffer_node(b); 495 if (level != btrfs_header_level(&c->header))
496 WARN_ON(1);
497 level = btrfs_header_level(&c->header);
483 p->nodes[level] = b; 498 p->nodes[level] = b;
484 ret = check_block(root, p, level); 499 ret = check_block(root, p, level);
485 if (ret) 500 if (ret)
@@ -1257,19 +1272,22 @@ int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
1257 data_size) 1272 data_size)
1258{ 1273{
1259 int ret = 0; 1274 int ret = 0;
1260 struct btrfs_path path; 1275 struct btrfs_path *path;
1261 u8 *ptr; 1276 u8 *ptr;
1262 1277
1263 btrfs_init_path(&path); 1278 path = btrfs_alloc_path();
1264 ret = btrfs_insert_empty_item(trans, root, &path, cpu_key, data_size); 1279 BUG_ON(!path);
1280 btrfs_init_path(path);
1281 ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size);
1265 if (!ret) { 1282 if (!ret) {
1266 ptr = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), 1283 ptr = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]),
1267 path.slots[0], u8); 1284 path->slots[0], u8);
1268 btrfs_memcpy(root, path.nodes[0]->b_data, 1285 btrfs_memcpy(root, path->nodes[0]->b_data,
1269 ptr, data, data_size); 1286 ptr, data, data_size);
1270 btrfs_mark_buffer_dirty(path.nodes[0]); 1287 btrfs_mark_buffer_dirty(path->nodes[0]);
1271 } 1288 }
1272 btrfs_release_path(root, &path); 1289 btrfs_release_path(root, path);
1290 btrfs_free_path(path);
1273 return ret; 1291 return ret;
1274} 1292}
1275 1293
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 9ec0d65ebe9b..d8e03bd797ff 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -7,6 +7,7 @@
7 7
8struct btrfs_trans_handle; 8struct btrfs_trans_handle;
9struct btrfs_transaction; 9struct btrfs_transaction;
10extern struct kmem_cache *btrfs_path_cachep;
10 11
11#define BTRFS_MAGIC "_BtRfS_M" 12#define BTRFS_MAGIC "_BtRfS_M"
12 13
@@ -888,6 +889,8 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
888 *root, struct btrfs_key *key, struct btrfs_path *p, int 889 *root, struct btrfs_key *key, struct btrfs_path *p, int
889 ins_len, int cow); 890 ins_len, int cow);
890void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p); 891void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p);
892struct btrfs_path *btrfs_alloc_path(void);
893void btrfs_free_path(struct btrfs_path *p);
891void btrfs_init_path(struct btrfs_path *p); 894void btrfs_init_path(struct btrfs_path *p);
892int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, 895int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
893 struct btrfs_path *path); 896 struct btrfs_path *path);
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index bb133104e2e9..2dbd55084a4e 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -8,18 +8,6 @@
8#include "disk-io.h" 8#include "disk-io.h"
9#include "transaction.h" 9#include "transaction.h"
10 10
11#define PATTERN 0xDEADBEEFUL
12static inline void check_pattern(struct buffer_head *buf)
13{
14 if (buf->b_private != (void *)PATTERN)
15 WARN_ON(1);
16}
17
18static inline void set_pattern(struct buffer_head *buf)
19{
20 buf->b_private = (void *)PATTERN;
21}
22
23static int check_tree_block(struct btrfs_root *root, struct buffer_head *buf) 11static int check_tree_block(struct btrfs_root *root, struct buffer_head *buf)
24{ 12{
25 struct btrfs_node *node = btrfs_buffer_node(buf); 13 struct btrfs_node *node = btrfs_buffer_node(buf);
@@ -35,6 +23,8 @@ static int check_tree_block(struct btrfs_root *root, struct buffer_head *buf)
35 23
36struct buffer_head *btrfs_find_tree_block(struct btrfs_root *root, u64 blocknr) 24struct buffer_head *btrfs_find_tree_block(struct btrfs_root *root, u64 blocknr)
37{ 25{
26 return sb_find_get_block(root->fs_info->sb, blocknr);
27#if 0
38 struct address_space *mapping = root->fs_info->btree_inode->i_mapping; 28 struct address_space *mapping = root->fs_info->btree_inode->i_mapping;
39 int blockbits = root->fs_info->sb->s_blocksize_bits; 29 int blockbits = root->fs_info->sb->s_blocksize_bits;
40 unsigned long index = blocknr >> (PAGE_CACHE_SHIFT - blockbits); 30 unsigned long index = blocknr >> (PAGE_CACHE_SHIFT - blockbits);
@@ -43,6 +33,7 @@ struct buffer_head *btrfs_find_tree_block(struct btrfs_root *root, u64 blocknr)
43 struct buffer_head *head; 33 struct buffer_head *head;
44 struct buffer_head *ret = NULL; 34 struct buffer_head *ret = NULL;
45 35
36
46 page = find_lock_page(mapping, index); 37 page = find_lock_page(mapping, index);
47 if (!page) 38 if (!page)
48 return NULL; 39 return NULL;
@@ -64,15 +55,17 @@ out_unlock:
64 unlock_page(page); 55 unlock_page(page);
65 if (ret) { 56 if (ret) {
66 touch_buffer(ret); 57 touch_buffer(ret);
67 check_pattern(ret);
68 } 58 }
69 page_cache_release(page); 59 page_cache_release(page);
70 return ret; 60 return ret;
61#endif
71} 62}
72 63
73struct buffer_head *btrfs_find_create_tree_block(struct btrfs_root *root, 64struct buffer_head *btrfs_find_create_tree_block(struct btrfs_root *root,
74 u64 blocknr) 65 u64 blocknr)
75{ 66{
67 return sb_getblk(root->fs_info->sb, blocknr);
68#if 0
76 struct address_space *mapping = root->fs_info->btree_inode->i_mapping; 69 struct address_space *mapping = root->fs_info->btree_inode->i_mapping;
77 int blockbits = root->fs_info->sb->s_blocksize_bits; 70 int blockbits = root->fs_info->sb->s_blocksize_bits;
78 unsigned long index = blocknr >> (PAGE_CACHE_SHIFT - blockbits); 71 unsigned long index = blocknr >> (PAGE_CACHE_SHIFT - blockbits);
@@ -95,7 +88,6 @@ struct buffer_head *btrfs_find_create_tree_block(struct btrfs_root *root,
95 bh->b_bdev = root->fs_info->sb->s_bdev; 88 bh->b_bdev = root->fs_info->sb->s_bdev;
96 bh->b_blocknr = first_block; 89 bh->b_blocknr = first_block;
97 set_buffer_mapped(bh); 90 set_buffer_mapped(bh);
98 set_pattern(bh);
99 } 91 }
100 if (bh->b_blocknr == blocknr) { 92 if (bh->b_blocknr == blocknr) {
101 ret = bh; 93 ret = bh;
@@ -111,6 +103,7 @@ out_unlock:
111 touch_buffer(ret); 103 touch_buffer(ret);
112 page_cache_release(page); 104 page_cache_release(page);
113 return ret; 105 return ret;
106#endif
114} 107}
115 108
116static sector_t max_block(struct block_device *bdev) 109static sector_t max_block(struct block_device *bdev)
@@ -225,6 +218,8 @@ static struct address_space_operations btree_aops = {
225 218
226struct buffer_head *read_tree_block(struct btrfs_root *root, u64 blocknr) 219struct buffer_head *read_tree_block(struct btrfs_root *root, u64 blocknr)
227{ 220{
221 return sb_bread(root->fs_info->sb, blocknr);
222#if 0
228 struct buffer_head *bh = NULL; 223 struct buffer_head *bh = NULL;
229 224
230 bh = btrfs_find_create_tree_block(root, blocknr); 225 bh = btrfs_find_create_tree_block(root, blocknr);
@@ -239,7 +234,6 @@ struct buffer_head *read_tree_block(struct btrfs_root *root, u64 blocknr)
239 if (!buffer_uptodate(bh)) 234 if (!buffer_uptodate(bh))
240 goto fail; 235 goto fail;
241 csum_tree_block(root, bh, 1); 236 csum_tree_block(root, bh, 1);
242 set_pattern(bh);
243 } else { 237 } else {
244 unlock_buffer(bh); 238 unlock_buffer(bh);
245 } 239 }
@@ -250,6 +244,7 @@ fail:
250 brelse(bh); 244 brelse(bh);
251 return NULL; 245 return NULL;
252 246
247#endif
253} 248}
254 249
255int dirty_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, 250int dirty_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
@@ -268,14 +263,14 @@ int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
268 return 0; 263 return 0;
269} 264}
270 265
271static int __setup_root(struct btrfs_super_block *super, 266static int __setup_root(int blocksize,
272 struct btrfs_root *root, 267 struct btrfs_root *root,
273 struct btrfs_fs_info *fs_info, 268 struct btrfs_fs_info *fs_info,
274 u64 objectid) 269 u64 objectid)
275{ 270{
276 root->node = NULL; 271 root->node = NULL;
277 root->commit_root = NULL; 272 root->commit_root = NULL;
278 root->blocksize = btrfs_super_blocksize(super); 273 root->blocksize = blocksize;
279 root->ref_cows = 0; 274 root->ref_cows = 0;
280 root->fs_info = fs_info; 275 root->fs_info = fs_info;
281 memset(&root->root_key, 0, sizeof(root->root_key)); 276 memset(&root->root_key, 0, sizeof(root->root_key));
@@ -283,7 +278,7 @@ static int __setup_root(struct btrfs_super_block *super,
283 return 0; 278 return 0;
284} 279}
285 280
286static int find_and_setup_root(struct btrfs_super_block *super, 281static int find_and_setup_root(int blocksize,
287 struct btrfs_root *tree_root, 282 struct btrfs_root *tree_root,
288 struct btrfs_fs_info *fs_info, 283 struct btrfs_fs_info *fs_info,
289 u64 objectid, 284 u64 objectid,
@@ -291,7 +286,7 @@ static int find_and_setup_root(struct btrfs_super_block *super,
291{ 286{
292 int ret; 287 int ret;
293 288
294 __setup_root(super, root, fs_info, objectid); 289 __setup_root(blocksize, root, fs_info, objectid);
295 ret = btrfs_find_last_root(tree_root, objectid, 290 ret = btrfs_find_last_root(tree_root, objectid,
296 &root->root_item, &root->root_key); 291 &root->root_item, &root->root_key);
297 BUG_ON(ret); 292 BUG_ON(ret);
@@ -302,9 +297,7 @@ static int find_and_setup_root(struct btrfs_super_block *super,
302 return 0; 297 return 0;
303} 298}
304 299
305struct btrfs_root *open_ctree(struct super_block *sb, 300struct btrfs_root *open_ctree(struct super_block *sb)
306 struct buffer_head *sb_buffer,
307 struct btrfs_super_block *disk_super)
308{ 301{
309 struct btrfs_root *root = kmalloc(sizeof(struct btrfs_root), 302 struct btrfs_root *root = kmalloc(sizeof(struct btrfs_root),
310 GFP_NOFS); 303 GFP_NOFS);
@@ -317,13 +310,11 @@ struct btrfs_root *open_ctree(struct super_block *sb,
317 struct btrfs_fs_info *fs_info = kmalloc(sizeof(*fs_info), 310 struct btrfs_fs_info *fs_info = kmalloc(sizeof(*fs_info),
318 GFP_NOFS); 311 GFP_NOFS);
319 int ret; 312 int ret;
313 struct btrfs_super_block *disk_super;
320 314
321 if (!btrfs_super_root(disk_super)) {
322 return NULL;
323 }
324 init_bit_radix(&fs_info->pinned_radix); 315 init_bit_radix(&fs_info->pinned_radix);
325 init_bit_radix(&fs_info->pending_del_radix); 316 init_bit_radix(&fs_info->pending_del_radix);
326 sb_set_blocksize(sb, sb_buffer->b_size); 317 sb_set_blocksize(sb, 4096);
327 fs_info->running_transaction = NULL; 318 fs_info->running_transaction = NULL;
328 fs_info->fs_root = root; 319 fs_info->fs_root = root;
329 fs_info->tree_root = tree_root; 320 fs_info->tree_root = tree_root;
@@ -331,55 +322,59 @@ struct btrfs_root *open_ctree(struct super_block *sb,
331 fs_info->inode_root = inode_root; 322 fs_info->inode_root = inode_root;
332 fs_info->last_inode_alloc = 0; 323 fs_info->last_inode_alloc = 0;
333 fs_info->last_inode_alloc_dirid = 0; 324 fs_info->last_inode_alloc_dirid = 0;
334 fs_info->disk_super = disk_super;
335 fs_info->sb = sb; 325 fs_info->sb = sb;
326 fs_info->btree_inode = NULL;
327#if 0
336 fs_info->btree_inode = new_inode(sb); 328 fs_info->btree_inode = new_inode(sb);
337 fs_info->btree_inode->i_ino = 1; 329 fs_info->btree_inode->i_ino = 1;
330 fs_info->btree_inode->i_nlink = 1;
338 fs_info->btree_inode->i_size = sb->s_bdev->bd_inode->i_size; 331 fs_info->btree_inode->i_size = sb->s_bdev->bd_inode->i_size;
339 fs_info->btree_inode->i_mapping->a_ops = &btree_aops; 332 fs_info->btree_inode->i_mapping->a_ops = &btree_aops;
340 insert_inode_hash(fs_info->btree_inode); 333 insert_inode_hash(fs_info->btree_inode);
341
342 mapping_set_gfp_mask(fs_info->btree_inode->i_mapping, GFP_NOFS); 334 mapping_set_gfp_mask(fs_info->btree_inode->i_mapping, GFP_NOFS);
335#endif
343 fs_info->hash_tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC); 336 fs_info->hash_tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
344 spin_lock_init(&fs_info->hash_lock); 337 spin_lock_init(&fs_info->hash_lock);
345
346 if (!fs_info->hash_tfm || IS_ERR(fs_info->hash_tfm)) { 338 if (!fs_info->hash_tfm || IS_ERR(fs_info->hash_tfm)) {
347 printk("failed to allocate sha256 hash\n"); 339 printk("failed to allocate sha256 hash\n");
348 return NULL; 340 return NULL;
349 } 341 }
350
351 mutex_init(&fs_info->trans_mutex); 342 mutex_init(&fs_info->trans_mutex);
352 mutex_init(&fs_info->fs_mutex); 343 mutex_init(&fs_info->fs_mutex);
353 memset(&fs_info->current_insert, 0, sizeof(fs_info->current_insert)); 344 memset(&fs_info->current_insert, 0, sizeof(fs_info->current_insert));
354 memset(&fs_info->last_insert, 0, sizeof(fs_info->last_insert)); 345 memset(&fs_info->last_insert, 0, sizeof(fs_info->last_insert));
355 346
356 __setup_root(disk_super, tree_root, fs_info, BTRFS_ROOT_TREE_OBJECTID); 347 __setup_root(sb->s_blocksize, tree_root,
357 348 fs_info, BTRFS_ROOT_TREE_OBJECTID);
358 fs_info->sb_buffer = read_tree_block(tree_root, sb_buffer->b_blocknr); 349 fs_info->sb_buffer = read_tree_block(tree_root,
350 BTRFS_SUPER_INFO_OFFSET /
351 sb->s_blocksize);
359 352
360 if (!fs_info->sb_buffer) { 353 if (!fs_info->sb_buffer) {
361printk("failed2\n"); 354printk("failed2\n");
362 return NULL; 355 return NULL;
363 } 356 }
364 brelse(sb_buffer);
365 sb_buffer = NULL;
366 disk_super = (struct btrfs_super_block *)fs_info->sb_buffer->b_data; 357 disk_super = (struct btrfs_super_block *)fs_info->sb_buffer->b_data;
358 if (!btrfs_super_root(disk_super)) {
359 return NULL;
360 }
367 fs_info->disk_super = disk_super; 361 fs_info->disk_super = disk_super;
368
369 tree_root->node = read_tree_block(tree_root, 362 tree_root->node = read_tree_block(tree_root,
370 btrfs_super_root(disk_super)); 363 btrfs_super_root(disk_super));
371 BUG_ON(!tree_root->node); 364 BUG_ON(!tree_root->node);
372 365
373 ret = find_and_setup_root(disk_super, tree_root, fs_info, 366 mutex_lock(&fs_info->fs_mutex);
367 ret = find_and_setup_root(sb->s_blocksize, tree_root, fs_info,
374 BTRFS_EXTENT_TREE_OBJECTID, extent_root); 368 BTRFS_EXTENT_TREE_OBJECTID, extent_root);
375 BUG_ON(ret); 369 BUG_ON(ret);
376 370
377 ret = find_and_setup_root(disk_super, tree_root, fs_info, 371 ret = find_and_setup_root(sb->s_blocksize, tree_root, fs_info,
378 BTRFS_INODE_MAP_OBJECTID, inode_root); 372 BTRFS_INODE_MAP_OBJECTID, inode_root);
379 BUG_ON(ret); 373 BUG_ON(ret);
380 374
381 ret = find_and_setup_root(disk_super, tree_root, fs_info, 375 ret = find_and_setup_root(sb->s_blocksize, tree_root, fs_info,
382 BTRFS_FS_TREE_OBJECTID, root); 376 BTRFS_FS_TREE_OBJECTID, root);
377 mutex_unlock(&fs_info->fs_mutex);
383 BUG_ON(ret); 378 BUG_ON(ret);
384 root->commit_root = root->node; 379 root->commit_root = root->node;
385 get_bh(root->node); 380 get_bh(root->node);
@@ -392,9 +387,11 @@ int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root
392 *root) 387 *root)
393{ 388{
394 struct buffer_head *bh = root->fs_info->sb_buffer; 389 struct buffer_head *bh = root->fs_info->sb_buffer;
390
395 btrfs_set_super_root(root->fs_info->disk_super, 391 btrfs_set_super_root(root->fs_info->disk_super,
396 root->fs_info->tree_root->node->b_blocknr); 392 root->fs_info->tree_root->node->b_blocknr);
397 lock_buffer(bh); 393 lock_buffer(bh);
394 WARN_ON(atomic_read(&bh->b_count) < 1);
398 clear_buffer_dirty(bh); 395 clear_buffer_dirty(bh);
399 csum_tree_block(root, bh, 0); 396 csum_tree_block(root, bh, 0);
400 bh->b_end_io = end_buffer_write_sync; 397 bh->b_end_io = end_buffer_write_sync;
@@ -413,6 +410,7 @@ int close_ctree(struct btrfs_root *root)
413 int ret; 410 int ret;
414 struct btrfs_trans_handle *trans; 411 struct btrfs_trans_handle *trans;
415 412
413 mutex_lock(&root->fs_info->fs_mutex);
416 trans = btrfs_start_transaction(root, 1); 414 trans = btrfs_start_transaction(root, 1);
417 btrfs_commit_transaction(trans, root); 415 btrfs_commit_transaction(trans, root);
418 /* run commit again to drop the original snapshot */ 416 /* run commit again to drop the original snapshot */
@@ -421,6 +419,7 @@ int close_ctree(struct btrfs_root *root)
421 ret = btrfs_write_and_wait_transaction(NULL, root); 419 ret = btrfs_write_and_wait_transaction(NULL, root);
422 BUG_ON(ret); 420 BUG_ON(ret);
423 write_ctree_super(NULL, root); 421 write_ctree_super(NULL, root);
422 mutex_unlock(&root->fs_info->fs_mutex);
424 423
425 if (root->node) 424 if (root->node)
426 btrfs_block_release(root, root->node); 425 btrfs_block_release(root, root->node);
@@ -436,8 +435,8 @@ int close_ctree(struct btrfs_root *root)
436 btrfs_block_release(root, root->commit_root); 435 btrfs_block_release(root, root->commit_root);
437 btrfs_block_release(root, root->fs_info->sb_buffer); 436 btrfs_block_release(root, root->fs_info->sb_buffer);
438 crypto_free_hash(root->fs_info->hash_tfm); 437 crypto_free_hash(root->fs_info->hash_tfm);
439 truncate_inode_pages(root->fs_info->btree_inode->i_mapping, 0); 438 // truncate_inode_pages(root->fs_info->btree_inode->i_mapping, 0);
440 iput(root->fs_info->btree_inode); 439 // iput(root->fs_info->btree_inode);
441 kfree(root->fs_info->extent_root); 440 kfree(root->fs_info->extent_root);
442 kfree(root->fs_info->inode_root); 441 kfree(root->fs_info->inode_root);
443 kfree(root->fs_info->tree_root); 442 kfree(root->fs_info->tree_root);
@@ -448,7 +447,6 @@ int close_ctree(struct btrfs_root *root)
448 447
449void btrfs_block_release(struct btrfs_root *root, struct buffer_head *buf) 448void btrfs_block_release(struct btrfs_root *root, struct buffer_head *buf)
450{ 449{
451 check_pattern(buf); 450 // brelse(buf);
452 brelse(buf);
453} 451}
454 452
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index f6998e2192ce..ac6764ba8aa6 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -31,9 +31,7 @@ int clean_tree_block(struct btrfs_trans_handle *trans,
31 struct btrfs_root *root, struct buffer_head *buf); 31 struct btrfs_root *root, struct buffer_head *buf);
32int btrfs_commit_transaction(struct btrfs_trans_handle *trans, 32int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
33 struct btrfs_root *root); 33 struct btrfs_root *root);
34struct btrfs_root *open_ctree(struct super_block *sb, 34struct btrfs_root *open_ctree(struct super_block *sb);
35 struct buffer_head *sb_buffer,
36 struct btrfs_super_block *disk_super);
37int close_ctree(struct btrfs_root *root); 35int close_ctree(struct btrfs_root *root);
38void btrfs_block_release(struct btrfs_root *root, struct buffer_head *buf); 36void btrfs_block_release(struct btrfs_root *root, struct buffer_head *buf);
39int write_ctree_super(struct btrfs_trans_handle *trans, 37int write_ctree_super(struct btrfs_trans_handle *trans,
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index c4194dab7a33..37b87e28a2f3 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -173,12 +173,16 @@ static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending)
173 173
174 if (!pending) { 174 if (!pending) {
175 bh = btrfs_find_tree_block(root, blocknr); 175 bh = btrfs_find_tree_block(root, blocknr);
176 if (bh && buffer_uptodate(bh)) { 176 if (bh) {
177 header = btrfs_buffer_header(bh); 177 if (buffer_uptodate(bh)) {
178 if (btrfs_header_generation(header) == 178 u64 transid =
179 root->fs_info->running_transaction->transid) { 179 root->fs_info->running_transaction->transid;
180 btrfs_block_release(root, bh); 180 header = btrfs_buffer_header(bh);
181 return 0; 181 if (btrfs_header_generation(header) ==
182 transid) {
183 btrfs_block_release(root, bh);
184 return 0;
185 }
182 } 186 }
183 btrfs_block_release(root, bh); 187 btrfs_block_release(root, bh);
184 } 188 }
@@ -539,6 +543,8 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
539 */ 543 */
540 while(*level >= 0) { 544 while(*level >= 0) {
541 cur = path->nodes[*level]; 545 cur = path->nodes[*level];
546 if (btrfs_header_level(btrfs_buffer_header(cur)) != *level)
547 WARN_ON(1);
542 if (path->slots[*level] >= 548 if (path->slots[*level] >=
543 btrfs_header_nritems(btrfs_buffer_header(cur))) 549 btrfs_header_nritems(btrfs_buffer_header(cur)))
544 break; 550 break;
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 894a70bf26d2..6969b672b570 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -14,6 +14,7 @@
14#include "ctree.h" 14#include "ctree.h"
15#include "disk-io.h" 15#include "disk-io.h"
16#include "transaction.h" 16#include "transaction.h"
17#include "btrfs_inode.h"
17 18
18#define BTRFS_SUPER_MAGIC 0x9123682E 19#define BTRFS_SUPER_MAGIC 0x9123682E
19 20
@@ -24,6 +25,14 @@ static struct inode_operations btrfs_file_inode_operations;
24static struct address_space_operations btrfs_aops; 25static struct address_space_operations btrfs_aops;
25static struct file_operations btrfs_file_operations; 26static struct file_operations btrfs_file_operations;
26 27
28static int check_inode(struct inode *inode)
29{
30 struct btrfs_inode *ei = BTRFS_I(inode);
31 WARN_ON(ei->magic != 0xDEADBEEF);
32 WARN_ON(ei->magic2 != 0xDEADBEAF);
33 return 0;
34}
35
27static void btrfs_read_locked_inode(struct inode *inode) 36static void btrfs_read_locked_inode(struct inode *inode)
28{ 37{
29 struct btrfs_path path; 38 struct btrfs_path path;
@@ -34,6 +43,7 @@ static void btrfs_read_locked_inode(struct inode *inode)
34 btrfs_init_path(&path); 43 btrfs_init_path(&path);
35 mutex_lock(&root->fs_info->fs_mutex); 44 mutex_lock(&root->fs_info->fs_mutex);
36 45
46 check_inode(inode);
37 ret = btrfs_lookup_inode(NULL, root, &path, inode->i_ino, 0); 47 ret = btrfs_lookup_inode(NULL, root, &path, inode->i_ino, 0);
38 if (ret) { 48 if (ret) {
39 btrfs_release_path(root, &path); 49 btrfs_release_path(root, &path);
@@ -41,6 +51,7 @@ static void btrfs_read_locked_inode(struct inode *inode)
41 make_bad_inode(inode); 51 make_bad_inode(inode);
42 return; 52 return;
43 } 53 }
54 check_inode(inode);
44 inode_item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), 55 inode_item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]),
45 path.slots[0], 56 path.slots[0],
46 struct btrfs_inode_item); 57 struct btrfs_inode_item);
@@ -60,6 +71,7 @@ static void btrfs_read_locked_inode(struct inode *inode)
60 inode->i_generation = btrfs_inode_generation(inode_item); 71 inode->i_generation = btrfs_inode_generation(inode_item);
61 btrfs_release_path(root, &path); 72 btrfs_release_path(root, &path);
62 mutex_unlock(&root->fs_info->fs_mutex); 73 mutex_unlock(&root->fs_info->fs_mutex);
74 check_inode(inode);
63 switch (inode->i_mode & S_IFMT) { 75 switch (inode->i_mode & S_IFMT) {
64#if 0 76#if 0
65 default: 77 default:
@@ -80,6 +92,7 @@ static void btrfs_read_locked_inode(struct inode *inode)
80 // inode->i_op = &page_symlink_inode_operations; 92 // inode->i_op = &page_symlink_inode_operations;
81 break; 93 break;
82 } 94 }
95 check_inode(inode);
83 return; 96 return;
84} 97}
85 98
@@ -347,6 +360,7 @@ static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry,
347 namelen, 0); 360 namelen, 0);
348 if (ret || !btrfs_match_dir_item_name(root, &path, name, namelen)) { 361 if (ret || !btrfs_match_dir_item_name(root, &path, name, namelen)) {
349 *ino = 0; 362 *ino = 0;
363 ret = 0;
350 goto out; 364 goto out;
351 } 365 }
352 di = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], 366 di = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0],
@@ -354,6 +368,7 @@ static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry,
354 *ino = btrfs_dir_objectid(di); 368 *ino = btrfs_dir_objectid(di);
355out: 369out:
356 btrfs_release_path(root, &path); 370 btrfs_release_path(root, &path);
371 check_inode(dir);
357 return ret; 372 return ret;
358} 373}
359 374
@@ -367,7 +382,6 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
367 382
368 if (dentry->d_name.len > BTRFS_NAME_LEN) 383 if (dentry->d_name.len > BTRFS_NAME_LEN)
369 return ERR_PTR(-ENAMETOOLONG); 384 return ERR_PTR(-ENAMETOOLONG);
370
371 mutex_lock(&root->fs_info->fs_mutex); 385 mutex_lock(&root->fs_info->fs_mutex);
372 ret = btrfs_inode_by_name(dir, dentry, &ino); 386 ret = btrfs_inode_by_name(dir, dentry, &ino);
373 mutex_unlock(&root->fs_info->fs_mutex); 387 mutex_unlock(&root->fs_info->fs_mutex);
@@ -378,7 +392,9 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
378 inode = iget(dir->i_sb, ino); 392 inode = iget(dir->i_sb, ino);
379 if (!inode) 393 if (!inode)
380 return ERR_PTR(-EACCES); 394 return ERR_PTR(-EACCES);
395 check_inode(inode);
381 } 396 }
397 check_inode(dir);
382 return d_splice_alias(inode, dentry); 398 return d_splice_alias(inode, dentry);
383} 399}
384 400
@@ -471,23 +487,14 @@ static int btrfs_fill_super(struct super_block * sb, void * data, int silent)
471 struct inode * inode; 487 struct inode * inode;
472 struct dentry * root_dentry; 488 struct dentry * root_dentry;
473 struct btrfs_super_block *disk_super; 489 struct btrfs_super_block *disk_super;
474 struct buffer_head *bh;
475 struct btrfs_root *root; 490 struct btrfs_root *root;
476 491
477 sb->s_maxbytes = MAX_LFS_FILESIZE; 492 sb->s_maxbytes = MAX_LFS_FILESIZE;
478 sb->s_blocksize = PAGE_CACHE_SIZE;
479 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
480 sb->s_magic = BTRFS_SUPER_MAGIC; 493 sb->s_magic = BTRFS_SUPER_MAGIC;
481 sb->s_op = &btrfs_super_ops; 494 sb->s_op = &btrfs_super_ops;
482 sb->s_time_gran = 1; 495 sb->s_time_gran = 1;
483 496
484 bh = sb_bread(sb, BTRFS_SUPER_INFO_OFFSET / sb->s_blocksize); 497 root = open_ctree(sb);
485 if (!bh) {
486 printk("btrfs: unable to read on disk super\n");
487 return -EIO;
488 }
489 disk_super = (struct btrfs_super_block *)bh->b_data;
490 root = open_ctree(sb, bh, disk_super);
491 498
492 if (!root) { 499 if (!root) {
493 printk("btrfs: open_ctree failed\n"); 500 printk("btrfs: open_ctree failed\n");
@@ -533,6 +540,7 @@ static void fill_inode_item(struct btrfs_inode_item *item,
533 btrfs_set_timespec_nsec(&item->ctime, inode->i_ctime.tv_nsec); 540 btrfs_set_timespec_nsec(&item->ctime, inode->i_ctime.tv_nsec);
534 btrfs_set_inode_nblocks(item, inode->i_blocks); 541 btrfs_set_inode_nblocks(item, inode->i_blocks);
535 btrfs_set_inode_generation(item, inode->i_generation); 542 btrfs_set_inode_generation(item, inode->i_generation);
543 check_inode(inode);
536} 544}
537 545
538static int btrfs_update_inode(struct btrfs_trans_handle *trans, 546static int btrfs_update_inode(struct btrfs_trans_handle *trans,
@@ -560,6 +568,7 @@ static int btrfs_update_inode(struct btrfs_trans_handle *trans,
560 btrfs_mark_buffer_dirty(path.nodes[0]); 568 btrfs_mark_buffer_dirty(path.nodes[0]);
561failed: 569failed:
562 btrfs_release_path(root, &path); 570 btrfs_release_path(root, &path);
571 check_inode(inode);
563 return 0; 572 return 0;
564} 573}
565 574
@@ -577,6 +586,7 @@ static int btrfs_write_inode(struct inode *inode, int wait)
577 else 586 else
578 btrfs_end_transaction(trans, root); 587 btrfs_end_transaction(trans, root);
579 mutex_unlock(&root->fs_info->fs_mutex); 588 mutex_unlock(&root->fs_info->fs_mutex);
589 check_inode(inode);
580 return ret; 590 return ret;
581} 591}
582 592
@@ -594,6 +604,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
594 if (!inode) 604 if (!inode)
595 return ERR_PTR(-ENOMEM); 605 return ERR_PTR(-ENOMEM);
596 606
607 check_inode(inode);
597 ret = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid); 608 ret = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid);
598 BUG_ON(ret); 609 BUG_ON(ret);
599 610
@@ -616,6 +627,8 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
616 BUG_ON(ret); 627 BUG_ON(ret);
617 628
618 insert_inode_hash(inode); 629 insert_inode_hash(inode);
630 check_inode(inode);
631 check_inode(dir);
619 return inode; 632 return inode;
620} 633}
621 634
@@ -632,7 +645,8 @@ static int btrfs_add_link(struct btrfs_trans_handle *trans,
632 ret = btrfs_update_inode(trans, btrfs_sb(inode->i_sb), 645 ret = btrfs_update_inode(trans, btrfs_sb(inode->i_sb),
633 dentry->d_parent->d_inode); 646 dentry->d_parent->d_inode);
634 } 647 }
635 648 check_inode(inode);
649 check_inode(dentry->d_parent->d_inode);
636 return ret; 650 return ret;
637} 651}
638 652
@@ -644,6 +658,9 @@ static int btrfs_add_nondir(struct btrfs_trans_handle *trans,
644 d_instantiate(dentry, inode); 658 d_instantiate(dentry, inode);
645 return 0; 659 return 0;
646 } 660 }
661 if (err > 0)
662 err = -EEXIST;
663 check_inode(inode);
647 return err; 664 return err;
648} 665}
649 666
@@ -675,6 +692,9 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
675out_unlock: 692out_unlock:
676 btrfs_end_transaction(trans, root); 693 btrfs_end_transaction(trans, root);
677 mutex_unlock(&root->fs_info->fs_mutex); 694 mutex_unlock(&root->fs_info->fs_mutex);
695 check_inode(inode);
696 check_inode(dir);
697
678 if (drop_inode) { 698 if (drop_inode) {
679 inode_dec_link_count(inode); 699 inode_dec_link_count(inode);
680 iput(inode); 700 iput(inode);
@@ -755,11 +775,11 @@ static int btrfs_sync_fs(struct super_block *sb, int wait)
755 775
756 sb->s_dirt = 0; 776 sb->s_dirt = 0;
757 if (!wait) { 777 if (!wait) {
758 filemap_flush(root->fs_info->btree_inode->i_mapping); 778 // filemap_flush(root->fs_info->btree_inode->i_mapping);
779 filemap_flush(root->fs_info->sb->s_bdev->bd_inode->i_mapping);
759 return 0; 780 return 0;
760 } 781 }
761 filemap_write_and_wait(root->fs_info->btree_inode->i_mapping); 782 filemap_write_and_wait(root->fs_info->sb->s_bdev->bd_inode->i_mapping);
762
763 mutex_lock(&root->fs_info->fs_mutex); 783 mutex_lock(&root->fs_info->fs_mutex);
764 trans = btrfs_start_transaction(root, 1); 784 trans = btrfs_start_transaction(root, 1);
765 ret = btrfs_commit_transaction(trans, root); 785 ret = btrfs_commit_transaction(trans, root);
@@ -1242,6 +1262,95 @@ static ssize_t btrfs_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
1242 return retval; 1262 return retval;
1243} 1263}
1244 1264
1265static struct kmem_cache *btrfs_inode_cachep;
1266struct kmem_cache *btrfs_trans_handle_cachep;
1267struct kmem_cache *btrfs_transaction_cachep;
1268struct kmem_cache *btrfs_bit_radix_cachep;
1269struct kmem_cache *btrfs_path_cachep;
1270
1271/*
1272 * Called inside transaction, so use GFP_NOFS
1273 */
1274static struct inode *btrfs_alloc_inode(struct super_block *sb)
1275{
1276 struct btrfs_inode *ei;
1277
1278 ei = kmem_cache_alloc(btrfs_inode_cachep, GFP_NOFS);
1279 if (!ei)
1280 return NULL;
1281 ei->magic = 0xDEADBEEF;
1282 ei->magic2 = 0xDEADBEAF;
1283 return &ei->vfs_inode;
1284}
1285
1286static void btrfs_destroy_inode(struct inode *inode)
1287{
1288 struct btrfs_inode *ei = BTRFS_I(inode);
1289 WARN_ON(ei->magic != 0xDEADBEEF);
1290 WARN_ON(ei->magic2 != 0xDEADBEAF);
1291 WARN_ON(!list_empty(&inode->i_dentry));
1292 WARN_ON(inode->i_ino == 1);
1293 WARN_ON(inode->i_data.nrpages);
1294
1295 ei->magic = 0;
1296 ei->magic2 = 0;
1297 kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode));
1298}
1299
1300static void init_once(void * foo, struct kmem_cache * cachep,
1301 unsigned long flags)
1302{
1303 struct btrfs_inode *ei = (struct btrfs_inode *) foo;
1304
1305 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
1306 SLAB_CTOR_CONSTRUCTOR) {
1307 inode_init_once(&ei->vfs_inode);
1308 }
1309}
1310
1311static int init_inodecache(void)
1312{
1313 btrfs_inode_cachep = kmem_cache_create("btrfs_inode_cache",
1314 sizeof(struct btrfs_inode),
1315 0, (SLAB_RECLAIM_ACCOUNT|
1316 SLAB_MEM_SPREAD),
1317 init_once, NULL);
1318 btrfs_trans_handle_cachep = kmem_cache_create("btrfs_trans_handle_cache",
1319 sizeof(struct btrfs_trans_handle),
1320 0, (SLAB_RECLAIM_ACCOUNT|
1321 SLAB_MEM_SPREAD),
1322 NULL, NULL);
1323 btrfs_transaction_cachep = kmem_cache_create("btrfs_transaction_cache",
1324 sizeof(struct btrfs_transaction),
1325 0, (SLAB_RECLAIM_ACCOUNT|
1326 SLAB_MEM_SPREAD),
1327 NULL, NULL);
1328 btrfs_path_cachep = kmem_cache_create("btrfs_path_cache",
1329 sizeof(struct btrfs_transaction),
1330 0, (SLAB_RECLAIM_ACCOUNT|
1331 SLAB_MEM_SPREAD),
1332 NULL, NULL);
1333 btrfs_bit_radix_cachep = kmem_cache_create("btrfs_radix",
1334 256,
1335 0, (SLAB_RECLAIM_ACCOUNT|
1336 SLAB_MEM_SPREAD |
1337 SLAB_DESTROY_BY_RCU),
1338 NULL, NULL);
1339 if (btrfs_inode_cachep == NULL || btrfs_trans_handle_cachep == NULL ||
1340 btrfs_transaction_cachep == NULL || btrfs_bit_radix_cachep == NULL)
1341 return -ENOMEM;
1342 return 0;
1343}
1344
1345static void destroy_inodecache(void)
1346{
1347 kmem_cache_destroy(btrfs_inode_cachep);
1348 kmem_cache_destroy(btrfs_trans_handle_cachep);
1349 kmem_cache_destroy(btrfs_transaction_cachep);
1350 kmem_cache_destroy(btrfs_bit_radix_cachep);
1351 kmem_cache_destroy(btrfs_path_cachep);
1352}
1353
1245static int btrfs_get_sb(struct file_system_type *fs_type, 1354static int btrfs_get_sb(struct file_system_type *fs_type,
1246 int flags, const char *dev_name, void *data, struct vfsmount *mnt) 1355 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
1247{ 1356{
@@ -1265,6 +1374,8 @@ static struct super_operations btrfs_super_ops = {
1265 .write_super = btrfs_write_super, 1374 .write_super = btrfs_write_super,
1266 .sync_fs = btrfs_sync_fs, 1375 .sync_fs = btrfs_sync_fs,
1267 .write_inode = btrfs_write_inode, 1376 .write_inode = btrfs_write_inode,
1377 .alloc_inode = btrfs_alloc_inode,
1378 .destroy_inode = btrfs_destroy_inode,
1268}; 1379};
1269 1380
1270static struct inode_operations btrfs_dir_inode_operations = { 1381static struct inode_operations btrfs_dir_inode_operations = {
@@ -1305,12 +1416,17 @@ static struct file_operations btrfs_file_operations = {
1305 1416
1306static int __init init_btrfs_fs(void) 1417static int __init init_btrfs_fs(void)
1307{ 1418{
1419 int err;
1308 printk("btrfs loaded!\n"); 1420 printk("btrfs loaded!\n");
1421 err = init_inodecache();
1422 if (err)
1423 return err;
1309 return register_filesystem(&btrfs_fs_type); 1424 return register_filesystem(&btrfs_fs_type);
1310} 1425}
1311 1426
1312static void __exit exit_btrfs_fs(void) 1427static void __exit exit_btrfs_fs(void)
1313{ 1428{
1429 destroy_inodecache();
1314 unregister_filesystem(&btrfs_fs_type); 1430 unregister_filesystem(&btrfs_fs_type);
1315 printk("btrfs unloaded\n"); 1431 printk("btrfs unloaded\n");
1316} 1432}
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 84c4e278ce2e..72b52e1e0b1b 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -5,13 +5,20 @@
5#include "transaction.h" 5#include "transaction.h"
6 6
7static int total_trans = 0; 7static int total_trans = 0;
8extern struct kmem_cache *btrfs_trans_handle_cachep;
9extern struct kmem_cache *btrfs_transaction_cachep;
10
11#define TRANS_MAGIC 0xE1E10E
8static void put_transaction(struct btrfs_transaction *transaction) 12static void put_transaction(struct btrfs_transaction *transaction)
9{ 13{
14 WARN_ON(transaction->use_count == 0);
10 transaction->use_count--; 15 transaction->use_count--;
16 WARN_ON(transaction->magic != TRANS_MAGIC);
11 if (transaction->use_count == 0) { 17 if (transaction->use_count == 0) {
12 WARN_ON(total_trans == 0); 18 WARN_ON(total_trans == 0);
13 total_trans--; 19 total_trans--;
14 kfree(transaction); 20 memset(transaction, 0, sizeof(*transaction));
21 kmem_cache_free(btrfs_transaction_cachep, transaction);
15 } 22 }
16} 23}
17 24
@@ -20,7 +27,8 @@ static int join_transaction(struct btrfs_root *root)
20 struct btrfs_transaction *cur_trans; 27 struct btrfs_transaction *cur_trans;
21 cur_trans = root->fs_info->running_transaction; 28 cur_trans = root->fs_info->running_transaction;
22 if (!cur_trans) { 29 if (!cur_trans) {
23 cur_trans = kmalloc(sizeof(*cur_trans), GFP_NOFS); 30 cur_trans = kmem_cache_alloc(btrfs_transaction_cachep,
31 GFP_NOFS);
24 total_trans++; 32 total_trans++;
25 BUG_ON(!cur_trans); 33 BUG_ON(!cur_trans);
26 root->fs_info->running_transaction = cur_trans; 34 root->fs_info->running_transaction = cur_trans;
@@ -28,6 +36,7 @@ static int join_transaction(struct btrfs_root *root)
28 cur_trans->transid = root->root_key.offset + 1; 36 cur_trans->transid = root->root_key.offset + 1;
29 init_waitqueue_head(&cur_trans->writer_wait); 37 init_waitqueue_head(&cur_trans->writer_wait);
30 init_waitqueue_head(&cur_trans->commit_wait); 38 init_waitqueue_head(&cur_trans->commit_wait);
39 cur_trans->magic = TRANS_MAGIC;
31 cur_trans->in_commit = 0; 40 cur_trans->in_commit = 0;
32 cur_trans->use_count = 1; 41 cur_trans->use_count = 1;
33 cur_trans->commit_done = 0; 42 cur_trans->commit_done = 0;
@@ -39,7 +48,8 @@ static int join_transaction(struct btrfs_root *root)
39struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root, 48struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
40 int num_blocks) 49 int num_blocks)
41{ 50{
42 struct btrfs_trans_handle *h = kmalloc(sizeof(*h), GFP_NOFS); 51 struct btrfs_trans_handle *h =
52 kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS);
43 int ret; 53 int ret;
44 54
45 mutex_lock(&root->fs_info->trans_mutex); 55 mutex_lock(&root->fs_info->trans_mutex);
@@ -51,6 +61,7 @@ struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
51 h->blocks_used = 0; 61 h->blocks_used = 0;
52 root->fs_info->running_transaction->use_count++; 62 root->fs_info->running_transaction->use_count++;
53 mutex_unlock(&root->fs_info->trans_mutex); 63 mutex_unlock(&root->fs_info->trans_mutex);
64 h->magic = h->magic2 = TRANS_MAGIC;
54 return h; 65 return h;
55} 66}
56 67
@@ -58,6 +69,8 @@ int btrfs_end_transaction(struct btrfs_trans_handle *trans,
58 struct btrfs_root *root) 69 struct btrfs_root *root)
59{ 70{
60 struct btrfs_transaction *cur_trans; 71 struct btrfs_transaction *cur_trans;
72 WARN_ON(trans->magic != TRANS_MAGIC);
73 WARN_ON(trans->magic2 != TRANS_MAGIC);
61 mutex_lock(&root->fs_info->trans_mutex); 74 mutex_lock(&root->fs_info->trans_mutex);
62 cur_trans = root->fs_info->running_transaction; 75 cur_trans = root->fs_info->running_transaction;
63 WARN_ON(cur_trans->num_writers < 1); 76 WARN_ON(cur_trans->num_writers < 1);
@@ -67,7 +80,7 @@ int btrfs_end_transaction(struct btrfs_trans_handle *trans,
67 put_transaction(cur_trans); 80 put_transaction(cur_trans);
68 mutex_unlock(&root->fs_info->trans_mutex); 81 mutex_unlock(&root->fs_info->trans_mutex);
69 memset(trans, 0, sizeof(*trans)); 82 memset(trans, 0, sizeof(*trans));
70 kfree(trans); 83 kmem_cache_free(btrfs_trans_handle_cachep, trans);
71 return 0; 84 return 0;
72} 85}
73 86
@@ -75,7 +88,7 @@ int btrfs_end_transaction(struct btrfs_trans_handle *trans,
75int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, 88int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
76 struct btrfs_root *root) 89 struct btrfs_root *root)
77{ 90{
78 filemap_write_and_wait(root->fs_info->btree_inode->i_mapping); 91 filemap_write_and_wait(root->fs_info->sb->s_bdev->bd_inode->i_mapping);
79 return 0; 92 return 0;
80} 93}
81 94
@@ -137,6 +150,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
137 150
138 mutex_lock(&root->fs_info->trans_mutex); 151 mutex_lock(&root->fs_info->trans_mutex);
139 if (trans->transaction->in_commit) { 152 if (trans->transaction->in_commit) {
153printk("already in commit!, waiting\n");
140 cur_trans = trans->transaction; 154 cur_trans = trans->transaction;
141 trans->transaction->use_count++; 155 trans->transaction->use_count++;
142 btrfs_end_transaction(trans, root); 156 btrfs_end_transaction(trans, root);
@@ -146,7 +160,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
146 mutex_unlock(&root->fs_info->trans_mutex); 160 mutex_unlock(&root->fs_info->trans_mutex);
147 return 0; 161 return 0;
148 } 162 }
163 cur_trans = trans->transaction;
164 trans->transaction->in_commit = 1;
149 while (trans->transaction->num_writers > 1) { 165 while (trans->transaction->num_writers > 1) {
166 WARN_ON(cur_trans != trans->transaction);
150 prepare_to_wait(&trans->transaction->writer_wait, &wait, 167 prepare_to_wait(&trans->transaction->writer_wait, &wait,
151 TASK_UNINTERRUPTIBLE); 168 TASK_UNINTERRUPTIBLE);
152 if (trans->transaction->num_writers <= 1) 169 if (trans->transaction->num_writers <= 1)
@@ -154,15 +171,15 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
154 mutex_unlock(&root->fs_info->trans_mutex); 171 mutex_unlock(&root->fs_info->trans_mutex);
155 schedule(); 172 schedule();
156 mutex_lock(&root->fs_info->trans_mutex); 173 mutex_lock(&root->fs_info->trans_mutex);
174 finish_wait(&trans->transaction->writer_wait, &wait);
157 } 175 }
158 finish_wait(&trans->transaction->writer_wait, &wait); 176 finish_wait(&trans->transaction->writer_wait, &wait);
159 177 WARN_ON(cur_trans != trans->transaction);
160 if (root->node != root->commit_root) { 178 if (root->node != root->commit_root) {
161 memcpy(&snap_key, &root->root_key, sizeof(snap_key)); 179 memcpy(&snap_key, &root->root_key, sizeof(snap_key));
162 root->root_key.offset++; 180 root->root_key.offset++;
163 } 181 }
164 182
165
166 if (btrfs_root_blocknr(&root->root_item) != root->node->b_blocknr) { 183 if (btrfs_root_blocknr(&root->root_item) != root->node->b_blocknr) {
167 btrfs_set_root_blocknr(&root->root_item, root->node->b_blocknr); 184 btrfs_set_root_blocknr(&root->root_item, root->node->b_blocknr);
168 ret = btrfs_insert_root(trans, root->fs_info->tree_root, 185 ret = btrfs_insert_root(trans, root->fs_info->tree_root,
@@ -172,22 +189,21 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
172 189
173 ret = btrfs_commit_tree_roots(trans, root); 190 ret = btrfs_commit_tree_roots(trans, root);
174 BUG_ON(ret); 191 BUG_ON(ret);
175
176 cur_trans = root->fs_info->running_transaction; 192 cur_trans = root->fs_info->running_transaction;
177 root->fs_info->running_transaction = NULL; 193 root->fs_info->running_transaction = NULL;
178 mutex_unlock(&root->fs_info->trans_mutex); 194 mutex_unlock(&root->fs_info->trans_mutex);
179
180 ret = btrfs_write_and_wait_transaction(trans, root); 195 ret = btrfs_write_and_wait_transaction(trans, root);
181 BUG_ON(ret); 196 BUG_ON(ret);
182 197
183 write_ctree_super(trans, root); 198 write_ctree_super(trans, root);
184 btrfs_finish_extent_commit(trans, root); 199 btrfs_finish_extent_commit(trans, root);
185 mutex_lock(&root->fs_info->trans_mutex); 200 mutex_lock(&root->fs_info->trans_mutex);
201 cur_trans->commit_done = 1;
202 wake_up(&cur_trans->commit_wait);
186 put_transaction(cur_trans); 203 put_transaction(cur_trans);
187 put_transaction(cur_trans); 204 put_transaction(cur_trans);
188 mutex_unlock(&root->fs_info->trans_mutex); 205 mutex_unlock(&root->fs_info->trans_mutex);
189 kfree(trans); 206 kmem_cache_free(btrfs_trans_handle_cachep, trans);
190
191 if (root->node != root->commit_root) { 207 if (root->node != root->commit_root) {
192 trans = btrfs_start_transaction(root, 1); 208 trans = btrfs_start_transaction(root, 1);
193 snap = root->commit_root; 209 snap = root->commit_root;
@@ -203,7 +219,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
203 ret = btrfs_end_transaction(trans, root); 219 ret = btrfs_end_transaction(trans, root);
204 BUG_ON(ret); 220 BUG_ON(ret);
205 } 221 }
206
207 return ret; 222 return ret;
208} 223}
209 224
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
index 7e6c08a0accd..4f1496ae6f24 100644
--- a/fs/btrfs/transaction.h
+++ b/fs/btrfs/transaction.h
@@ -7,15 +7,18 @@ struct btrfs_transaction {
7 int in_commit; 7 int in_commit;
8 int use_count; 8 int use_count;
9 int commit_done; 9 int commit_done;
10 int magic;
10 wait_queue_head_t writer_wait; 11 wait_queue_head_t writer_wait;
11 wait_queue_head_t commit_wait; 12 wait_queue_head_t commit_wait;
12}; 13};
13 14
14struct btrfs_trans_handle { 15struct btrfs_trans_handle {
16 int magic;
15 u64 transid; 17 u64 transid;
16 unsigned long blocks_reserved; 18 unsigned long blocks_reserved;
17 unsigned long blocks_used; 19 unsigned long blocks_used;
18 struct btrfs_transaction *transaction; 20 struct btrfs_transaction *transaction;
21 int magic2;
19}; 22};
20 23
21 24