ext4: fix lock order problem in ext4_move_extents()
[safe/jmp/linux-2.6] / fs / ext4 / mballoc.c
index 5ef6daf..bba1282 100644 (file)
@@ -910,6 +910,100 @@ out:
        return err;
 }
 
+static noinline_for_stack
+int ext4_mb_init_group(struct super_block *sb, ext4_group_t group)
+{
+
+       int ret = 0;
+       void *bitmap;
+       int blocks_per_page;
+       int block, pnum, poff;
+       int num_grp_locked = 0;
+       struct ext4_group_info *this_grp;
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       struct inode *inode = sbi->s_buddy_cache;
+       struct page *page = NULL, *bitmap_page = NULL;
+
+       mb_debug(1, "init group %u\n", group);
+       blocks_per_page = PAGE_CACHE_SIZE / sb->s_blocksize;
+       this_grp = ext4_get_group_info(sb, group);
+       /*
+        * This ensures that we don't reinit the buddy cache
+        * page which map to the group from which we are already
+        * allocating. If we are looking at the buddy cache we would
+        * have taken a reference using ext4_mb_load_buddy and that
+        * would have taken the alloc_sem lock.
+        */
+       num_grp_locked =  ext4_mb_get_buddy_cache_lock(sb, group);
+       if (!EXT4_MB_GRP_NEED_INIT(this_grp)) {
+               /*
+                * somebody initialized the group
+                * return without doing anything
+                */
+               ret = 0;
+               goto err;
+       }
+       /*
+        * the buddy cache inode stores the block bitmap
+        * and buddy information in consecutive blocks.
+        * So for each group we need two blocks.
+        */
+       block = group * 2;
+       pnum = block / blocks_per_page;
+       poff = block % blocks_per_page;
+       page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS);
+       if (page) {
+               BUG_ON(page->mapping != inode->i_mapping);
+               ret = ext4_mb_init_cache(page, NULL);
+               if (ret) {
+                       unlock_page(page);
+                       goto err;
+               }
+               unlock_page(page);
+       }
+       if (page == NULL || !PageUptodate(page)) {
+               ret = -EIO;
+               goto err;
+       }
+       mark_page_accessed(page);
+       bitmap_page = page;
+       bitmap = page_address(page) + (poff * sb->s_blocksize);
+
+       /* init buddy cache */
+       block++;
+       pnum = block / blocks_per_page;
+       poff = block % blocks_per_page;
+       page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS);
+       if (page == bitmap_page) {
+               /*
+                * If both the bitmap and buddy are in
+                * the same page we don't need to force
+                * init the buddy
+                */
+               unlock_page(page);
+       } else if (page) {
+               BUG_ON(page->mapping != inode->i_mapping);
+               ret = ext4_mb_init_cache(page, bitmap);
+               if (ret) {
+                       unlock_page(page);
+                       goto err;
+               }
+               unlock_page(page);
+       }
+       if (page == NULL || !PageUptodate(page)) {
+               ret = -EIO;
+               goto err;
+       }
+       mark_page_accessed(page);
+err:
+       ext4_mb_put_buddy_cache_lock(sb, group, num_grp_locked);
+       if (bitmap_page)
+               page_cache_release(bitmap_page);
+       if (page)
+               page_cache_release(page);
+       return ret;
+}
+
 static noinline_for_stack int
 ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group,
                                        struct ext4_buddy *e4b)
@@ -943,8 +1037,26 @@ ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group,
         * groups mapped by the page is blocked
         * till we are done with allocation
         */
+repeat_load_buddy:
        down_read(e4b->alloc_semp);
 
