When a new file is created under msharefs, allocate a new mm_struct to be associated with it for the lifetime of the file. The mm_struct will hold the VMAs and pagetables for the mshare region the file represents. Signed-off-by: Khalid Aziz <khalid@xxxxxxxxxx> Signed-off-by: Anthony Yznaga <anthony.yznaga@xxxxxxxxxx> --- mm/mshare.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/mm/mshare.c b/mm/mshare.c index f718b8934cdf..a37849e724e1 100644 --- a/mm/mshare.c +++ b/mm/mshare.c @@ -17,6 +17,10 @@ #include <linux/fs_context.h> #include <uapi/linux/magic.h> +struct mshare_data { + struct mm_struct *mm; +}; + struct msharefs_info { struct dentry *info_dentry; }; @@ -29,11 +33,51 @@ static const struct file_operations msharefs_file_operations = { .llseek = no_llseek, }; +static int +msharefs_fill_mm(struct inode *inode) +{ + struct mm_struct *mm; + struct mshare_data *m_data = NULL; + int ret = 0; + + mm = mm_alloc(); + if (!mm) { + ret = -ENOMEM; + goto err_free; + } + + mm->mmap_base = mm->task_size = 0; + + m_data = kzalloc(sizeof(*m_data), GFP_KERNEL); + if (!m_data) { + ret = -ENOMEM; + goto err_free; + } + m_data->mm = mm; + inode->i_private = m_data; + + return 0; + +err_free: + if (mm) + mmput(mm); + kfree(m_data); + return ret; +} + +static void +msharefs_delmm(struct mshare_data *m_data) +{ + mmput(m_data->mm); + kfree(m_data); +} + static struct inode *msharefs_get_inode(struct mnt_idmap *idmap, struct super_block *sb, const struct inode *dir, umode_t mode) { struct inode *inode = new_inode(sb); + int ret; if (!inode) return ERR_PTR(-ENOMEM); @@ -46,6 +90,11 @@ static struct inode case S_IFREG: inode->i_op = &msharefs_file_inode_ops; inode->i_fop = &msharefs_file_operations; + ret = msharefs_fill_mm(inode); + if (ret) { + discard_new_inode(inode); + inode = ERR_PTR(ret); + } break; case S_IFDIR: inode->i_op = &msharefs_dir_inode_ops; @@ -141,6 +190,16 @@ static const struct inode_operations msharefs_dir_inode_ops = { .rename = msharefs_rename, }; +static void +mshare_evict_inode(struct inode *inode) +{ + struct mshare_data *m_data = inode->i_private; + + if (m_data) + msharefs_delmm(m_data); + clear_inode(inode); +} + static ssize_t mshare_info_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) @@ -158,6 +217,7 @@ static const struct file_operations mshare_info_ops = { static const struct super_operations mshare_s_ops = { .statfs = simple_statfs, + .evict_inode = mshare_evict_inode, }; static int -- 2.43.5