From 39bf5471944c7fe560d0dfe194a4f3c17a76c542 Mon Sep 17 00:00:00 2001 From: randomdan Date: Fri, 12 Nov 2010 22:48:16 +0000 Subject: 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 --- netfs/daemon.cpp | 6 +-- netfs/daemon.h | 2 +- netfs/daemonDirs.cpp | 6 +-- netfs/daemonFileSystem.h | 3 +- netfs/daemonFiles.cpp | 16 ++++---- netfs/daemonMisc.cpp | 22 +++++------ netfs/daemonSystem.cpp | 2 +- netfs/entCache.cpp | 96 +++++++++++++++++++++--------------------------- netfs/entCache.h | 28 +++++++++----- netfs/fuse.cpp | 4 +- netfs/fuse.h | 3 +- netfs/fuseFiles.cpp | 4 +- netfs/fuseMisc.cpp | 4 +- 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 -EntCache::EntCache() -{ -} +#define LOCK boost::unique_lock _lck(lock) +#define SLOCK boost::shared_lock _lck(lock) -EntCache::~EntCache() +template +EntCache::EntCache() { } -uid_t -EntCache::getUID(const std::string & u) const +template +EntCache::~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 +const id_t & +EntCache::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 +const name_t & +EntCache::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; void -EntCache::makeuidCache() const +UserEntCache::fillCache() const { + LOCK; setpwent(); - uidcache.clear(); + idcache.clear(); while (struct passwd * pwp = getpwent()) { - uidcache.insert(boost::bimap::value_type(pwp->pw_uid, pwp->pw_name)); + idcache.insert(boost::bimap::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::value_type(grpp->gr_gid, grpp->gr_name)); + idcache.insert(boost::bimap::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 #include #include +#include +template 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 IDs; + mutable IDs idcache; + mutable boost::shared_mutex lock; +}; + +class UserEntCache : public EntCache { + private: + void fillCache() const; +}; + +class GroupEntCache : public EntCache { private: - void makeuidCache() const; - void makegidCache() const; - typedef boost::bimap UIDs; - typedef boost::bimap 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; -- cgit v1.2.3