From a2138fee6ce78339899919ea4cd7c4472dcbdb01 Mon Sep 17 00:00:00 2001 From: Michel Lespinasse Date: Thu, 29 Apr 2021 10:28:25 -0700 Subject: [PATCH] FROMLIST: fs: list file types that support speculative faults. Add a speculative field to the vm_operations_struct, which indicates if the associated file type supports speculative faults. Initially this is set for files that implement fault() with filemap_fault(). Signed-off-by: Michel Lespinasse Link: https://lore.kernel.org/all/20210407014502.24091-30-michel@lespinasse.org/ Bug: 161210518 Signed-off-by: Suren Baghdasaryan Change-Id: Ic92efdf13283c45e7da7bf703f4f85f8b392ba69 --- fs/btrfs/file.c | 1 + fs/cifs/file.c | 1 + fs/fuse/file.c | 1 + fs/nfs/file.c | 1 + fs/ubifs/file.c | 1 + fs/vboxsf/file.c | 1 + include/linux/mm.h | 7 +++++++ mm/filemap.c | 1 + 8 files changed, 14 insertions(+) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index e44742b55746..853334910a5f 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -2315,6 +2315,7 @@ static const struct vm_operations_struct btrfs_file_vm_ops = { .fault = filemap_fault, .map_pages = filemap_map_pages, .page_mkwrite = btrfs_page_mkwrite, + .speculative = true, }; static int btrfs_file_mmap(struct file *filp, struct vm_area_struct *vma) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 82bbaf8e92b7..baeecc877880 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -4211,6 +4211,7 @@ static const struct vm_operations_struct cifs_file_vm_ops = { .fault = filemap_fault, .map_pages = filemap_map_pages, .page_mkwrite = cifs_page_mkwrite, + .speculative = true, }; int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 70b5421d7133..fdbad561df38 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -2402,6 +2402,7 @@ static const struct vm_operations_struct fuse_file_vm_ops = { .fault = filemap_fault, .map_pages = filemap_map_pages, .page_mkwrite = fuse_page_mkwrite, + .speculative = true, }; static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma) diff --git a/fs/nfs/file.c b/fs/nfs/file.c index aa353fd58240..d8dc3620706d 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -588,6 +588,7 @@ static const struct vm_operations_struct nfs_file_vm_ops = { .fault = filemap_fault, .map_pages = filemap_map_pages, .page_mkwrite = nfs_vm_page_mkwrite, + .speculative = true, }; static int nfs_need_check_write(struct file *filp, struct inode *inode, diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 5cfa28cd00cd..c994c8062f60 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c @@ -1598,6 +1598,7 @@ static const struct vm_operations_struct ubifs_file_vm_ops = { .fault = filemap_fault, .map_pages = filemap_map_pages, .page_mkwrite = ubifs_vm_page_mkwrite, + .speculative = true, }; static int ubifs_file_mmap(struct file *file, struct vm_area_struct *vma) diff --git a/fs/vboxsf/file.c b/fs/vboxsf/file.c index 864c2fad23be..2bdfdfc826a5 100644 --- a/fs/vboxsf/file.c +++ b/fs/vboxsf/file.c @@ -163,6 +163,7 @@ static const struct vm_operations_struct vboxsf_file_vm_ops = { .close = vboxsf_vma_close, .fault = filemap_fault, .map_pages = filemap_map_pages, + .speculative = true, }; static int vboxsf_file_mmap(struct file *file, struct vm_area_struct *vma) diff --git a/include/linux/mm.h b/include/linux/mm.h index e699e407aadc..db9916f6caae 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -663,6 +663,13 @@ struct vm_operations_struct { */ struct page *(*find_special_page)(struct vm_area_struct *vma, unsigned long addr); + /* + * speculative indicates that the vm_operations support + * speculative page faults. This allows ->fault and ->map_pages + * to be called with FAULT_FLAG_SPECULATIVE set; such calls will + * run within an rcu read locked section and with mmap lock not held. + */ + bool speculative; }; static inline void vma_init(struct vm_area_struct *vma, struct mm_struct *mm) diff --git a/mm/filemap.c b/mm/filemap.c index 27f52e186199..02fb6c79fe90 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -3425,6 +3425,7 @@ const struct vm_operations_struct generic_file_vm_ops = { .fault = filemap_fault, .map_pages = filemap_map_pages, .page_mkwrite = filemap_page_mkwrite, + .speculative = true, }; /* This is used for a general mmap of a disk file */