From: Sunil Mushran Date: Tue, 8 Nov 2011 21:00:19 +0000 (-0800) Subject: ocfs2: Tighten free bit calculation in the global bitmap X-Git-Tag: v2.6.39-400.9.0~575 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=2cd1ca35b44490e0300f275dad7aa8b0ba86085c;p=users%2Fjedix%2Flinux-maple.git ocfs2: Tighten free bit calculation in the global bitmap When clearing bits in the global bitmap, we do not test the current bit value. This patch tightens the code by considering the possiblity that the bit being cleared was already cleared. Now this should not happen. But we are seeing stray instances in which free bit count in the global bitmap exceeds the total bit count. In each instance the bitmap is correct. Only the free bit count is incorrect. This patch checks the current bit value and increments the free bit count only if the bit was previously set. It also prints information to allow us to debug further. Signed-off-by: Sunil Mushran --- diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index ba5d97e4a73e..4f7123c2d19d 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c @@ -2386,6 +2386,7 @@ static int ocfs2_block_group_clear_bits(handle_t *handle, int status; unsigned int tmp; struct ocfs2_group_desc *undo_bg = NULL; + unsigned int bits_cleared = 0; /* The caller got this descriptor from * ocfs2_read_group_descriptor(). Any corruption is a code bug. */ @@ -2413,13 +2414,27 @@ static int ocfs2_block_group_clear_bits(handle_t *handle, tmp = num_bits; while(tmp--) { - ocfs2_clear_bit((bit_off + tmp), - (unsigned long *) bg->bg_bitmap); + if (ocfs2_test_bit((bit_off + tmp), + (unsigned long *) bg->bg_bitmap)) { + ocfs2_clear_bit((bit_off + tmp), + (unsigned long *) bg->bg_bitmap); + bits_cleared++; + } if (undo_fn) undo_fn(bit_off + tmp, (unsigned long *) undo_bg->bg_bitmap); } - le16_add_cpu(&bg->bg_free_bits_count, num_bits); + + le16_add_cpu(&bg->bg_free_bits_count, bits_cleared); + + if (num_bits != bits_cleared) { + printk(KERN_NOTICE "ocfs2: Trying to clear %u bits at " + "offset %u in group descriptor # %llu (device %s), " + "needed to clear %u bits\n", num_bits, bit_off, + (unsigned long long)le64_to_cpu(bg->bg_blkno), + alloc_inode->i_sb->s_id, bits_cleared); + } + if (le16_to_cpu(bg->bg_free_bits_count) > le16_to_cpu(bg->bg_bits)) { ocfs2_error(alloc_inode->i_sb, "Group descriptor # %llu has bit" " count %u but claims %u are freed. num_bits %d",