diff options
-rw-r--r-- | fs/inode.c | 45 | ||||
-rw-r--r-- | include/linux/fs.h | 3 |
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 | */ |
772 | static inline struct inode *ifind(struct super_block *sb, | 773 | static 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 | */ | ||
845 | struct 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 | |||
853 | EXPORT_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 | ||
849 | EXPORT_SYMBOL(ilookup5); | 882 | EXPORT_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); | |||
1441 | extern void generic_delete_inode(struct inode *inode); | 1441 | extern void generic_delete_inode(struct inode *inode); |
1442 | extern void generic_drop_inode(struct inode *inode); | 1442 | extern void generic_drop_inode(struct inode *inode); |
1443 | 1443 | ||
1444 | extern struct inode *ilookup5_nowait(struct super_block *sb, | ||
1445 | unsigned long hashval, int (*test)(struct inode *, void *), | ||
1446 | void *data); | ||
1444 | extern struct inode *ilookup5(struct super_block *sb, unsigned long hashval, | 1447 | extern 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); |
1446 | extern struct inode *ilookup(struct super_block *sb, unsigned long ino); | 1449 | extern struct inode *ilookup(struct super_block *sb, unsigned long ino); |