diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/filemap.c | 12 | ||||
-rw-r--r-- | mm/readahead.c | 14 |
2 files changed, 26 insertions, 0 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 7c76a123ba18..e9a0f330d33e 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -3150,6 +3150,14 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf) unsigned long vm_flags = vmf->vma->vm_flags; unsigned int mmap_miss; + /* + * If we have pre-content watches we need to disable readahead to make + * sure that we don't populate our mapping with 0 filled pages that we + * never emitted an event for. + */ + if (unlikely(FMODE_FSNOTIFY_HSM(file->f_mode))) + return fpin; + #ifdef CONFIG_TRANSPARENT_HUGEPAGE /* Use the readahead code, even if readahead is disabled */ 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, struct file *fpin = NULL; unsigned int mmap_miss; + /* See comment in do_sync_mmap_readahead. */ + if (unlikely(FMODE_FSNOTIFY_HSM(file->f_mode))) + return fpin; + /* If we don't want any read-ahead, don't bother */ if (vmf->vma->vm_flags & VM_RAND_READ || !ra->ra_pages) return fpin; diff --git a/mm/readahead.c b/mm/readahead.c index 8f1cf599b572..1fa4710bdf89 100644 --- a/mm/readahead.c +++ b/mm/readahead.c @@ -128,6 +128,7 @@ #include <linux/blk-cgroup.h> #include <linux/fadvise.h> #include <linux/sched/mm.h> +#include <linux/fsnotify.h> #include "internal.h" @@ -550,6 +551,15 @@ void page_cache_sync_ra(struct readahead_control *ractl, pgoff_t prev_index, miss; /* + * If we have pre-content watches we need to disable readahead to make + * sure that we don't find 0 filled pages in cache that we never emitted + * events for. Filesystems supporting HSM must make sure to not call + * this function with ractl->file unset for files handled by HSM. + */ + if (ractl->file && unlikely(FMODE_FSNOTIFY_HSM(ractl->file->f_mode))) + return; + + /* * Even if readahead is disabled, issue this request as readahead * as we'll need it to satisfy the requested range. The forced * readahead will do the right thing and limit the read to just the @@ -627,6 +637,10 @@ void page_cache_async_ra(struct readahead_control *ractl, if (!ra->ra_pages) return; + /* See the comment in page_cache_sync_ra. */ + if (ractl->file && unlikely(FMODE_FSNOTIFY_HSM(ractl->file->f_mode))) + return; + /* * Same bit is used for PG_readahead and PG_reclaim. */ |