On Monday, October 24, 2022 6:57:51 AM CET Bin Meng wrote: > From: Guohuai Shi <guohuai....@windriver.com> > > On Windows 'struct dirent' does not have current directory offset. > We have to save current directory offset and update offset when > reading directory. > > Signed-off-by: Guohuai Shi <guohuai....@windriver.com> > Signed-off-by: Bin Meng <bin.m...@windriver.com> > --- > > hw/9pfs/9p.c | 16 ++++++++++++++++ > hw/9pfs/codir.c | 15 +++++++++++++++ > 2 files changed, 31 insertions(+) > > diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c > index aebadeaa03..6c4af86240 100644 > --- a/hw/9pfs/9p.c > +++ b/hw/9pfs/9p.c > @@ -2319,7 +2319,15 @@ static int coroutine_fn > v9fs_do_readdir_with_stat(V9fsPDU *pdu, > count += len; > v9fs_stat_free(&v9stat); > v9fs_path_free(&path); > +#ifndef CONFIG_WIN32 > saved_dir_pos = qemu_dirent_off(dent); > +#else > + /* > + * Get offset by calling telldir() manually, > + * as Windows does not have dent->d_off. > + */ > + saved_dir_pos = v9fs_co_telldir(pdu, fidp); > +#endif > }
That's not the way to go. We already had the same discussion with the macOS patches and why we introduced qemu_dirent_off() for exactly that purpose: v9fs_co_telldir() would dispatch the coroutine from QEMU main thread to background worker thread and vice versa. So you would get side effects by doing this. Please implement this adequately in qemu_dirent_off() instead of touching the controller portion here. > > v9fs_readdir_unlock(&fidp->fs.dir); > @@ -2520,7 +2528,15 @@ static int coroutine_fn v9fs_do_readdir(V9fsPDU *pdu, > V9fsFidState *fidp, > qid.version = 0; > } > > +#ifndef CONFIG_WIN32 > off = qemu_dirent_off(dent); > +#else > + /* > + * Get offset by calling telldir() manually, > + * as Windows does not have dent->d_off. > + */ > + off = v9fs_co_telldir(pdu, fidp); > +#endif > v9fs_string_init(&name); > v9fs_string_sprintf(&name, "%s", dent->d_name); > > diff --git a/hw/9pfs/codir.c b/hw/9pfs/codir.c > index 93ba44fb75..2fbe7b831b 100644 > --- a/hw/9pfs/codir.c > +++ b/hw/9pfs/codir.c > @@ -78,6 +78,9 @@ static int do_readdir_many(V9fsPDU *pdu, V9fsFidState *fidp, > int len, err = 0; > int32_t size = 0; > off_t saved_dir_pos; > +#ifdef CONFIG_WIN32 > + off_t next_dir_pos; > +#endif > struct dirent *dent; > struct V9fsDirEnt *e = NULL; > V9fsPath path; > @@ -124,6 +127,14 @@ static int do_readdir_many(V9fsPDU *pdu, V9fsFidState > *fidp, > break; > } > > +#ifdef CONFIG_WIN32 > + next_dir_pos = s->ops->telldir(&s->ctx, &fidp->fs); > + if (next_dir_pos < 0) { > + err = next_dir_pos; > + goto out; > + } > +#endif > + > /* > * stop this loop as soon as it would exceed the allowed maximum > * response message size for the directory entries collected so far, > @@ -168,7 +179,11 @@ static int do_readdir_many(V9fsPDU *pdu, V9fsFidState > *fidp, > } > > size += len; > +#ifndef CONFIG_WIN32 > saved_dir_pos = qemu_dirent_off(dent); > +#else > + saved_dir_pos = next_dir_pos; > +#endif > } > > /* restore (last) saved position */ >