From c5686d6fd71a8d760d782079dd4234a065e2b43a Mon Sep 17 00:00:00 2001 From: randomdan Date: Fri, 12 Nov 2010 00:27:39 +0000 Subject: Add locking for safe multi-threaded use in client Fix bug with symlink name Fix bug with stating symlinks --- netfs/Jamfile.jam | 2 ++ netfs/daemonMisc.cpp | 2 +- netfs/fuse.cpp | 9 ++++++++- netfs/fuse.h | 7 +++++++ netfs/fuseDirs.cpp | 19 +++++++++++++++++-- netfs/fuseFiles.cpp | 25 +++++++++++++++++++------ netfs/fuseMisc.cpp | 2 +- 7 files changed, 55 insertions(+), 11 deletions(-) diff --git a/netfs/Jamfile.jam b/netfs/Jamfile.jam index a43d287..1fa92b5 100644 --- a/netfs/Jamfile.jam +++ b/netfs/Jamfile.jam @@ -10,6 +10,7 @@ alias libxmlpp : : : : lib boost_regex : : boost_regex ; lib boost_filesystem : : boost_filesystem ; lib boost_random : : boost_random ; +lib boost_thread : : boost_thread ; lib Ice : : Ice ; lib fuse : : fuse ; @@ -91,6 +92,7 @@ exe netfs : ../libmisc//misc netfsComms netfsCommon + boost_thread fuse Ice ; diff --git a/netfs/daemonMisc.cpp b/netfs/daemonMisc.cpp index 06ba166..2228476 100644 --- a/netfs/daemonMisc.cpp +++ b/netfs/daemonMisc.cpp @@ -21,7 +21,7 @@ FileSystemServer::getattr(const NetFSComms::ReqEnv & re, const std::string & pat SessionPtr sess(dgs->getSession(re.tok)); TempPrivs tp(re, &entries); struct stat s; - if (::stat((sess->exportCfg->root / path).string().c_str(), &s) != 0) { + if (::lstat((sess->exportCfg->root / path).string().c_str(), &s) != 0) { throw NetFSComms::SystemError(errno); } NetFSComms::Attr a; diff --git a/netfs/fuse.cpp b/netfs/fuse.cpp index 4b3f3bd..cbb3707 100644 --- a/netfs/fuse.cpp +++ b/netfs/fuse.cpp @@ -60,6 +60,12 @@ NetFS::opt_parse(void *, const char * arg, int key, struct fuse_args *) void NetFS::connect() +{ + LOCK; + connect_nl(); +} +void +NetFS::connect_nl() { authtok = service->connect(exportName, "bar"); BOOST_FOREACH(const OpenFiles::value_type & of, openFiles) { @@ -84,6 +90,7 @@ NetFS::onError(const std::exception & e) throw() NetFS::ReqEnv NetFS::reqEnv() { + LOCK; if (!service || !filesystem) { FuseConfig::ExportPtr e = fc->exports[exportName]; const std::string & ep = *e->endpoints.begin(); @@ -99,7 +106,7 @@ NetFS::reqEnv() } } if (authtok == 0) { - connect(); + connect_nl(); } return ReqEnv(this); } diff --git a/netfs/fuse.h b/netfs/fuse.h index b16a67c..707e54a 100644 --- a/netfs/fuse.h +++ b/netfs/fuse.h @@ -1,6 +1,7 @@ #ifndef FUSE_H #define FUSE_H +#include #include #include "netfsComms.h" #include "fuseapp.h" @@ -8,6 +9,8 @@ #include "entCache.h" #include "intrusivePtrBase.h" +#define LOCK boost::unique_lock _lck(lock) + class NetFS : public FuseAppBase { private: @@ -44,6 +47,7 @@ class NetFS : public FuseAppBase void * init (struct fuse_conn_info * info); int opt_parse(void *, const char * arg, int key, struct fuse_args *); void connect(); + void connect_nl(); // misc int access(const char * p, int a); int getattr(const char * p, struct stat * s); @@ -75,7 +79,9 @@ class NetFS : public FuseAppBase // stuff int onError(const std::exception & err) throw(); int getNextFileID(); + Ice::Int getRemoteIDforFile(int localID) const; int getNextDirID(); + Ice::Int getRemoteIDforDir(int localID) const; ReqEnv reqEnv(); @@ -83,6 +89,7 @@ class NetFS : public FuseAppBase char ** _argv; Ice::CommunicatorPtr ic; FuseConfigPtr fc; + mutable boost::mutex lock; NetFSComms::FileSystemPrx filesystem; NetFSComms::ServicePrx service; diff --git a/netfs/fuseDirs.cpp b/netfs/fuseDirs.cpp index 41f3013..b75ab5c 100644 --- a/netfs/fuseDirs.cpp +++ b/netfs/fuseDirs.cpp @@ -14,11 +14,23 @@ NetFS::getNextDirID() return openDirID; } +Ice::Int +NetFS::getRemoteIDforDir(int localID) const +{ + LOCK; + OpenDirs::const_iterator i = openDirs.find(localID); + if (i != openDirs.end()) { + return i->second->remoteID; + } + throw NetFSComms::SystemError(EBADF); +} + int NetFS::opendir(const char * p, struct fuse_file_info * fi) { try { Ice::Int remoteID = filesystem->opendir(reqEnv(), p); + LOCK; fi->fh = getNextDirID(); openDirs[fi->fh] = new OpenDir(remoteID, p); return 0; @@ -32,7 +44,8 @@ int NetFS::releasedir(const char *, struct fuse_file_info * fi) { try { - filesystem->closedir(authtok, openDirs[fi->fh]->remoteID); + filesystem->closedir(authtok, getRemoteIDforDir(fi->fh)); + LOCK; openDirs.erase(fi->fh); return 0; } @@ -45,7 +58,7 @@ int NetFS::readdir(const char *, void * buf, fuse_fill_dir_t filler, off_t, struct fuse_file_info * fi) { try { - NetFSComms::NameList ds = filesystem->readdir(authtok, openDirs[fi->fh]->remoteID); + NetFSComms::NameList ds = filesystem->readdir(authtok, getRemoteIDforDir(fi->fh)); for (NetFSComms::NameList::const_iterator e = ds.begin(); e != ds.end(); e++) { filler(buf, e->c_str(), NULL, 0); } @@ -67,6 +80,7 @@ NetFS::mkdir(const char * p, mode_t m) return -e.syserrno; } } + int NetFS::rmdir(const char * p) { @@ -78,3 +92,4 @@ NetFS::rmdir(const char * p) return -e.syserrno; } } + diff --git a/netfs/fuseFiles.cpp b/netfs/fuseFiles.cpp index 2bf18b7..1006c58 100644 --- a/netfs/fuseFiles.cpp +++ b/netfs/fuseFiles.cpp @@ -15,11 +15,23 @@ NetFS::getNextFileID() return openFileID; } +Ice::Int +NetFS::getRemoteIDforFile(int localID) const +{ + LOCK; + OpenFiles::const_iterator i = openFiles.find(localID); + if (i != openFiles.end()) { + return i->second->remoteID; + } + throw NetFSComms::SystemError(EBADF); +} + int NetFS::open(const char * p, struct fuse_file_info * fi) { try { Ice::Int remoteID = filesystem->open(reqEnv(), p, fi->flags); + LOCK; fi->fh = getNextFileID(); openFiles[fi->fh] = new OpenFile(remoteID, p, fi->flags); return 0; @@ -34,6 +46,7 @@ NetFS::create(const char * p, mode_t m, struct fuse_file_info * fi) { try { Ice::Int remoteID = filesystem->create(reqEnv(), p, fi->flags, m); + LOCK; fi->fh = getNextFileID(); openFiles[fi->fh] = new OpenFile(remoteID, p, fi->flags); return 0; @@ -47,7 +60,8 @@ int NetFS::release(const char *, struct fuse_file_info * fi) { try { - filesystem->close(authtok, openFiles[fi->fh]->remoteID); + filesystem->close(authtok, getRemoteIDforFile(fi->fh)); + LOCK; openFiles.erase(fi->fh); return 0; } @@ -60,7 +74,7 @@ int NetFS::read(const char *, char * buf, size_t s, off_t o, struct fuse_file_info * fi) { try { - NetFSComms::Buffer data = filesystem->read(authtok, openFiles[fi->fh]->remoteID, o, s); + NetFSComms::Buffer data = filesystem->read(authtok, getRemoteIDforFile(fi->fh), o, s); for (NetFSComms::Buffer::const_iterator i = data.begin(); i != data.end(); i++, buf++) { *buf = *i; } @@ -75,8 +89,7 @@ int NetFS::write(const char *, const char * buf, size_t s, off_t o, struct fuse_file_info * fi) { try { - NetFSComms::Buffer data(buf, buf + s); - filesystem->write(authtok, openFiles[fi->fh]->remoteID, o, s, data); + filesystem->write(authtok, getRemoteIDforFile(fi->fh), o, s, NetFSComms::Buffer(buf, buf + s)); return s; } catch (NetFSComms::SystemError & e) { @@ -100,7 +113,7 @@ int NetFS::ftruncate(const char *, off_t o, fuse_file_info * fi) { try { - filesystem->ftruncate(reqEnv(), openFiles[fi->fh]->remoteID, o); + filesystem->ftruncate(reqEnv(), getRemoteIDforFile(fi->fh), o); return 0; } catch (NetFSComms::SystemError & e) { @@ -112,7 +125,7 @@ int NetFS::fgetattr(const char *, struct stat * s, fuse_file_info * fi) { try { - NetFSComms::Attr a = filesystem->fgetattr(reqEnv(), openFiles[fi->fh]->remoteID); + NetFSComms::Attr a = filesystem->fgetattr(reqEnv(), getRemoteIDforFile(fi->fh)); s->st_dev = a.dev; s->st_ino = a.inode; s->st_mode = a.mode; diff --git a/netfs/fuseMisc.cpp b/netfs/fuseMisc.cpp index 4a855b9..ce0a05c 100644 --- a/netfs/fuseMisc.cpp +++ b/netfs/fuseMisc.cpp @@ -86,7 +86,7 @@ NetFS::readlink(const char * p, char * p2, size_t s) try { std::string l = filesystem->readlink(reqEnv(), p); l.copy(p2, s); - p2[s] = '\0'; + p2[l.length()] = '\0'; return 0; } catch (NetFSComms::SystemError & e) { -- cgit v1.2.3