diff options
| -rw-r--r-- | fs/inode.c | 59 | ||||
| -rw-r--r-- | include/linux/fs.h | 2 |
2 files changed, 61 insertions, 0 deletions
diff --git a/fs/inode.c b/fs/inode.c index 098a2443196f..7de1cda92489 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
| @@ -1032,6 +1032,65 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino) | |||
| 1032 | 1032 | ||
| 1033 | EXPORT_SYMBOL(iget_locked); | 1033 | EXPORT_SYMBOL(iget_locked); |
| 1034 | 1034 | ||
| 1035 | int insert_inode_locked(struct inode *inode) | ||
| 1036 | { | ||
| 1037 | struct super_block *sb = inode->i_sb; | ||
| 1038 | ino_t ino = inode->i_ino; | ||
| 1039 | struct hlist_head *head = inode_hashtable + hash(sb, ino); | ||
| 1040 | struct inode *old; | ||
| 1041 | |||
| 1042 | inode->i_state |= I_LOCK|I_NEW; | ||
| 1043 | while (1) { | ||
| 1044 | spin_lock(&inode_lock); | ||
| 1045 | old = find_inode_fast(sb, head, ino); | ||
| 1046 | if (likely(!old)) { | ||
| 1047 | hlist_add_head(&inode->i_hash, head); | ||
| 1048 | spin_unlock(&inode_lock); | ||
| 1049 | return 0; | ||
| 1050 | } | ||
| 1051 | __iget(old); | ||
| 1052 | spin_unlock(&inode_lock); | ||
| 1053 | wait_on_inode(old); | ||
| 1054 | if (unlikely(!hlist_unhashed(&old->i_hash))) { | ||
| 1055 | iput(old); | ||
| 1056 | return -EBUSY; | ||
| 1057 | } | ||
| 1058 | iput(old); | ||
| 1059 | } | ||
| 1060 | } | ||
| 1061 | |||
| 1062 | EXPORT_SYMBOL(insert_inode_locked); | ||
| 1063 | |||
| 1064 | int insert_inode_locked4(struct inode *inode, unsigned long hashval, | ||
| 1065 | int (*test)(struct inode *, void *), void *data) | ||
| 1066 | { | ||
| 1067 | struct super_block *sb = inode->i_sb; | ||
| 1068 | struct hlist_head *head = inode_hashtable + hash(sb, hashval); | ||
| 1069 | struct inode *old; | ||
| 1070 | |||
| 1071 | inode->i_state |= I_LOCK|I_NEW; | ||
| 1072 | |||
| 1073 | while (1) { | ||
| 1074 | spin_lock(&inode_lock); | ||
| 1075 | old = find_inode(sb, head, test, data); | ||
| 1076 | if (likely(!old)) { | ||
| 1077 | hlist_add_head(&inode->i_hash, head); | ||
| 1078 | spin_unlock(&inode_lock); | ||
| 1079 | return 0; | ||
| 1080 | } | ||
| 1081 | __iget(old); | ||
| 1082 | spin_unlock(&inode_lock); | ||
| 1083 | wait_on_inode(old); | ||
| 1084 | if (unlikely(!hlist_unhashed(&old->i_hash))) { | ||
| 1085 | iput(old); | ||
| 1086 | return -EBUSY; | ||
| 1087 | } | ||
| 1088 | iput(old); | ||
| 1089 | } | ||
| 1090 | } | ||
| 1091 | |||
| 1092 | EXPORT_SYMBOL(insert_inode_locked4); | ||
| 1093 | |||
| 1035 | /** | 1094 | /** |
| 1036 | * __insert_inode_hash - hash an inode | 1095 | * __insert_inode_hash - hash an inode |
| 1037 | * @inode: unhashed inode | 1096 | * @inode: unhashed inode |
diff --git a/include/linux/fs.h b/include/linux/fs.h index be16ce01fb1b..e2170ee21e18 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -1902,6 +1902,8 @@ extern struct inode *ilookup(struct super_block *sb, unsigned long ino); | |||
| 1902 | 1902 | ||
| 1903 | extern struct inode * iget5_locked(struct super_block *, unsigned long, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *); | 1903 | extern struct inode * iget5_locked(struct super_block *, unsigned long, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *); |
| 1904 | extern struct inode * iget_locked(struct super_block *, unsigned long); | 1904 | extern struct inode * iget_locked(struct super_block *, unsigned long); |
| 1905 | extern int insert_inode_locked4(struct inode *, unsigned long, int (*test)(struct inode *, void *), void *); | ||
| 1906 | extern int insert_inode_locked(struct inode *); | ||
| 1905 | extern void unlock_new_inode(struct inode *); | 1907 | extern void unlock_new_inode(struct inode *); |
| 1906 | 1908 | ||
| 1907 | extern void __iget(struct inode * inode); | 1909 | extern void __iget(struct inode * inode); |
