diff options
author | Amir Goldstein <amir73il@users.sf.net> | 2011-05-09 10:46:41 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2011-05-09 10:46:41 -0400 |
commit | 2846e82004a8d5ef0a63cd3209c84ea5cd796f11 (patch) | |
tree | 3b20c08ce64e918d4217bb95228fc597c63bf0e0 /fs/ext4 | |
parent | 66bb82798d9ff896271d13f5020f7fb9b7d88e1a (diff) |
ext4: move ext4_add_groupblocks() to mballoc.c
In preparation for the next patch, the function ext4_add_groupblocks()
is moved to mballoc.c, where it could use some static functions.
Signed-off-by: Amir Goldstein <amir73il@users.sf.net>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/balloc.c | 124 | ||||
-rw-r--r-- | fs/ext4/ext4.h | 4 | ||||
-rw-r--r-- | fs/ext4/mballoc.c | 124 |
3 files changed, 126 insertions, 126 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 9c6cd51c09e3..b2d10da505ef 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -362,130 +362,6 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group) | |||
362 | } | 362 | } |
363 | 363 | ||
364 | /** | 364 | /** |
365 | * ext4_add_groupblocks() -- Add given blocks to an existing group | ||
366 | * @handle: handle to this transaction | ||
367 | * @sb: super block | ||
368 | * @block: start physcial block to add to the block group | ||
369 | * @count: number of blocks to free | ||
370 | * | ||
371 | * This marks the blocks as free in the bitmap. We ask the | ||
372 | * mballoc to reload the buddy after this by setting group | ||
373 | * EXT4_GROUP_INFO_NEED_INIT_BIT flag | ||
374 | */ | ||
375 | void ext4_add_groupblocks(handle_t *handle, struct super_block *sb, | ||
376 | ext4_fsblk_t block, unsigned long count) | ||
377 | { | ||
378 | struct buffer_head *bitmap_bh = NULL; | ||
379 | struct buffer_head *gd_bh; | ||
380 | ext4_group_t block_group; | ||
381 | ext4_grpblk_t bit; | ||
382 | unsigned int i; | ||
383 | struct ext4_group_desc *desc; | ||
384 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
385 | int err = 0, ret, blk_free_count; | ||
386 | ext4_grpblk_t blocks_freed; | ||
387 | struct ext4_group_info *grp; | ||
388 | |||
389 | ext4_debug("Adding block(s) %llu-%llu\n", block, block + count - 1); | ||
390 | |||
391 | ext4_get_group_no_and_offset(sb, block, &block_group, &bit); | ||
392 | grp = ext4_get_group_info(sb, block_group); | ||
393 | /* | ||
394 | * Check to see if we are freeing blocks across a group | ||
395 | * boundary. | ||
396 | */ | ||
397 | if (bit + count > EXT4_BLOCKS_PER_GROUP(sb)) { | ||
398 | goto error_return; | ||
399 | } | ||
400 | bitmap_bh = ext4_read_block_bitmap(sb, block_group); | ||
401 | if (!bitmap_bh) | ||
402 | goto error_return; | ||
403 | desc = ext4_get_group_desc(sb, block_group, &gd_bh); | ||
404 | if (!desc) | ||
405 | goto error_return; | ||
406 | |||
407 | if (in_range(ext4_block_bitmap(sb, desc), block, count) || | ||
408 | in_range(ext4_inode_bitmap(sb, desc), block, count) || | ||
409 | in_range(block, ext4_inode_table(sb, desc), sbi->s_itb_per_group) || | ||
410 | in_range(block + count - 1, ext4_inode_table(sb, desc), | ||
411 | sbi->s_itb_per_group)) { | ||
412 | ext4_error(sb, "Adding blocks in system zones - " | ||
413 | "Block = %llu, count = %lu", | ||
414 | block, count); | ||
415 | goto error_return; | ||
416 | } | ||
417 | |||
418 | /* | ||
419 | * We are about to add blocks to the bitmap, | ||
420 | * so we need undo access. | ||
421 | */ | ||
422 | BUFFER_TRACE(bitmap_bh, "getting undo access"); | ||
423 | err = ext4_journal_get_undo_access(handle, bitmap_bh); | ||
424 | if (err) | ||
425 | goto error_return; | ||
426 | |||
427 | /* | ||
428 | * We are about to modify some metadata. Call the journal APIs | ||
429 | * to unshare ->b_data if a currently-committing transaction is | ||
430 | * using it | ||
431 | */ | ||
432 | BUFFER_TRACE(gd_bh, "get_write_access"); | ||
433 | err = ext4_journal_get_write_access(handle, gd_bh); | ||
434 | if (err) | ||
435 | goto error_return; | ||
436 | /* | ||
437 | * make sure we don't allow a parallel init on other groups in the | ||
438 | * same buddy cache | ||
439 | */ | ||
440 | down_write(&grp->alloc_sem); | ||
441 | for (i = 0, blocks_freed = 0; i < count; i++) { | ||
442 | BUFFER_TRACE(bitmap_bh, "clear bit"); | ||
443 | if (!ext4_clear_bit_atomic(ext4_group_lock_ptr(sb, block_group), | ||
444 | bit + i, bitmap_bh->b_data)) { | ||
445 | ext4_error(sb, "bit already cleared for block %llu", | ||
446 | (ext4_fsblk_t)(block + i)); | ||
447 | BUFFER_TRACE(bitmap_bh, "bit already cleared"); | ||
448 | } else { | ||
449 | blocks_freed++; | ||
450 | } | ||
451 | } | ||
452 | ext4_lock_group(sb, block_group); | ||
453 | blk_free_count = blocks_freed + ext4_free_blks_count(sb, desc); | ||
454 | ext4_free_blks_set(sb, desc, blk_free_count); | ||
455 | desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc); | ||
456 | ext4_unlock_group(sb, block_group); | ||
457 | percpu_counter_add(&sbi->s_freeblocks_counter, blocks_freed); | ||
458 | |||
459 | if (sbi->s_log_groups_per_flex) { | ||
460 | ext4_group_t flex_group = ext4_flex_group(sbi, block_group); | ||
461 | atomic_add(blocks_freed, | ||
462 | &sbi->s_flex_groups[flex_group].free_blocks); | ||
463 | } | ||
464 | /* | ||
465 | * request to reload the buddy with the | ||
466 | * new bitmap information | ||
467 | */ | ||
468 | set_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &(grp->bb_state)); | ||
469 | grp->bb_free += blocks_freed; | ||
470 | up_write(&grp->alloc_sem); | ||
471 | |||
472 | /* We dirtied the bitmap block */ | ||
473 | BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); | ||
474 | err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh); | ||
475 | |||
476 | /* And the group descriptor block */ | ||
477 | BUFFER_TRACE(gd_bh, "dirtied group descriptor block"); | ||
478 | ret = ext4_handle_dirty_metadata(handle, NULL, gd_bh); | ||
479 | if (!err) | ||
480 | err = ret; | ||
481 | |||
482 | error_return: | ||
483 | brelse(bitmap_bh); | ||
484 | ext4_std_error(sb, err); | ||
485 | return; | ||
486 | } | ||
487 | |||
488 | /** | ||
489 | * ext4_has_free_blocks() | 365 | * ext4_has_free_blocks() |
490 | * @sbi: in-core super block structure. | 366 | * @sbi: in-core super block structure. |
491 | * @nblocks: number of needed blocks | 367 | * @nblocks: number of needed blocks |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 076c5d212a3c..47986ae8dcec 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -1655,8 +1655,6 @@ extern unsigned long ext4_bg_num_gdb(struct super_block *sb, | |||
1655 | extern ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode, | 1655 | extern ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode, |
1656 | ext4_fsblk_t goal, unsigned long *count, int *errp); | 1656 | ext4_fsblk_t goal, unsigned long *count, int *errp); |
1657 | extern int ext4_claim_free_blocks(struct ext4_sb_info *sbi, s64 nblocks); | 1657 | extern int ext4_claim_free_blocks(struct ext4_sb_info *sbi, s64 nblocks); |
1658 | extern void ext4_add_groupblocks(handle_t *handle, struct super_block *sb, | ||
1659 | ext4_fsblk_t block, unsigned long count); | ||
1660 | extern ext4_fsblk_t ext4_count_free_blocks(struct super_block *); | 1658 | extern ext4_fsblk_t ext4_count_free_blocks(struct super_block *); |
1661 | extern void ext4_check_blocks_bitmap(struct super_block *); | 1659 | extern void ext4_check_blocks_bitmap(struct super_block *); |
1662 | extern struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb, | 1660 | extern struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb, |
@@ -1721,6 +1719,8 @@ extern void ext4_free_blocks(handle_t *handle, struct inode *inode, | |||
1721 | unsigned long count, int flags); | 1719 | unsigned long count, int flags); |
1722 | extern int ext4_mb_add_groupinfo(struct super_block *sb, | 1720 | extern int ext4_mb_add_groupinfo(struct super_block *sb, |
1723 | ext4_group_t i, struct ext4_group_desc *desc); | 1721 | ext4_group_t i, struct ext4_group_desc *desc); |
1722 | extern void ext4_add_groupblocks(handle_t *handle, struct super_block *sb, | ||
1723 | ext4_fsblk_t block, unsigned long count); | ||
1724 | extern int ext4_trim_fs(struct super_block *, struct fstrim_range *); | 1724 | extern int ext4_trim_fs(struct super_block *, struct fstrim_range *); |
1725 | 1725 | ||
1726 | /* inode.c */ | 1726 | /* inode.c */ |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 730c1a72a959..92aa05ddef66 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -4700,6 +4700,130 @@ error_return: | |||
4700 | } | 4700 | } |
4701 | 4701 | ||
4702 | /** | 4702 | /** |
4703 | * ext4_add_groupblocks() -- Add given blocks to an existing group | ||
4704 | * @handle: handle to this transaction | ||
4705 | * @sb: super block | ||
4706 | * @block: start physcial block to add to the block group | ||
4707 | * @count: number of blocks to free | ||
4708 | * | ||
4709 | * This marks the blocks as free in the bitmap. We ask the | ||
4710 | * mballoc to reload the buddy after this by setting group | ||
4711 | * EXT4_GROUP_INFO_NEED_INIT_BIT flag | ||
4712 | */ | ||
4713 | void ext4_add_groupblocks(handle_t *handle, struct super_block *sb, | ||
4714 | ext4_fsblk_t block, unsigned long count) | ||
4715 | { | ||
4716 | struct buffer_head *bitmap_bh = NULL; | ||
4717 | struct buffer_head *gd_bh; | ||
4718 | ext4_group_t block_group; | ||
4719 | ext4_grpblk_t bit; | ||
4720 | unsigned int i; | ||
4721 | struct ext4_group_desc *desc; | ||
4722 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
4723 | int err = 0, ret, blk_free_count; | ||
4724 | ext4_grpblk_t blocks_freed; | ||
4725 | struct ext4_group_info *grp; | ||
4726 | |||
4727 | ext4_debug("Adding block(s) %llu-%llu\n", block, block + count - 1); | ||
4728 | |||
4729 | ext4_get_group_no_and_offset(sb, block, &block_group, &bit); | ||
4730 | grp = ext4_get_group_info(sb, block_group); | ||
4731 | /* | ||
4732 | * Check to see if we are freeing blocks across a group | ||
4733 | * boundary. | ||
4734 | */ | ||
4735 | if (bit + count > EXT4_BLOCKS_PER_GROUP(sb)) { | ||
4736 | goto error_return; | ||
4737 | } | ||
4738 | bitmap_bh = ext4_read_block_bitmap(sb, block_group); | ||
4739 | if (!bitmap_bh) | ||
4740 | goto error_return; | ||
4741 | desc = ext4_get_group_desc(sb, block_group, &gd_bh); | ||
4742 | if (!desc) | ||
4743 | goto error_return; | ||
4744 | |||
4745 | if (in_range(ext4_block_bitmap(sb, desc), block, count) || | ||
4746 | in_range(ext4_inode_bitmap(sb, desc), block, count) || | ||
4747 | in_range(block, ext4_inode_table(sb, desc), sbi->s_itb_per_group) || | ||
4748 | in_range(block + count - 1, ext4_inode_table(sb, desc), | ||
4749 | sbi->s_itb_per_group)) { | ||
4750 | ext4_error(sb, "Adding blocks in system zones - " | ||
4751 | "Block = %llu, count = %lu", | ||
4752 | block, count); | ||
4753 | goto error_return; | ||
4754 | } | ||
4755 | |||
4756 | /* | ||
4757 | * We are about to add blocks to the bitmap, | ||
4758 | * so we need undo access. | ||
4759 | */ | ||
4760 | BUFFER_TRACE(bitmap_bh, "getting undo access"); | ||
4761 | err = ext4_journal_get_undo_access(handle, bitmap_bh); | ||
4762 | if (err) | ||
4763 | goto error_return; | ||
4764 | |||
4765 | /* | ||
4766 | * We are about to modify some metadata. Call the journal APIs | ||
4767 | * to unshare ->b_data if a currently-committing transaction is | ||
4768 | * using it | ||
4769 | */ | ||
4770 | BUFFER_TRACE(gd_bh, "get_write_access"); | ||
4771 | err = ext4_journal_get_write_access(handle, gd_bh); | ||
4772 | if (err) | ||
4773 | goto error_return; | ||
4774 | /* | ||
4775 | * make sure we don't allow a parallel init on other groups in the | ||
4776 | * same buddy cache | ||
4777 | */ | ||
4778 | down_write(&grp->alloc_sem); | ||
4779 | for (i = 0, blocks_freed = 0; i < count; i++) { | ||
4780 | BUFFER_TRACE(bitmap_bh, "clear bit"); | ||
4781 | if (!ext4_clear_bit_atomic(ext4_group_lock_ptr(sb, block_group), | ||
4782 | bit + i, bitmap_bh->b_data)) { | ||
4783 | ext4_error(sb, "bit already cleared for block %llu", | ||
4784 | (ext4_fsblk_t)(block + i)); | ||
4785 | BUFFER_TRACE(bitmap_bh, "bit already cleared"); | ||
4786 | } else { | ||
4787 | blocks_freed++; | ||
4788 | } | ||
4789 | } | ||
4790 | ext4_lock_group(sb, block_group); | ||
4791 | blk_free_count = blocks_freed + ext4_free_blks_count(sb, desc); | ||
4792 | ext4_free_blks_set(sb, desc, blk_free_count); | ||
4793 | desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc); | ||
4794 | ext4_unlock_group(sb, block_group); | ||
4795 | percpu_counter_add(&sbi->s_freeblocks_counter, blocks_freed); | ||
4796 | |||
4797 | if (sbi->s_log_groups_per_flex) { | ||
4798 | ext4_group_t flex_group = ext4_flex_group(sbi, block_group); | ||
4799 | atomic_add(blocks_freed, | ||
4800 | &sbi->s_flex_groups[flex_group].free_blocks); | ||
4801 | } | ||
4802 | /* | ||
4803 | * request to reload the buddy with the | ||
4804 | * new bitmap information | ||
4805 | */ | ||
4806 | set_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &(grp->bb_state)); | ||
4807 | grp->bb_free += blocks_freed; | ||
4808 | up_write(&grp->alloc_sem); | ||
4809 | |||
4810 | /* We dirtied the bitmap block */ | ||
4811 | BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); | ||
4812 | err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh); | ||
4813 | |||
4814 | /* And the group descriptor block */ | ||
4815 | BUFFER_TRACE(gd_bh, "dirtied group descriptor block"); | ||
4816 | ret = ext4_handle_dirty_metadata(handle, NULL, gd_bh); | ||
4817 | if (!err) | ||
4818 | err = ret; | ||
4819 | |||
4820 | error_return: | ||
4821 | brelse(bitmap_bh); | ||
4822 | ext4_std_error(sb, err); | ||
4823 | return; | ||
4824 | } | ||
4825 | |||
4826 | /** | ||
4703 | * ext4_trim_extent -- function to TRIM one single free extent in the group | 4827 | * ext4_trim_extent -- function to TRIM one single free extent in the group |
4704 | * @sb: super block for the file system | 4828 | * @sb: super block for the file system |
4705 | * @start: starting block of the free extent in the alloc. group | 4829 | * @start: starting block of the free extent in the alloc. group |