[PATCH V12 06/12] famfs: Introduce mmap and VM fault handling
John Groves <[email protected]> Mon, 3 Aug 2026 02:29:16 +0000
| Newsgroups | dev.linux.lists.fuse-devel,dev.linux.lists.nvdimm,org.kernel.vger.linux-cxl,org.kernel.vger.linux-doc,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <0100019fc5743aef-39284cf3-b235-4a69-832f-c51b2198e8da-000000@email.amazonses.com> |
From: John Groves <[email protected]>=0D=0A=0D=0AThis commit adds vm_operat= ions, plus famfs_mmap() and fault handlers.=0D=0AIt is still missing ioma= p_ops, iomap mapping resolution, and=0D=0Afamfs_ioctl() for setting up fi= le-to-memory mappings.=0D=0A=0D=0ASigned-off-by: John Groves <john@groves= =2Enet>=0D=0A---=0D=0A fs/famfs/famfs_file.c | 101 ++++++++++++++++++++++= +++++++++++++++++++-=0D=0A 1 file changed, 100 insertions(+), 1 deletion(= -)=0D=0A=0D=0Adiff --git a/fs/famfs/famfs_file.c b/fs/famfs/famfs_file.c=0D= =0Aindex e192b573c51f..678f2035fd5f 100644=0D=0A--- a/fs/famfs/famfs_file= =2Ec=0D=0A+++ b/fs/famfs/famfs_file.c=0D=0A@@ -16,6 +16,75 @@=0D=0A=20=0D= =0A #include "famfs_internal.h"=0D=0A=20=0D=0A+/*************************= ********************************************=0D=0A+ * vm_operations=0D=0A= + */=0D=0A+static vm_fault_t=0D=0A+__famfs_filemap_fault(struct vm_fault = *vmf, unsigned int order,=0D=0A+=09=09 bool write_fault)=0D=0A+{=0D=0A= +=09struct inode *inode =3D file_inode(vmf->vma->vm_file);=0D=0A+=09struc= t super_block *sb =3D inode->i_sb;=0D=0A+=09struct famfs_fs_info *fsi =3D= sb->s_fs_info;=0D=0A+=09vm_fault_t ret;=0D=0A+=09unsigned long pfn;=0D=0A= +=0D=0A+=09if (fsi->deverror)=0D=0A+=09=09return VM_FAULT_SIGBUS;=0D=0A+=0D= =0A+=09if (!IS_DAX(file_inode(vmf->vma->vm_file))) {=0D=0A+=09=09pr_err("= %s: file not marked IS_DAX!!\n", __func__);=0D=0A+=09=09return VM_FAULT_S= IGBUS;=0D=0A+=09}=0D=0A+=0D=0A+=09if (write_fault) {=0D=0A+=09=09sb_start= _pagefault(inode->i_sb);=0D=0A+=09=09file_update_time(vmf->vma->vm_file);= =0D=0A+=09}=0D=0A+=0D=0A+=09ret =3D dax_iomap_fault(vmf, order, &pfn, NUL= L, NULL /*&famfs_iomap_ops */);=0D=0A+=09if (ret & VM_FAULT_NEEDDSYNC)=0D= =0A+=09=09ret =3D dax_finish_sync_fault(vmf, order, pfn);=0D=0A+=0D=0A+=09= if (write_fault)=0D=0A+=09=09sb_end_pagefault(inode->i_sb);=0D=0A+=0D=0A+= =09return ret;=0D=0A+}=0D=0A+=0D=0A+static inline bool=0D=0A+famfs_is_wri= te_fault(struct vm_fault *vmf)=0D=0A+{=0D=0A+=09return (vmf->flags & FAUL= T_FLAG_WRITE) &&=0D=0A+=09 (vmf->vma->vm_flags & VM_SHARED);=0D=0A+= }=0D=0A+=0D=0A+static vm_fault_t=0D=0A+famfs_filemap_fault(struct vm_faul= t *vmf)=0D=0A+{=0D=0A+=09return __famfs_filemap_fault(vmf, 0, famfs_is_wr= ite_fault(vmf));=0D=0A+}=0D=0A+=0D=0A+static vm_fault_t=0D=0A+famfs_filem= ap_huge_fault(struct vm_fault *vmf, unsigned int order)=0D=0A+{=0D=0A+=09= return __famfs_filemap_fault(vmf, order, famfs_is_write_fault(vmf));=0D=0A= +}=0D=0A+=0D=0A+static vm_fault_t=0D=0A+famfs_filemap_mkwrite(struct vm_f= ault *vmf)=0D=0A+{=0D=0A+=09return __famfs_filemap_fault(vmf, 0, true);=0D= =0A+}=0D=0A+=0D=0A+const struct vm_operations_struct famfs_file_vm_ops =3D= {=0D=0A+=09.fault=09=09=3D famfs_filemap_fault,=0D=0A+=09.huge_fault=09=3D= famfs_filemap_huge_fault,=0D=0A+=09.map_pages=09=3D filemap_map_pages,=0D= =0A+=09.page_mkwrite=09=3D famfs_filemap_mkwrite,=0D=0A+=09.pfn_mkwrite=09= =3D famfs_filemap_mkwrite,=0D=0A+};=0D=0A+=0D=0A /***********************= **********************************************=0D=0A * file_operations=0D= =0A */=0D=0A@@ -117,6 +186,36 @@ famfs_dax_write_iter(struct kiocb *iocb= , struct iov_iter *from)=0D=0A =09return rc;=0D=0A }=0D=0A=20=0D=0A+stati= c int=0D=0A+famfs_file_mmap(struct file *file, struct vm_area_struct *vma= )=0D=0A+{=0D=0A+=09struct inode *inode =3D file_inode(file);=0D=0A+=09str= uct super_block *sb =3D inode->i_sb;=0D=0A+=09struct famfs_fs_info *fsi =3D= sb->s_fs_info;=0D=0A+=09ssize_t rc;=0D=0A+=0D=0A+=09if (fsi->deverror)=0D= =0A+=09=09return -ENODEV;=0D=0A+=0D=0A+=09/*=0D=0A+=09 * Gate shared-writ= able mappings on FAMFS_OPT_WRITE. This is best=0D=0A+=09 * effort: cleari= ng the bit blocks new writable mappings and write(),=0D=0A+=09 * but does= not revoke mappings that already exist.=0D=0A+=09 */=0D=0A+=09if ((vma->= vm_flags & VM_SHARED) && (vma->vm_flags & VM_WRITE) &&=0D=0A+=09 !famf= s_opt_enabled(fsi, FAMFS_OPT_WRITE))=0D=0A+=09=09return -EPERM;=0D=0A+=0D= =0A+=09rc =3D famfs_file_invalid(inode);=0D=0A+=09if (rc)=0D=0A+=09=09ret= urn (int)rc;=0D=0A+=0D=0A+=09file_accessed(file);=0D=0A+=09vma->vm_ops =3D= &famfs_file_vm_ops;=0D=0A+=09vm_flags_set(vma, VM_HUGEPAGE);=0D=0A+=09re= turn 0;=0D=0A+}=0D=0A+=0D=0A const struct file_operations famfs_file_oper= ations =3D {=0D=0A =09.owner =3D THIS_MODULE,=0D=0A=20=0D=0A@= @ -124,7 +223,7 @@ const struct file_operations famfs_file_operations =3D= {=0D=0A =09.write_iter=09 =3D famfs_dax_write_iter,=0D=0A =09.read_ite= r=09 =3D famfs_dax_read_iter,=0D=0A =09.unlocked_ioctl =3D NULL /*fa= mfs_file_ioctl*/,=0D=0A-=09.mmap=09=09 =3D NULL /* famfs_file_mmap */,=0D= =0A+=09.mmap=09=09 =3D famfs_file_mmap,=0D=0A=20=0D=0A =09/* Force PMD = alignment for mmap */=0D=0A =09.get_unmapped_area =3D thp_get_unmapped_ar= ea,=0D=0A--=20=0D=0A2.53.0=0D=0A=0D=0A