fs: fix data-loss on error
authorNick Piggin <npiggin@suse.de>
Tue, 16 Oct 2007 08:25:00 +0000 (01:25 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Tue, 16 Oct 2007 16:42:55 +0000 (09:42 -0700)
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>
fs/buffer.c

index 09bb80c479d8b84a02d6defc7f70fef831bb6eb8..9ece6c2086d0588c4a1e9f5bf276c5ca20df443d 100644 (file)
@@ -1813,7 +1813,9 @@ static int __block_prepare_write(struct inode *inode, struct page *page,
                                unmap_underlying_metadata(bh->b_bdev,
                                                        bh->b_blocknr);
                                if (PageUptodate(page)) {
+                                       clear_buffer_new(bh);
                                        set_buffer_uptodate(bh);
+                                       mark_buffer_dirty(bh);
                                        continue;
                                }
                                if (block_end > to || block_start < from) {