aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorAmir Goldstein <amir73il@users.sf.net>2011-05-09 10:46:41 -0400
committerTheodore Ts'o <tytso@mit.edu>2011-05-09 10:46:41 -0400
commit2846e82004a8d5ef0a63cd3209c84ea5cd796f11 (patch)
tree3b20c08ce64e918d4217bb95228fc597c63bf0e0 /fs/ext4
parent66bb82798d9ff896271d13f5020f7fb9b7d88e1a (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.c124
-rw-r--r--fs/ext4/ext4.h4
-rw-r--r--fs/ext4/mballoc.c124
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 */
375void 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
482error_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,
1655extern ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode, 1655extern 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);
1657extern int ext4_claim_free_blocks(struct ext4_sb_info *sbi, s64 nblocks); 1657extern int ext4_claim_free_blocks(struct ext4_sb_info *sbi, s64 nblocks);
1658extern void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
1659 ext4_fsblk_t block, unsigned long count);
1660extern ext4_fsblk_t ext4_count_free_blocks(struct super_block *); 1658extern ext4_fsblk_t ext4_count_free_blocks(struct super_block *);
1661extern void ext4_check_blocks_bitmap(struct super_block *); 1659extern void ext4_check_blocks_bitmap(struct super_block *);
1662extern struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb, 1660extern 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);
1722extern int ext4_mb_add_groupinfo(struct super_block *sb, 1720extern 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);
1722extern void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
1723 ext4_fsblk_t block, unsigned long count);
1724extern int ext4_trim_fs(struct super_block *, struct fstrim_range *); 1724extern 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 */
4713void 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
4820error_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