[rh7,5/5] mm/filemap: add pfcache support to filemap_map_pages

Submitted by Andrey Ryabinin on Feb. 26, 2020, 1:49 p.m.

Details

Message ID 20200226134945.1749-5-aryabinin@virtuozzo.com
State New
Series "Series without cover letter"
Headers show

Commit Message

Andrey Ryabinin Feb. 26, 2020, 1:49 p.m.
Make filmeap_map_pages to map pages from pfcache if that's available.

https://jira.sw.ru/browse/PSBM-101300
Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
---
 mm/filemap.c | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

Patch hide | download patch | download mbox

diff --git a/mm/filemap.c b/mm/filemap.c
index bbddfeb2675d..af1618bf97a6 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2409,11 +2409,11 @@  int filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 }
 EXPORT_SYMBOL(filemap_fault);
 
-void filemap_map_pages(struct vm_area_struct *vma, struct vm_fault *vmf)
+static void __filemap_map_pages(struct vm_area_struct *vma, struct vm_fault *vmf,
+				struct file *file)
 {
 	struct radix_tree_iter iter;
 	void **slot;
-	struct file *file = vma->vm_file;
 	struct address_space *mapping = file->f_mapping;
 	loff_t size;
 	struct page *page;
@@ -2421,7 +2421,6 @@  void filemap_map_pages(struct vm_area_struct *vma, struct vm_fault *vmf)
 	unsigned long addr;
 	pte_t *pte;
 
-	rcu_read_lock();
 	radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, vmf->pgoff) {
 		if (iter.index > vmf->max_pgoff)
 			break;
@@ -2477,7 +2476,25 @@  void filemap_map_pages(struct vm_area_struct *vma, struct vm_fault *vmf)
 		if (iter.index == vmf->max_pgoff)
 			break;
 	}
+}
+
+void filemap_map_pages(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+	struct file *file = vma->vm_file;
+	struct file *peer_file;
+
+	rcu_read_lock();
+	__filemap_map_pages(vma, vmf, file);
+
+	peer_file = rcu_dereference(file->f_mapping->i_peer_file);
+	if (peer_file && atomic_long_inc_not_zero(&peer_file->f_count))
+		__filemap_map_pages(vma, vmf, peer_file);
+	else
+		peer_file = NULL;
 	rcu_read_unlock();
+
+	if (peer_file)
+		fput(peer_file);
 }
 EXPORT_SYMBOL(filemap_map_pages);