Carlos Maiolino: > This V2 looks very reasonable, and fix the problem with files with inode=0 on > tmpfs which I tested here, so, consider it > > Reviewed-by: Carlos Maiolino <cmaiolino@xxxxxxxxxx> Just out of curious, how did you notice the problem of inode=0? I think it is hard for everyone to meet the problem. And after posting the patch, some people reported me a bug related to Sysv shm. This extra patch supports Sysv shm. But I don't like it since it introduces an additional condition into the very normal path. J. R. Okajima diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index ca658a8..fda816e 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -25,6 +25,7 @@ struct shmem_inode_info { struct shmem_sb_info { struct mutex idr_lock; + bool idr_nouse; struct idr idr; /* manages inode-number */ unsigned long max_blocks; /* How many blocks are allowed */ struct percpu_counter used_blocks; /* How many are allocated */ diff --git a/mm/shmem.c b/mm/shmem.c index 0aa3b85..5eb75e9 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -648,7 +648,7 @@ static void shmem_evict_inode(struct inode *inode) simple_xattrs_free(&info->xattrs); WARN_ON(inode->i_blocks); - if (inode->i_ino) { + if (!sbinfo->idr_nouse && inode->i_ino) { mutex_lock(&sbinfo->idr_lock); idr_remove(&sbinfo->idr, inode->i_ino); mutex_unlock(&sbinfo->idr_lock); @@ -1423,19 +1423,24 @@ static struct inode *shmem_get_inode(struct super_block *sb, const struct inode break; } - /* inum 0 and 1 are unused */ - mutex_lock(&sbinfo->idr_lock); - ino = idr_alloc(&sbinfo->idr, inode, 2, INT_MAX, GFP_NOFS); - if (ino > 0) { - inode->i_ino = ino; - mutex_unlock(&sbinfo->idr_lock); - __insert_inode_hash(inode, inode->i_ino); - } else { - inode->i_ino = 0; - mutex_unlock(&sbinfo->idr_lock); - iput(inode); /* shmem_free_inode() will be called */ - inode = NULL; - } + if (!sbinfo->idr_nouse) { + /* inum 0 and 1 are unused */ + mutex_lock(&sbinfo->idr_lock); + ino = idr_alloc(&sbinfo->idr, inode, 2, INT_MAX, + GFP_NOFS); + if (ino > 0) { + inode->i_ino = ino; + mutex_unlock(&sbinfo->idr_lock); + __insert_inode_hash(inode, inode->i_ino); + } else { + inode->i_ino = 0; + mutex_unlock(&sbinfo->idr_lock); + iput(inode); + /* shmem_free_inode() will be called */ + inode = NULL; + } + } else + inode->i_ino = get_next_ino(); } else shmem_free_inode(sb); return inode; @@ -2560,7 +2565,8 @@ static void shmem_put_super(struct super_block *sb) { struct shmem_sb_info *sbinfo = SHMEM_SB(sb); - idr_destroy(&sbinfo->idr); + if (!sbinfo->idr_nouse) + idr_destroy(&sbinfo->idr); percpu_counter_destroy(&sbinfo->used_blocks); mpol_put(sbinfo->mpol); kfree(sbinfo); @@ -2682,6 +2688,15 @@ static void shmem_destroy_inodecache(void) kmem_cache_destroy(shmem_inode_cachep); } +static __init void shmem_no_idr(struct super_block *sb) +{ + struct shmem_sb_info *sbinfo; + + sbinfo = SHMEM_SB(sb); + sbinfo->idr_nouse = true; + idr_destroy(&sbinfo->idr); +} + static const struct address_space_operations shmem_aops = { .writepage = shmem_writepage, .set_page_dirty = __set_page_dirty_no_writeback, @@ -2814,6 +2829,7 @@ int __init shmem_init(void) printk(KERN_ERR "Could not kern_mount tmpfs\n"); goto out1; } + shmem_no_idr(shm_mnt->mnt_sb); return 0; out1: -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html