diff options
Diffstat (limited to 'fs/dax.c')
| -rw-r--r-- | fs/dax.c | 24 | 
1 files changed, 24 insertions, 0 deletions
@@ -859,6 +859,7 @@ int dax_writeback_mapping_range(struct address_space *mapping,  			if (ret < 0)  				goto out;  		} +		start_index = indices[pvec.nr - 1] + 1;  	}  out:  	put_dax(dax_dev); @@ -1155,6 +1156,17 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf,  	}  	/* +	 * It is possible, particularly with mixed reads & writes to private +	 * mappings, that we have raced with a PMD fault that overlaps with +	 * the PTE we need to set up.  If so just return and the fault will be +	 * retried. +	 */ +	if (pmd_trans_huge(*vmf->pmd) || pmd_devmap(*vmf->pmd)) { +		vmf_ret = VM_FAULT_NOPAGE; +		goto unlock_entry; +	} + +	/*  	 * Note that we don't bother to use iomap_apply here: DAX required  	 * the file system block size to be equal the page size, which means  	 * that we never have to deal with more than a single extent here. @@ -1398,6 +1410,18 @@ static int dax_iomap_pmd_fault(struct vm_fault *vmf,  		goto fallback;  	/* +	 * It is possible, particularly with mixed reads & writes to private +	 * mappings, that we have raced with a PTE fault that overlaps with +	 * the PMD we need to set up.  If so just return and the fault will be +	 * retried. +	 */ +	if (!pmd_none(*vmf->pmd) && !pmd_trans_huge(*vmf->pmd) && +			!pmd_devmap(*vmf->pmd)) { +		result = 0; +		goto unlock_entry; +	} + +	/*  	 * Note that we don't use iomap_apply here.  We aren't doing I/O, only  	 * setting up a mapping, so really we're using iomap_begin() as a way  	 * to look up our filesystem block.  | 
