Merge tag 'for-v5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux...
[linux-2.6-microblaze.git] / fs / ext4 / mballoc.c
index 24af9ed..99bf091 100644 (file)
@@ -822,24 +822,6 @@ void ext4_mb_generate_buddy(struct super_block *sb,
        spin_unlock(&sbi->s_bal_lock);
 }
 
-static void mb_regenerate_buddy(struct ext4_buddy *e4b)
-{
-       int count;
-       int order = 1;
-       void *buddy;
-
-       while ((buddy = mb_find_buddy(e4b, order++, &count))) {
-               ext4_set_bits(buddy, 0, count);
-       }
-       e4b->bd_info->bb_fragments = 0;
-       memset(e4b->bd_info->bb_counters, 0,
-               sizeof(*e4b->bd_info->bb_counters) *
-               (e4b->bd_sb->s_blocksize_bits + 2));
-
-       ext4_mb_generate_buddy(e4b->bd_sb, e4b->bd_buddy,
-               e4b->bd_bitmap, e4b->bd_group);
-}
-
 /* The buddy information is attached the buddy cache inode
  * for convenience. The information regarding each group
  * is loaded via ext4_mb_load_buddy. The information involve
@@ -1307,22 +1289,18 @@ static void ext4_mb_unload_buddy(struct ext4_buddy *e4b)
 
 static int mb_find_order_for_block(struct ext4_buddy *e4b, int block)
 {
-       int order = 1;
-       int bb_incr = 1 << (e4b->bd_blkbits - 1);
+       int order = 1, max;
        void *bb;
 
        BUG_ON(e4b->bd_bitmap == e4b->bd_buddy);
        BUG_ON(block >= (1 << (e4b->bd_blkbits + 3)));
 
-       bb = e4b->bd_buddy;
        while (order <= e4b->bd_blkbits + 1) {
-               block = block >> 1;
-               if (!mb_test_bit(block, bb)) {
+               bb = mb_find_buddy(e4b, order, &max);
+               if (!mb_test_bit(block >> order, bb)) {
                        /* this block is part of buddy of order 'order' */
                        return order;
                }
-               bb += bb_incr;
-               bb_incr >>= 1;
                order++;
        }
        return 0;
@@ -1512,7 +1490,6 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b,
                                sb, e4b->bd_group,
                                EXT4_GROUP_INFO_BBITMAP_CORRUPT);
                }
-               mb_regenerate_buddy(e4b);
                goto done;
        }
 
@@ -2395,9 +2372,9 @@ repeat:
 
                                nr = sbi->s_mb_prefetch;
                                if (ext4_has_feature_flex_bg(sb)) {
-                                       nr = (group / sbi->s_mb_prefetch) *
-                                               sbi->s_mb_prefetch;
-                                       nr = nr + sbi->s_mb_prefetch - group;
+                                       nr = 1 << sbi->s_log_groups_per_flex;
+                                       nr -= group & (nr - 1);
+                                       nr = min(nr, sbi->s_mb_prefetch);
                                }
                                prefetch_grp = ext4_mb_prefetch(sb, group,
                                                        nr, &prefetch_ios);
@@ -2733,7 +2710,8 @@ static int ext4_mb_init_backend(struct super_block *sb)
 
        if (ext4_has_feature_flex_bg(sb)) {
                /* a single flex group is supposed to be read by a single IO */
-               sbi->s_mb_prefetch = 1 << sbi->s_es->s_log_groups_per_flex;
+               sbi->s_mb_prefetch = min(1 << sbi->s_es->s_log_groups_per_flex,
+                       BLK_MAX_SEGMENT_SIZE >> (sb->s_blocksize_bits - 9));
                sbi->s_mb_prefetch *= 8; /* 8 prefetch IOs in flight at most */
        } else {
                sbi->s_mb_prefetch = 32;
@@ -5126,6 +5104,7 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
                                ext4_group_first_block_no(sb, group) +
                                EXT4_C2B(sbi, cluster),
                                "Block already on to-be-freed list");
+                       kmem_cache_free(ext4_free_data_cachep, new_entry);
                        return 0;
                }
        }