@@ -90,6 +90,9 @@ static struct vfsmount *shm_mnt;
9090/* Pretend that each entry is of this size in directory's i_size */
9191#define BOGO_DIRENT_SIZE 20
9292
93+ /* Pretend that one inode + its dentry occupy this much memory */
94+ #define BOGO_INODE_SIZE 1024
95+
9396/* Symlink up to this size is kmalloc'ed instead of using a swappable page */
9497#define SHORT_SYMLINK_LEN 128
9598
@@ -137,7 +140,8 @@ static unsigned long shmem_default_max_inodes(void)
137140{
138141 unsigned long nr_pages = totalram_pages ();
139142
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 );
141145}
142146#endif
143147
@@ -331,11 +335,11 @@ static int shmem_reserve_inode(struct super_block *sb, ino_t *inop)
331335 if (!(sb -> s_flags & SB_KERNMOUNT )) {
332336 raw_spin_lock (& sbinfo -> stat_lock );
333337 if (sbinfo -> max_inodes ) {
334- if (! sbinfo -> free_inodes ) {
338+ if (sbinfo -> free_ispace < BOGO_INODE_SIZE ) {
335339 raw_spin_unlock (& sbinfo -> stat_lock );
336340 return - ENOSPC ;
337341 }
338- sbinfo -> free_inodes -- ;
342+ sbinfo -> free_ispace -= BOGO_INODE_SIZE ;
339343 }
340344 if (inop ) {
341345 ino = sbinfo -> next_ino ++ ;
@@ -394,7 +398,7 @@ static void shmem_free_inode(struct super_block *sb)
394398 struct shmem_sb_info * sbinfo = SHMEM_SB (sb );
395399 if (sbinfo -> max_inodes ) {
396400 raw_spin_lock (& sbinfo -> stat_lock );
397- sbinfo -> free_inodes ++ ;
401+ sbinfo -> free_ispace += BOGO_INODE_SIZE ;
398402 raw_spin_unlock (& sbinfo -> stat_lock );
399403 }
400404}
@@ -3158,7 +3162,7 @@ static int shmem_statfs(struct dentry *dentry, struct kstatfs *buf)
31583162 }
31593163 if (sbinfo -> max_inodes ) {
31603164 buf -> f_files = sbinfo -> max_inodes ;
3161- buf -> f_ffree = sbinfo -> free_inodes ;
3165+ buf -> f_ffree = sbinfo -> free_ispace / BOGO_INODE_SIZE ;
31623166 }
31633167 /* else leave those fields 0 like simple_statfs */
31643168
@@ -3818,13 +3822,13 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
38183822 break ;
38193823 case Opt_nr_blocks :
38203824 ctx -> blocks = memparse (param -> string , & rest );
3821- if (* rest || ctx -> blocks > S64_MAX )
3825+ if (* rest || ctx -> blocks > LONG_MAX )
38223826 goto bad_value ;
38233827 ctx -> seen |= SHMEM_SEEN_BLOCKS ;
38243828 break ;
38253829 case Opt_nr_inodes :
38263830 ctx -> inodes = memparse (param -> string , & rest );
3827- if (* rest )
3831+ if (* rest || ctx -> inodes > ULONG_MAX / BOGO_INODE_SIZE )
38283832 goto bad_value ;
38293833 ctx -> seen |= SHMEM_SEEN_INODES ;
38303834 break ;
@@ -4005,21 +4009,17 @@ static int shmem_parse_options(struct fs_context *fc, void *data)
40054009
40064010/*
40074011 * 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.
40124012 */
40134013static int shmem_reconfigure (struct fs_context * fc )
40144014{
40154015 struct shmem_options * ctx = fc -> fs_private ;
40164016 struct shmem_sb_info * sbinfo = SHMEM_SB (fc -> root -> d_sb );
4017- unsigned long inodes ;
4017+ unsigned long used_isp ;
40184018 struct mempolicy * mpol = NULL ;
40194019 const char * err ;
40204020
40214021 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 ;
40234023
40244024 if ((ctx -> seen & SHMEM_SEEN_BLOCKS ) && ctx -> blocks ) {
40254025 if (!sbinfo -> max_blocks ) {
@@ -4037,7 +4037,7 @@ static int shmem_reconfigure(struct fs_context *fc)
40374037 err = "Cannot retroactively limit inodes" ;
40384038 goto out ;
40394039 }
4040- if (ctx -> inodes < inodes ) {
4040+ if (ctx -> inodes * BOGO_INODE_SIZE < used_isp ) {
40414041 err = "Too few inodes for current use" ;
40424042 goto out ;
40434043 }
@@ -4083,7 +4083,7 @@ static int shmem_reconfigure(struct fs_context *fc)
40834083 sbinfo -> max_blocks = ctx -> blocks ;
40844084 if (ctx -> seen & SHMEM_SEEN_INODES ) {
40854085 sbinfo -> max_inodes = ctx -> inodes ;
4086- sbinfo -> free_inodes = ctx -> inodes - inodes ;
4086+ sbinfo -> free_ispace = ctx -> inodes * BOGO_INODE_SIZE - used_isp ;
40874087 }
40884088
40894089 /*
@@ -4214,7 +4214,8 @@ static int shmem_fill_super(struct super_block *sb, struct fs_context *fc)
42144214 sb -> s_flags |= SB_NOUSER ;
42154215#endif
42164216 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 ;
42184219 if (sb -> s_flags & SB_KERNMOUNT ) {
42194220 sbinfo -> ino_batch = alloc_percpu (ino_t );
42204221 if (!sbinfo -> ino_batch )
0 commit comments