aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/balloc.c
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2009-01-05 21:36:19 -0500
committerTheodore Ts'o <tytso@mit.edu>2009-01-05 21:36:19 -0500
commit920313a726e04fef0f2c0bcb04ad8229c0e700d8 (patch)
tree7e7644a2fd48586ec2f455e56525565174798e4a /fs/ext4/balloc.c
parente21675d4b63975d09eb75c443c48ebe663d23e18 (diff)
ext4: Use EXT4_GROUP_INFO_NEED_INIT_BIT during resize
The new groups added during resize are flagged as need_init group. Make sure we properly initialize these groups. When we have block size < page size and we are adding new groups the page may still be marked uptodate even though we haven't initialized the group. While forcing the init of buddy cache we need to make sure other groups part of the same page of buddy cache is not using the cache. group_info->alloc_sem is added to ensure the same. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> cc: stable@kernel.org
Diffstat (limited to 'fs/ext4/balloc.c')
-rw-r--r--fs/ext4/balloc.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index c54192e2384e..404d81cc9157 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -381,6 +381,7 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
381 ext4_debug("Adding block(s) %llu-%llu\n", block, block + count - 1); 381 ext4_debug("Adding block(s) %llu-%llu\n", block, block + count - 1);
382 382
383 ext4_get_group_no_and_offset(sb, block, &block_group, &bit); 383 ext4_get_group_no_and_offset(sb, block, &block_group, &bit);
384 grp = ext4_get_group_info(sb, block_group);
384 /* 385 /*
385 * Check to see if we are freeing blocks across a group 386 * Check to see if we are freeing blocks across a group
386 * boundary. 387 * boundary.
@@ -425,7 +426,11 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
425 err = ext4_journal_get_write_access(handle, gd_bh); 426 err = ext4_journal_get_write_access(handle, gd_bh);
426 if (err) 427 if (err)
427 goto error_return; 428 goto error_return;
428 429 /*
430 * make sure we don't allow a parallel init on other groups in the
431 * same buddy cache
432 */
433 down_write(&grp->alloc_sem);
429 for (i = 0, blocks_freed = 0; i < count; i++) { 434 for (i = 0, blocks_freed = 0; i < count; i++) {
430 BUFFER_TRACE(bitmap_bh, "clear bit"); 435 BUFFER_TRACE(bitmap_bh, "clear bit");
431 if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group), 436 if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group),
@@ -450,6 +455,13 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
450 sbi->s_flex_groups[flex_group].free_blocks += blocks_freed; 455 sbi->s_flex_groups[flex_group].free_blocks += blocks_freed;
451 spin_unlock(sb_bgl_lock(sbi, flex_group)); 456 spin_unlock(sb_bgl_lock(sbi, flex_group));
452 } 457 }
458 /*
459 * request to reload the buddy with the
460 * new bitmap information
461 */
462 set_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &(grp->bb_state));
463 ext4_mb_update_group_info(grp, blocks_freed);
464 up_write(&grp->alloc_sem);
453 465
454 /* We dirtied the bitmap block */ 466 /* We dirtied the bitmap block */
455 BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); 467 BUFFER_TRACE(bitmap_bh, "dirtied bitmap block");
@@ -461,13 +473,6 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
461 if (!err) 473 if (!err)
462 err = ret; 474 err = ret;
463 sb->s_dirt = 1; 475 sb->s_dirt = 1;
464 /*
465 * request to reload the buddy with the
466 * new bitmap information
467 */
468 grp = ext4_get_group_info(sb, block_group);
469 set_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &(grp->bb_state));
470 ext4_mb_update_group_info(grp, blocks_freed);
471 476
472error_return: 477error_return:
473 brelse(bitmap_bh); 478 brelse(bitmap_bh);