diff options
author | David S. Miller <davem@davemloft.net> | 2015-10-20 16:08:27 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-10-20 16:08:27 +0300 |
commit | 26440c835f8b1a491e2704118ac55bf87334366c (patch) | |
tree | 3c2d23b59fd49b252fdbf6c09efc41b354933fc6 /mm/filemap.c | |
parent | 371f1c7e0d854796adc622cc3bacfcc5fc638db1 (diff) | |
parent | 1099f86044111e9a7807f09523e42d4c9d0fb781 (diff) | |
download | linux-26440c835f8b1a491e2704118ac55bf87334366c.tar.xz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
drivers/net/usb/asix_common.c
net/ipv4/inet_connection_sock.c
net/switchdev/switchdev.c
In the inet_connection_sock.c case the request socket hashing scheme
is completely different in net-next.
The other two conflicts were overlapping changes.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'mm/filemap.c')
-rw-r--r-- | mm/filemap.c | 34 |
1 files changed, 16 insertions, 18 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 72940fb38666..1cc5467cf36c 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2473,6 +2473,21 @@ ssize_t generic_perform_write(struct file *file, iov_iter_count(i)); again: + /* + * Bring in the user page that we will copy from _first_. + * Otherwise there's a nasty deadlock on copying from the + * same page as we're writing to, without it being marked + * up-to-date. + * + * Not only is this an optimisation, but it is also required + * to check that the address is actually valid, when atomic + * usercopies are used, below. + */ + if (unlikely(iov_iter_fault_in_readable(i, bytes))) { + status = -EFAULT; + break; + } + status = a_ops->write_begin(file, mapping, pos, bytes, flags, &page, &fsdata); if (unlikely(status < 0)) @@ -2480,17 +2495,8 @@ again: if (mapping_writably_mapped(mapping)) flush_dcache_page(page); - /* - * 'page' is now locked. If we are trying to copy from a - * mapping of 'page' in userspace, the copy might fault and - * would need PageUptodate() to complete. But, page can not be - * made Uptodate without acquiring the page lock, which we hold. - * Deadlock. Avoid with pagefault_disable(). Fix up below with - * iov_iter_fault_in_readable(). - */ - pagefault_disable(); + copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes); - pagefault_enable(); flush_dcache_page(page); status = a_ops->write_end(file, mapping, pos, bytes, copied, @@ -2513,14 +2519,6 @@ again: */ bytes = min_t(unsigned long, PAGE_CACHE_SIZE - offset, iov_iter_single_seg_count(i)); - /* - * This is the fallback to recover if the copy from - * userspace above faults. - */ - if (unlikely(iov_iter_fault_in_readable(i, bytes))) { - status = -EFAULT; - break; - } goto again; } pos += copied; |