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 /fs/ext4/ialloc.c | |
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>
Diffstat (limited to 'fs/ext4/ialloc.c')
-rw-r--r-- | fs/ext4/ialloc.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 7d502f3be914..3f98ee712ff4 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 | ||