aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/super.c
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/btrfs/super.c
parentd6025579531b7ea170ba283b171ff7a6bf7d0e12 (diff)
Btrfs: still corruption hunting
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r--fs/btrfs/super.c146
1 files changed, 131 insertions, 15 deletions
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}