diff options
Diffstat (limited to 'mm/secretmem.c')
-rw-r--r-- | mm/secretmem.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/mm/secretmem.c b/mm/secretmem.c index 098638d3b8a4..206ed6b40c1d 100644 --- a/mm/secretmem.c +++ b/mm/secretmem.c @@ -145,19 +145,35 @@ static int secretmem_migratepage(struct address_space *mapping, return -EBUSY; } -static void secretmem_freepage(struct page *page) +static void secretmem_free_folio(struct folio *folio) { - set_direct_map_default_noflush(page); - clear_highpage(page); + set_direct_map_default_noflush(&folio->page); + folio_zero_segment(folio, 0, folio_size(folio)); } const struct address_space_operations secretmem_aops = { .dirty_folio = noop_dirty_folio, - .freepage = secretmem_freepage, + .free_folio = secretmem_free_folio, .migratepage = secretmem_migratepage, .isolate_page = secretmem_isolate_page, }; +static int secretmem_setattr(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *iattr) +{ + struct inode *inode = d_inode(dentry); + unsigned int ia_valid = iattr->ia_valid; + + if ((ia_valid & ATTR_SIZE) && inode->i_size) + return -EINVAL; + + return simple_setattr(mnt_userns, dentry, iattr); +} + +static const struct inode_operations secretmem_iops = { + .setattr = secretmem_setattr, +}; + static struct vfsmount *secretmem_mnt; static struct file *secretmem_file_create(unsigned long flags) @@ -177,6 +193,7 @@ static struct file *secretmem_file_create(unsigned long flags) mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER); mapping_set_unevictable(inode->i_mapping); + inode->i_op = &secretmem_iops; inode->i_mapping->a_ops = &secretmem_aops; /* pretend we are a normal file with zero size */ |