diff options
Diffstat (limited to 'fs/ext4/ialloc.c')
-rw-r--r-- | fs/ext4/ialloc.c | 58 |
1 files changed, 35 insertions, 23 deletions
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 575b5215c808..da18a74b966a 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
@@ -782,14 +782,15 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino) | |||
782 | unsigned long max_ino = le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count); | 782 | unsigned long max_ino = le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count); |
783 | ext4_group_t block_group; | 783 | ext4_group_t block_group; |
784 | int bit; | 784 | int bit; |
785 | struct buffer_head *bitmap_bh = NULL; | 785 | struct buffer_head *bitmap_bh; |
786 | struct inode *inode = NULL; | 786 | struct inode *inode = NULL; |
787 | long err = -EIO; | ||
787 | 788 | ||
788 | /* Error cases - e2fsck has already cleaned up for us */ | 789 | /* Error cases - e2fsck has already cleaned up for us */ |
789 | if (ino > max_ino) { | 790 | if (ino > max_ino) { |
790 | ext4_warning(sb, __FUNCTION__, | 791 | ext4_warning(sb, __FUNCTION__, |
791 | "bad orphan ino %lu! e2fsck was run?", ino); | 792 | "bad orphan ino %lu! e2fsck was run?", ino); |
792 | goto out; | 793 | goto error; |
793 | } | 794 | } |
794 | 795 | ||
795 | block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb); | 796 | block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb); |
@@ -798,38 +799,49 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino) | |||
798 | if (!bitmap_bh) { | 799 | if (!bitmap_bh) { |
799 | ext4_warning(sb, __FUNCTION__, | 800 | ext4_warning(sb, __FUNCTION__, |
800 | "inode bitmap error for orphan %lu", ino); | 801 | "inode bitmap error for orphan %lu", ino); |
801 | goto out; | 802 | goto error; |
802 | } | 803 | } |
803 | 804 | ||
804 | /* Having the inode bit set should be a 100% indicator that this | 805 | /* Having the inode bit set should be a 100% indicator that this |
805 | * is a valid orphan (no e2fsck run on fs). Orphans also include | 806 | * is a valid orphan (no e2fsck run on fs). Orphans also include |
806 | * inodes that were being truncated, so we can't check i_nlink==0. | 807 | * inodes that were being truncated, so we can't check i_nlink==0. |
807 | */ | 808 | */ |
808 | if (!ext4_test_bit(bit, bitmap_bh->b_data) || | 809 | if (!ext4_test_bit(bit, bitmap_bh->b_data)) |
809 | !(inode = iget(sb, ino)) || is_bad_inode(inode) || | 810 | goto bad_orphan; |
810 | NEXT_ORPHAN(inode) > max_ino) { | 811 | |
811 | ext4_warning(sb, __FUNCTION__, | 812 | inode = ext4_iget(sb, ino); |
812 | "bad orphan inode %lu! e2fsck was run?", ino); | 813 | if (IS_ERR(inode)) |
813 | printk(KERN_NOTICE "ext4_test_bit(bit=%d, block=%llu) = %d\n", | 814 | goto iget_failed; |
814 | bit, (unsigned long long)bitmap_bh->b_blocknr, | 815 | |
815 | ext4_test_bit(bit, bitmap_bh->b_data)); | 816 | if (NEXT_ORPHAN(inode) > max_ino) |
816 | printk(KERN_NOTICE "inode=%p\n", inode); | 817 | goto bad_orphan; |
817 | if (inode) { | 818 | brelse(bitmap_bh); |
818 | printk(KERN_NOTICE "is_bad_inode(inode)=%d\n", | 819 | return inode; |
819 | is_bad_inode(inode)); | 820 | |
820 | printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%u\n", | 821 | iget_failed: |
821 | NEXT_ORPHAN(inode)); | 822 | err = PTR_ERR(inode); |
822 | printk(KERN_NOTICE "max_ino=%lu\n", max_ino); | 823 | inode = NULL; |
823 | } | 824 | bad_orphan: |
825 | ext4_warning(sb, __FUNCTION__, | ||
826 | "bad orphan inode %lu! e2fsck was run?", ino); | ||
827 | printk(KERN_NOTICE "ext4_test_bit(bit=%d, block=%llu) = %d\n", | ||
828 | bit, (unsigned long long)bitmap_bh->b_blocknr, | ||
829 | ext4_test_bit(bit, bitmap_bh->b_data)); | ||
830 | printk(KERN_NOTICE "inode=%p\n", inode); | ||
831 | if (inode) { | ||
832 | printk(KERN_NOTICE "is_bad_inode(inode)=%d\n", | ||
833 | is_bad_inode(inode)); | ||
834 | printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%u\n", | ||
835 | NEXT_ORPHAN(inode)); | ||
836 | printk(KERN_NOTICE "max_ino=%lu\n", max_ino); | ||
824 | /* Avoid freeing blocks if we got a bad deleted inode */ | 837 | /* Avoid freeing blocks if we got a bad deleted inode */ |
825 | if (inode && inode->i_nlink == 0) | 838 | if (inode->i_nlink == 0) |
826 | inode->i_blocks = 0; | 839 | inode->i_blocks = 0; |
827 | iput(inode); | 840 | iput(inode); |
828 | inode = NULL; | ||
829 | } | 841 | } |
830 | out: | ||
831 | brelse(bitmap_bh); | 842 | brelse(bitmap_bh); |
832 | return inode; | 843 | error: |
844 | return ERR_PTR(err); | ||
833 | } | 845 | } |
834 | 846 | ||
835 | unsigned long ext4_count_free_inodes (struct super_block * sb) | 847 | unsigned long ext4_count_free_inodes (struct super_block * sb) |