Add goal argument to ext4_new_inode()
PATCH 1/2 Add goal argument to ext4_new_inode()
The EA inodes are not linked into any directory since a single directory per filesystem will cause a bottleneck. Instead a "goal" argument has been added to the ext4_new_inode() function to help a localized selection of the EA inode. Since ext4_new_inode() only used the dir argument to choose the group, we use goal argument to do the same.
Signed-off-by Andreas Dilger <[email protected]>
Signed-off-by Kalpak Shah <[email protected]>
ext4.h | 3 ++- ialloc.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- migrate.c | 5 ++--- namei.c | 8 ++++---- 4 files changed, 51 insertions(+), 10 deletions(-)
Thanks,
Kalpak.
Signed-off-by Kalpak Shah <[email protected]>
Signed-off-by Andreas Dilger <[email protected]>
fs/ext4/ialloc.c +43 -2
@@ -578,8 +578,12 @@ static int find_group_other(struct super* * For other inodes, search forward from the parent directory's block * group to find a free inode. +* +* If a goal inode is specified then try to allocate it else continue +* allocation as is. */ -struct inode *ext4_new_inode (handle_t *handle,struct inode *dir,int mode) +struct inode *ext4_new_inode (handle_t *handle,struct inode *dir,int mode, +unsigned long goal) {struct super_block *sb;struct buffer_head *bitmap_bh =NULL ;
@@ -591,7 +595,7 @@ struct inode *ext4_new_inode(handle_t *hstruct ext4_super_block *es;struct ext4_inode_info *ei;struct ext4_sb_info *sbi; -int ret2, err =0 ; +int ret2 =0 , err =0 ;struct inode *ret;ext4_group_t i;int free =0 ;
@@ -610,6 +614,43 @@ struct inode *ext4_new_inode(handle_t *h sbi =EXT4_SB (sb); es = sbi->s_es; +if (goal) { + group = (goal -1 ) /EXT4_INODES_PER_GROUP (sb); + ino = (goal -1 ) %EXT4_INODES_PER_GROUP (sb); + + err = -EIO ; + gdp =ext4_get_group_desc (sb, group, &bh2); +if (!gdp) + goto fail; + + bitmap_bh =ext4_read_inode_bitmap (sb, group); +if (!bitmap_bh) + goto fail; + +BUFFER_TRACE (bh,"get_write_access" ); + err =ext4_journal_get_write_access (handle, bitmap_bh); +if (err) + goto fail; + +if (ext4_set_bit_atomic (sb_bgl_lock (sbi, group), + ino, bitmap_bh->b_data)) { + goto continue_allocation; + } + +BUFFER_TRACE (bh,"call ext4_journal_dirty_metadata" ); + err =ext4_journal_dirty_metadata (handle, bitmap_bh); +if (err) + goto fail; + +/* +* We've shortcircuited the allocation system successfully, +* now finish filling in the inode. +*/ + goto got; + } + +continue_allocation: +if (sbi->s_log_groups_per_flex) { ret2 =find_group_flex (sb, dir, &group); goto got_group;
fs/ext4/namei.c +4 -4
@@ -1725,7 +1725,7 @@ retry:if (IS_DIRSYNC (dir)) handle->h_sync =1 ; - inode =ext4_new_inode (handle, dir, mode); + inode =ext4_new_inode (handle, dir, mode,0 ); err =PTR_ERR (inode);if (!IS_ERR (inode)) { inode->i_op = &ext4_file_inode_operations;
@@ -1759,7 +1759,7 @@ retry:if (IS_DIRSYNC (dir)) handle->h_sync =1 ; - inode =ext4_new_inode (handle, dir, mode); + inode =ext4_new_inode (handle, dir, mode,0 ); err =PTR_ERR (inode);if (!IS_ERR (inode)) {init_special_inode (inode, inode->i_mode, rdev);
@@ -1795,7 +1795,7 @@ retry:if (IS_DIRSYNC (dir)) handle->h_sync =1 ; - inode =ext4_new_inode (handle, dir,S_IFDIR | mode); + inode =ext4_new_inode (handle, dir,S_IFDIR | mode,0 ); err =PTR_ERR (inode);if (IS_ERR (inode)) goto out_stop;
@@ -2195,7 +2195,7 @@ retry:if (IS_DIRSYNC (dir)) handle->h_sync =1 ; - inode =ext4_new_inode (handle, dir,S_IFLNK |S_IRWXUGO ); + inode =ext4_new_inode (handle, dir,S_IFLNK |S_IRWXUGO ,0 ); err =PTR_ERR (inode);if (IS_ERR (inode)) goto out_stop;
fs/ext4/migrate.c +2 -3
@@ -482,9 +482,8 @@ int ext4_ext_migrate(struct inode *inode retval =PTR_ERR (handle); goto err_out; } - tmp_inode =ext4_new_inode (handle, - inode->i_sb->s_root->d_inode, -S_IFREG ); + tmp_inode =ext4_new_inode (handle, inode->i_sb->s_root->d_inode, +S_IFREG ,0 );if (IS_ERR (tmp_inode)) { retval = -ENOMEM ;ext4_journal_stop (handle);
fs/ext4/ext4.h +2 -1
@@ -1033,7 +1033,8 @@ extern int ext4fs_dirhash(const char *na dx_hash_info *hinfo);/* ialloc.c */ -extern struct inode *ext4_new_inode (handle_t *,struct inode *,int ); +extern struct inode *ext4_new_inode (handle_t *,struct inode *,int , +unsigned long );extern void ext4_free_inode (handle_t *,struct inode *);extern struct inode *ext4_orphan_get (struct super_block *,unsigned long );extern unsigned long ext4_count_free_inodes (struct super_block *);