Skip to content

Commit fac8484

Browse files
josefbacikjankara
authored andcommitted
fanotify: disable readahead if we have pre-content watches
With page faults we can trigger readahead on the file, and then subsequent faults can find these pages and insert them into the file without emitting an fanotify event. To avoid this case, disable readahead if we have pre-content watches on the file. This way we are guaranteed to get an event for every range we attempt to access on a pre-content watched file. Reviewed-by: Christian Brauner <[email protected]> Signed-off-by: Josef Bacik <[email protected]> Signed-off-by: Jan Kara <[email protected]> Link: https://patch.msgid.link/70a54e859f555e54bc7a47b32fe5aca92b085615.1731684329.git.josef@toxicpanda.com
1 parent b4b2ff4 commit fac8484

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

mm/filemap.c

+12
Original file line numberDiff line numberDiff line change
@@ -3150,6 +3150,14 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
31503150
unsigned long vm_flags = vmf->vma->vm_flags;
31513151
unsigned int mmap_miss;
31523152

3153+
/*
3154+
* If we have pre-content watches we need to disable readahead to make
3155+
* sure that we don't populate our mapping with 0 filled pages that we
3156+
* never emitted an event for.
3157+
*/
3158+
if (unlikely(FMODE_FSNOTIFY_HSM(file->f_mode)))
3159+
return fpin;
3160+
31533161
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
31543162
/* Use the readahead code, even if readahead is disabled */
31553163
if ((vm_flags & VM_HUGEPAGE) && HPAGE_PMD_ORDER <= MAX_PAGECACHE_ORDER) {
@@ -3218,6 +3226,10 @@ static struct file *do_async_mmap_readahead(struct vm_fault *vmf,
32183226
struct file *fpin = NULL;
32193227
unsigned int mmap_miss;
32203228

3229+
/* See comment in do_sync_mmap_readahead. */
3230+
if (unlikely(FMODE_FSNOTIFY_HSM(file->f_mode)))
3231+
return fpin;
3232+
32213233
/* If we don't want any read-ahead, don't bother */
32223234
if (vmf->vma->vm_flags & VM_RAND_READ || !ra->ra_pages)
32233235
return fpin;

mm/readahead.c

+14
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
#include <linux/blk-cgroup.h>
129129
#include <linux/fadvise.h>
130130
#include <linux/sched/mm.h>
131+
#include <linux/fsnotify.h>
131132

132133
#include "internal.h"
133134

@@ -549,6 +550,15 @@ void page_cache_sync_ra(struct readahead_control *ractl,
549550
unsigned long max_pages, contig_count;
550551
pgoff_t prev_index, miss;
551552

553+
/*
554+
* If we have pre-content watches we need to disable readahead to make
555+
* sure that we don't find 0 filled pages in cache that we never emitted
556+
* events for. Filesystems supporting HSM must make sure to not call
557+
* this function with ractl->file unset for files handled by HSM.
558+
*/
559+
if (ractl->file && unlikely(FMODE_FSNOTIFY_HSM(ractl->file->f_mode)))
560+
return;
561+
552562
/*
553563
* Even if readahead is disabled, issue this request as readahead
554564
* as we'll need it to satisfy the requested range. The forced
@@ -627,6 +637,10 @@ void page_cache_async_ra(struct readahead_control *ractl,
627637
if (!ra->ra_pages)
628638
return;
629639

640+
/* See the comment in page_cache_sync_ra. */
641+
if (ractl->file && unlikely(FMODE_FSNOTIFY_HSM(ractl->file->f_mode)))
642+
return;
643+
630644
/*
631645
* Same bit is used for PG_readahead and PG_reclaim.
632646
*/

0 commit comments

Comments
 (0)