X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=fs%2Fbuffer.c;h=39ff14403d137be85dcd11161584abeabd9d7577;hb=a70e65df8812c52252fa07a2eb92a46451a4427f;hp=98196327ddf0dddc2b3a911441bd4ff493026abf;hpb=8eefca4888c986d993b2571eb31f0397a5d0a178;p=linux-2.6 diff --git a/fs/buffer.c b/fs/buffer.c index 98196327dd..39ff14403d 100644 --- a/fs/buffer.c +++ b/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); }