History

Merge tag 'fsnotify_for_v6.14-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs

Pull fsnotify reverts from Jan Kara: "Syzbot has found out that fsnotify HSM events generated on page fault can be generated while we already hold freeze protection for the filesystem (when you do buffered write from a buffer which is mmapped file on the same filesystem) which violates expectations for HSM events and could lead to deadlocks of HSM clients with filesystem freezing. Since it's quite late in the cycle we've decided to revert changes implementing HSM events on page fault for now and instead just generate one event for the whole range on mmap(2) so that HSM client can fetch the data at that moment" * tag 'fsnotify_for_v6.14-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: Revert "fanotify: disable readahead if we have pre-content watches" Revert "mm: don't allow huge faults for files with pre content watches" Revert "fsnotify: generate pre-content permission event on page fault" Revert "xfs: add pre-content fsnotify hook for DAX faults" Revert "ext4: add pre-content fsnotify hook for DAX faults" fsnotify: add pre-content hooks on mmap()

Linus Torvalds committed 1 year ago

Commit eb88e6b2 parents 3571e8b 252256e9 files · +24 −143Browse files

Unified · Split

9 files
  1. fs/ext4/file.c +0 −3
  2. fs/xfs/xfs_file.c +0 −13
  3. include/linux/fsnotify.h +21 −0
  4. include/linux/mm.h +0 −1
  5. mm/filemap.c +0 −86
  6. mm/memory.c +0 −19
  7. mm/nommu.c +0 −7
  8. mm/readahead.c +0 −14
  9. mm/util.c +3 −0
