Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F131575629
D27770.id81155.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D27770.id81155.diff
View Options
Index: sys/fs/fuse/fuse_device.c
===================================================================
--- sys/fs/fuse/fuse_device.c
+++ sys/fs/fuse/fuse_device.c
@@ -276,6 +276,7 @@
return (revents);
}
+SDT_PROBE_DEFINE1(fusefs, , device, read_tick, "struct fuse_ticket*");
/*
* fuse_device_read hangs on the queue of VFS messages.
* When it's notified that there is a new one, it picks that and
@@ -287,9 +288,8 @@
int err;
struct fuse_data *data;
struct fuse_ticket *tick;
- void *buf[] = {NULL, NULL, NULL};
- int buflen[3];
- int i;
+ void *buf;
+ int buflen;
SDT_PROBE2(fusefs, , device, trace, 1, "fuse device read");
@@ -332,6 +332,7 @@
goto again;
}
fuse_lck_mtx_unlock(data->ms_mtx);
+ SDT_PROBE1(fusefs, , device, read_tick, tick);
if (fdata_get_dead(data)) {
/*
@@ -352,46 +353,27 @@
SDT_PROBE2(fusefs, , device, trace, 1,
"fuse device read message successfully");
- KASSERT(tick->tk_ms_bufdata || tick->tk_ms_bufsize == 0,
- ("non-null buf pointer with positive size"));
-
- switch (tick->tk_ms_type) {
- case FT_M_FIOV:
- buf[0] = tick->tk_ms_fiov.base;
- buflen[0] = tick->tk_ms_fiov.len;
- break;
- case FT_M_BUF:
- buf[0] = tick->tk_ms_fiov.base;
- buflen[0] = tick->tk_ms_fiov.len;
- buf[1] = tick->tk_ms_bufdata;
- buflen[1] = tick->tk_ms_bufsize;
- break;
- default:
- panic("unknown message type for fuse_ticket %p", tick);
- }
+ buf = tick->tk_ms_fiov.base;
+ buflen = tick->tk_ms_fiov.len;
- for (i = 0; buf[i]; i++) {
- /*
- * Why not ban mercilessly stupid daemons who can't keep up
- * with us? (There is no much use of a partial read here...)
- */
- /*
- * XXX note that in such cases Linux FUSE throws EIO at the
- * syscall invoker and stands back to the message queue. The
- * rationale should be made clear (and possibly adopt that
- * behaviour). Keeping the current scheme at least makes
- * fallacy as loud as possible...
- */
- if (uio->uio_resid < buflen[i]) {
- fdata_set_dead(data);
- SDT_PROBE2(fusefs, , device, trace, 2,
- "daemon is stupid, kick it off...");
- err = ENODEV;
- break;
- }
- err = uiomove(buf[i], buflen[i], uio);
- if (err)
- break;
+ /*
+ * Why not ban mercilessly stupid daemons who can't keep up
+ * with us? (There is no much use of a partial read here...)
+ */
+ /*
+ * XXX note that in such cases Linux FUSE throws EIO at the
+ * syscall invoker and stands back to the message queue. The
+ * rationale should be made clear (and possibly adopt that
+ * behaviour). Keeping the current scheme at least makes
+ * fallacy as loud as possible...
+ */
+ if (uio->uio_resid < buflen) {
+ fdata_set_dead(data);
+ SDT_PROBE2(fusefs, , device, trace, 2,
+ "daemon is stupid, kick it off...");
+ err = ENODEV;
+ } else {
+ err = uiomove(buf, buflen, uio);
}
FUSE_ASSERT_MS_DONE(tick);
Index: sys/fs/fuse/fuse_ipc.h
===================================================================
--- sys/fs/fuse/fuse_ipc.h
+++ sys/fs/fuse/fuse_ipc.h
@@ -123,17 +123,10 @@
/* fields for initiating an upgoing message */
struct fuse_iov tk_ms_fiov;
- void *tk_ms_bufdata;
- size_t tk_ms_bufsize;
- enum { FT_M_FIOV, FT_M_BUF } tk_ms_type;
STAILQ_ENTRY(fuse_ticket) tk_ms_link;
/* fields for handling answers coming from userspace */
struct fuse_iov tk_aw_fiov;
- void *tk_aw_bufdata;
- size_t tk_aw_bufsize;
- enum { FT_A_FIOV, FT_A_BUF } tk_aw_type;
-
struct fuse_out_header tk_aw_ohead;
int tk_aw_errno;
struct mtx tk_aw_mtx;
Index: sys/fs/fuse/fuse_ipc.c
===================================================================
--- sys/fs/fuse/fuse_ipc.c
+++ sys/fs/fuse/fuse_ipc.c
@@ -356,11 +356,9 @@
bzero(ftick, sizeof(struct fuse_ticket));
fiov_init(&ftick->tk_ms_fiov, sizeof(struct fuse_in_header));
- ftick->tk_ms_type = FT_M_FIOV;
mtx_init(&ftick->tk_aw_mtx, "fuse answer delivery mutex", NULL, MTX_DEF);
fiov_init(&ftick->tk_aw_fiov, 0);
- ftick->tk_aw_type = FT_A_FIOV;
return 0;
}
@@ -395,18 +393,11 @@
FUSE_ASSERT_AW_DONE(ftick);
fiov_refresh(&ftick->tk_ms_fiov);
- ftick->tk_ms_bufdata = NULL;
- ftick->tk_ms_bufsize = 0;
- ftick->tk_ms_type = FT_M_FIOV;
bzero(&ftick->tk_aw_ohead, sizeof(struct fuse_out_header));
fiov_refresh(&ftick->tk_aw_fiov);
ftick->tk_aw_errno = 0;
- ftick->tk_aw_bufdata = NULL;
- ftick->tk_aw_bufsize = 0;
- ftick->tk_aw_type = FT_A_FIOV;
-
ftick->tk_flag = 0;
}
@@ -417,17 +408,9 @@
FUSE_ASSERT_MS_DONE(ftick);
FUSE_ASSERT_AW_DONE(ftick);
- ftick->tk_ms_bufdata = NULL;
- ftick->tk_ms_bufsize = 0;
- ftick->tk_ms_type = FT_M_FIOV;
-
bzero(&ftick->tk_aw_ohead, sizeof(struct fuse_out_header));
ftick->tk_aw_errno = 0;
- ftick->tk_aw_bufdata = NULL;
- ftick->tk_aw_bufsize = 0;
- ftick->tk_aw_type = FT_A_FIOV;
-
ftick->tk_flag = 0;
}
@@ -546,20 +529,8 @@
size_t len = uio_resid(uio);
if (len) {
- switch (ftick->tk_aw_type) {
- case FT_A_FIOV:
- fiov_adjust(fticket_resp(ftick), len);
- err = uiomove(fticket_resp(ftick)->base, len, uio);
- break;
-
- case FT_A_BUF:
- ftick->tk_aw_bufsize = len;
- err = uiomove(ftick->tk_aw_bufdata, len, uio);
- break;
-
- default:
- panic("FUSE: unknown answer type for ticket %p", ftick);
- }
+ fiov_adjust(fticket_resp(ftick), len);
+ err = uiomove(fticket_resp(ftick)->base, len, uio);
}
return err;
}
Index: tests/sys/fs/fusefs/bmap.cc
===================================================================
--- tests/sys/fs/fusefs/bmap.cc
+++ tests/sys/fs/fusefs/bmap.cc
@@ -83,9 +83,9 @@
TEST_F(Bmap, bmap)
{
struct fiobmap2_arg arg;
- const off_t filesize = 1 << 20;
+ const off_t filesize = 1 << 30;
const ino_t ino = 42;
- int64_t lbn = 10;
+ int64_t lbn = 100;
int64_t pbn = 12345;
int fd;
@@ -112,7 +112,7 @@
TEST_F(Bmap, default_)
{
struct fiobmap2_arg arg;
- const off_t filesize = 1 << 20;
+ const off_t filesize = 1 << 30;
const ino_t ino = 42;
int64_t lbn;
int fd;
Index: tests/sys/fs/fusefs/mockfs.hh
===================================================================
--- tests/sys/fs/fusefs/mockfs.hh
+++ tests/sys/fs/fusefs/mockfs.hh
@@ -72,6 +72,14 @@
extern int verbosity;
+/*
+ * The maximum that a test case can set max_write, limited by the buffer
+ * supplied when reading from /dev/fuse. This limitation is imposed by
+ * fusefs-libs, but not by the FUSE protocol.
+ */
+const uint32_t max_max_write = 0x20000;
+
+
/* This struct isn't defined by fuse_kernel.h or libfuse, but it should be */
struct fuse_create_out {
struct fuse_entry_out entry;
@@ -138,8 +146,17 @@
union fuse_payloads_in {
fuse_access_in access;
fuse_bmap_in bmap;
- /* value is from fuse_kern_chan.c in fusefs-libs */
- uint8_t bytes[0x21000 - sizeof(struct fuse_in_header)];
+ /*
+ * In fusefs-libs 3.4.2 and below the buffer size is fixed at 0x21000
+ * minus the header sizes. fusefs-libs 3.4.3 (and FUSE Protocol 7.29)
+ * add a FUSE_MAX_PAGES option that allows it to be greater.
+ *
+ * See fuse_kern_chan.c in fusefs-libs 2.9.9 and below, or
+ * FUSE_DEFAULT_MAX_PAGES_PER_REQ in fusefs-libs 3.4.3 and above.
+ */
+ uint8_t bytes[
+ max_max_write + 0x1000 - sizeof(struct fuse_in_header)
+ ];
fuse_create_in create;
fuse_flush_in flush;
fuse_fsync_in fsync;
Index: tests/sys/fs/fusefs/mockfs.cc
===================================================================
--- tests/sys/fs/fusefs/mockfs.cc
+++ tests/sys/fs/fusefs/mockfs.cc
@@ -365,7 +365,7 @@
m_daemon_id = NULL;
m_kernel_minor_version = kernel_minor_version;
m_maxreadahead = max_readahead;
- m_maxwrite = max_write;
+ m_maxwrite = MIN(max_write, max_max_write);
m_nready = -1;
m_pm = pm;
m_time_gran = time_gran;
Index: tests/sys/fs/fusefs/utils.hh
===================================================================
--- tests/sys/fs/fusefs/utils.hh
+++ tests/sys/fs/fusefs/utils.hh
@@ -55,7 +55,6 @@
bool is_unsafe_aio_enabled(void);
extern const uint32_t libfuse_max_write;
-extern const uint32_t default_max_write;
class FuseTest : public ::testing::Test {
protected:
uint32_t m_maxreadahead;
@@ -80,7 +79,7 @@
FuseTest():
m_maxreadahead(0),
- m_maxwrite(default_max_write),
+ m_maxwrite(0),
m_init_flags(0),
m_allow_other(false),
m_default_permissions(false),
Index: tests/sys/fs/fusefs/utils.cc
===================================================================
--- tests/sys/fs/fusefs/utils.cc
+++ tests/sys/fs/fusefs/utils.cc
@@ -59,13 +59,6 @@
*/
const uint32_t libfuse_max_write = 32 * getpagesize() + 0x1000 - 4096;
-/*
- * Set the default max_write to a distinct value from MAXPHYS to catch bugs
- * that confuse the two.
- */
-const uint32_t default_max_write = MIN(libfuse_max_write, MAXPHYS / 2);
-
-
/* Check that fusefs(4) is accessible and the current user can mount(2) */
void check_environment()
{
@@ -156,6 +149,12 @@
ASSERT_EQ(0, sysctlbyname(maxphys_node, &val, &size, NULL, 0))
<< strerror(errno);
m_maxphys = val;
+ /*
+ * Set the default max_write to a distinct value from MAXPHYS to catch
+ * bugs that confuse the two.
+ */
+ if (m_maxwrite == 0)
+ m_maxwrite = MIN(libfuse_max_write, (uint32_t)m_maxphys / 2);
try {
m_mock = new MockFS(m_maxreadahead, m_allow_other,
Index: tests/sys/fs/fusefs/write.cc
===================================================================
--- tests/sys/fs/fusefs/write.cc
+++ tests/sys/fs/fusefs/write.cc
@@ -166,6 +166,7 @@
public:
virtual void SetUp() {
m_async = true;
+ m_maxwrite = 65536;
WriteBack::SetUp();
}
};
@@ -194,6 +195,19 @@
}
};
+/* Tests relating to the server's max_write property */
+class WriteMaxWrite: public Write {
+public:
+virtual void SetUp() {
+ /*
+ * For this test, m_maxwrite must be less than either m_maxbcachebuf or
+ * maxphys.
+ */
+ m_maxwrite = 32768;
+ Write::SetUp();
+}
+};
+
void sigxfsz_handler(int __unused sig) {
Write::s_sigxfsz = 1;
}
@@ -643,7 +657,7 @@
}
/* fuse(4) should not issue writes of greater size than the daemon requests */
-TEST_F(Write, write_large)
+TEST_F(WriteMaxWrite, write)
{
const char FULLPATH[] = "mountpoint/some_file.txt";
const char RELPATH[] = "some_file.txt";
@@ -653,6 +667,8 @@
ssize_t halfbufsize, bufsize;
halfbufsize = m_mock->m_maxwrite;
+ if (halfbufsize >= m_maxbcachebuf || halfbufsize >= m_maxphys)
+ GTEST_SKIP() << "Must lower m_maxwrite for this test";
bufsize = halfbufsize * 2;
contents = (int*)malloc(bufsize);
ASSERT_NE(nullptr, contents);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Oct 10, 10:21 AM (20 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23527635
Default Alt Text
D27770.id81155.diff (10 KB)
Attached To
Mode
D27770: fusefs: delete some dead code
Attached
Detach File
Event Timeline
Log In to Comment