]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - fs/ext4/mballoc.c
Merge branches 'for-4.11/upstream-fixes', 'for-4.12/accutouch', 'for-4.12/cp2112...
[mirror_ubuntu-artful-kernel.git] / fs / ext4 / mballoc.c
index 7ae43c59bc79578ddc2146328ca050ab68212bd2..10c62de642c6f9e24d82e6017f65e436683cb7ad 100644 (file)
@@ -1556,7 +1556,17 @@ static int mb_find_extent(struct ext4_buddy *e4b, int block,
                ex->fe_len += 1 << order;
        }
 
-       BUG_ON(ex->fe_start + ex->fe_len > (1 << (e4b->bd_blkbits + 3)));
+       if (ex->fe_start + ex->fe_len > (1 << (e4b->bd_blkbits + 3))) {
+               /* Should never happen! (but apparently sometimes does?!?) */
+               WARN_ON(1);
+               ext4_error(e4b->bd_sb, "corruption or bug in mb_find_extent "
+                          "block=%d, order=%d needed=%d ex=%u/%d/%d@%u",
+                          block, order, needed, ex->fe_group, ex->fe_start,
+                          ex->fe_len, ex->fe_logical);
+               ex->fe_len = 0;
+               ex->fe_start = 0;
+               ex->fe_group = 0;
+       }
        return ex->fe_len;
 }
 
@@ -2136,8 +2146,10 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
         * We search using buddy data only if the order of the request
         * is greater than equal to the sbi_s_mb_order2_reqs
         * You can tune it via /sys/fs/ext4/<partition>/mb_order2_req
+        * We also support searching for power-of-two requests only for
+        * requests upto maximum buddy size we have constructed.
         */
-       if (i >= sbi->s_mb_order2_reqs) {
+       if (i >= sbi->s_mb_order2_reqs && i <= sb->s_blocksize_bits + 2) {
                /*
                 * This should tell if fe_len is exactly power of 2
                 */
@@ -2207,7 +2219,7 @@ repeat:
                        }
 
                        ac->ac_groups_scanned++;
-                       if (cr == 0 && ac->ac_2order < sb->s_blocksize_bits+2)
+                       if (cr == 0)
                                ext4_mb_simple_scan_group(ac, &e4b);
                        else if (cr == 1 && sbi->s_stripe &&
                                        !(ac->ac_g_ex.fe_len % sbi->s_stripe))
@@ -3123,6 +3135,13 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
        if (ar->pright && start + size - 1 >= ar->lright)
                size -= start + size - ar->lright;
 
+       /*
+        * Trim allocation request for filesystems with artificially small
+        * groups.
+        */
+       if (size > EXT4_BLOCKS_PER_GROUP(ac->ac_sb))
+               size = EXT4_BLOCKS_PER_GROUP(ac->ac_sb);
+
        end = start + size;
 
        /* check we don't cross already preallocated blocks */