From: Nick Piggin 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 Signed-off-by: Andrew Morton --- fs/buffer.c | 2 ++ 1 files changed, 2 insertions(+) diff -puN fs/buffer.c~fs-fix-data-loss-on-error fs/buffer.c --- a/fs/buffer.c~fs-fix-data-loss-on-error +++ a/fs/buffer.c @@ -1785,7 +1785,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) { _