Add the ability to set up a shared anonymous mapping based on a VMA
descriptor rather than a VMA.

This is a prerequisite for converting to the char mm driver to use the
mmap_prepare hook.

Signed-off-by: Lorenzo Stoakes <[email protected]>
---
 include/linux/shmem_fs.h |  3 ++-
 mm/shmem.c               | 41 ++++++++++++++++++++++++++++++++--------
 2 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
index 0e47465ef0fd..5b368f9549d6 100644
--- a/include/linux/shmem_fs.h
+++ b/include/linux/shmem_fs.h
@@ -94,7 +94,8 @@ extern struct file *shmem_kernel_file_setup(const char *name, 
loff_t size,
                                            unsigned long flags);
 extern struct file *shmem_file_setup_with_mnt(struct vfsmount *mnt,
                const char *name, loff_t size, unsigned long flags);
-extern int shmem_zero_setup(struct vm_area_struct *);
+int shmem_zero_setup(struct vm_area_struct *vma);
+int shmem_zero_setup_desc(struct vm_area_desc *desc);
 extern unsigned long shmem_get_unmapped_area(struct file *, unsigned long addr,
                unsigned long len, unsigned long pgoff, unsigned long flags);
 extern int shmem_lock(struct file *file, int lock, struct ucounts *ucounts);
diff --git a/mm/shmem.c b/mm/shmem.c
index df02a2e0ebbb..72aa176023de 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -5893,14 +5893,9 @@ struct file *shmem_file_setup_with_mnt(struct vfsmount 
*mnt, const char *name,
 }
 EXPORT_SYMBOL_GPL(shmem_file_setup_with_mnt);
 
-/**
- * shmem_zero_setup - setup a shared anonymous mapping
- * @vma: the vma to be mmapped is prepared by do_mmap
- */
-int shmem_zero_setup(struct vm_area_struct *vma)
+static struct file *__shmem_zero_setup(unsigned long start, unsigned long end, 
vm_flags_t vm_flags)
 {
-       struct file *file;
-       loff_t size = vma->vm_end - vma->vm_start;
+       loff_t size = end - start;
 
        /*
         * Cloning a new file under mmap_lock leads to a lock ordering conflict
@@ -5908,7 +5903,18 @@ int shmem_zero_setup(struct vm_area_struct *vma)
         * accessible to the user through its mapping, use S_PRIVATE flag to
         * bypass file security, in the same way as shmem_kernel_file_setup().
         */
-       file = shmem_kernel_file_setup("dev/zero", size, vma->vm_flags);
+       return shmem_kernel_file_setup("dev/zero", size, vm_flags);
+}
+
+/**
+ * shmem_zero_setup - setup a shared anonymous mapping
+ * @vma: the vma to be mmapped is prepared by do_mmap
+ * Returns: 0 on success, or error
+ */
+int shmem_zero_setup(struct vm_area_struct *vma)
+{
+       struct file *file = __shmem_zero_setup(vma->vm_start, vma->vm_end, 
vma->vm_flags);
+
        if (IS_ERR(file))
                return PTR_ERR(file);
 
@@ -5920,6 +5926,25 @@ int shmem_zero_setup(struct vm_area_struct *vma)
        return 0;
 }
 
+/**
+ * shmem_zero_setup_desc - same as shmem_zero_setup, but determined by VMA
+ * descriptor for convenience.
+ * @desc: Describes VMA
+ * Returns: 0 on success, or error
+ */
+int shmem_zero_setup_desc(struct vm_area_desc *desc)
+{
+       struct file *file = __shmem_zero_setup(desc->start, desc->end, 
desc->vm_flags);
+
+       if (IS_ERR(file))
+               return PTR_ERR(file);
+
+       desc->vm_file = file;
+       desc->vm_ops = &shmem_anon_vm_ops;
+
+       return 0;
+}
+
 /**
  * shmem_read_folio_gfp - read into page cache, using specified page 
allocation flags.
  * @mapping:   the folio's address_space
-- 
2.51.0


Reply via email to