From ce5c9502aa374b55ce73bea3eea33645a306e9c4 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 25 Oct 2017 18:05:09 +0100 Subject: Implement background (file) writes --- netfs/fuse/fuseApp.h | 4 ++++ netfs/fuse/fuseFiles.cpp | 53 +++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/netfs/fuse/fuseApp.h b/netfs/fuse/fuseApp.h index a15d150..c37ba6d 100644 --- a/netfs/fuse/fuseApp.h +++ b/netfs/fuse/fuseApp.h @@ -32,9 +32,13 @@ namespace NetFS { public: OpenFile(FilePrx remote, const std::string & path, int flags); + void flush(); + void wait() const; + FilePrx remote; const std::string path; const int flags; + std::list bg; }; typedef IceUtil::Handle OpenFilePtr; typedef std::map OpenFiles; diff --git a/netfs/fuse/fuseFiles.cpp b/netfs/fuse/fuseFiles.cpp index 5268f4a..e31b4db 100644 --- a/netfs/fuse/fuseFiles.cpp +++ b/netfs/fuse/fuseFiles.cpp @@ -36,6 +36,25 @@ NetFS::FuseApp::clearFileProxy(uint64_t localID) openFiles.erase(localID); } +void +NetFS::FuseApp::OpenFile::wait() const +{ + for (const auto & w : bg) { + w->waitForCompleted(); + } +} + +void +NetFS::FuseApp::OpenFile::flush() +{ + while (!bg.empty()) { + auto w = bg.front(); + bg.pop_front(); + // bg operations are void, so no need to actually get the return value + w->throwLocalException(); + } +} + int NetFS::FuseApp::open(const char * p, struct fuse_file_info * fi) { @@ -66,12 +85,19 @@ int NetFS::FuseApp::release(const char *, struct fuse_file_info * fi) { try { - auto remote = getFileProxy(fi->fh)->remote; + auto of = getFileProxy(fi->fh); + auto remote = of->remote; + try { + of->flush(); + } + catch (NetFS::SystemError & e) { + } remote->close(); clearFileProxy(fi->fh); return 0; } catch (NetFS::SystemError & e) { + clearFileProxy(fi->fh); return -e.syserrno; } } @@ -80,7 +106,7 @@ int NetFS::FuseApp::flush(const char *, struct fuse_file_info * fi) { try { - (void)fi; + getFileProxy(fi->fh)->flush(); return 0; } catch (NetFS::SystemError & e) { @@ -92,7 +118,9 @@ int NetFS::FuseApp::read(const char *, char * buf, size_t s, off_t o, struct fuse_file_info * fi) { try { - auto remote = getFileProxy(fi->fh)->remote; + auto of = getFileProxy(fi->fh); + of->wait(); + auto remote = of->remote; NetFS::Buffer data = remote->read(o, s); memcpy(buf, &data.front(), data.size()); return data.size(); @@ -106,8 +134,15 @@ int NetFS::FuseApp::write(const char *, const char * buf, size_t s, off_t o, struct fuse_file_info * fi) { try { - auto remote = getFileProxy(fi->fh)->remote; - remote->write(o, s, NetFS::Buffer(buf, buf + s)); + auto of = getFileProxy(fi->fh); + auto remote = of->remote; + auto r = remote->begin_write(o, s, NetFS::Buffer(buf, buf + s)); + if (fcr->Async) { + of->bg.push_back(r); + } + else { + r->throwLocalException(); + } return s; } catch (NetFS::SystemError & e) { @@ -131,7 +166,9 @@ int NetFS::FuseApp::ftruncate(const char *, off_t o, fuse_file_info * fi) { try { - auto remote = getFileProxy(fi->fh)->remote; + auto of = getFileProxy(fi->fh); + of->wait(); + auto remote = of->remote; remote->ftruncate(reqEnv(), o); return 0; } @@ -144,7 +181,9 @@ int NetFS::FuseApp::fgetattr(const char *, struct stat * s, fuse_file_info * fi) { try { - auto remote = getFileProxy(fi->fh)->remote; + auto of = getFileProxy(fi->fh); + of->wait(); + auto remote = of->remote; *s = converter.convert(remote->fgetattr(reqEnv())); return 0; } -- cgit v1.2.3