From mboxrd@z Thu Jan 1 00:00:00 1970 From: Nick Piggin Subject: [patch 11/44] fs: fix data-loss on error Date: Tue, 24 Apr 2007 11:23:57 +1000 Message-ID: <20070424013433.778077000@suse.de> References: <20070424012346.696840000@suse.de> Cc: Linux Filesystems , Mark Fasheh , Linux Memory Management To: Andrew Morton Return-path: Received: from mx2.suse.de ([195.135.220.15]:50529 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1161586AbXDXFUx (ORCPT ); Tue, 24 Apr 2007 01:20:53 -0400 Content-Disposition: inline; filename=fs-dataloss-stop.patch Sender: linux-fsdevel-owner@vger.kernel.org List-Id: linux-fsdevel.vger.kernel.org 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. Cc: Linux Memory Management Cc: Linux Filesystems Signed-off-by: Nick Piggin fs/buffer.c | 2 ++ 1 file changed, 2 insertions(+) Index: linux-2.6/fs/buffer.c =================================================================== --- linux-2.6.orig/fs/buffer.c +++ linux-2.6/fs/buffer.c @@ -1800,7 +1800,9 @@ static int __block_prepare_write(struct 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) { --