summary refs log tree commit diff stats
path: root/hw/9pfs/9p-util-freebsd.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2025-09-19 12:21:35 -0700
committerRichard Henderson <richard.henderson@linaro.org>2025-09-19 12:21:35 -0700
commitab8008b231e758e03c87c1c483c03afdd9c02e19 (patch)
treeffd15bdf5bccf59e08f0d0d7a74a9511ee4f2c43 /hw/9pfs/9p-util-freebsd.c
parentcaf2e8de4ed056acad4fbdb6fe420d8124d38f11 (diff)
parentc921e5496f23221335bea0c9104364409cd0b2b8 (diff)
downloadfocaccia-qemu-ab8008b231e758e03c87c1c483c03afdd9c02e19.tar.gz
focaccia-qemu-ab8008b231e758e03c87c1c483c03afdd9c02e19.zip
Merge tag 'pull-9p-20250918' of https://github.com/cschoenebeck/qemu into staging
9pfs changes:

* Add FreeBSD host support.

* Fix glib header inclusion.

# -----BEGIN PGP SIGNATURE-----
#
# iQJLBAABCgA1FiEEltjREM96+AhPiFkBNMK1h2Wkc5UFAmjMYKMXHHFlbXVfb3Nz
# QGNydWRlYnl0ZS5jb20ACgkQNMK1h2Wkc5VUGBAAiRVM6vTErPwccp+w8UrpAVo5
# oXdN2TIpQoILGg2vSuHc4mGUXjMmqnihCbNP9p3ZUVSYQwSwpXa2i47GSe100Mzi
# kiv2/SROopohE6ZiDok65GCj2hXShF0tZGauTBoE0WTZP9LG+rvftMeupbgrEKll
# To5hOdsQbPw2HtATpTjRufvVTtaeu8oGeh+BPmtiyu7Aiea4xht9YCAMa8AVG44P
# 97ZmnqYAq/5bolE6fTuVEWj484cPjMPC/sMBddhNV57HwzYdqGdOinR3GqRHspvN
# B0oCq07HXeAV55APGQtPWOWq1SonGqIhHj0Hdnugl3DWUWiQs0CVSMPlE7Aag7at
# /8JbGS2j7RuM5N9Zdf8Wlq78jgvRmbpYZunD0RLd8O+jESaHAoNpjrNHm4v92WLa
# bUePytsxCK9ozStPqRVB9zGOYyx36LKG/8E5J4t00GX2F0FRB9OxgSPFWCWFnqM5
# R4IvR2huW8/DvplgvVpPc0SM+lMV7GZhAC92z7KkQYBE85s09EdAobIIHguK3B0l
# 5hy9w6tZ6nnFloaL0fWccE3XU+X56KrDkX0G/AEdppsxYBYYhs1XNhR5AYuQCEd5
# gdKtLrEOr1F2snb8aLfS8MDwTUCkU1lfbipyzDaX3sr4Gg+7L/vV3OxQoGmwMjOe
# xnI3cMzk0j7prHT1oSc=
# =3YK2
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 18 Sep 2025 12:42:27 PM PDT
# gpg:                using RSA key 96D8D110CF7AF8084F88590134C2B58765A47395
# gpg:                issuer "qemu_oss@crudebyte.com"
# gpg: Good signature from "Christian Schoenebeck <qemu_oss@crudebyte.com>" [unknown]
# gpg: WARNING: The key's User ID is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: ECAB 1A45 4014 1413 BA38  4926 30DB 47C3 A012 D5F4
#      Subkey fingerprint: 96D8 D110 CF7A F808 4F88  5901 34C2 B587 65A4 7395

