ext4: trim allocation requests to group size
[pandora-kernel.git] / fs / ext4 / mballoc.c
index 17a5a57..5efe721 100644 (file)
@@ -70,8 +70,8 @@
  *
  * pa_lstart -> the logical start block for this prealloc space
  * pa_pstart -> the physical start block for this prealloc space
- * pa_len    -> length for this prealloc space
- * pa_free   ->  free space available in this prealloc space
+ * pa_len    -> length for this prealloc space (in clusters)
+ * pa_free   ->  free space available in this prealloc space (in clusters)
  *
  * The inode preallocation space is used looking at the _logical_ start
  * block. If only the logical file block falls within the range of prealloc
  * list. In case of inode preallocation we follow a list of heuristics
  * based on file size. This can be found in ext4_mb_normalize_request. If
  * we are doing a group prealloc we try to normalize the request to
- * sbi->s_mb_group_prealloc. Default value of s_mb_group_prealloc is
+ * sbi->s_mb_group_prealloc.  The default value of s_mb_group_prealloc is
+ * dependent on the cluster size; for non-bigalloc file systems, it is
  * 512 blocks. This can be tuned via
  * /sys/fs/ext4/<partition>/mb_group_prealloc. The value is represented in
  * terms of number of blocks. If we have mounted the file system with -O
@@ -459,7 +460,7 @@ static void mb_free_blocks_double(struct inode *inode, struct ext4_buddy *e4b,
                        ext4_fsblk_t blocknr;
 
                        blocknr = ext4_group_first_block_no(sb, e4b->bd_group);
-                       blocknr += first + i;
+                       blocknr += EXT4_C2B(EXT4_SB(sb), first + i);
                        ext4_grp_locked_error(sb, e4b->bd_group,
                                              inode ? inode->i_ino : 0,
                                              blocknr,
@@ -580,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));
 