fs/ext4/file.c+0−3
@@ -756,9 +756,6 @@ retry: · 755 unmodified lines
756 return VM_FAULT_SIGBUS;756 return VM_FAULT_SIGBUS;
757 }757 }
758 } else {758 } else {
759 result = filemap_fsnotify_fault(vmf);
760 if (unlikely(result))
761 return result;
762 filemap_invalidate_lock_shared(mapping);759 filemap_invalidate_lock_shared(mapping);
763 }760 }
764 result = dax_iomap_fault(vmf, order, &pfn, &error, &ext4_iomap_ops);761 result = dax_iomap_fault(vmf, order, &pfn, &error, &ext4_iomap_ops);
fs/xfs/xfs_file.c+0−13
@@ -1451,9 +1451,6 @@ xfs_dax_read_fault( · 1450 unmodified lines
1451 1451
1452 trace_xfs_read_fault(ip, order);1452 trace_xfs_read_fault(ip, order);
1453 1453
1454 ret = filemap_fsnotify_fault(vmf);
1455 if (unlikely(ret))
1456 return ret;
1457 xfs_ilock(ip, XFS_MMAPLOCK_SHARED);1454 xfs_ilock(ip, XFS_MMAPLOCK_SHARED);
1458 ret = xfs_dax_fault_locked(vmf, order, false);1455 ret = xfs_dax_fault_locked(vmf, order, false);
1459 xfs_iunlock(ip, XFS_MMAPLOCK_SHARED);1456 xfs_iunlock(ip, XFS_MMAPLOCK_SHARED);
@@ -1482,16 +1479,6 @@ xfs_write_fault( · 22 unmodified lines
1482 vm_fault_t ret;1479 vm_fault_t ret;
1483 1480
1484 trace_xfs_write_fault(ip, order);1481 trace_xfs_write_fault(ip, order);
1485 /*
1486 * Usually we get here from ->page_mkwrite callback but in case of DAX
1487 * we will get here also for ordinary write fault. Handle HSM
1488 * notifications for that case.
1489 */
1490 if (IS_DAX(inode)) {
1491 ret = filemap_fsnotify_fault(vmf);
1492 if (unlikely(ret))
1493 return ret;
1494 }
1495 1482
1496 sb_start_pagefault(inode->i_sb);1483 sb_start_pagefault(inode->i_sb);
1497 file_update_time(vmf->vma->vm_file);1484 file_update_time(vmf->vma->vm_file);
include/linux/fsnotify.h+21−0
@@ -170,6 +170,21 @@ static inline int fsnotify_file_area_perm(struct file *file, int perm_mask, · 169 unmodified lines
170 return fsnotify_path(&file->f_path, FS_ACCESS_PERM);170 return fsnotify_path(&file->f_path, FS_ACCESS_PERM);
171}171}
172 172
173/*
174 * fsnotify_mmap_perm - permission hook before mmap of file range
175 */
176static inline int fsnotify_mmap_perm(struct file *file, int prot,
177 const loff_t off, size_t len)
178{
179 /*
180 * mmap() generates only pre-content events.
181 */
182 if (!file || likely(!FMODE_FSNOTIFY_HSM(file->f_mode)))
183 return 0;
184
185 return fsnotify_pre_content(&file->f_path, &off, len);
186}
187
173/*188/*
174 * fsnotify_truncate_perm - permission hook before file truncate189 * fsnotify_truncate_perm - permission hook before file truncate
175 */190 */
@@ -223,6 +238,12 @@ static inline int fsnotify_file_area_perm(struct file *file, int perm_mask, · 47 unmodified lines
223 return 0;238 return 0;
224}239}
225 240
241static inline int fsnotify_mmap_perm(struct file *file, int prot,
242 const loff_t off, size_t len)
243{
244 return 0;
245}
246
226static inline int fsnotify_truncate_perm(const struct path *path, loff_t length)247static inline int fsnotify_truncate_perm(const struct path *path, loff_t length)
227{248{
228 return 0;249 return 0;
include/linux/mm.h+0−1
@@ -3420,7 +3420,6 @@ extern vm_fault_t filemap_fault(struct vm_fault *vmf); · 3419 unmodified lines
3420extern vm_fault_t filemap_map_pages(struct vm_fault *vmf,3420extern vm_fault_t filemap_map_pages(struct vm_fault *vmf,
3421 pgoff_t start_pgoff, pgoff_t end_pgoff);3421 pgoff_t start_pgoff, pgoff_t end_pgoff);
3422extern vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf);3422extern vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf);
3423extern vm_fault_t filemap_fsnotify_fault(struct vm_fault *vmf);
3424 3423
3425extern unsigned long stack_guard_gap;3424extern unsigned long stack_guard_gap;
3426/* Generic expand stack which grows the stack according to GROWS{UP,DOWN} */3425/* Generic expand stack which grows the stack according to GROWS{UP,DOWN} */
mm/filemap.c+0−86
@@ -47,7 +47,6 @@ · 46 unmodified lines
47#include <linux/splice.h>47#include <linux/splice.h>
48#include <linux/rcupdate_wait.h>48#include <linux/rcupdate_wait.h>
49#include <linux/sched/mm.h>49#include <linux/sched/mm.h>
50#include <linux/fsnotify.h>
51#include <asm/pgalloc.h>50#include <asm/pgalloc.h>
52#include <asm/tlbflush.h>51#include <asm/tlbflush.h>
53#include "internal.h"52#include "internal.h"
@@ -3198,14 +3197,6 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf) · 3144 unmodified lines
3198 unsigned long vm_flags = vmf->vma->vm_flags;3197 unsigned long vm_flags = vmf->vma->vm_flags;
3199 unsigned int mmap_miss;3198 unsigned int mmap_miss;
3200 3199
3201 /*
3202 * If we have pre-content watches we need to disable readahead to make
3203 * sure that we don't populate our mapping with 0 filled pages that we
3204 * never emitted an event for.
3205 */
3206 if (unlikely(FMODE_FSNOTIFY_HSM(file->f_mode)))
3207 return fpin;
3208
3209#ifdef CONFIG_TRANSPARENT_HUGEPAGE3200#ifdef CONFIG_TRANSPARENT_HUGEPAGE
3210 /* Use the readahead code, even if readahead is disabled */3201 /* Use the readahead code, even if readahead is disabled */
3211 if ((vm_flags & VM_HUGEPAGE) && HPAGE_PMD_ORDER <= MAX_PAGECACHE_ORDER) {3202 if ((vm_flags & VM_HUGEPAGE) && HPAGE_PMD_ORDER <= MAX_PAGECACHE_ORDER) {
@@ -3274,10 +3265,6 @@ static struct file *do_async_mmap_readahead(struct vm_fault *vmf, · 62 unmodified lines
3274 struct file *fpin = NULL;3265 struct file *fpin = NULL;
3275 unsigned int mmap_miss;3266 unsigned int mmap_miss;
3276 3267
3277 /* See comment in do_sync_mmap_readahead. */
3278 if (unlikely(FMODE_FSNOTIFY_HSM(file->f_mode)))
3279 return fpin;
3280
3281 /* If we don't want any read-ahead, don't bother */3268 /* If we don't want any read-ahead, don't bother */
3282 if (vmf->vma->vm_flags & VM_RAND_READ || !ra->ra_pages)3269 if (vmf->vma->vm_flags & VM_RAND_READ || !ra->ra_pages)
3283 return fpin;3270 return fpin;
@@ -3336,48 +3323,6 @@ static vm_fault_t filemap_fault_recheck_pte_none(struct vm_fault *vmf) · 52 unmodified lines
3336 return ret;3323 return ret;
3337}3324}
3338 3325
3339/**
3340 * filemap_fsnotify_fault - maybe emit a pre-content event.
3341 * @vmf: struct vm_fault containing details of the fault.
3342 *
3343 * If we have a pre-content watch on this file we will emit an event for this
3344 * range. If we return anything the fault caller should return immediately, we
3345 * will return VM_FAULT_RETRY if we had to emit an event, which will trigger the
3346 * fault again and then the fault handler will run the second time through.
3347 *
3348 * Return: a bitwise-OR of %VM_FAULT_ codes, 0 if nothing happened.
3349 */
3350vm_fault_t filemap_fsnotify_fault(struct vm_fault *vmf)
3351{
3352 struct file *fpin = NULL;
3353 int mask = (vmf->flags & FAULT_FLAG_WRITE) ? MAY_WRITE : MAY_ACCESS;
3354 loff_t pos = vmf->pgoff >> PAGE_SHIFT;
3355 size_t count = PAGE_SIZE;
3356 int err;
3357
3358 /*
3359 * We already did this and now we're retrying with everything locked,
3360 * don't emit the event and continue.
3361 */
3362 if (vmf->flags & FAULT_FLAG_TRIED)
3363 return 0;
3364
3365 /* No watches, we're done. */
3366 if (likely(!FMODE_FSNOTIFY_HSM(vmf->vma->vm_file->f_mode)))
3367 return 0;
3368
3369 fpin = maybe_unlock_mmap_for_io(vmf, fpin);
3370 if (!fpin)
3371 return VM_FAULT_SIGBUS;
3372
3373 err = fsnotify_file_area_perm(fpin, mask, &pos, count);
3374 fput(fpin);
3375 if (err)
3376 return VM_FAULT_SIGBUS;
3377 return VM_FAULT_RETRY;
3378}
3379EXPORT_SYMBOL_GPL(filemap_fsnotify_fault);
3380
3381/**3326/**
3382 * filemap_fault - read in file data for page fault handling3327 * filemap_fault - read in file data for page fault handling
3383 * @vmf: struct vm_fault containing details of the fault3328 * @vmf: struct vm_fault containing details of the fault
@@ -3481,37 +3426,6 @@ retry_find: · 97 unmodified lines
3481 * or because readahead was otherwise unable to retrieve it.3426 * or because readahead was otherwise unable to retrieve it.
3482 */3427 */
3483 if (unlikely(!folio_test_uptodate(folio))) {3428 if (unlikely(!folio_test_uptodate(folio))) {
3484 /*
3485 * If this is a precontent file we have can now emit an event to
3486 * try and populate the folio.
3487 */
3488 if (!(vmf->flags & FAULT_FLAG_TRIED) &&
3489 unlikely(FMODE_FSNOTIFY_HSM(file->f_mode))) {
3490 loff_t pos = folio_pos(folio);
3491 size_t count = folio_size(folio);
3492
3493 /* We're NOWAIT, we have to retry. */
3494 if (vmf->flags & FAULT_FLAG_RETRY_NOWAIT) {
3495 folio_unlock(folio);
3496 goto out_retry;
3497 }
3498
3499 if (mapping_locked)
3500 filemap_invalidate_unlock_shared(mapping);
3501 mapping_locked = false;
3502
3503 folio_unlock(folio);
3504 fpin = maybe_unlock_mmap_for_io(vmf, fpin);
3505 if (!fpin)
3506 goto out_retry;
3507
3508 error = fsnotify_file_area_perm(fpin, MAY_ACCESS, &pos,
3509 count);
3510 if (error)
3511 ret = VM_FAULT_SIGBUS;
3512 goto out_retry;
3513 }
3514
3515 /*3429 /*
3516 * If the invalidate lock is not held, the folio was in cache3430 * If the invalidate lock is not held, the folio was in cache
3517 * and uptodate and now it is not. Strange but possible since we3431 * and uptodate and now it is not. Strange but possible since we
mm/memory.c+0−19
@@ -76,7 +76,6 @@ · 75 unmodified lines
76#include <linux/ptrace.h>76#include <linux/ptrace.h>
77#include <linux/vmalloc.h>77#include <linux/vmalloc.h>
78#include <linux/sched/sysctl.h>78#include <linux/sched/sysctl.h>
79#include <linux/fsnotify.h>
80 79
81#include <trace/events/kmem.h>80#include <trace/events/kmem.h>
82 81
@@ -5750,17 +5749,8 @@ out_map: · 5667 unmodified lines
5750static inline vm_fault_t create_huge_pmd(struct vm_fault *vmf)5749static inline vm_fault_t create_huge_pmd(struct vm_fault *vmf)
5751{5750{
5752 struct vm_area_struct *vma = vmf->vma;5751 struct vm_area_struct *vma = vmf->vma;
5753
5754 if (vma_is_anonymous(vma))5752 if (vma_is_anonymous(vma))
5755 return do_huge_pmd_anonymous_page(vmf);5753 return do_huge_pmd_anonymous_page(vmf);
5756 /*
5757 * Currently we just emit PAGE_SIZE for our fault events, so don't allow
5758 * a huge fault if we have a pre content watch on this file. This would
5759 * be trivial to support, but there would need to be tests to ensure
5760 * this works properly and those don't exist currently.
5761 */
5762 if (unlikely(FMODE_FSNOTIFY_HSM(vma->vm_file->f_mode)))
5763 return VM_FAULT_FALLBACK;
5764 if (vma->vm_ops->huge_fault)5754 if (vma->vm_ops->huge_fault)
5765 return vma->vm_ops->huge_fault(vmf, PMD_ORDER);5755 return vma->vm_ops->huge_fault(vmf, PMD_ORDER);
5766 return VM_FAULT_FALLBACK;5756 return VM_FAULT_FALLBACK;
@@ -5784,9 +5774,6 @@ static inline vm_fault_t wp_huge_pmd(struct vm_fault *vmf) · 17 unmodified lines
5784 }5774 }
5785 5775
5786 if (vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) {5776 if (vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) {
5787 /* See comment in create_huge_pmd. */
5788 if (unlikely(FMODE_FSNOTIFY_HSM(vma->vm_file->f_mode)))
5789 goto split;
5790 if (vma->vm_ops->huge_fault) {5777 if (vma->vm_ops->huge_fault) {
5791 ret = vma->vm_ops->huge_fault(vmf, PMD_ORDER);5778 ret = vma->vm_ops->huge_fault(vmf, PMD_ORDER);
5792 if (!(ret & VM_FAULT_FALLBACK))5779 if (!(ret & VM_FAULT_FALLBACK))
@@ -5809,9 +5796,6 @@ static vm_fault_t create_huge_pud(struct vm_fault *vmf) · 16 unmodified lines
5809 /* No support for anonymous transparent PUD pages yet */5796 /* No support for anonymous transparent PUD pages yet */
5810 if (vma_is_anonymous(vma))5797 if (vma_is_anonymous(vma))
5811 return VM_FAULT_FALLBACK;5798 return VM_FAULT_FALLBACK;
5812 /* See comment in create_huge_pmd. */
5813 if (unlikely(FMODE_FSNOTIFY_HSM(vma->vm_file->f_mode)))
5814 return VM_FAULT_FALLBACK;
5815 if (vma->vm_ops->huge_fault)5799 if (vma->vm_ops->huge_fault)
5816 return vma->vm_ops->huge_fault(vmf, PUD_ORDER);5800 return vma->vm_ops->huge_fault(vmf, PUD_ORDER);
5817#endif /* CONFIG_TRANSPARENT_HUGEPAGE */5801#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
@@ -5829,9 +5813,6 @@ static vm_fault_t wp_huge_pud(struct vm_fault *vmf, pud_t orig_pud) · 11 unmodified lines
5829 if (vma_is_anonymous(vma))5813 if (vma_is_anonymous(vma))
5830 goto split;5814 goto split;
5831 if (vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) {5815 if (vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) {
5832 /* See comment in create_huge_pmd. */
5833 if (unlikely(FMODE_FSNOTIFY_HSM(vma->vm_file->f_mode)))
5834 goto split;
5835 if (vma->vm_ops->huge_fault) {5816 if (vma->vm_ops->huge_fault) {
5836 ret = vma->vm_ops->huge_fault(vmf, PUD_ORDER);5817 ret = vma->vm_ops->huge_fault(vmf, PUD_ORDER);
5837 if (!(ret & VM_FAULT_FALLBACK))5818 if (!(ret & VM_FAULT_FALLBACK))
mm/nommu.c+0−7
@@ -1613,13 +1613,6 @@ int remap_vmalloc_range(struct vm_area_struct *vma, void *addr, · 1612 unmodified lines
1613}1613}
1614EXPORT_SYMBOL(remap_vmalloc_range);1614EXPORT_SYMBOL(remap_vmalloc_range);
1615 1615
1616vm_fault_t filemap_fsnotify_fault(struct vm_fault *vmf)
1617{
1618 BUG();
1619 return 0;
1620}
1621EXPORT_SYMBOL_GPL(filemap_fsnotify_fault);
1622
1623vm_fault_t filemap_fault(struct vm_fault *vmf)1616vm_fault_t filemap_fault(struct vm_fault *vmf)
1624{1617{
1625 BUG();1618 BUG();
mm/readahead.c+0−14
@@ -128,7 +128,6 @@ · 127 unmodified lines
128#include <linux/blk-cgroup.h>128#include <linux/blk-cgroup.h>
129#include <linux/fadvise.h>129#include <linux/fadvise.h>
130#include <linux/sched/mm.h>130#include <linux/sched/mm.h>
131#include <linux/fsnotify.h>
132 131
133#include "internal.h"132#include "internal.h"
134 133
@@ -558,15 +557,6 @@ void page_cache_sync_ra(struct readahead_control *ractl, · 423 unmodified lines
558 unsigned long max_pages, contig_count;557 unsigned long max_pages, contig_count;
559 pgoff_t prev_index, miss;558 pgoff_t prev_index, miss;
560 559
561 /*
562 * If we have pre-content watches we need to disable readahead to make
563 * sure that we don't find 0 filled pages in cache that we never emitted
564 * events for. Filesystems supporting HSM must make sure to not call
565 * this function with ractl->file unset for files handled by HSM.
566 */
567 if (ractl->file && unlikely(FMODE_FSNOTIFY_HSM(ractl->file->f_mode)))
568 return;
569
570 /*560 /*
571 * Even if readahead is disabled, issue this request as readahead561 * Even if readahead is disabled, issue this request as readahead
572 * as we'll need it to satisfy the requested range. The forced562 * as we'll need it to satisfy the requested range. The forced
@@ -645,10 +635,6 @@ void page_cache_async_ra(struct readahead_control *ractl, · 72 unmodified lines
645 if (!ra->ra_pages)635 if (!ra->ra_pages)
646 return;636 return;
647 637
648 /* See the comment in page_cache_sync_ra. */
649 if (ractl->file && unlikely(FMODE_FSNOTIFY_HSM(ractl->file->f_mode)))
650 return;
651
652 /*638 /*
653 * Same bit is used for PG_readahead and PG_reclaim.639 * Same bit is used for PG_readahead and PG_reclaim.
654 */640 */
mm/util.c+3−0
@@ -23,6 +23,7 @@ · 22 unmodified lines
23#include <linux/processor.h>23#include <linux/processor.h>
24#include <linux/sizes.h>24#include <linux/sizes.h>
25#include <linux/compat.h>25#include <linux/compat.h>
26#include <linux/fsnotify.h>
26 27
27#include <linux/uaccess.h>28#include <linux/uaccess.h>
28 29
@@ -569,6 +570,8 @@ unsigned long vm_mmap_pgoff(struct file *file, unsigned long addr, · 540 unmodified lines
569 LIST_HEAD(uf);570 LIST_HEAD(uf);
570 571
571 ret = security_mmap_file(file, prot, flag);572 ret = security_mmap_file(file, prot, flag);
573 if (!ret)
574 ret = fsnotify_mmap_perm(file, prot, pgoff >> PAGE_SHIFT, len);
572 if (!ret) {575 if (!ret) {
573 if (mmap_write_lock_killable(mm))576 if (mmap_write_lock_killable(mm))
574 return -EINTR;577 return -EINTR;