Message ID | 20190911025158.GG29434@bombadil.infradead.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | filemap_fault can lose errors | expand |
On Tue, Sep 10, 2019 at 07:51:58PM -0700, Matthew Wilcox wrote: > > If we encounter an error on a page, we can lose the error if we've > dropped the mmap_sem while we wait for the I/O. That can result in > taking the fault multiple times, and retrying the read multiple times. > Spotted by inspection. But does the patch make any difference? Looking into x86 code, VM_FAULT_RETRY makes it retry the fault or return to userspace before it checks for VM_FAULT_SIGBUS bit.
diff --git a/mm/filemap.c b/mm/filemap.c index d0cf700bf201..37bd4aedfccf 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2615,6 +2615,8 @@ vm_fault_t filemap_fault(struct vm_fault *vmf) if (!PageUptodate(page)) error = -EIO; } + if (error < 0) + ret |= VM_FAULT_SIGBUS; if (fpin) goto out_retry; put_page(page); @@ -2622,9 +2624,9 @@ vm_fault_t filemap_fault(struct vm_fault *vmf) if (!error || error == AOP_TRUNCATED_PAGE) goto retry_find; - /* Things didn't work out. Return zero to tell the mm layer so. */ + /* Things didn't work out. */ shrink_readahead_size_eio(file, ra); - return VM_FAULT_SIGBUS; + return ret; out_retry: /*
If we encounter an error on a page, we can lose the error if we've dropped the mmap_sem while we wait for the I/O. That can result in taking the fault multiple times, and retrying the read multiple times. Spotted by inspection. Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Fixes: 6b4c9f446981 ("filemap: drop the mmap_sem for all blocking operations")