@@ -272,9 +272,12 @@ struct inode *dir_search_u(struct inode *dir, const struct cpu_str *uni,
272
272
return err == - ENOENT ? NULL : err ? ERR_PTR (err ) : inode ;
273
273
}
274
274
275
- static inline int ntfs_filldir (struct ntfs_sb_info * sbi , struct ntfs_inode * ni ,
276
- const struct NTFS_DE * e , u8 * name ,
277
- struct dir_context * ctx )
275
+ /*
276
+ * returns false if 'ctx' if full
277
+ */
278
+ static inline bool ntfs_dir_emit (struct ntfs_sb_info * sbi ,
279
+ struct ntfs_inode * ni , const struct NTFS_DE * e ,
280
+ u8 * name , struct dir_context * ctx )
278
281
{
279
282
const struct ATTR_FILE_NAME * fname ;
280
283
unsigned long ino ;
@@ -284,29 +287,29 @@ static inline int ntfs_filldir(struct ntfs_sb_info *sbi, struct ntfs_inode *ni,
284
287
fname = Add2Ptr (e , sizeof (struct NTFS_DE ));
285
288
286
289
if (fname -> type == FILE_NAME_DOS )
287
- return 0 ;
290
+ return true ;
288
291
289
292
if (!mi_is_ref (& ni -> mi , & fname -> home ))
290
- return 0 ;
293
+ return true ;
291
294
292
295
ino = ino_get (& e -> ref );
293
296
294
297
if (ino == MFT_REC_ROOT )
295
- return 0 ;
298
+ return true ;
296
299
297
300
/* Skip meta files. Unless option to show metafiles is set. */
298
301
if (!sbi -> options -> showmeta && ntfs_is_meta_file (sbi , ino ))
299
- return 0 ;
302
+ return true ;
300
303
301
304
if (sbi -> options -> nohidden && (fname -> dup .fa & FILE_ATTRIBUTE_HIDDEN ))
302
- return 0 ;
305
+ return true ;
303
306
304
307
name_len = ntfs_utf16_to_nls (sbi , fname -> name , fname -> name_len , name ,
305
308
PATH_MAX );
306
309
if (name_len <= 0 ) {
307
310
ntfs_warn (sbi -> sb , "failed to convert name for inode %lx." ,
308
311
ino );
309
- return 0 ;
312
+ return true ;
310
313
}
311
314
312
315
/*
@@ -336,30 +339,33 @@ static inline int ntfs_filldir(struct ntfs_sb_info *sbi, struct ntfs_inode *ni,
336
339
}
337
340
}
338
341
339
- return ! dir_emit (ctx , (s8 * )name , name_len , ino , dt_type );
342
+ return dir_emit (ctx , (s8 * )name , name_len , ino , dt_type );
340
343
}
341
344
342
345
/*
343
346
* ntfs_read_hdr - Helper function for ntfs_readdir().
347
+ *
348
+ * returns 0 if ok.
349
+ * returns -EINVAL if directory is corrupted.
350
+ * returns +1 if 'ctx' is full.
344
351
*/
345
352
static int ntfs_read_hdr (struct ntfs_sb_info * sbi , struct ntfs_inode * ni ,
346
353
const struct INDEX_HDR * hdr , u64 vbo , u64 pos ,
347
354
u8 * name , struct dir_context * ctx )
348
355
{
349
- int err ;
350
356
const struct NTFS_DE * e ;
351
357
u32 e_size ;
352
358
u32 end = le32_to_cpu (hdr -> used );
353
359
u32 off = le32_to_cpu (hdr -> de_off );
354
360
355
361
for (;; off += e_size ) {
356
362
if (off + sizeof (struct NTFS_DE ) > end )
357
- return -1 ;
363
+ return - EINVAL ;
358
364
359
365
e = Add2Ptr (hdr , off );
360
366
e_size = le16_to_cpu (e -> size );
361
367
if (e_size < sizeof (struct NTFS_DE ) || off + e_size > end )
362
- return -1 ;
368
+ return - EINVAL ;
363
369
364
370
if (de_is_last (e ))
365
371
return 0 ;
@@ -369,14 +375,15 @@ static int ntfs_read_hdr(struct ntfs_sb_info *sbi, struct ntfs_inode *ni,
369
375
continue ;
370
376
371
377
if (le16_to_cpu (e -> key_size ) < SIZEOF_ATTRIBUTE_FILENAME )
372
- return -1 ;
378
+ return - EINVAL ;
373
379
374
380
ctx -> pos = vbo + off ;
375
381
376
382
/* Submit the name to the filldir callback. */
377
- err = ntfs_filldir (sbi , ni , e , name , ctx );
378
- if (err )
379
- return err ;
383
+ if (!ntfs_dir_emit (sbi , ni , e , name , ctx )) {
384
+ /* ctx is full. */
385
+ return +1 ;
386
+ }
380
387
}
381
388
}
382
389
@@ -475,8 +482,6 @@ static int ntfs_readdir(struct file *file, struct dir_context *ctx)
475
482
476
483
vbo = (u64 )bit << index_bits ;
477
484
if (vbo >= i_size ) {
478
- ntfs_inode_err (dir , "Looks like your dir is corrupt" );
479
- ctx -> pos = eod ;
480
485
err = - EINVAL ;
481
486
goto out ;
482
487
}
@@ -499,9 +504,16 @@ static int ntfs_readdir(struct file *file, struct dir_context *ctx)
499
504
__putname (name );
500
505
put_indx_node (node );
501
506
502
- if (err == - ENOENT ) {
507
+ if (err == 1 ) {
508
+ /* 'ctx' is full. */
509
+ err = 0 ;
510
+ } else if (err == - ENOENT ) {
503
511
err = 0 ;
504
512
ctx -> pos = pos ;
513
+ } else if (err < 0 ) {
514
+ if (err == - EINVAL )
515
+ ntfs_inode_err (dir , "directory corrupted" );
516
+ ctx -> pos = eod ;
505
517
}
506
518
507
519
return err ;
0 commit comments