]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - fs/ext4/mballoc.c
ext4: mark the blocks/inode bitmap beyond end of group as used
[mv-sheeva.git] / fs / ext4 / mballoc.c
index d559a03f3eb2834f937c941741d34c0925135aee..7d7f6f91d555ab9e584c10d0d6f061a9dff8267a 100644 (file)
@@ -794,22 +794,42 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
                if (bh[i] == NULL)
                        goto out;
 
-               if (buffer_uptodate(bh[i]) &&
-                   !(desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)))
+               if (bitmap_uptodate(bh[i]))
                        continue;
 
                lock_buffer(bh[i]);
+               if (bitmap_uptodate(bh[i])) {
+                       unlock_buffer(bh[i]);
+                       continue;
+               }
                spin_lock(sb_bgl_lock(EXT4_SB(sb), first_group + i));
                if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
                        ext4_init_block_bitmap(sb, bh[i],
                                                first_group + i, desc);
+                       set_bitmap_uptodate(bh[i]);
                        set_buffer_uptodate(bh[i]);
-                       unlock_buffer(bh[i]);
                        spin_unlock(sb_bgl_lock(EXT4_SB(sb), first_group + i));
+                       unlock_buffer(bh[i]);
                        continue;
                }
                spin_unlock(sb_bgl_lock(EXT4_SB(sb), first_group + i));
+               if (buffer_uptodate(bh[i])) {
+                       /*
+                        * if not uninit if bh is uptodate,
+                        * bitmap is also uptodate
+                        */
+                       set_bitmap_uptodate(bh[i]);
+                       unlock_buffer(bh[i]);
+                       continue;
+               }
                get_bh(bh[i]);
+               /*
+                * submit the buffer_head for read. We can
+                * safely mark the bitmap as uptodate now.
+                * We do it here so the bitmap uptodate bit
+                * get set with buffer lock held.
+                */
+               set_bitmap_uptodate(bh[i]);
                bh[i]->b_end_io = end_buffer_read_sync;
                submit_bh(READ, bh[i]);
                mb_debug("read bitmap for group %u\n", first_group + i);
@@ -2515,7 +2535,7 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group,
                        ext4_free_blocks_after_init(sb, group, desc);
        } else {
                meta_group_info[i]->bb_free =
-                       le16_to_cpu(desc->bg_free_blocks_count);
+                       ext4_free_blks_count(sb, desc);
        }
 
        INIT_LIST_HEAD(&meta_group_info[i]->bb_prealloc_list);
@@ -3018,8 +3038,8 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
            in_range(block + len - 1, ext4_inode_table(sb, gdp),
                     EXT4_SB(sb)->s_itb_per_group)) {
                ext4_error(sb, __func__,
-                          "Allocating block in system zone - block = %llu",
-                          block);
+                          "Allocating block %llu in system zone of %d group\n",
+                          block, ac->ac_b_ex.fe_group);
                /* File system mounted not to panic on error
                 * Fix the bitmap and repeat the block allocation
                 * We leak some of the blocks here.
@@ -3046,12 +3066,12 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
                                ac->ac_b_ex.fe_start, 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);
-               gdp->bg_free_blocks_count =
-                       cpu_to_le16(ext4_free_blocks_after_init(sb,
-                                               ac->ac_b_ex.fe_group,
-                                               gdp));
+               ext4_free_blks_set(sb, gdp,
+                                       ext4_free_blocks_after_init(sb,
+                                       ac->ac_b_ex.fe_group, gdp));
        }
-       le16_add_cpu(&gdp->bg_free_blocks_count, -ac->ac_b_ex.fe_len);
+       len = ext4_free_blks_count(sb, gdp) - ac->ac_b_ex.fe_len;
+       ext4_free_blks_set(sb, gdp, len);
        gdp->bg_checksum = ext4_group_desc_csum(sbi, ac->ac_b_ex.fe_group, gdp);
        spin_unlock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group));
        percpu_counter_sub(&sbi->s_freeblocks_counter, ac->ac_b_ex.fe_len);
@@ -4823,7 +4843,8 @@ do_more:
        }
 
        spin_lock(sb_bgl_lock(sbi, block_group));
-       le16_add_cpu(&gdp->bg_free_blocks_count, count);
+       ret = ext4_free_blks_count(sb, gdp) + count;
+       ext4_free_blks_set(sb, gdp, ret);
        gdp->bg_checksum = ext4_group_desc_csum(sbi, block_group, gdp);
        spin_unlock(sb_bgl_lock(sbi, block_group));
        percpu_counter_add(&sbi->s_freeblocks_counter, count);