Merge tag 'v3.10.103' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / fs / ext4 / mballoc.c
index aed1a67ab3a2bfedac039faadac4967d5d099a1f..d01573cc7f0101b670c3a8ee2961f1246638165c 100644 (file)
@@ -1232,6 +1232,7 @@ 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);
        void *bb;
 
        BUG_ON(e4b->bd_bitmap == e4b->bd_buddy);
@@ -1244,7 +1245,8 @@ static int mb_find_order_for_block(struct ext4_buddy *e4b, int block)
                        /* this block is part of buddy of order 'order' */
                        return order;
                }
-               bb += 1 << (e4b->bd_blkbits - order);
+               bb += bb_incr;
+               bb_incr >>= 1;
                order++;
        }
        return 0;
@@ -2514,7 +2516,7 @@ int ext4_mb_init(struct super_block *sb)
 {
        struct ext4_sb_info *sbi = EXT4_SB(sb);
        unsigned i, j;
-       unsigned offset;
+       unsigned offset, offset_incr;
        unsigned max;
        int ret;
 
@@ -2543,11 +2545,13 @@ int ext4_mb_init(struct super_block *sb)
 
        i = 1;
        offset = 0;
+       offset_incr = 1 << (sb->s_blocksize_bits - 1);
        max = sb->s_blocksize << 2;
        do {
                sbi->s_mb_offsets[i] = offset;
                sbi->s_mb_maxs[i] = max;
-               offset += 1 << (sb->s_blocksize_bits - i);
+               offset += offset_incr;
+               offset_incr = offset_incr >> 1;
                max = max >> 1;
                i++;
        } while (i <= sb->s_blocksize_bits + 1);
@@ -2873,7 +2877,7 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
                ext4_error(sb, "Allocating blocks %llu-%llu which overlap "
                           "fs metadata", block, block+len);
                /* File system mounted not to panic on error
-                * Fix the bitmap and repeat the block allocation
+                * Fix the bitmap and return EUCLEAN
                 * We leak some of the blocks here.
                 */
                ext4_lock_group(sb, ac->ac_b_ex.fe_group);
@@ -2882,7 +2886,7 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
                ext4_unlock_group(sb, ac->ac_b_ex.fe_group);
                err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
                if (!err)
-                       err = -EAGAIN;
+                       err = -EUCLEAN;
                goto out_err;
        }
 
@@ -4449,18 +4453,7 @@ repeat:
        }
        if (likely(ac->ac_status == AC_STATUS_FOUND)) {
                *errp = ext4_mb_mark_diskspace_used(ac, handle, reserv_clstrs);
-               if (*errp == -EAGAIN) {
-                       /*
-                        * drop the reference that we took
-                        * in ext4_mb_use_best_found
-                        */
-                       ext4_mb_release_context(ac);
-                       ac->ac_b_ex.fe_group = 0;
-                       ac->ac_b_ex.fe_start = 0;
-                       ac->ac_b_ex.fe_len = 0;
-                       ac->ac_status = AC_STATUS_CONTINUE;
-                       goto repeat;
-               } else if (*errp) {
+               if (*errp) {
                        ext4_discard_allocated_blocks(ac);
                        goto errout;
                } else {
@@ -4765,18 +4758,12 @@ do_more:
                /*
                 * blocks being freed are metadata. these blocks shouldn't
                 * be used until this transaction is committed
+                *
+                * We use __GFP_NOFAIL because ext4_free_blocks() is not allowed
+                * to fail.
                 */
-       retry:
-               new_entry = kmem_cache_alloc(ext4_free_data_cachep, GFP_NOFS);
-               if (!new_entry) {
-                       /*
-                        * We use a retry loop because
-                        * ext4_free_blocks() is not allowed to fail.
-                        */
-                       cond_resched();
-                       congestion_wait(BLK_RW_ASYNC, HZ/50);
-                       goto retry;
-               }
+               new_entry = kmem_cache_alloc(ext4_free_data_cachep,
+                               GFP_NOFS|__GFP_NOFAIL);
                new_entry->efd_start_cluster = bit;
                new_entry->efd_group = block_group;
                new_entry->efd_count = count_clusters;