]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/ext4/mballoc.c
Merge tag 'for-v3.17' of git://git.infradead.org/battery-2.6
[karo-tx-linux.git] / fs / ext4 / mballoc.c
index 7f72f50a8fa764e80a91cfaea969297f65a8b615..956027711faf29aa52669d27061794840e332e08 100644 (file)
@@ -752,8 +752,8 @@ void ext4_mb_generate_buddy(struct super_block *sb,
 
        if (free != grp->bb_free) {
                ext4_grp_locked_error(sb, group, 0, 0,
-                                     "%u clusters in bitmap, %u in gd; "
-                                     "block bitmap corrupt.",
+                                     "block bitmap and bg descriptor "
+                                     "inconsistent: %u vs %u free clusters",
                                      free, grp->bb_free);
                /*
                 * If we intend to continue, we consider group descriptor
@@ -3075,8 +3075,9 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
                                                        (23 - bsbits)) << 23;
                size = 8 * 1024 * 1024;
        } else {
-               start_off = (loff_t)ac->ac_o_ex.fe_logical << bsbits;
-               size      = ac->ac_o_ex.fe_len << bsbits;
+               start_off = (loff_t) ac->ac_o_ex.fe_logical << bsbits;
+               size      = (loff_t) EXT4_C2B(EXT4_SB(ac->ac_sb),
+                                             ac->ac_o_ex.fe_len) << bsbits;
        }
        size = size >> bsbits;
        start = start_off >> bsbits;
@@ -3216,8 +3217,27 @@ 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;
+       struct ext4_buddy e4b;
+       int err;
 
-       if (pa && pa->pa_type == MB_INODE_PA)
+       if (pa == NULL) {
+               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);
+               return;
+       }
+       if (pa->pa_type == MB_INODE_PA)
                pa->pa_free += ac->ac_b_ex.fe_len;
 }
 
@@ -4627,7 +4647,6 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode,
        struct buffer_head *gd_bh;
        ext4_group_t block_group;
        struct ext4_sb_info *sbi;
-       struct ext4_inode_info *ei = EXT4_I(inode);
        struct ext4_buddy e4b;
        unsigned int count_clusters;
        int err = 0;
@@ -4838,19 +4857,7 @@ do_more:
                             &sbi->s_flex_groups[flex_group].free_clusters);
        }
 
-       if (flags & EXT4_FREE_BLOCKS_RESERVE && ei->i_reserved_data_blocks) {
-               percpu_counter_add(&sbi->s_dirtyclusters_counter,
-                                  count_clusters);
-               spin_lock(&ei->i_block_reservation_lock);
-               if (flags & EXT4_FREE_BLOCKS_METADATA)
-                       ei->i_reserved_meta_blocks += count_clusters;
-               else
-                       ei->i_reserved_data_blocks += count_clusters;
-               spin_unlock(&ei->i_block_reservation_lock);
-               if (!(flags & EXT4_FREE_BLOCKS_NO_QUOT_UPDATE))
-                       dquot_reclaim_block(inode,
-                                       EXT4_C2B(sbi, count_clusters));
-       } else if (!(flags & EXT4_FREE_BLOCKS_NO_QUOT_UPDATE))
+       if (!(flags & EXT4_FREE_BLOCKS_NO_QUOT_UPDATE))
                dquot_free_block(inode, EXT4_C2B(sbi, count_clusters));
        percpu_counter_add(&sbi->s_freeclusters_counter, count_clusters);