Commit 81ee1bad86bd6752c626018d43a74e3f81f1ae72
Exists in
master
and in
20 other branches
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: ext3/4 with synchronous writes gets wedged by Postfix Fix nobh_truncate_page() to not pass stack garbage to get_block()
Showing 2 changed files Side-by-side Diff
fs/buffer.c
fs/inode.c
... | ... | @@ -1053,13 +1053,22 @@ |
1053 | 1053 | struct super_block *sb = inode->i_sb; |
1054 | 1054 | ino_t ino = inode->i_ino; |
1055 | 1055 | struct hlist_head *head = inode_hashtable + hash(sb, ino); |
1056 | - struct inode *old; | |
1057 | 1056 | |
1058 | 1057 | inode->i_state |= I_LOCK|I_NEW; |
1059 | 1058 | while (1) { |
1059 | + struct hlist_node *node; | |
1060 | + struct inode *old = NULL; | |
1060 | 1061 | spin_lock(&inode_lock); |
1061 | - old = find_inode_fast(sb, head, ino); | |
1062 | - if (likely(!old)) { | |
1062 | + hlist_for_each_entry(old, node, head, i_hash) { | |
1063 | + if (old->i_ino != ino) | |
1064 | + continue; | |
1065 | + if (old->i_sb != sb) | |
1066 | + continue; | |
1067 | + if (old->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) | |
1068 | + continue; | |
1069 | + break; | |
1070 | + } | |
1071 | + if (likely(!node)) { | |
1063 | 1072 | hlist_add_head(&inode->i_hash, head); |
1064 | 1073 | spin_unlock(&inode_lock); |
1065 | 1074 | return 0; |
1066 | 1075 | |
1067 | 1076 | |
... | ... | @@ -1081,14 +1090,24 @@ |
1081 | 1090 | { |
1082 | 1091 | struct super_block *sb = inode->i_sb; |
1083 | 1092 | struct hlist_head *head = inode_hashtable + hash(sb, hashval); |
1084 | - struct inode *old; | |
1085 | 1093 | |
1086 | 1094 | inode->i_state |= I_LOCK|I_NEW; |
1087 | 1095 | |
1088 | 1096 | while (1) { |
1097 | + struct hlist_node *node; | |
1098 | + struct inode *old = NULL; | |
1099 | + | |
1089 | 1100 | spin_lock(&inode_lock); |
1090 | - old = find_inode(sb, head, test, data); | |
1091 | - if (likely(!old)) { | |
1101 | + hlist_for_each_entry(old, node, head, i_hash) { | |
1102 | + if (old->i_sb != sb) | |
1103 | + continue; | |
1104 | + if (!test(old, data)) | |
1105 | + continue; | |
1106 | + if (old->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) | |
1107 | + continue; | |
1108 | + break; | |
1109 | + } | |
1110 | + if (likely(!node)) { | |
1092 | 1111 | hlist_add_head(&inode->i_hash, head); |
1093 | 1112 | spin_unlock(&inode_lock); |
1094 | 1113 | return 0; |