@@ -89,41 +89,44 @@ static void copy_fdtable(struct fdtable *nfdt, struct fdtable *ofdt)
89
89
* 'unsigned long' in some places, but simply because that is how the Linux
90
90
* kernel bitmaps are defined to work: they are not "bits in an array of bytes",
91
91
* they are very much "bits in an array of unsigned long".
92
- *
93
- * The ALIGN(nr, BITS_PER_LONG) here is for clarity: since we just multiplied
94
- * by that "1024/sizeof(ptr)" before, we already know there are sufficient
95
- * clear low bits. Clang seems to realize that, gcc ends up being confused.
96
- *
97
- * On a 128-bit machine, the ALIGN() would actually matter. In the meantime,
98
- * let's consider it documentation (and maybe a test-case for gcc to improve
99
- * its code generation ;)
100
92
*/
101
- static struct fdtable * alloc_fdtable (unsigned int nr )
93
+ static struct fdtable * alloc_fdtable (unsigned int slots_wanted )
102
94
{
103
95
struct fdtable * fdt ;
96
+ unsigned int nr ;
104
97
void * data ;
105
98
106
99
/*
107
100
* Figure out how many fds we actually want to support in this fdtable.
108
101
* Allocation steps are keyed to the size of the fdarray, since it
109
102
* grows far faster than any of the other dynamic data. We try to fit
110
103
* the fdarray into comfortable page-tuned chunks: starting at 1024B
111
- * and growing in powers of two from there on.
104
+ * and growing in powers of two from there on. Since we called only
105
+ * with slots_wanted > BITS_PER_LONG (embedded instance in files->fdtab
106
+ * already gives BITS_PER_LONG slots), the above boils down to
107
+ * 1. use the smallest power of two large enough to give us that many
108
+ * slots.
109
+ * 2. on 32bit skip 64 and 128 - the minimal capacity we want there is
110
+ * 256 slots (i.e. 1Kb fd array).
111
+ * 3. on 64bit don't skip anything, 1Kb fd array means 128 slots there
112
+ * and we are never going to be asked for 64 or less.
112
113
*/
113
- nr /= ( 1024 / sizeof ( struct file * ));
114
- nr = roundup_pow_of_two ( nr + 1 ) ;
115
- nr *= ( 1024 / sizeof ( struct file * ));
116
- nr = ALIGN ( nr , BITS_PER_LONG );
114
+ if ( IS_ENABLED ( CONFIG_32BIT ) && slots_wanted < 256 )
115
+ nr = 256 ;
116
+ else
117
+ nr = roundup_pow_of_two ( slots_wanted );
117
118
/*
118
119
* Note that this can drive nr *below* what we had passed if sysctl_nr_open
119
- * had been set lower between the check in expand_files() and here. Deal
120
- * with that in caller, it's cheaper that way.
120
+ * had been set lower between the check in expand_files() and here.
121
121
*
122
122
* We make sure that nr remains a multiple of BITS_PER_LONG - otherwise
123
123
* bitmaps handling below becomes unpleasant, to put it mildly...
124
124
*/
125
- if (unlikely (nr > sysctl_nr_open ))
126
- nr = ((sysctl_nr_open - 1 ) | (BITS_PER_LONG - 1 )) + 1 ;
125
+ if (unlikely (nr > sysctl_nr_open )) {
126
+ nr = round_down (sysctl_nr_open , BITS_PER_LONG );
127
+ if (nr < slots_wanted )
128
+ return ERR_PTR (- EMFILE );
129
+ }
127
130
128
131
fdt = kmalloc (sizeof (struct fdtable ), GFP_KERNEL_ACCOUNT );
129
132
if (!fdt )
@@ -152,7 +155,7 @@ static struct fdtable * alloc_fdtable(unsigned int nr)
152
155
out_fdt :
153
156
kfree (fdt );
154
157
out :
155
- return NULL ;
158
+ return ERR_PTR ( - ENOMEM ) ;
156
159
}
157
160
158
161
/*
@@ -169,7 +172,7 @@ static int expand_fdtable(struct files_struct *files, unsigned int nr)
169
172
struct fdtable * new_fdt , * cur_fdt ;
170
173
171
174
spin_unlock (& files -> file_lock );
172
- new_fdt = alloc_fdtable (nr );
175
+ new_fdt = alloc_fdtable (nr + 1 );
173
176
174
177
/* make sure all fd_install() have seen resize_in_progress
175
178
* or have finished their rcu_read_lock_sched() section.
@@ -178,16 +181,8 @@ static int expand_fdtable(struct files_struct *files, unsigned int nr)
178
181
synchronize_rcu ();
179
182
180
183
spin_lock (& files -> file_lock );
181
- if (!new_fdt )
182
- return - ENOMEM ;
183
- /*
184
- * extremely unlikely race - sysctl_nr_open decreased between the check in
185
- * caller and alloc_fdtable(). Cheaper to catch it here...
186
- */
187
- if (unlikely (new_fdt -> max_fds <= nr )) {
188
- __free_fdtable (new_fdt );
189
- return - EMFILE ;
190
- }
184
+ if (IS_ERR (new_fdt ))
185
+ return PTR_ERR (new_fdt );
191
186
cur_fdt = files_fdtable (files );
192
187
BUG_ON (nr < cur_fdt -> max_fds );
193
188
copy_fdtable (new_fdt , cur_fdt );
@@ -308,7 +303,6 @@ struct files_struct *dup_fd(struct files_struct *oldf, struct fd_range *punch_ho
308
303
struct file * * old_fds , * * new_fds ;
309
304
unsigned int open_files , i ;
310
305
struct fdtable * old_fdt , * new_fdt ;
311
- int error ;
312
306
313
307
newf = kmem_cache_alloc (files_cachep , GFP_KERNEL );
314
308
if (!newf )
@@ -340,17 +334,10 @@ struct files_struct *dup_fd(struct files_struct *oldf, struct fd_range *punch_ho
340
334
if (new_fdt != & newf -> fdtab )
341
335
__free_fdtable (new_fdt );
342
336
343
- new_fdt = alloc_fdtable (open_files - 1 );
344
- if (!new_fdt ) {
345
- error = - ENOMEM ;
346
- goto out_release ;
347
- }
348
-
349
- /* beyond sysctl_nr_open; nothing to do */
350
- if (unlikely (new_fdt -> max_fds < open_files )) {
351
- __free_fdtable (new_fdt );
352
- error = - EMFILE ;
353
- goto out_release ;
337
+ new_fdt = alloc_fdtable (open_files );
338
+ if (IS_ERR (new_fdt )) {
339
+ kmem_cache_free (files_cachep , newf );
340
+ return ERR_CAST (new_fdt );
354
341
}
355
342
356
343
/*
@@ -391,10 +378,6 @@ struct files_struct *dup_fd(struct files_struct *oldf, struct fd_range *punch_ho
391
378
rcu_assign_pointer (newf -> fdt , new_fdt );
392
379
393
380
return newf ;
394
-
395
- out_release :
396
- kmem_cache_free (files_cachep , newf );
397
- return ERR_PTR (error );
398
381
}
399
382
400
383
static struct fdtable * close_files (struct files_struct * files )
0 commit comments