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 --- |