diff mbox series

filemap_fault can lose errors

Message ID 20190911025158.GG29434@bombadil.infradead.org (mailing list archive)
State New, archived
Headers show
Series filemap_fault can lose errors | expand

Commit Message

Matthew Wilcox (Oracle) Sept. 11, 2019, 2:51 a.m. UTC
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")

Comments

Kirill A . Shutemov Sept. 11, 2019, 3:23 p.m. UTC | #1
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 mbox series

Patch

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:
 	/*