summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2010-11-12 22:48:16 +0000
committerrandomdan <randomdan@localhost>2010-11-12 22:48:16 +0000
commit39bf5471944c7fe560d0dfe194a4f3c17a76c542 (patch)
tree852c7db3e91af11b2165ef3f82aa12012f891b8a
parentAdd locking for safe multi-threaded use in client (diff)
downloadnetfs-39bf5471944c7fe560d0dfe194a4f3c17a76c542.tar.bz2
netfs-39bf5471944c7fe560d0dfe194a4f3c17a76c542.tar.xz
netfs-39bf5471944c7fe560d0dfe194a4f3c17a76c542.zip
Refactor and templatize EntCache to remove code duplication
Adding read/write locking to EntCache Related changes to separating EntCache into an instance for users and one for groups
-rw-r--r--netfs/daemon.cpp6
-rw-r--r--netfs/daemon.h2
-rw-r--r--netfs/daemonDirs.cpp6
-rw-r--r--netfs/daemonFileSystem.h3
-rw-r--r--netfs/daemonFiles.cpp16
-rw-r--r--netfs/daemonMisc.cpp22
-rw-r--r--netfs/daemonSystem.cpp2
-rw-r--r--netfs/entCache.cpp96
-rw-r--r--netfs/entCache.h28
-rw-r--r--netfs/fuse.cpp4
-rw-r--r--netfs/fuse.h3
-rw-r--r--netfs/fuseFiles.cpp4
-rw-r--r--netfs/fuseMisc.cpp4
13 files changed, 97 insertions, 99 deletions
diff --git a/netfs/daemon.cpp b/netfs/daemon.cpp
index 7ac795f..522f19f 100644
--- a/netfs/daemon.cpp
+++ b/netfs/daemon.cpp
@@ -113,9 +113,9 @@ TempPrivs::TempPrivs(uid_t u, gid_t g) :
throw NetFSComms::SystemError(errno);
}
-TempPrivs::TempPrivs(const NetFSComms::ReqEnv & re, const EntCache * ec) :
- myu(ec->getUID(re.user)), oldu(geteuid()),
- myg(ec->getGID(re.grp)), oldg(getegid())
+TempPrivs::TempPrivs(const NetFSComms::ReqEnv & re, const UserEntCache * uec, const GroupEntCache * gec) :
+ myu(uec->getID(re.user)), oldu(geteuid()),
+ myg(gec->getID(re.grp)), oldg(getegid())
{
if (setegid(myg))
throw NetFSComms::SystemError(errno);
diff --git a/netfs/daemon.h b/netfs/daemon.h
index 6acd314..d24353b 100644
--- a/netfs/daemon.h
+++ b/netfs/daemon.h
@@ -68,7 +68,7 @@ class SessionPtr {
class TempPrivs {
public:
TempPrivs(uid_t u, gid_t g);
- TempPrivs(const NetFSComms::ReqEnv & re, const EntCache * ec);
+ TempPrivs(const NetFSComms::ReqEnv & re, const UserEntCache * uec, const GroupEntCache * gec);
virtual ~TempPrivs();
private:
diff --git a/netfs/daemonDirs.cpp b/netfs/daemonDirs.cpp
index ac0247f..37f2a5c 100644
--- a/netfs/daemonDirs.cpp
+++ b/netfs/daemonDirs.cpp
@@ -9,7 +9,7 @@ Ice::Int
FileSystemServer::opendir(const NetFSComms::ReqEnv & re, const std::string & path, const Ice::Current&)
{
SessionPtr sess(dgs->getSession(re.tok));
- TempPrivs tp(re, &entries);
+ TempPrivs tp(re, &uentries, &gentries);
errno = 0;
DIR * od = ::opendir((sess->exportCfg->root / path).string().c_str());
if (!od) {
@@ -58,7 +58,7 @@ void
FileSystemServer::mkdir(const NetFSComms::ReqEnv & re, const std::string & path, Ice::Int mode, const Ice::Current&)
{
SessionPtr sess(dgs->getSession(re.tok));
- TempPrivs tp(re, &entries);
+ TempPrivs tp(re, &uentries, &gentries);
errno = 0;
if (::mkdir((sess->exportCfg->root / path).string().c_str(), mode) != 0) {
throw NetFSComms::SystemError(errno);
@@ -70,7 +70,7 @@ void
FileSystemServer::rmdir(const NetFSComms::ReqEnv & re, const std::string & path, const Ice::Current&)
{
SessionPtr sess(dgs->getSession(re.tok));
- TempPrivs tp(re, &entries);
+ TempPrivs tp(re, &uentries, &gentries);
errno = 0;
if (::rmdir((sess->exportCfg->root / path).string().c_str()) != 0) {
throw NetFSComms::SystemError(errno);
diff --git a/netfs/daemonFileSystem.h b/netfs/daemonFileSystem.h
index 999ad6c..2950f79 100644
--- a/netfs/daemonFileSystem.h
+++ b/netfs/daemonFileSystem.h
@@ -42,7 +42,8 @@ class FileSystemServer : public DaemonModule, public NetFSComms::FileSystem {
virtual void chown(const NetFSComms::ReqEnv &, const std::string & path, Ice::Int uid, Ice::Int gid, const Ice::Current&);
virtual void utimens(const NetFSComms::ReqEnv &, const std::string & path, Ice::Long, Ice::Long, Ice::Long, Ice::Long, const Ice::Current&);
private:
- EntCache entries;
+ UserEntCache uentries;
+ GroupEntCache gentries;
};
#endif
diff --git a/netfs/daemonFiles.cpp b/netfs/daemonFiles.cpp
index 2d4021f..aef3239 100644
--- a/netfs/daemonFiles.cpp
+++ b/netfs/daemonFiles.cpp
@@ -8,7 +8,7 @@ void
FileSystemServer::truncate(const NetFSComms::ReqEnv & re, const std::string & path, Ice::Long size, const Ice::Current&)
{
SessionPtr sess(dgs->getSession(re.tok));
- TempPrivs tp(re, &entries);
+ TempPrivs tp(re, &uentries, &gentries);
errno = 0;
if (::truncate((sess->exportCfg->root / path).string().c_str(), size) != 0) {
throw NetFSComms::SystemError(errno);
@@ -20,7 +20,7 @@ void
FileSystemServer::ftruncate(const NetFSComms::ReqEnv & re, Ice::Int id, Ice::Long size, const Ice::Current&)
{
SessionPtr sess(dgs->getSession(re.tok));
- TempPrivs tp(re, &entries);
+ TempPrivs tp(re, &uentries, &gentries);
if (sess->files.find(id) == sess->files.end()) {
throw NetFSComms::SystemError(EBADF);
}
@@ -35,7 +35,7 @@ NetFSComms::Attr
FileSystemServer::fgetattr(const NetFSComms::ReqEnv & re, Ice::Int id, const Ice::Current &)
{
SessionPtr sess(dgs->getSession(re.tok));
- TempPrivs tp(re, &entries);
+ TempPrivs tp(re, &uentries, &gentries);
if (sess->files.find(id) == sess->files.end()) {
throw NetFSComms::SystemError(EBADF);
}
@@ -48,8 +48,8 @@ FileSystemServer::fgetattr(const NetFSComms::ReqEnv & re, Ice::Int id, const Ice
a.inode = s.st_ino;
a.mode = s.st_mode;
a.links = s.st_nlink;
- a.uid = entries.getUName(s.st_uid);
- a.gid = entries.getGName(s.st_gid);
+ a.uid = uentries.getName(s.st_uid);
+ a.gid = gentries.getName(s.st_gid);
a.rdev = s.st_rdev;
a.size = s.st_size;
a.blockSize = s.st_blksize;
@@ -64,7 +64,7 @@ void
FileSystemServer::unlink(const NetFSComms::ReqEnv & re, const std::string & path, const Ice::Current&)
{
SessionPtr sess(dgs->getSession(re.tok));
- TempPrivs tp(re, &entries);
+ TempPrivs tp(re, &uentries, &gentries);
errno = 0;
if (::unlink((sess->exportCfg->root / path).string().c_str()) != 0) {
throw NetFSComms::SystemError(errno);
@@ -76,7 +76,7 @@ Ice::Int
FileSystemServer::open(const NetFSComms::ReqEnv & re, const std::string & path, Ice::Int flags, const Ice::Current&)
{
SessionPtr sess(dgs->getSession(re.tok));
- TempPrivs tp(re, &entries);
+ TempPrivs tp(re, &uentries, &gentries);
errno = 0;
int fd = ::open((sess->exportCfg->root / path).string().c_str(), flags);
if (fd == -1) {
@@ -91,7 +91,7 @@ Ice::Int
FileSystemServer::create(const NetFSComms::ReqEnv & re, const std::string & path, Ice::Int flags, Ice::Int mode, const Ice::Current&)
{
SessionPtr sess(dgs->getSession(re.tok));
- TempPrivs tp(re, &entries);
+ TempPrivs tp(re, &uentries, &gentries);
errno = 0;
int fd = ::open((sess->exportCfg->root / path).string().c_str(), O_CREAT | flags, mode);
if (fd == -1) {
diff --git a/netfs/daemonMisc.cpp b/netfs/daemonMisc.cpp
index 2228476..e584c4f 100644
--- a/netfs/daemonMisc.cpp
+++ b/netfs/daemonMisc.cpp
@@ -11,7 +11,7 @@ Ice::Int
FileSystemServer::access(const NetFSComms::ReqEnv & re, const std::string & path, Ice::Int mode, const Ice::Current &)
{
SessionPtr sess(dgs->getSession(re.tok));
- TempPrivs tp(re, &entries);
+ TempPrivs tp(re, &uentries, &gentries);
return ::access((sess->exportCfg->root / path).string().c_str(), mode);
}
@@ -19,7 +19,7 @@ NetFSComms::Attr
FileSystemServer::getattr(const NetFSComms::ReqEnv & re, const std::string & path, const Ice::Current &)
{
SessionPtr sess(dgs->getSession(re.tok));
- TempPrivs tp(re, &entries);
+ TempPrivs tp(re, &uentries, &gentries);
struct stat s;
if (::lstat((sess->exportCfg->root / path).string().c_str(), &s) != 0) {
throw NetFSComms::SystemError(errno);
@@ -29,8 +29,8 @@ FileSystemServer::getattr(const NetFSComms::ReqEnv & re, const std::string & pat
a.inode = s.st_ino;
a.mode = s.st_mode;
a.links = s.st_nlink;
- a.uid = entries.getUName(s.st_uid);
- a.gid = entries.getGName(s.st_gid);
+ a.uid = uentries.getName(s.st_uid);
+ a.gid = gentries.getName(s.st_gid);
a.rdev = s.st_rdev;
a.size = s.st_size;
a.blockSize = s.st_blksize;
@@ -45,7 +45,7 @@ void
FileSystemServer::symlink(const NetFSComms::ReqEnv & re, const std::string & path1, const std::string & path2, const Ice::Current &)
{
SessionPtr sess(dgs->getSession(re.tok));
- TempPrivs tp(re, &entries);
+ TempPrivs tp(re, &uentries, &gentries);
errno = 0;
if (::symlink((sess->exportCfg->root / path1).string().c_str(), (sess->exportCfg->root / path2).string().c_str()) != 0) {
throw NetFSComms::SystemError(errno);
@@ -57,7 +57,7 @@ void
FileSystemServer::link(const NetFSComms::ReqEnv & re, const std::string & path1, const std::string & path2, const Ice::Current &)
{
SessionPtr sess(dgs->getSession(re.tok));
- TempPrivs tp(re, &entries);
+ TempPrivs tp(re, &uentries, &gentries);
errno = 0;
if (::link((sess->exportCfg->root / path1).string().c_str(), (sess->exportCfg->root / path2).string().c_str()) != 0) {
throw NetFSComms::SystemError(errno);
@@ -69,7 +69,7 @@ void
FileSystemServer::rename(const NetFSComms::ReqEnv & re, const std::string & from, const std::string & to, const Ice::Current &)
{
SessionPtr sess(dgs->getSession(re.tok));
- TempPrivs tp(re, &entries);
+ TempPrivs tp(re, &uentries, &gentries);
errno = 0;
if (::rename((sess->exportCfg->root / from).string().c_str(), (sess->exportCfg->root / to).string().c_str()) != 0) {
throw NetFSComms::SystemError(errno);
@@ -81,7 +81,7 @@ std::string
FileSystemServer::readlink(const NetFSComms::ReqEnv & re, const std::string & path, const Ice::Current &)
{
SessionPtr sess(dgs->getSession(re.tok));
- TempPrivs tp(re, &entries);
+ TempPrivs tp(re, &uentries, &gentries);
errno = 0;
char buf[PATH_MAX];
ssize_t rc = ::readlink((sess->exportCfg->root / path).string().c_str(), buf, PATH_MAX);
@@ -95,7 +95,7 @@ void
FileSystemServer::chmod(const NetFSComms::ReqEnv & re, const std::string & path, Ice::Int mode, const Ice::Current &)
{
SessionPtr sess(dgs->getSession(re.tok));
- TempPrivs tp(re, &entries);
+ TempPrivs tp(re, &uentries, &gentries);
errno = 0;
if (::chmod((sess->exportCfg->root / path).string().c_str(), mode) != 0) {
throw NetFSComms::SystemError(errno);
@@ -107,7 +107,7 @@ void
FileSystemServer::chown(const NetFSComms::ReqEnv & re, const std::string & path, Ice::Int uid, Ice::Int gid, const Ice::Current &)
{
SessionPtr sess(dgs->getSession(re.tok));
- TempPrivs tp(re, &entries);
+ TempPrivs tp(re, &uentries, &gentries);
errno = 0;
if (::chown((sess->exportCfg->root / path).string().c_str(), uid, gid) != 0) {
throw NetFSComms::SystemError(errno);
@@ -120,7 +120,7 @@ FileSystemServer::utimens(const NetFSComms::ReqEnv & re, const std::string & pat
Ice::Long s0, Ice::Long ns0, Ice::Long s1, Ice::Long ns1, const Ice::Current&)
{
SessionPtr sess(dgs->getSession(re.tok));
- TempPrivs tp(re, &entries);
+ TempPrivs tp(re, &uentries, &gentries);
errno = 0;
struct timespec times[2];
times[0].tv_sec = s0;
diff --git a/netfs/daemonSystem.cpp b/netfs/daemonSystem.cpp
index 8e9a13c..2fcba7f 100644
--- a/netfs/daemonSystem.cpp
+++ b/netfs/daemonSystem.cpp
@@ -7,7 +7,7 @@ NetFSComms::VFS
FileSystemServer::statfs(const NetFSComms::ReqEnv & re, const std::string & path, const Ice::Current&)
{
SessionPtr sess(dgs->getSession(re.tok));
- TempPrivs tp(re, &entries);
+ TempPrivs tp(re, &uentries, &gentries);
errno = 0;
struct statvfs s;
if (::statvfs((sess->exportCfg->root / path).string().c_str(), &s) != 0) {
diff --git a/netfs/entCache.cpp b/netfs/entCache.cpp
index 52e8b67..f79146f 100644
--- a/netfs/entCache.cpp
+++ b/netfs/entCache.cpp
@@ -1,92 +1,80 @@
#include "entCache.h"
#include <netfsComms.h>
-EntCache::EntCache()
-{
-}
+#define LOCK boost::unique_lock<boost::shared_mutex> _lck(lock)
+#define SLOCK boost::shared_lock<boost::shared_mutex> _lck(lock)
-EntCache::~EntCache()
+template<class id_t, class name_t>
+EntCache<id_t, name_t>::EntCache()
{
}
-uid_t
-EntCache::getUID(const std::string & u) const
+template<class id_t, class name_t>
+EntCache<id_t, name_t>::~EntCache()
{
- UIDs::right_map::const_iterator cu = uidcache.right.find(u);
- if (cu != uidcache.right.end()) {
- return cu->second;
- }
- makeuidCache();
- cu = uidcache.right.find(u);
- if (cu != uidcache.right.end()) {
- return cu->second;
- }
- throw NetFSComms::SystemError(EPERM);
}
-gid_t
-EntCache::getGID(const std::string & g) const
+template<class id_t, class name_t>
+const id_t &
+EntCache<id_t, name_t>::getID(const name_t & u) const
{
- GIDs::right_map::const_iterator cg = gidcache.right.find(g);
- if (cg != gidcache.right.end()) {
- return cg->second;
- }
- makegidCache();
- cg = gidcache.right.find(g);
- if (cg != gidcache.right.end()) {
- return cg->second;
+ {
+ SLOCK;
+ typename IDs::right_map::const_iterator cu = idcache.right.find(u);
+ if (cu != idcache.right.end()) {
+ return cu->second;
+ }
}
- throw NetFSComms::SystemError(EPERM);
-}
-
-const std::string &
-EntCache::getUName(uid_t u) const
-{
- UIDs::left_map::const_iterator cu = uidcache.left.find(u);
- if (cu != uidcache.left.end()) {
- return cu->second;
- }
- makeuidCache();
- cu = uidcache.left.find(u);
- if (cu != uidcache.left.end()) {
+ fillCache();
+ SLOCK;
+ typename IDs::right_map::const_iterator cu = idcache.right.find(u);
+ if (cu != idcache.right.end()) {
return cu->second;
}
throw NetFSComms::SystemError(EPERM);
}
-const std::string &
-EntCache::getGName(gid_t g) const
+template<class id_t, class name_t>
+const name_t &
+EntCache<id_t, name_t>::getName(const id_t & u) const
{
- GIDs::left_map::const_iterator cg = gidcache.left.find(g);
- if (cg != gidcache.left.end()) {
- return cg->second;
+ {
+ SLOCK;
+ typename IDs::left_map::const_iterator cu = idcache.left.find(u);
+ if (cu != idcache.left.end()) {
+ return cu->second;
+ }
}
- makegidCache();
- cg = gidcache.left.find(g);
- if (cg != gidcache.left.end()) {
- return cg->second;
+ fillCache();
+ SLOCK;
+ typename IDs::left_map::const_iterator cu = idcache.left.find(u);
+ if (cu != idcache.left.end()) {
+ return cu->second;
}
throw NetFSComms::SystemError(EPERM);
}
+template class EntCache<uid_t, std::string>;
void
-EntCache::makeuidCache() const
+UserEntCache::fillCache() const
{
+ LOCK;
setpwent();
- uidcache.clear();
+ idcache.clear();
while (struct passwd * pwp = getpwent()) {
- uidcache.insert(boost::bimap<uid_t, std::string>::value_type(pwp->pw_uid, pwp->pw_name));
+ idcache.insert(boost::bimap<uid_t, std::string>::value_type(pwp->pw_uid, pwp->pw_name));
}
endpwent();
}
void
-EntCache::makegidCache() const
+GroupEntCache::fillCache() const
{
+ LOCK;
setgrent();
- gidcache.clear();
+ idcache.clear();
while (struct group * grpp = getgrent()) {
- gidcache.insert(boost::bimap<gid_t, std::string>::value_type(grpp->gr_gid, grpp->gr_name));
+ idcache.insert(boost::bimap<gid_t, std::string>::value_type(grpp->gr_gid, grpp->gr_name));
}
endgrent();
}
diff --git a/netfs/entCache.h b/netfs/entCache.h
index fc8ab08..c16cd0b 100644
--- a/netfs/entCache.h
+++ b/netfs/entCache.h
@@ -5,24 +5,32 @@
#include <grp.h>
#include <string>
#include <boost/bimap.hpp>
+#include <boost/thread/shared_mutex.hpp>
+template<class id_t, class name_t>
class EntCache {
public:
EntCache();
virtual ~EntCache();
- uid_t getUID(const std::string & ) const;
- gid_t getGID(const std::string & ) const;
- const std::string & getUName(uid_t) const;
- const std::string & getGName(gid_t) const;
+ const id_t & getID(const name_t & ) const;
+ const name_t & getName(const id_t &) const;
+ protected:
+ virtual void fillCache() const = 0;
+ typedef boost::bimap<id_t, name_t> IDs;
+ mutable IDs idcache;
+ mutable boost::shared_mutex lock;
+};
+
+class UserEntCache : public EntCache<uid_t, std::string> {
+ private:
+ void fillCache() const;
+};
+
+class GroupEntCache : public EntCache<gid_t, std::string> {
private:
- void makeuidCache() const;
- void makegidCache() const;
- typedef boost::bimap<uid_t, std::string> UIDs;
- typedef boost::bimap<gid_t, std::string> GIDs;
- mutable UIDs uidcache;
- mutable GIDs gidcache;
+ void fillCache() const;
};
#endif
diff --git a/netfs/fuse.cpp b/netfs/fuse.cpp
index cbb3707..d5943e3 100644
--- a/netfs/fuse.cpp
+++ b/netfs/fuse.cpp
@@ -6,8 +6,8 @@ NetFS::ReqEnv::ReqEnv(const NetFS * netfs)
{
struct fuse_context * c = fuse_get_context();
tok = netfs->authtok;
- user = netfs->entries.getUName(c->uid);
- grp = netfs->entries.getGName(c->gid);
+ user = netfs->uentries.getName(c->uid);
+ grp = netfs->gentries.getName(c->gid);
}
NetFS::NetFS(int & argc, char ** argv) :
diff --git a/netfs/fuse.h b/netfs/fuse.h
index 707e54a..0b25ad7 100644
--- a/netfs/fuse.h
+++ b/netfs/fuse.h
@@ -100,7 +100,8 @@ class NetFS : public FuseAppBase
std::string exportName;
std::string configPath;
- EntCache entries;
+ UserEntCache uentries;
+ GroupEntCache gentries;
OpenDirs openDirs;
int openDirID;
OpenFiles openFiles;
diff --git a/netfs/fuseFiles.cpp b/netfs/fuseFiles.cpp
index 1006c58..6a59492 100644
--- a/netfs/fuseFiles.cpp
+++ b/netfs/fuseFiles.cpp
@@ -130,8 +130,8 @@ NetFS::fgetattr(const char *, struct stat * s, fuse_file_info * fi)
s->st_ino = a.inode;
s->st_mode = a.mode;
s->st_nlink = a.links;
- s->st_uid = entries.getUID(a.uid);
- s->st_gid = entries.getGID(a.gid);
+ s->st_uid = uentries.getID(a.uid);
+ s->st_gid = gentries.getID(a.gid);
s->st_rdev = a.rdev;
s->st_size = a.size;
s->st_blksize = a.blockSize;
diff --git a/netfs/fuseMisc.cpp b/netfs/fuseMisc.cpp
index ce0a05c..1745240 100644
--- a/netfs/fuseMisc.cpp
+++ b/netfs/fuseMisc.cpp
@@ -16,8 +16,8 @@ NetFS::getattr(const char * p, struct stat * s)
s->st_ino = a.inode;
s->st_mode = a.mode;
s->st_nlink = a.links;
- s->st_uid = entries.getUID(a.uid);
- s->st_gid = entries.getGID(a.gid);
+ s->st_uid = uentries.getID(a.uid);
+ s->st_gid = gentries.getID(a.gid);
s->st_rdev = a.rdev;
s->st_size = a.size;
s->st_blksize = a.blockSize;