Merge tag 'hole_punch_for_v5.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull fs hole punching vs cache filling race fixes from Jan Kara: "Fix races leading to possible data corruption or stale data exposure in multiple filesystems when hole punching races with operations such as readahead. This is the series I was sending for the last merge window but with your objection fixed - now filemap_fault() has been modified to take invalidate_lock only when we need to create new page in the page cache and / or bring it uptodate" * tag 'hole_punch_for_v5.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: filesystems/locking: fix Malformed table warning cifs: Fix race between hole punch and page fault ceph: Fix race between hole punch and page fault fuse: Convert to using invalidate_lock f2fs: Convert to using invalidate_lock zonefs: Convert to using invalidate_lock xfs: Convert double locking of MMAPLOCK to use VFS helpers xfs: Convert to use invalidate_lock xfs: Refactor xfs_isilocked() ext2: Convert to using invalidate_lock ext4: Convert to use mapping->invalidate_lock mm: Add functions to lock invalidate_lock for two mappings mm: Protect operations adding pages to page cache with invalidate_lock documentation: Sync file_operations members with reality mm: Fix comments mentioning i_mutex
This commit is contained in:
@@ -436,6 +436,10 @@ int pagecache_write_end(struct file *, struct address_space *mapping,
|
||||
* struct address_space - Contents of a cacheable, mappable object.
|
||||
* @host: Owner, either the inode or the block_device.
|
||||
* @i_pages: Cached pages.
|
||||
* @invalidate_lock: Guards coherency between page cache contents and
|
||||
* file offset->disk block mappings in the filesystem during invalidates.
|
||||
* It is also used to block modification of page cache contents through
|
||||
* memory mappings.
|
||||
* @gfp_mask: Memory allocation flags to use for allocating pages.
|
||||
* @i_mmap_writable: Number of VM_SHARED mappings.
|
||||
* @nr_thps: Number of THPs in the pagecache (non-shmem only).
|
||||
@@ -453,6 +457,7 @@ int pagecache_write_end(struct file *, struct address_space *mapping,
|
||||
struct address_space {
|
||||
struct inode *host;
|
||||
struct xarray i_pages;
|
||||
struct rw_semaphore invalidate_lock;
|
||||
gfp_t gfp_mask;
|
||||
atomic_t i_mmap_writable;
|
||||
#ifdef CONFIG_READ_ONLY_THP_FOR_FS
|
||||
@@ -814,9 +819,42 @@ static inline void inode_lock_shared_nested(struct inode *inode, unsigned subcla
|
||||
down_read_nested(&inode->i_rwsem, subclass);
|
||||
}
|
||||
|
||||
static inline void filemap_invalidate_lock(struct address_space *mapping)
|
||||
{
|
||||
down_write(&mapping->invalidate_lock);
|
||||
}
|
||||
|
||||
static inline void filemap_invalidate_unlock(struct address_space *mapping)
|
||||
{
|
||||
up_write(&mapping->invalidate_lock);
|
||||
}
|
||||
|
||||
static inline void filemap_invalidate_lock_shared(struct address_space *mapping)
|
||||
{
|
||||
down_read(&mapping->invalidate_lock);
|
||||
}
|
||||
|
||||
static inline int filemap_invalidate_trylock_shared(
|
||||
struct address_space *mapping)
|
||||
{
|
||||
return down_read_trylock(&mapping->invalidate_lock);
|
||||
}
|
||||
|
||||
static inline void filemap_invalidate_unlock_shared(
|
||||
struct address_space *mapping)
|
||||
{
|
||||
up_read(&mapping->invalidate_lock);
|
||||
}
|
||||
|
||||
void lock_two_nondirectories(struct inode *, struct inode*);
|
||||
void unlock_two_nondirectories(struct inode *, struct inode*);
|
||||
|
||||
void filemap_invalidate_lock_two(struct address_space *mapping1,
|
||||
struct address_space *mapping2);
|
||||
void filemap_invalidate_unlock_two(struct address_space *mapping1,
|
||||
struct address_space *mapping2);
|
||||
|
||||
|
||||
/*
|
||||
* NOTE: in a 32bit arch with a preemptable kernel and
|
||||
* an UP compile the i_size_read/write must be atomic
|
||||
@@ -2490,6 +2528,7 @@ struct file_system_type {
|
||||
|
||||
struct lock_class_key i_lock_key;
|
||||
struct lock_class_key i_mutex_key;
|
||||
struct lock_class_key invalidate_lock_key;
|
||||
struct lock_class_key i_mutex_dir_key;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user