[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: [PATCH v3 07/17] hw/9pfs: Support getting current directory offset f
From: |
Shi, Guohuai |
Subject: |
RE: [PATCH v3 07/17] hw/9pfs: Support getting current directory offset for Windows |
Date: |
Wed, 21 Dec 2022 18:02:43 +0000 |
> -----Original Message-----
> From: Christian Schoenebeck <qemu_oss@crudebyte.com>
> Sent: Wednesday, December 21, 2022 22:48
> To: Greg Kurz <groug@kaod.org>; qemu-devel@nongnu.org
> Cc: Shi, Guohuai <Guohuai.Shi@windriver.com>; Meng, Bin
> <Bin.Meng@windriver.com>
> Subject: Re: [PATCH v3 07/17] hw/9pfs: Support getting current directory
> offset for Windows
>
> CAUTION: This email comes from a non Wind River email account!
> Do not click links or open attachments unless you recognize the sender and
> know the content is safe.
>
> On Monday, December 19, 2022 11:20:11 AM CET Bin Meng wrote:
> > From: Guohuai Shi <guohuai.shi@windriver.com>
> >
> > On Windows 'struct dirent' does not have current directory offset.
> > Update qemu_dirent_off() to support Windows.
> >
> > While we are here, add a build time check to error out if a new host
> > does not implement this helper.
> >
> > Signed-off-by: Guohuai Shi <guohuai.shi@windriver.com>
> > Signed-off-by: Bin Meng <bin.meng@windriver.com>
> > ---
> >
> > (no changes since v1)
> >
> > hw/9pfs/9p-util.h | 11 ++++++++---
> > hw/9pfs/9p-util-win32.c | 7 +++++++
> > hw/9pfs/9p.c | 4 ++--
> > hw/9pfs/codir.c | 2 +-
> > 4 files changed, 18 insertions(+), 6 deletions(-)
> >
> > diff --git a/hw/9pfs/9p-util.h b/hw/9pfs/9p-util.h index
> > 90420a7578..e395936b30 100644
> > --- a/hw/9pfs/9p-util.h
> > +++ b/hw/9pfs/9p-util.h
> > @@ -127,6 +127,7 @@ int unlinkat_win32(int dirfd, const char
> > *pathname, int flags); int statfs_win32(const char *root_path, struct
> > statfs *stbuf); int openat_dir(int dirfd, const char *name); int
> > openat_file(int dirfd, const char *name, int flags, mode_t mode);
> > +off_t qemu_dirent_off_win32(void *s, void *fs);
> > #endif
> >
> > static inline void close_preserve_errno(int fd) @@ -200,12 +201,16 @@
> > ssize_t fremovexattrat_nofollow(int dirfd, const char *filename,
> > * so ensure it is manually injected earlier and call here when
> > * needed.
> > */
> > -static inline off_t qemu_dirent_off(struct dirent *dent)
> > +static inline off_t qemu_dirent_off(struct dirent *dent, void *s,
> > +void *fs)
> > {
>
> Not sure why you chose void* here.
It is "V9fsState *" here, but 9p-util.h may be included by some other source
file which is not have definition of "V9fsState".
So change it to "void *" to prevent unnecessary type declarations.
>
> > -#ifdef CONFIG_DARWIN
> > +#if defined(CONFIG_DARWIN)
> > return dent->d_seekoff;
> > -#else
> > +#elif defined(CONFIG_LINUX)
> > return dent->d_off;
> > +#elif defined(CONFIG_WIN32)
> > + return qemu_dirent_off_win32(s, fs); #else #error Missing
> > +qemu_dirent_off() implementation for this host system
> > #endif
> > }
> >
> > diff --git a/hw/9pfs/9p-util-win32.c b/hw/9pfs/9p-util-win32.c index
> > 7a270a7bd5..3592e057ce 100644
> > --- a/hw/9pfs/9p-util-win32.c
> > +++ b/hw/9pfs/9p-util-win32.c
> > @@ -929,3 +929,10 @@ int qemu_mknodat(int dirfd, const char *filename,
> mode_t mode, dev_t dev)
> > errno = ENOTSUP;
> > return -1;
> > }
> > +
> > +off_t qemu_dirent_off_win32(void *s, void *fs) {
> > + V9fsState *v9fs = s;
> > +
> > + return v9fs->ops->telldir(&v9fs->ctx, (V9fsFidOpenState *)fs); }
>
> That's a bit tricky. So far (i.e. for Linux host, macOS host) we are storing
> the directory offset directly to the dirent struct. We are not using
> telldir() as the stream might have mutated in the meantime, hence calling
> telldir() might return a value that does no longer correlate to dirent in
> question.
>
> Hence my idea was to use the same hack for Windows as we did for macOS, where
> we simply misuse a dirent field known to be not used, on macOS that's
> d_seekoff which we are misusing for that purpose.
>
> Looking at the mingw dirent.h header though, there is not much we can choose
> from. d_reclen is not used, but too short, d_ino is not used by mingw, but
> currently we actually read this field in server common code to assemble a
> file ID for guest. I mean it is always zero on Windows, so we could still
> misuse it, but we would need to inject more hacks there. :/
If you check seekdir and telldir() implement in MinGW,
you can see that MinGW (and Windows) does not have a safety way to seek/tell
directory offset.
Because Windows POSIX and native API does not provide a way to seek directory.
Windows native API only allow to read directory forward, but not backward.
So even we store the d_seekoff to some places, the directory may still be
modified.
And Windows file system actually has inode number, MinGW does not introduce it
to MinGW API.
So I think it is not good way to use d_ino.
Thanks
Guohuai
>
> > diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index 072cf67956..be247eeb30
> > 100644
> > --- a/hw/9pfs/9p.c
> > +++ b/hw/9pfs/9p.c
> > @@ -2336,7 +2336,7 @@ static int coroutine_fn
> v9fs_do_readdir_with_stat(V9fsPDU *pdu,
> > count += len;
> > v9fs_stat_free(&v9stat);
> > v9fs_path_free(&path);
> > - saved_dir_pos = qemu_dirent_off(dent);
> > + saved_dir_pos = qemu_dirent_off(dent, pdu->s, &fidp->fs);
> > }
> >
> > v9fs_readdir_unlock(&fidp->fs.dir);
> > @@ -2537,7 +2537,7 @@ static int coroutine_fn v9fs_do_readdir(V9fsPDU *pdu,
> V9fsFidState *fidp,
> > qid.version = 0;
> > }
> >
> > - off = qemu_dirent_off(dent);
> > + off = qemu_dirent_off(dent, pdu->s, &fidp->fs);
> > 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..d40515a607 100644
> > --- a/hw/9pfs/codir.c
> > +++ b/hw/9pfs/codir.c
> > @@ -168,7 +168,7 @@ static int do_readdir_many(V9fsPDU *pdu, V9fsFidState
> *fidp,
> > }
> >
> > size += len;
> > - saved_dir_pos = qemu_dirent_off(dent);
> > + saved_dir_pos = qemu_dirent_off(dent, s, &fidp->fs);
> > }
> >
> > /* restore (last) saved position */
> >
>
>
- [PATCH v3 00/17] hw/9pfs: Add 9pfs support for Windows, Bin Meng, 2022/12/19
- [PATCH v3 02/17] hw/9pfs: Drop unnecessary *xattr wrapper API declarations, Bin Meng, 2022/12/19
- [PATCH v3 08/17] hw/9pfs: update helper qemu_stat_rdev(), Bin Meng, 2022/12/19
- [PATCH v3 16/17] tests/qtest: virtio-9p-test: Adapt the case for win32, Bin Meng, 2022/12/19
- [PATCH v3 15/17] hw/9pfs: Update synth fs driver for Windows, Bin Meng, 2022/12/19
- [PATCH v3 05/17] hw/9pfs: Implement Windows specific utilities functions for 9pfs, Bin Meng, 2022/12/19
- [PATCH v3 04/17] hw/9pfs: Add missing definitions for Windows, Bin Meng, 2022/12/19
- [PATCH v3 07/17] hw/9pfs: Support getting current directory offset for Windows, Bin Meng, 2022/12/19
[PATCH v3 06/17] hw/9pfs: Update the local fs driver to support Windows, Bin Meng, 2022/12/19
[PATCH v3 09/17] hw/9pfs: Add a helper qemu_stat_blksize(), Bin Meng, 2022/12/19
[PATCH v3 17/17] meson.build: Turn on virtfs for Windows, Bin Meng, 2022/12/19
[PATCH v3 01/17] qemu/xattr.h: Exclude <sys/xattr.h> for Windows, Bin Meng, 2022/12/19
[PATCH v3 10/17] hw/9pfs: Disable unsupported flags and features for Windows, Bin Meng, 2022/12/19
[PATCH v3 11/17] hw/9pfs: Update v9fs_set_fd_limit() for Windows, Bin Meng, 2022/12/19
[PATCH v3 13/17] hw/9pfs: Translate Windows errno to Linux value, Bin Meng, 2022/12/19