summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2020-11-05 11:57:44 -0500
committerKent Overstreet <kent.overstreet@gmail.com>2020-12-07 11:50:45 -0500
commitbcd3af86fe34c5d2cdea08e8eddd3b1b086b5187 (patch)
tree1ff5e4c4acbb4ae86c5fc3aab1b730cdc7a8c03d
parentcfe795f5292eba4bbfd207595b6168ba2d569e66 (diff)
fs: Delete duplicated code in fs/inode.c
There are many functions related to the inode hash table which have had more general versions added that duplicate the code in earlier simpler versions. - iget_locked() -> iget5_locked() - ilookup() -> ilookup5 - insert_inode_locked() -> insert_inode_locked4() - find_inode_by_ino_rcu() -> find_inode_rcu() Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r--fs/inode.c163
1 files changed, 16 insertions, 147 deletions
diff --git a/fs/inode.c b/fs/inode.c
index ed16ac959c60..8f779180c030 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -811,31 +811,19 @@ repeat:
return NULL;
}
-/*
- * find_inode_fast is the fast path version of find_inode, see the comment at
- * iget_locked for details.
- */
-static struct inode *find_inode_fast(struct super_block *sb,
- struct hlist_head *head, unsigned long ino)
+static int inum_test(struct inode *inode, void *p)
{
- struct inode *inode = NULL;
+ unsigned long *ino = p;
-repeat:
- hlist_for_each_entry(inode, head, i_hash) {
- if (inode->i_ino != ino)
- continue;
- if (inode->i_sb != sb)
- continue;
- spin_lock(&inode->i_lock);
- if (inode->i_state & (I_FREEING|I_WILL_FREE)) {
- __wait_on_freeing_inode(inode);
- goto repeat;
- }
- __iget(inode);
- spin_unlock(&inode->i_lock);
- return inode;
- }
- return NULL;
+ return *ino == inode->i_ino;
+}
+
+static int inum_set(struct inode *inode, void *p)
+{
+ unsigned long *ino = p;
+
+ inode->i_ino = *ino;
+ return 0;
}
/*
@@ -1152,62 +1140,7 @@ EXPORT_SYMBOL(iget5_locked);
*/
struct inode *iget_locked(struct super_block *sb, unsigned long ino)
{
- struct hlist_head *head = inode_hashtable + hash(sb, ino);
- struct inode *inode;
-again:
- spin_lock(&inode_hash_lock);
- inode = find_inode_fast(sb, head, ino);
- spin_unlock(&inode_hash_lock);
- if (inode) {
- if (IS_ERR(inode))
- return NULL;
- wait_on_inode(inode);
- if (unlikely(inode_unhashed(inode))) {
- iput(inode);
- goto again;
- }
- return inode;
- }
-
- inode = new_inode_pseudo(sb);
- if (inode) {
- struct inode *old;
-
- spin_lock(&inode_hash_lock);
- /* We released the lock, so.. */
- old = find_inode_fast(sb, head, ino);
- if (!old) {
- inode->i_ino = ino;
- spin_lock(&inode->i_lock);
- inode->i_state = I_NEW;
- hlist_add_head_rcu(&inode->i_hash, head);
- spin_unlock(&inode->i_lock);
- inode_sb_list_add(inode);
- spin_unlock(&inode_hash_lock);
-
- /* Return the locked inode with I_NEW set, the
- * caller is responsible for filling in the contents
- */
- return inode;
- }
-
- /*
- * Uhhuh, somebody else created the same inode under
- * us. Use the old inode instead of the one we just
- * allocated.
- */
- spin_unlock(&inode_hash_lock);
- destroy_inode(inode);
- if (IS_ERR(old))
- return NULL;
- inode = old;
- wait_on_inode(inode);
- if (unlikely(inode_unhashed(inode))) {
- iput(inode);
- goto again;
- }
- }
- return inode;
+ return iget5_locked(sb, hash(sb, ino), inum_test, inum_set, &ino);
}
EXPORT_SYMBOL(iget_locked);
@@ -1362,23 +1295,7 @@ EXPORT_SYMBOL(ilookup5);
*/
struct inode *ilookup(struct super_block *sb, unsigned long ino)
{
- struct hlist_head *head = inode_hashtable + hash(sb, ino);
- struct inode *inode;
-again:
- spin_lock(&inode_hash_lock);
- inode = find_inode_fast(sb, head, ino);
- spin_unlock(&inode_hash_lock);
-
- if (inode) {
- if (IS_ERR(inode))
- return NULL;
- wait_on_inode(inode);
- if (unlikely(inode_unhashed(inode))) {
- iput(inode);
- goto again;
- }
- }
- return inode;
+ return ilookup5(sb, hash(sb, ino), inum_test, &ino);
}
EXPORT_SYMBOL(ilookup);
@@ -1444,61 +1361,14 @@ EXPORT_SYMBOL(find_inode_rcu);
struct inode *find_inode_by_ino_rcu(struct super_block *sb,
unsigned long ino)
{
- struct hlist_head *head = inode_hashtable + hash(sb, ino);
- struct inode *inode;
-
- RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
- "suspicious find_inode_by_ino_rcu() usage");
-
- hlist_for_each_entry_rcu(inode, head, i_hash) {
- if (inode->i_ino == ino &&
- inode->i_sb == sb &&
- !(READ_ONCE(inode->i_state) & (I_FREEING | I_WILL_FREE)))
- return inode;
- }
- return NULL;
+ return find_inode_rcu(sb, ino, inum_test, &ino);
}
EXPORT_SYMBOL(find_inode_by_ino_rcu);
int insert_inode_locked(struct inode *inode)
{
- struct super_block *sb = inode->i_sb;
- ino_t ino = inode->i_ino;
- struct hlist_head *head = inode_hashtable + hash(sb, ino);
-
- while (1) {
- struct inode *old = NULL;
- spin_lock(&inode_hash_lock);
- hlist_for_each_entry(old, head, i_hash) {
- if (old->i_ino != ino)
- continue;
- if (old->i_sb != sb)
- continue;
- spin_lock(&old->i_lock);
- if (old->i_state & (I_FREEING|I_WILL_FREE)) {
- spin_unlock(&old->i_lock);
- continue;
- }
- break;
- }
- if (likely(!old)) {
- spin_lock(&inode->i_lock);
- inode->i_state |= I_NEW;
- hlist_add_head_rcu(&inode->i_hash, head);
- spin_unlock(&inode->i_lock);
- spin_unlock(&inode_hash_lock);
- return 0;
- }
- __iget(old);
- spin_unlock(&old->i_lock);
- spin_unlock(&inode_hash_lock);
- wait_on_inode(old);
- if (unlikely(!inode_unhashed(old))) {
- iput(old);
- return -EBUSY;
- }
- iput(old);
- }
+ return insert_inode_locked4(inode, hash(inode->i_sb, inode->i_ino),
+ inum_test, &inode->i_ino);
}
EXPORT_SYMBOL(insert_inode_locked);
@@ -1517,7 +1387,6 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval,
}
EXPORT_SYMBOL(insert_inode_locked4);
-
int generic_delete_inode(struct inode *inode)
{
return 1;