Skip to content

Commit c5cb4d1

Browse files
author
Ronnie Sahlberg
committed
cifs: fix skipping to incorrect offset in emit_cached_dirents
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2151418 commit 780614c 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 <lsahlber@redhat.com> Reviewed-by: Tom Talpey <tom@talpey.com> Signed-off-by: Steve French <stfrench@microsoft.com> (cherry picked from commit 780614c) Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
1 parent 4a14498 commit c5cb4d1

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)