diff options
Diffstat (limited to 'fs/ext3/ialloc.c')
-rw-r--r-- | fs/ext3/ialloc.c | 58 |
1 files changed, 35 insertions, 23 deletions
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index 1bc8cd89c51d..58ae2f943f12 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c | |||
@@ -642,14 +642,15 @@ struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino) | |||
642 | unsigned long max_ino = le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count); | 642 | unsigned long max_ino = le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count); |
643 | unsigned long block_group; | 643 | unsigned long block_group; |
644 | int bit; | 644 | int bit; |
645 | struct buffer_head *bitmap_bh = NULL; | 645 | struct buffer_head *bitmap_bh; |
646 | struct inode *inode = NULL; | 646 | struct inode *inode = NULL; |
647 | long err = -EIO; | ||
647 | 648 | ||
648 | /* Error cases - e2fsck has already cleaned up for us */ | 649 | /* Error cases - e2fsck has already cleaned up for us */ |
649 | if (ino > max_ino) { | 650 | if (ino > max_ino) { |
650 | ext3_warning(sb, __FUNCTION__, | 651 | ext3_warning(sb, __FUNCTION__, |
651 | "bad orphan ino %lu! e2fsck was run?", ino); | 652 | "bad orphan ino %lu! e2fsck was run?", ino); |
652 | goto out; | 653 | goto error; |
653 | } | 654 | } |
654 | 655 | ||
655 | block_group = (ino - 1) / EXT3_INODES_PER_GROUP(sb); | 656 | block_group = (ino - 1) / EXT3_INODES_PER_GROUP(sb); |
@@ -658,38 +659,49 @@ struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino) | |||
658 | if (!bitmap_bh) { | 659 | if (!bitmap_bh) { |
659 | ext3_warning(sb, __FUNCTION__, | 660 | ext3_warning(sb, __FUNCTION__, |
660 | "inode bitmap error for orphan %lu", ino); | 661 | "inode bitmap error for orphan %lu", ino); |
661 | goto out; | 662 | goto error; |
662 | } | 663 | } |
663 | 664 | ||
664 | /* Having the inode bit set should be a 100% indicator that this | 665 | /* Having the inode bit set should be a 100% indicator that this |
665 | * is a valid orphan (no e2fsck run on fs). Orphans also include | 666 | * is a valid orphan (no e2fsck run on fs). Orphans also include |
666 | * inodes that were being truncated, so we can't check i_nlink==0. | 667 | * inodes that were being truncated, so we can't check i_nlink==0. |
667 | */ | 668 | */ |
668 | if (!ext3_test_bit(bit, bitmap_bh->b_data) || | 669 | if (!ext3_test_bit(bit, bitmap_bh->b_data)) |
669 | !(inode = iget(sb, ino)) || is_bad_inode(inode) || | 670 | goto bad_orphan; |
670 | NEXT_ORPHAN(inode) > max_ino) { | 671 | |
671 | ext3_warning(sb, __FUNCTION__, | 672 | inode = ext3_iget(sb, ino); |
672 | "bad orphan inode %lu! e2fsck was run?", ino); | 673 | if (IS_ERR(inode)) |
673 | printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%llu) = %d\n", | 674 | goto iget_failed; |
674 | bit, (unsigned long long)bitmap_bh->b_blocknr, | 675 | |
675 | ext3_test_bit(bit, bitmap_bh->b_data)); | 676 | if (NEXT_ORPHAN(inode) > max_ino) |
676 | printk(KERN_NOTICE "inode=%p\n", inode); | 677 | goto bad_orphan; |
677 | if (inode) { | 678 | brelse(bitmap_bh); |
678 | printk(KERN_NOTICE "is_bad_inode(inode)=%d\n", | 679 | return inode; |
679 | is_bad_inode(inode)); | 680 | |
680 | printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%u\n", | 681 | iget_failed: |
681 | NEXT_ORPHAN(inode)); | 682 | err = PTR_ERR(inode); |
682 | printk(KERN_NOTICE "max_ino=%lu\n", max_ino); | 683 | inode = NULL; |
683 | } | 684 | bad_orphan: |
685 | ext3_warning(sb, __FUNCTION__, | ||
686 | "bad orphan inode %lu! e2fsck was run?", ino); | ||
687 | printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%llu) = %d\n", | ||
688 | bit, (unsigned long long)bitmap_bh->b_blocknr, | ||
689 | ext3_test_bit(bit, bitmap_bh->b_data)); | ||
690 | printk(KERN_NOTICE "inode=%p\n", inode); | ||
691 | if (inode) { | ||
692 | printk(KERN_NOTICE "is_bad_inode(inode)=%d\n", | ||
693 | is_bad_inode(inode)); | ||
694 | printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%u\n", | ||
695 | NEXT_ORPHAN(inode)); | ||
696 | printk(KERN_NOTICE "max_ino=%lu\n", max_ino); | ||
684 | /* Avoid freeing blocks if we got a bad deleted inode */ | 697 | /* Avoid freeing blocks if we got a bad deleted inode */ |
685 | if (inode && inode->i_nlink == 0) | 698 | if (inode->i_nlink == 0) |
686 | inode->i_blocks = 0; | 699 | inode->i_blocks = 0; |
687 | iput(inode); | 700 | iput(inode); |
688 | inode = NULL; | ||
689 | } | 701 | } |
690 | out: | ||
691 | brelse(bitmap_bh); | 702 | brelse(bitmap_bh); |
692 | return inode; | 703 | error: |
704 | return ERR_PTR(err); | ||
693 | } | 705 | } |
694 | 706 | ||
695 | unsigned long ext3_count_free_inodes (struct super_block * sb) | 707 | unsigned long ext3_count_free_inodes (struct super_block * sb) |