aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/dax.c35
-rw-r--r--mm/memory.c11
2 files changed, 21 insertions, 25 deletions
diff --git a/fs/dax.c b/fs/dax.c
index 9ef9b80cc132..ed54efedade6 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -554,6 +554,25 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
554 if (!buffer_size_valid(&bh) || bh.b_size < PMD_SIZE) 554 if (!buffer_size_valid(&bh) || bh.b_size < PMD_SIZE)
555 goto fallback; 555 goto fallback;
556 556
557 if (buffer_unwritten(&bh) || buffer_new(&bh)) {
558 int i;
559 for (i = 0; i < PTRS_PER_PMD; i++)
560 clear_page(kaddr + i * PAGE_SIZE);
561 count_vm_event(PGMAJFAULT);
562 mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT);
563 result |= VM_FAULT_MAJOR;
564 }
565
566 /*
567 * If we allocated new storage, make sure no process has any
568 * zero pages covering this hole
569 */
570 if (buffer_new(&bh)) {
571 i_mmap_unlock_write(mapping);
572 unmap_mapping_range(mapping, pgoff << PAGE_SHIFT, PMD_SIZE, 0);
573 i_mmap_lock_write(mapping);
574 }
575
557 /* 576 /*
558 * If a truncate happened while we were allocating blocks, we may 577 * If a truncate happened while we were allocating blocks, we may
559 * leave blocks allocated to the file that are beyond EOF. We can't 578 * leave blocks allocated to the file that are beyond EOF. We can't
@@ -568,13 +587,6 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
568 if ((pgoff | PG_PMD_COLOUR) >= size) 587 if ((pgoff | PG_PMD_COLOUR) >= size)
569 goto fallback; 588 goto fallback;
570 589
571 /*
572 * If we allocated new storage, make sure no process has any
573 * zero pages covering this hole
574 */
575 if (buffer_new(&bh))
576 unmap_mapping_range(mapping, pgoff << PAGE_SHIFT, PMD_SIZE, 0);
577
578 if (!write && !buffer_mapped(&bh) && buffer_uptodate(&bh)) { 590 if (!write && !buffer_mapped(&bh) && buffer_uptodate(&bh)) {
579 spinlock_t *ptl; 591 spinlock_t *ptl;
580 pmd_t entry; 592 pmd_t entry;
@@ -605,15 +617,6 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
605 if ((length < PMD_SIZE) || (pfn & PG_PMD_COLOUR)) 617 if ((length < PMD_SIZE) || (pfn & PG_PMD_COLOUR))
606 goto fallback; 618 goto fallback;
607 619
608 if (buffer_unwritten(&bh) || buffer_new(&bh)) {
609 int i;
610 for (i = 0; i < PTRS_PER_PMD; i++)
611 clear_page(kaddr + i * PAGE_SIZE);
612 count_vm_event(PGMAJFAULT);
613 mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT);
614 result |= VM_FAULT_MAJOR;
615 }
616
617 result |= vmf_insert_pfn_pmd(vma, address, pmd, pfn, write); 620 result |= vmf_insert_pfn_pmd(vma, address, pmd, pfn, write);
618 } 621 }
619 622
diff --git a/mm/memory.c b/mm/memory.c
index 320c42e95e69..ce8e983f3c4d 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2426,17 +2426,10 @@ void unmap_mapping_range(struct address_space *mapping,
2426 if (details.last_index < details.first_index) 2426 if (details.last_index < details.first_index)
2427 details.last_index = ULONG_MAX; 2427 details.last_index = ULONG_MAX;
2428 2428
2429 2429 i_mmap_lock_write(mapping);
2430 /*
2431 * DAX already holds i_mmap_lock to serialise file truncate vs
2432 * page fault and page fault vs page fault.
2433 */
2434 if (!IS_DAX(mapping->host))
2435 i_mmap_lock_write(mapping);
2436 if (unlikely(!RB_EMPTY_ROOT(&mapping->i_mmap))) 2430 if (unlikely(!RB_EMPTY_ROOT(&mapping->i_mmap)))
2437 unmap_mapping_range_tree(&mapping->i_mmap, &details); 2431 unmap_mapping_range_tree(&mapping->i_mmap, &details);
2438 if (!IS_DAX(mapping->host)) 2432 i_mmap_unlock_write(mapping);
2439 i_mmap_unlock_write(mapping);
2440} 2433}
2441EXPORT_SYMBOL(unmap_mapping_range); 2434EXPORT_SYMBOL(unmap_mapping_range);
2442 2435