aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/inode.c45
-rw-r--r--include/linux/fs.h3
2 files changed, 42 insertions, 6 deletions
diff --git a/fs/inode.c b/fs/inode.c
index 96364fae0844..e57f1724db3e 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -757,6 +757,7 @@ EXPORT_SYMBOL(igrab);
757 * @head: the head of the list to search 757 * @head: the head of the list to search
758 * @test: callback used for comparisons between inodes 758 * @test: callback used for comparisons between inodes
759 * @data: opaque data pointer to pass to @test 759 * @data: opaque data pointer to pass to @test
760 * @wait: if true wait for the inode to be unlocked, if false do not
760 * 761 *
761 * ifind() searches for the inode specified by @data in the inode 762 * ifind() searches for the inode specified by @data in the inode
762 * cache. This is a generalized version of ifind_fast() for file systems where 763 * cache. This is a generalized version of ifind_fast() for file systems where
@@ -771,7 +772,7 @@ EXPORT_SYMBOL(igrab);
771 */ 772 */
772static inline struct inode *ifind(struct super_block *sb, 773static inline struct inode *ifind(struct super_block *sb,
773 struct hlist_head *head, int (*test)(struct inode *, void *), 774 struct hlist_head *head, int (*test)(struct inode *, void *),
774 void *data) 775 void *data, const int wait)
775{ 776{
776 struct inode *inode; 777 struct inode *inode;
777 778
@@ -780,7 +781,8 @@ static inline struct inode *ifind(struct super_block *sb,
780 if (inode) { 781 if (inode) {
781 __iget(inode); 782 __iget(inode);
782 spin_unlock(&inode_lock); 783 spin_unlock(&inode_lock);
783 wait_on_inode(inode); 784 if (likely(wait))
785 wait_on_inode(inode);
784 return inode; 786 return inode;
785 } 787 }
786 spin_unlock(&inode_lock); 788 spin_unlock(&inode_lock);
@@ -820,7 +822,7 @@ static inline struct inode *ifind_fast(struct super_block *sb,
820} 822}
821 823
822/** 824/**
823 * ilookup5 - search for an inode in the inode cache 825 * ilookup5_nowait - search for an inode in the inode cache
824 * @sb: super block of file system to search 826 * @sb: super block of file system to search
825 * @hashval: hash value (usually inode number) to search for 827 * @hashval: hash value (usually inode number) to search for
826 * @test: callback used for comparisons between inodes 828 * @test: callback used for comparisons between inodes
@@ -832,7 +834,38 @@ static inline struct inode *ifind_fast(struct super_block *sb,
832 * identification of an inode. 834 * identification of an inode.
833 * 835 *
834 * If the inode is in the cache, the inode is returned with an incremented 836 * If the inode is in the cache, the inode is returned with an incremented
835 * reference count. 837 * reference count. Note, the inode lock is not waited upon so you have to be
838 * very careful what you do with the returned inode. You probably should be
839 * using ilookup5() instead.
840 *
841 * Otherwise NULL is returned.
842 *
843 * Note, @test is called with the inode_lock held, so can't sleep.
844 */
845struct inode *ilookup5_nowait(struct super_block *sb, unsigned long hashval,
846 int (*test)(struct inode *, void *), void *data)
847{
848 struct hlist_head *head = inode_hashtable + hash(sb, hashval);
849
850 return ifind(sb, head, test, data, 0);
851}
852
853EXPORT_SYMBOL(ilookup5_nowait);
854
855/**
856 * ilookup5 - search for an inode in the inode cache
857 * @sb: super block of file system to search
858 * @hashval: hash value (usually inode number) to search for
859 * @test: callback used for comparisons between inodes
860 * @data: opaque data pointer to pass to @test
861 *
862 * ilookup5() uses ifind() to search for the inode specified by @hashval and
863 * @data in the inode cache. This is a generalized version of ilookup() for
864 * file systems where the inode number is not sufficient for unique
865 * identification of an inode.
866 *
867 * If the inode is in the cache, the inode lock is waited upon and the inode is
868 * returned with an incremented reference count.
836 * 869 *
837 * Otherwise NULL is returned. 870 * Otherwise NULL is returned.
838 * 871 *
@@ -843,7 +876,7 @@ struct inode *ilookup5(struct super_block *sb, unsigned long hashval,
843{ 876{
844 struct hlist_head *head = inode_hashtable + hash(sb, hashval); 877 struct hlist_head *head = inode_hashtable + hash(sb, hashval);
845 878
846 return ifind(sb, head, test, data); 879 return ifind(sb, head, test, data, 1);
847} 880}
848 881
849EXPORT_SYMBOL(ilookup5); 882EXPORT_SYMBOL(ilookup5);
@@ -900,7 +933,7 @@ struct inode *iget5_locked(struct super_block *sb, unsigned long hashval,
900 struct hlist_head *head = inode_hashtable + hash(sb, hashval); 933 struct hlist_head *head = inode_hashtable + hash(sb, hashval);
901 struct inode *inode; 934 struct inode *inode;
902 935
903 inode = ifind(sb, head, test, data); 936 inode = ifind(sb, head, test, data, 1);
904 if (inode) 937 if (inode)
905 return inode; 938 return inode;
906 /* 939 /*
diff --git a/include/linux/fs.h b/include/linux/fs.h
index c9bf3746a9fb..0f53e0124941 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1441,6 +1441,9 @@ extern int inode_needs_sync(struct inode *inode);
1441extern void generic_delete_inode(struct inode *inode); 1441extern void generic_delete_inode(struct inode *inode);
1442extern void generic_drop_inode(struct inode *inode); 1442extern void generic_drop_inode(struct inode *inode);
1443 1443
1444extern struct inode *ilookup5_nowait(struct super_block *sb,
1445 unsigned long hashval, int (*test)(struct inode *, void *),
1446 void *data);
1444extern struct inode *ilookup5(struct super_block *sb, unsigned long hashval, 1447extern struct inode *ilookup5(struct super_block *sb, unsigned long hashval,
1445 int (*test)(struct inode *, void *), void *data); 1448 int (*test)(struct inode *, void *), void *data);
1446extern struct inode *ilookup(struct super_block *sb, unsigned long ino); 1449extern struct inode *ilookup(struct super_block *sb, unsigned long ino);