From mboxrd@z Thu Jan 1 00:00:00 1970 From: "J. R. Okajima" Subject: [PATCH v2 1/2] tmpfs: manage the inode-number by IDR Date: Fri, 30 May 2014 00:46:16 +0900 Message-ID: <1401378377-30757-1-git-send-email-hooanon05g@gmail.com> References: <20140522151431.GA25517@lst.de> To: linux-fsdevel@vger.kernel.org, dchinner@redhat.com, viro@zeniv.linux.org.uk, Eric Dumazet , Hugh Dickins , Christoph Hellwig , Andreas Dilger , Jan Kara Return-path: Received: from mail05-md.ns.itscom.net ([175.177.155.115]:60342 "EHLO mail05-md.ns.itscom.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932848AbaE2PqV (ORCPT ); Thu, 29 May 2014 11:46:21 -0400 In-Reply-To: <20140522151431.GA25517@lst.de> Sender: linux-fsdevel-owner@vger.kernel.org List-ID: To ensure the uniquness of the inode-number, manage it by IDR. Also it tries using the lowest unused inode-number, so the value will usually be smaller. Cc: Eric Dumazet Cc: Hugh Dickins Cc: Christoph Hellwig Cc: Andreas Dilger Cc: Jan Kara Signed-off-by: J. R. Okajima --- include/linux/shmem_fs.h | 2 ++ mm/shmem.c | 20 +++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index 4d1771c..30c75f0 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -24,6 +24,8 @@ struct shmem_inode_info { }; struct shmem_sb_info { + struct mutex idr_lock; + struct idr idr; /* manages inode-number */ unsigned long max_blocks; /* How many blocks are allowed */ struct percpu_counter used_blocks; /* How many are allocated */ unsigned long max_inodes; /* How many inodes are allowed */ diff --git a/mm/shmem.c b/mm/shmem.c index 368f314..440db70 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -569,6 +569,7 @@ static int shmem_setattr(struct dentry *dentry, struct iattr *attr) static void shmem_evict_inode(struct inode *inode) { struct shmem_inode_info *info = SHMEM_I(inode); + struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb); if (inode->i_mapping->a_ops == &shmem_aops) { shmem_unacct_size(info->flags, inode->i_size); @@ -584,6 +585,9 @@ static void shmem_evict_inode(struct inode *inode) simple_xattrs_free(&info->xattrs); WARN_ON(inode->i_blocks); + mutex_lock(&sbinfo->idr_lock); + idr_remove(&sbinfo->idr, inode->i_ino); + mutex_unlock(&sbinfo->idr_lock); shmem_free_inode(inode->i_sb); clear_inode(inode); } @@ -1315,13 +1319,13 @@ 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); + long long ino; /* signed to detect an error */ if (shmem_reserve_inode(sb)) return NULL; inode = new_inode(sb); if (inode) { - inode->i_ino = get_next_ino(); inode_init_owner(inode, dir, mode); inode->i_blocks = 0; inode->i_mapping->backing_dev_info = &shmem_backing_dev_info; @@ -1362,6 +1366,17 @@ static struct inode *shmem_get_inode(struct super_block *sb, const struct inode mpol_shared_policy_init(&info->policy, NULL); break; } + + /* inum 0 and 1 are unused */ + mutex_lock(&sbinfo->idr_lock); + ino = idr_alloc(&sbinfo->idr, inode, 2, UINT_MAX, GFP_NOFS); + if (ino > 0) + inode->i_ino = ino; + mutex_unlock(&sbinfo->idr_lock); + if (unlikely(ino < 0)) { + iput(inode); /* shmem_free_inode() will be called */ + inode = NULL; + } } else shmem_free_inode(sb); return inode; @@ -2504,6 +2519,7 @@ static void shmem_put_super(struct super_block *sb) { struct shmem_sb_info *sbinfo = SHMEM_SB(sb); + idr_destroy(&sbinfo->idr); percpu_counter_destroy(&sbinfo->used_blocks); mpol_put(sbinfo->mpol); kfree(sbinfo); @@ -2522,6 +2538,8 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) if (!sbinfo) return -ENOMEM; + mutex_init(&sbinfo->idr_lock); + idr_init(&sbinfo->idr); sbinfo->mode = S_IRWXUGO | S_ISVTX; sbinfo->uid = current_fsuid(); sbinfo->gid = current_fsgid(); -- 1.7.10.4