Merge branch 'for-3.2/drivers' of git://git.kernel.dk/linux-block
[cascardo/linux.git] / fs / ext4 / mballoc.c
index 90a3ed7..e2d8be8 100644 (file)
@@ -581,7 +581,7 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file,
                                continue;
                        }
 
-                       /* both bits in buddy2 must be 0 */
+                       /* both bits in buddy2 must be 1 */
                        MB_CHECK_ASSERT(mb_test_bit(i << 1, buddy2));
                        MB_CHECK_ASSERT(mb_test_bit((i << 1) + 1, buddy2));
 
@@ -1391,7 +1391,6 @@ static int mb_find_extent(struct ext4_buddy *e4b, int order, int block,
 {
        int next = block;
        int max;
-       int ord;
        void *buddy;
 
        assert_spin_locked(ext4_group_lock_ptr(e4b->bd_sb, e4b->bd_group));
@@ -1433,9 +1432,8 @@ static int mb_find_extent(struct ext4_buddy *e4b, int order, int block,
                if (mb_test_bit(next, EXT4_MB_BITMAP(e4b)))
                        break;
 
-               ord = mb_find_order_for_block(e4b, next);
+               order = mb_find_order_for_block(e4b, next);
 
-               order = ord;
                block = next >> order;
                ex->fe_len += 1 << order;
        }
@@ -2504,7 +2502,7 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
        sbi->s_locality_groups = alloc_percpu(struct ext4_locality_group);
        if (sbi->s_locality_groups == NULL) {
                ret = -ENOMEM;
-               goto out;
+               goto out_free_groupinfo_slab;
        }
        for_each_possible_cpu(i) {
                struct ext4_locality_group *lg;
@@ -2517,9 +2515,8 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
 
        /* init file for buddy data */
        ret = ext4_mb_init_backend(sb);
-       if (ret != 0) {
-               goto out;
-       }
+       if (ret != 0)
+               goto out_free_locality_groups;
 
        if (sbi->s_proc)
                proc_create_data("mb_groups", S_IRUGO, sbi->s_proc,
@@ -2527,11 +2524,19 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
 
        if (sbi->s_journal)
                sbi->s_journal->j_commit_callback = release_blocks_on_commit;
+
+       return 0;
+
+out_free_locality_groups:
+       free_percpu(sbi->s_locality_groups);
+       sbi->s_locality_groups = NULL;
+out_free_groupinfo_slab:
+       ext4_groupinfo_destroy_slabs();
 out:
-       if (ret) {
-               kfree(sbi->s_mb_offsets);
-               kfree(sbi->s_mb_maxs);
-       }
+       kfree(sbi->s_mb_offsets);
+       sbi->s_mb_offsets = NULL;
+       kfree(sbi->s_mb_maxs);
+       sbi->s_mb_maxs = NULL;
        return ret;
 }
 
@@ -3338,7 +3343,6 @@ void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
        ext4_group_t groupnr;
        ext4_grpblk_t start;
        int preallocated = 0;
-       int count = 0;
        int len;
 
        /* all form of preallocation discards first load group,
@@ -3361,7 +3365,6 @@ void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
                BUG_ON(groupnr != group);
                ext4_set_bits(bitmap, start, len);
                preallocated += len;
-               count++;
        }
        mb_debug(1, "prellocated %u for group %u\n", preallocated, group);
 }
@@ -3999,6 +4002,11 @@ static void ext4_mb_group_or_file(struct ext4_allocation_context *ac)
                return;
        }
 
+       if (sbi->s_mb_group_prealloc <= 0) {
+               ac->ac_flags |= EXT4_MB_STREAM_ALLOC;
+               return;
+       }
+
        /* don't use group allocation for large files */
        size = max(size, isize);
        if (size > sbi->s_mb_stream_request) {
@@ -4284,6 +4292,10 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
 
        trace_ext4_request_blocks(ar);
 
+       /* Allow to use superuser reservation for quota file */
+       if (IS_NOQUOTA(ar->inode))
+               ar->flags |= EXT4_MB_USE_ROOT_BLOCKS;
+
        /*
         * For delayed allocation, we could skip the ENOSPC and
         * EDQUOT check, as blocks and quotas have been already
@@ -4297,7 +4309,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
                 * and verify allocation doesn't exceed the quota limits.
                 */
                while (ar->len &&
-                       ext4_claim_free_blocks(sbi, ar->len, ar->flags)) {
+                       ext4_claim_free_clusters(sbi, ar->len, ar->flags)) {
 
                        /* let others to free the space */
                        yield();