On Monday, October 24, 2022 6:57:54 AM CET Bin Meng wrote: > From: Guohuai Shi <guohuai....@windriver.com> > > When using 9p2000.L protocol, the errno should use the Linux errno. > Currently magic numbers with comments are used. Replace these with > macros for future expansion. > > Signed-off-by: Guohuai Shi <guohuai....@windriver.com> > Signed-off-by: Bin Meng <bin.m...@windriver.com> > --- > > hw/9pfs/9p-linux-errno.h | 151 +++++++++++++++++++++++++++++++++++++++ > hw/9pfs/9p-util.h | 38 ++++++---- > 2 files changed, 176 insertions(+), 13 deletions(-) > create mode 100644 hw/9pfs/9p-linux-errno.h > > diff --git a/hw/9pfs/9p-linux-errno.h b/hw/9pfs/9p-linux-errno.h > new file mode 100644 > index 0000000000..56c37fa293 > --- /dev/null > +++ b/hw/9pfs/9p-linux-errno.h > @@ -0,0 +1,151 @@ > +/* > + * 9p Linux errno translation definition > + * > + * This work is licensed under the terms of the GNU GPL, version 2 or later. > + * See the COPYING file in the top-level directory. > + */ > + > +#include <errno.h> > + > +#ifndef QEMU_9P_LINUX_ERRNO_H > +#define QEMU_9P_LINUX_ERRNO_H > + > +/* > + * This file contains the Linux errno definitions to translate errnos set by > + * the 9P server (running on non-Linux hosts) to a corresponding errno value. > + * > + * This list should be periodically reviewed and updated; particularly for > + * errnos that might be set as a result of a file system operation. > + */
Yeah, that's my main concern here. I wonder if there is isn't a better maintainable solution at least for the list of Linux errors, so that we don't have to manually update the L_ macros below. > + > +#define L_EPERM 1 /* Operation not permitted */ > +#define L_ENOENT 2 /* No such file or directory */ > +#define L_ESRCH 3 /* No such process */ > +#define L_EINTR 4 /* Interrupted system call */ > +#define L_EIO 5 /* I/O error */ > +#define L_ENXIO 6 /* No such device or address */ > +#define L_E2BIG 7 /* Argument list too long */ > +#define L_ENOEXEC 8 /* Exec format error */ > +#define L_EBADF 9 /* Bad file number */ > +#define L_ECHILD 10 /* No child processes */ > +#define L_EAGAIN 11 /* Try again */ > +#define L_ENOMEM 12 /* Out of memory */ > +#define L_EACCES 13 /* Permission denied */ > +#define L_EFAULT 14 /* Bad address */ > +#define L_ENOTBLK 15 /* Block device required */ > +#define L_EBUSY 16 /* Device or resource busy */ > +#define L_EEXIST 17 /* File exists */ > +#define L_EXDEV 18 /* Cross-device link */ > +#define L_ENODEV 19 /* No such device */ > +#define L_ENOTDIR 20 /* Not a directory */ > +#define L_EISDIR 21 /* Is a directory */ > +#define L_EINVAL 22 /* Invalid argument */ > +#define L_ENFILE 23 /* File table overflow */ > +#define L_EMFILE 24 /* Too many open files */ > +#define L_ENOTTY 25 /* Not a typewriter */ > +#define L_ETXTBSY 26 /* Text file busy */ > +#define L_EFBIG 27 /* File too large */ > +#define L_ENOSPC 28 /* No space left on device */ > +#define L_ESPIPE 29 /* Illegal seek */ > +#define L_EROFS 30 /* Read-only file system */ > +#define L_EMLINK 31 /* Too many links */ > +#define L_EPIPE 32 /* Broken pipe */ > +#define L_EDOM 33 /* Math argument out of domain of func */ > +#define L_ERANGE 34 /* Math result not representable */ > +#define L_EDEADLK 35 /* Resource deadlock would occur */ > +#define L_ENAMETOOLONG 36 /* File name too long */ > +#define L_ENOLCK 37 /* No record locks available */ > +#define L_ENOSYS 38 /* Function not implemented */ > +#define L_ENOTEMPTY 39 /* Directory not empty */ > +#define L_ELOOP 40 /* Too many symbolic links encountered */ > +#define L_ENOMSG 42 /* No message of desired type */ > +#define L_EIDRM 43 /* Identifier removed */ > +#define L_ECHRNG 44 /* Channel number out of range */ > +#define L_EL2NSYNC 45 /* Level 2 not synchronized */ > +#define L_EL3HLT 46 /* Level 3 halted */ > +#define L_EL3RST 47 /* Level 3 reset */ > +#define L_ELNRNG 48 /* Link number out of range */ > +#define L_EUNATCH 49 /* Protocol driver not attached */ > +#define L_ENOCSI 50 /* No CSI structure available */ > +#define L_EL2HLT 51 /* Level 2 halted */ > +#define L_EBADE 52 /* Invalid exchange */ > +#define L_EBADR 53 /* Invalid request descriptor */ > +#define L_EXFULL 54 /* Exchange full */ > +#define L_ENOANO 55 /* No anode */ > +#define L_EBADRQC 56 /* Invalid request code */ > +#define L_EBADSLT 57 /* Invalid slot */ > +#define L_EBFONT 58 /* Bad font file format */ > +#define L_ENOSTR 59 /* Device not a stream */ > +#define L_ENODATA 61 /* No data available */ > +#define L_ETIME 62 /* Timer expired */ > +#define L_ENOSR 63 /* Out of streams resources */ > +#define L_ENONET 64 /* Machine is not on the network */ > +#define L_ENOPKG 65 /* Package not installed */ > +#define L_EREMOTE 66 /* Object is remote */ > +#define L_ENOLINK 67 /* Link has been severed */ > +#define L_EADV 68 /* Advertise error */ > +#define L_ESRMNT 69 /* Srmount error */ > +#define L_ECOMM 70 /* Communication error on send */ > +#define L_EPROTO 71 /* Protocol error */ > +#define L_EMULTIHOP 72 /* Multihop attempted */ > +#define L_EDOTDOT 73 /* RFS specific error */ > +#define L_EBADMSG 74 /* Not a data message */ > +#define L_EOVERFLOW 75 /* Value too large for defined data type */ > +#define L_ENOTUNIQ 76 /* Name not unique on network */ > +#define L_EBADFD 77 /* File descriptor in bad state */ > +#define L_EREMCHG 78 /* Remote address changed */ > +#define L_ELIBACC 79 /* Can not access a needed shared library */ > +#define L_ELIBBAD 80 /* Accessing a corrupted shared library */ > +#define L_ELIBSCN 81 /* .lib section in a.out corrupted */ > +#define L_ELIBMAX 82 /* Attempting to link in too many shared > libs */ > +#define L_ELIBEXEC 83 /* Cannot exec a shared library directly */ > +#define L_EILSEQ 84 /* Illegal byte sequence */ > +#define L_ERESTART 85 /* Interrupted system call should be > restarted */ > +#define L_ESTRPIPE 86 /* Streams pipe error */ > +#define L_EUSERS 87 /* Too many users */ > +#define L_ENOTSOCK 88 /* Socket operation on non-socket */ > +#define L_EDESTADDRREQ 89 /* Destination address required */ > +#define L_EMSGSIZE 90 /* Message too long */ > +#define L_EPROTOTYPE 91 /* Protocol wrong type for socket */ > +#define L_ENOPROTOOPT 92 /* Protocol not available */ > +#define L_EPROTONOSUPPORT 93 /* Protocol not supported */ > +#define L_ESOCKTNOSUPPORT 94 /* Socket type not supported */ > +#define L_EOPNOTSUPP 95 /* Operation not supported on transport > endpoint */ > +#define L_EPFNOSUPPORT 96 /* Protocol family not supported */ > +#define L_EAFNOSUPPORT 97 /* Address family not supported by protocol > */ > +#define L_EADDRINUSE 98 /* Address already in use */ > +#define L_EADDRNOTAVAIL 99 /* Cannot assign requested address */ > +#define L_ENETDOWN 100 /* Network is down */ > +#define L_ENETUNREACH 101 /* Network is unreachable */ > +#define L_ENETRESET 102 /* Network dropped connection because of > reset */ > +#define L_ECONNABORTED 103 /* Software caused connection abort */ > +#define L_ECONNRESET 104 /* Connection reset by peer */ > +#define L_ENOBUFS 105 /* No buffer space available */ > +#define L_EISCONN 106 /* Transport endpoint is already connected */ > +#define L_ENOTCONN 107 /* Transport endpoint is not connected */ > +#define L_ESHUTDOWN 108 /* Cannot send after transport endpoint > shutdown */ > +#define L_ETOOMANYREFS 109 /* Too many references: cannot splice */ > +#define L_ETIMEDOUT 110 /* Connection timed out */ > +#define L_ECONNREFUSED 111 /* Connection refused */ > +#define L_EHOSTDOWN 112 /* Host is down */ > +#define L_EHOSTUNREACH 113 /* No route to host */ > +#define L_EALREADY 114 /* Operation already in progress */ > +#define L_EINPROGRESS 115 /* Operation now in progress */ > +#define L_ESTALE 116 /* Stale NFS file handle */ > +#define L_EUCLEAN 117 /* Structure needs cleaning */ > +#define L_ENOTNAM 118 /* Not a XENIX named type file */ > +#define L_ENAVAIL 119 /* No XENIX semaphores available */ > +#define L_EISNAM 120 /* Is a named type file */ > +#define L_EREMOTEIO 121 /* Remote I/O error */ > +#define L_EDQUOT 122 /* Quota exceeded */ > +#define L_ENOMEDIUM 123 /* No medium found */ > +#define L_EMEDIUMTYPE 124 /* Wrong medium type */ > +#define L_ECANCELED 125 /* Operation Canceled */ > +#define L_ENOKEY 126 /* Required key not available */ > +#define L_EKEYEXPIRED 127 /* Key has expired */ > +#define L_EKEYREVOKED 128 /* Key has been revoked */ > +#define L_EKEYREJECTED 129 /* Key was rejected by service */ > +#define L_EOWNERDEAD 130 /* Owner died */ > +#define L_ENOTRECOVERABLE 131 /* State not recoverable */ > + > +#endif /* QEMU_9P_LINUX_ERRNO_H */ > diff --git a/hw/9pfs/9p-util.h b/hw/9pfs/9p-util.h > index 3d154e9103..281fdcbf8c 100644 > --- a/hw/9pfs/9p-util.h > +++ b/hw/9pfs/9p-util.h > @@ -62,8 +62,11 @@ static inline uint64_t host_dev_to_dotl_dev(dev_t dev) > #endif > } > > +#include "9p-linux-errno.h" > + > /* Translates errno from host -> Linux if needed */ > -static inline int errno_to_dotl(int err) { > +static inline int errno_to_dotl(int err) > +{ > #if defined(CONFIG_LINUX) > /* nothing to translate (Linux -> Linux) */ > #elif defined(CONFIG_DARWIN) > @@ -73,18 +76,27 @@ static inline int errno_to_dotl(int err) { > * FIXME: Only most important errnos translated here yet, this should be > * extended to as many errnos being translated as possible in future. > */ > - if (err == ENAMETOOLONG) { > - err = 36; /* ==ENAMETOOLONG on Linux */ > - } else if (err == ENOTEMPTY) { > - err = 39; /* ==ENOTEMPTY on Linux */ > - } else if (err == ELOOP) { > - err = 40; /* ==ELOOP on Linux */ > - } else if (err == ENOATTR) { > - err = 61; /* ==ENODATA on Linux */ > - } else if (err == ENOTSUP) { > - err = 95; /* ==EOPNOTSUPP on Linux */ > - } else if (err == EOPNOTSUPP) { > - err = 95; /* ==EOPNOTSUPP on Linux */ > + switch (err) { > + case ENAMETOOLONG: > + err = L_ENAMETOOLONG; > + break; > + case ENOTEMPTY: > + err = L_ENOTEMPTY; > + break; > + case ELOOP: > + err = L_ELOOP; > + break; > + case ENOATTR: > + err = L_ENODATA; > + break; > + case ENOTSUP > + err = L_EOPNOTSUPP; > + break; > + case EOPNOTSUPP: > + err = L_EOPNOTSUPP; > + break; > + default: > + break; > } What about a more compact solution like: switch (err) { case ENAMETOOLONG: return L_ENAMETOOLONG; case ENOTEMPTY: return L_ENOTEMPTY; ... default: return err; } Previously I suggested to use an array-solution with designated initializers instead, but I guess we don't know how high these error numbers could become on certain systems. > #else > #error Missing errno translation to Linux for this host system >