+       if (unlikely(EXT4_MB_GRP_NEED_INIT(grp))) {
+               /* we need to check for group need init flag
+                * with alloc_semp held so that we can be sure
+                * that new blocks didn't get added to the group
+                * when we are loading the buddy cache
+                */
+               up_read(e4b->alloc_semp);
+               /*
+                * we need full data about the group
+                * to make a good selection
+                */
+               ret = ext4_mb_init_group(sb, group);
+               if (ret)
+                       return ret;
+               goto repeat_load_buddy;
+       }
+
        /*
         * the buddy cache inode stores the block bitmap
         * and buddy information in consecutive blocks.
@@ -1839,97 +1951,6 @@ void ext4_mb_put_buddy_cache_lock(struct super_block *sb,
 
 }
 
-static noinline_for_stack
-int ext4_mb_init_group(struct super_block *sb, ext4_group_t group)
-{
-
-       int ret;
-       void *bitmap;
-       int blocks_per_page;
-       int block, pnum, poff;
-       int num_grp_locked = 0;
-       struct ext4_group_info *this_grp;
-       struct ext4_sb_info *sbi = EXT4_SB(sb);
-       struct inode *inode = sbi->s_buddy_cache;
-       struct page *page = NULL, *bitmap_page = NULL;
-
-       mb_debug(1, "init group %u\n", group);
-       blocks_per_page = PAGE_CACHE_SIZE / sb->s_blocksize;
-       this_grp = ext4_get_group_info(sb, group);
-       /*
-        * This ensures we don't add group
-        * to this buddy cache via resize
-        */
-       num_grp_locked =  ext4_mb_get_buddy_cache_lock(sb, group);
-       if (!EXT4_MB_GRP_NEED_INIT(this_grp)) {
-               /*
-                * somebody initialized the group
-                * return without doing anything
-                */
-               ret = 0;
-               goto err;
-       }
-       /*
-        * the buddy cache inode stores the block bitmap
-        * and buddy information in consecutive blocks.
-        * So for each group we need two blocks.
-        */
-       block = group * 2;
-       pnum = block / blocks_per_page;
-       poff = block % blocks_per_page;
-       page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS);
-       if (page) {
-               BUG_ON(page->mapping != inode->i_mapping);
-               ret = ext4_mb_init_cache(page, NULL);
-               if (ret) {
-                       unlock_page(page);
-                       goto err;
-               }
-               unlock_page(page);
-       }
-       if (page == NULL || !PageUptodate(page)) {
-               ret = -EIO;
-               goto err;
-       }
-       mark_page_accessed(page);
-       bitmap_page = page;
-       bitmap = page_address(page) + (poff * sb->s_blocksize);
-
-       /* init buddy cache */
-       block++;
-       pnum = block / blocks_per_page;
-       poff = block % blocks_per_page;
-       page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS);
-       if (page == bitmap_page) {
-               /*
-                * If both the bitmap and buddy are in
-                * the same page we don't need to force
-                * init the buddy
-                */
-               unlock_page(page);
-       } else if (page) {
-               BUG_ON(page->mapping != inode->i_mapping);
-               ret = ext4_mb_init_cache(page, bitmap);
-               if (ret) {
-                       unlock_page(page);
-                       goto err;
-               }
-               unlock_page(page);
-       }
-       if (page == NULL || !PageUptodate(page)) {
-               ret = -EIO;
-               goto err;
-       }
-       mark_page_accessed(page);
-err:
-       ext4_mb_put_buddy_cache_lock(sb, group, num_grp_locked);
-       if (bitmap_page)
-               page_cache_release(bitmap_page);
-       if (page)
-               page_cache_release(page);
-       return ret;
-}
-
 static noinline_for_stack int
 ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
 {
@@ -1944,6 +1965,10 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
        sb = ac->ac_sb;
        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))
+               ngroups = sbi->s_blockfile_groups;
+
        BUG_ON(ac->ac_status == AC_STATUS_FOUND);
 
        /* first, try the goal */
@@ -2012,27 +2037,6 @@ repeat:
                        if (grp->bb_free == 0)
                                continue;
 
-                       /*
-                        * if the group is already init we check whether it is
-                        * a good group and if not we don't load the buddy
-                        */
-                       if (EXT4_MB_GRP_NEED_INIT(grp)) {
-                               /*
-                                * we need full data about the group
-                                * to make a good selection
-                                */
-                               err = ext4_mb_init_group(sb, group);
-                               if (err)
-                                       goto out;
-                       }
-
-                       /*
-                        * If the particular group doesn't satisfy our
-                        * criteria we continue with the next group
-                        */
-                       if (!ext4_mb_good_group(ac, group, cr))
-                               continue;
-
                        err = ext4_mb_load_buddy(sb, group, &e4b);
                        if (err)
                                goto out;
@@ -2092,207 +2096,6 @@ out:
        return err;
 }
 
