diff options
author | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-20 02:21:59 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-21 20:04:31 +0300 |
commit | 46d2277c796f9f4937bfa668c40b2e3f43e93dd0 (patch) | |
tree | cfde4d8c4b1d721455c978a53e70a55a6c73c3ef /fs/buffer.c | |
parent | 9bfb18392ef586467277fa25d8f3a7a93611f6df (diff) | |
download | linux-46d2277c796f9f4937bfa668c40b2e3f43e93dd0.tar.xz |
Clean up and make try_to_free_buffers() not race with dirty pages
This is preparatory work in our continuing saga on some hard-to-trigger
file corruption with shared writable mmap() after the dirty page
tracking changes (commit d08b3851da41d0ee60851f2c75b118e1f7a5fc89 etc)
were merged.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/buffer.c')
-rw-r--r-- | fs/buffer.c | 18 |
1 files changed, 1 insertions, 17 deletions
diff --git a/fs/buffer.c b/fs/buffer.c index d1f1b54d3108..263f88e4dffb 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -2834,7 +2834,7 @@ int try_to_free_buffers(struct page *page) int ret = 0; BUG_ON(!PageLocked(page)); - if (PageWriteback(page)) + if (PageDirty(page) || PageWriteback(page)) return 0; if (mapping == NULL) { /* can this still happen? */ @@ -2845,22 +2845,6 @@ int try_to_free_buffers(struct page *page) spin_lock(&mapping->private_lock); ret = drop_buffers(page, &buffers_to_free); spin_unlock(&mapping->private_lock); - if (ret) { - /* - * If the filesystem writes its buffers by hand (eg ext3) - * then we can have clean buffers against a dirty page. We - * clean the page here; otherwise later reattachment of buffers - * could encounter a non-uptodate page, which is unresolvable. - * This only applies in the rare case where try_to_free_buffers - * succeeds but the page is not freed. - * - * Also, during truncate, discard_buffer will have marked all - * the page's buffers clean. We discover that here and clean - * the page also. - */ - if (test_clear_page_dirty(page)) - task_io_account_cancelled_write(PAGE_CACHE_SIZE); - } out: if (buffers_to_free) { struct buffer_head *bh = buffers_to_free; |