@@ -651,9 +652,9 @@ static void ext4_mb_mark_free_simple(struct super_block *sb,
        ext4_grpblk_t min;
        ext4_grpblk_t max;
        ext4_grpblk_t chunk;
-       unsigned short border;
+       unsigned int border;
 
-       BUG_ON(len > EXT4_BLOCKS_PER_GROUP(sb));
+       BUG_ON(len > EXT4_CLUSTERS_PER_GROUP(sb));
 
        border = 2 << sb->s_blocksize_bits;
 
@@ -705,7 +706,7 @@ void ext4_mb_generate_buddy(struct super_block *sb,
                                void *buddy, void *bitmap, ext4_group_t group)
 {
        struct ext4_group_info *grp = ext4_get_group_info(sb, group);
-       ext4_grpblk_t max = EXT4_BLOCKS_PER_GROUP(sb);
+       ext4_grpblk_t max = EXT4_CLUSTERS_PER_GROUP(sb);
        ext4_grpblk_t i = 0;
        ext4_grpblk_t first;
        ext4_grpblk_t len;
@@ -734,7 +735,7 @@ void ext4_mb_generate_buddy(struct super_block *sb,
 
        if (free != grp->bb_free) {
                ext4_grp_locked_error(sb, group, 0, 0,
-                                     "%u blocks in bitmap, %u in gd",
+                                     "%u clusters in bitmap, %u in gd",
                                      free, grp->bb_free);
                /*
                 * If we intent to continue, we consider group descritor
@@ -1311,6 +1312,8 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b,
        void *buddy2;
        struct super_block *sb = e4b->bd_sb;
 
+       if (WARN_ON(count == 0))
+               return;
        BUG_ON(first + count > (sb->s_blocksize << 3));
        assert_spin_locked(ext4_group_lock_ptr(sb, e4b->bd_group));
        mb_check_buddy(e4b);
@@ -1339,7 +1342,7 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b,
                        ext4_fsblk_t blocknr;
 
                        blocknr = ext4_group_first_block_no(sb, e4b->bd_group);
-                       blocknr += block;
+                       blocknr += EXT4_C2B(EXT4_SB(sb), block);
                        ext4_grp_locked_error(sb, e4b->bd_group,
                                              inode ? inode->i_ino : 0,
                                              blocknr,
@@ -1390,7 +1393,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));
@@ -1432,9 +1434,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;
        }
@@ -1624,8 +1625,8 @@ static void ext4_mb_measure_extent(struct ext4_allocation_context *ac,
        struct ext4_free_extent *gex = &ac->ac_g_ex;
 
        BUG_ON(ex->fe_len <= 0);
-       BUG_ON(ex->fe_len > EXT4_BLOCKS_PER_GROUP(ac->ac_sb));
-       BUG_ON(ex->fe_start >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb));
+       BUG_ON(ex->fe_len > EXT4_CLUSTERS_PER_GROUP(ac->ac_sb));
+       BUG_ON(ex->fe_start >= EXT4_CLUSTERS_PER_GROUP(ac->ac_sb));
        BUG_ON(ac->ac_status != AC_STATUS_CONTINUE);
 
        ac->ac_found++;
@@ -1823,15 +1824,15 @@ void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac,
 
        while (free && ac->ac_status == AC_STATUS_CONTINUE) {
                i = mb_find_next_zero_bit(bitmap,
-                                               EXT4_BLOCKS_PER_GROUP(sb), i);
-               if (i >= EXT4_BLOCKS_PER_GROUP(sb)) {
+                                               EXT4_CLUSTERS_PER_GROUP(sb), i);
+               if (i >= EXT4_CLUSTERS_PER_GROUP(sb)) {
                        /*
                         * IF we have corrupt bitmap, we won't find any
                         * free blocks even though group info says we
                         * we have free blocks
                         */
                        ext4_grp_locked_error(sb, e4b->bd_group, 0, 0,
-                                       "%d free blocks as per "
+                                       "%d free clusters as per "
                                        "group info. But bitmap says 0",
                                        free);
                        break;
@@ -1841,7 +1842,7 @@ void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac,
                BUG_ON(ex.fe_len <= 0);
                if (free < ex.fe_len) {
                        ext4_grp_locked_error(sb, e4b->bd_group, 0, 0,
-                                       "%d free blocks as per "
+                                       "%d free clusters as per "
                                        "group info. But got %d blocks",
                                        free, ex.fe_len);
                        /*
@@ -1887,7 +1888,7 @@ void ext4_mb_scan_aligned(struct ext4_allocation_context *ac,
        do_div(a, sbi->s_stripe);
        i = (a * sbi->s_stripe) - first_group_block;
 
-       while (i < EXT4_BLOCKS_PER_GROUP(sb)) {
+       while (i < EXT4_CLUSTERS_PER_GROUP(sb)) {
                if (!mb_test_bit(i, bitmap)) {
                        max = mb_find_extent(e4b, 0, i, sbi->s_stripe, &ex);
                        if (max >= sbi->s_stripe) {
@@ -2028,7 +2029,11 @@ repeat:
                group = ac->ac_g_ex.fe_group;
 
                for (i = 0; i < ngroups; group++, i++) {
-                       if (group == ngroups)
+                       /*
+                        * Artificially restricted ngroups for non-extent
+                        * files makes group > ngroups possible on first loop.
+                        */
+                       if (group >= ngroups)
                                group = 0;
 
                        /* This now checks without needing the buddy page */
@@ -2129,7 +2134,7 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v)
        struct ext4_buddy e4b;
        struct sg {
                struct ext4_group_info info;
-               ext4_grpblk_t counters[16];
+               ext4_grpblk_t counters[EXT4_MAX_BLOCK_LOG_SIZE + 2];
        } sg;
 
        group--;
@@ -2252,10 +2257,10 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group,
         */
        if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
                meta_group_info[i]->bb_free =
-                       ext4_free_blocks_after_init(sb, group, desc);
+                       ext4_free_clusters_after_init(sb, group, desc);
        } else {
                meta_group_info[i]->bb_free =
-                       ext4_free_blks_count(sb, desc);
+                       ext4_free_group_clusters(sb, desc);
        }
 
        INIT_LIST_HEAD(&meta_group_info[i]->bb_prealloc_list);
@@ -2473,7 +2478,20 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
        sbi->s_mb_stats = MB_DEFAULT_STATS;
        sbi->s_mb_stream_request = MB_DEFAULT_STREAM_THRESHOLD;
        sbi->s_mb_order2_reqs = MB_DEFAULT_ORDER2_REQS;
-       sbi->s_mb_group_prealloc = MB_DEFAULT_GROUP_PREALLOC;
+       /*
+        * The default group preallocation is 512, which for 4k block
+        * sizes translates to 2 megabytes.  However for bigalloc file
+        * systems, this is probably too big (i.e, if the cluster size
+        * is 1 megabyte, then group preallocation size becomes half a
+        * gigabyte!).  As a default, we will keep a two megabyte
+        * group pralloc size for cluster sizes up to 64k, and after
+        * that, we will force a minimum group preallocation size of
+        * 32 clusters.  This translates to 8 megs when the cluster
+        * size is 256k, and 32 megs when the cluster size is 1 meg,
+        * which seems reasonable as a default.
+        */
+       sbi->s_mb_group_prealloc = max(MB_DEFAULT_GROUP_PREALLOC >>
+                                      sbi->s_cluster_bits, 32);
        /*
         * If there is a s_stripe > 1, then we set the s_mb_group_prealloc
         * to the lowest multiple of s_stripe which is bigger than
@@ -2490,7 +2508,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;
@@ -2503,9 +2521,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,
@@ -2513,11 +2530,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;
 }
 
@@ -2548,6 +2573,9 @@ int ext4_mb_release(struct super_block *sb)
        struct ext4_sb_info *sbi = EXT4_SB(sb);
        struct kmem_cache *cachep = get_groupinfo_cache(sb->s_blocksize_bits);
 
+       if (sbi->s_proc)
+               remove_proc_entry("mb_groups", sbi->s_proc);
+
        if (sbi->s_group_info) {
                for (i = 0; i < ngroups; i++) {
                        grinfo = ext4_get_group_info(sb, i);
@@ -2595,18 +2623,18 @@ int ext4_mb_release(struct super_block *sb)
        }
 
        free_percpu(sbi->s_locality_groups);
-       if (sbi->s_proc)
-               remove_proc_entry("mb_groups", sbi->s_proc);
 
        return 0;
 }
 
 static inline int ext4_issue_discard(struct super_block *sb,
-               ext4_group_t block_group, ext4_grpblk_t block, int count)
+               ext4_group_t block_group, ext4_grpblk_t cluster, int count)
 {
        ext4_fsblk_t discard_block;
 
-       discard_block = block + ext4_group_first_block_no(sb, block_group);
+       discard_block = (EXT4_C2B(EXT4_SB(sb), cluster) +
+                        ext4_group_first_block_no(sb, block_group));
+       count = EXT4_C2B(EXT4_SB(sb), count);
        trace_ext4_discard_blocks(sb,
                        (unsigned long long) discard_block, count);
        return sb_issue_discard(sb, discard_block, count, GFP_NOFS, 0);
@@ -2633,7 +2661,7 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn)
 
                if (test_opt(sb, DISCARD))
                        ext4_issue_discard(sb, entry->group,
-                                          entry->start_blk, entry->count);
+                                          entry->start_cluster, entry->count);
 
                err = ext4_mb_load_buddy(sb, entry->group, &e4b);
                /* we expect to find existing buddy because it's pinned */
@@ -2646,7 +2674,7 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn)
                ext4_lock_group(sb, entry->group);
                /* Take it out of per group rb tree */
                rb_erase(&entry->node, &(db->bb_free_root));
-               mb_free_blocks(NULL, &e4b, entry->start_blk, entry->count);
+               mb_free_blocks(NULL, &e4b, entry->start_cluster, entry->count);
 
                /*
                 * Clear the trimmed flag for the group so that the next
@@ -2752,7 +2780,7 @@ void ext4_exit_mballoc(void)
  */
 static noinline_for_stack int
 ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
-                               handle_t *handle, unsigned int reserv_blks)
+                               handle_t *handle, unsigned int reserv_clstrs)
 {
        struct buffer_head *bitmap_bh = NULL;
        struct ext4_group_desc *gdp;
@@ -2783,7 +2811,7 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
                goto out_err;
 
        ext4_debug("using block group %u(%d)\n", ac->ac_b_ex.fe_group,
-                       ext4_free_blks_count(sb, gdp));
+                       ext4_free_group_clusters(sb, gdp));
 
        err = ext4_journal_get_write_access(handle, gdp_bh);
        if (err)
