diff options
Diffstat (limited to 'fs/ext4/mballoc.c')
-rw-r--r-- | fs/ext4/mballoc.c | 101 |
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 | */ | ||
3019 | static 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 | */ |
3011 | static void ext4_mb_use_inode_pa(struct ext4_allocation_context *ac, | 3034 | static 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 | */ |
4428 | void ext4_mb_free_blocks(handle_t *handle, struct inode *inode, | 4457 | void 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; |
4594 | error_return: | 4653 | error_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) |