From ce3cb07bda998e7f6390de0e5c326bdfce8a307e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 30 Dec 2008 01:48:21 -0500 Subject: [PATCH] --- yaml --- r: 125009 b: refs/heads/master c: 261bca86ed4f7f391d1938167624e78da61dcc6b h: refs/heads/master i: 125007: a8cf452cda3935070ca272eafdbe8d6a52c694d8 v: v3 --- [refs] | 2 +- trunk/fs/inode.c | 59 ++++++++++++++++++++++++++++++++++++++++ trunk/include/linux/fs.h | 2 ++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 3cbbf3e66623..b8a8c33b3444 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 272eb01485dda98e3b8910c7c1a53d597616b0a0 +refs/heads/master: 261bca86ed4f7f391d1938167624e78da61dcc6b diff --git a/trunk/fs/inode.c b/trunk/fs/inode.c index 098a2443196f..7de1cda92489 100644 --- a/trunk/fs/inode.c +++ b/trunk/fs/inode.c @@ -1032,6 +1032,65 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino) EXPORT_SYMBOL(iget_locked); +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); + struct inode *old; + + inode->i_state |= I_LOCK|I_NEW; + while (1) { + spin_lock(&inode_lock); + old = find_inode_fast(sb, head, ino); + if (likely(!old)) { + hlist_add_head(&inode->i_hash, head); + spin_unlock(&inode_lock); + return 0; + } + __iget(old); + spin_unlock(&inode_lock); + wait_on_inode(old); + if (unlikely(!hlist_unhashed(&old->i_hash))) { + iput(old); + return -EBUSY; + } + iput(old); + } +} + +EXPORT_SYMBOL(insert_inode_locked); + +int insert_inode_locked4(struct inode *inode, unsigned long hashval, + int (*test)(struct inode *, void *), void *data) +{ + struct super_block *sb = inode->i_sb; + struct hlist_head *head = inode_hashtable + hash(sb, hashval); + struct inode *old; + + inode->i_state |= I_LOCK|I_NEW; + + while (1) { + spin_lock(&inode_lock); + old = find_inode(sb, head, test, data); + if (likely(!old)) { + hlist_add_head(&inode->i_hash, head); + spin_unlock(&inode_lock); + return 0; + } + __iget(old); + spin_unlock(&inode_lock); + wait_on_inode(old); + if (unlikely(!hlist_unhashed(&old->i_hash))) { + iput(old); + return -EBUSY; + } + iput(old); + } +} + +EXPORT_SYMBOL(insert_inode_locked4); + /** * __insert_inode_hash - hash an inode * @inode: unhashed inode diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index be16ce01fb1b..e2170ee21e18 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -1902,6 +1902,8 @@ extern struct inode *ilookup(struct super_block *sb, unsigned long ino); extern struct inode * iget5_locked(struct super_block *, unsigned long, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *); extern struct inode * iget_locked(struct super_block *, unsigned long); +extern int insert_inode_locked4(struct inode *, unsigned long, int (*test)(struct inode *, void *), void *); +extern int insert_inode_locked(struct inode *); extern void unlock_new_inode(struct inode *); extern void __iget(struct inode * inode);