@@ -2791,12 +2819,12 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
 
        block = ext4_grp_offs_to_block(sb, &ac->ac_b_ex);
 
-       len = ac->ac_b_ex.fe_len;
+       len = EXT4_C2B(sbi, ac->ac_b_ex.fe_len);
        if (!ext4_data_block_valid(sbi, block, len)) {
                ext4_error(sb, "Allocating blocks %llu-%llu which overlap "
                           "fs metadata\n", block, block+len);
                /* File system mounted not to panic on error
-                * Fix the bitmap and repeat the block allocation
+                * Fix the bitmap and return EIO
                 * We leak some of the blocks here.
                 */
                ext4_lock_group(sb, ac->ac_b_ex.fe_group);
@@ -2805,7 +2833,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 = -EIO;
                goto out_err;
        }
 
@@ -2823,28 +2851,29 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
                      ac->ac_b_ex.fe_len);
        if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
                gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
-               ext4_free_blks_set(sb, gdp,
-                                       ext4_free_blocks_after_init(sb,
-                                       ac->ac_b_ex.fe_group, gdp));
+               ext4_free_group_clusters_set(sb, gdp,
+                                            ext4_free_clusters_after_init(sb,
+                                               ac->ac_b_ex.fe_group, gdp));
        }
-       len = ext4_free_blks_count(sb, gdp) - ac->ac_b_ex.fe_len;
-       ext4_free_blks_set(sb, gdp, len);
+       len = ext4_free_group_clusters(sb, gdp) - ac->ac_b_ex.fe_len;
+       ext4_free_group_clusters_set(sb, gdp, len);
        gdp->bg_checksum = ext4_group_desc_csum(sbi, ac->ac_b_ex.fe_group, gdp);
 
        ext4_unlock_group(sb, ac->ac_b_ex.fe_group);
-       percpu_counter_sub(&sbi->s_freeblocks_counter, ac->ac_b_ex.fe_len);
+       percpu_counter_sub(&sbi->s_freeclusters_counter, ac->ac_b_ex.fe_len);
        /*
         * Now reduce the dirty block count also. Should not go negative
         */
        if (!(ac->ac_flags & EXT4_MB_DELALLOC_RESERVED))
                /* release all the reserved blocks if non delalloc */
-               percpu_counter_sub(&sbi->s_dirtyblocks_counter, reserv_blks);
+               percpu_counter_sub(&sbi->s_dirtyclusters_counter,
+                                  reserv_clstrs);
 
        if (sbi->s_log_groups_per_flex) {
                ext4_group_t flex_group = ext4_flex_group(sbi,
                                                          ac->ac_b_ex.fe_group);
-               atomic_sub(ac->ac_b_ex.fe_len,
-                          &sbi->s_flex_groups[flex_group].free_blocks);
+               atomic64_sub(ac->ac_b_ex.fe_len,
+                            &sbi->s_flex_groups[flex_group].free_clusters);
        }
 
        err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
@@ -2886,6 +2915,7 @@ static noinline_for_stack void
 ext4_mb_normalize_request(struct ext4_allocation_context *ac,
                                struct ext4_allocation_request *ar)
 {
+       struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
        int bsbits, max;
        ext4_lblk_t end;
        loff_t size, orig_size, start_off;
@@ -2916,7 +2946,7 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
 
        /* first, let's learn actual file size
         * given current request is allocated */
-       size = ac->ac_o_ex.fe_logical + ac->ac_o_ex.fe_len;
+       size = ac->ac_o_ex.fe_logical + EXT4_C2B(sbi, ac->ac_o_ex.fe_len);
        size = size << bsbits;
        if (size < i_size_read(ac->ac_inode))
                size = i_size_read(ac->ac_inode);
@@ -2973,6 +3003,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 */
@@ -2988,7 +3025,8 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
                        continue;
                }
 
