summaryrefslogtreecommitdiff
path: root/netfs/fuse/fuseFiles.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'netfs/fuse/fuseFiles.cpp')
-rw-r--r--netfs/fuse/fuseFiles.cpp41
1 files changed, 35 insertions, 6 deletions
diff --git a/netfs/fuse/fuseFiles.cpp b/netfs/fuse/fuseFiles.cpp
index c1709cd..c50dcf1 100644
--- a/netfs/fuse/fuseFiles.cpp
+++ b/netfs/fuse/fuseFiles.cpp
@@ -1,10 +1,12 @@
#include "fuseFiles.h"
#include "fuseApp.impl.h"
#include "lockHelpers.h"
+#include <Ice/BuiltinSequences.h>
#include <cstring>
#include <entCache.h>
#include <mutex>
#include <numeric.h>
+#include <numeric>
namespace NetFS {
FuseApp::OpenFile::WriteState::WriteState() : future(promise.get_future().share()) { }
@@ -167,20 +169,47 @@ namespace NetFS {
FuseApp::read(const char *, char * buf, size_t s, off_t o, struct fuse_file_info * fi)
{
try {
- auto cpy = [buf](const auto && data) -> int {
- std::copy(data.begin(), data.end(), buf);
+ struct bgOp {
+ bgOp(int o, std::future<Ice::ByteSeq> r) : offset {o}, response {std::move(r)} { }
+ int offset;
+ std::future<Ice::ByteSeq> response;
+ };
+ auto cpy = [buf](off_t blockOffset, const auto && data) -> int {
+ std::copy(data.begin(), data.end(), buf + blockOffset);
return safe {data.size()};
};
auto of = getProxy<OpenFilePtr>(fi->fh);
auto remote = of->remote;
+ auto blockSizes = of->blockSizes(s);
if (fcr->Async) {
- auto p = waitOnWriteRangeAndThen<std::future<Buffer>>(s, o, of, [o, s, &remote](const auto &) {
- return remote->readAsync(o, safe {s});
+ std::vector<bgOp> ops;
+ blockSizeIterate(
+ blockSizes, [&ops, &o, &of, &remote, blockOffset = 0U](safe<size_t> blockSize) mutable {
+ ops.emplace_back(blockOffset,
+ waitOnWriteRangeAndThen<std::future<Buffer>>(
+ blockSize, o, of, [o, blockSize, &remote](const auto &) {
+ return remote->readAsync(o, blockSize);
+ }));
+ o += blockSize;
+ blockOffset += blockSize;
+ });
+ return std::accumulate(ops.begin(), ops.end(), 0, [cpy](auto && total, auto & op) {
+ return total += cpy(op.offset, op.response.get());
+ });
+ }
+ else if (of->bodyMaxSize < s) {
+ std::vector<bgOp> ops;
+ blockSizeIterate(blockSizes, [&ops, &o, &remote, blockOffset = 0U](safe<size_t> blockSize) mutable {
+ ops.emplace_back(blockOffset, remote->readAsync(o, blockSize));
+ o += blockSize;
+ blockOffset += blockSize;
+ });
+ return std::accumulate(ops.begin(), ops.end(), 0, [cpy](auto && total, auto & op) {
+ return total += cpy(op.offset, op.response.get());
});
- return cpy(p.get());
}
else {
- return cpy(remote->read(o, safe {s}));
+ return cpy(0, remote->read(o, safe {s}));
}
}
catch (SystemError & e) {