diff options
Diffstat (limited to 'fs/ext4/mballoc.c')
| -rw-r--r-- | fs/ext4/mballoc.c | 305 |
1 files changed, 13 insertions, 292 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index e9c61896d605..bba12824defa 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
| @@ -2096,207 +2096,6 @@ out: | |||
| 2096 | return err; | 2096 | return err; |
| 2097 | } | 2097 | } |
| 2098 | 2098 | ||
| 2099 | #ifdef EXT4_MB_HISTORY | ||
| 2100 | struct ext4_mb_proc_session { | ||
| 2101 | struct ext4_mb_history *history; | ||
| 2102 | struct super_block *sb; | ||
| 2103 | int start; | ||
| 2104 | int max; | ||
| 2105 | }; | ||
| 2106 | |||
| 2107 | static void *ext4_mb_history_skip_empty(struct ext4_mb_proc_session *s, | ||
| 2108 | struct ext4_mb_history *hs, | ||
| 2109 | int first) | ||
| 2110 | { | ||
| 2111 | if (hs == s->history + s->max) | ||
| 2112 | hs = s->history; | ||
| 2113 | if (!first && hs == s->history + s->start) | ||
| 2114 | return NULL; | ||
| 2115 | while (hs->orig.fe_len == 0) { | ||
| 2116 | hs++; | ||
| 2117 | if (hs == s->history + s->max) | ||
| 2118 | hs = s->history; | ||
| 2119 | if (hs == s->history + s->start) | ||
| 2120 | return NULL; | ||
| 2121 | } | ||
| 2122 | return hs; | ||
| 2123 | } | ||
| 2124 | |||
| 2125 | static void *ext4_mb_seq_history_start(struct seq_file *seq, loff_t *pos) | ||
| 2126 | { | ||
| 2127 | struct ext4_mb_proc_session *s = seq->private; | ||
| 2128 | struct ext4_mb_history *hs; | ||
| 2129 | int l = *pos; | ||
| 2130 | |||
| 2131 | if (l == 0) | ||
| 2132 | return SEQ_START_TOKEN; | ||
| 2133 | hs = ext4_mb_history_skip_empty(s, s->history + s->start, 1); | ||
| 2134 | if (!hs) | ||
| 2135 | return NULL; | ||
| 2136 | while (--l && (hs = ext4_mb_history_skip_empty(s, ++hs, 0)) != NULL); | ||
| 2137 | return hs; | ||
| 2138 | } | ||
| 2139 | |||
| 2140 | static void *ext4_mb_seq_history_next(struct seq_file *seq, void *v, | ||
| 2141 | loff_t *pos) | ||
| 2142 | { | ||
| 2143 | struct ext4_mb_proc_session *s = seq->private; | ||
| 2144 | struct ext4_mb_history *hs = v; | ||
| 2145 | |||
| 2146 | ++*pos; | ||
| 2147 | if (v == SEQ_START_TOKEN) | ||
| 2148 | return ext4_mb_history_skip_empty(s, s->history + s->start, 1); | ||
| 2149 | else | ||
| 2150 | return ext4_mb_history_skip_empty(s, ++hs, 0); | ||
| 2151 | } | ||
| 2152 | |||
| 2153 | static int ext4_mb_seq_history_show(struct seq_file *seq, void *v) | ||
| 2154 | { | ||
| 2155 | char buf[25], buf2[25], buf3[25], *fmt; | ||
| 2156 | struct ext4_mb_history *hs = v; | ||
| 2157 | |||
| 2158 | if (v == SEQ_START_TOKEN) { | ||
| 2159 | seq_printf(seq, "%-5s %-8s %-23s %-23s %-23s %-5s " | ||
| 2160 | "%-5s %-2s %-6s %-5s %-5s %-6s\n", | ||
| 2161 | "pid", "inode", "original", "goal", "result", "found", | ||
| 2162 | "grps", "cr", "flags", "merge", "tail", "broken"); | ||
| 2163 | return 0; | ||
| 2164 | } | ||
| 2165 | |||
| 2166 | if (hs->op == EXT4_MB_HISTORY_ALLOC) { | ||
| 2167 | fmt = "%-5u %-8u %-23s %-23s %-23s %-5u %-5u %-2u " | ||
| 2168 | "0x%04x %-5s %-5u %-6u\n"; | ||
| 2169 | sprintf(buf2, "%u/%d/%u@%u", hs->result.fe_group, | ||
| 2170 | hs->result.fe_start, hs->result.fe_len, | ||
| 2171 | hs->result.fe_logical); | ||
| 2172 | sprintf(buf, "%u/%d/%u@%u", hs->orig.fe_group, | ||
| 2173 | hs->orig.fe_start, hs->orig.fe_len, | ||
| 2174 | hs->orig.fe_logical); | ||
| 2175 | sprintf(buf3, "%u/%d/%u@%u", hs->goal.fe_group, | ||
| 2176 | hs->goal.fe_start, hs->goal.fe_len, | ||
| 2177 | hs->goal.fe_logical); | ||
| 2178 | seq_printf(seq, fmt, hs->pid, hs->ino, buf, buf3, buf2, | ||
| 2179 | hs->found, hs->groups, hs->cr, hs->flags, | ||
| 2180 | hs->merged ? "M" : "", hs->tail, | ||
| 2181 | hs->buddy ? 1 << hs->buddy : 0); | ||
| 2182 | } else if (hs->op == EXT4_MB_HISTORY_PREALLOC) { | ||
| 2183 | fmt = "%-5u %-8u %-23s %-23s %-23s\n"; | ||
| 2184 | sprintf(buf2, "%u/%d/%u@%u", hs->result.fe_group, | ||
| 2185 | hs->result.fe_start, hs->result.fe_len, | ||
| 2186 | hs->result.fe_logical); | ||
| 2187 | sprintf(buf, "%u/%d/%u@%u", hs->orig.fe_group, | ||
| 2188 | hs->orig.fe_start, hs->orig.fe_len, | ||
| 2189 | hs->orig.fe_logical); | ||
| 2190 | seq_printf(seq, fmt, hs->pid, hs->ino, buf, "", buf2); | ||
| 2191 | } else if (hs->op == EXT4_MB_HISTORY_DISCARD) { | ||
| 2192 | sprintf(buf2, "%u/%d/%u", hs->result.fe_group, | ||
| 2193 | hs->result.fe_start, hs->result.fe_len); | ||
| 2194 | seq_printf(seq, "%-5u %-8u %-23s discard\n", | ||
| 2195 | hs->pid, hs->ino, buf2); | ||
| 2196 | } else if (hs->op == EXT4_MB_HISTORY_FREE) { | ||
| 2197 | sprintf(buf2, "%u/%d/%u", hs->result.fe_group, | ||
| 2198 | hs->result.fe_start, hs->result.fe_len); | ||
| 2199 | seq_printf(seq, "%-5u %-8u %-23s free\n", | ||
| 2200 | hs->pid, hs->ino, buf2); | ||
| 2201 | } | ||
| 2202 | return 0; | ||
| 2203 | } | ||
| 2204 | |||
| 2205 | static void ext4_mb_seq_history_stop(struct seq_file *seq, void *v) | ||
| 2206 | { | ||
| 2207 | } | ||
| 2208 | |||
| 2209 | static const struct seq_operations ext4_mb_seq_history_ops = { | ||
| 2210 | .start = ext4_mb_seq_history_start, | ||
| 2211 | .next = ext4_mb_seq_history_next, | ||
| 2212 | .stop = ext4_mb_seq_history_stop, | ||
| 2213 | .show = ext4_mb_seq_history_show, | ||
| 2214 | }; | ||
| 2215 | |||
| 2216 | static int ext4_mb_seq_history_open(struct inode *inode, struct file *file) | ||
| 2217 | { | ||
| 2218 | struct super_block *sb = PDE(inode)->data; | ||
| 2219 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
| 2220 | struct ext4_mb_proc_session *s; | ||
| 2221 | int rc; | ||
| 2222 | int size; | ||
| 2223 | |||
| 2224 | if (unlikely(sbi->s_mb_history == NULL)) | ||
| 2225 | return -ENOMEM; | ||
| 2226 | s = kmalloc(sizeof(*s), GFP_KERNEL); | ||
| 2227 | if (s == NULL) | ||
| 2228 | return -ENOMEM; | ||
| 2229 | s->sb = sb; | ||
| 2230 | size = sizeof(struct ext4_mb_history) * sbi->s_mb_history_max; | ||
| 2231 | s->history = kmalloc(size, GFP_KERNEL); | ||
| 2232 | if (s->history == NULL) { | ||
| 2233 | kfree(s); | ||
| 2234 | return -ENOMEM; | ||
| 2235 | } | ||
| 2236 | |||
| 2237 | spin_lock(&sbi->s_mb_history_lock); | ||
| 2238 | memcpy(s->history, sbi->s_mb_history, size); | ||
| 2239 | s->max = sbi->s_mb_history_max; | ||
| 2240 | s->start = sbi->s_mb_history_cur % s->max; | ||
| 2241 | spin_unlock(&sbi->s_mb_history_lock); | ||
| 2242 | |||
| 2243 | rc = seq_open(file, &ext4_mb_seq_history_ops); | ||
| 2244 | if (rc == 0) { | ||
| 2245 | struct seq_file *m = (struct seq_file *)file->private_data; | ||
| 2246 | m->private = s; | ||
| 2247 | } else { | ||
| 2248 | kfree(s->history); | ||
| 2249 | kfree(s); | ||
| 2250 | } | ||
| 2251 | return rc; | ||
| 2252 | |||
| 2253 | } | ||
| 2254 | |||
| 2255 | static int ext4_mb_seq_history_release(struct inode *inode, struct file *file) | ||
| 2256 | { | ||
| 2257 | struct seq_file *seq = (struct seq_file *)file->private_data; | ||
| 2258 | struct ext4_mb_proc_session *s = seq->private; | ||
| 2259 | kfree(s->history); | ||
| 2260 | kfree(s); | ||
| 2261 | return seq_release(inode, file); | ||
| 2262 | } | ||
| 2263 | |||
| 2264 | static ssize_t ext4_mb_seq_history_write(struct file *file, | ||
| 2265 | const char __user *buffer, | ||
| 2266 | size_t count, loff_t *ppos) | ||
| 2267 | { | ||
| 2268 | struct seq_file *seq = (struct seq_file *)file->private_data; | ||
| 2269 | struct ext4_mb_proc_session *s = seq->private; | ||
| 2270 | struct super_block *sb = s->sb; | ||
| 2271 | char str[32]; | ||
| 2272 | int value; | ||
| 2273 | |||
| 2274 | if (count >= sizeof(str)) { | ||
| 2275 | printk(KERN_ERR "EXT4-fs: %s string too long, max %u bytes\n", | ||
| 2276 | "mb_history", (int)sizeof(str)); | ||
| 2277 | return -EOVERFLOW; | ||
| 2278 | } | ||
| 2279 | |||
| 2280 | if (copy_from_user(str, buffer, count)) | ||
| 2281 | return -EFAULT; | ||
| 2282 | |||
| 2283 | value = simple_strtol(str, NULL, 0); | ||
| 2284 | if (value < 0) | ||
| 2285 | return -ERANGE; | ||
| 2286 | EXT4_SB(sb)->s_mb_history_filter = value; | ||
| 2287 | |||
| 2288 | return count; | ||
| 2289 | } | ||
| 2290 | |||
| 2291 | static const struct file_operations ext4_mb_seq_history_fops = { | ||
| 2292 | .owner = THIS_MODULE, | ||
| 2293 | .open = ext4_mb_seq_history_open, | ||
| 2294 | .read = seq_read, | ||
| 2295 | .write = ext4_mb_seq_history_write, | ||
| 2296 | .llseek = seq_lseek, | ||
| 2297 | .release = ext4_mb_seq_history_release, | ||
| 2298 | }; | ||
| 2299 | |||
| 2300 | static void *ext4_mb_seq_groups_start(struct seq_file *seq, loff_t *pos) | 2099 | static void *ext4_mb_seq_groups_start(struct seq_file *seq, loff_t *pos) |
| 2301 | { | 2100 | { |
| 2302 | struct super_block *sb = seq->private; | 2101 | struct super_block *sb = seq->private; |
| @@ -2396,82 +2195,6 @@ static const struct file_operations ext4_mb_seq_groups_fops = { | |||
| 2396 | .release = seq_release, | 2195 | .release = seq_release, |
| 2397 | }; | 2196 | }; |
| 2398 | 2197 | ||
| 2399 | static void ext4_mb_history_release(struct super_block *sb) | ||
| 2400 | { | ||
| 2401 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
| 2402 | |||
| 2403 | if (sbi->s_proc != NULL) { | ||
| 2404 | remove_proc_entry("mb_groups", sbi->s_proc); | ||
| 2405 | if (sbi->s_mb_history_max) | ||
| 2406 | remove_proc_entry("mb_history", sbi->s_proc); | ||
| 2407 | } | ||
| 2408 | kfree(sbi->s_mb_history); | ||
| 2409 | } | ||
| 2410 | |||
| 2411 | static void ext4_mb_history_init(struct super_block *sb) | ||
| 2412 | { | ||
| 2413 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
| 2414 | int i; | ||
| 2415 | |||
| 2416 | if (sbi->s_proc != NULL) { | ||
| 2417 | if (sbi->s_mb_history_max) | ||
| 2418 | proc_create_data("mb_history", S_IRUGO, sbi->s_proc, | ||
| 2419 | &ext4_mb_seq_history_fops, sb); | ||
| 2420 | proc_create_data("mb_groups", S_IRUGO, sbi->s_proc, | ||
| 2421 | &ext4_mb_seq_groups_fops, sb); | ||
| 2422 | } | ||
| 2423 | |||
| 2424 | sbi->s_mb_history_cur = 0; | ||
| 2425 | spin_lock_init(&sbi->s_mb_history_lock); | ||
| 2426 | i = sbi->s_mb_history_max * sizeof(struct ext4_mb_history); | ||
| 2427 | sbi->s_mb_history = i ? kzalloc(i, GFP_KERNEL) : NULL; | ||
| 2428 | /* if we can't allocate history, then we simple won't use it */ | ||
| 2429 | } | ||
| 2430 | |||
| 2431 | static noinline_for_stack void | ||
| 2432 | ext4_mb_store_history(struct ext4_allocation_context *ac) | ||
| 2433 | { | ||
| 2434 | struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb); | ||
| 2435 | struct ext4_mb_history h; | ||
| 2436 | |||
| 2437 | if (sbi->s_mb_history == NULL) | ||
| 2438 | return; | ||
| 2439 | |||
| 2440 | if (!(ac->ac_op & sbi->s_mb_history_filter)) | ||
| 2441 | return; | ||
| 2442 | |||
| 2443 | h.op = ac->ac_op; | ||
| 2444 | h.pid = current->pid; | ||
| 2445 | h.ino = ac->ac_inode ? ac->ac_inode->i_ino : 0; | ||
| 2446 | h.orig = ac->ac_o_ex; | ||
| 2447 | h.result = ac->ac_b_ex; | ||
| 2448 | h.flags = ac->ac_flags; | ||
| 2449 | h.found = ac->ac_found; | ||
| 2450 | h.groups = ac->ac_groups_scanned; | ||
| 2451 | h.cr = ac->ac_criteria; | ||
| 2452 | h.tail = ac->ac_tail; | ||
| 2453 | h.buddy = ac->ac_buddy; | ||
| 2454 | h.merged = 0; | ||
| 2455 | if (ac->ac_op == EXT4_MB_HISTORY_ALLOC) { | ||
| 2456 | if (ac->ac_g_ex.fe_start == ac->ac_b_ex.fe_start && | ||
| 2457 | ac->ac_g_ex.fe_group == ac->ac_b_ex.fe_group) | ||
| 2458 | h.merged = 1; | ||
| 2459 | h.goal = ac->ac_g_ex; | ||
| 2460 | h.result = ac->ac_f_ex; | ||
| 2461 | } | ||
| 2462 | |||
| 2463 | spin_lock(&sbi->s_mb_history_lock); | ||
| 2464 | memcpy(sbi->s_mb_history + sbi->s_mb_history_cur, &h, sizeof(h)); | ||
| 2465 | if (++sbi->s_mb_history_cur >= sbi->s_mb_history_max) | ||
| 2466 | sbi->s_mb_history_cur = 0; | ||
| 2467 | spin_unlock(&sbi->s_mb_history_lock); | ||
| 2468 | } | ||
| 2469 | |||
| 2470 | #else | ||
| 2471 | #define ext4_mb_history_release(sb) | ||
| 2472 | #define ext4_mb_history_init(sb) | ||
| 2473 | #endif | ||
| 2474 | |||
| 2475 | 2198 | ||
| 2476 | /* Create and initialize ext4_group_info data for the given group. */ | 2199 | /* Create and initialize ext4_group_info data for the given group. */ |
| 2477 | int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group, | 2200 | int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group, |
| @@ -2690,7 +2413,6 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery) | |||
| 2690 | sbi->s_mb_stats = MB_DEFAULT_STATS; | 2413 | sbi->s_mb_stats = MB_DEFAULT_STATS; |
| 2691 | sbi->s_mb_stream_request = MB_DEFAULT_STREAM_THRESHOLD; | 2414 | sbi->s_mb_stream_request = MB_DEFAULT_STREAM_THRESHOLD; |
| 2692 | sbi->s_mb_order2_reqs = MB_DEFAULT_ORDER2_REQS; | 2415 | sbi->s_mb_order2_reqs = MB_DEFAULT_ORDER2_REQS; |
| 2693 | sbi->s_mb_history_filter = EXT4_MB_HISTORY_DEFAULT; | ||
| 2694 | sbi->s_mb_group_prealloc = MB_DEFAULT_GROUP_PREALLOC; | 2416 | sbi->s_mb_group_prealloc = MB_DEFAULT_GROUP_PREALLOC; |
| 2695 | 2417 | ||
| 2696 | sbi->s_locality_groups = alloc_percpu(struct ext4_locality_group); | 2418 | sbi->s_locality_groups = alloc_percpu(struct ext4_locality_group); |
| @@ -2708,12 +2430,12 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery) | |||
| 2708 | spin_lock_init(&lg->lg_prealloc_lock); | 2430 | spin_lock_init(&lg->lg_prealloc_lock); |
| 2709 | } | 2431 | } |
| 2710 | 2432 | ||
| 2711 | ext4_mb_history_init(sb); | 2433 | if (sbi->s_proc) |
| 2434 | proc_create_data("mb_groups", S_IRUGO, sbi->s_proc, | ||
| 2435 | &ext4_mb_seq_groups_fops, sb); | ||
| 2712 | 2436 | ||
| 2713 | if (sbi->s_journal) | 2437 | if (sbi->s_journal) |
| 2714 | sbi->s_journal->j_commit_callback = release_blocks_on_commit; | 2438 | sbi->s_journal->j_commit_callback = release_blocks_on_commit; |
| 2715 | |||
| 2716 | printk(KERN_INFO "EXT4-fs: mballoc enabled\n"); | ||
| 2717 | return 0; | 2439 | return 0; |
| 2718 | } | 2440 | } |
| 2719 | 2441 | ||
| @@ -2790,7 +2512,8 @@ int ext4_mb_release(struct super_block *sb) | |||
| 2790 | } | 2512 | } |
| 2791 | 2513 | ||
| 2792 | free_percpu(sbi->s_locality_groups); | 2514 | free_percpu(sbi->s_locality_groups); |
| 2793 | ext4_mb_history_release(sb); | 2515 | if (sbi->s_proc) |
| 2516 | remove_proc_entry("mb_groups", sbi->s_proc); | ||
| 2794 | 2517 | ||
| 2795 | return 0; | 2518 | return 0; |
| 2796 | } | 2519 | } |
| @@ -3276,7 +2999,10 @@ static void ext4_mb_collect_stats(struct ext4_allocation_context *ac) | |||
| 3276 | atomic_inc(&sbi->s_bal_breaks); | 2999 | atomic_inc(&sbi->s_bal_breaks); |
| 3277 | } | 3000 | } |
| 3278 | 3001 | ||
| 3279 | ext4_mb_store_history(ac); | 3002 | if (ac->ac_op == EXT4_MB_HISTORY_ALLOC) |
| 3003 | trace_ext4_mballoc_alloc(ac); | ||
| 3004 | else | ||
| 3005 | trace_ext4_mballoc_prealloc(ac); | ||
| 3280 | } | 3006 | } |
| 3281 | 3007 | ||
| 3282 | /* | 3008 | /* |
| @@ -3776,7 +3502,6 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh, | |||
| 3776 | if (ac) { | 3502 | if (ac) { |
| 3777 | ac->ac_sb = sb; | 3503 | ac->ac_sb = sb; |
| 3778 | ac->ac_inode = pa->pa_inode; | 3504 | ac->ac_inode = pa->pa_inode; |
| 3779 | ac->ac_op = EXT4_MB_HISTORY_DISCARD; | ||
| 3780 | } | 3505 | } |
| 3781 | 3506 | ||
| 3782 | while (bit < end) { | 3507 | while (bit < end) { |
| @@ -3796,7 +3521,7 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh, | |||
| 3796 | ac->ac_b_ex.fe_start = bit; | 3521 | ac->ac_b_ex.fe_start = bit; |
| 3797 | ac->ac_b_ex.fe_len = next - bit; | 3522 | ac->ac_b_ex.fe_len = next - bit; |
| 3798 | ac->ac_b_ex.fe_logical = 0; | 3523 | ac->ac_b_ex.fe_logical = 0; |
| 3799 | ext4_mb_store_history(ac); | 3524 | trace_ext4_mballoc_discard(ac); |
| 3800 | } | 3525 | } |
| 3801 | 3526 | ||
| 3802 | trace_ext4_mb_release_inode_pa(ac, pa, grp_blk_start + bit, | 3527 | trace_ext4_mb_release_inode_pa(ac, pa, grp_blk_start + bit, |
| @@ -3831,9 +3556,6 @@ ext4_mb_release_group_pa(struct ext4_buddy *e4b, | |||
| 3831 | ext4_group_t group; | 3556 | ext4_group_t group; |
| 3832 | ext4_grpblk_t bit; | 3557 | ext4_grpblk_t bit; |
| 3833 | 3558 | ||
| 3834 | if (ac) | ||
| 3835 | ac->ac_op = EXT4_MB_HISTORY_DISCARD; | ||
| 3836 | |||
| 3837 | trace_ext4_mb_release_group_pa(ac, pa); | 3559 | trace_ext4_mb_release_group_pa(ac, pa); |
| 3838 | BUG_ON(pa->pa_deleted == 0); | 3560 | BUG_ON(pa->pa_deleted == 0); |
| 3839 | ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit); | 3561 | ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit); |
| @@ -3848,7 +3570,7 @@ ext4_mb_release_group_pa(struct ext4_buddy *e4b, | |||
| 3848 | ac->ac_b_ex.fe_start = bit; | 3570 | ac->ac_b_ex.fe_start = bit; |
| 3849 | ac->ac_b_ex.fe_len = pa->pa_len; | 3571 | ac->ac_b_ex.fe_len = pa->pa_len; |
| 3850 | ac->ac_b_ex.fe_logical = 0; | 3572 | ac->ac_b_ex.fe_logical = 0; |
| 3851 | ext4_mb_store_history(ac); | 3573 | trace_ext4_mballoc_discard(ac); |
| 3852 | } | 3574 | } |
| 3853 | 3575 | ||
| 3854 | return 0; | 3576 | return 0; |
| @@ -4189,7 +3911,6 @@ static void ext4_mb_group_or_file(struct ext4_allocation_context *ac) | |||
| 4189 | size = ac->ac_o_ex.fe_logical + ac->ac_o_ex.fe_len; | 3911 | size = ac->ac_o_ex.fe_logical + ac->ac_o_ex.fe_len; |
| 4190 | isize = (i_size_read(ac->ac_inode) + ac->ac_sb->s_blocksize - 1) | 3912 | isize = (i_size_read(ac->ac_inode) + ac->ac_sb->s_blocksize - 1) |
| 4191 | >> bsbits; | 3913 | >> bsbits; |
| 4192 | size = max(size, isize); | ||
| 4193 | 3914 | ||
| 4194 | if ((size == isize) && | 3915 | if ((size == isize) && |
| 4195 | !ext4_fs_is_busy(sbi) && | 3916 | !ext4_fs_is_busy(sbi) && |
| @@ -4199,6 +3920,7 @@ static void ext4_mb_group_or_file(struct ext4_allocation_context *ac) | |||
| 4199 | } | 3920 | } |
| 4200 | 3921 | ||
| 4201 | /* don't use group allocation for large files */ | 3922 | /* don't use group allocation for large files */ |
| 3923 | size = max(size, isize); | ||
| 4202 | if (size >= sbi->s_mb_stream_request) { | 3924 | if (size >= sbi->s_mb_stream_request) { |
| 4203 | ac->ac_flags |= EXT4_MB_STREAM_ALLOC; | 3925 | ac->ac_flags |= EXT4_MB_STREAM_ALLOC; |
| 4204 | return; | 3926 | return; |
| @@ -4739,7 +4461,6 @@ void ext4_mb_free_blocks(handle_t *handle, struct inode *inode, | |||
| 4739 | 4461 | ||
| 4740 | ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS); | 4462 | ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS); |
| 4741 | if (ac) { | 4463 | if (ac) { |
| 4742 | ac->ac_op = EXT4_MB_HISTORY_FREE; | ||
| 4743 | ac->ac_inode = inode; | 4464 | ac->ac_inode = inode; |
| 4744 | ac->ac_sb = sb; | 4465 | ac->ac_sb = sb; |
| 4745 | } | 4466 | } |
| @@ -4806,7 +4527,7 @@ do_more: | |||
| 4806 | ac->ac_b_ex.fe_group = block_group; | 4527 | ac->ac_b_ex.fe_group = block_group; |
| 4807 | ac->ac_b_ex.fe_start = bit; | 4528 | ac->ac_b_ex.fe_start = bit; |
| 4808 | ac->ac_b_ex.fe_len = count; | 4529 | ac->ac_b_ex.fe_len = count; |
| 4809 | ext4_mb_store_history(ac); | 4530 | trace_ext4_mballoc_free(ac); |
| 4810 | } | 4531 | } |
| 4811 | 4532 | ||
| 4812 | err = ext4_mb_load_buddy(sb, block_group, &e4b); | 4533 | err = ext4_mb_load_buddy(sb, block_group, &e4b); |
