@@ -399,6 +399,8 @@ static loff_t offset_dir_llseek(struct file *file, loff_t offset, int whence)
399
399
return - EINVAL ;
400
400
}
401
401
402
+ /* In this case, ->private_data is protected by f_pos_lock */
403
+ file -> private_data = NULL ;
402
404
return vfs_setpos (file , offset , U32_MAX );
403
405
}
404
406
@@ -428,7 +430,7 @@ static bool offset_dir_emit(struct dir_context *ctx, struct dentry *dentry)
428
430
inode -> i_ino , fs_umode_to_dtype (inode -> i_mode ));
429
431
}
430
432
431
- static void offset_iterate_dir (struct inode * inode , struct dir_context * ctx )
433
+ static void * offset_iterate_dir (struct inode * inode , struct dir_context * ctx )
432
434
{
433
435
struct offset_ctx * so_ctx = inode -> i_op -> get_offset_ctx (inode );
434
436
XA_STATE (xas , & so_ctx -> xa , ctx -> pos );
@@ -437,7 +439,7 @@ static void offset_iterate_dir(struct inode *inode, struct dir_context *ctx)
437
439
while (true) {
438
440
dentry = offset_find_next (& xas );
439
441
if (!dentry )
440
- break ;
442
+ return ERR_PTR ( - ENOENT ) ;
441
443
442
444
if (!offset_dir_emit (ctx , dentry )) {
443
445
dput (dentry );
@@ -447,6 +449,7 @@ static void offset_iterate_dir(struct inode *inode, struct dir_context *ctx)
447
449
dput (dentry );
448
450
ctx -> pos = xas .xa_index + 1 ;
449
451
}
452
+ return NULL ;
450
453
}
451
454
452
455
/**
@@ -479,7 +482,12 @@ static int offset_readdir(struct file *file, struct dir_context *ctx)
479
482
if (!dir_emit_dots (file , ctx ))
480
483
return 0 ;
481
484
482
- offset_iterate_dir (d_inode (dir ), ctx );
485
+ /* In this case, ->private_data is protected by f_pos_lock */
486
+ if (ctx -> pos == 2 )
487
+ file -> private_data = NULL ;
488
+ else if (file -> private_data == ERR_PTR (- ENOENT ))
489
+ return 0 ;
490
+ file -> private_data = offset_iterate_dir (d_inode (dir ), ctx );
483
491
return 0 ;
484
492
}
485
493
0 commit comments