On Thu, Jul 11, 2019 at 04:00:10PM +0200, Jan Kara wrote:
Currently handling of MADV_WILLNEED hint calls directly into readahead code. Handle it by calling vfs_fadvise() instead so that filesystem can use its ->fadvise() callback to acquire necessary locks or otherwise prepare for the request.
Suggested-by: Amir Goldstein amir73il@gmail.com CC: stable@vger.kernel.org # Needed by "xfs: Fix stale data exposure when readahead races with hole punch" Signed-off-by: Jan Kara jack@suse.cz
Looks reasonable to me, though is this race between readahead and truncate severe enough to try to push it as a fix for 5.3 or are you targetting 5.4?
--D
mm/madvise.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/mm/madvise.c b/mm/madvise.c index 628022e674a7..ae56d0ef337d 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -14,6 +14,7 @@ #include <linux/userfaultfd_k.h> #include <linux/hugetlb.h> #include <linux/falloc.h> +#include <linux/fadvise.h> #include <linux/sched.h> #include <linux/ksm.h> #include <linux/fs.h> @@ -275,6 +276,7 @@ static long madvise_willneed(struct vm_area_struct *vma, unsigned long start, unsigned long end) { struct file *file = vma->vm_file;
- loff_t offset;
*prev = vma; #ifdef CONFIG_SWAP @@ -298,12 +300,20 @@ static long madvise_willneed(struct vm_area_struct *vma, return 0; }
- start = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
- if (end > vma->vm_end)
end = vma->vm_end;
- end = ((end - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
- force_page_cache_readahead(file->f_mapping, file, start, end - start);
- /*
* Filesystem's fadvise may need to take various locks. We need to
* explicitly grab a reference because the vma (and hence the
* vma's reference to the file) can go away as soon as we drop
* mmap_sem.
*/
- *prev = NULL; /* tell sys_madvise we drop mmap_sem */
- get_file(file);
- up_read(¤t->mm->mmap_sem);
- offset = (loff_t)(start - vma->vm_start)
+ ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
- vfs_fadvise(file, offset, end - start, POSIX_FADV_WILLNEED);
- fput(file);
- down_read(¤t->mm->mmap_sem); return 0;
} -- 2.16.4