]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - fs/ext4/mballoc.c
ext4: don't print scary messages for allocation failures post-abort
[mirror_ubuntu-bionic-kernel.git] / fs / ext4 / mballoc.c
index b423a364dca3c16cf8268861f3107f275c32474e..3da28281bc54b37f3346c46b4349e9fefc835f63 100644 (file)
@@ -446,10 +446,11 @@ static void mb_free_blocks_double(struct inode *inode, struct ext4_buddy *e4b,
                        blocknr = ext4_group_first_block_no(sb, e4b->bd_group);
                        blocknr += first + i;
                        ext4_grp_locked_error(sb, e4b->bd_group,
-                                  __func__, "double-free of inode"
-                                  " %lu's block %llu(bit %u in group %u)",
-                                  inode ? inode->i_ino : 0, blocknr,
-                                  first + i, e4b->bd_group);
+                                             inode ? inode->i_ino : 0,
+                                             blocknr,
+                                             "freeing block already freed "
+                                             "(bit %u)",
+                                             first + i);
                }
                mb_clear_bit(first + i, e4b->bd_info->bb_bitmap);
        }
@@ -658,6 +659,27 @@ static void ext4_mb_mark_free_simple(struct super_block *sb,
        }
 }
 
+/*
+ * Cache the order of the largest free extent we have available in this block
+ * group.
+ */
+static void
+mb_set_largest_free_order(struct super_block *sb, struct ext4_group_info *grp)
+{
+       int i;
+       int bits;
+
+       grp->bb_largest_free_order = -1; /* uninit */
+
+       bits = sb->s_blocksize_bits + 1;
+       for (i = bits; i >= 0; i--) {
+               if (grp->bb_counters[i] > 0) {
+                       grp->bb_largest_free_order = i;
+                       break;
+               }
+       }
+}
+
 static noinline_for_stack
 void ext4_mb_generate_buddy(struct super_block *sb,
                                void *buddy, void *bitmap, ext4_group_t group)
@@ -691,15 +713,16 @@ void ext4_mb_generate_buddy(struct super_block *sb,
        grp->bb_fragments = fragments;
 
        if (free != grp->bb_free) {
-               ext4_grp_locked_error(sb, group,  __func__,
-                       "EXT4-fs: group %u: %u blocks in bitmap, %u in gd",
-                       group, free, grp->bb_free);
+               ext4_grp_locked_error(sb, group, 0, 0,
+                                     "%u blocks in bitmap, %u in gd",
+                                     free, grp->bb_free);
                /*
                 * If we intent to continue, we consider group descritor
                 * corrupt and update bb_free using bitmap value
                 */
                grp->bb_free = free;
        }
+       mb_set_largest_free_order(sb, grp);
 
        clear_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &(grp->bb_state));
 
@@ -725,6 +748,9 @@ void ext4_mb_generate_buddy(struct super_block *sb,
  * contain blocks_per_page (PAGE_CACHE_SIZE / blocksize)  blocks.
  * So it can have information regarding groups_per_page which
  * is blocks_per_page/2
+ *
+ * Locking note:  This routine takes the block group lock of all groups
+ * for this page; do not hold this lock when calling this routine!
  */
 
 static int ext4_mb_init_cache(struct page *page, char *incore)
@@ -865,6 +891,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
                        BUG_ON(incore == NULL);
                        mb_debug(1, "put buddy for group %u in page %lu/%x\n",
                                group, page->index, i * blocksize);
+                       trace_ext4_mb_buddy_bitmap_load(sb, group);
                        grinfo = ext4_get_group_info(sb, group);
                        grinfo->bb_fragments = 0;
                        memset(grinfo->bb_counters, 0,
@@ -882,6 +909,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
                        BUG_ON(incore != NULL);
                        mb_debug(1, "put bitmap for group %u in page %lu/%x\n",
                                group, page->index, i * blocksize);
+                       trace_ext4_mb_bitmap_load(sb, group);
 
                        /* see comments in ext4_mb_put_pa() */
                        ext4_lock_group(sb, group);
@@ -910,6 +938,11 @@ out:
        return err;
 }
 
+/*
+ * Locking note:  This routine calls ext4_mb_init_cache(), which takes the
+ * block group lock of all groups for this page; do not hold the BG lock when
+ * calling this routine!
+ */
 static noinline_for_stack
 int ext4_mb_init_group(struct super_block *sb, ext4_group_t group)
 {
@@ -1004,6 +1037,11 @@ err:
        return ret;
 }
 
+/*
+ * Locking note:  This routine calls ext4_mb_init_cache(), which takes the
+ * block group lock of all groups for this page; do not hold the BG lock when
+ * calling this routine!
+ */
 static noinline_for_stack int
 ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group,
                                        struct ext4_buddy *e4b)
