Bug 72181 - ext4_mb_generate_buddy:22764 clusters in bitmap, 22762 in gd
Summary: ext4_mb_generate_buddy:22764 clusters in bitmap, 22762 in gd
Status: NEW
Alias: None
Product: File System
Classification: Unclassified
Component: ext4 (show other bugs)
Hardware: IA-64 Linux
: P1 normal
Assignee: fs_ext4@kernel-bugs.osdl.org
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-03-16 04:17 UTC by WeiZhang
Modified: 2016-03-20 10:15 UTC (History)
3 users (show)

See Also:
Kernel Version: 3.2
Subsystem:
Regression: No
Bisected commit-id:


Attachments

Description WeiZhang 2014-03-16 04:17:02 UTC
From the log, I notice three messages like below:
kernel: EXT4-fs error (device sdc1): ext4_mb_generate_buddy:727: group 313828953 clusters in bitmap, 28952 in gd
kernel: EXT4-fs error (device sdc1): ext4_mb_generate_buddy:727: group 313722764 clusters in bitmap, 22762 in gd
kernel: EXT4-fs error (device sdc1): ext4_mb_generate_buddy:727: group 321819941 clusters in bitmap, 19940 in gd

I have used the patch with the commit number of b0dd6b70f0fda17ae9762fbb72d98e40a4f66556 (ext4: fix the free blocks calculation for ext3 file systems w/ uninit_bg) 

However, I think this is another problem. Because the free block calculated form bitmap is much larger than 32768 while clusters per group is 32768(I added some code in e2fsprogs and have confirmed the cluster size).

Analyze the code, it seems impossible and confused me. I think the freeblock it's to no way to be larger than max(32768). Maybe the function (mb_find_next_bit && mb_find_next_zero_bit) return a int type value  while "free " is  unsigned may cause such a problem? I can't confirm.

attachment:
........................................................................
static noinline_for_stack
void ext4_mb_generate_buddy(struct super_block *sb,
				void *buddy, void *bitmap, ext4_group_t group)
{
	struct ext4_group_info *grp = ext4_get_group_info(sb, group);
	ext4_grpblk_t max = EXT4_CLUSTERS_PER_GROUP(sb);
	ext4_grpblk_t i = 0;
	ext4_grpblk_t first;
	ext4_grpblk_t len;
	unsigned free = 0;
	unsigned fragments = 0;
	unsigned long long period = get_cycles();

	/* initialize buddy from bitmap which is aggregation
	 * of on-disk bitmap and preallocations */
	i = mb_find_next_zero_bit(bitmap, max, 0);
	grp->bb_first_free = i;
	while (i < max) {
		fragments++;
		first = i;
		i = mb_find_next_bit(bitmap, max, i);
		len = i - first;
		free += len;
		if (len > 1)
			ext4_mb_mark_free_simple(sb, buddy, first, len, grp);
		else
			grp->bb_counters[0]++;
		if (i < max)
			i = mb_find_next_zero_bit(bitmap, max, i);
	}
	grp->bb_fragments = fragments;

	if (free != grp->bb_free) {
		ext4_grp_locked_error(sb, group, 0, 0,
				      "%u clusters in bitmap, %u in gd",
				      free, grp->bb_free);
		/*
		 * If we intent to continue, we consider group descritor
		 * corrupt and update bb_free using bitmap value
		 */
		grp->bb_free = free;
	}
.........................................................
static inline int mb_find_next_bit(void *addr, int max, int start)
{
	int fix = 0, ret, tmpmax;
	addr = mb_correct_addr_and_bit(&fix, addr);
	tmpmax = max + fix;
	start += fix;

	ret = ext4_find_next_bit(addr, tmpmax, start) - fix;
	if (ret > max)
		return max;
	return ret;
}
............................................................
static inline int mb_find_next_zero_bit(void *addr, int max, int start)
{
	int fix = 0, ret, tmpmax;
	addr = mb_correct_addr_and_bit(&fix, addr);
	tmpmax = max + fix;
	start += fix;

	ret = ext4_find_next_zero_bit(addr, tmpmax, start) - fix;
	if (ret > max)
		return max;
	return ret;
}
..............................................
#define ext4_find_next_zero_bit		ext2_find_next_zero_bit
#define ext4_find_next_bit		ext2_find_next_bit
Comment 1 WeiZhang 2014-03-16 04:22:35 UTC
usually, we just get a wrong number of "free" from bitmap while bitmap is corrupted. but it should not larger than "max = EXT4_CLUSTERS_PER_GROUP(sb)" right?
Comment 2 WeiZhang 2014-03-17 02:08:42 UTC
(In reply to WeiZhang from comment #1)
> usually, we just get a wrong number of "free" from bitmap while bitmap is
> corrupted. but it should not larger than "max = EXT4_CLUSTERS_PER_GROUP(sb)"
> right?

i add some printk and confirmed there is some wrong in ext4_grp_locked_error. the "free" is in the right range. Seems that the bitmap is still corrupted with the patch(ext4: fix the free blocks calculation for ext3 file systems w/ uninit_bg). I will look into it right now. Thx
Comment 3 WeiZhang 2014-03-17 07:01:12 UTC
(In reply to WeiZhang from comment #1)
> usually, we just get a wrong number of "free" from bitmap while bitmap is
> corrupted. but it should not larger than "max = EXT4_CLUSTERS_PER_GROUP(sb)"
> right?

sorry, "EXT4-fs error (device sdc1): ext4_mb_generate_buddy:727: group 313828953 clusters in bitmap, 28952 in gd   " group 313828953 clusters = group 3138 28953 clusters". I make a mistake here..

Note You need to log in before you can comment on or make changes to this bug.