summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--netfs/fuse/fuseApp.h4
-rw-r--r--netfs/fuse/fuseFiles.cpp53
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<Ice::AsyncResultPtr> bg;
};
typedef IceUtil::Handle<OpenFile> OpenFilePtr;
typedef std::map<int, OpenFilePtr> 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;
}