From: Guohuai Shi <guohuai....@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....@windriver.com> Signed-off-by: Bin Meng <bin.m...@windriver.com> --- hw/9pfs/9p-util.h | 16 +++++++++++++--- hw/9pfs/9p-util-win32.c | 5 +++++ hw/9pfs/9p.c | 4 ++-- hw/9pfs/codir.c | 2 +- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/hw/9pfs/9p-util.h b/hw/9pfs/9p-util.h index c1c251fbd1..91f70a4c38 100644 --- a/hw/9pfs/9p-util.h +++ b/hw/9pfs/9p-util.h @@ -19,6 +19,10 @@ #define O_PATH_9P_UTIL 0 #endif +/* forward declaration */ +union V9fsFidOpenState; +struct V9fsState; + #if !defined(CONFIG_LINUX) /* @@ -147,6 +151,7 @@ struct dirent *readdir_win32(DIR *pDir); void rewinddir_win32(DIR *pDir); void seekdir_win32(DIR *pDir, long pos); long telldir_win32(DIR *pDir); +off_t qemu_dirent_off_win32(struct V9fsState *s, union V9fsFidOpenState *fs); #endif static inline void close_preserve_errno(int fd) @@ -220,12 +225,17 @@ 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, struct V9fsState *s, + union V9fsFidOpenState *fs) { -#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 5503199300..050c177d0c 100644 --- a/hw/9pfs/9p-util-win32.c +++ b/hw/9pfs/9p-util-win32.c @@ -1273,3 +1273,8 @@ long telldir_win32(DIR *pDir) return (long)stream->offset; } + +off_t qemu_dirent_off_win32(struct V9fsState *s, union V9fsFidOpenState *fs) +{ + return s->ops->telldir(&s->ctx, fs); +} 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 7ba63be489..6d96e2d72b 100644 --- a/hw/9pfs/codir.c +++ b/hw/9pfs/codir.c @@ -167,7 +167,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 */ -- 2.25.1