Use a script to test tmpfs, after 10 days, there will be files share the same inode number, thus bug happens. The script is as follows: while(1) { create a file dlopen it ... remove it } I have tried to change last_ino type to unsigned long, while this was rejected, see details on https://patchwork.kernel.org/patch/11023915. Use ida to get inode number, from the fs_mark test, performance impact is small. CPU core: 128 memory: 8G Use fs_mark to create ten million files first in tmpfs. Then test performance in the following command(test five times): rm -rf /tmp/fsmark_test sync echo 3 > /proc/sys/vm/drop_caches sleep 10 fs_mark -t 20 -s 0 -n 102400 -D 64 -N 1600 -L 3 -d /tmp/fsmark_test result is file creation speed(Files/sec). get_next_ino | use ida 439506.7 | 423219.0 441453.0 | 406832.7 439868.0 | 441283.3 445642.3 | 428221.3 441776.7 | 438129.0 average: 441649.34 | 427537.06 Signed-off-by: zhengbin <zhengbin13@xxxxxxxxxx> --- mm/shmem.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/mm/shmem.c b/mm/shmem.c index 5b93877..6b5e01b 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -258,6 +258,7 @@ static const struct inode_operations shmem_dir_inode_operations; static const struct inode_operations shmem_special_inode_operations; static const struct vm_operations_struct shmem_vm_ops; static struct file_system_type shmem_fs_type; +static DEFINE_IDA(shmem_inode_ida); bool vma_is_shmem(struct vm_area_struct *vma) { @@ -1138,6 +1139,7 @@ static void shmem_evict_inode(struct inode *inode) simple_xattrs_free(&info->xattrs); WARN_ON(inode->i_blocks); + ida_simple_remove(&shmem_inode_ida, inode->i_ino); shmem_free_inode(inode->i_sb); clear_inode(inode); } @@ -2213,13 +2215,20 @@ static struct inode *shmem_get_inode(struct super_block *sb, const struct inode struct inode *inode; struct shmem_inode_info *info; struct shmem_sb_info *sbinfo = SHMEM_SB(sb); + int i_ino; if (shmem_reserve_inode(sb)) return NULL; + i_ino = ida_simple_get(&shmem_inode_ida, 0, 0, GFP_KERNEL); + if (i_ino < 0) { + shmem_free_inode(sb); + return NULL; + } + inode = new_inode(sb); if (inode) { - inode->i_ino = get_next_ino(); + inode->i_ino = i_ino; inode_init_owner(inode, dir, mode); inode->i_blocks = 0; inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode); @@ -2263,8 +2272,11 @@ static struct inode *shmem_get_inode(struct super_block *sb, const struct inode } lockdep_annotate_inode_mutex_key(inode); - } else + } else { + ida_simple_remove(&shmem_inode_ida, i_ino); shmem_free_inode(sb); + } + return inode; } -- 2.7.4