aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/mballoc.c21
-rw-r--r--fs/ext4/mballoc.h7
2 files changed, 17 insertions, 11 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index e72c72a0b807..7f6fc41a2dde 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -3555,8 +3555,11 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac,
3555 spin_unlock(&pa->pa_lock); 3555 spin_unlock(&pa->pa_lock);
3556 3556
3557 grp_blk = pa->pa_pstart; 3557 grp_blk = pa->pa_pstart;
3558 /* If linear, pa_pstart may be in the next group when pa is used up */ 3558 /*
3559 if (pa->pa_linear) 3559 * If doing group-based preallocation, pa_pstart may be in the
3560 * next group when pa is used up
3561 */
3562 if (pa->pa_type == MB_GROUP_PA)
3560 grp_blk--; 3563 grp_blk--;
3561 3564
3562 ext4_get_group_no_and_offset(sb, grp_blk, &grp, NULL); 3565 ext4_get_group_no_and_offset(sb, grp_blk, &grp, NULL);
@@ -3651,7 +3654,7 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)
3651 INIT_LIST_HEAD(&pa->pa_inode_list); 3654 INIT_LIST_HEAD(&pa->pa_inode_list);
3652 INIT_LIST_HEAD(&pa->pa_group_list); 3655 INIT_LIST_HEAD(&pa->pa_group_list);
3653 pa->pa_deleted = 0; 3656 pa->pa_deleted = 0;
3654 pa->pa_linear = 0; 3657 pa->pa_type = MB_INODE_PA;
3655 3658
3656 mb_debug("new inode pa %p: %llu/%u for %u\n", pa, 3659 mb_debug("new inode pa %p: %llu/%u for %u\n", pa,
3657 pa->pa_pstart, pa->pa_len, pa->pa_lstart); 3660 pa->pa_pstart, pa->pa_len, pa->pa_lstart);
@@ -3714,7 +3717,7 @@ ext4_mb_new_group_pa(struct ext4_allocation_context *ac)
3714 INIT_LIST_HEAD(&pa->pa_inode_list); 3717 INIT_LIST_HEAD(&pa->pa_inode_list);
3715 INIT_LIST_HEAD(&pa->pa_group_list); 3718 INIT_LIST_HEAD(&pa->pa_group_list);
3716 pa->pa_deleted = 0; 3719 pa->pa_deleted = 0;
3717 pa->pa_linear = 1; 3720 pa->pa_type = MB_GROUP_PA;
3718 3721
3719 mb_debug("new group pa %p: %llu/%u for %u\n", pa, 3722 mb_debug("new group pa %p: %llu/%u for %u\n", pa,
3720 pa->pa_pstart, pa->pa_len, pa->pa_lstart); 3723 pa->pa_pstart, pa->pa_len, pa->pa_lstart);
@@ -3968,7 +3971,7 @@ repeat:
3968 list_del_rcu(&pa->pa_inode_list); 3971 list_del_rcu(&pa->pa_inode_list);
3969 spin_unlock(pa->pa_obj_lock); 3972 spin_unlock(pa->pa_obj_lock);
3970 3973
3971 if (pa->pa_linear) 3974 if (pa->pa_type == MB_GROUP_PA)
3972 ext4_mb_release_group_pa(&e4b, pa, ac); 3975 ext4_mb_release_group_pa(&e4b, pa, ac);
3973 else 3976 else
3974 ext4_mb_release_inode_pa(&e4b, bitmap_bh, pa, ac); 3977 ext4_mb_release_inode_pa(&e4b, bitmap_bh, pa, ac);
@@ -4068,7 +4071,7 @@ repeat:
4068 spin_unlock(&ei->i_prealloc_lock); 4071 spin_unlock(&ei->i_prealloc_lock);
4069 4072
4070 list_for_each_entry_safe(pa, tmp, &list, u.pa_tmp_list) { 4073 list_for_each_entry_safe(pa, tmp, &list, u.pa_tmp_list) {
4071 BUG_ON(pa->pa_linear != 0); 4074 BUG_ON(pa->pa_type != MB_INODE_PA);
4072 ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, NULL); 4075 ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, NULL);
4073 4076
4074 err = ext4_mb_load_buddy(sb, group, &e4b); 4077 err = ext4_mb_load_buddy(sb, group, &e4b);
@@ -4320,7 +4323,7 @@ ext4_mb_discard_lg_preallocations(struct super_block *sb,
4320 continue; 4323 continue;
4321 } 4324 }
4322 /* only lg prealloc space */ 4325 /* only lg prealloc space */
4323 BUG_ON(!pa->pa_linear); 4326 BUG_ON(pa->pa_type != MB_GROUP_PA);
4324 4327
4325 /* seems this one can be freed ... */ 4328 /* seems this one can be freed ... */
4326 pa->pa_deleted = 1; 4329 pa->pa_deleted = 1;
@@ -4426,7 +4429,7 @@ static int ext4_mb_release_context(struct ext4_allocation_context *ac)
4426{ 4429{
4427 struct ext4_prealloc_space *pa = ac->ac_pa; 4430 struct ext4_prealloc_space *pa = ac->ac_pa;
4428 if (pa) { 4431 if (pa) {
4429 if (pa->pa_linear) { 4432 if (pa->pa_type == MB_GROUP_PA) {
4430 /* see comment in ext4_mb_use_group_pa() */ 4433 /* see comment in ext4_mb_use_group_pa() */
4431 spin_lock(&pa->pa_lock); 4434 spin_lock(&pa->pa_lock);
4432 pa->pa_pstart += ac->ac_b_ex.fe_len; 4435 pa->pa_pstart += ac->ac_b_ex.fe_len;
@@ -4446,7 +4449,7 @@ static int ext4_mb_release_context(struct ext4_allocation_context *ac)
4446 * doesn't grow big. We need to release 4449 * doesn't grow big. We need to release
4447 * alloc_semp before calling ext4_mb_add_n_trim() 4450 * alloc_semp before calling ext4_mb_add_n_trim()
4448 */ 4451 */
4449 if (pa->pa_linear && likely(pa->pa_free)) { 4452 if ((pa->pa_type == MB_GROUP_PA) && likely(pa->pa_free)) {
4450 spin_lock(pa->pa_obj_lock); 4453 spin_lock(pa->pa_obj_lock);
4451 list_del_rcu(&pa->pa_inode_list); 4454 list_del_rcu(&pa->pa_inode_list);
4452 spin_unlock(pa->pa_obj_lock); 4455 spin_unlock(pa->pa_obj_lock);
diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h
index 7acf5ef24537..dd9e6cd5f6cf 100644
--- a/fs/ext4/mballoc.h
+++ b/fs/ext4/mballoc.h
@@ -132,12 +132,15 @@ struct ext4_prealloc_space {
132 ext4_lblk_t pa_lstart; /* log. block */ 132 ext4_lblk_t pa_lstart; /* log. block */
133 unsigned short pa_len; /* len of preallocated chunk */ 133 unsigned short pa_len; /* len of preallocated chunk */
134 unsigned short pa_free; /* how many blocks are free */ 134 unsigned short pa_free; /* how many blocks are free */
135 unsigned short pa_linear; /* consumed in one direction 135 unsigned short pa_type; /* pa type. inode or group */
136 * strictly, for grp prealloc */
137 spinlock_t *pa_obj_lock; 136 spinlock_t *pa_obj_lock;
138 struct inode *pa_inode; /* hack, for history only */ 137 struct inode *pa_inode; /* hack, for history only */
139}; 138};
140 139
140enum {
141 MB_INODE_PA = 0,
142 MB_GROUP_PA = 1
143};
141 144
142struct ext4_free_extent { 145struct ext4_free_extent {
143 ext4_lblk_t fe_logical; 146 ext4_lblk_t fe_logical;