1 vfs: add find_active_inode_nowait() function
3 Add a new function find_active_inode_nowait() which will never block.
4 If there is an inode being freed or is still being initialized, this
5 function will return NULL instead of blocking waiting for an inode to
6 be freed or to finish initializing. Hence, a negative return from
7 this function does not mean that inode number is free for use. It is
8 useful for callers that want to opportunistically do some work on an
9 inode only if it is present and available in the cache, and where
10 blocking is not an option.
12 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
14 diff --git a/fs/inode.c b/fs/inode.c
15 index 8ceaa09..f9ad3fa 100644
18 @@ -1283,6 +1283,42 @@ struct inode *ilookup(struct super_block *sb, unsigned long ino)
20 EXPORT_SYMBOL(ilookup);
23 + * find_active_inode_nowait - find an active inode in the inode cache
24 + * @sb: super block of file system to search
25 + * @ino: inode number to search for
27 + * Search for an active inode @ino in the inode cache, and if the
28 + * inode is in the cache, the inode is returned with an incremented
29 + * reference count. If the inode is being freed or is newly
30 + * initialized, return nothing instead of trying to wait for the inode
31 + * initialization or destruction to be complete.
33 +struct inode *find_active_inode_nowait(struct super_block *sb,
36 + struct hlist_head *head = inode_hashtable + hash(sb, ino);
37 + struct inode *inode, *ret_inode = NULL;
39 + spin_lock(&inode_hash_lock);
40 + hlist_for_each_entry(inode, head, i_hash) {
41 + if ((inode->i_ino != ino) ||
42 + (inode->i_sb != sb))
44 + spin_lock(&inode->i_lock);
45 + if ((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW)) == 0) {
49 + spin_unlock(&inode->i_lock);
53 + spin_unlock(&inode_hash_lock);
56 +EXPORT_SYMBOL(find_active_inode_nowait);
58 int insert_inode_locked(struct inode *inode)
60 struct super_block *sb = inode->i_sb;
61 diff --git a/include/linux/fs.h b/include/linux/fs.h
62 index ff252cb..b24ad99 100644
63 --- a/include/linux/fs.h
64 +++ b/include/linux/fs.h
65 @@ -2414,6 +2414,8 @@ extern struct inode *ilookup(struct super_block *sb, unsigned long ino);
67 extern struct inode * iget5_locked(struct super_block *, unsigned long, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *);
68 extern struct inode * iget_locked(struct super_block *, unsigned long);
69 +extern struct inode *find_active_inode_nowait(struct super_block *,
71 extern int insert_inode_locked4(struct inode *, unsigned long, int (*test)(struct inode *, void *), void *);
72 extern int insert_inode_locked(struct inode *);
73 #ifdef CONFIG_DEBUG_LOCK_ALLOC