-#ifdef EXT4_MB_HISTORY
-struct ext4_mb_proc_session {
-       struct ext4_mb_history *history;
-       struct super_block *sb;
-       int start;
-       int max;
-};
-
-static void *ext4_mb_history_skip_empty(struct ext4_mb_proc_session *s,
-                                       struct ext4_mb_history *hs,
-                                       int first)
-{
-       if (hs == s->history + s->max)
-               hs = s->history;
-       if (!first && hs == s->history + s->start)
-               return NULL;
-       while (hs->orig.fe_len == 0) {
-               hs++;
-               if (hs == s->history + s->max)
-                       hs = s->history;
-               if (hs == s->history + s->start)
-                       return NULL;
-       }
-       return hs;
-}
-
-static void *ext4_mb_seq_history_start(struct seq_file *seq, loff_t *pos)
-{
-       struct ext4_mb_proc_session *s = seq->private;
-       struct ext4_mb_history *hs;
-       int l = *pos;
-
-       if (l == 0)
-               return SEQ_START_TOKEN;
-       hs = ext4_mb_history_skip_empty(s, s->history + s->start, 1);
-       if (!hs)
-               return NULL;
-       while (--l && (hs = ext4_mb_history_skip_empty(s, ++hs, 0)) != NULL);
-       return hs;
-}
-
-static void *ext4_mb_seq_history_next(struct seq_file *seq, void *v,
-                                     loff_t *pos)
-{
-       struct ext4_mb_proc_session *s = seq->private;
-       struct ext4_mb_history *hs = v;
-
-       ++*pos;
-       if (v == SEQ_START_TOKEN)
-               return ext4_mb_history_skip_empty(s, s->history + s->start, 1);
-       else
-               return ext4_mb_history_skip_empty(s, ++hs, 0);
-}
-
-static int ext4_mb_seq_history_show(struct seq_file *seq, void *v)
-{
-       char buf[25], buf2[25], buf3[25], *fmt;
-       struct ext4_mb_history *hs = v;
-
-       if (v == SEQ_START_TOKEN) {
-               seq_printf(seq, "%-5s %-8s %-23s %-23s %-23s %-5s "
-                               "%-5s %-2s %-6s %-5s %-5s %-6s\n",
-                         "pid", "inode", "original", "goal", "result", "found",
-                          "grps", "cr", "flags", "merge", "tail", "broken");
-               return 0;
-       }
-
-       if (hs->op == EXT4_MB_HISTORY_ALLOC) {
-               fmt = "%-5u %-8u %-23s %-23s %-23s %-5u %-5u %-2u "
-                       "0x%04x %-5s %-5u %-6u\n";
-               sprintf(buf2, "%u/%d/%u@%u", hs->result.fe_group,
-                       hs->result.fe_start, hs->result.fe_len,
-                       hs->result.fe_logical);
-               sprintf(buf, "%u/%d/%u@%u", hs->orig.fe_group,
-                       hs->orig.fe_start, hs->orig.fe_len,
-                       hs->orig.fe_logical);
-               sprintf(buf3, "%u/%d/%u@%u", hs->goal.fe_group,
-                       hs->goal.fe_start, hs->goal.fe_len,
-                       hs->goal.fe_logical);
-               seq_printf(seq, fmt, hs->pid, hs->ino, buf, buf3, buf2,
-                               hs->found, hs->groups, hs->cr, hs->flags,
-                               hs->merged ? "M" : "", hs->tail,
-                               hs->buddy ? 1 << hs->buddy : 0);
-       } else if (hs->op == EXT4_MB_HISTORY_PREALLOC) {
-               fmt = "%-5u %-8u %-23s %-23s %-23s\n";
-               sprintf(buf2, "%u/%d/%u@%u", hs->result.fe_group,
-                       hs->result.fe_start, hs->result.fe_len,
-                       hs->result.fe_logical);
-               sprintf(buf, "%u/%d/%u@%u", hs->orig.fe_group,
-                       hs->orig.fe_start, hs->orig.fe_len,
-                       hs->orig.fe_logical);
-               seq_printf(seq, fmt, hs->pid, hs->ino, buf, "", buf2);
-       } else if (hs->op == EXT4_MB_HISTORY_DISCARD) {
-               sprintf(buf2, "%u/%d/%u", hs->result.fe_group,
-                       hs->result.fe_start, hs->result.fe_len);
-               seq_printf(seq, "%-5u %-8u %-23s discard\n",
-                               hs->pid, hs->ino, buf2);
-       } else if (hs->op == EXT4_MB_HISTORY_FREE) {
-               sprintf(buf2, "%u/%d/%u", hs->result.fe_group,
-                       hs->result.fe_start, hs->result.fe_len);
-               seq_printf(seq, "%-5u %-8u %-23s free\n",
-                               hs->pid, hs->ino, buf2);
-       }
-       return 0;
-}
-
-static void ext4_mb_seq_history_stop(struct seq_file *seq, void *v)
-{
-}
-
-static const struct seq_operations ext4_mb_seq_history_ops = {
-       .start  = ext4_mb_seq_history_start,
-       .next   = ext4_mb_seq_history_next,
-       .stop   = ext4_mb_seq_history_stop,
-       .show   = ext4_mb_seq_history_show,
-};
-
-static int ext4_mb_seq_history_open(struct inode *inode, struct file *file)
-{
-       struct super_block *sb = PDE(inode)->data;
-       struct ext4_sb_info *sbi = EXT4_SB(sb);
-       struct ext4_mb_proc_session *s;
-       int rc;
-       int size;
-
-       if (unlikely(sbi->s_mb_history == NULL))
-               return -ENOMEM;
-       s = kmalloc(sizeof(*s), GFP_KERNEL);
-       if (s == NULL)
-               return -ENOMEM;
-       s->sb = sb;
-       size = sizeof(struct ext4_mb_history) * sbi->s_mb_history_max;
-       s->history = kmalloc(size, GFP_KERNEL);
-       if (s->history == NULL) {
-               kfree(s);
-               return -ENOMEM;
-       }
-
-       spin_lock(&sbi->s_mb_history_lock);
-       memcpy(s->history, sbi->s_mb_history, size);
-       s->max = sbi->s_mb_history_max;
-       s->start = sbi->s_mb_history_cur % s->max;
-       spin_unlock(&sbi->s_mb_history_lock);
-
-       rc = seq_open(file, &ext4_mb_seq_history_ops);
-       if (rc == 0) {
-               struct seq_file *m = (struct seq_file *)file->private_data;
-               m->private = s;
-       } else {
-               kfree(s->history);
-               kfree(s);
-       }
-       return rc;
-
-}
-
-static int ext4_mb_seq_history_release(struct inode *inode, struct file *file)
-{
-       struct seq_file *seq = (struct seq_file *)file->private_data;
-       struct ext4_mb_proc_session *s = seq->private;
-       kfree(s->history);
-       kfree(s);
-       return seq_release(inode, file);
-}
-
-static ssize_t ext4_mb_seq_history_write(struct file *file,
-                               const char __user *buffer,
-                               size_t count, loff_t *ppos)
-{
-       struct seq_file *seq = (struct seq_file *)file->private_data;
-       struct ext4_mb_proc_session *s = seq->private;
-       struct super_block *sb = s->sb;
-       char str[32];
-       int value;
-
-       if (count >= sizeof(str)) {
-               printk(KERN_ERR "EXT4-fs: %s string too long, max %u bytes\n",
-                               "mb_history", (int)sizeof(str));
-               return -EOVERFLOW;
-       }
-
-       if (copy_from_user(str, buffer, count))
-               return -EFAULT;
-
-       value = simple_strtol(str, NULL, 0);
-       if (value < 0)
-               return -ERANGE;
-       EXT4_SB(sb)->s_mb_history_filter = value;
-
-       return count;
-}
-
-static const struct file_operations ext4_mb_seq_history_fops = {
-       .owner          = THIS_MODULE,
-       .open           = ext4_mb_seq_history_open,
-       .read           = seq_read,
-       .write          = ext4_mb_seq_history_write,
-       .llseek         = seq_lseek,
-       .release        = ext4_mb_seq_history_release,
-};
-
 static void *ext4_mb_seq_groups_start(struct seq_file *seq, loff_t *pos)
 {
        struct super_block *sb = seq->private;
@@ -2392,82 +2195,6 @@ static const struct file_operations ext4_mb_seq_groups_fops = {
        .release        = seq_release,
 };
 
-static void ext4_mb_history_release(struct super_block *sb)
-{
-       struct ext4_sb_info *sbi = EXT4_SB(sb);
-
-       if (sbi->s_proc != NULL) {
-               remove_proc_entry("mb_groups", sbi->s_proc);
-               if (sbi->s_mb_history_max)
-                       remove_proc_entry("mb_history", sbi->s_proc);
-       }
-       kfree(sbi->s_mb_history);
-}
-
-static void ext4_mb_history_init(struct super_block *sb)
-{
-       struct ext4_sb_info *sbi = EXT4_SB(sb);
-       int i;
-
-       if (sbi->s_proc != NULL) {
-               if (sbi->s_mb_history_max)
-                       proc_create_data("mb_history", S_IRUGO, sbi->s_proc,
-                                        &ext4_mb_seq_history_fops, sb);
-               proc_create_data("mb_groups", S_IRUGO, sbi->s_proc,
-                                &ext4_mb_seq_groups_fops, sb);
-       }
-
-       sbi->s_mb_history_cur = 0;
-       spin_lock_init(&sbi->s_mb_history_lock);
-       i = sbi->s_mb_history_max * sizeof(struct ext4_mb_history);
-       sbi->s_mb_history = i ? kzalloc(i, GFP_KERNEL) : NULL;
-       /* if we can't allocate history, then we simple won't use it */
-}
-
-static noinline_for_stack void
-ext4_mb_store_history(struct ext4_allocation_context *ac)
-{
-       struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
-       struct ext4_mb_history h;
-
-       if (sbi->s_mb_history == NULL)
-               return;
-
-       if (!(ac->ac_op & sbi->s_mb_history_filter))
-               return;
-
-       h.op = ac->ac_op;
-       h.pid = current->pid;
-       h.ino = ac->ac_inode ? ac->ac_inode->i_ino : 0;
-       h.orig = ac->ac_o_ex;
-       h.result = ac->ac_b_ex;
-       h.flags = ac->ac_flags;
-       h.found = ac->ac_found;
-       h.groups = ac->ac_groups_scanned;
-       h.cr = ac->ac_criteria;
-       h.tail = ac->ac_tail;
-       h.buddy = ac->ac_buddy;
-       h.merged = 0;
-       if (ac->ac_op == EXT4_MB_HISTORY_ALLOC) {
-               if (ac->ac_g_ex.fe_start == ac->ac_b_ex.fe_start &&
-                               ac->ac_g_ex.fe_group == ac->ac_b_ex.fe_group)
-                       h.merged = 1;
-               h.goal = ac->ac_g_ex;
-               h.result = ac->ac_f_ex;
-       }
-
-       spin_lock(&sbi->s_mb_history_lock);
-       memcpy(sbi->s_mb_history + sbi->s_mb_history_cur, &h, sizeof(h));
-       if (++sbi->s_mb_history_cur >= sbi->s_mb_history_max)
-               sbi->s_mb_history_cur = 0;
-       spin_unlock(&sbi->s_mb_history_lock);
-}
-
-#else
-#define ext4_mb_history_release(sb)
-#define ext4_mb_history_init(sb)
-#endif
-
 
 /* Create and initialize ext4_group_info data for the given group. */
 int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group,
@@ -2686,7 +2413,6 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
        sbi->s_mb_stats = MB_DEFAULT_STATS;
        sbi->s_mb_stream_request = MB_DEFAULT_STREAM_THRESHOLD;
        sbi->s_mb_order2_reqs = MB_DEFAULT_ORDER2_REQS;
-       sbi->s_mb_history_filter = EXT4_MB_HISTORY_DEFAULT;
        sbi->s_mb_group_prealloc = MB_DEFAULT_GROUP_PREALLOC;
 
        sbi->s_locality_groups = alloc_percpu(struct ext4_locality_group);
@@ -2704,12 +2430,12 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
                spin_lock_init(&lg->lg_prealloc_lock);
        }
 
