aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-06 15:18:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-06 15:18:14 -0400
commit81ee1bad86bd6752c626018d43a74e3f81f1ae72 (patch)
treefb4b04433a95989dddd7729be3fe6a3250c90cb5
parent9ccb1aa16cef6316831fef61e4aeaa3784035cb8 (diff)
parent72a43d63cb51057393edfbcfc4596066205ad15d (diff)
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()
-rw-r--r--fs/buffer.c2
-rw-r--r--fs/inode.c31
2 files changed, 27 insertions, 6 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index aed297739eb0..49106127a4aa 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2736,6 +2736,8 @@ has_buffers:
2736 pos += blocksize; 2736 pos += blocksize;
2737 } 2737 }
2738 2738
2739 map_bh.b_size = blocksize;
2740 map_bh.b_state = 0;
2739 err = get_block(inode, iblock, &map_bh, 0); 2741 err = get_block(inode, iblock, &map_bh, 0);
2740 if (err) 2742 if (err)
2741 goto unlock; 2743 goto unlock;
diff --git a/fs/inode.c b/fs/inode.c
index 0571983755dc..a4876e561953 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1053,13 +1053,22 @@ int insert_inode_locked(struct inode *inode)
1053 struct super_block *sb = inode->i_sb; 1053 struct super_block *sb = inode->i_sb;
1054 ino_t ino = inode->i_ino; 1054 ino_t ino = inode->i_ino;
1055 struct hlist_head *head = inode_hashtable + hash(sb, ino); 1055 struct hlist_head *head = inode_hashtable + hash(sb, ino);
1056 struct inode *old;
1057 1056
1058 inode->i_state |= I_LOCK|I_NEW; 1057 inode->i_state |= I_LOCK|I_NEW;
1059 while (1) { 1058 while (1) {
1059 struct hlist_node *node;
1060 struct inode *old = NULL;
1060 spin_lock(&inode_lock); 1061 spin_lock(&inode_lock);
1061 old = find_inode_fast(sb, head, ino); 1062 hlist_for_each_entry(old, node, head, i_hash) {
1062 if (likely(!old)) { 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 hlist_add_head(&inode->i_hash, head); 1072 hlist_add_head(&inode->i_hash, head);
1064 spin_unlock(&inode_lock); 1073 spin_unlock(&inode_lock);
1065 return 0; 1074 return 0;
@@ -1081,14 +1090,24 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval,
1081{ 1090{
1082 struct super_block *sb = inode->i_sb; 1091 struct super_block *sb = inode->i_sb;
1083 struct hlist_head *head = inode_hashtable + hash(sb, hashval); 1092 struct hlist_head *head = inode_hashtable + hash(sb, hashval);
1084 struct inode *old;
1085 1093
1086 inode->i_state |= I_LOCK|I_NEW; 1094 inode->i_state |= I_LOCK|I_NEW;
1087 1095
1088 while (1) { 1096 while (1) {
1097 struct hlist_node *node;
1098 struct inode *old = NULL;
1099
1089 spin_lock(&inode_lock); 1100 spin_lock(&inode_lock);
1090 old = find_inode(sb, head, test, data); 1101 hlist_for_each_entry(old, node, head, i_hash) {
1091 if (likely(!old)) { 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 hlist_add_head(&inode->i_hash, head); 1111 hlist_add_head(&inode->i_hash, head);
1093 spin_unlock(&inode_lock); 1112 spin_unlock(&inode_lock);
1094 return 0; 1113 return 0;