@@ -1150,7 +1188,7 @@ err:
        return ret;
 }
 
-static void ext4_mb_release_desc(struct ext4_buddy *e4b)
+static void ext4_mb_unload_buddy(struct ext4_buddy *e4b)
 {
        if (e4b->bd_bitmap_page)
                page_cache_release(e4b->bd_bitmap_page);
@@ -1259,10 +1297,10 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b,
                        blocknr = ext4_group_first_block_no(sb, e4b->bd_group);
                        blocknr += block;
                        ext4_grp_locked_error(sb, e4b->bd_group,
-                                  __func__, "double-free of inode"
-                                  " %lu's block %llu(bit %u in group %u)",
-                                  inode ? inode->i_ino : 0, blocknr, block,
-                                  e4b->bd_group);
+                                             inode ? inode->i_ino : 0,
+                                             blocknr,
+                                             "freeing already freed block "
+                                             "(bit %u)", block);
                }
                mb_clear_bit(block, EXT4_MB_BITMAP(e4b));
                e4b->bd_info->bb_counters[order]++;
@@ -1299,6 +1337,7 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b,
                        buddy = buddy2;
                } while (1);
        }
+       mb_set_largest_free_order(sb, e4b->bd_info);
        mb_check_buddy(e4b);
 }
 
@@ -1427,6 +1466,7 @@ static int mb_mark_used(struct ext4_buddy *e4b, struct ext4_free_extent *ex)
                e4b->bd_info->bb_counters[ord]++;
                e4b->bd_info->bb_counters[ord]++;
        }
+       mb_set_largest_free_order(e4b->bd_sb, e4b->bd_info);
 
        mb_set_bits(EXT4_MB_BITMAP(e4b), ex->fe_start, len0);
        mb_check_buddy(e4b);
@@ -1617,7 +1657,7 @@ int ext4_mb_try_best_found(struct ext4_allocation_context *ac,
        }
 
        ext4_unlock_group(ac->ac_sb, group);
-       ext4_mb_release_desc(e4b);
+       ext4_mb_unload_buddy(e4b);
 
        return 0;
 }
@@ -1672,7 +1712,7 @@ int ext4_mb_find_by_goal(struct ext4_allocation_context *ac,
                ext4_mb_use_best_found(ac, e4b);
        }
        ext4_unlock_group(ac->ac_sb, group);
-       ext4_mb_release_desc(e4b);
+       ext4_mb_unload_buddy(e4b);
 
        return 0;
 }
@@ -1749,8 +1789,8 @@ void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac,
                         * free blocks even though group info says we
                         * we have free blocks
                         */
