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/mballoc.c | |
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/mballoc.c')
-rw-r--r-- | fs/ext4/mballoc.c | 124 |
1 files changed, 124 insertions, 0 deletions
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 |