diff options
Diffstat (limited to 'fs/inode.c')
-rw-r--r-- | fs/inode.c | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/fs/inode.c b/fs/inode.c index 0571983755dc..bca0c618fdb3 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -219,6 +219,7 @@ static struct inode *alloc_inode(struct super_block *sb) | |||
219 | void destroy_inode(struct inode *inode) | 219 | void destroy_inode(struct inode *inode) |
220 | { | 220 | { |
221 | BUG_ON(inode_has_buffers(inode)); | 221 | BUG_ON(inode_has_buffers(inode)); |
222 | ima_inode_free(inode); | ||
222 | security_inode_free(inode); | 223 | security_inode_free(inode); |
223 | if (inode->i_sb->s_op->destroy_inode) | 224 | if (inode->i_sb->s_op->destroy_inode) |
224 | inode->i_sb->s_op->destroy_inode(inode); | 225 | inode->i_sb->s_op->destroy_inode(inode); |
@@ -1053,13 +1054,22 @@ int insert_inode_locked(struct inode *inode) | |||
1053 | struct super_block *sb = inode->i_sb; | 1054 | struct super_block *sb = inode->i_sb; |
1054 | ino_t ino = inode->i_ino; | 1055 | ino_t ino = inode->i_ino; |
1055 | struct hlist_head *head = inode_hashtable + hash(sb, ino); | 1056 | struct hlist_head *head = inode_hashtable + hash(sb, ino); |
1056 | struct inode *old; | ||
1057 | 1057 | ||
1058 | inode->i_state |= I_LOCK|I_NEW; | 1058 | inode->i_state |= I_LOCK|I_NEW; |
1059 | while (1) { | 1059 | while (1) { |
1060 | struct hlist_node *node; | ||
1061 | struct inode *old = NULL; | ||
1060 | spin_lock(&inode_lock); | 1062 | spin_lock(&inode_lock); |
1061 | old = find_inode_fast(sb, head, ino); | 1063 | hlist_for_each_entry(old, node, head, i_hash) { |
1062 | if (likely(!old)) { | 1064 | if (old->i_ino != ino) |
1065 | continue; | ||
1066 | if (old->i_sb != sb) | ||
1067 | continue; | ||
1068 | if (old->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) | ||
1069 | continue; | ||
1070 | break; | ||
1071 | } | ||
1072 | if (likely(!node)) { | ||
1063 | hlist_add_head(&inode->i_hash, head); | 1073 | hlist_add_head(&inode->i_hash, head); |
1064 | spin_unlock(&inode_lock); | 1074 | spin_unlock(&inode_lock); |
1065 | return 0; | 1075 | return 0; |
@@ -1081,14 +1091,24 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval, | |||
1081 | { | 1091 | { |
1082 | struct super_block *sb = inode->i_sb; | 1092 | struct super_block *sb = inode->i_sb; |
1083 | struct hlist_head *head = inode_hashtable + hash(sb, hashval); | 1093 | struct hlist_head *head = inode_hashtable + hash(sb, hashval); |
1084 | struct inode *old; | ||
1085 | 1094 | ||
1086 | inode->i_state |= I_LOCK|I_NEW; | 1095 | inode->i_state |= I_LOCK|I_NEW; |
1087 | 1096 | ||
1088 | while (1) { | 1097 | while (1) { |
1098 | struct hlist_node *node; | ||
1099 | struct inode *old = NULL; | ||
1100 | |||
1089 | spin_lock(&inode_lock); | 1101 | spin_lock(&inode_lock); |
1090 | old = find_inode(sb, head, test, data); | 1102 | hlist_for_each_entry(old, node, head, i_hash) { |
1091 | if (likely(!old)) { | 1103 | if (old->i_sb != sb) |
1104 | continue; | ||
1105 | if (!test(old, data)) | ||
1106 | continue; | ||
1107 | if (old->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) | ||
1108 | continue; | ||
1109 | break; | ||
1110 | } | ||
1111 | if (likely(!node)) { | ||
1092 | hlist_add_head(&inode->i_hash, head); | 1112 | hlist_add_head(&inode->i_hash, head); |
1093 | spin_unlock(&inode_lock); | 1113 | spin_unlock(&inode_lock); |
1094 | return 0; | 1114 | return 0; |