Re: [PATCH V12 06/12] famfs: Introduce mmap and VM fault handling

"Darrick J. Wong" <[email protected]> Wed, 5 Aug 2026 22:16:43 -0700
Newsgroups org.kernel.vger.linux-cxl,dev.linux.lists.fuse-devel,dev.linux.lists.nvdimm,org.kernel.vger.linux-doc,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel
Message-ID <20260806051643.GF3560084@frogsfrogsfrogs>
On Mon, Aug 03, 2026 at 02:29:16AM +0000, John Groves wrote:
> From: John Groves <[email protected]>
> 
> This commit adds vm_operations, plus famfs_mmap() and fault handlers.
> It is still missing iomap_ops, iomap mapping resolution, and
> famfs_ioctl() for setting up file-to-memory mappings.
> 
> Signed-off-by: John Groves <[email protected]>
> ---
>  fs/famfs/famfs_file.c | 101 +++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 100 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/famfs/famfs_file.c b/fs/famfs/famfs_file.c
> index e192b573c51f..678f2035fd5f 100644
> --- a/fs/famfs/famfs_file.c
> +++ b/fs/famfs/famfs_file.c
> @@ -16,6 +16,75 @@
>  
>  #include "famfs_internal.h"
>  
> +/*********************************************************************
> + * vm_operations
> + */
> +static vm_fault_t
> +__famfs_filemap_fault(struct vm_fault *vmf, unsigned int order,
> +		      bool write_fault)
> +{
> +	struct inode *inode = file_inode(vmf->vma->vm_file);
> +	struct super_block *sb = inode->i_sb;
> +	struct famfs_fs_info *fsi = sb->s_fs_info;
> +	vm_fault_t ret;
> +	unsigned long pfn;
> +
> +	if (fsi->deverror)
> +		return VM_FAULT_SIGBUS;
> +
> +	if (!IS_DAX(file_inode(vmf->vma->vm_file))) {
> +		pr_err("%s: file not marked IS_DAX!!\n", __func__);
> +		return VM_FAULT_SIGBUS;
> +	}
> +
> +	if (write_fault) {
> +		sb_start_pagefault(inode->i_sb);
> +		file_update_time(vmf->vma->vm_file);
> +	}
> +
> +	ret = dax_iomap_fault(vmf, order, &pfn, NULL, NULL /*&famfs_iomap_ops */);
> +	if (ret & VM_FAULT_NEEDDSYNC)
> +		ret = dax_finish_sync_fault(vmf, order, pfn);
> +
> +	if (write_fault)
> +		sb_end_pagefault(inode->i_sb);
> +
> +	return ret;
> +}
> +
> +static inline bool
> +famfs_is_write_fault(struct vm_fault *vmf)
> +{
> +	return (vmf->flags & FAULT_FLAG_WRITE) &&
> +	       (vmf->vma->vm_flags & VM_SHARED);
> +}
> +
> +static vm_fault_t
> +famfs_filemap_fault(struct vm_fault *vmf)
> +{
> +	return __famfs_filemap_fault(vmf, 0, famfs_is_write_fault(vmf));
> +}
> +
> +static vm_fault_t
> +famfs_filemap_huge_fault(struct vm_fault *vmf, unsigned int order)
> +{
> +	return __famfs_filemap_fault(vmf, order, famfs_is_write_fault(vmf));
> +}
> +
> +static vm_fault_t
> +famfs_filemap_mkwrite(struct vm_fault *vmf)
> +{
> +	return __famfs_filemap_fault(vmf, 0, true);

Do neither of the conditions in famfs_is_write_fault apply here?

The rest of the patch looks ok to me.

--D

> +}
> +
> +const struct vm_operations_struct famfs_file_vm_ops = {
> +	.fault		= famfs_filemap_fault,
> +	.huge_fault	= famfs_filemap_huge_fault,
> +	.map_pages	= filemap_map_pages,
> +	.page_mkwrite	= famfs_filemap_mkwrite,
> +	.pfn_mkwrite	= famfs_filemap_mkwrite,
> +};
> +
>  /*********************************************************************
>   * file_operations
>   */
> @@ -117,6 +186,36 @@ famfs_dax_write_iter(struct kiocb *iocb, struct iov_iter *from)
>  	return rc;
>  }
>  
> +static int
> +famfs_file_mmap(struct file *file, struct vm_area_struct *vma)
> +{
> +	struct inode *inode = file_inode(file);
> +	struct super_block *sb = inode->i_sb;
> +	struct famfs_fs_info *fsi = sb->s_fs_info;
> +	ssize_t rc;
> +
> +	if (fsi->deverror)
> +		return -ENODEV;
> +
> +	/*
> +	 * Gate shared-writable mappings on FAMFS_OPT_WRITE. This is best
> +	 * effort: clearing the bit blocks new writable mappings and write(),
> +	 * but does not revoke mappings that already exist.
> +	 */
> +	if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_WRITE) &&
> +	    !famfs_opt_enabled(fsi, FAMFS_OPT_WRITE))
> +		return -EPERM;
> +
> +	rc = famfs_file_invalid(inode);
> +	if (rc)
> +		return (int)rc;
> +
> +	file_accessed(file);
> +	vma->vm_ops = &famfs_file_vm_ops;
> +	vm_flags_set(vma, VM_HUGEPAGE);
> +	return 0;
> +}
> +
>  const struct file_operations famfs_file_operations = {
>  	.owner             = THIS_MODULE,
>  
> @@ -124,7 +223,7 @@ const struct file_operations famfs_file_operations = {
>  	.write_iter	   = famfs_dax_write_iter,
>  	.read_iter	   = famfs_dax_read_iter,
>  	.unlocked_ioctl    = NULL /*famfs_file_ioctl*/,
> -	.mmap		   = NULL /* famfs_file_mmap */,
> +	.mmap		   = famfs_file_mmap,
>  
>  	/* Force PMD alignment for mmap */
>  	.get_unmapped_area = thp_get_unmapped_area,
> -- 
> 2.53.0
> 
> 
>