diff options
Diffstat (limited to 'fs/ext4/balloc.c')
-rw-r--r-- | fs/ext4/balloc.c | 28 |
1 files changed, 13 insertions, 15 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 53c72ad85877..e2126d70dff5 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/buffer_head.h> | 19 | #include <linux/buffer_head.h> |
20 | #include "ext4.h" | 20 | #include "ext4.h" |
21 | #include "ext4_jbd2.h" | 21 | #include "ext4_jbd2.h" |
22 | #include "group.h" | ||
23 | #include "mballoc.h" | 22 | #include "mballoc.h" |
24 | 23 | ||
25 | /* | 24 | /* |
@@ -88,6 +87,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, | |||
88 | ext4_group_t block_group, struct ext4_group_desc *gdp) | 87 | ext4_group_t block_group, struct ext4_group_desc *gdp) |
89 | { | 88 | { |
90 | int bit, bit_max; | 89 | int bit, bit_max; |
90 | ext4_group_t ngroups = ext4_get_groups_count(sb); | ||
91 | unsigned free_blocks, group_blocks; | 91 | unsigned free_blocks, group_blocks; |
92 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 92 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
93 | 93 | ||
@@ -123,7 +123,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, | |||
123 | bit_max += ext4_bg_num_gdb(sb, block_group); | 123 | bit_max += ext4_bg_num_gdb(sb, block_group); |
124 | } | 124 | } |
125 | 125 | ||
126 | if (block_group == sbi->s_groups_count - 1) { | 126 | if (block_group == ngroups - 1) { |
127 | /* | 127 | /* |
128 | * Even though mke2fs always initialize first and last group | 128 | * Even though mke2fs always initialize first and last group |
129 | * if some other tool enabled the EXT4_BG_BLOCK_UNINIT we need | 129 | * if some other tool enabled the EXT4_BG_BLOCK_UNINIT we need |
@@ -131,7 +131,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, | |||
131 | */ | 131 | */ |
132 | group_blocks = ext4_blocks_count(sbi->s_es) - | 132 | group_blocks = ext4_blocks_count(sbi->s_es) - |
133 | le32_to_cpu(sbi->s_es->s_first_data_block) - | 133 | le32_to_cpu(sbi->s_es->s_first_data_block) - |
134 | (EXT4_BLOCKS_PER_GROUP(sb) * (sbi->s_groups_count - 1)); | 134 | (EXT4_BLOCKS_PER_GROUP(sb) * (ngroups - 1)); |
135 | } else { | 135 | } else { |
136 | group_blocks = EXT4_BLOCKS_PER_GROUP(sb); | 136 | group_blocks = EXT4_BLOCKS_PER_GROUP(sb); |
137 | } | 137 | } |
@@ -205,18 +205,18 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb, | |||
205 | { | 205 | { |
206 | unsigned int group_desc; | 206 | unsigned int group_desc; |
207 | unsigned int offset; | 207 | unsigned int offset; |
208 | ext4_group_t ngroups = ext4_get_groups_count(sb); | ||
208 | struct ext4_group_desc *desc; | 209 | struct ext4_group_desc *desc; |
209 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 210 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
210 | 211 | ||
211 | if (block_group >= sbi->s_groups_count) { | 212 | if (block_group >= ngroups) { |
212 | ext4_error(sb, "ext4_get_group_desc", | 213 | ext4_error(sb, "ext4_get_group_desc", |
213 | "block_group >= groups_count - " | 214 | "block_group >= groups_count - " |
214 | "block_group = %u, groups_count = %u", | 215 | "block_group = %u, groups_count = %u", |
215 | block_group, sbi->s_groups_count); | 216 | block_group, ngroups); |
216 | 217 | ||
217 | return NULL; | 218 | return NULL; |
218 | } | 219 | } |
219 | smp_rmb(); | ||
220 | 220 | ||
221 | group_desc = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb); | 221 | group_desc = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb); |
222 | offset = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1); | 222 | offset = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1); |
@@ -326,16 +326,16 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group) | |||
326 | unlock_buffer(bh); | 326 | unlock_buffer(bh); |
327 | return bh; | 327 | return bh; |
328 | } | 328 | } |
329 | spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group)); | 329 | ext4_lock_group(sb, block_group); |
330 | if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { | 330 | if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { |
331 | ext4_init_block_bitmap(sb, bh, block_group, desc); | 331 | ext4_init_block_bitmap(sb, bh, block_group, desc); |
332 | set_bitmap_uptodate(bh); | 332 | set_bitmap_uptodate(bh); |
333 | set_buffer_uptodate(bh); | 333 | set_buffer_uptodate(bh); |
334 | spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); | 334 | ext4_unlock_group(sb, block_group); |
335 | unlock_buffer(bh); | 335 | unlock_buffer(bh); |
336 | return bh; | 336 | return bh; |
337 | } | 337 | } |
338 | spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); | 338 | ext4_unlock_group(sb, block_group); |
339 | if (buffer_uptodate(bh)) { | 339 | if (buffer_uptodate(bh)) { |
340 | /* | 340 | /* |
341 | * if not uninit if bh is uptodate, | 341 | * if not uninit if bh is uptodate, |
@@ -451,7 +451,7 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb, | |||
451 | down_write(&grp->alloc_sem); | 451 | down_write(&grp->alloc_sem); |
452 | for (i = 0, blocks_freed = 0; i < count; i++) { | 452 | for (i = 0, blocks_freed = 0; i < count; i++) { |
453 | BUFFER_TRACE(bitmap_bh, "clear bit"); | 453 | BUFFER_TRACE(bitmap_bh, "clear bit"); |
454 | if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group), | 454 | if (!ext4_clear_bit_atomic(ext4_group_lock_ptr(sb, block_group), |
455 | bit + i, bitmap_bh->b_data)) { | 455 | bit + i, bitmap_bh->b_data)) { |
456 | ext4_error(sb, __func__, | 456 | ext4_error(sb, __func__, |
457 | "bit already cleared for block %llu", | 457 | "bit already cleared for block %llu", |
@@ -461,11 +461,11 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb, | |||
461 | blocks_freed++; | 461 | blocks_freed++; |
462 | } | 462 | } |
463 | } | 463 | } |
464 | spin_lock(sb_bgl_lock(sbi, block_group)); | 464 | ext4_lock_group(sb, block_group); |
465 | blk_free_count = blocks_freed + ext4_free_blks_count(sb, desc); | 465 | blk_free_count = blocks_freed + ext4_free_blks_count(sb, desc); |
466 | ext4_free_blks_set(sb, desc, blk_free_count); | 466 | ext4_free_blks_set(sb, desc, blk_free_count); |
467 | desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc); | 467 | desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc); |
468 | spin_unlock(sb_bgl_lock(sbi, block_group)); | 468 | ext4_unlock_group(sb, block_group); |
469 | percpu_counter_add(&sbi->s_freeblocks_counter, blocks_freed); | 469 | percpu_counter_add(&sbi->s_freeblocks_counter, blocks_freed); |
470 | 470 | ||
471 | if (sbi->s_log_groups_per_flex) { | 471 | if (sbi->s_log_groups_per_flex) { |
@@ -665,7 +665,7 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb) | |||
665 | ext4_fsblk_t desc_count; | 665 | ext4_fsblk_t desc_count; |
666 | struct ext4_group_desc *gdp; | 666 | struct ext4_group_desc *gdp; |
667 | ext4_group_t i; | 667 | ext4_group_t i; |
668 | ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count; | 668 | ext4_group_t ngroups = ext4_get_groups_count(sb); |
669 | #ifdef EXT4FS_DEBUG | 669 | #ifdef EXT4FS_DEBUG |
670 | struct ext4_super_block *es; | 670 | struct ext4_super_block *es; |
671 | ext4_fsblk_t bitmap_count; | 671 | ext4_fsblk_t bitmap_count; |
@@ -677,7 +677,6 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb) | |||
677 | bitmap_count = 0; | 677 | bitmap_count = 0; |
678 | gdp = NULL; | 678 | gdp = NULL; |
679 | 679 | ||
680 | smp_rmb(); | ||
681 | for (i = 0; i < ngroups; i++) { | 680 | for (i = 0; i < ngroups; i++) { |
682 | gdp = ext4_get_group_desc(sb, i, NULL); | 681 | gdp = ext4_get_group_desc(sb, i, NULL); |
683 | if (!gdp) | 682 | if (!gdp) |
@@ -700,7 +699,6 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb) | |||
700 | return bitmap_count; | 699 | return bitmap_count; |
701 | #else | 700 | #else |
702 | desc_count = 0; | 701 | desc_count = 0; |
703 | smp_rmb(); | ||
704 | for (i = 0; i < ngroups; i++) { | 702 | for (i = 0; i < ngroups; i++) { |
705 | gdp = ext4_get_group_desc(sb, i, NULL); | 703 | gdp = ext4_get_group_desc(sb, i, NULL); |
706 | if (!gdp) | 704 | if (!gdp) |