aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/inode.c
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2009-03-12 12:18:34 -0400
committerTheodore Ts'o <tytso@mit.edu>2009-03-12 12:18:34 -0400
commita4912123b688e057084e6557cef8924f7ae5bbde (patch)
tree34e88705d6617b52caa0f87692b480119a9c9e2e /fs/ext4/inode.c
parent2dc6b0d48ca0599837df21b14bb8393d0804af57 (diff)
ext4: New inode/block allocation algorithms for flex_bg filesystems
The find_group_flex() inode allocator is now only used if the filesystem is mounted using the "oldalloc" mount option. It is replaced with the original Orlov allocator that has been updated for flex_bg filesystems (it should behave the same way if flex_bg is disabled). The inode allocator now functions by taking into account each flex_bg group, instead of each block group, when deciding whether or not it's time to allocate a new directory into a fresh flex_bg. The block allocator has also been changed so that the first block group in each flex_bg is preferred for use for storing directory blocks. This keeps directory blocks close together, which is good for speeding up e2fsck since large directories are more likely to look like this: debugfs: stat /home/tytso/Maildir/cur Inode: 1844562 Type: directory Mode: 0700 Flags: 0x81000 Generation: 1132745781 Version: 0x00000000:0000ad71 User: 15806 Group: 15806 Size: 1060864 File ACL: 0 Directory ACL: 0 Links: 2 Blockcount: 2072 Fragment: Address: 0 Number: 0 Size: 0 ctime: 0x499c0ff4:164961f4 -- Wed Feb 18 08:41:08 2009 atime: 0x499c0ff4:00000000 -- Wed Feb 18 08:41:08 2009 mtime: 0x49957f51:00000000 -- Fri Feb 13 09:10:25 2009 crtime: 0x499c0f57:00d51440 -- Wed Feb 18 08:38:31 2009 Size of extra inode fields: 28 BLOCKS: (0):7348651, (1-258):7348654-7348911 TOTAL: 259 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r--fs/ext4/inode.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 71d3ecd5db79..25811507d2b0 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -459,6 +459,8 @@ static ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind)
459 ext4_fsblk_t bg_start; 459 ext4_fsblk_t bg_start;
460 ext4_fsblk_t last_block; 460 ext4_fsblk_t last_block;
461 ext4_grpblk_t colour; 461 ext4_grpblk_t colour;
462 ext4_group_t block_group;
463 int flex_size = ext4_flex_bg_size(EXT4_SB(inode->i_sb));
462 464
463 /* Try to find previous block */ 465 /* Try to find previous block */
464 for (p = ind->p - 1; p >= start; p--) { 466 for (p = ind->p - 1; p >= start; p--) {
@@ -474,9 +476,22 @@ static ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind)
474 * It is going to be referred to from the inode itself? OK, just put it 476 * It is going to be referred to from the inode itself? OK, just put it
475 * into the same cylinder group then. 477 * into the same cylinder group then.
476 */ 478 */
477 bg_start = ext4_group_first_block_no(inode->i_sb, ei->i_block_group); 479 block_group = ei->i_block_group;
480 if (flex_size >= EXT4_FLEX_SIZE_DIR_ALLOC_SCHEME) {
481 block_group &= ~(flex_size-1);
482 if (S_ISREG(inode->i_mode))
483 block_group++;
484 }
485 bg_start = ext4_group_first_block_no(inode->i_sb, block_group);
478 last_block = ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es) - 1; 486 last_block = ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es) - 1;
479 487
488 /*
489 * If we are doing delayed allocation, we don't need take
490 * colour into account.
491 */
492 if (test_opt(inode->i_sb, DELALLOC))
493 return bg_start;
494
480 if (bg_start + EXT4_BLOCKS_PER_GROUP(inode->i_sb) <= last_block) 495 if (bg_start + EXT4_BLOCKS_PER_GROUP(inode->i_sb) <= last_block)
481 colour = (current->pid % 16) * 496 colour = (current->pid % 16) *
482 (EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16); 497 (EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16);
@@ -4287,6 +4302,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
4287 ei->i_disksize = inode->i_size; 4302 ei->i_disksize = inode->i_size;
4288 inode->i_generation = le32_to_cpu(raw_inode->i_generation); 4303 inode->i_generation = le32_to_cpu(raw_inode->i_generation);
4289 ei->i_block_group = iloc.block_group; 4304 ei->i_block_group = iloc.block_group;
4305 ei->i_last_alloc_group = ~0;
4290 /* 4306 /*
4291 * NOTE! The in-memory inode i_data array is in little-endian order 4307 * NOTE! The in-memory inode i_data array is in little-endian order
4292 * even on big-endian machines: we do NOT byteswap the block numbers! 4308 * even on big-endian machines: we do NOT byteswap the block numbers!