diff options
author | Nick Piggin <npiggin@suse.de> | 2010-01-29 15:38:34 -0800 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2010-04-27 17:32:55 +0200 |
commit | 973d7b552f168e9a895cbf0df7711de126f2b638 (patch) | |
tree | 8e1d5e37e056dcc53e2da9051ff875b558acf510 | |
parent | c8c34fe3ba9b739aa495e2f295ac8d46b479567a (diff) | |
download | lwn-973d7b552f168e9a895cbf0df7711de126f2b638.tar.gz lwn-973d7b552f168e9a895cbf0df7711de126f2b638.zip |
fs-inode-hash-rcu
Signed-off-by: Nick Piggin <npiggin@suse.de>
Signed-off-by: John Stultz <johnstul@us.ibm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | fs/inode.c | 38 |
1 files changed, 20 insertions, 18 deletions
diff --git a/fs/inode.c b/fs/inode.c index fdd682265869..fc9973a57afc 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -607,26 +607,27 @@ static struct inode *find_inode(struct super_block *sb, struct inode *inode = NULL; repeat: - spin_lock(&b->lock); - hlist_for_each_entry(inode, node, &b->head, i_hash) { + rcu_read_lock(); + hlist_for_each_entry_rcu(inode, node, &b->head, i_hash) { if (inode->i_sb != sb) continue; - if (!spin_trylock(&inode->i_lock)) { - spin_unlock(&b->lock); - goto repeat; + spin_lock(&inode->i_lock); + if (hlist_unhashed(&inode->i_hash)) { + spin_unlock(&inode->i_lock); + continue; } if (!test(inode, data)) { spin_unlock(&inode->i_lock); continue; } if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) { - spin_unlock(&b->lock); + rcu_read_unlock(); __wait_on_freeing_inode(inode); goto repeat; } break; } - spin_unlock(&b->lock); + rcu_read_unlock(); return node ? inode : NULL; } @@ -642,24 +643,25 @@ static struct inode *find_inode_fast(struct super_block *sb, struct inode *inode = NULL; repeat: - spin_lock(&b->lock); - hlist_for_each_entry(inode, node, &b->head, i_hash) { + rcu_read_lock(); + hlist_for_each_entry_rcu(inode, node, &b->head, i_hash) { if (inode->i_ino != ino) continue; if (inode->i_sb != sb) continue; - if (!spin_trylock(&inode->i_lock)) { - spin_unlock(&b->lock); - goto repeat; + spin_lock(&inode->i_lock); + if (hlist_unhashed(&inode->i_hash)) { + spin_unlock(&inode->i_lock); + continue; } if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) { - spin_unlock(&b->lock); + rcu_read_unlock(); __wait_on_freeing_inode(inode); goto repeat; } break; } - spin_unlock(&b->lock); + rcu_read_unlock(); return node ? inode : NULL; } @@ -943,14 +945,14 @@ static int test_inode_iunique(struct super_block *sb, struct hlist_node *node; struct inode *inode = NULL; - spin_lock(&b->lock); - hlist_for_each_entry(inode, node, &b->head, i_hash) { + rcu_read_lock(); + hlist_for_each_entry_rcu(inode, node, &b->head, i_hash) { if (inode->i_ino == ino && inode->i_sb == sb) { - spin_unlock(&b->lock); + rcu_read_unlock(); return 0; } } - spin_unlock(&b->lock); + rcu_read_unlock(); return 1; } |