Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 1042

kernel-2.6.18-238.el5.src.rpm

From: Eric Sandeen <sandeen@redhat.com>
Date: Thu, 10 Dec 2009 17:16:47 -0500
Subject: [fs] fix possible inode corruption on unlock
Message-id: <4B212CFF.60901@redhat.com>
Patchwork-id: 21853
O-Subject: [PATCH RHEL5.5] fs: make sure data stored into inode is properly
	seen before unlocking new inode
Bugzilla: 545612
RH-Acked-by: Jeff Moyer <jmoyer@redhat.com>
RH-Acked-by: Larry Woodman <lwoodman@redhat.com>

[fs] make sure data stored into inode is properly seen before unlocking new inode

This is for:
 Bug 545612 - Please implement upstream fix for potential filesystem corruption bug

And is a trivial backport of the following upstream one-liner:

From: Jan Kara <jack@suse.cz>
Date: Tue, 22 Sep 2009 00:01:06 +0000 (-0700)
Subject: fs: make sure data stored into inode is properly seen before unlocking new inode
X-Git-Tag: v2.6.32-rc1~608
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=580be0837a7a59b207c3d5c661d044d8dd0a6a30

fs: make sure data stored into inode is properly seen before unlocking new inode

In theory it could happen that on one CPU we initialize a new inode but
clearing of I_NEW | I_LOCK gets reordered before some of the
initialization.  Thus on another CPU we return not fully uptodate inode
from iget_locked().

This seems to fix a corruption issue on ext3 mounted over NFS.

[akpm@linux-foundation.org: add some commentary]
Signed-off-by: Jan Kara <jack@suse.cz>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

diff --git a/fs/inode.c b/fs/inode.c
index 8875b3c..5b80cb0 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -570,13 +570,15 @@ EXPORT_SYMBOL(new_inode);
 void unlock_new_inode(struct inode *inode)
 {
 	/*
-	 * This is special!  We do not need the spinlock
-	 * when clearing I_LOCK, because we're guaranteed
-	 * that nobody else tries to do anything about the
-	 * state of the inode when it is locked, as we
-	 * just created it (so there can be no old holders
-	 * that haven't tested I_LOCK).
+	 * This is special!  We do not need the spinlock when clearing I_LOCK,
+	 * because we're guaranteed that nobody else tries to do anything about
+	 * the state of the inode when it is locked, as we just created it (so
+	 * there can be no old holders that haven't tested I_LOCK).
+	 * However we must emit the memory barrier so that other CPUs reliably
+	 * see the clearing of I_LOCK after the other inode initialisation has
+	 * completed.
 	 */
+	smp_mb();
 	inode->i_state &= ~(I_LOCK|I_NEW);
 	wake_up_inode(inode);
 }