diff options
Diffstat (limited to 'src/client/fuse_ll.cc')
-rw-r--r-- | src/client/fuse_ll.cc | 39 |
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"; |