Re: [PATCH 13/16] mm: update cramfs to use mmap_prepare, mmap_complete

Jason Gunthorpe
2025-09-08T13:27:28Z

On Mon, Sep 08, 2025 at 12:10:44PM +0100, Lorenzo Stoakes wrote:
> We thread the state through the mmap_context, allowing for both PFN map and
> mixed mapped pre-population.
>
> Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
> ---
> fs/cramfs/inode.c | 134 +++++++++++++++++++++++++++++++---------------
> 1 file changed, 92 insertions(+), 42 deletions(-)
>
> diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
> index b002e9b734f9..11a11213304d 100644
> --- a/fs/cramfs/inode.c
> +++ b/fs/cramfs/inode.c
> @@ -59,6 +59,12 @@ static const struct address_space_operations cramfs_aops;
>
> static DEFINE_MUTEX(read_mutex);
>
> +/* How should the mapping be completed? */
> +enum cramfs_mmap_state {
> + NO_PREPOPULATE,
> + PREPOPULATE_PFNMAP,
> + PREPOPULATE_MIXEDMAP,
> +};
>
> /* These macros may change in future, to provide better st_ino semantics. */
> #define OFFSET(x) ((x)->i_ino)
> @@ -342,34 +348,89 @@ static bool cramfs_last_page_is_shared(struct inode *inode)
> return memchr_inv(tail_data, 0, PAGE_SIZE - partial) ? true : false;
> }
>
> -static int cramfs_physmem_mmap(struct file *file, struct vm_area_struct *vma)
> +static int cramfs_physmem_mmap_complete(struct file *file, struct vm_area_struct *vma,
> + const void *context)
> {
> struct inode *inode = file_inode(file);
> struct cramfs_sb_info *sbi = CRAMFS_SB(inode->i_sb);
> - unsigned int pages, max_pages, offset;
> unsigned long address, pgoff = vma->vm_pgoff;
> - char *bailout_reason;
> - int ret;
> + unsigned int pages, offset;
> + enum cramfs_mmap_state mmap_state = (enum cramfs_mmap_state)context;
> + int ret = 0;
>
> - ret = generic_file_readonly_mmap(file, vma);
> - if (ret)
> - return ret;
> + if (mmap_state == NO_PREPOPULATE)
> + return 0;

It would be nicer to have different ops than this, the normal op could
just call the generic helper and then there is only the mixed map op.

Makes me wonder if putting the op in the fops was right, a
mixed/non-mixed vm_ops would do this nicely.

Jason