aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/mballoc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/mballoc.c')
-rw-r--r--fs/ext4/mballoc.c45
1 files changed, 28 insertions, 17 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index deba54f6cbed..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,
1447 struct ext4_free_extent *gex = &ac->ac_g_ex; 1447 struct ext4_free_extent *gex = &ac->ac_g_ex;
1448 1448
1449 BUG_ON(ex->fe_len <= 0); 1449 BUG_ON(ex->fe_len <= 0);
1450 BUG_ON(ex->fe_len >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); 1450 BUG_ON(ex->fe_len > EXT4_BLOCKS_PER_GROUP(ac->ac_sb));
1451 BUG_ON(ex->fe_start >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); 1451 BUG_ON(ex->fe_start >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb));
1452 BUG_ON(ac->ac_status != AC_STATUS_CONTINUE); 1452 BUG_ON(ac->ac_status != AC_STATUS_CONTINUE);
1453 1453
@@ -3292,7 +3292,7 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
3292 } 3292 }
3293 BUG_ON(start + size <= ac->ac_o_ex.fe_logical && 3293 BUG_ON(start + size <= ac->ac_o_ex.fe_logical &&
3294 start > ac->ac_o_ex.fe_logical); 3294 start > ac->ac_o_ex.fe_logical);
3295 BUG_ON(size <= 0 || size >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); 3295 BUG_ON(size <= 0 || size > EXT4_BLOCKS_PER_GROUP(ac->ac_sb));
3296 3296
3297 /* now prepare goal request */ 3297 /* now prepare goal request */
3298 3298
@@ -3589,6 +3589,7 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac,
3589 struct super_block *sb, struct ext4_prealloc_space *pa) 3589 struct super_block *sb, struct ext4_prealloc_space *pa)
3590{ 3590{
3591 ext4_group_t grp; 3591 ext4_group_t grp;
3592 ext4_fsblk_t grp_blk;
3592 3593
3593 if (!atomic_dec_and_test(&pa->pa_count) || pa->pa_free != 0) 3594 if (!atomic_dec_and_test(&pa->pa_count) || pa->pa_free != 0)
3594 return; 3595 return;
@@ -3603,8 +3604,12 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac,
3603 pa->pa_deleted = 1; 3604 pa->pa_deleted = 1;
3604 spin_unlock(&pa->pa_lock); 3605 spin_unlock(&pa->pa_lock);
3605 3606
3606 /* -1 is to protect from crossing allocation group */ 3607 grp_blk = pa->pa_pstart;
3607 ext4_get_group_no_and_offset(sb, pa->pa_pstart - 1, &grp, NULL); 3608 /* If linear, pa_pstart may be in the next group when pa is used up */
3609 if (pa->pa_linear)
3610 grp_blk--;
3611
3612 ext4_get_group_no_and_offset(sb, grp_blk, &grp, NULL);
3608 3613
3609 /* 3614 /*
3610 * possible race: 3615 * possible race:
@@ -3693,6 +3698,8 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)
3693 pa->pa_free = pa->pa_len; 3698 pa->pa_free = pa->pa_len;
3694 atomic_set(&pa->pa_count, 1); 3699 atomic_set(&pa->pa_count, 1);
3695 spin_lock_init(&pa->pa_lock); 3700 spin_lock_init(&pa->pa_lock);
3701 INIT_LIST_HEAD(&pa->pa_inode_list);
3702 INIT_LIST_HEAD(&pa->pa_group_list);
3696 pa->pa_deleted = 0; 3703 pa->pa_deleted = 0;
3697 pa->pa_linear = 0; 3704 pa->pa_linear = 0;
3698 3705
@@ -3755,6 +3762,7 @@ ext4_mb_new_group_pa(struct ext4_allocation_context *ac)
3755 atomic_set(&pa->pa_count, 1); 3762 atomic_set(&pa->pa_count, 1);
3756 spin_lock_init(&pa->pa_lock); 3763 spin_lock_init(&pa->pa_lock);
3757 INIT_LIST_HEAD(&pa->pa_inode_list); 3764 INIT_LIST_HEAD(&pa->pa_inode_list);
3765 INIT_LIST_HEAD(&pa->pa_group_list);
3758 pa->pa_deleted = 0; 3766 pa->pa_deleted = 0;
3759 pa->pa_linear = 1; 3767 pa->pa_linear = 1;
3760 3768
@@ -4476,23 +4484,26 @@ static int ext4_mb_release_context(struct ext4_allocation_context *ac)
4476 pa->pa_free -= ac->ac_b_ex.fe_len; 4484 pa->pa_free -= ac->ac_b_ex.fe_len;
4477 pa->pa_len -= ac->ac_b_ex.fe_len; 4485 pa->pa_len -= ac->ac_b_ex.fe_len;
4478 spin_unlock(&pa->pa_lock); 4486 spin_unlock(&pa->pa_lock);
4479 /*
4480 * We want to add the pa to the right bucket.
4481 * Remove it from the list and while adding
4482 * make sure the list to which we are adding
4483 * doesn't grow big.
4484 */
4485 if (likely(pa->pa_free)) {
4486 spin_lock(pa->pa_obj_lock);
4487 list_del_rcu(&pa->pa_inode_list);
4488 spin_unlock(pa->pa_obj_lock);
4489 ext4_mb_add_n_trim(ac);
4490 }
4491 } 4487 }
4492 ext4_mb_put_pa(ac, ac->ac_sb, pa);
4493 } 4488 }
4494 if (ac->alloc_semp) 4489 if (ac->alloc_semp)
4495 up_read(ac->alloc_semp); 4490 up_read(ac->alloc_semp);
4491 if (pa) {
4492 /*
4493 * We want to add the pa to the right bucket.
4494 * Remove it from the list and while adding
4495 * make sure the list to which we are adding
4496 * doesn't grow big. We need to release
4497 * alloc_semp before calling ext4_mb_add_n_trim()
4498 */
4499 if (pa->pa_linear && likely(pa->pa_free)) {
4500 spin_lock(pa->pa_obj_lock);
4501 list_del_rcu(&pa->pa_inode_list);
4502 spin_unlock(pa->pa_obj_lock);
4503 ext4_mb_add_n_trim(ac);
4504 }
4505 ext4_mb_put_pa(ac, ac->ac_sb, pa);
4506 }
4496 if (ac->ac_bitmap_page) 4507 if (ac->ac_bitmap_page)
4497 page_cache_release(ac->ac_bitmap_page); 4508 page_cache_release(ac->ac_bitmap_page);
4498 if (ac->ac_buddy_page) 4509 if (ac->ac_buddy_page)