aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/mballoc.c82
1 files changed, 60 insertions, 22 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index c17063ddb307..860766421fe8 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -335,6 +335,8 @@ static struct kmem_cache *ext4_ac_cachep;
335static struct kmem_cache *ext4_free_ext_cachep; 335static struct kmem_cache *ext4_free_ext_cachep;
336static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, 336static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
337 ext4_group_t group); 337 ext4_group_t group);
338static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap,
339 ext4_group_t group);
338static int ext4_mb_init_per_dev_proc(struct super_block *sb); 340static int ext4_mb_init_per_dev_proc(struct super_block *sb);
339static int ext4_mb_destroy_per_dev_proc(struct super_block *sb); 341static int ext4_mb_destroy_per_dev_proc(struct super_block *sb);
340static void release_blocks_on_commit(journal_t *journal, transaction_t *txn); 342static void release_blocks_on_commit(journal_t *journal, transaction_t *txn);
@@ -858,7 +860,9 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
858 /* 860 /*
859 * incore got set to the group block bitmap below 861 * incore got set to the group block bitmap below
860 */ 862 */
863 ext4_lock_group(sb, group);
861 ext4_mb_generate_buddy(sb, data, incore, group); 864 ext4_mb_generate_buddy(sb, data, incore, group);
865 ext4_unlock_group(sb, group);
862 incore = NULL; 866 incore = NULL;
863 } else { 867 } else {
864 /* this is block of bitmap */ 868 /* this is block of bitmap */
@@ -872,6 +876,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
872 876
873 /* mark all preallocated blks used in in-core bitmap */ 877 /* mark all preallocated blks used in in-core bitmap */
874 ext4_mb_generate_from_pa(sb, data, group); 878 ext4_mb_generate_from_pa(sb, data, group);
879 ext4_mb_generate_from_freelist(sb, data, group);
875 ext4_unlock_group(sb, group); 880 ext4_unlock_group(sb, group);
876 881
877 /* set incore so that the buddy information can be 882 /* set incore so that the buddy information can be
@@ -3472,6 +3477,32 @@ ext4_mb_use_preallocated(struct ext4_allocation_context *ac)
3472} 3477}
3473 3478
3474/* 3479/*
3480 * the function goes through all block freed in the group
3481 * but not yet committed and marks them used in in-core bitmap.
3482 * buddy must be generated from this bitmap
3483 * Need to be called with ext4 group lock (ext4_lock_group)
3484 */
3485static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap,
3486 ext4_group_t group)
3487{
3488 struct rb_node *n;
3489 struct ext4_group_info *grp;
3490 struct ext4_free_data *entry;
3491
3492 grp = ext4_get_group_info(sb, group);
3493 n = rb_first(&(grp->bb_free_root));
3494
3495 while (n) {
3496 entry = rb_entry(n, struct ext4_free_data, node);
3497 mb_set_bits(sb_bgl_lock(EXT4_SB(sb), group),
3498 bitmap, entry->start_blk,
3499 entry->count);
3500 n = rb_next(n);
3501 }
3502 return;
3503}
3504
3505/*
3475 * the function goes through all preallocation in this group and marks them 3506 * the function goes through all preallocation in this group and marks them
3476 * used in in-core bitmap. buddy must be generated from this bitmap 3507 * used in in-core bitmap. buddy must be generated from this bitmap
3477 * Need to be called with ext4 group lock (ext4_lock_group) 3508 * Need to be called with ext4 group lock (ext4_lock_group)
@@ -4568,12 +4599,13 @@ static int can_merge(struct ext4_free_data *entry1,
4568 4599
4569static noinline_for_stack int 4600static noinline_for_stack int
4570ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b, 4601ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
4571 ext4_group_t group, ext4_grpblk_t block, int count) 4602 struct ext4_free_data *new_entry)
4572{ 4603{
4604 ext4_grpblk_t block;
4605 struct ext4_free_data *entry;
4573 struct ext4_group_info *db = e4b->bd_info; 4606 struct ext4_group_info *db = e4b->bd_info;
4574 struct super_block *sb = e4b->bd_sb; 4607 struct super_block *sb = e4b->bd_sb;
4575 struct ext4_sb_info *sbi = EXT4_SB(sb); 4608 struct ext4_sb_info *sbi = EXT4_SB(sb);
4576 struct ext4_free_data *entry, *new_entry;
4577 struct rb_node **n = &db->bb_free_root.rb_node, *node; 4609 struct rb_node **n = &db->bb_free_root.rb_node, *node;
4578 struct rb_node *parent = NULL, *new_node; 4610 struct rb_node *parent = NULL, *new_node;
4579 4611
@@ -4581,14 +4613,9 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
4581 BUG_ON(e4b->bd_bitmap_page == NULL); 4613 BUG_ON(e4b->bd_bitmap_page == NULL);
4582 BUG_ON(e4b->bd_buddy_page == NULL); 4614 BUG_ON(e4b->bd_buddy_page == NULL);
4583 4615
4584 new_entry = kmem_cache_alloc(ext4_free_ext_cachep, GFP_NOFS);
4585 new_entry->start_blk = block;
4586 new_entry->group = group;
4587 new_entry->count = count;
4588 new_entry->t_tid = handle->h_transaction->t_tid;
4589 new_node = &new_entry->node; 4616 new_node = &new_entry->node;
4617 block = new_entry->start_blk;
4590 4618
4591 ext4_lock_group(sb, group);
4592 if (!*n) { 4619 if (!*n) {
4593 /* first free block exent. We need to 4620 /* first free block exent. We need to
4594 protect buddy cache from being freed, 4621 protect buddy cache from being freed,
@@ -4606,7 +4633,6 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
4606 else if (block >= (entry->start_blk + entry->count)) 4633 else if (block >= (entry->start_blk + entry->count))
4607 n = &(*n)->rb_right; 4634 n = &(*n)->rb_right;
4608 else { 4635 else {
4609 ext4_unlock_group(sb, group);
4610 ext4_error(sb, __func__, 4636 ext4_error(sb, __func__,
4611 "Double free of blocks %d (%d %d)", 4637 "Double free of blocks %d (%d %d)",
4612 block, entry->start_blk, entry->count); 4638 block, entry->start_blk, entry->count);
@@ -4648,7 +4674,6 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
4648 spin_lock(&sbi->s_md_lock); 4674 spin_lock(&sbi->s_md_lock);
4649 list_add(&new_entry->list, &handle->h_transaction->t_private_list); 4675 list_add(&new_entry->list, &handle->h_transaction->t_private_list);
4650 spin_unlock(&sbi->s_md_lock); 4676 spin_unlock(&sbi->s_md_lock);
4651 ext4_unlock_group(sb, group);
4652 return 0; 4677 return 0;
4653} 4678}
4654 4679
@@ -4753,15 +4778,6 @@ do_more:
4753 BUG_ON(!mb_test_bit(bit + i, bitmap_bh->b_data)); 4778 BUG_ON(!mb_test_bit(bit + i, bitmap_bh->b_data));
4754 } 4779 }
4755#endif 4780#endif
4756 mb_clear_bits(sb_bgl_lock(sbi, block_group), bitmap_bh->b_data,
4757 bit, count);
4758
4759 /* We dirtied the bitmap block */
4760 BUFFER_TRACE(bitmap_bh, "dirtied bitmap block");
4761 err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
4762 if (err)
4763 goto error_return;
4764
4765 if (ac) { 4781 if (ac) {
4766 ac->ac_b_ex.fe_group = block_group; 4782 ac->ac_b_ex.fe_group = block_group;
4767 ac->ac_b_ex.fe_start = bit; 4783 ac->ac_b_ex.fe_start = bit;
@@ -4773,11 +4789,29 @@ do_more:
4773 if (err) 4789 if (err)
4774 goto error_return; 4790 goto error_return;
4775 if (metadata && ext4_handle_valid(handle)) { 4791 if (metadata && ext4_handle_valid(handle)) {
4776 /* blocks being freed are metadata. these blocks shouldn't 4792 struct ext4_free_data *new_entry;
4777 * be used until this transaction is committed */ 4793 /*
4778 ext4_mb_free_metadata(handle, &e4b, block_group, bit, count); 4794 * blocks being freed are metadata. these blocks shouldn't
4795 * be used until this transaction is committed
4796 */
4797 new_entry = kmem_cache_alloc(ext4_free_ext_cachep, GFP_NOFS);
4798 new_entry->start_blk = bit;
4799 new_entry->group = block_group;
4800 new_entry->count = count;
4801 new_entry->t_tid = handle->h_transaction->t_tid;
4802 ext4_lock_group(sb, block_group);
4803 mb_clear_bits(sb_bgl_lock(sbi, block_group), bitmap_bh->b_data,
4804 bit, count);
4805 ext4_mb_free_metadata(handle, &e4b, new_entry);
4806 ext4_unlock_group(sb, block_group);
4779 } else { 4807 } else {
4780 ext4_lock_group(sb, block_group); 4808 ext4_lock_group(sb, block_group);
4809 /* need to update group_info->bb_free and bitmap
4810 * with group lock held. generate_buddy look at
4811 * them with group lock_held
4812 */
4813 mb_clear_bits(sb_bgl_lock(sbi, block_group), bitmap_bh->b_data,
4814 bit, count);
4781 mb_free_blocks(inode, &e4b, bit, count); 4815 mb_free_blocks(inode, &e4b, bit, count);
4782 ext4_mb_return_to_preallocation(inode, &e4b, block, count); 4816 ext4_mb_return_to_preallocation(inode, &e4b, block, count);
4783 ext4_unlock_group(sb, block_group); 4817 ext4_unlock_group(sb, block_group);
@@ -4800,6 +4834,10 @@ do_more:
4800 4834
4801 *freed += count; 4835 *freed += count;
4802 4836
4837 /* We dirtied the bitmap block */
4838 BUFFER_TRACE(bitmap_bh, "dirtied bitmap block");
4839 err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
4840
4803 /* And the group descriptor block */ 4841 /* And the group descriptor block */
4804 BUFFER_TRACE(gd_bh, "dirtied group descriptor block"); 4842 BUFFER_TRACE(gd_bh, "dirtied group descriptor block");
4805 ret = ext4_handle_dirty_metadata(handle, NULL, gd_bh); 4843 ret = ext4_handle_dirty_metadata(handle, NULL, gd_bh);