diff options
Diffstat (limited to 'fs/ext4/mballoc.c')
| -rw-r--r-- | fs/ext4/mballoc.c | 13 | 
1 files changed, 9 insertions, 4 deletions
| diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 4415beeb0b62..9f61e62f435f 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -1447,7 +1447,7 @@ static void ext4_mb_measure_extent(struct ext4_allocation_context *ac,  	struct ext4_free_extent *gex = &ac->ac_g_ex;  	BUG_ON(ex->fe_len <= 0); -	BUG_ON(ex->fe_len >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); +	BUG_ON(ex->fe_len > EXT4_BLOCKS_PER_GROUP(ac->ac_sb));  	BUG_ON(ex->fe_start >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb));  	BUG_ON(ac->ac_status != AC_STATUS_CONTINUE); @@ -3292,7 +3292,7 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,  	}  	BUG_ON(start + size <= ac->ac_o_ex.fe_logical &&  			start > ac->ac_o_ex.fe_logical); -	BUG_ON(size <= 0 || size >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); +	BUG_ON(size <= 0 || size > EXT4_BLOCKS_PER_GROUP(ac->ac_sb));  	/* now prepare goal request */ @@ -3589,6 +3589,7 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac,  			struct super_block *sb, struct ext4_prealloc_space *pa)  {  	ext4_group_t grp; +	ext4_fsblk_t grp_blk;  	if (!atomic_dec_and_test(&pa->pa_count) || pa->pa_free != 0)  		return; @@ -3603,8 +3604,12 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac,  	pa->pa_deleted = 1;  	spin_unlock(&pa->pa_lock); -	/* -1 is to protect from crossing allocation group */ -	ext4_get_group_no_and_offset(sb, pa->pa_pstart - 1, &grp, NULL); +	grp_blk = pa->pa_pstart; +	/* If linear, pa_pstart may be in the next group when pa is used up */ +	if (pa->pa_linear) +		grp_blk--; + +	ext4_get_group_no_and_offset(sb, grp_blk, &grp, NULL);  	/*  	 * possible race: |