mirror of
https://github.com/vgough/encfs.git
synced 2024-11-25 09:23:13 +01:00
Simplify FileNode Cache. Remove the need for PlaceHolder.
- Store std::shared_ptr's directly, no need for PlaceHolder wrapper - Use std::forward_list to store shared_ptr's, the shared_ptr is guaranteed to be unique hence a set is an unnecessary overhead - Refactor code to use FileNode * instead of PlaceHolder *
This commit is contained in:
parent
ba9b25a1d2
commit
af64702dd0
@ -95,10 +95,9 @@ std::shared_ptr<FileNode> EncFS_Context::lookupNode(const char *path) {
|
|||||||
if (it != openFiles.end()) {
|
if (it != openFiles.end()) {
|
||||||
// all the items in the set point to the same node.. so just use the
|
// all the items in the set point to the same node.. so just use the
|
||||||
// first
|
// first
|
||||||
return (*it->second.begin())->node;
|
return it->second.front();
|
||||||
} else {
|
|
||||||
return std::shared_ptr<FileNode>();
|
|
||||||
}
|
}
|
||||||
|
return std::shared_ptr<FileNode>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EncFS_Context::renameNode(const char *from, const char *to) {
|
void EncFS_Context::renameNode(const char *from, const char *to) {
|
||||||
@ -106,36 +105,27 @@ void EncFS_Context::renameNode(const char *from, const char *to) {
|
|||||||
|
|
||||||
FileMap::iterator it = openFiles.find(std::string(from));
|
FileMap::iterator it = openFiles.find(std::string(from));
|
||||||
if (it != openFiles.end()) {
|
if (it != openFiles.end()) {
|
||||||
std::set<Placeholder *> val = it->second;
|
auto val = it->second;
|
||||||
openFiles.erase(it);
|
openFiles.erase(it);
|
||||||
openFiles[std::string(to)] = val;
|
openFiles[std::string(to)] = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::shared_ptr<FileNode> EncFS_Context::getNode(void *pl) {
|
|
||||||
Placeholder *ph = (Placeholder *)pl;
|
FileNode *EncFS_Context::putNode(const char *path,
|
||||||
return ph->node;
|
std::shared_ptr<FileNode> &&node) {
|
||||||
|
Lock lock(contextMutex);
|
||||||
|
auto &list = openFiles[std::string(path)];
|
||||||
|
list.push_front(std::move(node));
|
||||||
|
return list.front().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void *EncFS_Context::putNode(const char *path,
|
void EncFS_Context::eraseNode(const char *path, FileNode *pl) {
|
||||||
const std::shared_ptr<FileNode> &node) {
|
|
||||||
Lock lock(contextMutex);
|
Lock lock(contextMutex);
|
||||||
Placeholder *pl = new Placeholder(node);
|
|
||||||
openFiles[std::string(path)].insert(pl);
|
|
||||||
|
|
||||||
return (void *)pl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EncFS_Context::eraseNode(const char *path, void *pl) {
|
|
||||||
Lock lock(contextMutex);
|
|
||||||
|
|
||||||
Placeholder *ph = (Placeholder *)pl;
|
|
||||||
|
|
||||||
FileMap::iterator it = openFiles.find(std::string(path));
|
FileMap::iterator it = openFiles.find(std::string(path));
|
||||||
rAssert(it != openFiles.end());
|
rAssert(it != openFiles.end());
|
||||||
|
|
||||||
int rmCount = it->second.erase(ph);
|
it->second.pop_front();
|
||||||
|
|
||||||
rAssert(rmCount == 1);
|
|
||||||
|
|
||||||
// if no more references to this file, remove the record all together
|
// if no more references to this file, remove the record all together
|
||||||
if (it->second.empty()) {
|
if (it->second.empty()) {
|
||||||
@ -145,8 +135,6 @@ void EncFS_Context::eraseNode(const char *path, void *pl) {
|
|||||||
openFiles.erase(it);
|
openFiles.erase(it);
|
||||||
storedName.assign(storedName.length(), '\0');
|
storedName.assign(storedName.length(), '\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
delete ph;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace encfs
|
} // namespace encfs
|
||||||
|
@ -21,10 +21,10 @@
|
|||||||
#ifndef _Context_incl_
|
#ifndef _Context_incl_
|
||||||
#define _Context_incl_
|
#define _Context_incl_
|
||||||
|
|
||||||
|
#include <forward_list>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
@ -42,15 +42,14 @@ class EncFS_Context {
|
|||||||
EncFS_Context();
|
EncFS_Context();
|
||||||
~EncFS_Context();
|
~EncFS_Context();
|
||||||
|
|
||||||
std::shared_ptr<FileNode> getNode(void *ptr);
|
|
||||||
std::shared_ptr<FileNode> lookupNode(const char *path);
|
std::shared_ptr<FileNode> lookupNode(const char *path);
|
||||||
|
|
||||||
int getAndResetUsageCounter();
|
int getAndResetUsageCounter();
|
||||||
int openFileCount() const;
|
int openFileCount() const;
|
||||||
|
|
||||||
void *putNode(const char *path, const std::shared_ptr<FileNode> &node);
|
FileNode *putNode(const char *path, std::shared_ptr<FileNode> &&node);
|
||||||
|
|
||||||
void eraseNode(const char *path, void *placeholder);
|
void eraseNode(const char *path, FileNode *fnode);
|
||||||
|
|
||||||
void renameNode(const char *oldName, const char *newName);
|
void renameNode(const char *oldName, const char *newName);
|
||||||
|
|
||||||
@ -81,13 +80,9 @@ class EncFS_Context {
|
|||||||
* release() is called. std::shared_ptr then does our reference counting for
|
* release() is called. std::shared_ptr then does our reference counting for
|
||||||
* us.
|
* us.
|
||||||
*/
|
*/
|
||||||
struct Placeholder {
|
|
||||||
std::shared_ptr<FileNode> node;
|
|
||||||
|
|
||||||
Placeholder(const std::shared_ptr<FileNode> &ptr) : node(ptr) {}
|
typedef std::unordered_map<
|
||||||
};
|
std::string, std::forward_list<std::shared_ptr<FileNode>>> FileMap;
|
||||||
|
|
||||||
typedef std::unordered_map<std::string, std::set<Placeholder *> > FileMap;
|
|
||||||
|
|
||||||
mutable pthread_mutex_t contextMutex;
|
mutable pthread_mutex_t contextMutex;
|
||||||
FileMap openFiles;
|
FileMap openFiles;
|
||||||
|
@ -633,7 +633,6 @@ std::shared_ptr<FileNode> DirNode::renameNode(const char *from, const char *to,
|
|||||||
std::shared_ptr<FileNode> DirNode::findOrCreate(const char *plainName) {
|
std::shared_ptr<FileNode> DirNode::findOrCreate(const char *plainName) {
|
||||||
std::shared_ptr<FileNode> node;
|
std::shared_ptr<FileNode> node;
|
||||||
if (ctx) node = ctx->lookupNode(plainName);
|
if (ctx) node = ctx->lookupNode(plainName);
|
||||||
|
|
||||||
if (!node) {
|
if (!node) {
|
||||||
uint64_t iv = 0;
|
uint64_t iv = 0;
|
||||||
string cipherName = naming->encodePath(plainName, &iv);
|
string cipherName = naming->encodePath(plainName, &iv);
|
||||||
@ -647,14 +646,11 @@ std::shared_ptr<FileNode> DirNode::findOrCreate(const char *plainName) {
|
|||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
std::shared_ptr<FileNode> DirNode::lookupNode(const char *plainName,
|
|
||||||
const char *requestor) {
|
shared_ptr<FileNode> DirNode::lookupNode(const char *plainName,
|
||||||
(void)requestor;
|
const char * /* requestor */) {
|
||||||
Lock _lock(mutex);
|
Lock _lock(mutex);
|
||||||
|
return findOrCreate(plainName);
|
||||||
std::shared_ptr<FileNode> node = findOrCreate(plainName);
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -866,8 +866,7 @@ static void selectBlockMAC(int *macBytes, int *macRandBytes, bool forceMac) {
|
|||||||
"performance but it also means [almost] any modifications or errors\n"
|
"performance but it also means [almost] any modifications or errors\n"
|
||||||
"within a block will be caught and will cause a read error."));
|
"within a block will be caught and will cause a read error."));
|
||||||
} else {
|
} else {
|
||||||
cout << "\n\n"
|
cout << "\n\n" << _("You specified --require-macs. "
|
||||||
<< _("You specified --require-macs. "
|
|
||||||
"Enabling block authentication code headers...")
|
"Enabling block authentication code headers...")
|
||||||
<< "\n\n";
|
<< "\n\n";
|
||||||
addMAC = true;
|
addMAC = true;
|
||||||
|
@ -122,24 +122,25 @@ static int withFileNode(const char *opName, const char *path,
|
|||||||
if (!FSRoot) return res;
|
if (!FSRoot) return res;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
std::shared_ptr<FileNode> fnode;
|
|
||||||
|
|
||||||
if (fi != NULL)
|
auto do_op = [&FSRoot, opName, &op](FileNode *fnode) {
|
||||||
fnode = GET_FN(ctx, fi);
|
rAssert(fnode != nullptr);
|
||||||
else
|
|
||||||
fnode = FSRoot->lookupNode(path, opName);
|
|
||||||
|
|
||||||
rAssert(fnode.get() != NULL);
|
|
||||||
VLOG(1) << "op: " << opName << " : " << fnode->cipherName();
|
VLOG(1) << "op: " << opName << " : " << fnode->cipherName();
|
||||||
|
|
||||||
// check that we're not recursing into the mount point itself
|
// check that we're not recursing into the mount point itself
|
||||||
if (FSRoot->touchesMountpoint(fnode->cipherName())) {
|
if (FSRoot->touchesMountpoint(fnode->cipherName())) {
|
||||||
VLOG(1) << "op: " << opName << " error: Tried to touch mountpoint: '"
|
VLOG(1) << "op: " << opName << " error: Tried to touch mountpoint: '"
|
||||||
<< fnode->cipherName() << "'";
|
<< fnode->cipherName() << "'";
|
||||||
return res; // still -EIO
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
return op(fnode);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (fi != nullptr)
|
||||||
|
res = do_op(reinterpret_cast<FileNode *>(fi->fh));
|
||||||
|
else
|
||||||
|
res = do_op(FSRoot->lookupNode(path, opName).get());
|
||||||
|
|
||||||
res = op(fnode.get());
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
RLOG(DEBUG) << "op: " << opName << " error: " << strerror(-res);
|
RLOG(DEBUG) << "op: " << opName << " error: " << strerror(-res);
|
||||||
}
|
}
|
||||||
@ -522,7 +523,8 @@ int encfs_open(const char *path, struct fuse_file_info *file) {
|
|||||||
<< file->flags;
|
<< file->flags;
|
||||||
|
|
||||||
if (res >= 0) {
|
if (res >= 0) {
|
||||||
file->fh = (uintptr_t)ctx->putNode(path, fnode);
|
file->fh =
|
||||||
|
reinterpret_cast<uintptr_t>(ctx->putNode(path, std::move(fnode)));
|
||||||
res = ESUCCESS;
|
res = ESUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -571,7 +573,7 @@ int encfs_release(const char *path, struct fuse_file_info *finfo) {
|
|||||||
EncFS_Context *ctx = context();
|
EncFS_Context *ctx = context();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ctx->eraseNode(path, (void *)(uintptr_t)finfo->fh);
|
ctx->eraseNode(path, reinterpret_cast<FileNode *>(finfo->fh));
|
||||||
return ESUCCESS;
|
return ESUCCESS;
|
||||||
} catch (encfs::Error &err) {
|
} catch (encfs::Error &err) {
|
||||||
RLOG(ERROR) << "error caught in release: " << err.what();
|
RLOG(ERROR) << "error caught in release: " << err.what();
|
||||||
|
@ -182,29 +182,25 @@ static int showInfo(int argc, char **argv) {
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
case Config_V3:
|
case Config_V3:
|
||||||
// xgroup(diag)
|
// xgroup(diag)
|
||||||
cout << "\n"
|
cout << "\n" << autosprintf(_("Version 3 configuration; "
|
||||||
<< autosprintf(_("Version 3 configuration; "
|
|
||||||
"created by %s\n"),
|
"created by %s\n"),
|
||||||
config->creator.c_str());
|
config->creator.c_str());
|
||||||
break;
|
break;
|
||||||
case Config_V4:
|
case Config_V4:
|
||||||
// xgroup(diag)
|
// xgroup(diag)
|
||||||
cout << "\n"
|
cout << "\n" << autosprintf(_("Version 4 configuration; "
|
||||||
<< autosprintf(_("Version 4 configuration; "
|
|
||||||
"created by %s\n"),
|
"created by %s\n"),
|
||||||
config->creator.c_str());
|
config->creator.c_str());
|
||||||
break;
|
break;
|
||||||
case Config_V5:
|
case Config_V5:
|
||||||
// xgroup(diag)
|
// xgroup(diag)
|
||||||
cout << "\n"
|
cout << "\n" << autosprintf(_("Version 5 configuration; "
|
||||||
<< autosprintf(_("Version 5 configuration; "
|
|
||||||
"created by %s (revision %i)\n"),
|
"created by %s (revision %i)\n"),
|
||||||
config->creator.c_str(), config->subVersion);
|
config->creator.c_str(), config->subVersion);
|
||||||
break;
|
break;
|
||||||
case Config_V6:
|
case Config_V6:
|
||||||
// xgroup(diag)
|
// xgroup(diag)
|
||||||
cout << "\n"
|
cout << "\n" << autosprintf(_("Version 6 configuration; "
|
||||||
<< autosprintf(_("Version 6 configuration; "
|
|
||||||
"created by %s (revision %i)\n"),
|
"created by %s (revision %i)\n"),
|
||||||
config->creator.c_str(), config->subVersion);
|
config->creator.c_str(), config->subVersion);
|
||||||
break;
|
break;
|
||||||
|
@ -155,8 +155,7 @@ static void usage(const char *name) {
|
|||||||
" encfs ~/.crypt ~/crypt\n"
|
" encfs ~/.crypt ~/crypt\n"
|
||||||
"\n")
|
"\n")
|
||||||
// xgroup(usage)
|
// xgroup(usage)
|
||||||
<< _("For more information, see the man page encfs(1)") << "\n"
|
<< _("For more information, see the man page encfs(1)") << "\n" << endl;
|
||||||
<< endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FuseUsage() {
|
static void FuseUsage() {
|
||||||
|
Loading…
Reference in New Issue
Block a user