ext4: fix fault handling when mounted with -o dax,ro
If an ext4 filesystem is mounted with both the DAX and read-only options, executables on that filesystem will fail to start (claiming 'Segmentation fault') due to the fault handler returning VM_FAULT_SIGBUS. This is due to the DAX fault handler (see ext4_dax_huge_fault) attempting to write to the journal when FAULT_FLAG_WRITE is set. This is the wrong behavior for write faults which will lead to a COW page; in particular, this fails for readonly mounts. This change avoids journal writes for faults that are expected to COW. It might be the case that this could be better handled in ext4_iomap_begin / ext4_iomap_end (called via iomap_ops inside dax_iomap_fault). These is some overlap already (e.g. grabbing journal handles). Signed-off-by: Randy Dodgen <dodgen@google.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Ross Zwisler <ross.zwisler@linux.intel.com>
This commit is contained in:
parent
95f1fda47c
commit
fd96b8da68
1 changed files with 14 additions and 1 deletions
|
@ -279,7 +279,20 @@ static int ext4_dax_huge_fault(struct vm_fault *vmf,
|
|||
handle_t *handle = NULL;
|
||||
struct inode *inode = file_inode(vmf->vma->vm_file);
|
||||
struct super_block *sb = inode->i_sb;
|
||||
bool write = vmf->flags & FAULT_FLAG_WRITE;
|
||||
|
||||
/*
|
||||
* We have to distinguish real writes from writes which will result in a
|
||||
* COW page; COW writes should *not* poke the journal (the file will not
|
||||
* be changed). Doing so would cause unintended failures when mounted
|
||||
* read-only.
|
||||
*
|
||||
* We check for VM_SHARED rather than vmf->cow_page since the latter is
|
||||
* unset for pe_size != PE_SIZE_PTE (i.e. only in do_cow_fault); for
|
||||
* other sizes, dax_iomap_fault will handle splitting / fallback so that
|
||||
* we eventually come back with a COW page.
|
||||
*/
|
||||
bool write = (vmf->flags & FAULT_FLAG_WRITE) &&
|
||||
(vmf->vma->vm_flags & VM_SHARED);
|
||||
|
||||
if (write) {
|
||||
sb_start_pagefault(sb);
|
||||
|
|
Loading…
Reference in a new issue