> -----Original Message-----
> From: Christian Schoenebeck <qemu_...@crudebyte.com>
> Sent: Tuesday, November 1, 2022 23:04
> To: qemu-devel@nongnu.org
> Cc: Shi, Guohuai <guohuai....@windriver.com>; Greg Kurz <gr...@kaod.org>;
> Meng, Bin <bin.m...@windriver.com>
> Subject: Re: [PATCH 09/16] hw/9pfs: Disable unsupported flags and features
> for Windows
> 
> [Please note: This e-mail is from an EXTERNAL e-mail address]
> 
> On Monday, October 24, 2022 6:57:52 AM CET Bin Meng wrote:
> > From: Guohuai Shi <guohuai....@windriver.com>
> >
> > Some flags and features are not supported on Windows, like mknod,
> > readlink, file mode, etc. Update the codes for Windows.
> >
> > Signed-off-by: Guohuai Shi <guohuai....@windriver.com>
> > Signed-off-by: Bin Meng <bin.m...@windriver.com>
> > ---
> >
> >  hw/9pfs/9p-util.h |  6 +++-
> >  hw/9pfs/9p.c      | 90 ++++++++++++++++++++++++++++++++++++++++++-----
> >  2 files changed, 86 insertions(+), 10 deletions(-)
> >
> > diff --git a/hw/9pfs/9p-util.h b/hw/9pfs/9p-util.h index
> > 82b2d0c3e4..3d154e9103 100644
> > --- a/hw/9pfs/9p-util.h
> > +++ b/hw/9pfs/9p-util.h
> > @@ -53,8 +53,10 @@ static inline uint64_t makedev_dotl(uint32_t dev_major,
> uint32_t dev_minor)
> >   */
> >  static inline uint64_t host_dev_to_dotl_dev(dev_t dev)  { -#ifdef
> > CONFIG_LINUX
> > +#if defined(CONFIG_LINUX)
> >      return dev;
> > +#elif defined(CONFIG_WIN32)
> > +    return 0;
> 
> Really?

Check MS this document: 
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/fstat-fstat32-fstat64-fstati64-fstat32i64-fstat64i32?view=msvc-170
st_rdev: If a device, fd; otherwise 0.
st_dev: If a device, fd; otherwise 0.

So for any file open, it should be 0.

> 
> >  #else
> >      return makedev_dotl(major(dev), minor(dev));  #endif @@ -260,7
> > +262,9 @@ static inline struct dirent *qemu_dirent_dup(struct dirent
> > *dent)  #if defined CONFIG_DARWIN && defined CONFIG_PTHREAD_FCHDIR_NP
> > int pthread_fchdir_np(int fd) __attribute__((weak_import));  #endif
> > +#ifndef CONFIG_WIN32
> >  int qemu_mknodat(P9_FILE_ID dirfd, const char *filename, mode_t mode,
> >                   dev_t dev);
> > +#endif
> >
> >  #endif
> > diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index 6c4af86240..771aab34ac
> > 100644
> > --- a/hw/9pfs/9p.c
> > +++ b/hw/9pfs/9p.c
> > @@ -39,6 +39,11 @@
> >  #include "qemu/xxhash.h"
> >  #include <math.h>
> >
> > +#ifdef CONFIG_WIN32
> > +#define UTIME_NOW   ((1l << 30) - 1l)
> > +#define UTIME_OMIT  ((1l << 30) - 2l) #endif
> > +
> >  int open_fd_hw;
> >  int total_open_fd;
> >  static int open_fd_rc;
> > @@ -132,13 +137,17 @@ static int dotl_to_open_flags(int flags)
> >      DotlOpenflagMap dotl_oflag_map[] = {
> >          { P9_DOTL_CREATE, O_CREAT },
> >          { P9_DOTL_EXCL, O_EXCL },
> > +#ifndef CONFIG_WIN32
> >          { P9_DOTL_NOCTTY , O_NOCTTY },
> > +#endif
> >          { P9_DOTL_TRUNC, O_TRUNC },
> >          { P9_DOTL_APPEND, O_APPEND },
> > +#ifndef CONFIG_WIN32
> >          { P9_DOTL_NONBLOCK, O_NONBLOCK } ,
> >          { P9_DOTL_DSYNC, O_DSYNC },
> >          { P9_DOTL_FASYNC, FASYNC },
> > -#ifndef CONFIG_DARWIN
> > +#endif
> > +#ifdef CONFIG_LINUX
> 
> Better
> 
>    #if !defined(CONFIG_DARWIN) && !defined(CONFIG_WIN32)
> 

It is OK.

> Otherwise it might automatically opt-out other future platforms
> unintentionally.
> 
> >          { P9_DOTL_NOATIME, O_NOATIME },
> >          /*
> >           *  On Darwin, we could map to F_NOCACHE, which is @@ -151,8
> > +160,10 @@ static int dotl_to_open_flags(int flags)  #endif
> >          { P9_DOTL_LARGEFILE, O_LARGEFILE },
> >          { P9_DOTL_DIRECTORY, O_DIRECTORY },
> > +#ifndef CONFIG_WIN32
> >          { P9_DOTL_NOFOLLOW, O_NOFOLLOW },
> >          { P9_DOTL_SYNC, O_SYNC },
> > +#endif
> >      };
> >
> >      for (i = 0; i < ARRAY_SIZE(dotl_oflag_map); i++) { @@ -179,8
> > +190,11 @@ static int get_dotl_openflags(V9fsState *s, int oflags)
> >       * Filter the client open flags
> >       */
> >      flags = dotl_to_open_flags(oflags);
> > -    flags &= ~(O_NOCTTY | O_ASYNC | O_CREAT);
> > -#ifndef CONFIG_DARWIN
> > +    flags &= ~(O_CREAT);
> > +#ifndef CONFIG_WIN32
> > +    flags &= ~(O_NOCTTY | O_ASYNC);
> > +#endif
> > +#ifdef CONFIG_LINUX
> 
> Same as above: better explicitly opt-out than the other way around.
> 

It is OK.

> >      /*
> >       * Ignore direct disk access hint until the server supports it.
> >       */
> > @@ -986,9 +1000,11 @@ static int stat_to_qid(V9fsPDU *pdu, const struct
> stat *stbuf, V9fsQID *qidp)
> >      if (S_ISDIR(stbuf->st_mode)) {
> >          qidp->type |= P9_QID_TYPE_DIR;
> >      }
> > +#ifndef CONFIG_WIN32
> >      if (S_ISLNK(stbuf->st_mode)) {
> >          qidp->type |= P9_QID_TYPE_SYMLINK;
> >      }
> > +#endif
> >
> >      return 0;
> >  }
> > @@ -1097,6 +1113,7 @@ static mode_t v9mode_to_mode(uint32_t mode,
> V9fsString *extension)
> >          ret |= S_IFDIR;
> >      }
> >
> > +#ifndef CONFIG_WIN32
> >      if (mode & P9_STAT_MODE_SYMLINK) {
> >          ret |= S_IFLNK;
> >      }
> > @@ -1106,6 +1123,7 @@ static mode_t v9mode_to_mode(uint32_t mode,
> V9fsString *extension)
> >      if (mode & P9_STAT_MODE_NAMED_PIPE) {
> >          ret |= S_IFIFO;
> >      }
> > +#endif
> >      if (mode & P9_STAT_MODE_DEVICE) {
> >          if (extension->size && extension->data[0] == 'c') {
> >              ret |= S_IFCHR;
> > @@ -1118,6 +1136,7 @@ static mode_t v9mode_to_mode(uint32_t mode,
> V9fsString *extension)
> >          ret |= S_IFREG;
> >      }
> >
> > +#ifndef CONFIG_WIN32
> >      if (mode & P9_STAT_MODE_SETUID) {
> >          ret |= S_ISUID;
> >      }
> > @@ -1127,6 +1146,7 @@ static mode_t v9mode_to_mode(uint32_t mode,
> V9fsString *extension)
> >      if (mode & P9_STAT_MODE_SETVTX) {
> >          ret |= S_ISVTX;
> >      }
> > +#endif
> >
> >      return ret;
> >  }
> > @@ -1182,6 +1202,7 @@ static uint32_t stat_to_v9mode(const struct stat
> *stbuf)
> >          mode |= P9_STAT_MODE_DIR;
> >      }
> >
> > +#ifndef CONFIG_WIN32
> >      if (S_ISLNK(stbuf->st_mode)) {
> >          mode |= P9_STAT_MODE_SYMLINK;
> >      }
> > @@ -1193,11 +1214,13 @@ static uint32_t stat_to_v9mode(const struct stat
> *stbuf)
> >      if (S_ISFIFO(stbuf->st_mode)) {
> >          mode |= P9_STAT_MODE_NAMED_PIPE;
> >      }
> > +#endif
> >
> >      if (S_ISBLK(stbuf->st_mode) || S_ISCHR(stbuf->st_mode)) {
> >          mode |= P9_STAT_MODE_DEVICE;
> >      }
> >
> > +#ifndef CONFIG_WIN32
> >      if (stbuf->st_mode & S_ISUID) {
> >          mode |= P9_STAT_MODE_SETUID;
> >      }
> > @@ -1209,6 +1232,7 @@ static uint32_t stat_to_v9mode(const struct stat
> *stbuf)
> >      if (stbuf->st_mode & S_ISVTX) {
> >          mode |= P9_STAT_MODE_SETVTX;
> >      }
> > +#endif
> >
> >      return mode;
> >  }
> > @@ -1247,9 +1271,17 @@ static int coroutine_fn stat_to_v9stat(V9fsPDU *pdu,
> V9fsPath *path,
> >              return err;
> >          }
> >      } else if (v9stat->mode & P9_STAT_MODE_DEVICE) {
> > +        unsigned maj, min;
> > +
> > +#ifndef CONFIG_WIN32
> > +        maj = major(stbuf->st_rdev);
> > +        min = minor(stbuf->st_rdev);
> > +#else
> > +        maj = min = 0;
> > +#endif
> 
> Really?

See above link.

> 
> >          v9fs_string_sprintf(&v9stat->extension, "%c %u %u",
> >                  S_ISCHR(stbuf->st_mode) ? 'c' : 'b',
> > -                major(stbuf->st_rdev), minor(stbuf->st_rdev));
> > +                maj, min);
> >      } else if (S_ISDIR(stbuf->st_mode) || S_ISREG(stbuf->st_mode)) {
> >          v9fs_string_sprintf(&v9stat->extension, "%s %lu",
> >                  "HARDLINKCOUNT", (unsigned long)stbuf->st_nlink); @@
> > -1317,7 +1349,14 @@ static int32_t blksize_to_iounit(const V9fsPDU
> > *pdu, int32_t blksize)
> >
> >  static int32_t stat_to_iounit(const V9fsPDU *pdu, const struct stat
> > *stbuf)  {
> > -    return blksize_to_iounit(pdu, stbuf->st_blksize);
> > +    int32_t blksize;
> > +
> > +#ifndef CONFIG_WIN32
> > +    blksize = stbuf->st_blksize);
> > +#else
> > +    blksize = 0;
> > +#endif
> 
> Really?

Windows struct stat does not have such field. See above link.

> 
> > +    return blksize_to_iounit(pdu, blksize);
> >  }
> >
> >  static int stat_to_v9stat_dotl(V9fsPDU *pdu, const struct stat
> > *stbuf, @@ -1332,7 +1371,11 @@ static int stat_to_v9stat_dotl(V9fsPDU *pdu,
> const struct stat *stbuf,
> >      v9lstat->st_rdev = host_dev_to_dotl_dev(stbuf->st_rdev);
> >      v9lstat->st_size = stbuf->st_size;
> >      v9lstat->st_blksize = stat_to_iounit(pdu, stbuf);
> > +#ifndef CONFIG_WIN32
> >      v9lstat->st_blocks = stbuf->st_blocks;
> > +#else
> > +    v9lstat->st_blocks = 0;
> > +#endif
> 
> Really?

Windows struct stat does not have such field. See above link.

> 
> >      v9lstat->st_atime_sec = stbuf->st_atime;
> >      v9lstat->st_mtime_sec = stbuf->st_mtime;
> >      v9lstat->st_ctime_sec = stbuf->st_ctime; @@ -1340,7 +1383,8 @@
> > static int stat_to_v9stat_dotl(V9fsPDU *pdu, const struct stat *stbuf,
> >      v9lstat->st_atime_nsec = stbuf->st_atimespec.tv_nsec;
> >      v9lstat->st_mtime_nsec = stbuf->st_mtimespec.tv_nsec;
> >      v9lstat->st_ctime_nsec = stbuf->st_ctimespec.tv_nsec; -#else
> > +#endif
> > +#ifdef CONFIG_LINUX
> >      v9lstat->st_atime_nsec = stbuf->st_atim.tv_nsec;
> >      v9lstat->st_mtime_nsec = stbuf->st_mtim.tv_nsec;
> >      v9lstat->st_ctime_nsec = stbuf->st_ctim.tv_nsec; @@ -2471,6
> > +2515,7 @@ static int coroutine_fn v9fs_do_readdir(V9fsPDU *pdu,
> V9fsFidState *fidp,
> >      struct dirent *dent;
> >      struct stat *st;
> >      struct V9fsDirEnt *entries = NULL;
> > +    unsigned char d_type = 0;
> >
> >      /*
> >       * inode remapping requires the device id, which in turn might be
> > @@ -2540,10 +2585,13 @@ static int coroutine_fn v9fs_do_readdir(V9fsPDU
> *pdu, V9fsFidState *fidp,
> >          v9fs_string_init(&name);
> >          v9fs_string_sprintf(&name, "%s", dent->d_name);
> >
> > +#ifndef CONFIG_WIN32
> > +        d_type = dent->d_type;
> > +#endif
> >          /* 11 = 7 + 4 (7 = start offset, 4 = space for storing count) */
> >          len = pdu_marshal(pdu, 11 + count, "Qqbs",
> >                            &qid, off,
> > -                          dent->d_type, &name);
> > +                          d_type, &name);
> 
> Are you saying that d_type is not initialized with zero already?

struct dirent is defined by MinGW, it does not have d_type member:

https://github.com/Alexpux/mingw-w64/blob/master/mingw-w64-headers/crt/dirent.h


> 
> >          v9fs_string_free(&name);
> >
> > @@ -2873,8 +2921,12 @@ static void coroutine_fn v9fs_create(void *opaque)
> >          }
> >
> >          nmode |= perm & 0777;
> > +#ifndef CONFIG_WIN32
> >          err = v9fs_co_mknod(pdu, fidp, &name, fidp->uid, -1,
> >                              makedev(major, minor), nmode, &stbuf);
> > +#else
> > +        err = -ENOTSUP;
> > +#endif
> >          if (err < 0) {
> >              goto out;
> >          }
> > @@ -2899,8 +2951,12 @@ static void coroutine_fn v9fs_create(void *opaque)
> >          v9fs_path_copy(&fidp->path, &path);
> >          v9fs_path_unlock(s);
> >      } else if (perm & P9_STAT_MODE_SOCKET) {
> > +#ifndef CONFIG_WIN32
> >          err = v9fs_co_mknod(pdu, fidp, &name, fidp->uid, -1,
> >                              0, S_IFSOCK | (perm & 0777), &stbuf);
> > +#else
> > +        err = -ENOTSUP;
> > +#endif
> 
> As with previous patches, I would consider making the user aware to use
> mapped(-xattr) with something like error_report_once().

OK, got it.

> 
> >          if (err < 0) {
> >              goto out;
> >          }
> > @@ -3634,7 +3690,7 @@ out_nofid:
> >
> >  static void coroutine_fn v9fs_mknod(void *opaque)  {
> > -
> > +#ifndef CONFIG_WIN32
> >      int mode;
> >      gid_t gid;
> >      int32_t fid;
> > @@ -3691,6 +3747,10 @@ out:
> >  out_nofid:
> >      pdu_complete(pdu, err);
> >      v9fs_string_free(&name);
> > +#else
> > +    V9fsPDU *pdu = opaque;
> > +    pdu_complete(pdu, -1);
> > +#endif
> >  }
> >
> >  /*
> > @@ -3963,7 +4023,7 @@ out_nofid:
> >  #if defined(CONFIG_LINUX)
> >  /* Currently, only Linux has XATTR_SIZE_MAX */  #define
> > P9_XATTR_SIZE_MAX XATTR_SIZE_MAX -#elif defined(CONFIG_DARWIN)
> > +#elif defined(CONFIG_DARWIN) || defined(CONFIG_WIN32)
> >  /*
> >   * Darwin doesn't seem to define a maximum xattr size in its user
> >   * space header, so manually configure it across platforms as 64k.
> > @@ -3980,6 +4040,7 @@ out_nofid:
> >
> >  static void coroutine_fn v9fs_xattrcreate(void *opaque)  {
> > +#ifndef CONFIG_WIN32
> >      int flags, rflags = 0;
> >      int32_t fid;
> >      uint64_t size;
> > @@ -4041,10 +4102,15 @@ out_put_fid:
> >  out_nofid:
> >      pdu_complete(pdu, err);
> >      v9fs_string_free(&name);
> > +#else
> > +    V9fsPDU *pdu = opaque;
> > +    pdu_complete(pdu, -1);
> > +#endif
> >  }
> >
> >  static void coroutine_fn v9fs_readlink(void *opaque)  {
> > +#ifndef CONFIG_WIN32
> >      V9fsPDU *pdu = opaque;
> >      size_t offset = 7;
> >      V9fsString target;
> > @@ -4080,6 +4146,10 @@ out:
> >      put_fid(pdu, fidp);
> >  out_nofid:
> >      pdu_complete(pdu, err);
> > +#else
> > +    V9fsPDU *pdu = opaque;
> > +    pdu_complete(pdu, -1);
> > +#endif
> 
> Unnecessary double declaration of pdu.
> 

OK, got it.

> >  }
> >
> >  static CoroutineEntry *pdu_co_handlers[] = { @@ -4341,6 +4411,7 @@
> > void v9fs_reset(V9fsState *s)
> >
> >  static void __attribute__((__constructor__)) v9fs_set_fd_limit(void)
> > {
> > +#ifndef CONFIG_WIN32
> >      struct rlimit rlim;
> >      if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
> >          error_report("Failed to get the resource limit"); @@ -4348,4
> > +4419,5 @@ static void __attribute__((__constructor__))
> v9fs_set_fd_limit(void)
> >      }
> >      open_fd_hw = rlim.rlim_cur - MIN(400, rlim.rlim_cur / 3);
> >      open_fd_rc = rlim.rlim_cur / 2;
> > +#endif
> 
> Really?

Windows does not provide getrlimit()

> 
> >  }
> >
> 
> 


Reply via email to