aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2011-09-09 18:42:51 -0400
committerTheodore Ts'o <tytso@mit.edu>2011-09-09 18:42:51 -0400
commitfd034a84e1ea5c8c8d159cd2089c32e792c269b0 (patch)
tree5992d541a005137a57a44921fd1be6311ee841d2
parent49f7f9af4bb4d7972f3a35a74877937fec9f622d (diff)
ext4: split out ext4_free_blocks_after_init()
The function ext4_free_blocks_after_init() used to be a #define of ext4_init_block_bitmap(). This actually made it difficult to understand how the function worked, and made it hard make changes to support clusters. So as an initial cleanup, I've separated out the functionality of initializing block bitmap from calculating the number of free blocks in the new block group. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r--fs/ext4/balloc.c105
-rw-r--r--fs/ext4/ext4.h13
-rw-r--r--fs/ext4/ialloc.c20
3 files changed, 66 insertions, 72 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 8573e2bfb78..735d9fcc72e 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -102,74 +102,73 @@ static unsigned int num_blocks_in_group(struct super_block *sb,
102 return EXT4_BLOCKS_PER_GROUP(sb); 102 return EXT4_BLOCKS_PER_GROUP(sb);
103} 103}
104 104
105/* Initializes an uninitialized block bitmap if given, and returns the 105/* Initializes an uninitialized block bitmap */
106 * number of blocks free in the group. */ 106void 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, 107 ext4_group_t block_group,
108 ext4_group_t block_group, struct ext4_group_desc *gdp) 108 struct ext4_group_desc *gdp)
109{ 109{
110 unsigned int bit, bit_max = num_base_meta_blocks(sb, block_group); 110 unsigned int bit, bit_max = num_base_meta_blocks(sb, block_group);
111 ext4_group_t ngroups = ext4_get_groups_count(sb);
112 unsigned group_blocks = num_blocks_in_group(sb, block_group);
113 struct ext4_sb_info *sbi = EXT4_SB(sb); 111 struct ext4_sb_info *sbi = EXT4_SB(sb);
114 112 ext4_fsblk_t start, tmp;
115 if (bh) { 113 int flex_bg = 0;
116 J_ASSERT_BH(bh, buffer_locked(bh)); 114
117 115 J_ASSERT_BH(bh, buffer_locked(bh));
118 /* If checksum is bad mark all blocks used to prevent allocation 116
119 * essentially implementing a per-group read-only flag. */ 117 /* If checksum is bad mark all blocks used to prevent allocation
120 if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) { 118 * essentially implementing a per-group read-only flag. */
121 ext4_error(sb, "Checksum bad for group %u", 119 if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
122 block_group); 120 ext4_error(sb, "Checksum bad for group %u", block_group);
123 ext4_free_blks_set(sb, gdp, 0); 121 ext4_free_blks_set(sb, gdp, 0);
124 ext4_free_inodes_set(sb, gdp, 0); 122 ext4_free_inodes_set(sb, gdp, 0);
125 ext4_itable_unused_set(sb, gdp, 0); 123 ext4_itable_unused_set(sb, gdp, 0);
126 memset(bh->b_data, 0xff, sb->s_blocksize); 124 memset(bh->b_data, 0xff, sb->s_blocksize);
127 return 0; 125 return;
128 }
129 memset(bh->b_data, 0, sb->s_blocksize);
130 } 126 }
127 memset(bh->b_data, 0, sb->s_blocksize);
131 128
132 if (bh) { 129 for (bit = 0; bit < bit_max; bit++)
133 ext4_fsblk_t start, tmp; 130 ext4_set_bit(bit, bh->b_data);
134 int flex_bg = 0;
135 131
136 for (bit = 0; bit < bit_max; bit++) 132 start = ext4_group_first_block_no(sb, block_group);
137 ext4_set_bit(bit, bh->b_data);
138 133
139 start = ext4_group_first_block_no(sb, block_group); 134 if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
135 flex_bg = 1;
140 136
141 if (EXT4_HAS_INCOMPAT_FEATURE(sb, 137 /* Set bits for block and inode bitmaps, and inode table */
142 EXT4_FEATURE_INCOMPAT_FLEX_BG)) 138 tmp = ext4_block_bitmap(sb, gdp);
143 flex_bg = 1; 139 if (!flex_bg || ext4_block_in_group(sb, tmp, block_group))
140 ext4_set_bit(tmp - start, bh->b_data);
144 141
145 /* Set bits for block and inode bitmaps, and inode table */ 142 tmp = ext4_inode_bitmap(sb, gdp);
146 tmp = ext4_block_bitmap(sb, gdp); 143 if (!flex_bg || ext4_block_in_group(sb, tmp, block_group))
147 if (!flex_bg || ext4_block_in_group(sb, tmp, block_group)) 144 ext4_set_bit(tmp - start, bh->b_data);
148 ext4_set_bit(tmp - start, bh->b_data);
149 145
150 tmp = ext4_inode_bitmap(sb, gdp); 146 tmp = ext4_inode_table(sb, gdp);
147 for (; tmp < ext4_inode_table(sb, gdp) +
148 sbi->s_itb_per_group; tmp++) {
151 if (!flex_bg || ext4_block_in_group(sb, tmp, block_group)) 149 if (!flex_bg || ext4_block_in_group(sb, tmp, block_group))
152 ext4_set_bit(tmp - start, bh->b_data); 150 ext4_set_bit(tmp - start, bh->b_data);
153
154 tmp = ext4_inode_table(sb, gdp);
155 for (; tmp < ext4_inode_table(sb, gdp) +
156 sbi->s_itb_per_group; tmp++) {
157 if (!flex_bg ||
158 ext4_block_in_group(sb, tmp, block_group))
159 ext4_set_bit(tmp - start, bh->b_data);
160 }
161 /*
162 * Also if the number of blocks within the group is
163 * less than the blocksize * 8 ( which is the size
164 * of bitmap ), set rest of the block bitmap to 1
165 */
166 ext4_mark_bitmap_end(group_blocks, sb->s_blocksize * 8,
167 bh->b_data);
168 } 151 }
169 return group_blocks - bit_max - 152 /*
170 ext4_group_used_meta_blocks(sb, block_group, gdp); 153 * Also if the number of blocks within the group is less than
154 * the blocksize * 8 ( which is the size of bitmap ), set rest
155 * of the block bitmap to 1
156 */
157 ext4_mark_bitmap_end(num_blocks_in_group(sb, block_group),
158 sb->s_blocksize * 8, bh->b_data);
171} 159}
172 160
161/* Return the number of free blocks in a block group. It is used when
162 * the block bitmap is uninitialized, so we can't just count the bits
163 * in the bitmap. */
164unsigned ext4_free_blocks_after_init(struct super_block *sb,
165 ext4_group_t block_group,
166 struct ext4_group_desc *gdp)
167{
168 return num_blocks_in_group(sb, block_group) -
169 num_base_meta_blocks(sb, block_group) -
170 ext4_group_used_meta_blocks(sb, block_group, gdp);
171}
173 172
174/* 173/*
175 * The free blocks are managed by bitmaps. A file system contains several 174 * The free blocks are managed by bitmaps. A file system contains several
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index f7257aa6bf8..b0b7b67e439 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1763,12 +1763,13 @@ extern struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
1763extern int ext4_should_retry_alloc(struct super_block *sb, int *retries); 1763extern int ext4_should_retry_alloc(struct super_block *sb, int *retries);
1764struct buffer_head *ext4_read_block_bitmap(struct super_block *sb, 1764struct buffer_head *ext4_read_block_bitmap(struct super_block *sb,
1765 ext4_group_t block_group); 1765 ext4_group_t block_group);
1766extern unsigned ext4_init_block_bitmap(struct super_block *sb, 1766extern void ext4_init_block_bitmap(struct super_block *sb,
1767 struct buffer_head *bh, 1767 struct buffer_head *bh,
1768 ext4_group_t group, 1768 ext4_group_t group,
1769 struct ext4_group_desc *desc); 1769 struct ext4_group_desc *desc);
1770#define ext4_free_blocks_after_init(sb, group, desc) \ 1770extern unsigned ext4_free_blocks_after_init(struct super_block *sb,
1771 ext4_init_block_bitmap(sb, NULL, group, desc) 1771 ext4_group_t block_group,
1772 struct ext4_group_desc *gdp);
1772ext4_fsblk_t ext4_inode_to_goal_block(struct inode *); 1773ext4_fsblk_t ext4_inode_to_goal_block(struct inode *);
1773 1774
1774/* dir.c */ 1775/* dir.c */
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 9c63f273b55..b7a8130d0af 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -816,7 +816,6 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode,
816 int ret2, err = 0; 816 int ret2, err = 0;
817 struct inode *ret; 817 struct inode *ret;
818 ext4_group_t i; 818 ext4_group_t i;
819 int free = 0;
820 static int once = 1; 819 static int once = 1;
821 ext4_group_t flex_group; 820 ext4_group_t flex_group;
822 821
@@ -950,26 +949,21 @@ got:
950 goto fail; 949 goto fail;
951 } 950 }
952 951
953 free = 0; 952 BUFFER_TRACE(block_bitmap_bh, "dirty block bitmap");
954 ext4_lock_group(sb, group); 953 err = ext4_handle_dirty_metadata(handle, NULL, block_bitmap_bh);
954 brelse(block_bitmap_bh);
955
955 /* recheck and clear flag under lock if we still need to */ 956 /* recheck and clear flag under lock if we still need to */
957 ext4_lock_group(sb, group);
956 if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { 958 if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
957 free = ext4_free_blocks_after_init(sb, group, gdp);
958 gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); 959 gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
959 ext4_free_blks_set(sb, gdp, free); 960 ext4_free_blks_set(sb, gdp,
961 ext4_free_blocks_after_init(sb, group, gdp));
960 gdp->bg_checksum = ext4_group_desc_csum(sbi, group, 962 gdp->bg_checksum = ext4_group_desc_csum(sbi, group,
961 gdp); 963 gdp);
962 } 964 }
963 ext4_unlock_group(sb, group); 965 ext4_unlock_group(sb, group);
964 966
965 /* Don't need to dirty bitmap block if we didn't change it */
966 if (free) {
967 BUFFER_TRACE(block_bitmap_bh, "dirty block bitmap");
968 err = ext4_handle_dirty_metadata(handle,
969 NULL, block_bitmap_bh);
970 }
971
972 brelse(block_bitmap_bh);
973 if (err) 967 if (err)
974 goto fail; 968 goto fail;
975 } 969 }