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.cpp326
1 files changed, 158 insertions, 168 deletions
diff --git a/netfs/fuse/fuseFiles.cpp b/netfs/fuse/fuseFiles.cpp
index 149e8b3..a3c9dd4 100644
--- a/netfs/fuse/fuseFiles.cpp
+++ b/netfs/fuse/fuseFiles.cpp
@@ -1,12 +1,10 @@
#include "fuseFiles.h"
-#include "fuseApp.impl.h"
+#include "fuseApp.impl.h" // IWYU pragma: keep - getProxy definition
#include "lockHelpers.h"
#include <Ice/BuiltinSequences.h>
#include <algorithm>
-#include <atomic>
#include <cstring>
#include <entCache.h>
-#include <exception>
#include <functional>
#include <future>
#include <iterator>
@@ -20,8 +18,8 @@
namespace NetFS {
FuseApp::OpenFile::WriteState::WriteState() : future(promise.get_future().share()) { }
- FuseApp::OpenFile::OpenFile(FilePrxPtr r, std::string p, int f, size_t mms) :
- remote(std::move(r)), path(std::move(p)), flags(f), bodyMaxSize(mms - 1024)
+ FuseApp::OpenFile::OpenFile(FilePrxPtr remotePrx, std::string remotePath, int openFlags, size_t messageMaxSize) :
+ remote(std::move(remotePrx)), path(std::move(remotePath)), flags(openFlags), bodyMaxSize(messageMaxSize - 1024)
{
}
@@ -39,35 +37,35 @@ namespace NetFS {
SharedLock(mutex);
return bg;
}();
- for (const auto & w : cbg) {
- w.second->future.get();
+ for (const auto & operation : cbg) {
+ operation.second->future.get();
}
}
void
FuseApp::OpenFile::flush()
{
- auto first = [this]() {
+ auto getFirstBackgroundOp = [this]() {
SharedLock(mutex);
return bg.empty() ? nullptr : bg.begin()->second;
};
- while (auto w = first()) {
- w->future.get();
+ while (auto operation = getFirstBackgroundOp()) {
+ operation->future.get();
}
}
FuseApp::OpenFile::BGs::interval_type
- FuseApp::OpenFile::range(off_t o, size_t s)
+ FuseApp::OpenFile::range(off_t offset, size_t size)
{
- return OpenFile::BGs::interval_type::right_open(safe {o}, safe {o} + s);
+ return OpenFile::BGs::interval_type::right_open(safe {offset}, safe {offset} + size);
}
int
- FuseApp::open(const char * p, struct fuse_file_info * fi)
+ FuseApp::open(const char * path, struct fuse_file_info * fileInfo)
{
try {
- auto remote = volume->open(reqEnv(), p, fi->flags);
- setProxy<OpenFilePtr>(fi->fh, remote, p, fi->flags, combinedSettings.MessageSizeMax);
+ auto remote = volume->open(reqEnv(), path, fileInfo->flags);
+ setProxy<OpenFilePtr>(fileInfo->fh, remote, path, fileInfo->flags, combinedSettings.messageSizeMax);
return 0;
}
catch (SystemError & e) {
@@ -76,11 +74,11 @@ namespace NetFS {
}
int
- FuseApp::create(const char * p, mode_t m, struct fuse_file_info * fi)
+ FuseApp::create(const char * path, mode_t mode, struct fuse_file_info * fileInfo)
{
try {
- auto remote = volume->create(reqEnv(), p, fi->flags, safe {m});
- setProxy<OpenFilePtr>(fi->fh, remote, p, fi->flags, combinedSettings.MessageSizeMax);
+ auto remote = volume->create(reqEnv(), path, fileInfo->flags, safe {mode});
+ setProxy<OpenFilePtr>(fileInfo->fh, remote, path, fileInfo->flags, combinedSettings.messageSizeMax);
return 0;
}
catch (SystemError & e) {
@@ -89,34 +87,34 @@ namespace NetFS {
}
int
- FuseApp::release(const char *, struct fuse_file_info * fi)
+ FuseApp::release(const char *, struct fuse_file_info * fileInfo)
{
try {
- auto of = getProxy<OpenFilePtr>(fi->fh);
- auto remote = of->remote;
+ auto openFile = getProxy<OpenFilePtr>(fileInfo->fh);
+ auto remote = openFile->remote;
try {
- of->flush();
- clearProxy<OpenFilePtr>(fi->fh);
+ openFile->flush();
+ clearProxy<OpenFilePtr>(fileInfo->fh);
remote->close();
}
catch (SystemError & e) {
- clearProxy<OpenFilePtr>(fi->fh);
+ clearProxy<OpenFilePtr>(fileInfo->fh);
remote->close();
throw;
}
return 0;
}
catch (SystemError & e) {
- clearProxy<OpenFilePtr>(fi->fh);
+ clearProxy<OpenFilePtr>(fileInfo->fh);
return -e.syserrno;
}
}
int
- FuseApp::flush(const char *, struct fuse_file_info * fi)
+ FuseApp::flush(const char *, struct fuse_file_info * fileInfo)
{
try {
- getProxy<OpenFilePtr>(fi->fh)->flush();
+ getProxy<OpenFilePtr>(fileInfo->fh)->flush();
return 0;
}
catch (SystemError & e) {
@@ -124,68 +122,67 @@ namespace NetFS {
}
}
- template<typename F>
+ template<typename Callback>
inline auto
- FuseApp::waitOnWriteRangeAndThen(size_t s, off_t o, const OpenFilePtr & of, const F & f)
+ FuseApp::waitOnWriteRangeAndThen(size_t size, off_t offset, const OpenFilePtr & openFile, const Callback & callback)
{
- const auto key = OpenFile::range(o, s);
+ const auto key = OpenFile::range(offset, size);
while (true) {
- std::unique_lock lock(of->mutex);
+ std::unique_lock lock(openFile->mutex);
// Acquire operations to wait for
- const auto R = of->bg.equal_range(key);
- if (R.first == R.second) {
+ const auto pendingRange = openFile->bg.equal_range(key);
+ if (pendingRange.first == pendingRange.second) {
// Perform operation
- return f(key);
+ return callback(key);
}
- else {
- const auto overlap = [R]() {
- std::vector<std::shared_future<void>> out;
- out.reserve(safe<ptrdiff_t> {std::distance(R.first, R.second)});
- std::transform(R.first, R.second, std::back_inserter(out), [](auto && i) {
- return i.second->future;
- });
- return out;
- }();
- // Wait for them whilst unlocked
- lock.release()->unlock();
- try {
- std::for_each(overlap.begin(), overlap.end(), [](auto && r) {
- r.get();
- });
- }
- catch (const SystemError &) {
- throw;
- }
- catch (...) {
- throw SystemError {ECOMM};
- }
- // Cause this thread to yield so the callback can lock mutex
- usleep(0);
+ const auto overlap = [pendingRange]() {
+ std::vector<std::shared_future<void>> out;
+ out.reserve(safe<ptrdiff_t> {std::distance(pendingRange.first, pendingRange.second)});
+ std::transform(pendingRange.first, pendingRange.second, std::back_inserter(out), [](auto && operation) {
+ return operation.second->future;
+ });
+ return out;
+ }();
+ // Wait for them whilst unlocked
+ lock.release()->unlock();
+ try {
+ std::for_each(overlap.begin(), overlap.end(), [](auto && operationFuture) {
+ operationFuture.get();
+ });
}
+ catch (const SystemError &) {
+ throw;
+ }
+ catch (...) {
+ throw SystemError {ECOMM};
+ }
+ // Cause this thread to yield so the callback can lock mutex
+ usleep(0);
}
}
- template<typename CB>
- void
- blockSizeIterate(FuseApp::OpenFile::BlockSizes bs, CB && cb)
- {
- if (bs.size1) {
- cb(bs.size1);
- }
- while (bs.N--) {
- cb(bs.sizeN);
+ namespace {
+ void
+ blockSizeIterate(FuseApp::OpenFile::BlockSizes blockSizes, auto && callback)
+ {
+ if (blockSizes.size1) {
+ callback(blockSizes.size1);
+ }
+ while (blockSizes.count--) {
+ callback(blockSizes.sizeN);
+ }
}
- }
- template<typename T>
- auto
- operator++(std::vector<std::unique_ptr<T>> & v)
- {
- return v.emplace_back(std::make_unique<T>()).get();
+ template<typename T>
+ auto
+ appendNewDefault(std::vector<std::unique_ptr<T>> & container)
+ {
+ return container.emplace_back(std::make_unique<T>()).get();
+ }
}
int
- FuseApp::read(const char *, char * buf, size_t s, off_t o, struct fuse_file_info * fi)
+ FuseApp::read(const char *, char * buf, size_t size, off_t offset, struct fuse_file_info * fileInfo)
{
try {
using BackgroundOps = std::vector<std::unique_ptr<std::promise<int>>>;
@@ -195,58 +192,57 @@ namespace NetFS {
return safe {data.size()};
};
auto collateTotal = [](auto && ops) {
- return std::accumulate(ops.begin(), ops.end(), 0, [](auto && total, auto & op) {
- return total += op->get_future().get();
+ return std::accumulate(ops.begin(), ops.end(), 0, [](auto && total, auto & operation) {
+ return total += operation->get_future().get();
});
};
- auto of = getProxy<OpenFilePtr>(fi->fh);
- auto remote = of->remote;
- auto blockSizes = of->blockSizes(s);
+ auto openFile = getProxy<OpenFilePtr>(fileInfo->fh);
+ auto remote = openFile->remote;
+ auto blockSizes = openFile->blockSizes(size);
if (fcr->Async) {
BackgroundFuncs fs;
BackgroundOps ops;
blockSizeIterate(blockSizes,
- [&ops, &fs, &o, &of, &remote, blockOffset = 0U, &cpy](safe<size_t> blockSize) mutable {
- const auto p = ++ops;
- fs.push_back(waitOnWriteRangeAndThen(
- blockSize, o, of, [p, o, blockOffset, blockSize, &remote, &cpy](const auto &) {
+ [&ops, &fs, &offset, &openFile, &remote, blockOffset = 0U, &cpy](
+ safe<size_t> blockSize) mutable {
+ const auto p = appendNewDefault(ops);
+ fs.push_back(waitOnWriteRangeAndThen(blockSize, offset, openFile,
+ [p, offset, blockOffset, blockSize, &remote, &cpy](const auto &) {
return remote->readAsync(
- o, blockSize,
+ offset, blockSize,
[cpy, p, blockOffset](auto && resultBuf) {
p->set_value(
cpy(blockOffset, std::forward<Ice::ByteSeq>(resultBuf)));
},
- [p](auto ex) {
- p->set_exception(ex);
+ [p](auto error) {
+ p->set_exception(std::move(error));
});
}));
- o += blockSize;
+ offset += blockSize;
blockOffset += blockSize;
});
return collateTotal(ops);
}
- else if (of->bodyMaxSize < s) {
+ if (openFile->bodyMaxSize < size) {
BackgroundFuncs fs;
BackgroundOps ops;
- blockSizeIterate(
- blockSizes, [&o, &remote, blockOffset = 0U, &ops, &fs, &cpy](safe<size_t> blockSize) mutable {
- const auto p = ++ops;
+ blockSizeIterate(blockSizes,
+ [&offset, &remote, blockOffset = 0U, &ops, &fs, &cpy](safe<size_t> blockSize) mutable {
+ const auto p = appendNewDefault(ops);
fs.push_back(remote->readAsync(
- o, blockSize,
+ offset, blockSize,
[cpy, p, blockOffset](auto && resultBuf) {
p->set_value(cpy(blockOffset, std::forward<Ice::ByteSeq>(resultBuf)));
},
- [p](auto ex) {
- p->set_exception(ex);
+ [p](auto error) {
+ p->set_exception(std::move(error));
}));
- o += blockSize;
+ offset += blockSize;
blockOffset += blockSize;
});
return collateTotal(ops);
}
- else {
- return cpy(0, remote->read(o, safe {s}));
- }
+ return cpy(0, remote->read(offset, safe {size}));
}
catch (SystemError & e) {
return -e.syserrno;
@@ -254,48 +250,48 @@ namespace NetFS {
}
int
- FuseApp::write(const char *, const char * buf, size_t s, off_t o, struct fuse_file_info * fi)
+ FuseApp::write(const char *, const char * buf, size_t size, off_t offset, struct fuse_file_info * fileInfo)
{
try {
- auto of = getProxy<OpenFilePtr>(fi->fh);
- auto remote = of->remote;
+ auto openFile = getProxy<OpenFilePtr>(fileInfo->fh);
+ auto remote = openFile->remote;
auto bytes = reinterpret_cast<const ::Ice::Byte *>(buf);
if (fcr->Async) {
- blockSizeIterate(of->blockSizes(s), [&bytes, &o, &remote, &of](safe<size_t> blockSize) {
- waitOnWriteRangeAndThen(blockSize, o, of, [o, blockSize, bytes, &of, remote](const auto & key) {
- auto p = std::make_shared<OpenFile::WriteState>();
- of->bg.insert({key, p});
- remote->writeAsync(
- o, blockSize, std::make_pair(bytes, bytes + blockSize),
- [p, of, key]() {
- p->promise.set_value();
- ScopeLock(of->mutex) {
- of->bg.erase(key);
- }
- },
- [p, of](auto e) {
- p->promise.set_exception(e);
- });
- });
- bytes += blockSize;
- o += blockSize;
- });
+ blockSizeIterate(
+ openFile->blockSizes(size), [&bytes, &offset, &remote, &openFile](safe<size_t> blockSize) {
+ waitOnWriteRangeAndThen(blockSize, offset, openFile,
+ [offset, blockSize, bytes, &openFile, remote](const auto & key) {
+ auto p = std::make_shared<OpenFile::WriteState>();
+ openFile->bg.insert({key, p});
+ remote->writeAsync(
+ offset, blockSize, std::make_pair(bytes, bytes + blockSize),
+ [p, openFile, key]() {
+ p->promise.set_value();
+ ScopeLock(openFile->mutex) {
+ openFile->bg.erase(key);
+ }
+ },
+ [p, openFile](auto error) {
+ p->promise.set_exception(std::move(error));
+ });
+ });
+ bytes += blockSize;
+ offset += blockSize;
+ });
}
- else if (of->bodyMaxSize < s) {
+ else if (openFile->bodyMaxSize < size) {
std::vector<std::future<void>> ops;
- blockSizeIterate(of->blockSizes(s), [&ops, &bytes, &o, &remote](safe<size_t> blockSize) {
- ops.emplace_back(remote->writeAsync(o, blockSize, std::make_pair(bytes, bytes + blockSize)));
+ blockSizeIterate(openFile->blockSizes(size), [&ops, &bytes, &offset, &remote](safe<size_t> blockSize) {
+ ops.emplace_back(remote->writeAsync(offset, blockSize, std::make_pair(bytes, bytes + blockSize)));
bytes += blockSize;
- o += blockSize;
- });
- std::for_each(ops.begin(), ops.end(), [](auto && op) {
- op.get();
+ offset += blockSize;
});
+ std::ranges::for_each(ops, &std::future<void>::get);
}
else {
- remote->write(o, safe {s}, std::make_pair(bytes, bytes + s));
+ remote->write(offset, safe {size}, std::make_pair(bytes, bytes + size));
}
- return safe {s};
+ return safe {size};
}
catch (SystemError & e) {
return -e.syserrno;
@@ -306,39 +302,35 @@ namespace NetFS {
FuseApp::OpenFile::blockSizes(size_t total, size_t max) noexcept
{
if (max >= total) { // Simple case, all in remainder block
- return {total, 0, 0};
+ return {.size1 = total, .sizeN = 0, .count = 0};
}
- else if (total % max == 0) { // Simplish case, multiples of max
- return {0, max, total / max};
+ if (total % max == 0) { // Simplish case, multiples of max
+ return {.size1 = 0, .sizeN = max, .count = total / max};
}
- else {
- const auto blocks = (total / max);
- const auto blockSize = (total / (blocks + 1)) + 1;
- const auto batchTotal = blockSize * blocks;
- const auto remainder = total - batchTotal;
+ const auto blocks = (total / max);
+ const auto blockSize = (total / (blocks + 1)) + 1;
+ const auto batchTotal = blockSize * blocks;
+ const auto remainder = total - batchTotal;
- return {remainder, blockSize, blocks};
- }
+ return {.size1 = remainder, .sizeN = blockSize, .count = blocks};
}
size_t
FuseApp::OpenFile::BlockSizes::total() const noexcept
{
- return size1 + (sizeN * N);
+ return size1 + (sizeN * count);
}
ssize_t
- FuseApp::copy_file_range(const char *, struct fuse_file_info * fi_in, off_t offset_in, const char *,
- struct fuse_file_info * fi_out, off_t offset_out, size_t size, int flags)
+ FuseApp::copy_file_range(const char *, struct fuse_file_info * fileInfoIn, off_t offsetIn, const char *,
+ struct fuse_file_info * fileInfoOut, off_t offsetOut, size_t size, int flags)
{
try {
- auto of_in = getProxy<OpenFilePtr>(fi_in->fh);
- auto of_out = getProxy<OpenFilePtr>(fi_out->fh);
- auto remote_in = of_in->remote;
- auto remote_out = of_out->remote;
- of_in->wait();
- of_out->wait();
- return remote_in->copyrange(remote_out, offset_in, offset_out, safe {size}, flags);
+ auto openFileIn = getProxy<OpenFilePtr>(fileInfoIn->fh);
+ auto openFileOut = getProxy<OpenFilePtr>(fileInfoOut->fh);
+ openFileIn->wait();
+ openFileOut->wait();
+ return openFileIn->remote->copyrange(openFileOut->remote, offsetIn, offsetOut, safe {size}, flags);
}
catch (SystemError & e) {
return -e.syserrno;
@@ -346,17 +338,16 @@ namespace NetFS {
}
int
- FuseApp::truncate(const char * p, off_t o, fuse_file_info * fi)
+ FuseApp::truncate(const char * path, off_t offset, fuse_file_info * fileInfo)
{
try {
- if (fi) {
- auto of = getProxy<OpenFilePtr>(fi->fh);
- of->wait();
- auto remote = of->remote;
- remote->ftruncate(o);
+ if (fileInfo) {
+ auto openFile = getProxy<OpenFilePtr>(fileInfo->fh);
+ openFile->wait();
+ openFile->remote->ftruncate(offset);
}
else {
- volume->truncate(reqEnv(), p, o);
+ volume->truncate(reqEnv(), path, offset);
}
return 0;
}
@@ -366,24 +357,23 @@ namespace NetFS {
}
int
- FuseApp::getattr(const char * p, struct stat * s, fuse_file_info * fi)
+ FuseApp::getattr(const char * path, struct stat * stat, fuse_file_info * fileInfo)
{
try {
- if (fi) {
- auto of = getProxy<OpenFilePtr>(fi->fh);
- of->wait();
- auto remote = of->remote;
- *s = converter.convert(remote->fgetattr());
+ if (fileInfo) {
+ auto openFile = getProxy<OpenFilePtr>(fileInfo->fh);
+ openFile->wait();
+ *stat = converter.convert(openFile->remote->fgetattr());
}
else {
- if (auto cacehedStat = statCache.get(std::filesystem::hash_value(p))) {
- *s = *cacehedStat;
+ if (auto cacehedStat = statCache.get(std::filesystem::hash_value(path))) {
+ *stat = *cacehedStat;
}
else {
- *s = converter.convert(volume->getattr(reqEnv(), p));
+ *stat = converter.convert(volume->getattr(reqEnv(), path));
}
}
- return s->st_mode ? 0 : -ENOENT;
+ return stat->st_mode ? 0 : -ENOENT;
}
catch (SystemError & e) {
return -e.syserrno;
@@ -391,10 +381,10 @@ namespace NetFS {
}
int
- FuseApp::unlink(const char * p)
+ FuseApp::unlink(const char * path)
{
try {
- volume->unlink(reqEnv(), p);
+ volume->unlink(reqEnv(), path);
return 0;
}
catch (SystemError & e) {