@@ -90,6 +90,9 @@ static struct vfsmount *shm_mnt;
90
90
/* Pretend that each entry is of this size in directory's i_size */
91
91
#define BOGO_DIRENT_SIZE 20
92
92
93
+ /* Pretend that one inode + its dentry occupy this much memory */
94
+ #define BOGO_INODE_SIZE 1024
95
+
93
96
/* Symlink up to this size is kmalloc'ed instead of using a swappable page */
94
97
#define SHORT_SYMLINK_LEN 128
95
98
@@ -137,7 +140,8 @@ static unsigned long shmem_default_max_inodes(void)
137
140
{
138
141
unsigned long nr_pages = totalram_pages ();
139
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
145
}
142
146
#endif
143
147
@@ -331,11 +335,11 @@ static int shmem_reserve_inode(struct super_block *sb, ino_t *inop)
331
335
if (!(sb -> s_flags & SB_KERNMOUNT )) {
332
336
raw_spin_lock (& sbinfo -> stat_lock );
333
337
if (sbinfo -> max_inodes ) {
334
- if (! sbinfo -> free_inodes ) {
338
+ if (sbinfo -> free_ispace < BOGO_INODE_SIZE ) {
335
339
raw_spin_unlock (& sbinfo -> stat_lock );
336
340
return - ENOSPC ;
337
341
}
338
- sbinfo -> free_inodes -- ;
342
+ sbinfo -> free_ispace -= BOGO_INODE_SIZE ;
339
343
}
340
344
if (inop ) {
341
345
ino = sbinfo -> next_ino ++ ;
@@ -394,7 +398,7 @@ static void shmem_free_inode(struct super_block *sb)
394
398
struct shmem_sb_info * sbinfo = SHMEM_SB (sb );
395
399
if (sbinfo -> max_inodes ) {
396
400
raw_spin_lock (& sbinfo -> stat_lock );
397
- sbinfo -> free_inodes ++ ;
401
+ sbinfo -> free_ispace += BOGO_INODE_SIZE ;
398
402
raw_spin_unlock (& sbinfo -> stat_lock );
399
403
}
400
404
}
@@ -3158,7 +3162,7 @@ static int shmem_statfs(struct dentry *dentry, struct kstatfs *buf)
3158
3162
}
3159
3163
if (sbinfo -> max_inodes ) {
3160
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
3166
}
3163
3167
/* else leave those fields 0 like simple_statfs */
3164
3168
@@ -3818,13 +3822,13 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
3818
3822
break ;
3819
3823
case Opt_nr_blocks :
3820
3824
ctx -> blocks = memparse (param -> string , & rest );
3821
- if (* rest || ctx -> blocks > S64_MAX )
3825
+ if (* rest || ctx -> blocks > LONG_MAX )
3822
3826
goto bad_value ;
3823
3827
ctx -> seen |= SHMEM_SEEN_BLOCKS ;
3824
3828
break ;
3825
3829
case Opt_nr_inodes :
3826
3830
ctx -> inodes = memparse (param -> string , & rest );
3827
- if (* rest )
3831
+ if (* rest || ctx -> inodes > ULONG_MAX / BOGO_INODE_SIZE )
3828
3832
goto bad_value ;
3829
3833
ctx -> seen |= SHMEM_SEEN_INODES ;
3830
3834
break ;
@@ -4005,21 +4009,17 @@ static int shmem_parse_options(struct fs_context *fc, void *data)
4005
4009
4006
4010
/*
4007
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
4012
*/
4013
4013
static int shmem_reconfigure (struct fs_context * fc )
4014
4014
{
4015
4015
struct shmem_options * ctx = fc -> fs_private ;
4016
4016
struct shmem_sb_info * sbinfo = SHMEM_SB (fc -> root -> d_sb );
4017
- unsigned long inodes ;
4017
+ unsigned long used_isp ;
4018
4018
struct mempolicy * mpol = NULL ;
4019
4019
const char * err ;
4020
4020
4021
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
4023
4024
4024
if ((ctx -> seen & SHMEM_SEEN_BLOCKS ) && ctx -> blocks ) {
4025
4025
if (!sbinfo -> max_blocks ) {
@@ -4037,7 +4037,7 @@ static int shmem_reconfigure(struct fs_context *fc)
4037
4037
err = "Cannot retroactively limit inodes" ;
4038
4038
goto out ;
4039
4039
}
4040
- if (ctx -> inodes < inodes ) {
4040
+ if (ctx -> inodes * BOGO_INODE_SIZE < used_isp ) {
4041
4041
err = "Too few inodes for current use" ;
4042
4042
goto out ;
4043
4043
}
@@ -4083,7 +4083,7 @@ static int shmem_reconfigure(struct fs_context *fc)
4083
4083
sbinfo -> max_blocks = ctx -> blocks ;
4084
4084
if (ctx -> seen & SHMEM_SEEN_INODES ) {
4085
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
4087
}
4088
4088
4089
4089
/*
@@ -4214,7 +4214,8 @@ static int shmem_fill_super(struct super_block *sb, struct fs_context *fc)
4214
4214
sb -> s_flags |= SB_NOUSER ;
4215
4215
#endif
4216
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
4219
if (sb -> s_flags & SB_KERNMOUNT ) {
4219
4220
sbinfo -> ino_batch = alloc_percpu (ino_t );
4220
4221
if (!sbinfo -> ino_batch )
0 commit comments