* tag 'pull-9p-20250918' of https://github.com/cschoenebeck/qemu:
  9pfs: Stop including gstrfuncs.h
  9pfs: Add FreeBSD support

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'hw/9pfs/9p-util-freebsd.c')
-rw-r--r--hw/9pfs/9p-util-freebsd.c132
1 files changed, 132 insertions, 0 deletions
diff --git a/hw/9pfs/9p-util-freebsd.c b/hw/9pfs/9p-util-freebsd.c
new file mode 100644
index 0000000000..9dd1d069f6
--- /dev/null
+++ b/hw/9pfs/9p-util-freebsd.c
@@ -0,0 +1,132 @@
+/*
+ * 9p utilities (FreeBSD Implementation)
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+/*
+ * Not so fast! You might want to read the 9p developer docs first:
+ * https://wiki.qemu.org/Documentation/9p
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/xattr.h"
+#include "9p-util.h"
+
+static int mangle_xattr_name(const char **namep)
+{
+    const char *name = *namep;
+
+    /*
+     * ZFS forbids attributes in starting with "user." or "system.".
+     */
+    if (strncmp(name, "system.", 7) == 0) {
+        *namep = name + 7;
+        return EXTATTR_NAMESPACE_SYSTEM;
+    }
+    if (strncmp(name, "user.", 5) == 0) {
+        *namep = name + 5;
+    }
+    return EXTATTR_NAMESPACE_USER;
+}
+
+ssize_t fgetxattr(int fd, const char *name, void *value, size_t size)
+{
+    int namespace;
+
+    namespace = mangle_xattr_name(&name);
+    return extattr_get_fd(fd, namespace, name, value, size);
+}
+
+ssize_t fgetxattrat_nofollow(int dirfd, const char *filename, const char *name,
+                             void *value, size_t size)
+{
+    ssize_t ret;
+    int fd, namespace;
+
+    fd = openat_file(dirfd, filename,
+                     O_RDONLY | O_PATH_9P_UTIL | O_NOFOLLOW, 0);
+    if (fd == -1) {
+        return -1;
+    }
+    namespace = mangle_xattr_name(&name);
+    ret = extattr_get_fd(fd, namespace, name, value, size);
+    close_preserve_errno(fd);
+    return ret;
+}
+
+ssize_t flistxattrat_nofollow(int dirfd, const char *filename,
+                              char *list, size_t size)
+{
+    ssize_t ret;
+    int fd;
+
+    fd = openat_file(dirfd, filename,
+                     O_RDONLY | O_PATH_9P_UTIL | O_NOFOLLOW, 0);
+    if (fd == -1) {
+        return -1;
+    }
+    ret = extattr_list_fd(fd, EXTATTR_NAMESPACE_USER, list, size);
+    close_preserve_errno(fd);
+    return ret;
+}
+
+ssize_t fremovexattrat_nofollow(int dirfd, const char *filename,
+                                const char *name)
+{
+    int fd, namespace, ret;
+
+    fd = openat_file(dirfd, filename,
+                     O_RDONLY | O_PATH_9P_UTIL | O_NOFOLLOW, 0);
+    if (fd == -1) {
+        return -1;
+    }
+    namespace = mangle_xattr_name(&name);
+    ret = extattr_delete_fd(fd, namespace, name);
+    close_preserve_errno(fd);
+    return ret;
+}
+
+int fsetxattrat_nofollow(int dirfd, const char *filename, const char *name,
+                         void *value, size_t size, int flags)
+{
+    ssize_t ret;
+    int fd, namespace;
+
+    namespace = mangle_xattr_name(&name);
+    if (flags == (XATTR_CREATE | XATTR_REPLACE)) {
+        errno = EINVAL;
+        return -1;
+    }
+    fd = openat_file(dirfd, filename,
+                     O_RDONLY | O_PATH_9P_UTIL | O_NOFOLLOW, 0);
+    if (fd == -1) {
+        return -1;
+    }
+    if (flags & (XATTR_CREATE | XATTR_REPLACE)) {
+        ret = extattr_get_fd(fd, namespace, name, NULL, 0);
+        if (ret == -1 && errno != ENOATTR) {
+            close_preserve_errno(fd);
+            return -1;
+        }
+        if (ret >= 0 && (flags & XATTR_CREATE)) {
+            errno = EEXIST;
+            close_preserve_errno(fd);
+            return -1;
+        }
+        if (ret == -1 && (flags & XATTR_REPLACE)) {
+            errno = ENOATTR;
+            close_preserve_errno(fd);
+            return -1;
+        }
+    }
+    ret = extattr_set_fd(fd, namespace, name, value, size);
+    close_preserve_errno(fd);
+    return ret;
+}
+
+int qemu_mknodat(int dirfd, const char *filename, mode_t mode, dev_t dev)
+{
+    return mknodat(dirfd, filename, mode, dev);
+}