diff options
Diffstat (limited to 'fs/ext4/mballoc.c')
| -rw-r--r-- | fs/ext4/mballoc.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 4d113efa024c..04a5c7504be9 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
| @@ -3442,6 +3442,9 @@ static void ext4_mb_pa_callback(struct rcu_head *head) | |||
| 3442 | { | 3442 | { |
| 3443 | struct ext4_prealloc_space *pa; | 3443 | struct ext4_prealloc_space *pa; |
| 3444 | pa = container_of(head, struct ext4_prealloc_space, u.pa_rcu); | 3444 | pa = container_of(head, struct ext4_prealloc_space, u.pa_rcu); |
| 3445 | |||
| 3446 | BUG_ON(atomic_read(&pa->pa_count)); | ||
| 3447 | BUG_ON(pa->pa_deleted == 0); | ||
| 3445 | kmem_cache_free(ext4_pspace_cachep, pa); | 3448 | kmem_cache_free(ext4_pspace_cachep, pa); |
| 3446 | } | 3449 | } |
| 3447 | 3450 | ||
| @@ -3455,11 +3458,13 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac, | |||
| 3455 | ext4_group_t grp; | 3458 | ext4_group_t grp; |
| 3456 | ext4_fsblk_t grp_blk; | 3459 | ext4_fsblk_t grp_blk; |
| 3457 | 3460 | ||
| 3458 | if (!atomic_dec_and_test(&pa->pa_count) || pa->pa_free != 0) | ||
| 3459 | return; | ||
| 3460 | |||
| 3461 | /* in this short window concurrent discard can set pa_deleted */ | 3461 | /* in this short window concurrent discard can set pa_deleted */ |
| 3462 | spin_lock(&pa->pa_lock); | 3462 | spin_lock(&pa->pa_lock); |
| 3463 | if (!atomic_dec_and_test(&pa->pa_count) || pa->pa_free != 0) { | ||
| 3464 | spin_unlock(&pa->pa_lock); | ||
| 3465 | return; | ||
| 3466 | } | ||
| 3467 | |||
| 3463 | if (pa->pa_deleted == 1) { | 3468 | if (pa->pa_deleted == 1) { |
| 3464 | spin_unlock(&pa->pa_lock); | 3469 | spin_unlock(&pa->pa_lock); |
| 3465 | return; | 3470 | return; |
| @@ -4121,7 +4126,7 @@ ext4_mb_initialize_context(struct ext4_allocation_context *ac, | |||
| 4121 | ext4_get_group_no_and_offset(sb, goal, &group, &block); | 4126 | ext4_get_group_no_and_offset(sb, goal, &group, &block); |
| 4122 | 4127 | ||
| 4123 | /* set up allocation goals */ | 4128 | /* set up allocation goals */ |
| 4124 | ac->ac_b_ex.fe_logical = ar->logical & ~(sbi->s_cluster_ratio - 1); | 4129 | ac->ac_b_ex.fe_logical = EXT4_LBLK_CMASK(sbi, ar->logical); |
| 4125 | ac->ac_status = AC_STATUS_CONTINUE; | 4130 | ac->ac_status = AC_STATUS_CONTINUE; |
| 4126 | ac->ac_sb = sb; | 4131 | ac->ac_sb = sb; |
| 4127 | ac->ac_inode = ar->inode; | 4132 | ac->ac_inode = ar->inode; |
| @@ -4663,7 +4668,7 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, | |||
| 4663 | * blocks at the beginning or the end unless we are explicitly | 4668 | * blocks at the beginning or the end unless we are explicitly |
| 4664 | * requested to avoid doing so. | 4669 | * requested to avoid doing so. |
| 4665 | */ | 4670 | */ |
| 4666 | overflow = block & (sbi->s_cluster_ratio - 1); | 4671 | overflow = EXT4_PBLK_COFF(sbi, block); |
| 4667 | if (overflow) { | 4672 | if (overflow) { |
| 4668 | if (flags & EXT4_FREE_BLOCKS_NOFREE_FIRST_CLUSTER) { | 4673 | if (flags & EXT4_FREE_BLOCKS_NOFREE_FIRST_CLUSTER) { |
| 4669 | overflow = sbi->s_cluster_ratio - overflow; | 4674 | overflow = sbi->s_cluster_ratio - overflow; |
| @@ -4677,7 +4682,7 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, | |||
| 4677 | count += overflow; | 4682 | count += overflow; |
| 4678 | } | 4683 | } |
| 4679 | } | 4684 | } |
| 4680 | overflow = count & (sbi->s_cluster_ratio - 1); | 4685 | overflow = EXT4_LBLK_COFF(sbi, count); |
| 4681 | if (overflow) { | 4686 | if (overflow) { |
| 4682 | if (flags & EXT4_FREE_BLOCKS_NOFREE_LAST_CLUSTER) { | 4687 | if (flags & EXT4_FREE_BLOCKS_NOFREE_LAST_CLUSTER) { |
| 4683 | if (count > overflow) | 4688 | if (count > overflow) |
