diff options
author | Theodore Ts'o <tytso@mit.edu> | 2009-06-13 11:09:42 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2009-06-13 11:09:42 -0400 |
commit | f157a4aa98a18bd3817a72bea90d48494e2586e7 (patch) | |
tree | 105547639a67296b4ea7acdc35c9e65ee2a85fd8 | |
parent | 8a8a2050c844d9de224ff591e91bda3f77bd6eda (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.h | 3 | ||||
-rw-r--r-- | fs/ext4/ialloc.c | 19 | ||||
-rw-r--r-- | fs/ext4/migrate.c | 5 | ||||
-rw-r--r-- | fs/ext4/namei.c | 8 |
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 */ |
1318 | extern struct inode * ext4_new_inode(handle_t *, struct inode *, int); | 1318 | extern struct inode *ext4_new_inode(handle_t *, struct inode *, int, |
1319 | const struct qstr *qstr); | ||
1319 | extern void ext4_free_inode(handle_t *, struct inode *); | 1320 | extern void ext4_free_inode(handle_t *, struct inode *); |
1320 | extern struct inode * ext4_orphan_get(struct super_block *, unsigned long); | 1321 | extern struct inode * ext4_orphan_get(struct super_block *, unsigned long); |
1321 | extern unsigned long ext4_count_free_inodes(struct super_block *); | 1322 | extern 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 | ||
472 | static int find_group_orlov(struct super_block *sb, struct inode *parent, | 472 | static 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 | */ |
793 | struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) | 801 | struct 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; |