Skip to content

Commit f9f07b6

Browse files
jankaraAl Viro
authored and
Al Viro
committed
vfs: Fix data corruption after failed write in __block_write_begin()
I've got a report of a file corruption from fsxlinux on ext3. The important operations to the page were: mapwrite to a hole partial write to the page read - found the page zeroed from the end of the normal write The culprit seems to be that if get_block() fails in __block_write_begin() (e.g. transient ENOSPC in ext3), the function does ClearPageUptodate(page). Thus when we retry the write, the logic in __block_write_begin() thinks zeroing of the page is needed and overwrites old data. In fact, I don't see why we should ever need to zero the uptodate bit here - either the page was uptodate when we entered __block_write_begin() and it should stay so when we leave it, or it was not uptodate and noone had right to set it uptodate during __block_write_begin() so it remains !uptodate when we leave as well. So just remove clearing of the bit. Signed-off-by: Jan Kara <[email protected]> Signed-off-by: Al Viro <[email protected]>
1 parent 5e7f233 commit f9f07b6

File tree

1 file changed

+1
-3
lines changed

1 file changed

+1
-3
lines changed

fs/buffer.c

+1-3
Original file line numberDiff line numberDiff line change
@@ -1902,10 +1902,8 @@ int __block_write_begin(struct page *page, loff_t pos, unsigned len,
19021902
if (!buffer_uptodate(*wait_bh))
19031903
err = -EIO;
19041904
}
1905-
if (unlikely(err)) {
1905+
if (unlikely(err))
19061906
page_zero_new_buffers(page, from, to);
1907-
ClearPageUptodate(page);
1908-
}
19091907
return err;
19101908
}
19111909
EXPORT_SYMBOL(__block_write_begin);

0 commit comments

Comments
 (0)