Skip to content

Commit 7a17f31

Browse files
Hobin Woonamjaejeon
Hobin Woo
authored andcommitted
ksmbd: retry iterate_dir in smb2_query_dir
Some file systems do not ensure that the single call of iterate_dir reaches the end of the directory. For example, FUSE fetches entries from a daemon using 4KB buffer and stops fetching if entries exceed the buffer. And then an actor of caller, KSMBD, is used to fill the entries from the buffer. Thus, pattern searching on FUSE, files located after the 4KB could not be found and STATUS_NO_SUCH_FILE was returned. Signed-off-by: Hobin Woo <[email protected]> Reviewed-by: Sungjong Seo <[email protected]> Reviewed-by: Namjae Jeon <[email protected]> Tested-by: Yoonho Shin <[email protected]> Signed-off-by: Namjae Jeon <[email protected]>
1 parent 2fc566b commit 7a17f31

File tree

2 files changed

+11
-0
lines changed

2 files changed

+11
-0
lines changed

smb2pdu.c

+10
Original file line numberDiff line numberDiff line change
@@ -4443,6 +4443,7 @@ static int __query_dir(struct dir_context *ctx, const char *name, int namlen,
44434443
#else
44444444
return 0;
44454445
#endif
4446+
d_info->num_scan++;
44464447
if (ksmbd_share_veto_filename(priv->work->tcon->share_conf, name))
44474448
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
44484449
return true;
@@ -4637,7 +4638,16 @@ int smb2_query_dir(struct ksmbd_work *work)
46374638
dir_fp->readdir_data.private = &query_dir_private;
46384639
set_ctx_actor(&dir_fp->readdir_data.ctx, __query_dir);
46394640

4641+
again:
46404642
rc = iterate_dir(dir_fp->filp, &dir_fp->readdir_data.ctx);
4643+
/*
4644+
* num_entry can be 0 if the directory iteration stops before reaching
4645+
* the end of the directory and no file is matched with the search
4646+
* pattern.
4647+
*/
4648+
if (rc >= 0 && !d_info.num_entry && d_info.num_scan &&
4649+
d_info.out_buf_len > 0)
4650+
goto again;
46414651
/*
46424652
* req->OutputBufferLength is too small to contain even one entry.
46434653
* In this case, it immediately returns OutputBufferLength 0 to client.

vfs.h

+1
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ struct ksmbd_dir_info {
8585
char *rptr;
8686
int name_len;
8787
int out_buf_len;
88+
int num_scan;
8889
int num_entry;
8990
int data_count;
9091
int last_entry_offset;

0 commit comments

Comments
 (0)