shmem.c (5de75970c9fd7220e394b76e6d20fbafa1369b5a) | shmem.c (e07c469e979c104464300aaa3b7923f929055cd0) |
---|---|
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. --- 76 unchanged lines hidden (view full) --- 85#include "internal.h" 86 87#define BLOCKS_PER_PAGE (PAGE_SIZE/512) 88#define VM_ACCT(size) (PAGE_ALIGN(size) >> PAGE_SHIFT) 89 90/* Pretend that each entry is of this size in directory's i_size */ 91#define BOGO_DIRENT_SIZE 20 92 | 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. --- 76 unchanged lines hidden (view full) --- 85#include "internal.h" 86 87#define BLOCKS_PER_PAGE (PAGE_SIZE/512) 88#define VM_ACCT(size) (PAGE_ALIGN(size) >> PAGE_SHIFT) 89 90/* Pretend that each entry is of this size in directory's i_size */ 91#define BOGO_DIRENT_SIZE 20 92 |
93/* Pretend that one inode + its dentry occupy this much memory */ 94#define BOGO_INODE_SIZE 1024 95 |
|
93/* Symlink up to this size is kmalloc'ed instead of using a swappable page */ 94#define SHORT_SYMLINK_LEN 128 95 96/* 97 * shmem_fallocate communicates with shmem_fault or shmem_writepage via 98 * inode->i_private (with i_rwsem making sure that it has only one user at 99 * a time): we would prefer not to enlarge the shmem inode just for that. 100 */ --- 31 unchanged lines hidden (view full) --- 132{ 133 return totalram_pages() / 2; 134} 135 136static unsigned long shmem_default_max_inodes(void) 137{ 138 unsigned long nr_pages = totalram_pages(); 139 | 96/* Symlink up to this size is kmalloc'ed instead of using a swappable page */ 97#define SHORT_SYMLINK_LEN 128 98 99/* 100 * shmem_fallocate communicates with shmem_fault or shmem_writepage via 101 * inode->i_private (with i_rwsem making sure that it has only one user at 102 * a time): we would prefer not to enlarge the shmem inode just for that. 103 */ --- 31 unchanged lines hidden (view full) --- 135{ 136 return totalram_pages() / 2; 137} 138 139static unsigned long shmem_default_max_inodes(void) 140{ 141 unsigned long nr_pages = totalram_pages(); 142 |
140 return min(nr_pages - totalhigh_pages(), nr_pages / 2); | 143 return min3(nr_pages - totalhigh_pages(), nr_pages / 2, 144 ULONG_MAX / BOGO_INODE_SIZE); |
141} 142#endif 143 144static int shmem_swapin_folio(struct inode *inode, pgoff_t index, 145 struct folio **foliop, enum sgp_type sgp, 146 gfp_t gfp, struct vm_area_struct *vma, 147 vm_fault_t *fault_type); 148 --- 177 unchanged lines hidden (view full) --- 326static int shmem_reserve_inode(struct super_block *sb, ino_t *inop) 327{ 328 struct shmem_sb_info *sbinfo = SHMEM_SB(sb); 329 ino_t ino; 330 331 if (!(sb->s_flags & SB_KERNMOUNT)) { 332 raw_spin_lock(&sbinfo->stat_lock); 333 if (sbinfo->max_inodes) { | 145} 146#endif 147 148static int shmem_swapin_folio(struct inode *inode, pgoff_t index, 149 struct folio **foliop, enum sgp_type sgp, 150 gfp_t gfp, struct vm_area_struct *vma, 151 vm_fault_t *fault_type); 152 --- 177 unchanged lines hidden (view full) --- 330static int shmem_reserve_inode(struct super_block *sb, ino_t *inop) 331{ 332 struct shmem_sb_info *sbinfo = SHMEM_SB(sb); 333 ino_t ino; 334 335 if (!(sb->s_flags & SB_KERNMOUNT)) { 336 raw_spin_lock(&sbinfo->stat_lock); 337 if (sbinfo->max_inodes) { |
334 if (!sbinfo->free_inodes) { | 338 if (sbinfo->free_ispace < BOGO_INODE_SIZE) { |
335 raw_spin_unlock(&sbinfo->stat_lock); 336 return -ENOSPC; 337 } | 339 raw_spin_unlock(&sbinfo->stat_lock); 340 return -ENOSPC; 341 } |
338 sbinfo->free_inodes--; | 342 sbinfo->free_ispace -= BOGO_INODE_SIZE; |
339 } 340 if (inop) { 341 ino = sbinfo->next_ino++; 342 if (unlikely(is_zero_ino(ino))) 343 ino = sbinfo->next_ino++; 344 if (unlikely(!sbinfo->full_inums && 345 ino > UINT_MAX)) { 346 /* --- 42 unchanged lines hidden (view full) --- 389 return 0; 390} 391 392static void shmem_free_inode(struct super_block *sb) 393{ 394 struct shmem_sb_info *sbinfo = SHMEM_SB(sb); 395 if (sbinfo->max_inodes) { 396 raw_spin_lock(&sbinfo->stat_lock); | 343 } 344 if (inop) { 345 ino = sbinfo->next_ino++; 346 if (unlikely(is_zero_ino(ino))) 347 ino = sbinfo->next_ino++; 348 if (unlikely(!sbinfo->full_inums && 349 ino > UINT_MAX)) { 350 /* --- 42 unchanged lines hidden (view full) --- 393 return 0; 394} 395 396static void shmem_free_inode(struct super_block *sb) 397{ 398 struct shmem_sb_info *sbinfo = SHMEM_SB(sb); 399 if (sbinfo->max_inodes) { 400 raw_spin_lock(&sbinfo->stat_lock); |
397 sbinfo->free_inodes++; | 401 sbinfo->free_ispace += BOGO_INODE_SIZE; |
398 raw_spin_unlock(&sbinfo->stat_lock); 399 } 400} 401 402/** 403 * shmem_recalc_inode - recalculate the block usage of an inode 404 * @inode: inode to recalc 405 * @alloced: the change in number of pages allocated to inode --- 2747 unchanged lines hidden (view full) --- 3153 if (sbinfo->max_blocks) { 3154 buf->f_blocks = sbinfo->max_blocks; 3155 buf->f_bavail = 3156 buf->f_bfree = sbinfo->max_blocks - 3157 percpu_counter_sum(&sbinfo->used_blocks); 3158 } 3159 if (sbinfo->max_inodes) { 3160 buf->f_files = sbinfo->max_inodes; | 402 raw_spin_unlock(&sbinfo->stat_lock); 403 } 404} 405 406/** 407 * shmem_recalc_inode - recalculate the block usage of an inode 408 * @inode: inode to recalc 409 * @alloced: the change in number of pages allocated to inode --- 2747 unchanged lines hidden (view full) --- 3157 if (sbinfo->max_blocks) { 3158 buf->f_blocks = sbinfo->max_blocks; 3159 buf->f_bavail = 3160 buf->f_bfree = sbinfo->max_blocks - 3161 percpu_counter_sum(&sbinfo->used_blocks); 3162 } 3163 if (sbinfo->max_inodes) { 3164 buf->f_files = sbinfo->max_inodes; |
3161 buf->f_ffree = sbinfo->free_inodes; | 3165 buf->f_ffree = sbinfo->free_ispace / BOGO_INODE_SIZE; |
3162 } 3163 /* else leave those fields 0 like simple_statfs */ 3164 3165 buf->f_fsid = uuid_to_fsid(dentry->d_sb->s_uuid.b); 3166 3167 return 0; 3168} 3169 --- 643 unchanged lines hidden (view full) --- 3813 } 3814 if (*rest) 3815 goto bad_value; 3816 ctx->blocks = DIV_ROUND_UP(size, PAGE_SIZE); 3817 ctx->seen |= SHMEM_SEEN_BLOCKS; 3818 break; 3819 case Opt_nr_blocks: 3820 ctx->blocks = memparse(param->string, &rest); | 3166 } 3167 /* else leave those fields 0 like simple_statfs */ 3168 3169 buf->f_fsid = uuid_to_fsid(dentry->d_sb->s_uuid.b); 3170 3171 return 0; 3172} 3173 --- 643 unchanged lines hidden (view full) --- 3817 } 3818 if (*rest) 3819 goto bad_value; 3820 ctx->blocks = DIV_ROUND_UP(size, PAGE_SIZE); 3821 ctx->seen |= SHMEM_SEEN_BLOCKS; 3822 break; 3823 case Opt_nr_blocks: 3824 ctx->blocks = memparse(param->string, &rest); |
3821 if (*rest || ctx->blocks > S64_MAX) | 3825 if (*rest || ctx->blocks > LONG_MAX) |
3822 goto bad_value; 3823 ctx->seen |= SHMEM_SEEN_BLOCKS; 3824 break; 3825 case Opt_nr_inodes: 3826 ctx->inodes = memparse(param->string, &rest); | 3826 goto bad_value; 3827 ctx->seen |= SHMEM_SEEN_BLOCKS; 3828 break; 3829 case Opt_nr_inodes: 3830 ctx->inodes = memparse(param->string, &rest); |
3827 if (*rest) | 3831 if (*rest || ctx->inodes > ULONG_MAX / BOGO_INODE_SIZE) |
3828 goto bad_value; 3829 ctx->seen |= SHMEM_SEEN_INODES; 3830 break; 3831 case Opt_mode: 3832 ctx->mode = result.uint_32 & 07777; 3833 break; 3834 case Opt_uid: 3835 kuid = make_kuid(current_user_ns(), result.uint_32); --- 164 unchanged lines hidden (view full) --- 4000 return err; 4001 } 4002 } 4003 return 0; 4004} 4005 4006/* 4007 * Reconfigure a shmem filesystem. | 3832 goto bad_value; 3833 ctx->seen |= SHMEM_SEEN_INODES; 3834 break; 3835 case Opt_mode: 3836 ctx->mode = result.uint_32 & 07777; 3837 break; 3838 case Opt_uid: 3839 kuid = make_kuid(current_user_ns(), result.uint_32); --- 164 unchanged lines hidden (view full) --- 4004 return err; 4005 } 4006 } 4007 return 0; 4008} 4009 4010/* 4011 * Reconfigure a shmem filesystem. |
4008 * 4009 * Note that we disallow change from limited->unlimited blocks/inodes while any 4010 * are in use; but we must separately disallow unlimited->limited, because in 4011 * that case we have no record of how much is already in use. | |
4012 */ 4013static int shmem_reconfigure(struct fs_context *fc) 4014{ 4015 struct shmem_options *ctx = fc->fs_private; 4016 struct shmem_sb_info *sbinfo = SHMEM_SB(fc->root->d_sb); | 4012 */ 4013static int shmem_reconfigure(struct fs_context *fc) 4014{ 4015 struct shmem_options *ctx = fc->fs_private; 4016 struct shmem_sb_info *sbinfo = SHMEM_SB(fc->root->d_sb); |
4017 unsigned long inodes; | 4017 unsigned long used_isp; |
4018 struct mempolicy *mpol = NULL; 4019 const char *err; 4020 4021 raw_spin_lock(&sbinfo->stat_lock); | 4018 struct mempolicy *mpol = NULL; 4019 const char *err; 4020 4021 raw_spin_lock(&sbinfo->stat_lock); |
4022 inodes = sbinfo->max_inodes - sbinfo->free_inodes; | 4022 used_isp = sbinfo->max_inodes * BOGO_INODE_SIZE - sbinfo->free_ispace; |
4023 4024 if ((ctx->seen & SHMEM_SEEN_BLOCKS) && ctx->blocks) { 4025 if (!sbinfo->max_blocks) { 4026 err = "Cannot retroactively limit size"; 4027 goto out; 4028 } 4029 if (percpu_counter_compare(&sbinfo->used_blocks, 4030 ctx->blocks) > 0) { 4031 err = "Too small a size for current use"; 4032 goto out; 4033 } 4034 } 4035 if ((ctx->seen & SHMEM_SEEN_INODES) && ctx->inodes) { 4036 if (!sbinfo->max_inodes) { 4037 err = "Cannot retroactively limit inodes"; 4038 goto out; 4039 } | 4023 4024 if ((ctx->seen & SHMEM_SEEN_BLOCKS) && ctx->blocks) { 4025 if (!sbinfo->max_blocks) { 4026 err = "Cannot retroactively limit size"; 4027 goto out; 4028 } 4029 if (percpu_counter_compare(&sbinfo->used_blocks, 4030 ctx->blocks) > 0) { 4031 err = "Too small a size for current use"; 4032 goto out; 4033 } 4034 } 4035 if ((ctx->seen & SHMEM_SEEN_INODES) && ctx->inodes) { 4036 if (!sbinfo->max_inodes) { 4037 err = "Cannot retroactively limit inodes"; 4038 goto out; 4039 } |
4040 if (ctx->inodes < inodes) { | 4040 if (ctx->inodes * BOGO_INODE_SIZE < used_isp) { |
4041 err = "Too few inodes for current use"; 4042 goto out; 4043 } 4044 } 4045 4046 if ((ctx->seen & SHMEM_SEEN_INUMS) && !ctx->full_inums && 4047 sbinfo->next_ino > UINT_MAX) { 4048 err = "Current inum too high to switch to 32-bit inums"; --- 29 unchanged lines hidden (view full) --- 4078 if (ctx->seen & SHMEM_SEEN_HUGE) 4079 sbinfo->huge = ctx->huge; 4080 if (ctx->seen & SHMEM_SEEN_INUMS) 4081 sbinfo->full_inums = ctx->full_inums; 4082 if (ctx->seen & SHMEM_SEEN_BLOCKS) 4083 sbinfo->max_blocks = ctx->blocks; 4084 if (ctx->seen & SHMEM_SEEN_INODES) { 4085 sbinfo->max_inodes = ctx->inodes; | 4041 err = "Too few inodes for current use"; 4042 goto out; 4043 } 4044 } 4045 4046 if ((ctx->seen & SHMEM_SEEN_INUMS) && !ctx->full_inums && 4047 sbinfo->next_ino > UINT_MAX) { 4048 err = "Current inum too high to switch to 32-bit inums"; --- 29 unchanged lines hidden (view full) --- 4078 if (ctx->seen & SHMEM_SEEN_HUGE) 4079 sbinfo->huge = ctx->huge; 4080 if (ctx->seen & SHMEM_SEEN_INUMS) 4081 sbinfo->full_inums = ctx->full_inums; 4082 if (ctx->seen & SHMEM_SEEN_BLOCKS) 4083 sbinfo->max_blocks = ctx->blocks; 4084 if (ctx->seen & SHMEM_SEEN_INODES) { 4085 sbinfo->max_inodes = ctx->inodes; |
4086 sbinfo->free_inodes = ctx->inodes - inodes; | 4086 sbinfo->free_ispace = ctx->inodes * BOGO_INODE_SIZE - used_isp; |
4087 } 4088 4089 /* 4090 * Preserve previous mempolicy unless mpol remount option was specified. 4091 */ 4092 if (ctx->mpol) { 4093 mpol = sbinfo->mpol; 4094 sbinfo->mpol = ctx->mpol; /* transfers initial ref */ --- 114 unchanged lines hidden (view full) --- 4209 sb->s_flags |= SB_NOUSER; 4210 } 4211 sb->s_export_op = &shmem_export_ops; 4212 sb->s_flags |= SB_NOSEC | SB_I_VERSION; 4213#else 4214 sb->s_flags |= SB_NOUSER; 4215#endif 4216 sbinfo->max_blocks = ctx->blocks; | 4087 } 4088 4089 /* 4090 * Preserve previous mempolicy unless mpol remount option was specified. 4091 */ 4092 if (ctx->mpol) { 4093 mpol = sbinfo->mpol; 4094 sbinfo->mpol = ctx->mpol; /* transfers initial ref */ --- 114 unchanged lines hidden (view full) --- 4209 sb->s_flags |= SB_NOUSER; 4210 } 4211 sb->s_export_op = &shmem_export_ops; 4212 sb->s_flags |= SB_NOSEC | SB_I_VERSION; 4213#else 4214 sb->s_flags |= SB_NOUSER; 4215#endif 4216 sbinfo->max_blocks = ctx->blocks; |
4217 sbinfo->free_inodes = sbinfo->max_inodes = ctx->inodes; | 4217 sbinfo->max_inodes = ctx->inodes; 4218 sbinfo->free_ispace = sbinfo->max_inodes * BOGO_INODE_SIZE; |
4218 if (sb->s_flags & SB_KERNMOUNT) { 4219 sbinfo->ino_batch = alloc_percpu(ino_t); 4220 if (!sbinfo->ino_batch) 4221 goto failed; 4222 } 4223 sbinfo->uid = ctx->uid; 4224 sbinfo->gid = ctx->gid; 4225 sbinfo->full_inums = ctx->full_inums; --- 619 unchanged lines hidden --- | 4219 if (sb->s_flags & SB_KERNMOUNT) { 4220 sbinfo->ino_batch = alloc_percpu(ino_t); 4221 if (!sbinfo->ino_batch) 4222 goto failed; 4223 } 4224 sbinfo->uid = ctx->uid; 4225 sbinfo->gid = ctx->gid; 4226 sbinfo->full_inums = ctx->full_inums; --- 619 unchanged lines hidden --- |