summaryrefslogtreecommitdiffstats
path: root/src/client/fuse_ll.cc
diff options
context:
space:
mode:
authorXiubo Li <xiubli@redhat.com>2020-04-30 09:53:26 +0200
committerXiubo Li <xiubli@redhat.com>2020-07-08 09:59:07 +0200
commit3e09f71b7f6f0c5ce2c714d1c3e71a130de9e5e2 (patch)
tree5a7a47b2adabad5a8086dbf78eafbb65b7f51de1 /src/client/fuse_ll.cc
parentceph-fuse: add connection args parsing support for libfuse > 3.0 (diff)
downloadceph-3e09f71b7f6f0c5ce2c714d1c3e71a130de9e5e2.tar.xz
ceph-3e09f71b7f6f0c5ce2c714d1c3e71a130de9e5e2.zip
ceph-fuse: add splice read/write support to reduce the memory copy
Fixes: https://tracker.ceph.com/issues/45267 Signed-off-by: Xiubo Li <xiubli@redhat.com>
Diffstat (limited to 'src/client/fuse_ll.cc')
-rw-r--r--src/client/fuse_ll.cc39
1 files changed, 38 insertions, 1 deletions
diff --git a/src/client/fuse_ll.cc b/src/client/fuse_ll.cc
index 7cec8d70b9b..82c152ad56f 100644
--- a/src/client/fuse_ll.cc
+++ b/src/client/fuse_ll.cc
@@ -615,7 +615,23 @@ static void fuse_ll_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
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
@@ -994,6 +1010,9 @@ static void do_init(void *data, fuse_conn_info *conn)
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
@@ -1139,7 +1158,7 @@ int CephFuse::Handle::init(int argc, const char *argv[])
// 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;
@@ -1158,6 +1177,12 @@ int CephFuse::Handle::init(int argc, const char *argv[])
"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");
@@ -1186,6 +1211,18 @@ int CephFuse::Handle::init(int argc, const char *argv[])
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";