]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
ceph-fuse: add splice read/write support to reduce the memory copy
authorXiubo Li <xiubli@redhat.com>
Thu, 30 Apr 2020 07:53:26 +0000 (03:53 -0400)
committerXiubo Li <xiubli@redhat.com>
Wed, 8 Jul 2020 07:59:07 +0000 (03:59 -0400)
Fixes: https://tracker.ceph.com/issues/45267
Signed-off-by: Xiubo Li <xiubli@redhat.com>
src/client/fuse_ll.cc
src/common/options.cc

index 7cec8d70b9be28b325d9644e4b8fb3968ef5538a..82c152ad56fd80eec891783482555078ad654cd7 100644 (file)
@@ -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";
index 9def1ca6ecc696ea2b3a184990ce77201f1379e2..52606d085374998d4eeb67b811a39268e1ce8b29 100644 (file)
@@ -8555,6 +8555,18 @@ std::vector<Option> get_mds_client_options() {
     .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"),