diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-07 16:03:53 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-07 16:03:53 -0400 |
commit | 09dc942c2a767e2d298f1cc9294bc19c7d7208c5 (patch) | |
tree | d310c118467c90c264e953bdc320ae08394c662a /fs/ext4/mballoc.c | |
parent | 90e0c225968f0878e090c7ff3f88323973476cee (diff) | |
parent | 6c7a120ac6c62316ab1fc78dfc0a7b13f3bfcbff (diff) |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (40 commits)
ext4: Adding error check after calling ext4_mb_regular_allocator()
ext4: Fix dirtying of journalled buffers in data=journal mode
ext4: re-inline ext4_rec_len_(to|from)_disk functions
jbd2: Remove t_handle_lock from start_this_handle()
jbd2: Change j_state_lock to be a rwlock_t
jbd2: Use atomic variables to avoid taking t_handle_lock in jbd2_journal_stop
ext4: Add mount options in superblock
ext4: force block allocation on quota_off
ext4: fix freeze deadlock under IO
ext4: drop inode from orphan list if ext4_delete_inode() fails
ext4: check to make make sure bd_dev is set before dereferencing it
jbd2: Make barrier messages less scary
ext4: don't print scary messages for allocation failures post-abort
ext4: fix EFBIG edge case when writing to large non-extent file
ext4: fix ext4_get_blocks references
ext4: Always journal quota file modifications
ext4: Fix potential memory leak in ext4_fill_super
ext4: Don't error out the fs if the user tries to make a file too big
ext4: allocate stripe-multiple IOs on stripe boundaries
ext4: move aio completion after unwritten extent conversion
...
Fix up conflicts in fs/ext4/inode.c as per Ted.
Fix up xfs conflicts as per earlier xfs merge.
Diffstat (limited to 'fs/ext4/mballoc.c')
-rw-r--r-- | fs/ext4/mballoc.c | 153 |
1 files changed, 76 insertions, 77 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 0e83dfd351d5..4b4ad4b7ce57 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -446,10 +446,11 @@ static void mb_free_blocks_double(struct inode *inode, struct ext4_buddy *e4b, | |||
446 | blocknr = ext4_group_first_block_no(sb, e4b->bd_group); | 446 | blocknr = ext4_group_first_block_no(sb, e4b->bd_group); |
447 | blocknr += first + i; | 447 | blocknr += first + i; |
448 | ext4_grp_locked_error(sb, e4b->bd_group, | 448 | ext4_grp_locked_error(sb, e4b->bd_group, |
449 | __func__, "double-free of inode" | 449 | inode ? inode->i_ino : 0, |
450 | " %lu's block %llu(bit %u in group %u)", | 450 | blocknr, |
451 | inode ? inode->i_ino : 0, blocknr, | 451 | "freeing block already freed " |
452 | first + i, e4b->bd_group); | 452 | "(bit %u)", |
453 | first + i); | ||
453 | } | 454 | } |
454 | mb_clear_bit(first + i, e4b->bd_info->bb_bitmap); | 455 | mb_clear_bit(first + i, e4b->bd_info->bb_bitmap); |
455 | } | 456 | } |
@@ -712,9 +713,9 @@ void ext4_mb_generate_buddy(struct super_block *sb, | |||
712 | grp->bb_fragments = fragments; | 713 | grp->bb_fragments = fragments; |
713 | 714 | ||
714 | if (free != grp->bb_free) { | 715 | if (free != grp->bb_free) { |
715 | ext4_grp_locked_error(sb, group, __func__, | 716 | ext4_grp_locked_error(sb, group, 0, 0, |
716 | "EXT4-fs: group %u: %u blocks in bitmap, %u in gd", | 717 | "%u blocks in bitmap, %u in gd", |
717 | group, free, grp->bb_free); | 718 | free, grp->bb_free); |
718 | /* | 719 | /* |
719 | * If we intent to continue, we consider group descritor | 720 | * If we intent to continue, we consider group descritor |
720 | * corrupt and update bb_free using bitmap value | 721 | * corrupt and update bb_free using bitmap value |
@@ -1296,10 +1297,10 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b, | |||
1296 | blocknr = ext4_group_first_block_no(sb, e4b->bd_group); | 1297 | blocknr = ext4_group_first_block_no(sb, e4b->bd_group); |
1297 | blocknr += block; | 1298 | blocknr += block; |
1298 | ext4_grp_locked_error(sb, e4b->bd_group, | 1299 | ext4_grp_locked_error(sb, e4b->bd_group, |
1299 | __func__, "double-free of inode" | 1300 | inode ? inode->i_ino : 0, |
1300 | " %lu's block %llu(bit %u in group %u)", | 1301 | blocknr, |
1301 | inode ? inode->i_ino : 0, blocknr, block, | 1302 | "freeing already freed block " |
1302 | e4b->bd_group); | 1303 | "(bit %u)", block); |
1303 | } | 1304 | } |
1304 | mb_clear_bit(block, EXT4_MB_BITMAP(e4b)); | 1305 | mb_clear_bit(block, EXT4_MB_BITMAP(e4b)); |
1305 | e4b->bd_info->bb_counters[order]++; | 1306 | e4b->bd_info->bb_counters[order]++; |
@@ -1788,8 +1789,8 @@ void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, | |||
1788 | * free blocks even though group info says we | 1789 | * free blocks even though group info says we |
1789 | * we have free blocks | 1790 | * we have free blocks |
1790 | */ | 1791 | */ |
1791 | ext4_grp_locked_error(sb, e4b->bd_group, | 1792 | ext4_grp_locked_error(sb, e4b->bd_group, 0, 0, |
1792 | __func__, "%d free blocks as per " | 1793 | "%d free blocks as per " |
1793 | "group info. But bitmap says 0", | 1794 | "group info. But bitmap says 0", |
1794 | free); | 1795 | free); |
1795 | break; | 1796 | break; |
@@ -1798,8 +1799,8 @@ void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, | |||
1798 | mb_find_extent(e4b, 0, i, ac->ac_g_ex.fe_len, &ex); | 1799 | mb_find_extent(e4b, 0, i, ac->ac_g_ex.fe_len, &ex); |
1799 | BUG_ON(ex.fe_len <= 0); | 1800 | BUG_ON(ex.fe_len <= 0); |
1800 | if (free < ex.fe_len) { | 1801 | if (free < ex.fe_len) { |
1801 | ext4_grp_locked_error(sb, e4b->bd_group, | 1802 | ext4_grp_locked_error(sb, e4b->bd_group, 0, 0, |
1802 | __func__, "%d free blocks as per " | 1803 | "%d free blocks as per " |
1803 | "group info. But got %d blocks", | 1804 | "group info. But got %d blocks", |
1804 | free, ex.fe_len); | 1805 | free, ex.fe_len); |
1805 | /* | 1806 | /* |
@@ -1821,8 +1822,7 @@ void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, | |||
1821 | 1822 | ||
1822 | /* | 1823 | /* |
1823 | * This is a special case for storages like raid5 | 1824 | * This is a special case for storages like raid5 |
1824 | * we try to find stripe-aligned chunks for stripe-size requests | 1825 | * we try to find stripe-aligned chunks for stripe-size-multiple requests |
1825 | * XXX should do so at least for multiples of stripe size as well | ||
1826 | */ | 1826 | */ |
1827 | static noinline_for_stack | 1827 | static noinline_for_stack |
1828 | void ext4_mb_scan_aligned(struct ext4_allocation_context *ac, | 1828 | void ext4_mb_scan_aligned(struct ext4_allocation_context *ac, |
@@ -1999,7 +1999,6 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac) | |||
1999 | ext4_group_t ngroups, group, i; | 1999 | ext4_group_t ngroups, group, i; |
2000 | int cr; | 2000 | int cr; |
2001 | int err = 0; | 2001 | int err = 0; |
2002 | int bsbits; | ||
2003 | struct ext4_sb_info *sbi; | 2002 | struct ext4_sb_info *sbi; |
2004 | struct super_block *sb; | 2003 | struct super_block *sb; |
2005 | struct ext4_buddy e4b; | 2004 | struct ext4_buddy e4b; |
@@ -2041,8 +2040,6 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac) | |||
2041 | ac->ac_2order = i - 1; | 2040 | ac->ac_2order = i - 1; |
2042 | } | 2041 | } |
2043 | 2042 | ||
2044 | bsbits = ac->ac_sb->s_blocksize_bits; | ||
2045 | |||
2046 | /* if stream allocation is enabled, use global goal */ | 2043 | /* if stream allocation is enabled, use global goal */ |
2047 | if (ac->ac_flags & EXT4_MB_STREAM_ALLOC) { | 2044 | if (ac->ac_flags & EXT4_MB_STREAM_ALLOC) { |
2048 | /* TBD: may be hot point */ | 2045 | /* TBD: may be hot point */ |
@@ -2094,8 +2091,8 @@ repeat: | |||
2094 | ac->ac_groups_scanned++; | 2091 | ac->ac_groups_scanned++; |
2095 | if (cr == 0) | 2092 | if (cr == 0) |
2096 | ext4_mb_simple_scan_group(ac, &e4b); | 2093 | ext4_mb_simple_scan_group(ac, &e4b); |
2097 | else if (cr == 1 && | 2094 | else if (cr == 1 && sbi->s_stripe && |
2098 | ac->ac_g_ex.fe_len == sbi->s_stripe) | 2095 | !(ac->ac_g_ex.fe_len % sbi->s_stripe)) |
2099 | ext4_mb_scan_aligned(ac, &e4b); | 2096 | ext4_mb_scan_aligned(ac, &e4b); |
2100 | else | 2097 | else |
2101 | ext4_mb_complex_scan_group(ac, &e4b); | 2098 | ext4_mb_complex_scan_group(ac, &e4b); |
@@ -2221,7 +2218,7 @@ static int ext4_mb_seq_groups_open(struct inode *inode, struct file *file) | |||
2221 | 2218 | ||
2222 | rc = seq_open(file, &ext4_mb_seq_groups_ops); | 2219 | rc = seq_open(file, &ext4_mb_seq_groups_ops); |
2223 | if (rc == 0) { | 2220 | if (rc == 0) { |
2224 | struct seq_file *m = (struct seq_file *)file->private_data; | 2221 | struct seq_file *m = file->private_data; |
2225 | m->private = sb; | 2222 | m->private = sb; |
2226 | } | 2223 | } |
2227 | return rc; | 2224 | return rc; |
@@ -2560,6 +2557,22 @@ int ext4_mb_release(struct super_block *sb) | |||
2560 | return 0; | 2557 | return 0; |
2561 | } | 2558 | } |
2562 | 2559 | ||
2560 | static inline void ext4_issue_discard(struct super_block *sb, | ||
2561 | ext4_group_t block_group, ext4_grpblk_t block, int count) | ||
2562 | { | ||
2563 | int ret; | ||
2564 | ext4_fsblk_t discard_block; | ||
2565 | |||
2566 | discard_block = block + ext4_group_first_block_no(sb, block_group); | ||
2567 | trace_ext4_discard_blocks(sb, | ||
2568 | (unsigned long long) discard_block, count); | ||
2569 | ret = sb_issue_discard(sb, discard_block, count); | ||
2570 | if (ret == EOPNOTSUPP) { | ||
2571 | ext4_warning(sb, "discard not supported, disabling"); | ||
2572 | clear_opt(EXT4_SB(sb)->s_mount_opt, DISCARD); | ||
2573 | } | ||
2574 | } | ||
2575 | |||
2563 | /* | 2576 | /* |
2564 | * This function is called by the jbd2 layer once the commit has finished, | 2577 | * This function is called by the jbd2 layer once the commit has finished, |
2565 | * so we know we can free the blocks that were released with that commit. | 2578 | * so we know we can free the blocks that were released with that commit. |
@@ -2579,22 +2592,9 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn) | |||
2579 | mb_debug(1, "gonna free %u blocks in group %u (0x%p):", | 2592 | mb_debug(1, "gonna free %u blocks in group %u (0x%p):", |
2580 | entry->count, entry->group, entry); | 2593 | entry->count, entry->group, entry); |
2581 | 2594 | ||
2582 | if (test_opt(sb, DISCARD)) { | 2595 | if (test_opt(sb, DISCARD)) |
2583 | int ret; | 2596 | ext4_issue_discard(sb, entry->group, |
2584 | ext4_fsblk_t discard_block; | 2597 | entry->start_blk, entry->count); |
2585 | |||
2586 | discard_block = entry->start_blk + | ||
2587 | ext4_group_first_block_no(sb, entry->group); | ||
2588 | trace_ext4_discard_blocks(sb, | ||
2589 | (unsigned long long)discard_block, | ||
2590 | entry->count); | ||
2591 | ret = sb_issue_discard(sb, discard_block, entry->count); | ||
2592 | if (ret == EOPNOTSUPP) { | ||
2593 | ext4_warning(sb, | ||
2594 | "discard not supported, disabling"); | ||
2595 | clear_opt(EXT4_SB(sb)->s_mount_opt, DISCARD); | ||
2596 | } | ||
2597 | } | ||
2598 | 2598 | ||
2599 | err = ext4_mb_load_buddy(sb, entry->group, &e4b); | 2599 | err = ext4_mb_load_buddy(sb, entry->group, &e4b); |
2600 | /* we expect to find existing buddy because it's pinned */ | 2600 | /* we expect to find existing buddy because it's pinned */ |
@@ -2712,7 +2712,6 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, | |||
2712 | handle_t *handle, unsigned int reserv_blks) | 2712 | handle_t *handle, unsigned int reserv_blks) |
2713 | { | 2713 | { |
2714 | struct buffer_head *bitmap_bh = NULL; | 2714 | struct buffer_head *bitmap_bh = NULL; |
2715 | struct ext4_super_block *es; | ||
2716 | struct ext4_group_desc *gdp; | 2715 | struct ext4_group_desc *gdp; |
2717 | struct buffer_head *gdp_bh; | 2716 | struct buffer_head *gdp_bh; |
2718 | struct ext4_sb_info *sbi; | 2717 | struct ext4_sb_info *sbi; |
@@ -2725,8 +2724,6 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, | |||
2725 | 2724 | ||
2726 | sb = ac->ac_sb; | 2725 | sb = ac->ac_sb; |
2727 | sbi = EXT4_SB(sb); | 2726 | sbi = EXT4_SB(sb); |
2728 | es = sbi->s_es; | ||
2729 | |||
2730 | 2727 | ||
2731 | err = -EIO; | 2728 | err = -EIO; |
2732 | bitmap_bh = ext4_read_block_bitmap(sb, ac->ac_b_ex.fe_group); | 2729 | bitmap_bh = ext4_read_block_bitmap(sb, ac->ac_b_ex.fe_group); |
@@ -2812,7 +2809,7 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, | |||
2812 | err = ext4_handle_dirty_metadata(handle, NULL, gdp_bh); | 2809 | err = ext4_handle_dirty_metadata(handle, NULL, gdp_bh); |
2813 | 2810 | ||
2814 | out_err: | 2811 | out_err: |
2815 | sb->s_dirt = 1; | 2812 | ext4_mark_super_dirty(sb); |
2816 | brelse(bitmap_bh); | 2813 | brelse(bitmap_bh); |
2817 | return err; | 2814 | return err; |
2818 | } | 2815 | } |
@@ -2850,7 +2847,7 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, | |||
2850 | int bsbits, max; | 2847 | int bsbits, max; |
2851 | ext4_lblk_t end; | 2848 | ext4_lblk_t end; |
2852 | loff_t size, orig_size, start_off; | 2849 | loff_t size, orig_size, start_off; |
2853 | ext4_lblk_t start, orig_start; | 2850 | ext4_lblk_t start; |
2854 | struct ext4_inode_info *ei = EXT4_I(ac->ac_inode); | 2851 | struct ext4_inode_info *ei = EXT4_I(ac->ac_inode); |
2855 | struct ext4_prealloc_space *pa; | 2852 | struct ext4_prealloc_space *pa; |
2856 | 2853 | ||
@@ -2881,6 +2878,7 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, | |||
2881 | size = size << bsbits; | 2878 | size = size << bsbits; |
2882 | if (size < i_size_read(ac->ac_inode)) | 2879 | if (size < i_size_read(ac->ac_inode)) |
2883 | size = i_size_read(ac->ac_inode); | 2880 | size = i_size_read(ac->ac_inode); |
2881 | orig_size = size; | ||
2884 | 2882 | ||
2885 | /* max size of free chunks */ | 2883 | /* max size of free chunks */ |
2886 | max = 2 << bsbits; | 2884 | max = 2 << bsbits; |
@@ -2922,8 +2920,8 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, | |||
2922 | start_off = (loff_t)ac->ac_o_ex.fe_logical << bsbits; | 2920 | start_off = (loff_t)ac->ac_o_ex.fe_logical << bsbits; |
2923 | size = ac->ac_o_ex.fe_len << bsbits; | 2921 | size = ac->ac_o_ex.fe_len << bsbits; |
2924 | } | 2922 | } |
2925 | orig_size = size = size >> bsbits; | 2923 | size = size >> bsbits; |
2926 | orig_start = start = start_off >> bsbits; | 2924 | start = start_off >> bsbits; |
2927 | 2925 | ||
2928 | /* don't cover already allocated blocks in selected range */ | 2926 | /* don't cover already allocated blocks in selected range */ |
2929 | if (ar->pleft && start <= ar->lleft) { | 2927 | if (ar->pleft && start <= ar->lleft) { |
@@ -3547,7 +3545,6 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh, | |||
3547 | ext4_group_t group; | 3545 | ext4_group_t group; |
3548 | ext4_grpblk_t bit; | 3546 | ext4_grpblk_t bit; |
3549 | unsigned long long grp_blk_start; | 3547 | unsigned long long grp_blk_start; |
3550 | sector_t start; | ||
3551 | int err = 0; | 3548 | int err = 0; |
3552 | int free = 0; | 3549 | int free = 0; |
3553 | 3550 | ||
@@ -3567,10 +3564,9 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh, | |||
3567 | if (bit >= end) | 3564 | if (bit >= end) |
3568 | break; | 3565 | break; |
3569 | next = mb_find_next_bit(bitmap_bh->b_data, end, bit); | 3566 | next = mb_find_next_bit(bitmap_bh->b_data, end, bit); |
3570 | start = ext4_group_first_block_no(sb, group) + bit; | ||
3571 | mb_debug(1, " free preallocated %u/%u in group %u\n", | 3567 | mb_debug(1, " free preallocated %u/%u in group %u\n", |
3572 | (unsigned) start, (unsigned) next - bit, | 3568 | (unsigned) ext4_group_first_block_no(sb, group) + bit, |
3573 | (unsigned) group); | 3569 | (unsigned) next - bit, (unsigned) group); |
3574 | free += next - bit; | 3570 | free += next - bit; |
3575 | 3571 | ||
3576 | if (ac) { | 3572 | if (ac) { |
@@ -3581,7 +3577,7 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh, | |||
3581 | trace_ext4_mballoc_discard(ac); | 3577 | trace_ext4_mballoc_discard(ac); |
3582 | } | 3578 | } |
3583 | 3579 | ||
3584 | trace_ext4_mb_release_inode_pa(ac, pa, grp_blk_start + bit, | 3580 | trace_ext4_mb_release_inode_pa(sb, ac, pa, grp_blk_start + bit, |
3585 | next - bit); | 3581 | next - bit); |
3586 | mb_free_blocks(pa->pa_inode, e4b, bit, next - bit); | 3582 | mb_free_blocks(pa->pa_inode, e4b, bit, next - bit); |
3587 | bit = next + 1; | 3583 | bit = next + 1; |
@@ -3591,8 +3587,7 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh, | |||
3591 | pa, (unsigned long) pa->pa_lstart, | 3587 | pa, (unsigned long) pa->pa_lstart, |
3592 | (unsigned long) pa->pa_pstart, | 3588 | (unsigned long) pa->pa_pstart, |
3593 | (unsigned long) pa->pa_len); | 3589 | (unsigned long) pa->pa_len); |
3594 | ext4_grp_locked_error(sb, group, | 3590 | ext4_grp_locked_error(sb, group, 0, 0, "free %u, pa_free %u", |
3595 | __func__, "free %u, pa_free %u", | ||
3596 | free, pa->pa_free); | 3591 | free, pa->pa_free); |
3597 | /* | 3592 | /* |
3598 | * pa is already deleted so we use the value obtained | 3593 | * pa is already deleted so we use the value obtained |
@@ -3613,7 +3608,7 @@ ext4_mb_release_group_pa(struct ext4_buddy *e4b, | |||
3613 | ext4_group_t group; | 3608 | ext4_group_t group; |
3614 | ext4_grpblk_t bit; | 3609 | ext4_grpblk_t bit; |
3615 | 3610 | ||
3616 | trace_ext4_mb_release_group_pa(ac, pa); | 3611 | trace_ext4_mb_release_group_pa(sb, ac, pa); |
3617 | BUG_ON(pa->pa_deleted == 0); | 3612 | BUG_ON(pa->pa_deleted == 0); |
3618 | ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit); | 3613 | ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit); |
3619 | BUG_ON(group != e4b->bd_group && pa->pa_len != 0); | 3614 | BUG_ON(group != e4b->bd_group && pa->pa_len != 0); |
@@ -3889,6 +3884,9 @@ static void ext4_mb_show_ac(struct ext4_allocation_context *ac) | |||
3889 | struct super_block *sb = ac->ac_sb; | 3884 | struct super_block *sb = ac->ac_sb; |
3890 | ext4_group_t ngroups, i; | 3885 | ext4_group_t ngroups, i; |
3891 | 3886 | ||
3887 | if (EXT4_SB(sb)->s_mount_flags & EXT4_MF_FS_ABORTED) | ||
3888 | return; | ||
3889 | |||
3892 | printk(KERN_ERR "EXT4-fs: Can't allocate:" | 3890 | printk(KERN_ERR "EXT4-fs: Can't allocate:" |
3893 | " Allocation context details:\n"); | 3891 | " Allocation context details:\n"); |
3894 | printk(KERN_ERR "EXT4-fs: status %d flags %d\n", | 3892 | printk(KERN_ERR "EXT4-fs: status %d flags %d\n", |
@@ -4255,7 +4253,7 @@ static int ext4_mb_discard_preallocations(struct super_block *sb, int needed) | |||
4255 | * to usual allocation | 4253 | * to usual allocation |
4256 | */ | 4254 | */ |
4257 | ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, | 4255 | ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, |
4258 | struct ext4_allocation_request *ar, int *errp) | 4256 | struct ext4_allocation_request *ar, int *errp) |
4259 | { | 4257 | { |
4260 | int freed; | 4258 | int freed; |
4261 | struct ext4_allocation_context *ac = NULL; | 4259 | struct ext4_allocation_context *ac = NULL; |
@@ -4299,7 +4297,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, | |||
4299 | inquota = ar->len; | 4297 | inquota = ar->len; |
4300 | if (ar->len == 0) { | 4298 | if (ar->len == 0) { |
4301 | *errp = -EDQUOT; | 4299 | *errp = -EDQUOT; |
4302 | goto out3; | 4300 | goto out; |
4303 | } | 4301 | } |
4304 | } | 4302 | } |
4305 | 4303 | ||
@@ -4307,13 +4305,13 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, | |||
4307 | if (!ac) { | 4305 | if (!ac) { |
4308 | ar->len = 0; | 4306 | ar->len = 0; |
4309 | *errp = -ENOMEM; | 4307 | *errp = -ENOMEM; |
4310 | goto out1; | 4308 | goto out; |
4311 | } | 4309 | } |
4312 | 4310 | ||
4313 | *errp = ext4_mb_initialize_context(ac, ar); | 4311 | *errp = ext4_mb_initialize_context(ac, ar); |
4314 | if (*errp) { | 4312 | if (*errp) { |
4315 | ar->len = 0; | 4313 | ar->len = 0; |
4316 | goto out2; | 4314 | goto out; |
4317 | } | 4315 | } |
4318 | 4316 | ||
4319 | ac->ac_op = EXT4_MB_HISTORY_PREALLOC; | 4317 | ac->ac_op = EXT4_MB_HISTORY_PREALLOC; |
@@ -4322,7 +4320,9 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, | |||
4322 | ext4_mb_normalize_request(ac, ar); | 4320 | ext4_mb_normalize_request(ac, ar); |
4323 | repeat: | 4321 | repeat: |
4324 | /* allocate space in core */ | 4322 | /* allocate space in core */ |
4325 | ext4_mb_regular_allocator(ac); | 4323 | *errp = ext4_mb_regular_allocator(ac); |
4324 | if (*errp) | ||
4325 | goto errout; | ||
4326 | 4326 | ||
4327 | /* as we've just preallocated more space than | 4327 | /* as we've just preallocated more space than |
4328 | * user requested orinally, we store allocated | 4328 | * user requested orinally, we store allocated |
@@ -4333,7 +4333,7 @@ repeat: | |||
4333 | } | 4333 | } |
4334 | if (likely(ac->ac_status == AC_STATUS_FOUND)) { | 4334 | if (likely(ac->ac_status == AC_STATUS_FOUND)) { |
4335 | *errp = ext4_mb_mark_diskspace_used(ac, handle, reserv_blks); | 4335 | *errp = ext4_mb_mark_diskspace_used(ac, handle, reserv_blks); |
4336 | if (*errp == -EAGAIN) { | 4336 | if (*errp == -EAGAIN) { |
4337 | /* | 4337 | /* |
4338 | * drop the reference that we took | 4338 | * drop the reference that we took |
4339 | * in ext4_mb_use_best_found | 4339 | * in ext4_mb_use_best_found |
@@ -4344,12 +4344,10 @@ repeat: | |||
4344 | ac->ac_b_ex.fe_len = 0; | 4344 | ac->ac_b_ex.fe_len = 0; |
4345 | ac->ac_status = AC_STATUS_CONTINUE; | 4345 | ac->ac_status = AC_STATUS_CONTINUE; |
4346 | goto repeat; | 4346 | goto repeat; |
4347 | } else if (*errp) { | 4347 | } else if (*errp) |
4348 | errout: | ||
4348 | ext4_discard_allocated_blocks(ac); | 4349 | ext4_discard_allocated_blocks(ac); |
4349 | ac->ac_b_ex.fe_len = 0; | 4350 | else { |
4350 | ar->len = 0; | ||
4351 | ext4_mb_show_ac(ac); | ||
4352 | } else { | ||
4353 | block = ext4_grp_offs_to_block(sb, &ac->ac_b_ex); | 4351 | block = ext4_grp_offs_to_block(sb, &ac->ac_b_ex); |
4354 | ar->len = ac->ac_b_ex.fe_len; | 4352 | ar->len = ac->ac_b_ex.fe_len; |
4355 | } | 4353 | } |
@@ -4358,19 +4356,19 @@ repeat: | |||
4358 | if (freed) | 4356 | if (freed) |
4359 | goto repeat; | 4357 | goto repeat; |
4360 | *errp = -ENOSPC; | 4358 | *errp = -ENOSPC; |
4359 | } | ||
4360 | |||
4361 | if (*errp) { | ||
4361 | ac->ac_b_ex.fe_len = 0; | 4362 | ac->ac_b_ex.fe_len = 0; |
4362 | ar->len = 0; | 4363 | ar->len = 0; |
4363 | ext4_mb_show_ac(ac); | 4364 | ext4_mb_show_ac(ac); |
4364 | } | 4365 | } |
4365 | |||
4366 | ext4_mb_release_context(ac); | 4366 | ext4_mb_release_context(ac); |
4367 | 4367 | out: | |
4368 | out2: | 4368 | if (ac) |
4369 | kmem_cache_free(ext4_ac_cachep, ac); | 4369 | kmem_cache_free(ext4_ac_cachep, ac); |
4370 | out1: | ||
4371 | if (inquota && ar->len < inquota) | 4370 | if (inquota && ar->len < inquota) |
4372 | dquot_free_block(ar->inode, inquota - ar->len); | 4371 | dquot_free_block(ar->inode, inquota - ar->len); |
4373 | out3: | ||
4374 | if (!ar->len) { | 4372 | if (!ar->len) { |
4375 | if (!EXT4_I(ar->inode)->i_delalloc_reserved_flag) | 4373 | if (!EXT4_I(ar->inode)->i_delalloc_reserved_flag) |
4376 | /* release all the reserved blocks if non delalloc */ | 4374 | /* release all the reserved blocks if non delalloc */ |
@@ -4402,6 +4400,7 @@ static noinline_for_stack int | |||
4402 | ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b, | 4400 | ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b, |
4403 | struct ext4_free_data *new_entry) | 4401 | struct ext4_free_data *new_entry) |
4404 | { | 4402 | { |
4403 | ext4_group_t group = e4b->bd_group; | ||
4405 | ext4_grpblk_t block; | 4404 | ext4_grpblk_t block; |
4406 | struct ext4_free_data *entry; | 4405 | struct ext4_free_data *entry; |
4407 | struct ext4_group_info *db = e4b->bd_info; | 4406 | struct ext4_group_info *db = e4b->bd_info; |
@@ -4434,9 +4433,9 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b, | |||
4434 | else if (block >= (entry->start_blk + entry->count)) | 4433 | else if (block >= (entry->start_blk + entry->count)) |
4435 | n = &(*n)->rb_right; | 4434 | n = &(*n)->rb_right; |
4436 | else { | 4435 | else { |
4437 | ext4_grp_locked_error(sb, e4b->bd_group, __func__, | 4436 | ext4_grp_locked_error(sb, group, 0, |
4438 | "Double free of blocks %d (%d %d)", | 4437 | ext4_group_first_block_no(sb, group) + block, |
4439 | block, entry->start_blk, entry->count); | 4438 | "Block already on to-be-freed list"); |
4440 | return 0; | 4439 | return 0; |
4441 | } | 4440 | } |
4442 | } | 4441 | } |
@@ -4494,7 +4493,6 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, | |||
4494 | struct super_block *sb = inode->i_sb; | 4493 | struct super_block *sb = inode->i_sb; |
4495 | struct ext4_allocation_context *ac = NULL; | 4494 | struct ext4_allocation_context *ac = NULL; |
4496 | struct ext4_group_desc *gdp; | 4495 | struct ext4_group_desc *gdp; |
4497 | struct ext4_super_block *es; | ||
4498 | unsigned long freed = 0; | 4496 | unsigned long freed = 0; |
4499 | unsigned int overflow; | 4497 | unsigned int overflow; |
4500 | ext4_grpblk_t bit; | 4498 | ext4_grpblk_t bit; |
@@ -4513,7 +4511,6 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, | |||
4513 | } | 4511 | } |
4514 | 4512 | ||
4515 | sbi = EXT4_SB(sb); | 4513 | sbi = EXT4_SB(sb); |
4516 | es = EXT4_SB(sb)->s_es; | ||
4517 | if (!(flags & EXT4_FREE_BLOCKS_VALIDATED) && | 4514 | if (!(flags & EXT4_FREE_BLOCKS_VALIDATED) && |
4518 | !ext4_data_block_valid(sbi, block, count)) { | 4515 | !ext4_data_block_valid(sbi, block, count)) { |
4519 | ext4_error(sb, "Freeing blocks not in datazone - " | 4516 | ext4_error(sb, "Freeing blocks not in datazone - " |
@@ -4647,6 +4644,8 @@ do_more: | |||
4647 | mb_clear_bits(bitmap_bh->b_data, bit, count); | 4644 | mb_clear_bits(bitmap_bh->b_data, bit, count); |
4648 | mb_free_blocks(inode, &e4b, bit, count); | 4645 | mb_free_blocks(inode, &e4b, bit, count); |
4649 | ext4_mb_return_to_preallocation(inode, &e4b, block, count); | 4646 | ext4_mb_return_to_preallocation(inode, &e4b, block, count); |
4647 | if (test_opt(sb, DISCARD)) | ||
4648 | ext4_issue_discard(sb, block_group, bit, count); | ||
4650 | } | 4649 | } |
4651 | 4650 | ||
4652 | ret = ext4_free_blks_count(sb, gdp) + count; | 4651 | ret = ext4_free_blks_count(sb, gdp) + count; |
@@ -4680,7 +4679,7 @@ do_more: | |||
4680 | put_bh(bitmap_bh); | 4679 | put_bh(bitmap_bh); |
4681 | goto do_more; | 4680 | goto do_more; |
4682 | } | 4681 | } |
4683 | sb->s_dirt = 1; | 4682 | ext4_mark_super_dirty(sb); |
4684 | error_return: | 4683 | error_return: |
4685 | if (freed) | 4684 | if (freed) |
4686 | dquot_free_block(inode, freed); | 4685 | dquot_free_block(inode, freed); |