vfs: Fix data corruption after failed write in __block_write_begin()
authorJan Kara <jack@suse.cz>
Mon, 13 Jun 2011 22:58:27 +0000 (00:58 +0200)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 16 Jun 2011 15:44:46 +0000 (11:44 -0400)
commitf9f07b6c1372b1436aa6b45333445b443ffd8c95
treeb8bd034260b2c1eee2ca585397ee598079ac261b
parent5e7f23373bf9a853e9256e81e86724cdd0a33c29
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 <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/buffer.c