-                       ext4_grp_locked_error(sb, e4b->bd_group,
-                                       __func__, "%d free blocks as per "
+                       ext4_grp_locked_error(sb, e4b->bd_group, 0, 0,
+                                       "%d free blocks as per "
                                        "group info. But bitmap says 0",
                                        free);
                        break;
@@ -1759,8 +1799,8 @@ void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac,
                mb_find_extent(e4b, 0, i, ac->ac_g_ex.fe_len, &ex);
                BUG_ON(ex.fe_len <= 0);
                if (free < ex.fe_len) {
-                       ext4_grp_locked_error(sb, e4b->bd_group,
-                                       __func__, "%d free blocks as per "
+                       ext4_grp_locked_error(sb, e4b->bd_group, 0, 0,
+                                       "%d free blocks as per "
                                        "group info. But got %d blocks",
                                        free, ex.fe_len);
                        /*
@@ -1782,8 +1822,7 @@ void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac,
 
 /*
  * This is a special case for storages like raid5
- * we try to find stripe-aligned chunks for stripe-size requests
- * XXX should do so at least for multiples of stripe size as well
+ * we try to find stripe-aligned chunks for stripe-size-multiple requests
  */
 static noinline_for_stack
 void ext4_mb_scan_aligned(struct ext4_allocation_context *ac,
@@ -1821,16 +1860,22 @@ void ext4_mb_scan_aligned(struct ext4_allocation_context *ac,
        }
 }
 
+/* This is now called BEFORE we load the buddy bitmap. */
 static int ext4_mb_good_group(struct ext4_allocation_context *ac,
                                ext4_group_t group, int cr)
 {
        unsigned free, fragments;
-       unsigned i, bits;
        int flex_size = ext4_flex_bg_size(EXT4_SB(ac->ac_sb));
        struct ext4_group_info *grp = ext4_get_group_info(ac->ac_sb, group);
 
        BUG_ON(cr < 0 || cr >= 4);
-       BUG_ON(EXT4_MB_GRP_NEED_INIT(grp));
+
+       /* We only do this if the grp has never been initialized */
+       if (unlikely(EXT4_MB_GRP_NEED_INIT(grp))) {
+               int ret = ext4_mb_init_group(ac->ac_sb, group);
+               if (ret)
+                       return 0;
+       }
 
        free = grp->bb_free;
        fragments = grp->bb_fragments;
@@ -1843,17 +1888,16 @@ static int ext4_mb_good_group(struct ext4_allocation_context *ac,
        case 0:
                BUG_ON(ac->ac_2order == 0);
 
+               if (grp->bb_largest_free_order < ac->ac_2order)
+                       return 0;
+
                /* Avoid using the first bg of a flexgroup for data files */
                if ((ac->ac_flags & EXT4_MB_HINT_DATA) &&
                    (flex_size >= EXT4_FLEX_SIZE_DIR_ALLOC_SCHEME) &&
                    ((group % flex_size) == 0))
                        return 0;
 
-               bits = ac->ac_sb->s_blocksize_bits + 1;
-               for (i = ac->ac_2order; i <= bits; i++)
-                       if (grp->bb_counters[i] > 0)
-                               return 1;
-               break;
+               return 1;
        case 1:
                if ((free / fragments) >= ac->ac_g_ex.fe_len)
                        return 1;
@@ -1955,7 +1999,6 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
        ext4_group_t ngroups, group, i;
        int cr;
        int err = 0;
-       int bsbits;
        struct ext4_sb_info *sbi;
        struct super_block *sb;
        struct ext4_buddy e4b;
@@ -1964,7 +2007,7 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
        sbi = EXT4_SB(sb);
        ngroups = ext4_get_groups_count(sb);
        /* non-extent files are limited to low blocks/groups */
-       if (!(EXT4_I(ac->ac_inode)->i_flags & EXT4_EXTENTS_FL))
+       if (!(ext4_test_inode_flag(ac->ac_inode, EXT4_INODE_EXTENTS)))
                ngroups = sbi->s_blockfile_groups;
 
        BUG_ON(ac->ac_status == AC_STATUS_FOUND);
@@ -1997,8 +2040,6 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
                        ac->ac_2order = i - 1;
        }
 
-       bsbits = ac->ac_sb->s_blocksize_bits;
-
        /* if stream allocation is enabled, use global goal */
        if (ac->ac_flags & EXT4_MB_STREAM_ALLOC) {
                /* TBD: may be hot point */
@@ -2024,15 +2065,11 @@ repeat:
                group = ac->ac_g_ex.fe_group;
 
                for (i = 0; i < ngroups; group++, i++) {
-                       struct ext4_group_info *grp;
-                       struct ext4_group_desc *desc;
-
                        if (group == ngroups)
                                group = 0;
 
-                       /* quick check to skip empty groups */
-                       grp = ext4_get_group_info(sb, group);
-                       if (grp->bb_free == 0)
+                       /* This now checks without needing the buddy page */
+                       if (!ext4_mb_good_group(ac, group, cr))
                                continue;
 
                        err = ext4_mb_load_buddy(sb, group, &e4b);
@@ -2040,25 +2077,28 @@ repeat:
                                goto out;
 
                        ext4_lock_group(sb, group);
+
+                       /*
+                        * We need to check again after locking the
+                        * block group
+                        */
                        if (!ext4_mb_good_group(ac, group, cr)) {
-                               /* someone did allocation from this group */
                                ext4_unlock_group(sb, group);
-                               ext4_mb_release_desc(&e4b);
+                               ext4_mb_unload_buddy(&e4b);
                                continue;
                        }
 
                        ac->ac_groups_scanned++;
-                       desc = ext4_get_group_desc(sb, group, NULL);
                        if (cr == 0)
                                ext4_mb_simple_scan_group(ac, &e4b);
-                       else if (cr == 1 &&
-                                       ac->ac_g_ex.fe_len == sbi->s_stripe)
+                       else if (cr == 1 && sbi->s_stripe &&
+                                       !(ac->ac_g_ex.fe_len % sbi->s_stripe))
                                ext4_mb_scan_aligned(ac, &e4b);
                        else
                                ext4_mb_complex_scan_group(ac, &e4b);
 
                        ext4_unlock_group(sb, group);
-                       ext4_mb_release_desc(&e4b);
+                       ext4_mb_unload_buddy(&e4b);
 
                        if (ac->ac_status != AC_STATUS_CONTINUE)
                                break;
@@ -2148,7 +2188,7 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v)
        ext4_lock_group(sb, group);
        memcpy(&sg, ext4_get_group_info(sb, group), i);
        ext4_unlock_group(sb, group);
-       ext4_mb_release_desc(&e4b);
+       ext4_mb_unload_buddy(&e4b);
 
        seq_printf(seq, "#%-5u: %-5u %-5u %-5u [", group, sg.info.bb_free,
                        sg.info.bb_fragments, sg.info.bb_first_free);
@@ -2178,7 +2218,7 @@ static int ext4_mb_seq_groups_open(struct inode *inode, struct file *file)
 
        rc = seq_open(file, &ext4_mb_seq_groups_ops);
        if (rc == 0) {
-               struct seq_file *m = (struct seq_file *)file->private_data;
+               struct seq_file *m = file->private_data;
                m->private = sb;
        }
        return rc;
@@ -2255,6 +2295,7 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group,
        INIT_LIST_HEAD(&meta_group_info[i]->bb_prealloc_list);
        init_rwsem(&meta_group_info[i]->alloc_sem);
        meta_group_info[i]->bb_free_root = RB_ROOT;
+       meta_group_info[i]->bb_largest_free_order = -1;  /* uninit */
 
 #ifdef DOUBLE_CHECK
        {
@@ -2516,6 +2557,22 @@ int ext4_mb_release(struct super_block *sb)
        return 0;
 }
 
+static inline void ext4_issue_discard(struct super_block *sb,
+               ext4_group_t block_group, ext4_grpblk_t block, int count)
+{
+       int ret;
+       ext4_fsblk_t discard_block;
+
+       discard_block = block + ext4_group_first_block_no(sb, block_group);
+       trace_ext4_discard_blocks(sb,
+                       (unsigned long long) discard_block, count);
+       ret = sb_issue_discard(sb, discard_block, count);
+       if (ret == EOPNOTSUPP) {
+               ext4_warning(sb, "discard not supported, disabling");
+               clear_opt(EXT4_SB(sb)->s_mount_opt, DISCARD);
+       }
+}
+
 /*
  * This function is called by the jbd2 layer once the commit has finished,
  * so we know we can free the blocks that were released with that commit.
@@ -2535,16 +2592,9 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn)
                mb_debug(1, "gonna free %u blocks in group %u (0x%p):",
                         entry->count, entry->group, entry);
 
-               if (test_opt(sb, DISCARD)) {
-                       ext4_fsblk_t discard_block;
-
-                       discard_block = entry->start_blk +
-                               ext4_group_first_block_no(sb, entry->group);
-                       trace_ext4_discard_blocks(sb,
-                                       (unsigned long long)discard_block,
-                                       entry->count);
-                       sb_issue_discard(sb, discard_block, entry->count);
-               }
+               if (test_opt(sb, DISCARD))
+                       ext4_issue_discard(sb, entry->group,
+                                       entry->start_blk, entry->count);
 
                err = ext4_mb_load_buddy(sb, entry->group, &e4b);
                /* we expect to find existing buddy because it's pinned */
@@ -2568,7 +2618,7 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn)
                }
                ext4_unlock_group(sb, entry->group);
                kmem_cache_free(ext4_free_ext_cachep, entry);
-               ext4_mb_release_desc(&e4b);
+               ext4_mb_unload_buddy(&e4b);
        }
 
        mb_debug(1, "freed %u blocks in %u structures\n", count, count2);
@@ -2641,7 +2691,7 @@ int __init init_ext4_mballoc(void)
 
 void exit_ext4_mballoc(void)
 {
-       /* 
+       /*
         * Wait for completion of call_rcu()'s on ext4_pspace_cachep
         * before destroying the slab cache.
         */
@@ -2662,7 +2712,6 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
                                handle_t *handle, unsigned int reserv_blks)
 {
        struct buffer_head *bitmap_bh = NULL;
-       struct ext4_super_block *es;
        struct ext4_group_desc *gdp;
        struct buffer_head *gdp_bh;
        struct ext4_sb_info *sbi;
@@ -2675,8 +2724,6 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
 
        sb = ac->ac_sb;
        sbi = EXT4_SB(sb);
-       es = sbi->s_es;
-
 
        err = -EIO;
        bitmap_bh = ext4_read_block_bitmap(sb, ac->ac_b_ex.fe_group);
@@ -2762,7 +2809,7 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
        err = ext4_handle_dirty_metadata(handle, NULL, gdp_bh);
 
 out_err:
-       sb->s_dirt = 1;
+       ext4_mark_super_dirty(sb);
        brelse(bitmap_bh);
        return err;
 }
@@ -2800,7 +2847,7 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
        int bsbits, max;
        ext4_lblk_t end;
        loff_t size, orig_size, start_off;
-       ext4_lblk_t start, orig_start;
+       ext4_lblk_t start;
        struct ext4_inode_info *ei = EXT4_I(ac->ac_inode);
        struct ext4_prealloc_space *pa;
 
@@ -2831,6 +2878,7 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
        size = size << bsbits;
        if (size < i_size_read(ac->ac_inode))
                size = i_size_read(ac->ac_inode);
+       orig_size = size;
 
        /* max size of free chunks */
        max = 2 << bsbits;
@@ -2872,8 +2920,8 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
                start_off = (loff_t)ac->ac_o_ex.fe_logical << bsbits;
                size      = ac->ac_o_ex.fe_len << bsbits;
        }
-       orig_size = size = size >> bsbits;
-       orig_start = start = start_off >> bsbits;
+       size = size >> bsbits;
+       start = start_off >> bsbits;
 
        /* don't cover already allocated blocks in selected range */
        if (ar->pleft && start <= ar->lleft) {
@@ -2981,7 +3029,7 @@ static void ext4_mb_collect_stats(struct ext4_allocation_context *ac)
        if (sbi->s_mb_stats && ac->ac_g_ex.fe_len > 1) {
                atomic_inc(&sbi->s_bal_reqs);
                atomic_add(ac->ac_b_ex.fe_len, &sbi->s_bal_allocated);
-               if (ac->ac_o_ex.fe_len >= ac->ac_g_ex.fe_len)
+               if (ac->ac_b_ex.fe_len >= ac->ac_o_ex.fe_len)
                        atomic_inc(&sbi->s_bal_success);
                atomic_add(ac->ac_found, &sbi->s_bal_ex_scanned);
                if (ac->ac_g_ex.fe_start == ac->ac_b_ex.fe_start &&
@@ -3123,7 +3171,7 @@ ext4_mb_use_preallocated(struct ext4_allocation_context *ac)
                        continue;
 
                /* non-extent files can't have physical blocks past 2^32 */
-               if (!(EXT4_I(ac->ac_inode)->i_flags & EXT4_EXTENTS_FL) &&
+               if (!(ext4_test_inode_flag(ac->ac_inode, EXT4_INODE_EXTENTS)) &&
                        pa->pa_pstart + pa->pa_len > EXT4_MAX_BLOCK_FILE_PHYS)
                        continue;
 
@@ -3280,7 +3328,7 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac,
        spin_unlock(&pa->pa_lock);
 
        grp_blk = pa->pa_pstart;
-       /* 
+       /*
         * If doing group-based preallocation, pa_pstart may be in the
         * next group when pa is used up
         */
@@ -3497,7 +3545,6 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh,
        ext4_group_t group;
        ext4_grpblk_t bit;
        unsigned long long grp_blk_start;
-       sector_t start;
        int err = 0;
        int free = 0;
 
@@ -3517,10 +3564,9 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh,
                if (bit >= end)
                        break;
                next = mb_find_next_bit(bitmap_bh->b_data, end, bit);
-               start = ext4_group_first_block_no(sb, group) + bit;
                mb_debug(1, "    free preallocated %u/%u in group %u\n",
-                               (unsigned) start, (unsigned) next - bit,
-                               (unsigned) group);
+                        (unsigned) ext4_group_first_block_no(sb, group) + bit,
+                        (unsigned) next - bit, (unsigned) group);
                free += next - bit;
 
                if (ac) {
@@ -3531,7 +3577,7 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh,
                        trace_ext4_mballoc_discard(ac);
                }
 
-               trace_ext4_mb_release_inode_pa(ac, pa, grp_blk_start + bit,
+               trace_ext4_mb_release_inode_pa(sb, ac, pa, grp_blk_start + bit,
                                               next - bit);
                mb_free_blocks(pa->pa_inode, e4b, bit, next - bit);
                bit = next + 1;
@@ -3541,8 +3587,7 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh,
                        pa, (unsigned long) pa->pa_lstart,
                        (unsigned long) pa->pa_pstart,
                        (unsigned long) pa->pa_len);
-               ext4_grp_locked_error(sb, group,
-                                       __func__, "free %u, pa_free %u",
+               ext4_grp_locked_error(sb, group, 0, 0, "free %u, pa_free %u",
                                        free, pa->pa_free);
                /*
                 * pa is already deleted so we use the value obtained
@@ -3563,7 +3608,7 @@ ext4_mb_release_group_pa(struct ext4_buddy *e4b,
        ext4_group_t group;
        ext4_grpblk_t bit;
 
-       trace_ext4_mb_release_group_pa(ac, pa);
+       trace_ext4_mb_release_group_pa(sb, ac, pa);
        BUG_ON(pa->pa_deleted == 0);
        ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit);
        BUG_ON(group != e4b->bd_group && pa->pa_len != 0);
@@ -3697,7 +3742,7 @@ out:
        ext4_unlock_group(sb, group);
        if (ac)
                kmem_cache_free(ext4_ac_cachep, ac);
-       ext4_mb_release_desc(&e4b);
+       ext4_mb_unload_buddy(&e4b);
        put_bh(bitmap_bh);
        return free;
 }
@@ -3801,7 +3846,7 @@ repeat:
                if (bitmap_bh == NULL) {
                        ext4_error(sb, "Error reading block bitmap for %u",
                                        group);
-                       ext4_mb_release_desc(&e4b);
+                       ext4_mb_unload_buddy(&e4b);
                        continue;
                }
 
@@ -3810,7 +3855,7 @@ repeat:
                ext4_mb_release_inode_pa(&e4b, bitmap_bh, pa, ac);
                ext4_unlock_group(sb, group);
 
-               ext4_mb_release_desc(&e4b);
+               ext4_mb_unload_buddy(&e4b);
                put_bh(bitmap_bh);
 
                list_del(&pa->u.pa_tmp_list);
@@ -3839,6 +3884,9 @@ static void ext4_mb_show_ac(struct ext4_allocation_context *ac)
        struct super_block *sb = ac->ac_sb;
        ext4_group_t ngroups, i;
 
+       if (EXT4_SB(sb)->s_mount_flags & EXT4_MF_FS_ABORTED)
+               return;
+
        printk(KERN_ERR "EXT4-fs: Can't allocate:"
                        " Allocation context details:\n");
        printk(KERN_ERR "EXT4-fs: status %d flags %d\n",
@@ -4074,7 +4122,7 @@ ext4_mb_discard_lg_preallocations(struct super_block *sb,
                ext4_mb_release_group_pa(&e4b, pa, ac);
                ext4_unlock_group(sb, group);
 
-               ext4_mb_release_desc(&e4b);
+               ext4_mb_unload_buddy(&e4b);
                list_del(&pa->u.pa_tmp_list);
                call_rcu(&(pa)->u.pa_rcu, ext4_mb_pa_callback);
        }
@@ -4352,6 +4400,7 @@ static noinline_for_stack int
 ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
                      struct ext4_free_data *new_entry)
 {
+       ext4_group_t group = e4b->bd_group;
        ext4_grpblk_t block;
        struct ext4_free_data *entry;
        struct ext4_group_info *db = e4b->bd_info;
@@ -4384,9 +4433,9 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
                else if (block >= (entry->start_blk + entry->count))
                        n = &(*n)->rb_right;
                else {
-                       ext4_grp_locked_error(sb, e4b->bd_group, __func__,
-                                       "Double free of blocks %d (%d %d)",
-                                       block, entry->start_blk, entry->count);
+                       ext4_grp_locked_error(sb, group, 0,
+                               ext4_group_first_block_no(sb, group) + block,
+                               "Block already on to-be-freed list");
                        return 0;
                }
        }
@@ -4444,7 +4493,6 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode,
        struct super_block *sb = inode->i_sb;
        struct ext4_allocation_context *ac = NULL;
        struct ext4_group_desc *gdp;
-       struct ext4_super_block *es;
        unsigned long freed = 0;
        unsigned int overflow;
        ext4_grpblk_t bit;
@@ -4463,7 +4511,6 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode,
        }
 
        sbi = EXT4_SB(sb);
-       es = EXT4_SB(sb)->s_es;
        if (!(flags & EXT4_FREE_BLOCKS_VALIDATED) &&
            !ext4_data_block_valid(sbi, block, count)) {
                ext4_error(sb, "Freeing blocks not in datazone - "
@@ -4484,12 +4531,12 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode,
                        if (!bh)
                                tbh = sb_find_get_block(inode->i_sb,
                                                        block + i);
-                       ext4_forget(handle, flags & EXT4_FREE_BLOCKS_METADATA, 
+                       ext4_forget(handle, flags & EXT4_FREE_BLOCKS_METADATA,
                                    inode, tbh, block + i);
                }
        }
 
-       /* 
+       /*
         * We need to make sure we don't reuse the freed block until
         * after the transaction is committed, which we can do by
         * treating the block as metadata, below.  We make an
@@ -4597,6 +4644,8 @@ do_more:
                mb_clear_bits(bitmap_bh->b_data, bit, count);
                mb_free_blocks(inode, &e4b, bit, count);
                ext4_mb_return_to_preallocation(inode, &e4b, block, count);
+               if (test_opt(sb, DISCARD))
+                       ext4_issue_discard(sb, block_group, bit, count);
        }
 
        ret = ext4_free_blks_count(sb, gdp) + count;
@@ -4610,7 +4659,7 @@ do_more:
                atomic_add(count, &sbi->s_flex_groups[flex_group].free_blocks);
        }
 
-       ext4_mb_release_desc(&e4b);
+       ext4_mb_unload_buddy(&e4b);
 
        freed += count;
 
@@ -4630,7 +4679,7 @@ do_more:
                put_bh(bitmap_bh);
                goto do_more;
        }
-       sb->s_dirt = 1;
+       ext4_mark_super_dirty(sb);
 error_return:
        if (freed)
                dquot_free_block(inode, freed);