summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--netfs/daemon/daemonFile.cpp8
-rw-r--r--netfs/daemon/daemonFile.h6
-rw-r--r--netfs/daemon/daemonService.cpp2
-rw-r--r--netfs/daemon/daemonService.h4
-rw-r--r--netfs/daemon/daemonVolume.cpp54
-rw-r--r--netfs/daemon/daemonVolume.h6
-rw-r--r--netfs/daemon/modeCheck.cpp30
-rw-r--r--netfs/daemon/modeCheck.h12
-rw-r--r--netfs/fuse/fuseApp.cpp4
-rw-r--r--netfs/fuse/fuseApp.h4
-rw-r--r--netfs/fuse/fuseDirs.cpp2
-rw-r--r--netfs/fuse/fuseFiles.cpp2
-rw-r--r--netfs/fuse/fuseMisc.cpp2
-rw-r--r--netfs/ice/typeConvert.cpp8
-rw-r--r--netfs/ice/typeConvert.h26
-rw-r--r--netfs/lib/Jamfile.jam1
-rw-r--r--netfs/lib/entCache.cpp15
-rw-r--r--netfs/lib/entCache.h12
18 files changed, 116 insertions, 82 deletions
diff --git a/netfs/daemon/daemonFile.cpp b/netfs/daemon/daemonFile.cpp
index 3acd1ca..313027f 100644
--- a/netfs/daemon/daemonFile.cpp
+++ b/netfs/daemon/daemonFile.cpp
@@ -8,8 +8,10 @@
#include "daemonFile.h"
#include <entCache.h>
-FileServer::FileServer(int f) :
- fd(f)
+FileServer::FileServer(int f, const EntryResolver<uid_t> & u, const EntryResolver<gid_t> & g) :
+ fd(f),
+ userLookup(u),
+ groupLookup(g)
{
}
@@ -36,7 +38,7 @@ FileServer::fgetattr(const NetFS::ReqEnv & re, const Ice::Current &)
throw NetFS::SystemError(errno);
}
NetFS::Attr a;
- a << StatSource { s, boost::bind(&UserEntCache::getName, &UserEntCache::instance, _1, _2), boost::bind(&GroupEntCache::getName, &GroupEntCache::instance, _1, _2) };
+ a << StatSource { s, userLookup, groupLookup };
return a;
}
diff --git a/netfs/daemon/daemonFile.h b/netfs/daemon/daemonFile.h
index 8449386..933d687 100644
--- a/netfs/daemon/daemonFile.h
+++ b/netfs/daemon/daemonFile.h
@@ -2,10 +2,11 @@
#define DAEMONFILE_H
#include <file.h>
+#include <typeConvert.h>
class FileServer : public NetFS::File {
public:
- FileServer(int fd);
+ FileServer(int fd, const EntryResolver<uid_t> &, const EntryResolver<gid_t> &);
virtual ~FileServer();
virtual void close(const Ice::Current&) override;
@@ -17,6 +18,9 @@ class FileServer : public NetFS::File {
private:
const int fd;
+
+ const EntryResolver<uid_t> & userLookup;
+ const EntryResolver<gid_t> & groupLookup;
};
#endif
diff --git a/netfs/daemon/daemonService.cpp b/netfs/daemon/daemonService.cpp
index 7a81e51..9a88688 100644
--- a/netfs/daemon/daemonService.cpp
+++ b/netfs/daemon/daemonService.cpp
@@ -19,6 +19,6 @@ ServiceServer::connect(const std::string & share, const std::string & authtoken,
if (!e->second->AuthToken.empty() && e->second->AuthToken != authtoken) {
throw NetFS::AuthError();
}
- return NetFS::VolumePrx::checkedCast(ice.adapter->addWithUUID(new VolumeServer(e->second->RootPath)));
+ return NetFS::VolumePrx::checkedCast(ice.adapter->addWithUUID(new VolumeServer(e->second->RootPath, userLookup, groupLookup)));
}
diff --git a/netfs/daemon/daemonService.h b/netfs/daemon/daemonService.h
index 345df2c..09058b6 100644
--- a/netfs/daemon/daemonService.h
+++ b/netfs/daemon/daemonService.h
@@ -4,6 +4,7 @@
#include <service.h>
#include <entCache.h>
#include <daemonConfig.h>
+#include <entCache.h>
class ServiceServer : public NetFS::Service {
public:
@@ -12,6 +13,9 @@ class ServiceServer : public NetFS::Service {
virtual NetFS::VolumePrx connect(const std::string & share, const std::string & auth, const Ice::Current&) override;
private:
+ EntCache<User> userLookup;
+ EntCache<Group> groupLookup;
+
NetFS::Daemon::ConfigurationPtr config;
};
diff --git a/netfs/daemon/daemonVolume.cpp b/netfs/daemon/daemonVolume.cpp
index 347dbe2..4b8fe29 100644
--- a/netfs/daemon/daemonVolume.cpp
+++ b/netfs/daemon/daemonVolume.cpp
@@ -18,8 +18,10 @@
extern std::map<Ice::Int, int> files;
-VolumeServer::VolumeServer(const boost::filesystem::path & r) :
- root(r)
+VolumeServer::VolumeServer(const boost::filesystem::path & r, const EntCache<User> & u, const EntCache<Group> & g) :
+ root(r),
+ userLookup(u),
+ groupLookup(g)
{
}
@@ -36,7 +38,7 @@ VolumeServer::disconnect(const Ice::Current & ice)
Ice::Int
VolumeServer::access(const NetFS::ReqEnv & re, const std::string & path, Ice::Int mode, const Ice::Current &)
{
- ModeCheck mc(re, root);
+ ModeCheck mc(re, root, userLookup, groupLookup);
struct stat s;
boost::filesystem::path p(resolvePath(path));
if (::stat(p.string().c_str(), &s) != 0) {
@@ -47,13 +49,13 @@ VolumeServer::access(const NetFS::ReqEnv & re, const std::string & path, Ice::In
return 0;
}
mc.AssertRead(p.parent_path());
- if (mode & R_OK && !ModeCheck::ReadableBy(s, mc.myu, mc.myg)) {
+ if (mode & R_OK && !mc.ReadableBy(s, mc.myu, mc.myg)) {
return EACCES;
}
- if (mode & W_OK && !ModeCheck::WritableBy(s, mc.myu, mc.myg)) {
+ if (mode & W_OK && !mc.WritableBy(s, mc.myu, mc.myg)) {
return EACCES;
}
- if (mode & X_OK && !ModeCheck::ExecutableBy(s, mc.myu, mc.myg)) {
+ if (mode & X_OK && !mc.ExecutableBy(s, mc.myu, mc.myg)) {
return EACCES;
}
return 0;
@@ -62,7 +64,7 @@ VolumeServer::access(const NetFS::ReqEnv & re, const std::string & path, Ice::In
NetFS::Attr
VolumeServer::getattr(const NetFS::ReqEnv & re, const std::string & path, const Ice::Current &)
{
- ModeCheck mc(re, root);
+ ModeCheck mc(re, root, userLookup, groupLookup);
struct stat s;
boost::filesystem::path p(resolvePath(path));
mc.AssertRead(p.parent_path());
@@ -70,14 +72,14 @@ VolumeServer::getattr(const NetFS::ReqEnv & re, const std::string & path, const
throw NetFS::SystemError(errno);
}
NetFS::Attr a;
- a << StatSource { s, boost::bind(&UserEntCache::getName, &UserEntCache::instance, _1, _2), boost::bind(&GroupEntCache::getName, &GroupEntCache::instance, _1, _2) };
+ a << StatSource { s, userLookup, groupLookup };
return a;
}
void
VolumeServer::mknod(const NetFS::ReqEnv & re, const std::string & path, Ice::Int mode, Ice::Int dev, const Ice::Current&)
{
- ModeCheck mc(re, root);
+ ModeCheck mc(re, root, userLookup, groupLookup);
errno = 0;
boost::filesystem::path p(resolvePath(path));
mc.AssertWrite(p.parent_path());
@@ -89,7 +91,7 @@ VolumeServer::mknod(const NetFS::ReqEnv & re, const std::string & path, Ice::Int
void
VolumeServer::symlink(const NetFS::ReqEnv & re, const std::string & path1, const std::string & path2, const Ice::Current &)
{
- ModeCheck mc(re, root);
+ ModeCheck mc(re, root, userLookup, groupLookup);
errno = 0;
boost::filesystem::path p(resolvePath(path2));
mc.AssertWrite(p.parent_path());
@@ -105,7 +107,7 @@ VolumeServer::symlink(const NetFS::ReqEnv & re, const std::string & path1, const
void
VolumeServer::link(const NetFS::ReqEnv & re, const std::string & path1, const std::string & path2, const Ice::Current &)
{
- ModeCheck mc(re, root);
+ ModeCheck mc(re, root, userLookup, groupLookup);
errno = 0;
boost::filesystem::path p1(resolvePath(path1));
boost::filesystem::path p2(resolvePath(path2));
@@ -121,7 +123,7 @@ VolumeServer::link(const NetFS::ReqEnv & re, const std::string & path1, const st
void
VolumeServer::rename(const NetFS::ReqEnv & re, const std::string & from, const std::string & to, const Ice::Current &)
{
- ModeCheck mc(re, root);
+ ModeCheck mc(re, root, userLookup, groupLookup);
errno = 0;
boost::filesystem::path f(resolvePath(from));
boost::filesystem::path t(resolvePath(to));
@@ -141,7 +143,7 @@ VolumeServer::rename(const NetFS::ReqEnv & re, const std::string & from, const s
std::string
VolumeServer::readlink(const NetFS::ReqEnv & re, const std::string & path, const Ice::Current &)
{
- ModeCheck mc(re, root);
+ ModeCheck mc(re, root, userLookup, groupLookup);
errno = 0;
char buf[PATH_MAX];
boost::filesystem::path p(resolvePath(path));
@@ -156,7 +158,7 @@ VolumeServer::readlink(const NetFS::ReqEnv & re, const std::string & path, const
void
VolumeServer::chmod(const NetFS::ReqEnv & re, const std::string & path, Ice::Int mode, const Ice::Current &)
{
- ModeCheck mc(re, root);
+ ModeCheck mc(re, root, userLookup, groupLookup);
errno = 0;
boost::filesystem::path p(resolvePath(path));
mc.AssertWrite(p);
@@ -168,7 +170,7 @@ VolumeServer::chmod(const NetFS::ReqEnv & re, const std::string & path, Ice::Int
void
VolumeServer::chown(const NetFS::ReqEnv & re, const std::string & path, Ice::Int uid, Ice::Int gid, const Ice::Current &)
{
- ModeCheck mc(re, root);
+ ModeCheck mc(re, root, userLookup, groupLookup);
errno = 0;
boost::filesystem::path p(resolvePath(path));
mc.AssertWrite(p);
@@ -181,7 +183,7 @@ void
VolumeServer::utimens(const NetFS::ReqEnv & re, const std::string & path,
Ice::Long s0, Ice::Long ns0, Ice::Long s1, Ice::Long ns1, const Ice::Current&)
{
- ModeCheck mc(re, root);
+ ModeCheck mc(re, root, userLookup, groupLookup);
errno = 0;
struct timespec times[2];
times[0].tv_sec = s0;
@@ -198,7 +200,7 @@ VolumeServer::utimens(const NetFS::ReqEnv & re, const std::string & path,
NetFS::VFS
VolumeServer::statfs(const NetFS::ReqEnv & re, const std::string & path, const Ice::Current&)
{
- ModeCheck mc(re, root);
+ ModeCheck mc(re, root, userLookup, groupLookup);
errno = 0;
struct statvfs s;
boost::filesystem::path p(resolvePath(path));
@@ -214,7 +216,7 @@ VolumeServer::statfs(const NetFS::ReqEnv & re, const std::string & path, const I
void
VolumeServer::truncate(const NetFS::ReqEnv & re, const std::string & path, Ice::Long size, const Ice::Current&)
{
- ModeCheck mc(re, root);
+ ModeCheck mc(re, root, userLookup, groupLookup);
errno = 0;
boost::filesystem::path p(resolvePath(path));
mc.AssertWrite(p);
@@ -226,7 +228,7 @@ VolumeServer::truncate(const NetFS::ReqEnv & re, const std::string & path, Ice::
void
VolumeServer::unlink(const NetFS::ReqEnv & re, const std::string & path, const Ice::Current&)
{
- ModeCheck mc(re, root);
+ ModeCheck mc(re, root, userLookup, groupLookup);
errno = 0;
boost::filesystem::path p(resolvePath(path));
mc.AssertWrite(p);
@@ -245,7 +247,7 @@ VolumeServer::openReadOnly(const NetFS::ReqEnv & re, const std::string & path, I
NetFS::FilePrx
VolumeServer::open(const NetFS::ReqEnv & re, const std::string & path, Ice::Int flags, const Ice::Current & ice)
{
- ModeCheck mc(re, root);
+ ModeCheck mc(re, root, userLookup, groupLookup);
errno = 0;
boost::filesystem::path p(resolvePath(path));
mc.AssertRead(p);
@@ -256,13 +258,13 @@ VolumeServer::open(const NetFS::ReqEnv & re, const std::string & path, Ice::Int
if (fd == -1) {
throw NetFS::SystemError(errno);
}
- return NetFS::FilePrx::checkedCast(ice.adapter->addWithUUID(new FileServer(fd)));
+ return NetFS::FilePrx::checkedCast(ice.adapter->addWithUUID(new FileServer(fd, userLookup, groupLookup)));
}
NetFS::FilePrx
VolumeServer::create(const NetFS::ReqEnv & re, const std::string & path, Ice::Int flags, Ice::Int mode, const Ice::Current & ice)
{
- ModeCheck mc(re, root);
+ ModeCheck mc(re, root, userLookup, groupLookup);
errno = 0;
boost::filesystem::path p(resolvePath(path));
mc.AssertWrite(p.parent_path());
@@ -275,13 +277,13 @@ VolumeServer::create(const NetFS::ReqEnv & re, const std::string & path, Ice::In
::unlink(p.string().c_str());
throw NetFS::SystemError(errno);
}
- return NetFS::FilePrx::checkedCast(ice.adapter->addWithUUID(new FileServer(fd)));
+ return NetFS::FilePrx::checkedCast(ice.adapter->addWithUUID(new FileServer(fd, userLookup, groupLookup)));
}
NetFS::DirectoryPrx
VolumeServer::opendir(const NetFS::ReqEnv & re, const std::string & path, const Ice::Current & ice)
{
- ModeCheck mc(re, root);
+ ModeCheck mc(re, root, userLookup, groupLookup);
errno = 0;
boost::filesystem::path p(resolvePath(path));
mc.AssertRead(p);
@@ -295,7 +297,7 @@ VolumeServer::opendir(const NetFS::ReqEnv & re, const std::string & path, const
void
VolumeServer::mkdir(const NetFS::ReqEnv & re, const std::string & path, Ice::Int mode, const Ice::Current&)
{
- ModeCheck mc(re, root);
+ ModeCheck mc(re, root, userLookup, groupLookup);
errno = 0;
boost::filesystem::path p(resolvePath(path));
mc.AssertWrite(p.parent_path());
@@ -311,7 +313,7 @@ VolumeServer::mkdir(const NetFS::ReqEnv & re, const std::string & path, Ice::Int
void
VolumeServer::rmdir(const NetFS::ReqEnv & re, const std::string & path, const Ice::Current&)
{
- ModeCheck mc(re, root);
+ ModeCheck mc(re, root, userLookup, groupLookup);
errno = 0;
boost::filesystem::path p(resolvePath(path));
mc.AssertWrite(p);
diff --git a/netfs/daemon/daemonVolume.h b/netfs/daemon/daemonVolume.h
index d4b5221..18441f1 100644
--- a/netfs/daemon/daemonVolume.h
+++ b/netfs/daemon/daemonVolume.h
@@ -4,10 +4,11 @@
#include <volume.h>
#include <boost/thread/shared_mutex.hpp>
#include <boost/filesystem/path.hpp>
+#include <entCache.h>
class VolumeServer : public NetFS::Volume {
public:
- VolumeServer(const boost::filesystem::path & root);
+ VolumeServer(const boost::filesystem::path & root, const EntCache<User> &, const EntCache<Group> &);
virtual ~VolumeServer();
virtual NetFS::DirectoryPrx opendir(const NetFS::ReqEnv &, const std::string & path, const Ice::Current&) override;
@@ -44,6 +45,9 @@ class VolumeServer : public NetFS::Volume {
private:
const boost::filesystem::path root;
mutable boost::shared_mutex lock;
+
+ const EntCache<User> & userLookup;
+ const EntCache<Group> & groupLookup;
};
#endif
diff --git a/netfs/daemon/modeCheck.cpp b/netfs/daemon/modeCheck.cpp
index 7a201e0..36fe92d 100644
--- a/netfs/daemon/modeCheck.cpp
+++ b/netfs/daemon/modeCheck.cpp
@@ -2,13 +2,12 @@
#include <entCache.h>
#include <exceptions.h>
-#define us UserEntCache::instance
-#define gs GroupEntCache::instance
-
-ModeCheck::ModeCheck(const NetFS::ReqEnv & re, const boost::filesystem::path & r) :
- myu(us.getEntry(re.user)->id),
- myg(gs.getEntry(re.grp)->id),
- root(r)
+ModeCheck::ModeCheck(const NetFS::ReqEnv & re, const boost::filesystem::path & r, const EntCache<User> & u, const EntCache<Group> & g) :
+ myu(u.getEntry(re.user)->id),
+ myg(g.getEntry(re.grp)->id),
+ root(r),
+ userLookup(u),
+ groupLookup(g)
{
}
@@ -18,7 +17,7 @@ ModeCheck::AssertRead(const boost::filesystem::path & p) const
if (p != root) {
AssertRead(p.parent_path());
}
- if (!ModeCheck::ReadableBy(lstat(p), myu, myg)) {
+ if (!ReadableBy(lstat(p), myu, myg)) {
throw NetFS::SystemError(EACCES);
}
}
@@ -29,7 +28,7 @@ ModeCheck::AssertWrite(const boost::filesystem::path & p) const
if (p != root) {
AssertRead(p.parent_path());
}
- if (!ModeCheck::WritableBy(lstat(p), myu, myg)) {
+ if (!WritableBy(lstat(p), myu, myg)) {
throw NetFS::SystemError(EACCES);
}
}
@@ -45,33 +44,32 @@ ModeCheck::lstat(const boost::filesystem::path & p)
}
bool
-ModeCheck::ReadableBy(const struct stat & s, uid_t u, gid_t g)
+ModeCheck::ReadableBy(const struct stat & s, uid_t u, gid_t g) const
{
if (u == 0) return true;
if (s.st_mode & S_IROTH) return true;
if (s.st_mode & S_IRUSR && s.st_uid == u) return true;
- if (s.st_mode & S_IRGRP && (s.st_gid == g || us.getEntry(u)->group == s.st_gid || gs.getEntry(s.st_gid)->hasMember(u))) return true;
+ if (s.st_mode & S_IRGRP && (s.st_gid == g || userLookup.getEntry(u)->group == s.st_gid || groupLookup.getEntry(s.st_gid)->hasMember(u))) return true;
return false;
}
bool
-ModeCheck::WritableBy(const struct stat & s, uid_t u, gid_t g)
+ModeCheck::WritableBy(const struct stat & s, uid_t u, gid_t g) const
{
if (u == 0) return true;
if (s.st_mode & S_IWOTH) return true;
if (s.st_mode & S_IWUSR && s.st_uid == u) return true;
- if (s.st_mode & S_IWGRP && (s.st_gid == g || us.getEntry(u)->group == s.st_gid || gs.getEntry(s.st_gid)->hasMember(u))) return true;
+ if (s.st_mode & S_IWGRP && (s.st_gid == g || userLookup.getEntry(u)->group == s.st_gid || groupLookup.getEntry(s.st_gid)->hasMember(u))) return true;
return false;
}
bool
-ModeCheck::ExecutableBy(const struct stat & s, uid_t u, gid_t g)
+ModeCheck::ExecutableBy(const struct stat & s, uid_t u, gid_t g) const
{
if (u == 0 && (s.st_mode & (S_IXOTH | S_IXGRP | S_IXUSR))) return true;
if (s.st_mode & S_IXOTH) return true;
if (s.st_mode & S_IXUSR && s.st_uid == u) return true;
- if (s.st_mode & S_IXGRP && (s.st_gid == g || us.getEntry(u)->group == s.st_gid || gs.getEntry(s.st_gid)->hasMember(u))) return true;
+ if (s.st_mode & S_IXGRP && (s.st_gid == g || userLookup.getEntry(u)->group == s.st_gid || groupLookup.getEntry(s.st_gid)->hasMember(u))) return true;
return false;
}
-
diff --git a/netfs/daemon/modeCheck.h b/netfs/daemon/modeCheck.h
index 17d40fc..d43fa2f 100644
--- a/netfs/daemon/modeCheck.h
+++ b/netfs/daemon/modeCheck.h
@@ -4,10 +4,11 @@
#include <sys/stat.h>
#include <types.h>
#include <boost/filesystem/path.hpp>
+#include <entCache.h>
class ModeCheck {
public:
- ModeCheck(const NetFS::ReqEnv & re, const boost::filesystem::path &);
+ ModeCheck(const NetFS::ReqEnv & re, const boost::filesystem::path &, const EntCache<User> &, const EntCache<Group> &);
void AssertRead(const boost::filesystem::path &) const;
void AssertWrite(const boost::filesystem::path &) const;
@@ -16,12 +17,15 @@ class ModeCheck {
const gid_t myg;
const boost::filesystem::path & root;
- static bool ReadableBy(const struct stat &, uid_t u, gid_t g);
- static bool WritableBy(const struct stat &, uid_t u, gid_t g);
- static bool ExecutableBy(const struct stat &, uid_t u, gid_t g);
+ bool ReadableBy(const struct stat &, uid_t u, gid_t g) const;
+ bool WritableBy(const struct stat &, uid_t u, gid_t g) const;
+ bool ExecutableBy(const struct stat &, uid_t u, gid_t g) const;
private:
static struct stat lstat(const boost::filesystem::path &);
+
+ const EntCache<User> & userLookup;
+ const EntCache<Group> & groupLookup;
};
#endif
diff --git a/netfs/fuse/fuseApp.cpp b/netfs/fuse/fuseApp.cpp
index a752e47..133860a 100644
--- a/netfs/fuse/fuseApp.cpp
+++ b/netfs/fuse/fuseApp.cpp
@@ -202,8 +202,8 @@ NetFS::FuseApp::reqEnv()
connectToVolume();
struct fuse_context * c = fuse_get_context();
NetFS::ReqEnv re;
- UserEntCache::instance.getName(c->uid, &re.user);
- GroupEntCache::instance.getName(c->gid, &re.grp);
+ userLookup.getName(c->uid, &re.user);
+ groupLookup.getName(c->gid, &re.grp);
return re;
}
diff --git a/netfs/fuse/fuseApp.h b/netfs/fuse/fuseApp.h
index 3ab1cb0..60ecee9 100644
--- a/netfs/fuse/fuseApp.h
+++ b/netfs/fuse/fuseApp.h
@@ -5,6 +5,7 @@
#include <Ice/Ice.h>
#include <Glacier2/Session.h>
#include <service.h>
+#include <entCache.h>
#include "fuseAppBase.h"
#include "fuseConfig.h"
#include "cache.h"
@@ -115,6 +116,9 @@ namespace NetFS {
OpenFiles openFiles;
int openFileID;
+ EntCache<User> userLookup;
+ EntCache<Group> groupLookup;
+
typedef Cache<struct stat, std::string, IceUtil::Shared, IceUtil::Handle<Cacheable<struct stat, std::string, IceUtil::Shared>>> StatCache;
StatCache statCache;
};
diff --git a/netfs/fuse/fuseDirs.cpp b/netfs/fuse/fuseDirs.cpp
index 1da9484..fa9f13b 100644
--- a/netfs/fuse/fuseDirs.cpp
+++ b/netfs/fuse/fuseDirs.cpp
@@ -79,7 +79,7 @@ NetFS::FuseApp::readdir(const char * p, void * buf, fuse_fill_dir_t filler, off_
statCache.Add(new OptimisticCallCacheable<struct stat, std::string, IceUtil::Shared>(
[asga,this]() {
struct stat s;
- s << AttrSource { volume->end_getattr(asga), boost::bind(&UserEntCache::getID, &UserEntCache::instance, _1, _2), boost::bind(&GroupEntCache::getID, &GroupEntCache::instance, _1, _2) };
+ s << AttrSource { volume->end_getattr(asga), userLookup, groupLookup };
return s;
}, epath, time_t(NULL) + 2));
}
diff --git a/netfs/fuse/fuseFiles.cpp b/netfs/fuse/fuseFiles.cpp
index c6d4283..6206749 100644
--- a/netfs/fuse/fuseFiles.cpp
+++ b/netfs/fuse/fuseFiles.cpp
@@ -135,7 +135,7 @@ NetFS::FuseApp::fgetattr(const char *, struct stat * s, fuse_file_info * fi)
{
try {
auto remote = getFileProxy(fi->fh)->remote;
- *s << AttrSource { remote->fgetattr(reqEnv()), boost::bind(&UserEntCache::getID, &UserEntCache::instance, _1, _2), boost::bind(&GroupEntCache::getID, &GroupEntCache::instance, _1, _2) };
+ *s << AttrSource { remote->fgetattr(reqEnv()), userLookup, groupLookup };
return 0;
}
catch (NetFS::SystemError & e) {
diff --git a/netfs/fuse/fuseMisc.cpp b/netfs/fuse/fuseMisc.cpp
index 1f999bd..12a550f 100644
--- a/netfs/fuse/fuseMisc.cpp
+++ b/netfs/fuse/fuseMisc.cpp
@@ -19,7 +19,7 @@ NetFS::FuseApp::getattr(const char * p, struct stat * s)
*s = *cacehedStat;
}
else {
- *s << AttrSource { volume->getattr(reqEnv(), p), boost::bind(&UserEntCache::getID, &UserEntCache::instance, _1, _2), boost::bind(&GroupEntCache::getID, &GroupEntCache::instance, _1, _2) };
+ *s << AttrSource { volume->getattr(reqEnv(), p), userLookup, groupLookup };
}
return 0;
}
diff --git a/netfs/ice/typeConvert.cpp b/netfs/ice/typeConvert.cpp
index cc3ee93..91b2cf4 100644
--- a/netfs/ice/typeConvert.cpp
+++ b/netfs/ice/typeConvert.cpp
@@ -7,8 +7,8 @@ operator<<(struct stat & s, const AttrSource & a)
s.st_ino = a.attr.inode;
s.st_mode = a.attr.mode;
s.st_nlink = a.attr.links;
- a.user(a.attr.uid, &s.st_uid);
- a.group(a.attr.gid, &s.st_gid);
+ a.user.getID(a.attr.uid, &s.st_uid);
+ a.group.getID(a.attr.gid, &s.st_gid);
s.st_rdev = a.attr.rdev;
s.st_size = a.attr.size;
s.st_blksize = a.attr.blockSize;
@@ -41,8 +41,8 @@ operator<<(NetFS::Attr & a, const struct StatSource & s)
a.inode = s.stat.st_ino;
a.mode = s.stat.st_mode;
a.links = s.stat.st_nlink;
- s.user(s.stat.st_uid, &a.uid);
- s.group(s.stat.st_gid, &a.gid);
+ s.user.getName(s.stat.st_uid, &a.uid);
+ s.group.getName(s.stat.st_gid, &a.gid);
a.rdev = s.stat.st_rdev;
a.size = s.stat.st_size;
a.blockSize = s.stat.st_blksize;
diff --git a/netfs/ice/typeConvert.h b/netfs/ice/typeConvert.h
index 13e2b44..1c9e773 100644
--- a/netfs/ice/typeConvert.h
+++ b/netfs/ice/typeConvert.h
@@ -1,24 +1,28 @@
+#ifndef NETFS_TYPECONVERT_H
+#define NETFS_TYPECONVERT_H
+
#include <types.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
-#include <boost/function.hpp>
-
-typedef boost::function<void(const std::string &, uid_t *)> UserIdLookup;
-typedef boost::function<void(const std::string &, gid_t *)> GroupIdLookup;
-typedef boost::function<void(uid_t, std::string *)> UserNameLookup;
-typedef boost::function<void(gid_t, std::string *)> GroupNameLookup;
+template <class entry_t>
+class EntryResolver {
+ public:
+ typedef std::string name_t;
+ virtual void getID(const name_t &, id_t *) const = 0;
+ virtual void getName(const id_t &, name_t *) const = 0;
+};
struct AttrSource {
const NetFS::Attr & attr;
- const UserIdLookup & user;
- const GroupIdLookup & group;
+ const EntryResolver<uid_t> & user;
+ const EntryResolver<gid_t> & group;
};
struct StatSource {
const struct stat & stat;
- const UserNameLookup & user;
- const GroupNameLookup & group;
+ const EntryResolver<uid_t> & user;
+ const EntryResolver<gid_t> & group;
};
void operator<<(struct stat &, const AttrSource &);
@@ -27,3 +31,5 @@ void operator<<(struct statvfs &, const NetFS::VFS &);
void operator<<(NetFS::Attr &, const struct StatSource &);
void operator<<(NetFS::VFS &, const struct statvfs &);
+#endif
+
diff --git a/netfs/lib/Jamfile.jam b/netfs/lib/Jamfile.jam
index 45d40f1..81d0be1 100644
--- a/netfs/lib/Jamfile.jam
+++ b/netfs/lib/Jamfile.jam
@@ -9,6 +9,7 @@ lib netfsCommon :
:
<define>_FILE_OFFSET_BITS=64
<include>../../libmisc
+ <include>../ice
<library>..//boost_system
<library>..//boost_thread
<library>../ice//netfsComms
diff --git a/netfs/lib/entCache.cpp b/netfs/lib/entCache.cpp
index c16678f..411202f 100644
--- a/netfs/lib/entCache.cpp
+++ b/netfs/lib/entCache.cpp
@@ -105,11 +105,12 @@ EntCache<Group>::fillCache() const
char buf[BUFLEN];
idcache.clear();
struct group grpbuf, * grp;
+ EntCache<User> instance;
while (getgrent_r(&grpbuf, buf, BUFLEN, &grp) == 0) {
auto g = new Group(grp->gr_gid, grp->gr_name);
for (auto member = grp->gr_mem; *member; member++) {
try {
- g->members.insert(EntCache<User>::instance.getEntry((const name_t &)*member)->id);
+ g->members.insert(instance.getEntry((const name_t &)*member)->id);
}
catch (const NetFS::SystemError &) {
}
@@ -126,11 +127,17 @@ Group::hasMember(uid_t u) const
return (members.find(u) != members.end());
}
-template<class T> const EntCache<T> EntCache<T>::instance;
-template class EntCache<User>;
+template EntCache<User>::EntCache();
+template EntCache<User>::~EntCache();
template IceUtil::Handle<User> EntCache<User>::getEntry<std::string>(const std::string &) const;
template IceUtil::Handle<User> EntCache<User>::getEntry<uid_t>(const uid_t &) const;
-template class EntCache<Group>;
+template void EntCache<User>::getName(const gid_t &, std::string *) const;
+template void EntCache<User>::getID(const std::string &, gid_t *) const;
+
+template EntCache<Group>::EntCache();
+template EntCache<Group>::~EntCache();
template IceUtil::Handle<Group> EntCache<Group>::getEntry<std::string>(const std::string &) const;
template IceUtil::Handle<Group> EntCache<Group>::getEntry<gid_t>(const gid_t &) const;
+template void EntCache<Group>::getName(const gid_t &, std::string *) const;
+template void EntCache<Group>::getID(const std::string &, gid_t *) const;
diff --git a/netfs/lib/entCache.h b/netfs/lib/entCache.h
index 443474f..40fc0c1 100644
--- a/netfs/lib/entCache.h
+++ b/netfs/lib/entCache.h
@@ -9,6 +9,7 @@
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/thread/shared_mutex.hpp>
+#include <typeConvert.h>
class User : public IceUtil::Shared {
public:
@@ -30,24 +31,21 @@ class Group : public IceUtil::Shared {
};
template<class entry_t>
-class EntCache {
+class EntCache : public EntryResolver<decltype(entry_t::id)> {
public:
typedef decltype(entry_t::id) id_t;
typedef decltype(entry_t::name) name_t;
typedef IceUtil::Handle<entry_t> entry_ptr;
+ EntCache();
virtual ~EntCache();
- void getID(const name_t &, id_t *) const;
- void getName(const id_t &, name_t *) const;
+ void getID(const name_t &, id_t *) const override;
+ void getName(const id_t &, name_t *) const override;
template<class key_t>
entry_ptr getEntry(const key_t &) const;
- static const EntCache<entry_t> instance;
-
protected:
- EntCache();
-
void fillCache() const;
template<class key_t>
entry_ptr getEntryNoFill(const key_t &) const;