aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Piggin <npiggin@suse.de>2007-10-16 04:25:00 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:42:55 -0400
commit637aff46f94a754207c80c8c64bf1b74f24b967d (patch)
tree837fb3196236998c3c3ae44762ed3167ef0256f4
parent2f718ffc16c43a435d12919c75dbfad518abd056 (diff)
fs: fix data-loss on error
New buffers against uptodate pages are simply be marked uptodate, while the buffer_new bit remains set. This causes error-case code to zero out parts of those buffers because it thinks they contain stale data: wrong, they are actually uptodate so this is a data loss situation. Fix this by actually clearning buffer_new and marking the buffer dirty. It makes sense to always clear buffer_new before setting a buffer uptodate. Signed-off-by: Nick Piggin <npiggin@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/buffer.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index 09bb80c479d8..9ece6c2086d0 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1813,7 +1813,9 @@ static int __block_prepare_write(struct inode *inode, struct page *page,
1813 unmap_underlying_metadata(bh->b_bdev, 1813 unmap_underlying_metadata(bh->b_bdev,
1814 bh->b_blocknr); 1814 bh->b_blocknr);
1815 if (PageUptodate(page)) { 1815 if (PageUptodate(page)) {
1816 clear_buffer_new(bh);
1816 set_buffer_uptodate(bh); 1817 set_buffer_uptodate(bh);
1818 mark_buffer_dirty(bh);
1817 continue; 1819 continue;
1818 } 1820 }
1819 if (block_end > to || block_start < from) { 1821 if (block_end > to || block_start < from) {