-       ext4_mb_history_init(sb);
+       if (sbi->s_proc)
+               proc_create_data("mb_groups", S_IRUGO, sbi->s_proc,
+                                &ext4_mb_seq_groups_fops, sb);
 
        if (sbi->s_journal)
                sbi->s_journal->j_commit_callback = release_blocks_on_commit;
-
-       printk(KERN_INFO "EXT4-fs: mballoc enabled\n");
        return 0;
 }
 
@@ -2786,7 +2512,8 @@ int ext4_mb_release(struct super_block *sb)
        }
 
        free_percpu(sbi->s_locality_groups);
-       ext4_mb_history_release(sb);
+       if (sbi->s_proc)
+               remove_proc_entry("mb_groups", sbi->s_proc);
 
        return 0;
 }
@@ -3272,7 +2999,10 @@ static void ext4_mb_collect_stats(struct ext4_allocation_context *ac)
                        atomic_inc(&sbi->s_bal_breaks);
        }
 
-       ext4_mb_store_history(ac);
+       if (ac->ac_op == EXT4_MB_HISTORY_ALLOC)
+               trace_ext4_mballoc_alloc(ac);
+       else
+               trace_ext4_mballoc_prealloc(ac);
 }
 
 /*
@@ -3382,6 +3112,11 @@ ext4_mb_use_preallocated(struct ext4_allocation_context *ac)
                        ac->ac_o_ex.fe_logical >= pa->pa_lstart + pa->pa_len)
                        continue;
 
+               /* non-extent files can't have physical blocks past 2^32 */
+               if (!(EXT4_I(ac->ac_inode)->i_flags & EXT4_EXTENTS_FL) &&
+                       pa->pa_pstart + pa->pa_len > EXT4_MAX_BLOCK_FILE_PHYS)
+                       continue;
+
                /* found preallocated blocks, use them */
                spin_lock(&pa->pa_lock);
                if (pa->pa_deleted == 0 && pa->pa_free) {
@@ -3767,7 +3502,6 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh,
        if (ac) {
                ac->ac_sb = sb;
                ac->ac_inode = pa->pa_inode;
-               ac->ac_op = EXT4_MB_HISTORY_DISCARD;
        }
 
        while (bit < end) {
@@ -3787,7 +3521,7 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh,
                        ac->ac_b_ex.fe_start = bit;
                        ac->ac_b_ex.fe_len = next - bit;
                        ac->ac_b_ex.fe_logical = 0;
-                       ext4_mb_store_history(ac);
+                       trace_ext4_mballoc_discard(ac);
                }
 
                trace_ext4_mb_release_inode_pa(ac, pa, grp_blk_start + bit,
@@ -3822,9 +3556,6 @@ ext4_mb_release_group_pa(struct ext4_buddy *e4b,
        ext4_group_t group;
        ext4_grpblk_t bit;
 
-       if (ac)
-               ac->ac_op = EXT4_MB_HISTORY_DISCARD;
-
        trace_ext4_mb_release_group_pa(ac, pa);
        BUG_ON(pa->pa_deleted == 0);
        ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit);
@@ -3839,7 +3570,7 @@ ext4_mb_release_group_pa(struct ext4_buddy *e4b,
                ac->ac_b_ex.fe_start = bit;
                ac->ac_b_ex.fe_len = pa->pa_len;
                ac->ac_b_ex.fe_logical = 0;
-               ext4_mb_store_history(ac);
+               trace_ext4_mballoc_discard(ac);
        }
 
        return 0;
@@ -4180,7 +3911,6 @@ static void ext4_mb_group_or_file(struct ext4_allocation_context *ac)
        size = ac->ac_o_ex.fe_logical + ac->ac_o_ex.fe_len;
        isize = (i_size_read(ac->ac_inode) + ac->ac_sb->s_blocksize - 1)
                >> bsbits;
-       size = max(size, isize);
 
        if ((size == isize) &&
            !ext4_fs_is_busy(sbi) &&
@@ -4190,6 +3920,7 @@ static void ext4_mb_group_or_file(struct ext4_allocation_context *ac)
        }
 
        /* don't use group allocation for large files */
+       size = max(size, isize);
        if (size >= sbi->s_mb_stream_request) {
                ac->ac_flags |= EXT4_MB_STREAM_ALLOC;
                return;
@@ -4730,7 +4461,6 @@ void ext4_mb_free_blocks(handle_t *handle, struct inode *inode,
 
        ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS);
        if (ac) {
-               ac->ac_op = EXT4_MB_HISTORY_FREE;
                ac->ac_inode = inode;
                ac->ac_sb = sb;
        }
@@ -4797,7 +4527,7 @@ do_more:
                ac->ac_b_ex.fe_group = block_group;
                ac->ac_b_ex.fe_start = bit;
                ac->ac_b_ex.fe_len = count;
-               ext4_mb_store_history(ac);
+               trace_ext4_mballoc_free(ac);
        }
 
        err = ext4_mb_load_buddy(sb, block_group, &e4b);