Skip to content

Commit

Permalink
9pfs: fix wrong errno being sent to Linux client on macOS host
Browse files Browse the repository at this point in the history
Linux and macOS only share some errno definitions with equal macro
name and value. In fact most mappings for errno are completely
different on the two systems.

This patch converts some important errno values from macOS host to
corresponding Linux errno values before eventually sending such error
codes along with 'Rlerror' replies (if 9p2000.L is used that is). Not
having translated errnos before violated the 9p2000.L protocol spec,
which says:

  "
  size[4] Rlerror tag[2] ecode[4]

  ... ecode is a numerical Linux errno.
  "

  https://github.com/chaos/diod/wiki/protocol#lerror----return-error-code

This patch fixes a bunch of misbehaviours when running a Linux client
on macOS host. For instance this patch fixes:

  mount -t 9p -o posixacl ...

on Linux guest if security_mode=mapped was used for 9p server, which
refused to mount successfully, because macOS returned ENOATTR==93
when client tried to retrieve POSIX ACL xattrs, because errno 93
is defined as EPROTONOSUPPORT==93 on Linux, so Linux client believed
that xattrs were not supported by filesystem on host in general.

Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
Link: https://lore.kernel.org/qemu-devel/20220421124835.3e664669@bahia/
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
Message-Id: <b322ab298a62069e527d2b032028bdc9115afacd.1651228001.git.qemu_oss@crudebyte.com>
  • Loading branch information
cschoenebeck committed May 1, 2022
1 parent e5c88e2 commit 951fe2f
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 0 deletions.
30 changes: 30 additions & 0 deletions hw/9pfs/9p-util.h
Expand Up @@ -58,6 +58,36 @@ static inline uint64_t host_dev_to_dotl_dev(dev_t dev)
#endif
}

/* Translates errno from host -> Linux if needed */
static inline int errno_to_dotl(int err) {
#if defined(CONFIG_LINUX)
/* nothing to translate (Linux -> Linux) */
#elif defined(CONFIG_DARWIN)
/*
* translation mandatory for macOS hosts
*
* 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 */
}
#else
#error Missing errno translation to Linux for this host system
#endif
return err;
}

#ifdef CONFIG_DARWIN
#define qemu_fgetxattr(...) fgetxattr(__VA_ARGS__, 0, 0)
#define qemu_lgetxattr(...) getxattr(__VA_ARGS__, 0, XATTR_NOFOLLOW)
Expand Down
2 changes: 2 additions & 0 deletions hw/9pfs/9p.c
Expand Up @@ -1054,6 +1054,8 @@ static void coroutine_fn pdu_complete(V9fsPDU *pdu, ssize_t len)
}
len += ret;
id = P9_RERROR;
} else {
err = errno_to_dotl(err);
}

ret = pdu_marshal(pdu, len, "d", err);
Expand Down

0 comments on commit 951fe2f

Please sign in to comment.