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 | |
| 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')
| -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 06ee5a582917..d035cf149e0e 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 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 | ||
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c index fe64d9f79852..80d075b8aeaf 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 07eb6649e4fa..5f00d2418a83 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; |
