Sophie

Sophie

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

kernel-2.6.18-238.el5.src.rpm

From: Mikulas Patocka <mpatocka@redhat.com>
Date: Wed, 30 Apr 2008 01:03:46 -0400
Subject: [fs] potential race in mark_buffer_dirty
Message-id: Pine.LNX.4.64.0804300059020.31147@engineering.redhat.com
O-Subject: [RHEL 5.3 PATCH] backport potential race in mark_buffer_dirty
Bugzilla: 442577
RH-Acked-by: Josef Bacik <jbacik@redhat.com>
RH-Acked-by: Larry Woodman <lwoodman@redhat.com>
RH-Acked-by: Eric Sandeen <sandeen@redhat.com>

Hi

This is a backport of a bugfix in 2.6.25, fixing a potential race
condition in mark_buffer_dirty. For discussion, see
http://www.uwsg.indiana.edu/hypermail/linux/kernel/0804.0/0854.html

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=442577

diff --git a/fs/buffer.c b/fs/buffer.c
index a360f5f..a70fa87 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1273,7 +1273,19 @@ __getblk_slow(struct block_device *bdev, sector_t block, int size)
  */
 void fastcall mark_buffer_dirty(struct buffer_head *bh)
 {
-	if (!buffer_dirty(bh) && !test_set_buffer_dirty(bh))
+	/*
+	 * Very *carefully* optimize the it-is-already-dirty case.
+	 *
+	 * Don't let the final "is it dirty" escape to before we
+	 * perhaps modified the buffer.
+	 */
+	if (buffer_dirty(bh)) {
+		smp_mb();
+		if (buffer_dirty(bh))
+			return;
+	}
+
+	if (!test_set_buffer_dirty(bh))
 		__set_page_dirty_nobuffers(bh->b_page);
 }