Commit 912bdf17 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Fix short buffered writes

In the buffered write path, we have to check for short writes that write
to the full page, where the page wasn't UpToDate; when this happens, the
page is partly garbage, so we have to zero it out and revert that part
of the write.

This check was wrong - we reverted total from copied, but didn't revert
the iov_iter, probably also leading to corrupted writes.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 0ba95acc
......@@ -1454,23 +1454,23 @@ static int __bch2_buffered_write(struct bch_inode_info *inode,
if (!pg_copied)
break;
if (!PageUptodate(page) &&
pg_copied != PAGE_SIZE &&
pos + copied + pg_copied < inode->v.i_size) {
zero_user(page, 0, PAGE_SIZE);
break;
}
flush_dcache_page(page);
copied += pg_copied;
if (pg_copied != pg_len)
break;
}
if (!copied)
goto out;
if (copied < len &&
((offset + copied) & (PAGE_SIZE - 1))) {
struct page *page = pages[(offset + copied) >> PAGE_SHIFT];
if (!PageUptodate(page)) {
zero_user(page, 0, PAGE_SIZE);
copied -= (offset + copied) & (PAGE_SIZE - 1);
}
}
spin_lock(&inode->v.i_lock);
if (pos + copied > inode->v.i_size)
i_size_write(&inode->v, pos + copied);
......@@ -1567,6 +1567,7 @@ static ssize_t bch2_buffered_write(struct kiocb *iocb, struct iov_iter *iter)
}
pos += ret;
written += ret;
ret = 0;
balance_dirty_pages_ratelimited(mapping);
} while (iov_iter_count(iter));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment