mm/filemap.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/mm/filemap.c b/mm/filemap.c index 72940fb38666..e8d01936817a 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2493,6 +2493,20 @@ again: pagefault_enable(); flush_dcache_page(page); + /* + * If we didn't successfully copy all the data from user space, + * and the target page is not up-to-date, we will have to prefault + * the source. And if the page wasn't up-to-date before the write, + * the "write_end()" may need to *make* it up-to-date, and thus + * overwrite our partial copy. + * + * So for that case, thow away the whole thing and force a full + * restart (see comment above, and iov_iter_fault_in_readable() + * below). + */ + if (copied < bytes && !PageUptodate(page)) + copied = 0; + status = a_ops->write_end(file, mapping, pos, bytes, copied, page, fsdata); if (unlikely(status < 0))