From 0fb067ba77ab74a298ec1f2e56a6a773613bd359 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 4 Apr 2008 14:38:17 -0700 Subject: [PATCH] --- yaml --- r: 88132 b: refs/heads/master c: 1be62dc190ebaca331038962c873e7967de6cc4b h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/fs/buffer.c | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index 2a7ca63def8a..c359b8992ed8 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 4ed919014eb2b591eb8fdd4dd00226a65faddef4 +refs/heads/master: 1be62dc190ebaca331038962c873e7967de6cc4b diff --git a/trunk/fs/buffer.c b/trunk/fs/buffer.c index 98196327ddf0..39ff14403d13 100644 --- a/trunk/fs/buffer.c +++ b/trunk/fs/buffer.c @@ -1181,7 +1181,20 @@ __getblk_slow(struct block_device *bdev, sector_t block, int size) void mark_buffer_dirty(struct buffer_head *bh) { WARN_ON_ONCE(!buffer_uptodate(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(bh->b_page, page_mapping(bh->b_page), 0); }