aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/mballoc.c
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2008-02-10 01:10:04 -0500
committerTheodore Ts'o <tytso@mit.edu>2008-02-10 01:10:04 -0500
commit26346ff681cb42c1436ed09c44dcae4809470dab (patch)
tree1f1b8bff59e9aedbd0ad80a51317d5c1e5cbad91 /fs/ext4/mballoc.c
parent256bdb497c6f562462f1e89fc8e1409f61ef40cb (diff)
ext4: Don't panic in case of corrupt bitmap
Multiblock allocator calls BUG_ON in many case if the free and used blocks count obtained looking at the bitmap is different from what the allocator internally accounted for. Use ext4_error in such case and don't panic the system. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: Mingming Cao <cmm@us.ibm.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/mballoc.c')
-rw-r--r--fs/ext4/mballoc.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 5e3c35191412..dd0fcfcb35ce 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -681,7 +681,6 @@ static void *mb_find_buddy(struct ext4_buddy *e4b, int order, int *max)
681{ 681{
682 char *bb; 682 char *bb;
683 683
684 /* FIXME!! is this needed */
685 BUG_ON(EXT4_MB_BITMAP(e4b) == EXT4_MB_BUDDY(e4b)); 684 BUG_ON(EXT4_MB_BITMAP(e4b) == EXT4_MB_BUDDY(e4b));
686 BUG_ON(max == NULL); 685 BUG_ON(max == NULL);
687 686
@@ -965,7 +964,7 @@ static void ext4_mb_generate_buddy(struct super_block *sb,
965 grp->bb_fragments = fragments; 964 grp->bb_fragments = fragments;
966 965
967 if (free != grp->bb_free) { 966 if (free != grp->bb_free) {
968 printk(KERN_DEBUG 967 ext4_error(sb, __FUNCTION__,
969 "EXT4-fs: group %lu: %u blocks in bitmap, %u in gd\n", 968 "EXT4-fs: group %lu: %u blocks in bitmap, %u in gd\n",
970 group, free, grp->bb_free); 969 group, free, grp->bb_free);
971 grp->bb_free = free; 970 grp->bb_free = free;
@@ -1822,13 +1821,24 @@ static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac,
1822 i = ext4_find_next_zero_bit(bitmap, 1821 i = ext4_find_next_zero_bit(bitmap,
1823 EXT4_BLOCKS_PER_GROUP(sb), i); 1822 EXT4_BLOCKS_PER_GROUP(sb), i);
1824 if (i >= EXT4_BLOCKS_PER_GROUP(sb)) { 1823 if (i >= EXT4_BLOCKS_PER_GROUP(sb)) {
1825 BUG_ON(free != 0); 1824 /*
1825 * IF we corrupt the bitmap we won't find any
1826 * free blocks even though group info says we
1827 * we have free blocks
1828 */
1829 ext4_error(sb, __FUNCTION__, "%d free blocks as per "
1830 "group info. But bitmap says 0\n",
1831 free);
1826 break; 1832 break;
1827 } 1833 }
1828 1834
1829 mb_find_extent(e4b, 0, i, ac->ac_g_ex.fe_len, &ex); 1835 mb_find_extent(e4b, 0, i, ac->ac_g_ex.fe_len, &ex);
1830 BUG_ON(ex.fe_len <= 0); 1836 BUG_ON(ex.fe_len <= 0);
1831 BUG_ON(free < ex.fe_len); 1837 if (free < ex.fe_len) {
1838 ext4_error(sb, __FUNCTION__, "%d free blocks as per "
1839 "group info. But got %d blocks\n",
1840 free, ex.fe_len);
1841 }
1832 1842
1833 ext4_mb_measure_extent(ac, &ex, e4b); 1843 ext4_mb_measure_extent(ac, &ex, e4b);
1834 1844
@@ -3363,13 +3373,10 @@ static void ext4_mb_use_group_pa(struct ext4_allocation_context *ac,
3363 ac->ac_pa = pa; 3373 ac->ac_pa = pa;
3364 3374
3365 /* we don't correct pa_pstart or pa_plen here to avoid 3375 /* we don't correct pa_pstart or pa_plen here to avoid
3366 * possible race when tte group is being loaded concurrently 3376 * possible race when the group is being loaded concurrently
3367 * instead we correct pa later, after blocks are marked 3377 * instead we correct pa later, after blocks are marked
3368 * in on-disk bitmap -- see ext4_mb_release_context() */ 3378 * in on-disk bitmap -- see ext4_mb_release_context()
3369 /* 3379 * Other CPUs are prevented from allocating from this pa by lg_mutex
3370 * FIXME!! but the other CPUs can look at this particular
3371 * pa and think that it have enought free blocks if we
3372 * don't update pa_free here right ?
3373 */ 3380 */
3374 mb_debug("use %u/%u from group pa %p\n", pa->pa_lstart-len, len, pa); 3381 mb_debug("use %u/%u from group pa %p\n", pa->pa_lstart-len, len, pa);
3375} 3382}
@@ -3758,13 +3765,13 @@ static int ext4_mb_release_inode_pa(struct ext4_buddy *e4b,
3758 bit = next + 1; 3765 bit = next + 1;
3759 } 3766 }
3760 if (free != pa->pa_free) { 3767 if (free != pa->pa_free) {
3761 printk(KERN_ERR "pa %p: logic %lu, phys. %lu, len %lu\n", 3768 printk(KERN_CRIT "pa %p: logic %lu, phys. %lu, len %lu\n",
3762 pa, (unsigned long) pa->pa_lstart, 3769 pa, (unsigned long) pa->pa_lstart,
3763 (unsigned long) pa->pa_pstart, 3770 (unsigned long) pa->pa_pstart,
3764 (unsigned long) pa->pa_len); 3771 (unsigned long) pa->pa_len);
3765 printk(KERN_ERR "free %u, pa_free %u\n", free, pa->pa_free); 3772 ext4_error(sb, __FUNCTION__, "free %u, pa_free %u\n",
3773 free, pa->pa_free);
3766 } 3774 }
3767 BUG_ON(free != pa->pa_free);
3768 atomic_add(free, &sbi->s_mb_discarded); 3775 atomic_add(free, &sbi->s_mb_discarded);
3769 if (ac) 3776 if (ac)
3770 kmem_cache_free(ext4_ac_cachep, ac); 3777 kmem_cache_free(ext4_ac_cachep, ac);
@@ -4435,7 +4442,7 @@ void ext4_mb_free_blocks(handle_t *handle, struct inode *inode,
4435 unsigned long block, unsigned long count, 4442 unsigned long block, unsigned long count,
4436 int metadata, unsigned long *freed) 4443 int metadata, unsigned long *freed)
4437{ 4444{
4438 struct buffer_head *bitmap_bh = 0; 4445 struct buffer_head *bitmap_bh = NULL;
4439 struct super_block *sb = inode->i_sb; 4446 struct super_block *sb = inode->i_sb;
4440 struct ext4_allocation_context *ac = NULL; 4447 struct ext4_allocation_context *ac = NULL;
4441 struct ext4_group_desc *gdp; 4448 struct ext4_group_desc *gdp;