From: Zhang Yi <yi.zhang@xxxxxxxxxx> Impliment mmap iomap path, direct use iomap_page_mkwrite() for the .page_mkwrite() callback. Signed-off-by: Zhang Yi <yi.zhang@xxxxxxxxxx> --- fs/ext4/ext4.h | 1 + fs/ext4/file.c | 6 ++++++ fs/ext4/inode.c | 24 ++++++++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 65373d53ba6a..6b3e34ea58ad 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -3006,6 +3006,7 @@ extern int ext4_chunk_trans_blocks(struct inode *, int nrblocks); extern int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode, loff_t lstart, loff_t lend); extern vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf); +extern vm_fault_t ext4_iomap_page_mkwrite(struct vm_fault *vmf); extern qsize_t *ext4_get_reserved_space(struct inode *inode); extern int ext4_get_projid(struct inode *inode, kprojid_t *projid); extern void ext4_da_release_space(struct inode *inode, int to_free); diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 6830ea3a6c59..15fe65744cba 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -798,6 +798,12 @@ static const struct vm_operations_struct ext4_file_vm_ops = { .page_mkwrite = ext4_page_mkwrite, }; +static const struct vm_operations_struct ext4_iomap_file_vm_ops = { + .fault = filemap_fault, + .map_pages = filemap_map_pages, + .page_mkwrite = ext4_iomap_page_mkwrite, +}; + static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma) { struct inode *inode = file->f_mapping->host; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index ca66afd61fb3..2efa898403f7 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3748,6 +3748,10 @@ const struct iomap_ops ext4_iomap_read_ops = { .iomap_begin = ext4_iomap_buffered_io_begin, }; +const struct iomap_ops ext4_iomap_page_mkwrite_ops = { + .iomap_begin = ext4_iomap_buffered_io_begin, +}; + static int ext4_iomap_read_folio(struct file *file, struct folio *folio) { return iomap_read_folio(folio, &ext4_iomap_read_ops); @@ -6698,3 +6702,23 @@ vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf) ext4_journal_stop(handle); goto out; } + +vm_fault_t ext4_iomap_page_mkwrite(struct vm_fault *vmf) +{ + struct inode *inode = file_inode(vmf->vma->vm_file); + struct address_space *mapping = inode->i_mapping; + vm_fault_t ret; + + if (unlikely(IS_IMMUTABLE(inode))) + return VM_FAULT_SIGBUS; + + sb_start_pagefault(inode->i_sb); + file_update_time(vmf->vma->vm_file); + + filemap_invalidate_lock_shared(mapping); + ret = iomap_page_mkwrite(vmf, &ext4_iomap_page_mkwrite_ops); + filemap_invalidate_unlock_shared(mapping); + + sb_end_pagefault(inode->i_sb); + return ret; +} -- 2.39.2