int r = cfuse->client->ll_read(fh, off, size, &bl);
if (r >= 0) {
vector<iovec> iov;
+ size_t len;
+ struct fuse_bufvec *bufv;
+
bl.prepare_iov(&iov);
+ len = sizeof(struct fuse_bufvec) + sizeof(struct fuse_buf) * (iov.size() - 1);
+ bufv = (struct fuse_bufvec *)calloc(1, len);
+ if (bufv) {
+ int i = 0;
+ bufv->count = iov.size();
+ for (auto &v: iov) {
+ bufv->buf[i].mem = v.iov_base;
+ bufv->buf[i++].size = v.iov_len;
+ }
+ fuse_reply_data(req, bufv, FUSE_BUF_SPLICE_MOVE);
+ free(bufv);
+ return;
+ }
iov.insert(iov.begin(), {0}); // the first one is reserved for fuse_out_header
fuse_reply_iov(req, &iov[0], iov.size());
} else
fuse_apply_conn_info_opts(cfuse->conn_opts, conn);
#endif
+ if(conn->capable & FUSE_CAP_SPLICE_MOVE)
+ conn->want |= FUSE_CAP_SPLICE_MOVE;
+
#if !defined(__APPLE__)
if (!client->fuse_default_permissions && client->ll_handle_umask()) {
// apply umask in userspace if posix acl is enabled
// set up fuse argc/argv
int newargc = 0;
- const char **newargv = (const char **) malloc((argc + 11) * sizeof(char *));
+ const char **newargv = (const char **) malloc((argc + 17) * sizeof(char *));
if(!newargv)
return ENOMEM;
"fuse_max_write");
auto fuse_atomic_o_trunc = client->cct->_conf.get_val<bool>(
"fuse_atomic_o_trunc");
+ auto fuse_splice_read = client->cct->_conf.get_val<bool>(
+ "fuse_splice_read");
+ auto fuse_splice_write = client->cct->_conf.get_val<bool>(
+ "fuse_splice_write");
+ auto fuse_splice_move = client->cct->_conf.get_val<bool>(
+ "fuse_splice_move");
auto fuse_debug = client->cct->_conf.get_val<bool>(
"fuse_debug");
newargv[newargc++] = "-o";
newargv[newargc++] = "atomic_o_trunc";
}
+ if (fuse_splice_read) {
+ newargv[newargc++] = "-o";
+ newargv[newargc++] = "splice_read";
+ }
+ if (fuse_splice_write) {
+ newargv[newargc++] = "-o";
+ newargv[newargc++] = "splice_write";
+ }
+ if (fuse_splice_move) {
+ newargv[newargc++] = "-o";
+ newargv[newargc++] = "splice_move";
+ }
#endif
if (fuse_debug)
newargv[newargc++] = "-d";
.set_description("pass default_permisions to FUSE on mount")
.set_flag(Option::FLAG_STARTUP),
+ Option("fuse_splice_read", Option::TYPE_BOOL, Option::LEVEL_ADVANCED)
+ .set_default(true)
+ .set_description("enable splice read to reduce the memory copies"),
+
+ Option("fuse_splice_write", Option::TYPE_BOOL, Option::LEVEL_ADVANCED)
+ .set_default(true)
+ .set_description("enable splice write to reduce the memory copies"),
+
+ Option("fuse_splice_move", Option::TYPE_BOOL, Option::LEVEL_ADVANCED)
+ .set_default(true)
+ .set_description("enable splice move to reduce the memory copies"),
+
Option("fuse_big_writes", Option::TYPE_BOOL, Option::LEVEL_ADVANCED)
.set_default(true)
.set_description("big_writes is deprecated in libfuse 3.0.0"),