@@ -204,21 +204,16 @@ const struct dentry_operations exfat_utf8_dentry_ops = {
204
204
.d_compare = exfat_utf8_d_cmp ,
205
205
};
206
206
207
- /* used only in search empty_slot() */
208
- #define CNT_UNUSED_NOHIT (-1)
209
- #define CNT_UNUSED_HIT (-2)
210
207
/* search EMPTY CONTINUOUS "num_entries" entries */
211
208
static int exfat_search_empty_slot (struct super_block * sb ,
212
209
struct exfat_hint_femp * hint_femp , struct exfat_chain * p_dir ,
213
- int num_entries )
210
+ int num_entries , struct exfat_entry_set_cache * es )
214
211
{
215
- int i , dentry , num_empty = 0 ;
212
+ int i , dentry , ret ;
216
213
int dentries_per_clu ;
217
- unsigned int type ;
218
214
struct exfat_chain clu ;
219
- struct exfat_dentry * ep ;
220
215
struct exfat_sb_info * sbi = EXFAT_SB (sb );
221
- struct buffer_head * bh ;
216
+ int total_entries = EXFAT_CLU_TO_DEN ( p_dir -> size , sbi ) ;
222
217
223
218
dentries_per_clu = sbi -> dentries_per_clu ;
224
219
@@ -231,7 +226,7 @@ static int exfat_search_empty_slot(struct super_block *sb,
231
226
* Otherwise, and if "dentry + hint_famp->count" is also equal
232
227
* to "p_dir->size * dentries_per_clu", it means ENOSPC.
233
228
*/
234
- if (dentry + hint_femp -> count == p_dir -> size * dentries_per_clu &&
229
+ if (dentry + hint_femp -> count == total_entries &&
235
230
num_entries > hint_femp -> count )
236
231
return - ENOSPC ;
237
232
@@ -242,69 +237,41 @@ static int exfat_search_empty_slot(struct super_block *sb,
242
237
dentry = 0 ;
243
238
}
244
239
245
- while (clu .dir != EXFAT_EOF_CLUSTER ) {
240
+ while (dentry + num_entries < total_entries &&
241
+ clu .dir != EXFAT_EOF_CLUSTER ) {
246
242
i = dentry & (dentries_per_clu - 1 );
247
243
248
- for (; i < dentries_per_clu ; i ++ , dentry ++ ) {
249
- ep = exfat_get_dentry (sb , & clu , i , & bh );
250
- if (!ep )
251
- return - EIO ;
252
- type = exfat_get_entry_type (ep );
253
- brelse (bh );
254
-
255
- if (type == TYPE_UNUSED || type == TYPE_DELETED ) {
256
- num_empty ++ ;
257
- if (hint_femp -> eidx == EXFAT_HINT_NONE ) {
258
- hint_femp -> eidx = dentry ;
259
- hint_femp -> count = CNT_UNUSED_NOHIT ;
260
- exfat_chain_set (& hint_femp -> cur ,
261
- clu .dir , clu .size , clu .flags );
262
- }
263
-
264
- if (type == TYPE_UNUSED &&
265
- hint_femp -> count != CNT_UNUSED_HIT )
266
- hint_femp -> count = CNT_UNUSED_HIT ;
244
+ ret = exfat_get_empty_dentry_set (es , sb , & clu , i , num_entries );
245
+ if (ret < 0 )
246
+ return ret ;
247
+ else if (ret == 0 )
248
+ return dentry ;
249
+
250
+ dentry += ret ;
251
+ i += ret ;
252
+
253
+ while (i >= dentries_per_clu ) {
254
+ if (clu .flags == ALLOC_NO_FAT_CHAIN ) {
255
+ if (-- clu .size > 0 )
256
+ clu .dir ++ ;
257
+ else
258
+ clu .dir = EXFAT_EOF_CLUSTER ;
267
259
} else {
268
- if (hint_femp -> eidx != EXFAT_HINT_NONE &&
269
- hint_femp -> count == CNT_UNUSED_HIT ) {
270
- /* unused empty group means
271
- * an empty group which includes
272
- * unused dentry
273
- */
274
- exfat_fs_error (sb ,
275
- "found bogus dentry(%d) beyond unused empty group(%d) (start_clu : %u, cur_clu : %u)" ,
276
- dentry , hint_femp -> eidx ,
277
- p_dir -> dir , clu .dir );
260
+ if (exfat_get_next_cluster (sb , & clu .dir ))
278
261
return - EIO ;
279
- }
280
-
281
- num_empty = 0 ;
282
- hint_femp -> eidx = EXFAT_HINT_NONE ;
283
262
}
284
263
285
- if (num_empty >= num_entries ) {
286
- /* found and invalidate hint_femp */
287
- hint_femp -> eidx = EXFAT_HINT_NONE ;
288
- return (dentry - (num_entries - 1 ));
289
- }
290
- }
291
-
292
- if (clu .flags == ALLOC_NO_FAT_CHAIN ) {
293
- if (-- clu .size > 0 )
294
- clu .dir ++ ;
295
- else
296
- clu .dir = EXFAT_EOF_CLUSTER ;
297
- } else {
298
- if (exfat_get_next_cluster (sb , & clu .dir ))
299
- return - EIO ;
264
+ i -= dentries_per_clu ;
300
265
}
301
266
}
302
267
303
- hint_femp -> eidx = p_dir -> size * dentries_per_clu - num_empty ;
304
- hint_femp -> count = num_empty ;
305
- if (num_empty == 0 )
268
+ hint_femp -> eidx = dentry ;
269
+ hint_femp -> count = 0 ;
270
+ if (dentry == total_entries || clu . dir == EXFAT_EOF_CLUSTER )
306
271
exfat_chain_set (& hint_femp -> cur , EXFAT_EOF_CLUSTER , 0 ,
307
272
clu .flags );
273
+ else
274
+ hint_femp -> cur = clu ;
308
275
309
276
return - ENOSPC ;
310
277
}
@@ -325,7 +292,8 @@ static int exfat_check_max_dentries(struct inode *inode)
325
292
* if there isn't any empty slot, expand cluster chain.
326
293
*/
327
294
static int exfat_find_empty_entry (struct inode * inode ,
328
- struct exfat_chain * p_dir , int num_entries )
295
+ struct exfat_chain * p_dir , int num_entries ,
296
+ struct exfat_entry_set_cache * es )
329
297
{
330
298
int dentry ;
331
299
unsigned int ret , last_clu ;
@@ -344,7 +312,7 @@ static int exfat_find_empty_entry(struct inode *inode,
344
312
}
345
313
346
314
while ((dentry = exfat_search_empty_slot (sb , & hint_femp , p_dir ,
347
- num_entries )) < 0 ) {
315
+ num_entries , es )) < 0 ) {
348
316
if (dentry == - EIO )
349
317
break ;
350
318
@@ -515,16 +483,18 @@ static int exfat_add_entry(struct inode *inode, const char *path,
515
483
}
516
484
517
485
/* exfat_find_empty_entry must be called before alloc_cluster() */
518
- dentry = exfat_find_empty_entry (inode , p_dir , num_entries );
486
+ dentry = exfat_find_empty_entry (inode , p_dir , num_entries , & es );
519
487
if (dentry < 0 ) {
520
488
ret = dentry ; /* -EIO or -ENOSPC */
521
489
goto out ;
522
490
}
523
491
524
492
if (type == TYPE_DIR && !sbi -> options .zero_size_dir ) {
525
493
ret = exfat_alloc_new_dir (inode , & clu );
526
- if (ret )
494
+ if (ret ) {
495
+ exfat_put_dentry_set (& es , false);
527
496
goto out ;
497
+ }
528
498
start_clu = clu .dir ;
529
499
clu_size = sbi -> cluster_size ;
530
500
}
@@ -533,11 +503,6 @@ static int exfat_add_entry(struct inode *inode, const char *path,
533
503
/* fill the dos name directory entry information of the created file.
534
504
* the first cluster is not determined yet. (0)
535
505
*/
536
-
537
- ret = exfat_get_empty_dentry_set (& es , sb , p_dir , dentry , num_entries );
538
- if (ret )
539
- goto out ;
540
-
541
506
exfat_init_dir_entry (& es , type , start_clu , clu_size , & ts );
542
507
exfat_init_ext_entry (& es , num_entries , & uniname );
543
508
@@ -1033,18 +998,13 @@ static int exfat_rename_file(struct inode *inode, struct exfat_chain *p_dir,
1033
998
if (old_es .num_entries < num_new_entries ) {
1034
999
int newentry ;
1035
1000
1036
- newentry =
1037
- exfat_find_empty_entry ( inode , p_dir , num_new_entries );
1001
+ newentry = exfat_find_empty_entry ( inode , p_dir , num_new_entries ,
1002
+ & new_es );
1038
1003
if (newentry < 0 ) {
1039
1004
ret = newentry ; /* -EIO or -ENOSPC */
1040
1005
goto put_old_es ;
1041
1006
}
1042
1007
1043
- ret = exfat_get_empty_dentry_set (& new_es , sb , p_dir , newentry ,
1044
- num_new_entries );
1045
- if (ret )
1046
- goto put_old_es ;
1047
-
1048
1008
epnew = exfat_get_dentry_cached (& new_es , ES_IDX_FILE );
1049
1009
* epnew = * epold ;
1050
1010
if (exfat_get_entry_type (epnew ) == TYPE_FILE ) {
@@ -1094,19 +1054,17 @@ static int exfat_move_file(struct inode *inode, struct exfat_chain *p_olddir,
1094
1054
if (num_new_entries < 0 )
1095
1055
return num_new_entries ;
1096
1056
1097
- newentry = exfat_find_empty_entry (inode , p_newdir , num_new_entries );
1098
- if (newentry < 0 )
1099
- return newentry ; /* -EIO or -ENOSPC */
1100
-
1101
1057
ret = exfat_get_dentry_set (& mov_es , sb , p_olddir , oldentry ,
1102
1058
ES_ALL_ENTRIES );
1103
1059
if (ret )
1104
1060
return - EIO ;
1105
1061
1106
- ret = exfat_get_empty_dentry_set (& new_es , sb , p_newdir , newentry ,
1107
- num_new_entries );
1108
- if (ret )
1062
+ newentry = exfat_find_empty_entry (inode , p_newdir , num_new_entries ,
1063
+ & new_es );
1064
+ if (newentry < 0 ) {
1065
+ ret = newentry ; /* -EIO or -ENOSPC */
1109
1066
goto put_mov_es ;
1067
+ }
1110
1068
1111
1069
epmov = exfat_get_dentry_cached (& mov_es , ES_IDX_FILE );
1112
1070
epnew = exfat_get_dentry_cached (& new_es , ES_IDX_FILE );
0 commit comments