svn commit: r347395 - in projects/fuse2: sys/fs/fuse tests/sys/fs/fusefs
Alan Somers
asomers at FreeBSD.org
Thu May 9 16:25:03 UTC 2019
Author: asomers
Date: Thu May 9 16:25:01 2019
New Revision: 347395
URL: https://svnweb.freebsd.org/changeset/base/347395
Log:
fusefs: create sockets with FUSE_MKNOD, not FUSE_CREATE
libfuse expects sockets to be created with FUSE_MKNOD, not FUSE_CREATE,
because that's how Linux does it. My first attempt at creating sockets
(r346894) used FUSE_CREATE because FreeBSD uses VOP_CREATE for this purpose.
There are no backwards-compatibility concerns with this change, because
socket support hasn't yet been merged to head.
Sponsored by: The FreeBSD Foundation
Modified:
projects/fuse2/sys/fs/fuse/fuse_internal.c
projects/fuse2/sys/fs/fuse/fuse_internal.h
projects/fuse2/sys/fs/fuse/fuse_vnops.c
projects/fuse2/tests/sys/fs/fusefs/create.cc
projects/fuse2/tests/sys/fs/fusefs/fifo.cc
projects/fuse2/tests/sys/fs/fusefs/mknod.cc
Modified: projects/fuse2/sys/fs/fuse/fuse_internal.c
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_internal.c Thu May 9 14:06:24 2019 (r347394)
+++ projects/fuse2/sys/fs/fuse/fuse_internal.c Thu May 9 16:25:01 2019 (r347395)
@@ -312,6 +312,19 @@ fuse_internal_fsync(struct vnode *vp,
return err;
}
+/* mknod */
+int
+fuse_internal_mknod(struct vnode *dvp, struct vnode **vpp,
+ struct componentname *cnp, struct vattr *vap)
+{
+ struct fuse_mknod_in fmni;
+
+ fmni.mode = MAKEIMODE(vap->va_type, vap->va_mode);
+ fmni.rdev = vap->va_rdev;
+ return (fuse_internal_newentry(dvp, vpp, cnp, FUSE_MKNOD, &fmni,
+ sizeof(fmni), vap->va_type));
+}
+
/* readdir */
int
Modified: projects/fuse2/sys/fs/fuse/fuse_internal.h
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_internal.h Thu May 9 14:06:24 2019 (r347394)
+++ projects/fuse2/sys/fs/fuse/fuse_internal.h Thu May 9 16:25:01 2019 (r347395)
@@ -228,6 +228,11 @@ struct pseudo_dirent {
uint32_t d_namlen;
};
+/* mknod */
+int fuse_internal_mknod(struct vnode *dvp, struct vnode **vpp,
+ struct componentname *cnp, struct vattr *vap);
+
+/* readdir */
int fuse_internal_readdir(struct vnode *vp, struct uio *uio,
struct fuse_filehandle *fufh, struct fuse_iov *cookediov);
int fuse_internal_readdir_processdata(struct uio *uio, size_t reqsize,
Modified: projects/fuse2/sys/fs/fuse/fuse_vnops.c
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_vnops.c Thu May 9 14:06:24 2019 (r347394)
+++ projects/fuse2/sys/fs/fuse/fuse_vnops.c Thu May 9 16:25:01 2019 (r347395)
@@ -537,6 +537,13 @@ fuse_vnop_create(struct vop_create_args *ap)
enum fuse_opcode op;
int flags;
+ if (fuse_isdeadfs(dvp))
+ return ENXIO;
+
+ /* FUSE expects sockets to be created with FUSE_MKNOD */
+ if (vap->va_type == VSOCK)
+ return fuse_internal_mknod(dvp, vpp, cnp, vap);
+
/*
* VOP_CREATE doesn't tell us the open(2) flags, so we guess. Only a
* writable mode makes sense, and we might as well include readability
@@ -544,15 +551,12 @@ fuse_vnop_create(struct vop_create_args *ap)
*/
flags = O_RDWR;
- if (fuse_isdeadfs(dvp)) {
- return ENXIO;
- }
bzero(&fdi, sizeof(fdi));
- if ((vap->va_type != VREG && vap->va_type != VSOCK))
+ if (vap->va_type != VREG)
return (EINVAL);
- if (!fsess_isimpl(mp, FUSE_CREATE)) {
+ if (!fsess_isimpl(mp, FUSE_CREATE) || vap->va_type == VSOCK) {
/* Fallback to FUSE_MKNOD/FUSE_OPEN */
fdisp_make_mknod_for_fallback(fdip, cnp, dvp, parentnid, td,
cred, mode, &op);
@@ -1163,15 +1167,11 @@ fuse_vnop_mknod(struct vop_mknod_args *ap)
struct vnode **vpp = ap->a_vpp;
struct componentname *cnp = ap->a_cnp;
struct vattr *vap = ap->a_vap;
- struct fuse_mknod_in fmni;
if (fuse_isdeadfs(dvp))
return ENXIO;
- fmni.mode = MAKEIMODE(vap->va_type, vap->va_mode);
- fmni.rdev = vap->va_rdev;
- return (fuse_internal_newentry(dvp, vpp, cnp, FUSE_MKNOD, &fmni,
- sizeof(fmni), vap->va_type));
+ return fuse_internal_mknod(dvp, vpp, cnp, vap);
}
/*
Modified: projects/fuse2/tests/sys/fs/fusefs/create.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/create.cc Thu May 9 14:06:24 2019 (r347394)
+++ projects/fuse2/tests/sys/fs/fusefs/create.cc Thu May 9 16:25:01 2019 (r347395)
@@ -30,8 +30,6 @@
extern "C" {
#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/un.h>
}
#include "mockfs.hh"
@@ -308,34 +306,6 @@ TEST_F(Create, ok)
fd = open(FULLPATH, O_CREAT | O_EXCL, mode);
EXPECT_LE(0, fd) << strerror(errno);
/* Deliberately leak fd. close(2) will be tested in release.cc */
-}
-
-/* Create a unix-domain socket */
-TEST_F(Create, socket)
-{
- const char FULLPATH[] = "mountpoint/some_sock";
- const char RELPATH[] = "some_sock";
- mode_t mode = S_IFSOCK | 0755;
- struct sockaddr_un sa;
- uint64_t ino = 42;
- int fd;
-
- EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT)));
- expect_create(RELPATH, mode,
- ReturnImmediate([=](auto in __unused, auto out) {
- SET_OUT_HEADER_LEN(out, create);
- out->body.create.entry.attr.mode = mode;
- out->body.create.entry.nodeid = ino;
- out->body.create.entry.entry_valid = UINT64_MAX;
- out->body.create.entry.attr_valid = UINT64_MAX;
- }));
-
- fd = socket(AF_UNIX, SOCK_STREAM, 0);
- ASSERT_LE(0, fd) << strerror(errno);
- sa.sun_family = AF_UNIX;
- strlcpy(sa.sun_path, FULLPATH, sizeof(sa.sun_path));
- ASSERT_EQ(0, bind(fd, (struct sockaddr*)&sa, sizeof(sa)))
- << strerror(errno);
}
/*
Modified: projects/fuse2/tests/sys/fs/fusefs/fifo.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/fifo.cc Thu May 9 14:06:24 2019 (r347394)
+++ projects/fuse2/tests/sys/fs/fusefs/fifo.cc Thu May 9 16:25:01 2019 (r347395)
@@ -159,17 +159,18 @@ TEST_F(Socket, read_write)
EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT)));
EXPECT_CALL(*m_mock, process(
ResultOf([=](auto in) {
- return (in->header.opcode == FUSE_CREATE);
+ return (in->header.opcode == FUSE_MKNOD);
}, Eq(true)),
_)
).InSequence(seq)
.WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto out) {
- SET_OUT_HEADER_LEN(out, create);
- out->body.create.entry.attr.mode = mode;
- out->body.create.entry.nodeid = ino;
- out->body.create.entry.entry_valid = UINT64_MAX;
- out->body.create.entry.attr_valid = UINT64_MAX;
+ SET_OUT_HEADER_LEN(out, entry);
+ out->body.entry.attr.mode = mode;
+ out->body.entry.nodeid = ino;
+ out->body.entry.entry_valid = UINT64_MAX;
+ out->body.entry.attr_valid = UINT64_MAX;
})));
+
EXPECT_LOOKUP(1, RELPATH)
.InSequence(seq)
.WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto out) {
Modified: projects/fuse2/tests/sys/fs/fusefs/mknod.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/mknod.cc Thu May 9 14:06:24 2019 (r347394)
+++ projects/fuse2/tests/sys/fs/fusefs/mknod.cc Thu May 9 16:25:01 2019 (r347395)
@@ -30,6 +30,8 @@
extern "C" {
#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
}
#include "mockfs.hh"
@@ -135,6 +137,28 @@ TEST_F(Mknod, fifo)
dev_t rdev = VNOVAL; /* Fifos don't have device numbers */
expect_mknod(mode, rdev);
EXPECT_EQ(0, mkfifo(FULLPATH, mode)) << strerror(errno);
+}
+
+/*
+ * Create a unix-domain socket.
+ *
+ * This test case doesn't actually need root privileges.
+ */
+TEST_F(Mknod, socket)
+{
+ mode_t mode = S_IFSOCK | 0755;
+ struct sockaddr_un sa;
+ int fd;
+ dev_t rdev = -1; /* Really it's a don't care */
+
+ expect_mknod(mode, rdev);
+
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ ASSERT_LE(0, fd) << strerror(errno);
+ sa.sun_family = AF_UNIX;
+ strlcpy(sa.sun_path, FULLPATH, sizeof(sa.sun_path));
+ ASSERT_EQ(0, bind(fd, (struct sockaddr*)&sa, sizeof(sa)))
+ << strerror(errno);
}
/*
More information about the svn-src-projects
mailing list