diff options
Diffstat (limited to 'netfs/fuse/fuseFiles.cpp')
| -rw-r--r-- | netfs/fuse/fuseFiles.cpp | 41 | 
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) {  | 
