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@xxxxxxxxxxxxx> Fixes: 6b4c9f446981 ("filemap: drop the mmap_sem for all blocking operations") 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: /*