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.c101
1 files changed, 81 insertions, 20 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 74e495dabe09..c1e19d5b5985 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2529,7 +2529,6 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn)
2529 struct ext4_group_info *db; 2529 struct ext4_group_info *db;
2530 int err, count = 0, count2 = 0; 2530 int err, count = 0, count2 = 0;
2531 struct ext4_free_data *entry; 2531 struct ext4_free_data *entry;
2532 ext4_fsblk_t discard_block;
2533 struct list_head *l, *ltmp; 2532 struct list_head *l, *ltmp;
2534 2533
2535 list_for_each_safe(l, ltmp, &txn->t_private_list) { 2534 list_for_each_safe(l, ltmp, &txn->t_private_list) {
@@ -2559,13 +2558,19 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn)
2559 page_cache_release(e4b.bd_bitmap_page); 2558 page_cache_release(e4b.bd_bitmap_page);
2560 } 2559 }
2561 ext4_unlock_group(sb, entry->group); 2560 ext4_unlock_group(sb, entry->group);
2562 discard_block = (ext4_fsblk_t) entry->group * EXT4_BLOCKS_PER_GROUP(sb) 2561 if (test_opt(sb, DISCARD)) {
2563 + entry->start_blk 2562 ext4_fsblk_t discard_block;
2564 + le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block); 2563 struct ext4_super_block *es = EXT4_SB(sb)->s_es;
2565 trace_ext4_discard_blocks(sb, (unsigned long long)discard_block, 2564
2566 entry->count); 2565 discard_block = (ext4_fsblk_t)entry->group *
2567 sb_issue_discard(sb, discard_block, entry->count); 2566 EXT4_BLOCKS_PER_GROUP(sb)
2568 2567 + entry->start_blk
2568 + le32_to_cpu(es->s_first_data_block);
2569 trace_ext4_discard_blocks(sb,
2570 (unsigned long long)discard_block,
2571 entry->count);
2572 sb_issue_discard(sb, discard_block, entry->count);
2573 }
2569 kmem_cache_free(ext4_free_ext_cachep, entry); 2574 kmem_cache_free(ext4_free_ext_cachep, entry);
2570 ext4_mb_release_desc(&e4b); 2575 ext4_mb_release_desc(&e4b);
2571 } 2576 }
@@ -3006,6 +3011,24 @@ static void ext4_mb_collect_stats(struct ext4_allocation_context *ac)
3006} 3011}
3007 3012
3008/* 3013/*
3014 * Called on failure; free up any blocks from the inode PA for this
3015 * context. We don't need this for MB_GROUP_PA because we only change
3016 * pa_free in ext4_mb_release_context(), but on failure, we've already
3017 * zeroed out ac->ac_b_ex.fe_len, so group_pa->pa_free is not changed.
3018 */
3019static void ext4_discard_allocated_blocks(struct ext4_allocation_context *ac)
3020{
3021 struct ext4_prealloc_space *pa = ac->ac_pa;
3022 int len;
3023
3024 if (pa && pa->pa_type == MB_INODE_PA) {
3025 len = ac->ac_b_ex.fe_len;
3026 pa->pa_free += len;
3027 }
3028
3029}
3030
3031/*
3009 * use blocks preallocated to inode 3032 * use blocks preallocated to inode
3010 */ 3033 */
3011static void ext4_mb_use_inode_pa(struct ext4_allocation_context *ac, 3034static void ext4_mb_use_inode_pa(struct ext4_allocation_context *ac,
@@ -4290,6 +4313,7 @@ repeat:
4290 ac->ac_status = AC_STATUS_CONTINUE; 4313 ac->ac_status = AC_STATUS_CONTINUE;
4291 goto repeat; 4314 goto repeat;
4292 } else if (*errp) { 4315 } else if (*errp) {
4316 ext4_discard_allocated_blocks(ac);
4293 ac->ac_b_ex.fe_len = 0; 4317 ac->ac_b_ex.fe_len = 0;
4294 ar->len = 0; 4318 ar->len = 0;
4295 ext4_mb_show_ac(ac); 4319 ext4_mb_show_ac(ac);
@@ -4422,18 +4446,24 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
4422 return 0; 4446 return 0;
4423} 4447}
4424 4448
4425/* 4449/**
4426 * Main entry point into mballoc to free blocks 4450 * ext4_free_blocks() -- Free given blocks and update quota
4451 * @handle: handle for this transaction
4452 * @inode: inode
4453 * @block: start physical block to free
4454 * @count: number of blocks to count
4455 * @metadata: Are these metadata blocks
4427 */ 4456 */
4428void ext4_mb_free_blocks(handle_t *handle, struct inode *inode, 4457void ext4_free_blocks(handle_t *handle, struct inode *inode,
4429 ext4_fsblk_t block, unsigned long count, 4458 struct buffer_head *bh, ext4_fsblk_t block,
4430 int metadata, unsigned long *freed) 4459 unsigned long count, int flags)
4431{ 4460{
4432 struct buffer_head *bitmap_bh = NULL; 4461 struct buffer_head *bitmap_bh = NULL;
4433 struct super_block *sb = inode->i_sb; 4462 struct super_block *sb = inode->i_sb;
4434 struct ext4_allocation_context *ac = NULL; 4463 struct ext4_allocation_context *ac = NULL;
4435 struct ext4_group_desc *gdp; 4464 struct ext4_group_desc *gdp;
4436 struct ext4_super_block *es; 4465 struct ext4_super_block *es;
4466 unsigned long freed = 0;
4437 unsigned int overflow; 4467 unsigned int overflow;
4438 ext4_grpblk_t bit; 4468 ext4_grpblk_t bit;
4439 struct buffer_head *gd_bh; 4469 struct buffer_head *gd_bh;
@@ -4443,13 +4473,16 @@ void ext4_mb_free_blocks(handle_t *handle, struct inode *inode,
4443 int err = 0; 4473 int err = 0;
4444 int ret; 4474 int ret;
4445 4475
4446 *freed = 0; 4476 if (bh) {
4477 if (block)
4478 BUG_ON(block != bh->b_blocknr);
4479 else
4480 block = bh->b_blocknr;
4481 }
4447 4482
4448 sbi = EXT4_SB(sb); 4483 sbi = EXT4_SB(sb);
4449 es = EXT4_SB(sb)->s_es; 4484 es = EXT4_SB(sb)->s_es;
4450 if (block < le32_to_cpu(es->s_first_data_block) || 4485 if (!ext4_data_block_valid(sbi, block, count)) {
4451 block + count < block ||
4452 block + count > ext4_blocks_count(es)) {
4453 ext4_error(sb, __func__, 4486 ext4_error(sb, __func__,
4454 "Freeing blocks not in datazone - " 4487 "Freeing blocks not in datazone - "
4455 "block = %llu, count = %lu", block, count); 4488 "block = %llu, count = %lu", block, count);
@@ -4457,7 +4490,32 @@ void ext4_mb_free_blocks(handle_t *handle, struct inode *inode,
4457 } 4490 }
4458 4491
4459 ext4_debug("freeing block %llu\n", block); 4492 ext4_debug("freeing block %llu\n", block);
4460 trace_ext4_free_blocks(inode, block, count, metadata); 4493 trace_ext4_free_blocks(inode, block, count, flags);
4494
4495 if (flags & EXT4_FREE_BLOCKS_FORGET) {
4496 struct buffer_head *tbh = bh;
4497 int i;
4498
4499 BUG_ON(bh && (count > 1));
4500
4501 for (i = 0; i < count; i++) {
4502 if (!bh)
4503 tbh = sb_find_get_block(inode->i_sb,
4504 block + i);
4505 ext4_forget(handle, flags & EXT4_FREE_BLOCKS_METADATA,
4506 inode, tbh, block + i);
4507 }
4508 }
4509
4510 /*
4511 * We need to make sure we don't reuse the freed block until
4512 * after the transaction is committed, which we can do by
4513 * treating the block as metadata, below. We make an
4514 * exception if the inode is to be written in writeback mode
4515 * since writeback mode has weak data consistency guarantees.
4516 */
4517 if (!ext4_should_writeback_data(inode))
4518 flags |= EXT4_FREE_BLOCKS_METADATA;
4461 4519
4462 ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS); 4520 ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS);
4463 if (ac) { 4521 if (ac) {
@@ -4533,7 +4591,8 @@ do_more:
4533 err = ext4_mb_load_buddy(sb, block_group, &e4b); 4591 err = ext4_mb_load_buddy(sb, block_group, &e4b);
4534 if (err) 4592 if (err)
4535 goto error_return; 4593 goto error_return;
4536 if (metadata && ext4_handle_valid(handle)) { 4594
4595 if ((flags & EXT4_FREE_BLOCKS_METADATA) && ext4_handle_valid(handle)) {
4537 struct ext4_free_data *new_entry; 4596 struct ext4_free_data *new_entry;
4538 /* 4597 /*
4539 * blocks being freed are metadata. these blocks shouldn't 4598 * blocks being freed are metadata. these blocks shouldn't
@@ -4572,7 +4631,7 @@ do_more:
4572 4631
4573 ext4_mb_release_desc(&e4b); 4632 ext4_mb_release_desc(&e4b);
4574 4633
4575 *freed += count; 4634 freed += count;
4576 4635
4577 /* We dirtied the bitmap block */ 4636 /* We dirtied the bitmap block */
4578 BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); 4637 BUFFER_TRACE(bitmap_bh, "dirtied bitmap block");
@@ -4592,6 +4651,8 @@ do_more:
4592 } 4651 }
4593 sb->s_dirt = 1; 4652 sb->s_dirt = 1;
4594error_return: 4653error_return:
4654 if (freed)
4655 vfs_dq_free_block(inode, freed);
4595 brelse(bitmap_bh); 4656 brelse(bitmap_bh);
4596 ext4_std_error(sb, err); 4657 ext4_std_error(sb, err);
4597 if (ac) 4658 if (ac)