HomeFreeBSD

Fix buffered/direct/mmap I/O race

Description

Fix buffered/direct/mmap I/O race

When a page is faulted in for memory mapped I/O the page lock
may be dropped before it has been read and marked up to date.
If a buffered read encounters such a page in mappedread() it
must wait until the page has been updated. Failure to do so
will result in a panic on debug builds and incorrect data on
production builds.

The critical part of this change is in mappedread() where pages
which are not up to date are now handled. Additionally, it
includes the following simplifications.

  • zfs_getpage() and zfs_fillpage() could be passed an array of pages. This could be more efficient if it was used but in practice only a single page was ever provided. These interfaces were simplified to acknowledge that.
  • update_pages() was modified to correctly set the PG_error bit on a page when it cannot be read by dmu_read().
  • Setting PG_error and PG_uptodate was moved to zfs_fillpage() from zpl_readpage_common(). This is consistent with the handling in update_pages() and mappedread().
  • Minor additional refactoring to comments and variable declarations to improve readability.
  • Add a test case to exercise concurrent buffered, direct, and mmap IO to the same file.
  • Reduce the mmap_sync test case default run time.

Reviewed-by: Richard Yao <richard.yao@alumni.stonybrook.edu>
Reviewed-by: Brian Atkinson <batkinson@lanl.gov>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #13608
Closes #14498

Details

Provenance
Brian Behlendorf <behlendorf1@llnl.gov>Authored on Feb 23 2023, 6:57 PM
GitHub <noreply@github.com>Committed on Feb 23 2023, 6:57 PM
Parents
rG7cb67d627c0c: Fix NULL pointer dereference in zio_ready()
Branches
Unknown
Tags
Unknown