shmem.c (272ac32f566e3f925b20c231a2b30f6893aa258a) shmem.c (e408e695f5f1f60d784913afc45ff2c387a5aeb8)
1/*
2 * Resizable virtual memory filesystem for Linux.
3 *
4 * Copyright (C) 2000 Linus Torvalds.
5 * 2000 Transmeta Corp.
6 * 2000-2001 Christoph Rohland
7 * 2000-2001 SAP AG
8 * 2002 Red Hat Inc.

--- 14 unchanged lines hidden (view full) ---

23
24#include <linux/fs.h>
25#include <linux/init.h>
26#include <linux/vfs.h>
27#include <linux/mount.h>
28#include <linux/ramfs.h>
29#include <linux/pagemap.h>
30#include <linux/file.h>
1/*
2 * Resizable virtual memory filesystem for Linux.
3 *
4 * Copyright (C) 2000 Linus Torvalds.
5 * 2000 Transmeta Corp.
6 * 2000-2001 Christoph Rohland
7 * 2000-2001 SAP AG
8 * 2002 Red Hat Inc.

--- 14 unchanged lines hidden (view full) ---

23
24#include <linux/fs.h>
25#include <linux/init.h>
26#include <linux/vfs.h>
27#include <linux/mount.h>
28#include <linux/ramfs.h>
29#include <linux/pagemap.h>
30#include <linux/file.h>
31#include <linux/fileattr.h>
31#include <linux/mm.h>
32#include <linux/random.h>
33#include <linux/sched/signal.h>
34#include <linux/export.h>
35#include <linux/swap.h>
36#include <linux/uio.h>
37#include <linux/hugetlb.h>
38#include <linux/fs_parser.h>

--- 1014 unchanged lines hidden (view full) ---

1053 struct inode *inode = path->dentry->d_inode;
1054 struct shmem_inode_info *info = SHMEM_I(inode);
1055
1056 if (info->alloced - info->swapped != inode->i_mapping->nrpages) {
1057 spin_lock_irq(&info->lock);
1058 shmem_recalc_inode(inode);
1059 spin_unlock_irq(&info->lock);
1060 }
32#include <linux/mm.h>
33#include <linux/random.h>
34#include <linux/sched/signal.h>
35#include <linux/export.h>
36#include <linux/swap.h>
37#include <linux/uio.h>
38#include <linux/hugetlb.h>
39#include <linux/fs_parser.h>

--- 1014 unchanged lines hidden (view full) ---

1054 struct inode *inode = path->dentry->d_inode;
1055 struct shmem_inode_info *info = SHMEM_I(inode);
1056
1057 if (info->alloced - info->swapped != inode->i_mapping->nrpages) {
1058 spin_lock_irq(&info->lock);
1059 shmem_recalc_inode(inode);
1060 spin_unlock_irq(&info->lock);
1061 }
1062 if (info->fsflags & FS_APPEND_FL)
1063 stat->attributes |= STATX_ATTR_APPEND;
1064 if (info->fsflags & FS_IMMUTABLE_FL)
1065 stat->attributes |= STATX_ATTR_IMMUTABLE;
1066 if (info->fsflags & FS_NODUMP_FL)
1067 stat->attributes |= STATX_ATTR_NODUMP;
1068 stat->attributes_mask |= (STATX_ATTR_APPEND |
1069 STATX_ATTR_IMMUTABLE |
1070 STATX_ATTR_NODUMP);
1061 generic_fillattr(&init_user_ns, inode, stat);
1062
1063 if (shmem_is_huge(NULL, inode, 0))
1064 stat->blksize = HPAGE_PMD_SIZE;
1065
1066 if (request_mask & STATX_BTIME) {
1067 stat->result_mask |= STATX_BTIME;
1068 stat->btime.tv_sec = info->i_crtime.tv_sec;

--- 617 unchanged lines hidden (view full) ---

1686 swapin_error = make_swapin_error_entry(&folio->page);
1687 old = xa_cmpxchg_irq(&mapping->i_pages, index,
1688 swp_to_radix_entry(swap),
1689 swp_to_radix_entry(swapin_error), 0);
1690 if (old != swp_to_radix_entry(swap))
1691 return;
1692
1693 folio_wait_writeback(folio);
1071 generic_fillattr(&init_user_ns, inode, stat);
1072
1073 if (shmem_is_huge(NULL, inode, 0))
1074 stat->blksize = HPAGE_PMD_SIZE;
1075
1076 if (request_mask & STATX_BTIME) {
1077 stat->result_mask |= STATX_BTIME;
1078 stat->btime.tv_sec = info->i_crtime.tv_sec;

--- 617 unchanged lines hidden (view full) ---

1696 swapin_error = make_swapin_error_entry(&folio->page);
1697 old = xa_cmpxchg_irq(&mapping->i_pages, index,
1698 swp_to_radix_entry(swap),
1699 swp_to_radix_entry(swapin_error), 0);
1700 if (old != swp_to_radix_entry(swap))
1701 return;
1702
1703 folio_wait_writeback(folio);
1694 delete_from_swap_cache(&folio->page);
1704 delete_from_swap_cache(folio);
1695 spin_lock_irq(&info->lock);
1696 /*
1697 * Don't treat swapin error folio as alloced. Otherwise inode->i_blocks won't
1698 * be 0 when inode is released and thus trigger WARN_ON(inode->i_blocks) in
1699 * shmem_evict_inode.
1700 */
1701 info->alloced--;
1702 info->swapped--;
1703 shmem_recalc_inode(inode);
1704 spin_unlock_irq(&info->lock);
1705 swap_free(swap);
1706}
1707
1708/*
1705 spin_lock_irq(&info->lock);
1706 /*
1707 * Don't treat swapin error folio as alloced. Otherwise inode->i_blocks won't
1708 * be 0 when inode is released and thus trigger WARN_ON(inode->i_blocks) in
1709 * shmem_evict_inode.
1710 */
1711 info->alloced--;
1712 info->swapped--;
1713 shmem_recalc_inode(inode);
1714 spin_unlock_irq(&info->lock);
1715 swap_free(swap);
1716}
1717
1718/*
1709 * Swap in the page pointed to by *pagep.
1710 * Caller has to make sure that *pagep contains a valid swapped page.
1711 * Returns 0 and the page in pagep if success. On failure, returns the
1712 * error code and NULL in *pagep.
1719 * Swap in the folio pointed to by *foliop.
1720 * Caller has to make sure that *foliop contains a valid swapped folio.
1721 * Returns 0 and the folio in foliop if success. On failure, returns the
1722 * error code and NULL in *foliop.
1713 */
1714static int shmem_swapin_folio(struct inode *inode, pgoff_t index,
1715 struct folio **foliop, enum sgp_type sgp,
1716 gfp_t gfp, struct vm_area_struct *vma,
1717 vm_fault_t *fault_type)
1718{
1719 struct address_space *mapping = inode->i_mapping;
1720 struct shmem_inode_info *info = SHMEM_I(inode);

--- 23 unchanged lines hidden (view full) ---

1744 page = shmem_swapin(swap, gfp, info, index);
1745 if (!page) {
1746 error = -ENOMEM;
1747 goto failed;
1748 }
1749 }
1750 folio = page_folio(page);
1751
1723 */
1724static int shmem_swapin_folio(struct inode *inode, pgoff_t index,
1725 struct folio **foliop, enum sgp_type sgp,
1726 gfp_t gfp, struct vm_area_struct *vma,
1727 vm_fault_t *fault_type)
1728{
1729 struct address_space *mapping = inode->i_mapping;
1730 struct shmem_inode_info *info = SHMEM_I(inode);

--- 23 unchanged lines hidden (view full) ---

1754 page = shmem_swapin(swap, gfp, info, index);
1755 if (!page) {
1756 error = -ENOMEM;
1757 goto failed;
1758 }
1759 }
1760 folio = page_folio(page);
1761
1752 /* We have to do this with page locked to prevent races */
1762 /* We have to do this with folio locked to prevent races */
1753 folio_lock(folio);
1754 if (!folio_test_swapcache(folio) ||
1755 folio_swap_entry(folio).val != swap.val ||
1756 !shmem_confirm_swap(mapping, index, swap)) {
1757 error = -EEXIST;
1758 goto unlock;
1759 }
1760 if (!folio_test_uptodate(folio)) {

--- 23 unchanged lines hidden (view full) ---

1784 spin_lock_irq(&info->lock);
1785 info->swapped--;
1786 shmem_recalc_inode(inode);
1787 spin_unlock_irq(&info->lock);
1788
1789 if (sgp == SGP_WRITE)
1790 folio_mark_accessed(folio);
1791
1763 folio_lock(folio);
1764 if (!folio_test_swapcache(folio) ||
1765 folio_swap_entry(folio).val != swap.val ||
1766 !shmem_confirm_swap(mapping, index, swap)) {
1767 error = -EEXIST;
1768 goto unlock;
1769 }
1770 if (!folio_test_uptodate(folio)) {

--- 23 unchanged lines hidden (view full) ---

1794 spin_lock_irq(&info->lock);
1795 info->swapped--;
1796 shmem_recalc_inode(inode);
1797 spin_unlock_irq(&info->lock);
1798
1799 if (sgp == SGP_WRITE)
1800 folio_mark_accessed(folio);
1801
1792 delete_from_swap_cache(&folio->page);
1802 delete_from_swap_cache(folio);
1793 folio_mark_dirty(folio);
1794 swap_free(swap);
1795
1796 *foliop = folio;
1797 return 0;
1798failed:
1799 if (!shmem_confirm_swap(mapping, index, swap))
1800 error = -EEXIST;

--- 466 unchanged lines hidden (view full) ---

2267 /* arm64 - allow memory tagging on RAM-based files */
2268 vma->vm_flags |= VM_MTE_ALLOWED;
2269
2270 file_accessed(file);
2271 vma->vm_ops = &shmem_vm_ops;
2272 return 0;
2273}
2274
1803 folio_mark_dirty(folio);
1804 swap_free(swap);
1805
1806 *foliop = folio;
1807 return 0;
1808failed:
1809 if (!shmem_confirm_swap(mapping, index, swap))
1810 error = -EEXIST;

--- 466 unchanged lines hidden (view full) ---

2277 /* arm64 - allow memory tagging on RAM-based files */
2278 vma->vm_flags |= VM_MTE_ALLOWED;
2279
2280 file_accessed(file);
2281 vma->vm_ops = &shmem_vm_ops;
2282 return 0;
2283}
2284
2275static struct inode *shmem_get_inode(struct super_block *sb, const struct inode *dir,
2285/* Mask out flags that are inappropriate for the given type of inode. */
2286static unsigned shmem_mask_flags(umode_t mode, __u32 flags)
2287{
2288 if (S_ISDIR(mode))
2289 return flags;
2290 else if (S_ISREG(mode))
2291 return flags & SHMEM_REG_FLMASK;
2292 else
2293 return flags & SHMEM_OTHER_FLMASK;
2294}
2295
2296static struct inode *shmem_get_inode(struct super_block *sb, struct inode *dir,
2276 umode_t mode, dev_t dev, unsigned long flags)
2277{
2278 struct inode *inode;
2279 struct shmem_inode_info *info;
2280 struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
2281 ino_t ino;
2282
2283 if (shmem_reserve_inode(sb, &ino))

--- 8 unchanged lines hidden (view full) ---

2292 inode->i_generation = prandom_u32();
2293 info = SHMEM_I(inode);
2294 memset(info, 0, (char *)inode - (char *)info);
2295 spin_lock_init(&info->lock);
2296 atomic_set(&info->stop_eviction, 0);
2297 info->seals = F_SEAL_SEAL;
2298 info->flags = flags & VM_NORESERVE;
2299 info->i_crtime = inode->i_mtime;
2297 umode_t mode, dev_t dev, unsigned long flags)
2298{
2299 struct inode *inode;
2300 struct shmem_inode_info *info;
2301 struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
2302 ino_t ino;
2303
2304 if (shmem_reserve_inode(sb, &ino))

--- 8 unchanged lines hidden (view full) ---

2313 inode->i_generation = prandom_u32();
2314 info = SHMEM_I(inode);
2315 memset(info, 0, (char *)inode - (char *)info);
2316 spin_lock_init(&info->lock);
2317 atomic_set(&info->stop_eviction, 0);
2318 info->seals = F_SEAL_SEAL;
2319 info->flags = flags & VM_NORESERVE;
2320 info->i_crtime = inode->i_mtime;
2321 info->fsflags = (dir == NULL) ? 0 :
2322 SHMEM_I(dir)->fsflags & SHMEM_FL_INHERITED;
2323 info->fsflags = shmem_mask_flags(mode, info->fsflags);
2300 INIT_LIST_HEAD(&info->shrinklist);
2301 INIT_LIST_HEAD(&info->swaplist);
2302 simple_xattrs_init(&info->xattrs);
2303 cache_no_acl(inode);
2304 mapping_set_large_folios(inode->i_mapping);
2305
2306 switch (mode & S_IFMT) {
2307 default:

--- 825 unchanged lines hidden (view full) ---

3133 }
3134 unlock_page(page);
3135 }
3136 set_delayed_call(done, shmem_put_link, page);
3137 return page_address(page);
3138}
3139
3140#ifdef CONFIG_TMPFS_XATTR
2324 INIT_LIST_HEAD(&info->shrinklist);
2325 INIT_LIST_HEAD(&info->swaplist);
2326 simple_xattrs_init(&info->xattrs);
2327 cache_no_acl(inode);
2328 mapping_set_large_folios(inode->i_mapping);
2329
2330 switch (mode & S_IFMT) {
2331 default:

--- 825 unchanged lines hidden (view full) ---

3157 }
3158 unlock_page(page);
3159 }
3160 set_delayed_call(done, shmem_put_link, page);
3161 return page_address(page);
3162}
3163
3164#ifdef CONFIG_TMPFS_XATTR
3165
3166static int shmem_fileattr_get(struct dentry *dentry, struct fileattr *fa)
3167{
3168 struct shmem_inode_info *info = SHMEM_I(d_inode(dentry));
3169
3170 fileattr_fill_flags(fa, info->fsflags & SHMEM_FL_USER_VISIBLE);
3171
3172 return 0;
3173}
3174
3175static int shmem_fileattr_set(struct user_namespace *mnt_userns,
3176 struct dentry *dentry, struct fileattr *fa)
3177{
3178 struct inode *inode = d_inode(dentry);
3179 struct shmem_inode_info *info = SHMEM_I(inode);
3180
3181 if (fileattr_has_fsx(fa))
3182 return -EOPNOTSUPP;
3183
3184 info->fsflags = (info->fsflags & ~SHMEM_FL_USER_MODIFIABLE) |
3185 (fa->flags & SHMEM_FL_USER_MODIFIABLE);
3186
3187 inode->i_flags &= ~(S_APPEND | S_IMMUTABLE | S_NOATIME);
3188 if (info->fsflags & FS_APPEND_FL)
3189 inode->i_flags |= S_APPEND;
3190 if (info->fsflags & FS_IMMUTABLE_FL)
3191 inode->i_flags |= S_IMMUTABLE;
3192 if (info->fsflags & FS_NOATIME_FL)
3193 inode->i_flags |= S_NOATIME;
3194
3195 inode->i_ctime = current_time(inode);
3196 return 0;
3197}
3198
3141/*
3142 * Superblocks without xattr inode operations may get some security.* xattr
3143 * support from the LSM "for free". As soon as we have any other xattrs
3144 * like ACLs, we also need to implement the security.* handlers at
3145 * filesystem level, though.
3146 */
3147
3148/*

--- 238 unchanged lines hidden (view full) ---

3387 }
3388 if (*rest)
3389 goto bad_value;
3390 ctx->blocks = DIV_ROUND_UP(size, PAGE_SIZE);
3391 ctx->seen |= SHMEM_SEEN_BLOCKS;
3392 break;
3393 case Opt_nr_blocks:
3394 ctx->blocks = memparse(param->string, &rest);
3199/*
3200 * Superblocks without xattr inode operations may get some security.* xattr
3201 * support from the LSM "for free". As soon as we have any other xattrs
3202 * like ACLs, we also need to implement the security.* handlers at
3203 * filesystem level, though.
3204 */
3205
3206/*

--- 238 unchanged lines hidden (view full) ---

3445 }
3446 if (*rest)
3447 goto bad_value;
3448 ctx->blocks = DIV_ROUND_UP(size, PAGE_SIZE);
3449 ctx->seen |= SHMEM_SEEN_BLOCKS;
3450 break;
3451 case Opt_nr_blocks:
3452 ctx->blocks = memparse(param->string, &rest);
3395 if (*rest || ctx->blocks > S64_MAX)
3453 if (*rest)
3396 goto bad_value;
3397 ctx->seen |= SHMEM_SEEN_BLOCKS;
3398 break;
3399 case Opt_nr_inodes:
3400 ctx->inodes = memparse(param->string, &rest);
3401 if (*rest)
3402 goto bad_value;
3403 ctx->seen |= SHMEM_SEEN_INODES;

--- 105 unchanged lines hidden (view full) ---

3509 struct shmem_options *ctx = fc->fs_private;
3510 struct shmem_sb_info *sbinfo = SHMEM_SB(fc->root->d_sb);
3511 unsigned long inodes;
3512 struct mempolicy *mpol = NULL;
3513 const char *err;
3514
3515 raw_spin_lock(&sbinfo->stat_lock);
3516 inodes = sbinfo->max_inodes - sbinfo->free_inodes;
3454 goto bad_value;
3455 ctx->seen |= SHMEM_SEEN_BLOCKS;
3456 break;
3457 case Opt_nr_inodes:
3458 ctx->inodes = memparse(param->string, &rest);
3459 if (*rest)
3460 goto bad_value;
3461 ctx->seen |= SHMEM_SEEN_INODES;

--- 105 unchanged lines hidden (view full) ---

3567 struct shmem_options *ctx = fc->fs_private;
3568 struct shmem_sb_info *sbinfo = SHMEM_SB(fc->root->d_sb);
3569 unsigned long inodes;
3570 struct mempolicy *mpol = NULL;
3571 const char *err;
3572
3573 raw_spin_lock(&sbinfo->stat_lock);
3574 inodes = sbinfo->max_inodes - sbinfo->free_inodes;
3517
3575 if (ctx->blocks > S64_MAX) {
3576 err = "Number of blocks too large";
3577 goto out;
3578 }
3518 if ((ctx->seen & SHMEM_SEEN_BLOCKS) && ctx->blocks) {
3519 if (!sbinfo->max_blocks) {
3520 err = "Cannot retroactively limit size";
3521 goto out;
3522 }
3523 if (percpu_counter_compare(&sbinfo->used_blocks,
3524 ctx->blocks) > 0) {
3525 err = "Too small a size for current use";

--- 294 unchanged lines hidden (view full) ---

3820};
3821
3822static const struct inode_operations shmem_inode_operations = {
3823 .getattr = shmem_getattr,
3824 .setattr = shmem_setattr,
3825#ifdef CONFIG_TMPFS_XATTR
3826 .listxattr = shmem_listxattr,
3827 .set_acl = simple_set_acl,
3579 if ((ctx->seen & SHMEM_SEEN_BLOCKS) && ctx->blocks) {
3580 if (!sbinfo->max_blocks) {
3581 err = "Cannot retroactively limit size";
3582 goto out;
3583 }
3584 if (percpu_counter_compare(&sbinfo->used_blocks,
3585 ctx->blocks) > 0) {
3586 err = "Too small a size for current use";

--- 294 unchanged lines hidden (view full) ---

3881};
3882
3883static const struct inode_operations shmem_inode_operations = {
3884 .getattr = shmem_getattr,
3885 .setattr = shmem_setattr,
3886#ifdef CONFIG_TMPFS_XATTR
3887 .listxattr = shmem_listxattr,
3888 .set_acl = simple_set_acl,
3889 .fileattr_get = shmem_fileattr_get,
3890 .fileattr_set = shmem_fileattr_set,
3828#endif
3829};
3830
3831static const struct inode_operations shmem_dir_inode_operations = {
3832#ifdef CONFIG_TMPFS
3833 .getattr = shmem_getattr,
3834 .create = shmem_create,
3835 .lookup = simple_lookup,
3836 .link = shmem_link,
3837 .unlink = shmem_unlink,
3838 .symlink = shmem_symlink,
3839 .mkdir = shmem_mkdir,
3840 .rmdir = shmem_rmdir,
3841 .mknod = shmem_mknod,
3842 .rename = shmem_rename2,
3843 .tmpfile = shmem_tmpfile,
3844#endif
3845#ifdef CONFIG_TMPFS_XATTR
3846 .listxattr = shmem_listxattr,
3891#endif
3892};
3893
3894static const struct inode_operations shmem_dir_inode_operations = {
3895#ifdef CONFIG_TMPFS
3896 .getattr = shmem_getattr,
3897 .create = shmem_create,
3898 .lookup = simple_lookup,
3899 .link = shmem_link,
3900 .unlink = shmem_unlink,
3901 .symlink = shmem_symlink,
3902 .mkdir = shmem_mkdir,
3903 .rmdir = shmem_rmdir,
3904 .mknod = shmem_mknod,
3905 .rename = shmem_rename2,
3906 .tmpfile = shmem_tmpfile,
3907#endif
3908#ifdef CONFIG_TMPFS_XATTR
3909 .listxattr = shmem_listxattr,
3910 .fileattr_get = shmem_fileattr_get,
3911 .fileattr_set = shmem_fileattr_set,
3847#endif
3848#ifdef CONFIG_TMPFS_POSIX_ACL
3849 .setattr = shmem_setattr,
3850 .set_acl = simple_set_acl,
3851#endif
3852};
3853
3854static const struct inode_operations shmem_special_inode_operations = {

--- 365 unchanged lines hidden ---
3912#endif
3913#ifdef CONFIG_TMPFS_POSIX_ACL
3914 .setattr = shmem_setattr,
3915 .set_acl = simple_set_acl,
3916#endif
3917};
3918
3919static const struct inode_operations shmem_special_inode_operations = {

--- 365 unchanged lines hidden ---