|
@@ -1181,7 +1181,20 @@ __getblk_slow(struct block_device *bdev, sector_t block, int size)
|
|
void mark_buffer_dirty(struct buffer_head *bh)
|
|
void mark_buffer_dirty(struct buffer_head *bh)
|
|
{
|
|
{
|
|
WARN_ON_ONCE(!buffer_uptodate(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);
|
|
__set_page_dirty(bh->b_page, page_mapping(bh->b_page), 0);
|
|
}
|
|
}
|
|
|
|
|