-               pa_end = pa->pa_lstart + pa->pa_len;
+               pa_end = pa->pa_lstart + EXT4_C2B(EXT4_SB(ac->ac_sb),
+                                                 pa->pa_len);
 
                /* PA must not overlap original request */
                BUG_ON(!(ac->ac_o_ex.fe_logical >= pa_end ||
@@ -3018,9 +3056,11 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
        rcu_read_lock();
        list_for_each_entry_rcu(pa, &ei->i_prealloc_list, pa_inode_list) {
                ext4_lblk_t pa_end;
+
                spin_lock(&pa->pa_lock);
                if (pa->pa_deleted == 0) {
-                       pa_end = pa->pa_lstart + pa->pa_len;
+                       pa_end = pa->pa_lstart + EXT4_C2B(EXT4_SB(ac->ac_sb),
+                                                         pa->pa_len);
                        BUG_ON(!(start >= pa_end || end <= pa->pa_lstart));
                }
                spin_unlock(&pa->pa_lock);
@@ -3043,7 +3083,7 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
        /* XXX: is it better to align blocks WRT to logical
         * placement or satisfy big request as is */
        ac->ac_g_ex.fe_logical = start;
-       ac->ac_g_ex.fe_len = size;
+       ac->ac_g_ex.fe_len = EXT4_NUM_B2C(sbi, size);
 
        /* define goal start in order to merge */
        if (ar->pright && (ar->lright == (start + size))) {
@@ -3097,13 +3137,31 @@ static void ext4_mb_collect_stats(struct ext4_allocation_context *ac)
 static void ext4_discard_allocated_blocks(struct ext4_allocation_context *ac)
 {
        struct ext4_prealloc_space *pa = ac->ac_pa;
-       int len;
+       struct ext4_buddy e4b;
+       int err;
 
-       if (pa && pa->pa_type == MB_INODE_PA) {
-               len = ac->ac_b_ex.fe_len;
-               pa->pa_free += len;
+       if (pa == NULL) {
+               if (ac->ac_f_ex.fe_len == 0)
+                       return;
+               err = ext4_mb_load_buddy(ac->ac_sb, ac->ac_f_ex.fe_group, &e4b);
+               if (err) {
+                       /*
+                        * This should never happen since we pin the
+                        * pages in the ext4_allocation_context so
+                        * ext4_mb_load_buddy() should never fail.
+                        */
+                       WARN(1, "mb_load_buddy failed (%d)", err);
+                       return;
+               }
+               ext4_lock_group(ac->ac_sb, ac->ac_f_ex.fe_group);
+               mb_free_blocks(ac->ac_inode, &e4b, ac->ac_f_ex.fe_start,
+                              ac->ac_f_ex.fe_len);
+               ext4_unlock_group(ac->ac_sb, ac->ac_f_ex.fe_group);
+               ext4_mb_unload_buddy(&e4b);
+               return;
        }
-
+       if (pa->pa_type == MB_INODE_PA)
+               pa->pa_free += ac->ac_b_ex.fe_len;
 }
 
 /*
@@ -3112,14 +3170,16 @@ static void ext4_discard_allocated_blocks(struct ext4_allocation_context *ac)
 static void ext4_mb_use_inode_pa(struct ext4_allocation_context *ac,
                                struct ext4_prealloc_space *pa)
 {
+       struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
        ext4_fsblk_t start;
        ext4_fsblk_t end;
        int len;
 
        /* found preallocated blocks, use them */
        start = pa->pa_pstart + (ac->ac_o_ex.fe_logical - pa->pa_lstart);
-       end = min(pa->pa_pstart + pa->pa_len, start + ac->ac_o_ex.fe_len);
-       len = end - start;
+       end = min(pa->pa_pstart + EXT4_C2B(sbi, pa->pa_len),
+                 start + EXT4_C2B(sbi, ac->ac_o_ex.fe_len));
+       len = EXT4_NUM_B2C(sbi, end - start);
        ext4_get_group_no_and_offset(ac->ac_sb, start, &ac->ac_b_ex.fe_group,
                                        &ac->ac_b_ex.fe_start);
        ac->ac_b_ex.fe_len = len;
@@ -3127,7 +3187,7 @@ static void ext4_mb_use_inode_pa(struct ext4_allocation_context *ac,
        ac->ac_pa = pa;
 
        BUG_ON(start < pa->pa_pstart);
-       BUG_ON(start + len > pa->pa_pstart + pa->pa_len);
+       BUG_ON(end > pa->pa_pstart + EXT4_C2B(sbi, pa->pa_len));
        BUG_ON(pa->pa_free < len);
        pa->pa_free -= len;
 
@@ -3193,6 +3253,7 @@ ext4_mb_check_group_pa(ext4_fsblk_t goal_block,
 static noinline_for_stack int
 ext4_mb_use_preallocated(struct ext4_allocation_context *ac)
 {
+       struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
        int order, i;
        struct ext4_inode_info *ei = EXT4_I(ac->ac_inode);
        struct ext4_locality_group *lg;
@@ -3210,12 +3271,14 @@ ext4_mb_use_preallocated(struct ext4_allocation_context *ac)
                /* all fields in this condition don't change,
                 * so we can skip locking for them */
                if (ac->ac_o_ex.fe_logical < pa->pa_lstart ||
-                       ac->ac_o_ex.fe_logical >= pa->pa_lstart + pa->pa_len)
+                   ac->ac_o_ex.fe_logical >= (pa->pa_lstart +
+                                              EXT4_C2B(sbi, pa->pa_len)))
                        continue;
 
                /* non-extent files can't have physical blocks past 2^32 */
                if (!(ext4_test_inode_flag(ac->ac_inode, EXT4_INODE_EXTENTS)) &&
-                       pa->pa_pstart + pa->pa_len > EXT4_MAX_BLOCK_FILE_PHYS)
+                   (pa->pa_pstart + EXT4_C2B(sbi, pa->pa_len) >
+                    EXT4_MAX_BLOCK_FILE_PHYS))
                        continue;
 
                /* found preallocated blocks, use them */
@@ -3291,7 +3354,7 @@ static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap,
 
        while (n) {
                entry = rb_entry(n, struct ext4_free_data, node);
-               ext4_set_bits(bitmap, entry->start_blk, entry->count);
+               ext4_set_bits(bitmap, entry->start_cluster, entry->count);
                n = rb_next(n);
        }
        return;
@@ -3312,7 +3375,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,
@@ -3335,7 +3397,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);
 }
@@ -3344,6 +3405,9 @@ static void ext4_mb_pa_callback(struct rcu_head *head)
 {
        struct ext4_prealloc_space *pa;
        pa = container_of(head, struct ext4_prealloc_space, u.pa_rcu);
+
+       BUG_ON(atomic_read(&pa->pa_count));
+       BUG_ON(pa->pa_deleted == 0);
        kmem_cache_free(ext4_pspace_cachep, pa);
 }
 
@@ -3357,11 +3421,13 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac,
        ext4_group_t grp;
        ext4_fsblk_t grp_blk;
 
-       if (!atomic_dec_and_test(&pa->pa_count) || pa->pa_free != 0)
-               return;
-
        /* in this short window concurrent discard can set pa_deleted */
        spin_lock(&pa->pa_lock);
+       if (!atomic_dec_and_test(&pa->pa_count) || pa->pa_free != 0) {
+               spin_unlock(&pa->pa_lock);
+               return;
+       }
+
        if (pa->pa_deleted == 1) {
                spin_unlock(&pa->pa_lock);
                return;
@@ -3412,6 +3478,7 @@ static noinline_for_stack int
 ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)
 {
        struct super_block *sb = ac->ac_sb;
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
        struct ext4_prealloc_space *pa;
        struct ext4_group_info *grp;
        struct ext4_inode_info *ei;
@@ -3443,16 +3510,18 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)
                winl = ac->ac_o_ex.fe_logical - ac->ac_g_ex.fe_logical;
 
                /* also, we should cover whole original request */
-               wins = ac->ac_b_ex.fe_len - ac->ac_o_ex.fe_len;
+               wins = EXT4_C2B(sbi, ac->ac_b_ex.fe_len - ac->ac_o_ex.fe_len);
 
                /* the smallest one defines real window */
                win = min(winl, wins);
 
-               offs = ac->ac_o_ex.fe_logical % ac->ac_b_ex.fe_len;
+               offs = ac->ac_o_ex.fe_logical %
+                       EXT4_C2B(sbi, ac->ac_b_ex.fe_len);
                if (offs && offs < win)
                        win = offs;
 
-               ac->ac_b_ex.fe_logical = ac->ac_o_ex.fe_logical - win;
+               ac->ac_b_ex.fe_logical = ac->ac_o_ex.fe_logical -
+                       EXT4_NUM_B2C(sbi, win);
                BUG_ON(ac->ac_o_ex.fe_logical < ac->ac_b_ex.fe_logical);
                BUG_ON(ac->ac_o_ex.fe_len > ac->ac_b_ex.fe_len);
        }
@@ -3477,7 +3546,7 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)
        trace_ext4_mb_new_inode_pa(ac, pa);
 
        ext4_mb_use_inode_pa(ac, pa);
-       atomic_add(pa->pa_free, &EXT4_SB(sb)->s_mb_preallocated);
+       atomic_add(pa->pa_free, &sbi->s_mb_preallocated);
 
        ei = EXT4_I(ac->ac_inode);
        grp = ext4_get_group_info(sb, ac->ac_b_ex.fe_group);
@@ -3592,7 +3661,7 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh,
 
        BUG_ON(pa->pa_deleted == 0);
        ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit);
-       grp_blk_start = pa->pa_pstart - bit;
+       grp_blk_start = pa->pa_pstart - EXT4_C2B(sbi, bit);
        BUG_ON(group != e4b->bd_group && pa->pa_len != 0);
        end = bit + pa->pa_len;
 
@@ -3607,7 +3676,8 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh,
                free += next - bit;
 
                trace_ext4_mballoc_discard(sb, NULL, group, bit, next - bit);
-               trace_ext4_mb_release_inode_pa(pa, grp_blk_start + bit,
+               trace_ext4_mb_release_inode_pa(pa, (grp_blk_start +
+                                                   EXT4_C2B(sbi, bit)),
                                               next - bit);
                mb_free_blocks(pa->pa_inode, e4b, bit, next - bit);
                bit = next + 1;
@@ -3690,7 +3760,7 @@ ext4_mb_discard_group_preallocations(struct super_block *sb,
        }
 
        if (needed == 0)
-               needed = EXT4_BLOCKS_PER_GROUP(sb) + 1;
+               needed = EXT4_CLUSTERS_PER_GROUP(sb) + 1;
 
        INIT_LIST_HEAD(&list);
 repeat:
@@ -3958,7 +4028,7 @@ static void ext4_mb_group_or_file(struct ext4_allocation_context *ac)
        if (unlikely(ac->ac_flags & EXT4_MB_HINT_GOAL_ONLY))
                return;
 
-       size = ac->ac_o_ex.fe_logical + ac->ac_o_ex.fe_len;
+       size = ac->ac_o_ex.fe_logical + EXT4_C2B(sbi, ac->ac_o_ex.fe_len);
        isize = (i_size_read(ac->ac_inode) + ac->ac_sb->s_blocksize - 1)
                >> bsbits;
 
@@ -3969,6 +4039,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) {
@@ -4007,8 +4082,8 @@ ext4_mb_initialize_context(struct ext4_allocation_context *ac,
        len = ar->len;
 
        /* just a dirty hack to filter too big requests  */
-       if (len >= EXT4_BLOCKS_PER_GROUP(sb) - 10)
-               len = EXT4_BLOCKS_PER_GROUP(sb) - 10;
+       if (len >= EXT4_CLUSTERS_PER_GROUP(sb) - 10)
+               len = EXT4_CLUSTERS_PER_GROUP(sb) - 10;
 
        /* start searching from the goal */
        goal = ar->goal;
@@ -4019,18 +4094,15 @@ ext4_mb_initialize_context(struct ext4_allocation_context *ac,
 
        /* set up allocation goals */
        memset(ac, 0, sizeof(struct ext4_allocation_context));
-       ac->ac_b_ex.fe_logical = ar->logical;
+       ac->ac_b_ex.fe_logical = EXT4_LBLK_CMASK(sbi, ar->logical);
        ac->ac_status = AC_STATUS_CONTINUE;
        ac->ac_sb = sb;
        ac->ac_inode = ar->inode;
-       ac->ac_o_ex.fe_logical = ar->logical;
+       ac->ac_o_ex.fe_logical = ac->ac_b_ex.fe_logical;
        ac->ac_o_ex.fe_group = group;
        ac->ac_o_ex.fe_start = block;
        ac->ac_o_ex.fe_len = len;
-       ac->ac_g_ex.fe_logical = ar->logical;
-       ac->ac_g_ex.fe_group = group;
-       ac->ac_g_ex.fe_start = block;
-       ac->ac_g_ex.fe_len = len;
+       ac->ac_g_ex = ac->ac_o_ex;
        ac->ac_flags = ar->flags;
 
        /* we have to define context: we'll we work with a file or
@@ -4142,7 +4214,7 @@ static void ext4_mb_add_n_trim(struct ext4_allocation_context *ac)
                /* The max size of hash table is PREALLOC_TB_SIZE */
                order = PREALLOC_TB_SIZE - 1;
        /* Add the prealloc space to lg */
-       rcu_read_lock();
+       spin_lock(&lg->lg_prealloc_lock);
        list_for_each_entry_rcu(tmp_pa, &lg->lg_prealloc_list[order],
                                                pa_inode_list) {
                spin_lock(&tmp_pa->pa_lock);
@@ -4166,12 +4238,12 @@ static void ext4_mb_add_n_trim(struct ext4_allocation_context *ac)
        if (!added)
                list_add_tail_rcu(&pa->pa_inode_list,
                                        &lg->lg_prealloc_list[order]);
-       rcu_read_unlock();
+       spin_unlock(&lg->lg_prealloc_lock);
 
        /* Now trim the list to be not more than 8 elements */
        if (lg_prealloc_count > 8) {
                ext4_mb_discard_lg_preallocations(sb, lg,
-                                               order, lg_prealloc_count);
+                                                 order, lg_prealloc_count);
                return;
        }
        return ;
@@ -4182,13 +4254,14 @@ static void ext4_mb_add_n_trim(struct ext4_allocation_context *ac)
  */
 static int ext4_mb_release_context(struct ext4_allocation_context *ac)
 {
+       struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
        struct ext4_prealloc_space *pa = ac->ac_pa;
        if (pa) {
                if (pa->pa_type == MB_GROUP_PA) {
                        /* see comment in ext4_mb_use_group_pa() */
                        spin_lock(&pa->pa_lock);
-                       pa->pa_pstart += ac->ac_b_ex.fe_len;
-                       pa->pa_lstart += ac->ac_b_ex.fe_len;
+                       pa->pa_pstart += EXT4_C2B(sbi, ac->ac_b_ex.fe_len);
+                       pa->pa_lstart += EXT4_C2B(sbi, ac->ac_b_ex.fe_len);
                        pa->pa_free -= ac->ac_b_ex.fe_len;
                        pa->pa_len -= ac->ac_b_ex.fe_len;
                        spin_unlock(&pa->pa_lock);
@@ -4249,13 +4322,17 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
        struct super_block *sb;
        ext4_fsblk_t block = 0;
        unsigned int inquota = 0;
-       unsigned int reserv_blks = 0;
+       unsigned int reserv_clstrs = 0;
 
        sb = ar->inode->i_sb;
        sbi = EXT4_SB(sb);
 
        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
@@ -4269,7 +4346,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();
@@ -4279,12 +4356,14 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
                        *errp = -ENOSPC;
                        return 0;
                }
-               reserv_blks = ar->len;
+               reserv_clstrs = ar->len;
                if (ar->flags & EXT4_MB_USE_ROOT_BLOCKS) {
-                       dquot_alloc_block_nofail(ar->inode, ar->len);
+                       dquot_alloc_block_nofail(ar->inode,
+                                                EXT4_C2B(sbi, ar->len));
                } else {
                        while (ar->len &&
-                               dquot_alloc_block(ar->inode, ar->len)) {
+                               dquot_alloc_block(ar->inode,
+                                                 EXT4_C2B(sbi, ar->len))) {
 
                                ar->flags |= EXT4_MB_HINT_NOPREALLOC;
                                ar->len--;
@@ -4328,19 +4407,8 @@ repeat:
                        ext4_mb_new_preallocation(ac);
        }
        if (likely(ac->ac_status == AC_STATUS_FOUND)) {
-               *errp = ext4_mb_mark_diskspace_used(ac, handle, reserv_blks);
-               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)
+               *errp = ext4_mb_mark_diskspace_used(ac, handle, reserv_clstrs);
+               if (*errp)
                errout:
                        ext4_discard_allocated_blocks(ac);
                else {
@@ -4364,13 +4432,13 @@ out:
        if (ac)
                kmem_cache_free(ext4_ac_cachep, ac);
        if (inquota && ar->len < inquota)
-               dquot_free_block(ar->inode, inquota - ar->len);
+               dquot_free_block(ar->inode, EXT4_C2B(sbi, inquota - ar->len));
        if (!ar->len) {
                if (!ext4_test_inode_state(ar->inode,
                                           EXT4_STATE_DELALLOC_RESERVED))
                        /* release all the reserved blocks if non delalloc */
-                       percpu_counter_sub(&sbi->s_dirtyblocks_counter,
-                                               reserv_blks);
+                       percpu_counter_sub(&sbi->s_dirtyclusters_counter,
+                                               reserv_clstrs);
        }
 
        trace_ext4_allocate_blocks(ar, (unsigned long long)block);
@@ -4388,7 +4456,7 @@ static int can_merge(struct ext4_free_data *entry1,
 {
        if ((entry1->t_tid == entry2->t_tid) &&
            (entry1->group == entry2->group) &&
-           ((entry1->start_blk + entry1->count) == entry2->start_blk))
+           ((entry1->start_cluster + entry1->count) == entry2->start_cluster))
                return 1;
        return 0;
 }
@@ -4398,7 +4466,7 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
                      struct ext4_free_data *new_entry)
 {
        ext4_group_t group = e4b->bd_group;
-       ext4_grpblk_t block;
+       ext4_grpblk_t cluster;
        struct ext4_free_data *entry;
        struct ext4_group_info *db = e4b->bd_info;
        struct super_block *sb = e4b->bd_sb;
@@ -4411,7 +4479,7 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
        BUG_ON(e4b->bd_buddy_page == NULL);
 
        new_node = &new_entry->node;
-       block = new_entry->start_blk;
+       cluster = new_entry->start_cluster;
 
        if (!*n) {
                /* first free block exent. We need to
@@ -4425,13 +4493,14 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
        while (*n) {
                parent = *n;
                entry = rb_entry(parent, struct ext4_free_data, node);
-               if (block < entry->start_blk)
+               if (cluster < entry->start_cluster)
                        n = &(*n)->rb_left;
-               else if (block >= (entry->start_blk + entry->count))
+               else if (cluster >= (entry->start_cluster + entry->count))
                        n = &(*n)->rb_right;
                else {
                        ext4_grp_locked_error(sb, group, 0,
-                               ext4_group_first_block_no(sb, group) + block,
+                               ext4_group_first_block_no(sb, group) +
+                               EXT4_C2B(sbi, cluster),
                                "Block already on to-be-freed list");
                        return 0;
                }
@@ -4445,7 +4514,7 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
        if (node) {
                entry = rb_entry(node, struct ext4_free_data, node);
                if (can_merge(entry, new_entry)) {
-                       new_entry->start_blk = entry->start_blk;
+                       new_entry->start_cluster = entry->start_cluster;
                        new_entry->count += entry->count;
                        rb_erase(node, &(db->bb_free_root));
                        spin_lock(&sbi->s_md_lock);
@@ -4496,6 +4565,7 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode,
        ext4_group_t block_group;
        struct ext4_sb_info *sbi;
        struct ext4_buddy e4b;
+       unsigned int count_clusters;
        int err = 0;
        int ret;
 
@@ -4544,6 +4614,38 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode,
        if (!ext4_should_writeback_data(inode))
                flags |= EXT4_FREE_BLOCKS_METADATA;
 
+       /*
+        * If the extent to be freed does not begin on a cluster
+        * boundary, we need to deal with partial clusters at the
+        * beginning and end of the extent.  Normally we will free
+        * blocks at the beginning or the end unless we are explicitly
+        * requested to avoid doing so.
+        */
+       overflow = EXT4_PBLK_COFF(sbi, block);
+       if (overflow) {
+               if (flags & EXT4_FREE_BLOCKS_NOFREE_FIRST_CLUSTER) {
+                       overflow = sbi->s_cluster_ratio - overflow;
+                       block += overflow;
+                       if (count > overflow)
+                               count -= overflow;
+                       else
+                               return;
+               } else {
+                       block -= overflow;
+                       count += overflow;
+               }
+       }
+       overflow = EXT4_LBLK_COFF(sbi, count);
+       if (overflow) {
+               if (flags & EXT4_FREE_BLOCKS_NOFREE_LAST_CLUSTER) {
+                       if (count > overflow)
+                               count -= overflow;
+                       else
+                               return;
+               } else
+                       count += sbi->s_cluster_ratio - overflow;
+       }
+
 do_more:
        overflow = 0;
        ext4_get_group_no_and_offset(sb, block, &block_group, &bit);
@@ -4552,10 +4654,12 @@ do_more:
         * Check to see if we are freeing blocks across a group
         * boundary.
         */
-       if (bit + count > EXT4_BLOCKS_PER_GROUP(sb)) {
-               overflow = bit + count - EXT4_BLOCKS_PER_GROUP(sb);
+       if (EXT4_C2B(sbi, bit) + count > EXT4_BLOCKS_PER_GROUP(sb)) {
+               overflow = EXT4_C2B(sbi, bit) + count -
+                       EXT4_BLOCKS_PER_GROUP(sb);
                count -= overflow;
        }
+       count_clusters = EXT4_NUM_B2C(sbi, count);
        bitmap_bh = ext4_read_block_bitmap(sb, block_group);
        if (!bitmap_bh) {
                err = -EIO;
@@ -4570,9 +4674,9 @@ do_more:
        if (in_range(ext4_block_bitmap(sb, gdp), block, count) ||
            in_range(ext4_inode_bitmap(sb, gdp), block, count) ||
            in_range(block, ext4_inode_table(sb, gdp),
-                     EXT4_SB(sb)->s_itb_per_group) ||
+                    EXT4_SB(sb)->s_itb_per_group) ||
            in_range(block + count - 1, ext4_inode_table(sb, gdp),
-                     EXT4_SB(sb)->s_itb_per_group)) {
+                    EXT4_SB(sb)->s_itb_per_group)) {
 
                ext4_error(sb, "Freeing blocks in system zone - "
                           "Block = %llu, count = %lu", block, count);
@@ -4597,11 +4701,11 @@ do_more:
 #ifdef AGGRESSIVE_CHECK
        {
                int i;
-               for (i = 0; i < count; i++)
+               for (i = 0; i < count_clusters; i++)
                        BUG_ON(!mb_test_bit(bit + i, bitmap_bh->b_data));
        }
 #endif
-       trace_ext4_mballoc_free(sb, inode, block_group, bit, count);
+       trace_ext4_mballoc_free(sb, inode, block_group, bit, count_clusters);
 
        err = ext4_mb_load_buddy(sb, block_group, &e4b);
        if (err)
@@ -4612,19 +4716,19 @@ 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.
                 */
-               new_entry = kmem_cache_alloc(ext4_free_ext_cachep, GFP_NOFS);
-               if (!new_entry) {
-                       err = -ENOMEM;
-                       goto error_return;
-               }
-               new_entry->start_blk = bit;
+               new_entry = kmem_cache_alloc(ext4_free_ext_cachep,
+                               GFP_NOFS|__GFP_NOFAIL);
+               new_entry->start_cluster = bit;
                new_entry->group  = block_group;
-               new_entry->count = count;
+               new_entry->count = count_clusters;
                new_entry->t_tid = handle->h_transaction->t_tid;
 
                ext4_lock_group(sb, block_group);
-               mb_clear_bits(bitmap_bh->b_data, bit, count);
+               mb_clear_bits(bitmap_bh->b_data, bit, count_clusters);
                ext4_mb_free_metadata(handle, &e4b, new_entry);
        } else {
                /* need to update group_info->bb_free and bitmap
@@ -4632,25 +4736,29 @@ do_more:
                 * them with group lock_held
                 */
                ext4_lock_group(sb, block_group);
-               mb_clear_bits(bitmap_bh->b_data, bit, count);
-               mb_free_blocks(inode, &e4b, bit, count);
+               mb_clear_bits(bitmap_bh->b_data, bit, count_clusters);
+               mb_free_blocks(inode, &e4b, bit, count_clusters);
        }
 
-       ret = ext4_free_blks_count(sb, gdp) + count;
-       ext4_free_blks_set(sb, gdp, ret);
+       ret = ext4_free_group_clusters(sb, gdp) + count_clusters;
+       ext4_free_group_clusters_set(sb, gdp, ret);
        gdp->bg_checksum = ext4_group_desc_csum(sbi, block_group, gdp);
        ext4_unlock_group(sb, block_group);
-       percpu_counter_add(&sbi->s_freeblocks_counter, count);
+       percpu_counter_add(&sbi->s_freeclusters_counter, count_clusters);
 
        if (sbi->s_log_groups_per_flex) {
                ext4_group_t flex_group = ext4_flex_group(sbi, block_group);
-               atomic_add(count, &sbi->s_flex_groups[flex_group].free_blocks);
+               atomic64_add(count_clusters,
+                            &sbi->s_flex_groups[flex_group].free_clusters);
        }
 
        ext4_mb_unload_buddy(&e4b);
 
        freed += count;
 
+       if (!(flags & EXT4_FREE_BLOCKS_NO_QUOT_UPDATE))
+               dquot_free_block(inode, EXT4_C2B(sbi, count_clusters));
+
        /* We dirtied the bitmap block */
        BUFFER_TRACE(bitmap_bh, "dirtied bitmap block");
        err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
@@ -4669,8 +4777,6 @@ do_more:
        }
        ext4_mark_super_dirty(sb);
 error_return:
-       if (freed && !(flags & EXT4_FREE_BLOCKS_NO_QUOT_UPDATE))
-               dquot_free_block(inode, freed);
        brelse(bitmap_bh);
        ext4_std_error(sb, err);
        return;
@@ -4778,16 +4884,17 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb,
        ext4_lock_group(sb, block_group);
        mb_clear_bits(bitmap_bh->b_data, bit, count);
        mb_free_blocks(NULL, &e4b, bit, count);
-       blk_free_count = blocks_freed + ext4_free_blks_count(sb, desc);
-       ext4_free_blks_set(sb, desc, blk_free_count);
+       blk_free_count = blocks_freed + ext4_free_group_clusters(sb, desc);
+       ext4_free_group_clusters_set(sb, desc, blk_free_count);
        desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc);
        ext4_unlock_group(sb, block_group);
-       percpu_counter_add(&sbi->s_freeblocks_counter, blocks_freed);
+       percpu_counter_add(&sbi->s_freeclusters_counter,
+                          EXT4_NUM_B2C(sbi, blocks_freed));
 
        if (sbi->s_log_groups_per_flex) {
                ext4_group_t flex_group = ext4_flex_group(sbi, block_group);
-               atomic_add(blocks_freed,
-                          &sbi->s_flex_groups[flex_group].free_blocks);
+               atomic64_add(EXT4_NUM_B2C(sbi, blocks_freed),
+                            &sbi->s_flex_groups[flex_group].free_clusters);
        }
 
        ext4_mb_unload_buddy(&e4b);
@@ -4948,7 +5055,7 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
        struct ext4_group_info *grp;
        ext4_group_t first_group, last_group;
        ext4_group_t group, ngroups = ext4_get_groups_count(sb);
-       ext4_grpblk_t cnt = 0, first_block, last_block;
+       ext4_grpblk_t cnt = 0, first_cluster, last_cluster;
        uint64_t start, len, minlen, trimmed = 0;
        ext4_fsblk_t first_data_blk =
                        le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block);
@@ -4958,7 +5065,7 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
        len = range->len >> sb->s_blocksize_bits;
        minlen = range->minlen >> sb->s_blocksize_bits;
 
-       if (unlikely(minlen > EXT4_BLOCKS_PER_GROUP(sb)))
+       if (unlikely(minlen > EXT4_CLUSTERS_PER_GROUP(sb)))
                return -EINVAL;
        if (start + len <= first_data_blk)
                goto out;
@@ -4969,11 +5076,11 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
 
        /* Determine first and last group to examine based on start and len */
        ext4_get_group_no_and_offset(sb, (ext4_fsblk_t) start,
-                                    &first_group, &first_block);
+                                    &first_group, &first_cluster);
        ext4_get_group_no_and_offset(sb, (ext4_fsblk_t) (start + len),
-                                    &last_group, &last_block);
+                                    &last_group, &last_cluster);
        last_group = (last_group > ngroups - 1) ? ngroups - 1 : last_group;
-       last_block = EXT4_BLOCKS_PER_GROUP(sb);
+       last_cluster = EXT4_CLUSTERS_PER_GROUP(sb);
 
        if (first_group > last_group)
                return -EINVAL;
@@ -4993,20 +5100,20 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
                 * change it for the last group in which case start +
                 * len < EXT4_BLOCKS_PER_GROUP(sb).
                 */
-               if (first_block + len < EXT4_BLOCKS_PER_GROUP(sb))
-                       last_block = first_block + len;
-               len -= last_block - first_block;
+               if (first_cluster + len < EXT4_CLUSTERS_PER_GROUP(sb))
+                       last_cluster = first_cluster + len;
+               len -= last_cluster - first_cluster;
 
                if (grp->bb_free >= minlen) {
-                       cnt = ext4_trim_all_free(sb, group, first_block,
-                                               last_block, minlen);
+                       cnt = ext4_trim_all_free(sb, group, first_cluster,
+                                               last_cluster, minlen);
                        if (cnt < 0) {
                                ret = cnt;
                                break;
                        }
                }
                trimmed += cnt;
-               first_block = 0;
+               first_cluster = 0;
        }
        range->len = trimmed * sb->s_blocksize;