aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/balloc.c
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2011-09-09 18:40:51 -0400
committerTheodore Ts'o <tytso@mit.edu>2011-09-09 18:40:51 -0400
commit49f7f9af4bb4d7972f3a35a74877937fec9f622d (patch)
tree19ef79ae359e6524a1d8d9d303005c9e5dbf813c /fs/ext4/balloc.c
parent7137d7a48e2213eb1f6d6529da14c2ed3706b795 (diff)
ext4: factor out block group accounting into functions
This makes it easier to understand how ext4_init_block_bitmap() works, and it will assist when we split out ext4_free_blocks_after_init() in the next commit. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/balloc.c')
-rw-r--r--fs/ext4/balloc.c80
1 files changed, 48 insertions, 32 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index f8224adf496e..8573e2bfb78a 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -23,6 +23,9 @@
23 23
24#include <trace/events/ext4.h> 24#include <trace/events/ext4.h>
25 25
26static unsigned int num_base_meta_blocks(struct super_block *sb,
27 ext4_group_t block_group);
28
26/* 29/*
27 * balloc.c contains the blocks allocation and deallocation routines 30 * balloc.c contains the blocks allocation and deallocation routines
28 */ 31 */
@@ -83,14 +86,30 @@ static int ext4_group_used_meta_blocks(struct super_block *sb,
83 return used_blocks; 86 return used_blocks;
84} 87}
85 88
89static unsigned int num_blocks_in_group(struct super_block *sb,
90 ext4_group_t block_group)
91{
92 if (block_group == ext4_get_groups_count(sb) - 1) {
93 /*
94 * Even though mke2fs always initializes the first and
95 * last group, just in case some other tool was used,
96 * we need to make sure we calculate the right free
97 * blocks.
98 */
99 return ext4_blocks_count(EXT4_SB(sb)->s_es) -
100 ext4_group_first_block_no(sb, block_group);
101 } else
102 return EXT4_BLOCKS_PER_GROUP(sb);
103}
104
86/* Initializes an uninitialized block bitmap if given, and returns the 105/* Initializes an uninitialized block bitmap if given, and returns the
87 * number of blocks free in the group. */ 106 * number of blocks free in the group. */
88unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, 107unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
89 ext4_group_t block_group, struct ext4_group_desc *gdp) 108 ext4_group_t block_group, struct ext4_group_desc *gdp)
90{ 109{
91 int bit, bit_max; 110 unsigned int bit, bit_max = num_base_meta_blocks(sb, block_group);
92 ext4_group_t ngroups = ext4_get_groups_count(sb); 111 ext4_group_t ngroups = ext4_get_groups_count(sb);
93 unsigned free_blocks, group_blocks; 112 unsigned group_blocks = num_blocks_in_group(sb, block_group);
94 struct ext4_sb_info *sbi = EXT4_SB(sb); 113 struct ext4_sb_info *sbi = EXT4_SB(sb);
95 114
96 if (bh) { 115 if (bh) {
@@ -110,35 +129,6 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
110 memset(bh->b_data, 0, sb->s_blocksize); 129 memset(bh->b_data, 0, sb->s_blocksize);
111 } 130 }
112 131
113 /* Check for superblock and gdt backups in this group */
114 bit_max = ext4_bg_has_super(sb, block_group);
115
116 if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG) ||
117 block_group < le32_to_cpu(sbi->s_es->s_first_meta_bg) *
118 sbi->s_desc_per_block) {
119 if (bit_max) {
120 bit_max += ext4_bg_num_gdb(sb, block_group);
121 bit_max +=
122 le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks);
123 }
124 } else { /* For META_BG_BLOCK_GROUPS */
125 bit_max += ext4_bg_num_gdb(sb, block_group);
126 }
127
128 if (block_group == ngroups - 1) {
129 /*
130 * Even though mke2fs always initialize first and last group
131 * if some other tool enabled the EXT4_BG_BLOCK_UNINIT we need
132 * to make sure we calculate the right free blocks
133 */
134 group_blocks = ext4_blocks_count(sbi->s_es) -
135 ext4_group_first_block_no(sb, ngroups - 1);
136 } else {
137 group_blocks = EXT4_BLOCKS_PER_GROUP(sb);
138 }
139
140 free_blocks = group_blocks - bit_max;
141
142 if (bh) { 132 if (bh) {
143 ext4_fsblk_t start, tmp; 133 ext4_fsblk_t start, tmp;
144 int flex_bg = 0; 134 int flex_bg = 0;
@@ -176,7 +166,8 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
176 ext4_mark_bitmap_end(group_blocks, sb->s_blocksize * 8, 166 ext4_mark_bitmap_end(group_blocks, sb->s_blocksize * 8,
177 bh->b_data); 167 bh->b_data);
178 } 168 }
179 return free_blocks - ext4_group_used_meta_blocks(sb, block_group, gdp); 169 return group_blocks - bit_max -
170 ext4_group_used_meta_blocks(sb, block_group, gdp);
180} 171}
181 172
182 173
@@ -620,6 +611,31 @@ unsigned long ext4_bg_num_gdb(struct super_block *sb, ext4_group_t group)
620 611
621} 612}
622 613
614/*
615 * This function returns the number of file system metadata blocks at
616 * the beginning of a block group, including the reserved gdt blocks.
617 */
618static unsigned int num_base_meta_blocks(struct super_block *sb,
619 ext4_group_t block_group)
620{
621 struct ext4_sb_info *sbi = EXT4_SB(sb);
622 int num;
623
624 /* Check for superblock and gdt backups in this group */
625 num = ext4_bg_has_super(sb, block_group);
626
627 if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG) ||
628 block_group < le32_to_cpu(sbi->s_es->s_first_meta_bg) *
629 sbi->s_desc_per_block) {
630 if (num) {
631 num += ext4_bg_num_gdb(sb, block_group);
632 num += le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks);
633 }
634 } else { /* For META_BG_BLOCK_GROUPS */
635 num += ext4_bg_num_gdb(sb, block_group);
636 }
637 return num;
638}
623/** 639/**
624 * ext4_inode_to_goal_block - return a hint for block allocation 640 * ext4_inode_to_goal_block - return a hint for block allocation
625 * @inode: inode for block allocation 641 * @inode: inode for block allocation