Skip to content

Commit 780614c

Browse files
Ronnie Sahlbergsmfrench
authored andcommitted
cifs: fix skipping to incorrect offset in emit_cached_dirents
When application has done lseek() to a different offset on a directory fd we skipped one entry too many before we start emitting directory entries from the cache. We need to also make sure that when we are starting to emit directory entries from the cache, the ->pos sequence might have holes and skip some indices. Signed-off-by: Ronnie Sahlberg <[email protected]> Reviewed-by: Tom Talpey <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent ac1e8c6 commit 780614c

File tree

1 file changed

+23
-6
lines changed

1 file changed

+23
-6
lines changed

fs/cifs/readdir.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -844,17 +844,34 @@ static bool emit_cached_dirents(struct cached_dirents *cde,
844844
struct dir_context *ctx)
845845
{
846846
struct cached_dirent *dirent;
847-
int rc;
847+
bool rc;
848848

849849
list_for_each_entry(dirent, &cde->entries, entry) {
850-
if (ctx->pos >= dirent->pos)
850+
/*
851+
* Skip all early entries prior to the current lseek()
852+
* position.
853+
*/
854+
if (ctx->pos > dirent->pos)
851855
continue;
856+
/*
857+
* We recorded the current ->pos value for the dirent
858+
* when we stored it in the cache.
859+
* However, this sequence of ->pos values may have holes
860+
* in it, for example dot-dirs returned from the server
861+
* are suppressed.
862+
* Handle this bu forcing ctx->pos to be the same as the
863+
* ->pos of the current dirent we emit from the cache.
864+
* This means that when we emit these entries from the cache
865+
* we now emit them with the same ->pos value as in the
866+
* initial scan.
867+
*/
852868
ctx->pos = dirent->pos;
853869
rc = dir_emit(ctx, dirent->name, dirent->namelen,
854870
dirent->fattr.cf_uniqueid,
855871
dirent->fattr.cf_dtype);
856872
if (!rc)
857873
return rc;
874+
ctx->pos++;
858875
}
859876
return true;
860877
}
@@ -1202,10 +1219,10 @@ int cifs_readdir(struct file *file, struct dir_context *ctx)
12021219
ctx->pos, tmp_buf);
12031220
cifs_save_resume_key(current_entry, cifsFile);
12041221
break;
1205-
} else
1206-
current_entry =
1207-
nxt_dir_entry(current_entry, end_of_smb,
1208-
cifsFile->srch_inf.info_level);
1222+
}
1223+
current_entry =
1224+
nxt_dir_entry(current_entry, end_of_smb,
1225+
cifsFile->srch_inf.info_level);
12091226
}
12101227
kfree(tmp_buf);
12111228

0 commit comments

Comments
 (0)