diff options
author | Eric Sandeen <sandeen@redhat.com> | 2011-06-28 10:01:31 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2011-06-28 10:01:31 -0400 |
commit | f86186b44b4164600cce03d0d93ad48ec21fa429 (patch) | |
tree | 48aafabbbe46d22de84e4e9b3ebf7c5b35fd6d1e | |
parent | dae1e52cb1267bf8f52e5e47a80fab566d7e8aa4 (diff) |
ext4: refactor duplicated block placement code
I found that ext4_ext_find_goal() and ext4_find_near()
share the same code for returning a coloured start block
based on i_block_group.
We can refactor this into a common function so that they
don't diverge in the future.
Thanks to adilger for suggesting the new function name.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r-- | fs/ext4/balloc.c | 48 | ||||
-rw-r--r-- | fs/ext4/ext4.h | 1 | ||||
-rw-r--r-- | fs/ext4/extents.c | 37 | ||||
-rw-r--r-- | fs/ext4/indirect.c | 28 |
4 files changed, 51 insertions, 63 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 264f6949511e..f8224adf496e 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -620,3 +620,51 @@ unsigned long ext4_bg_num_gdb(struct super_block *sb, ext4_group_t group) | |||
620 | 620 | ||
621 | } | 621 | } |
622 | 622 | ||
623 | /** | ||
624 | * ext4_inode_to_goal_block - return a hint for block allocation | ||
625 | * @inode: inode for block allocation | ||
626 | * | ||
627 | * Return the ideal location to start allocating blocks for a | ||
628 | * newly created inode. | ||
629 | */ | ||
630 | ext4_fsblk_t ext4_inode_to_goal_block(struct inode *inode) | ||
631 | { | ||
632 | struct ext4_inode_info *ei = EXT4_I(inode); | ||
633 | ext4_group_t block_group; | ||
634 | ext4_grpblk_t colour; | ||
635 | int flex_size = ext4_flex_bg_size(EXT4_SB(inode->i_sb)); | ||
636 | ext4_fsblk_t bg_start; | ||
637 | ext4_fsblk_t last_block; | ||
638 | |||
639 | block_group = ei->i_block_group; | ||
640 | if (flex_size >= EXT4_FLEX_SIZE_DIR_ALLOC_SCHEME) { | ||
641 | /* | ||
642 | * If there are at least EXT4_FLEX_SIZE_DIR_ALLOC_SCHEME | ||
643 | * block groups per flexgroup, reserve the first block | ||
644 | * group for directories and special files. Regular | ||
645 | * files will start at the second block group. This | ||
646 | * tends to speed up directory access and improves | ||
647 | * fsck times. | ||
648 | */ | ||
649 | block_group &= ~(flex_size-1); | ||
650 | if (S_ISREG(inode->i_mode)) | ||
651 | block_group++; | ||
652 | } | ||
653 | bg_start = ext4_group_first_block_no(inode->i_sb, block_group); | ||
654 | last_block = ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es) - 1; | ||
655 | |||
656 | /* | ||
657 | * If we are doing delayed allocation, we don't need take | ||
658 | * colour into account. | ||
659 | */ | ||
660 | if (test_opt(inode->i_sb, DELALLOC)) | ||
661 | return bg_start; | ||
662 | |||
663 | if (bg_start + EXT4_BLOCKS_PER_GROUP(inode->i_sb) <= last_block) | ||
664 | colour = (current->pid % 16) * | ||
665 | (EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16); | ||
666 | else | ||
667 | colour = (current->pid % 16) * ((last_block - bg_start) / 16); | ||
668 | return bg_start + colour; | ||
669 | } | ||
670 | |||
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index ddaf5043fb38..49d2cea47382 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -1743,6 +1743,7 @@ extern unsigned ext4_init_block_bitmap(struct super_block *sb, | |||
1743 | struct ext4_group_desc *desc); | 1743 | struct ext4_group_desc *desc); |
1744 | #define ext4_free_blocks_after_init(sb, group, desc) \ | 1744 | #define ext4_free_blocks_after_init(sb, group, desc) \ |
1745 | ext4_init_block_bitmap(sb, NULL, group, desc) | 1745 | ext4_init_block_bitmap(sb, NULL, group, desc) |
1746 | ext4_fsblk_t ext4_inode_to_goal_block(struct inode *); | ||
1746 | 1747 | ||
1747 | /* dir.c */ | 1748 | /* dir.c */ |
1748 | extern int __ext4_check_dir_entry(const char *, unsigned int, struct inode *, | 1749 | extern int __ext4_check_dir_entry(const char *, unsigned int, struct inode *, |
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index eb63c7b8dfd2..f331e5010f68 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -114,12 +114,6 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode, | |||
114 | struct ext4_ext_path *path, | 114 | struct ext4_ext_path *path, |
115 | ext4_lblk_t block) | 115 | ext4_lblk_t block) |
116 | { | 116 | { |
117 | struct ext4_inode_info *ei = EXT4_I(inode); | ||
118 | ext4_fsblk_t bg_start; | ||
119 | ext4_fsblk_t last_block; | ||
120 | ext4_grpblk_t colour; | ||
121 | ext4_group_t block_group; | ||
122 | int flex_size = ext4_flex_bg_size(EXT4_SB(inode->i_sb)); | ||
123 | int depth; | 117 | int depth; |
124 | 118 | ||
125 | if (path) { | 119 | if (path) { |
@@ -161,36 +155,7 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode, | |||
161 | } | 155 | } |
162 | 156 | ||
163 | /* OK. use inode's group */ | 157 | /* OK. use inode's group */ |
164 | block_group = ei->i_block_group; | 158 | return ext4_inode_to_goal_block(inode); |
165 | if (flex_size >= EXT4_FLEX_SIZE_DIR_ALLOC_SCHEME) { | ||
166 | /* | ||
167 | * If there are at least EXT4_FLEX_SIZE_DIR_ALLOC_SCHEME | ||
168 | * block groups per flexgroup, reserve the first block | ||
169 | * group for directories and special files. Regular | ||
170 | * files will start at the second block group. This | ||
171 | * tends to speed up directory access and improves | ||
172 | * fsck times. | ||
173 | */ | ||
174 | block_group &= ~(flex_size-1); | ||
175 | if (S_ISREG(inode->i_mode)) | ||
176 | block_group++; | ||
177 | } | ||
178 | bg_start = ext4_group_first_block_no(inode->i_sb, block_group); | ||
179 | last_block = ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es) - 1; | ||
180 | |||
181 | /* | ||
182 | * If we are doing delayed allocation, we don't need take | ||
183 | * colour into account. | ||
184 | */ | ||
185 | if (test_opt(inode->i_sb, DELALLOC)) | ||
186 | return bg_start; | ||
187 | |||
188 | if (bg_start + EXT4_BLOCKS_PER_GROUP(inode->i_sb) <= last_block) | ||
189 | colour = (current->pid % 16) * | ||
190 | (EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16); | ||
191 | else | ||
192 | colour = (current->pid % 16) * ((last_block - bg_start) / 16); | ||
193 | return bg_start + colour + block; | ||
194 | } | 159 | } |
195 | 160 | ||
196 | /* | 161 | /* |
diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c index c3e85a86e821..6c271115dbb6 100644 --- a/fs/ext4/indirect.c +++ b/fs/ext4/indirect.c | |||
@@ -207,11 +207,6 @@ static ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind) | |||
207 | struct ext4_inode_info *ei = EXT4_I(inode); | 207 | struct ext4_inode_info *ei = EXT4_I(inode); |
208 | __le32 *start = ind->bh ? (__le32 *) ind->bh->b_data : ei->i_data; | 208 | __le32 *start = ind->bh ? (__le32 *) ind->bh->b_data : ei->i_data; |
209 | __le32 *p; | 209 | __le32 *p; |
210 | ext4_fsblk_t bg_start; | ||
211 | ext4_fsblk_t last_block; | ||
212 | ext4_grpblk_t colour; | ||
213 | ext4_group_t block_group; | ||
214 | int flex_size = ext4_flex_bg_size(EXT4_SB(inode->i_sb)); | ||
215 | 210 | ||
216 | /* Try to find previous block */ | 211 | /* Try to find previous block */ |
217 | for (p = ind->p - 1; p >= start; p--) { | 212 | for (p = ind->p - 1; p >= start; p--) { |
@@ -227,28 +222,7 @@ static ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind) | |||
227 | * It is going to be referred to from the inode itself? OK, just put it | 222 | * It is going to be referred to from the inode itself? OK, just put it |
228 | * into the same cylinder group then. | 223 | * into the same cylinder group then. |
229 | */ | 224 | */ |
230 | block_group = ei->i_block_group; | 225 | return ext4_inode_to_goal_block(inode); |
231 | if (flex_size >= EXT4_FLEX_SIZE_DIR_ALLOC_SCHEME) { | ||
232 | block_group &= ~(flex_size-1); | ||
233 | if (S_ISREG(inode->i_mode)) | ||
234 | block_group++; | ||
235 | } | ||
236 | bg_start = ext4_group_first_block_no(inode->i_sb, block_group); | ||
237 | last_block = ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es) - 1; | ||
238 | |||
239 | /* | ||
240 | * If we are doing delayed allocation, we don't need take | ||
241 | * colour into account. | ||
242 | */ | ||
243 | if (test_opt(inode->i_sb, DELALLOC)) | ||
244 | return bg_start; | ||
245 | |||
246 | if (bg_start + EXT4_BLOCKS_PER_GROUP(inode->i_sb) <= last_block) | ||
247 | colour = (current->pid % 16) * | ||
248 | (EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16); | ||
249 | else | ||
250 | colour = (current->pid % 16) * ((last_block - bg_start) / 16); | ||
251 | return bg_start + colour; | ||
252 | } | 226 | } |
253 | 227 | ||
254 | /** | 228 | /** |