aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2009-06-13 11:09:42 -0400
committerTheodore Ts'o <tytso@mit.edu>2009-06-13 11:09:42 -0400
commitf157a4aa98a18bd3817a72bea90d48494e2586e7 (patch)
tree105547639a67296b4ea7acdc35c9e65ee2a85fd8
parent8a8a2050c844d9de224ff591e91bda3f77bd6eda (diff)
ext4: Use a hash of the topdir directory name for the Orlov parent group
Instead of using a random number to determine the goal parent grop for the Orlov top directories, use a hash of the directory name. This allows for repeatable results when trying to benchmark filesystem layout algorithms. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r--fs/ext4/ext4.h3
-rw-r--r--fs/ext4/ialloc.c19
-rw-r--r--fs/ext4/migrate.c5
-rw-r--r--fs/ext4/namei.c8
4 files changed, 22 insertions, 13 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 06ee5a58291..d035cf149e0 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1315,7 +1315,8 @@ extern int ext4fs_dirhash(const char *name, int len, struct
1315 dx_hash_info *hinfo); 1315 dx_hash_info *hinfo);
1316 1316
1317/* ialloc.c */ 1317/* ialloc.c */
1318extern struct inode * ext4_new_inode(handle_t *, struct inode *, int); 1318extern struct inode *ext4_new_inode(handle_t *, struct inode *, int,
1319 const struct qstr *qstr);
1319extern void ext4_free_inode(handle_t *, struct inode *); 1320extern void ext4_free_inode(handle_t *, struct inode *);
1320extern struct inode * ext4_orphan_get(struct super_block *, unsigned long); 1321extern struct inode * ext4_orphan_get(struct super_block *, unsigned long);
1321extern unsigned long ext4_count_free_inodes(struct super_block *); 1322extern unsigned long ext4_count_free_inodes(struct super_block *);
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 7d502f3be91..3f98ee712ff 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -470,7 +470,8 @@ void get_orlov_stats(struct super_block *sb, ext4_group_t g,
470 */ 470 */
471 471
472static int find_group_orlov(struct super_block *sb, struct inode *parent, 472static int find_group_orlov(struct super_block *sb, struct inode *parent,
473 ext4_group_t *group, int mode) 473 ext4_group_t *group, int mode,
474 const struct qstr *qstr)
474{ 475{
475 ext4_group_t parent_group = EXT4_I(parent)->i_block_group; 476 ext4_group_t parent_group = EXT4_I(parent)->i_block_group;
476 struct ext4_sb_info *sbi = EXT4_SB(sb); 477 struct ext4_sb_info *sbi = EXT4_SB(sb);
@@ -485,6 +486,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent,
485 struct ext4_group_desc *desc; 486 struct ext4_group_desc *desc;
486 struct orlov_stats stats; 487 struct orlov_stats stats;
487 int flex_size = ext4_flex_bg_size(sbi); 488 int flex_size = ext4_flex_bg_size(sbi);
489 struct dx_hash_info hinfo;
488 490
489 ngroups = real_ngroups; 491 ngroups = real_ngroups;
490 if (flex_size > 1) { 492 if (flex_size > 1) {
@@ -506,7 +508,13 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent,
506 int best_ndir = inodes_per_group; 508 int best_ndir = inodes_per_group;
507 int ret = -1; 509 int ret = -1;
508 510
509 get_random_bytes(&grp, sizeof(grp)); 511 if (qstr) {
512 hinfo.hash_version = DX_HASH_HALF_MD4;
513 hinfo.seed = sbi->s_hash_seed;
514 ext4fs_dirhash(qstr->name, qstr->len, &hinfo);
515 grp = hinfo.hash;
516 } else
517 get_random_bytes(&grp, sizeof(grp));
510 parent_group = (unsigned)grp % ngroups; 518 parent_group = (unsigned)grp % ngroups;
511 for (i = 0; i < ngroups; i++) { 519 for (i = 0; i < ngroups; i++) {
512 g = (parent_group + i) % ngroups; 520 g = (parent_group + i) % ngroups;
@@ -649,7 +657,7 @@ static int find_group_other(struct super_block *sb, struct inode *parent,
649 *group = parent_group + flex_size; 657 *group = parent_group + flex_size;
650 if (*group > ngroups) 658 if (*group > ngroups)
651 *group = 0; 659 *group = 0;
652 return find_group_orlov(sb, parent, group, mode); 660 return find_group_orlov(sb, parent, group, mode, 0);
653 } 661 }
654 662
655 /* 663 /*
@@ -790,7 +798,8 @@ err_ret:
790 * For other inodes, search forward from the parent directory's block 798 * For other inodes, search forward from the parent directory's block
791 * group to find a free inode. 799 * group to find a free inode.
792 */ 800 */
793struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) 801struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode,
802 const struct qstr *qstr)
794{ 803{
795 struct super_block *sb; 804 struct super_block *sb;
796 struct buffer_head *inode_bitmap_bh = NULL; 805 struct buffer_head *inode_bitmap_bh = NULL;
@@ -839,7 +848,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode)
839 if (test_opt(sb, OLDALLOC)) 848 if (test_opt(sb, OLDALLOC))
840 ret2 = find_group_dir(sb, dir, &group); 849 ret2 = find_group_dir(sb, dir, &group);
841 else 850 else
842 ret2 = find_group_orlov(sb, dir, &group, mode); 851 ret2 = find_group_orlov(sb, dir, &group, mode, qstr);
843 } else 852 } else
844 ret2 = find_group_other(sb, dir, &group, mode); 853 ret2 = find_group_other(sb, dir, &group, mode);
845 854
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
index fe64d9f7985..80d075b8aea 100644
--- a/fs/ext4/migrate.c
+++ b/fs/ext4/migrate.c
@@ -483,9 +483,8 @@ int ext4_ext_migrate(struct inode *inode)
483 retval = PTR_ERR(handle); 483 retval = PTR_ERR(handle);
484 return retval; 484 return retval;
485 } 485 }
486 tmp_inode = ext4_new_inode(handle, 486 tmp_inode = ext4_new_inode(handle, inode->i_sb->s_root->d_inode,
487 inode->i_sb->s_root->d_inode, 487 S_IFREG, 0);
488 S_IFREG);
489 if (IS_ERR(tmp_inode)) { 488 if (IS_ERR(tmp_inode)) {
490 retval = -ENOMEM; 489 retval = -ENOMEM;
491 ext4_journal_stop(handle); 490 ext4_journal_stop(handle);
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 07eb6649e4f..5f00d2418a8 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1782,7 +1782,7 @@ retry:
1782 if (IS_DIRSYNC(dir)) 1782 if (IS_DIRSYNC(dir))
1783 ext4_handle_sync(handle); 1783 ext4_handle_sync(handle);
1784 1784
1785 inode = ext4_new_inode (handle, dir, mode); 1785 inode = ext4_new_inode(handle, dir, mode, &dentry->d_name);
1786 err = PTR_ERR(inode); 1786 err = PTR_ERR(inode);
1787 if (!IS_ERR(inode)) { 1787 if (!IS_ERR(inode)) {
1788 inode->i_op = &ext4_file_inode_operations; 1788 inode->i_op = &ext4_file_inode_operations;
@@ -1816,7 +1816,7 @@ retry:
1816 if (IS_DIRSYNC(dir)) 1816 if (IS_DIRSYNC(dir))
1817 ext4_handle_sync(handle); 1817 ext4_handle_sync(handle);
1818 1818
1819 inode = ext4_new_inode(handle, dir, mode); 1819 inode = ext4_new_inode(handle, dir, mode, &dentry->d_name);
1820 err = PTR_ERR(inode); 1820 err = PTR_ERR(inode);
1821 if (!IS_ERR(inode)) { 1821 if (!IS_ERR(inode)) {
1822 init_special_inode(inode, inode->i_mode, rdev); 1822 init_special_inode(inode, inode->i_mode, rdev);
@@ -1853,7 +1853,7 @@ retry:
1853 if (IS_DIRSYNC(dir)) 1853 if (IS_DIRSYNC(dir))
1854 ext4_handle_sync(handle); 1854 ext4_handle_sync(handle);
1855 1855
1856 inode = ext4_new_inode(handle, dir, S_IFDIR | mode); 1856 inode = ext4_new_inode(handle, dir, S_IFDIR | mode, &dentry->d_name);
1857 err = PTR_ERR(inode); 1857 err = PTR_ERR(inode);
1858 if (IS_ERR(inode)) 1858 if (IS_ERR(inode))
1859 goto out_stop; 1859 goto out_stop;
@@ -2264,7 +2264,7 @@ retry:
2264 if (IS_DIRSYNC(dir)) 2264 if (IS_DIRSYNC(dir))
2265 ext4_handle_sync(handle); 2265 ext4_handle_sync(handle);
2266 2266
2267 inode = ext4_new_inode(handle, dir, S_IFLNK|S_IRWXUGO); 2267 inode = ext4_new_inode(handle, dir, S_IFLNK|S_IRWXUGO, &dentry->d_name);
2268 err = PTR_ERR(inode); 2268 err = PTR_ERR(inode);
2269 if (IS_ERR(inode)) 2269 if (IS_ERR(inode))
2270 goto out_stop; 2270 goto out_stop;