Refactor DirEntries
This commit is contained in:
parent
5f8bf4cea4
commit
52d85f4de3
@ -82,15 +82,15 @@ optional<unique_ref<fspp::Node>> CryDevice::Load(const bf::path &path) {
|
||||
}
|
||||
const auto &entry = *optEntry;
|
||||
|
||||
if (entry.type == fspp::Dir::EntryType::DIR) {
|
||||
return optional<unique_ref<fspp::Node>>(make_unique_ref<CryDir>(this, std::move(parent), entry.key));
|
||||
} else if (entry.type == fspp::Dir::EntryType::FILE) {
|
||||
return optional<unique_ref<fspp::Node>>(make_unique_ref<CryFile>(this, std::move(parent), entry.key));
|
||||
} else if (entry.type == fspp::Dir::EntryType::SYMLINK) {
|
||||
return optional<unique_ref<fspp::Node>>(make_unique_ref<CrySymlink>(this, std::move(parent), entry.key));
|
||||
} else {
|
||||
ASSERT(false, "Unknown entry type");
|
||||
switch(entry.type()) {
|
||||
case fspp::Dir::EntryType::DIR:
|
||||
return optional<unique_ref<fspp::Node>>(make_unique_ref<CryDir>(this, std::move(parent), entry.key()));
|
||||
case fspp::Dir::EntryType::FILE:
|
||||
return optional<unique_ref<fspp::Node>>(make_unique_ref<CryFile>(this, std::move(parent), entry.key()));
|
||||
case fspp::Dir::EntryType::SYMLINK:
|
||||
return optional<unique_ref<fspp::Node>>(make_unique_ref<CrySymlink>(this, std::move(parent), entry.key()));
|
||||
}
|
||||
ASSERT(false, "Switch/case not exhaustive");
|
||||
}
|
||||
|
||||
unique_ref<DirBlobRef> CryDevice::LoadDirBlob(const bf::path &path) {
|
||||
@ -119,7 +119,7 @@ unique_ref<FsBlobRef> CryDevice::LoadBlob(const bf::path &path) {
|
||||
if (childOpt == boost::none) {
|
||||
throw FuseErrnoException(ENOENT); // Child entry in directory not found
|
||||
}
|
||||
Key childKey = childOpt->key;
|
||||
Key childKey = childOpt->key();
|
||||
currentBlob = _fsBlobStore->load(childKey);
|
||||
if (currentBlob == none) {
|
||||
throw FuseErrnoException(ENOENT); // Blob for directory entry not found
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "CryDevice.h"
|
||||
#include "CryFile.h"
|
||||
#include "CryOpenFile.h"
|
||||
#include "fsblobstore/utils/time.h"
|
||||
|
||||
//TODO Get rid of this in favor of exception hierarchy
|
||||
using fspp::fuse::CHECK_RETVAL;
|
||||
@ -39,7 +40,8 @@ CryDir::~CryDir() {
|
||||
unique_ref<fspp::OpenFile> CryDir::createAndOpenFile(const string &name, mode_t mode, uid_t uid, gid_t gid) {
|
||||
device()->callFsActionCallbacks();
|
||||
auto child = device()->CreateFileBlob();
|
||||
LoadBlob()->AddChildFile(name, child->key(), mode, uid, gid);
|
||||
auto now = fsblobstore::time::now();
|
||||
LoadBlob()->AddChildFile(name, child->key(), mode, uid, gid, now, now);
|
||||
return make_unique_ref<CryOpenFile>(device(), std::move(child));
|
||||
}
|
||||
|
||||
@ -47,7 +49,8 @@ void CryDir::createDir(const string &name, mode_t mode, uid_t uid, gid_t gid) {
|
||||
device()->callFsActionCallbacks();
|
||||
auto blob = LoadBlob();
|
||||
auto child = device()->CreateDirBlob();
|
||||
blob->AddChildDir(name, child->key(), mode, uid, gid);
|
||||
auto now = fsblobstore::time::now();
|
||||
blob->AddChildDir(name, child->key(), mode, uid, gid, now, now);
|
||||
}
|
||||
|
||||
unique_ref<DirBlobRef> CryDir::LoadBlob() const {
|
||||
@ -76,7 +79,8 @@ void CryDir::createSymlink(const string &name, const bf::path &target, uid_t uid
|
||||
device()->callFsActionCallbacks();
|
||||
auto blob = LoadBlob();
|
||||
auto child = device()->CreateSymlinkBlob(target);
|
||||
blob->AddChildSymlink(name, child->key(), uid, gid);
|
||||
auto now = fsblobstore::time::now();
|
||||
blob->AddChildSymlink(name, child->key(), uid, gid, now, now);
|
||||
}
|
||||
|
||||
void CryDir::remove() {
|
||||
|
@ -56,13 +56,15 @@ void CryNode::rename(const bf::path &to) {
|
||||
throw FuseErrnoException(ENOENT);
|
||||
}
|
||||
const auto &old = *optOld;
|
||||
auto mode = old.mode;
|
||||
auto uid = old.uid;
|
||||
auto gid = old.gid;
|
||||
auto mode = old.mode();
|
||||
auto uid = old.uid();
|
||||
auto gid = old.gid();
|
||||
auto lastAccessTime = old.lastAccessTime();
|
||||
auto lastModificationTime = old.lastModificationTime();
|
||||
(*_parent)->RemoveChild(_key);
|
||||
(*_parent)->flush();
|
||||
auto targetDir = _device->LoadDirBlob(to.parent_path());
|
||||
targetDir->AddChild(to.filename().native(), _key, getType(), mode, uid, gid);
|
||||
targetDir->AddChild(to.filename().native(), _key, getType(), mode, uid, gid, lastAccessTime, lastModificationTime);
|
||||
}
|
||||
|
||||
void CryNode::utimens(timespec lastAccessTime, timespec lastModificationTime) {
|
||||
|
@ -39,8 +39,8 @@ public:
|
||||
}
|
||||
|
||||
void AddChild(const std::string &name, const blockstore::Key &blobKey, fspp::Dir::EntryType type,
|
||||
mode_t mode, uid_t uid, gid_t gid) {
|
||||
return _base->AddChild(name, blobKey, type, mode, uid, gid);
|
||||
mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) {
|
||||
return _base->AddChild(name, blobKey, type, mode, uid, gid, lastAccessTime, lastModificationTime);
|
||||
}
|
||||
|
||||
void statChild(const blockstore::Key &key, struct ::stat *result) const {
|
||||
@ -59,16 +59,16 @@ public:
|
||||
return _base->utimensChild(key, lastAccessTime, lastModificationTime);
|
||||
}
|
||||
|
||||
void AddChildDir(const std::string &name, const blockstore::Key &blobKey, mode_t mode, uid_t uid, gid_t gid) {
|
||||
return _base->AddChildDir(name, blobKey, mode, uid, gid);
|
||||
void AddChildDir(const std::string &name, const blockstore::Key &blobKey, mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) {
|
||||
return _base->AddChildDir(name, blobKey, mode, uid, gid, lastAccessTime, lastModificationTime);
|
||||
}
|
||||
|
||||
void AddChildFile(const std::string &name, const blockstore::Key &blobKey, mode_t mode, uid_t uid, gid_t gid) {
|
||||
return _base->AddChildFile(name, blobKey, mode, uid, gid);
|
||||
void AddChildFile(const std::string &name, const blockstore::Key &blobKey, mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) {
|
||||
return _base->AddChildFile(name, blobKey, mode, uid, gid, lastAccessTime, lastModificationTime);
|
||||
}
|
||||
|
||||
void AddChildSymlink(const std::string &name, const blockstore::Key &blobKey, uid_t uid, gid_t gid) {
|
||||
return _base->AddChildSymlink(name, blobKey, uid, gid);
|
||||
void AddChildSymlink(const std::string &name, const blockstore::Key &blobKey, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) {
|
||||
return _base->AddChildSymlink(name, blobKey, uid, gid, lastAccessTime, lastModificationTime);
|
||||
}
|
||||
|
||||
void AppendChildrenTo(std::vector<fspp::Dir::Entry> *result) const {
|
||||
|
@ -64,22 +64,22 @@ void DirBlob::_readEntriesFromBlob() {
|
||||
_entries.deserializeFrom(static_cast<uint8_t*>(data.data()), data.size());
|
||||
}
|
||||
|
||||
void DirBlob::AddChildDir(const std::string &name, const Key &blobKey, mode_t mode, uid_t uid, gid_t gid) {
|
||||
AddChild(name, blobKey, fspp::Dir::EntryType::DIR, mode, uid, gid);
|
||||
void DirBlob::AddChildDir(const std::string &name, const Key &blobKey, mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) {
|
||||
AddChild(name, blobKey, fspp::Dir::EntryType::DIR, mode, uid, gid, lastAccessTime, lastModificationTime);
|
||||
}
|
||||
|
||||
void DirBlob::AddChildFile(const std::string &name, const Key &blobKey, mode_t mode, uid_t uid, gid_t gid) {
|
||||
AddChild(name, blobKey, fspp::Dir::EntryType::FILE, mode, uid, gid);
|
||||
void DirBlob::AddChildFile(const std::string &name, const Key &blobKey, mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) {
|
||||
AddChild(name, blobKey, fspp::Dir::EntryType::FILE, mode, uid, gid, lastAccessTime, lastModificationTime);
|
||||
}
|
||||
|
||||
void DirBlob::AddChildSymlink(const std::string &name, const blockstore::Key &blobKey, uid_t uid, gid_t gid) {
|
||||
AddChild(name, blobKey, fspp::Dir::EntryType::SYMLINK, S_IFLNK | S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH, uid, gid);
|
||||
void DirBlob::AddChildSymlink(const std::string &name, const blockstore::Key &blobKey, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) {
|
||||
AddChild(name, blobKey, fspp::Dir::EntryType::SYMLINK, S_IFLNK | S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH, uid, gid, lastAccessTime, lastModificationTime);
|
||||
}
|
||||
|
||||
void DirBlob::AddChild(const std::string &name, const Key &blobKey,
|
||||
fspp::Dir::EntryType entryType, mode_t mode, uid_t uid, gid_t gid) {
|
||||
fspp::Dir::EntryType entryType, mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) {
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
_entries.add(name, blobKey, entryType, mode, uid, gid);
|
||||
_entries.add(name, blobKey, entryType, mode, uid, gid, lastAccessTime, lastModificationTime);
|
||||
_changed = true;
|
||||
}
|
||||
|
||||
@ -103,7 +103,7 @@ void DirBlob::AppendChildrenTo(vector<fspp::Dir::Entry> *result) const {
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
result->reserve(result->size() + _entries.size());
|
||||
for (const auto &entry : _entries) {
|
||||
result->emplace_back(entry.type, entry.name);
|
||||
result->emplace_back(entry.type(), entry.name());
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,19 +119,19 @@ void DirBlob::statChild(const Key &key, struct ::stat *result) const {
|
||||
const auto &child = *childOpt;
|
||||
//TODO Loading the blob for only getting the size of the file/symlink is not very performant.
|
||||
// Furthermore, this is the only reason why DirBlob needs a pointer to _fsBlobStore, which is ugly
|
||||
result->st_mode = child.mode;
|
||||
result->st_uid = child.uid;
|
||||
result->st_gid = child.gid;
|
||||
result->st_mode = child.mode();
|
||||
result->st_uid = child.uid();
|
||||
result->st_gid = child.gid();
|
||||
//TODO If possible without performance loss, then for a directory, st_nlink should return number of dir entries (including "." and "..")
|
||||
result->st_nlink = 1;
|
||||
#ifdef __APPLE__
|
||||
result->st_atimespec = child.lastAccessTime;
|
||||
result->st_mtimespec = child.lastModificationTime;
|
||||
result->st_ctimespec = child.lastMetadataChangeTime;
|
||||
result->st_atimespec = child.lastAccessTime();
|
||||
result->st_mtimespec = child.lastModificationTime();
|
||||
result->st_ctimespec = child.lastMetadataChangeTime();
|
||||
#else
|
||||
result->st_atim = child.lastAccessTime;
|
||||
result->st_mtim = child.lastModificationTime;
|
||||
result->st_ctim = child.lastMetadataChangeTime;
|
||||
result->st_atim = child.lastAccessTime();
|
||||
result->st_mtim = child.lastModificationTime();
|
||||
result->st_ctim = child.lastMetadataChangeTime();
|
||||
#endif
|
||||
result->st_size = _getLstatSize(key);
|
||||
//TODO Move ceilDivision to general utils which can be used by cryfs as well
|
||||
|
@ -36,16 +36,15 @@ namespace cryfs {
|
||||
boost::optional<const DirEntry&> GetChild(const blockstore::Key &key) const;
|
||||
|
||||
void AddChildDir(const std::string &name, const blockstore::Key &blobKey, mode_t mode, uid_t uid,
|
||||
gid_t gid);
|
||||
gid_t gid, timespec lastAccessTime, timespec lastModificationTime);
|
||||
|
||||
void AddChildFile(const std::string &name, const blockstore::Key &blobKey, mode_t mode, uid_t uid,
|
||||
gid_t gid);
|
||||
gid_t gid, timespec lastAccessTime, timespec lastModificationTime);
|
||||
|
||||
void AddChildSymlink(const std::string &name, const blockstore::Key &blobKey, uid_t uid, gid_t gid);
|
||||
void AddChildSymlink(const std::string &name, const blockstore::Key &blobKey, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime);
|
||||
|
||||
void AddChild(const std::string &name, const blockstore::Key &blobKey, fspp::Dir::EntryType type,
|
||||
mode_t mode,
|
||||
uid_t uid, gid_t gid);
|
||||
mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime);
|
||||
|
||||
void RemoveChild(const blockstore::Key &key);
|
||||
|
||||
|
@ -8,21 +8,22 @@ namespace cryfs {
|
||||
namespace fsblobstore {
|
||||
void DirEntry::serialize(uint8_t *dest) const {
|
||||
ASSERT(
|
||||
((type == fspp::Dir::EntryType::FILE) && S_ISREG(mode) && !S_ISDIR(mode) && !S_ISLNK(mode)) ||
|
||||
((type == fspp::Dir::EntryType::DIR) && !S_ISREG(mode) && S_ISDIR(mode) && !S_ISLNK(mode)) ||
|
||||
((type == fspp::Dir::EntryType::SYMLINK) && !S_ISREG(mode) && !S_ISDIR(mode) && S_ISLNK(mode))
|
||||
, "Wrong mode bit set for this type: "+std::to_string(mode & S_IFREG)+", "+std::to_string(mode&S_IFDIR)+", "+std::to_string(mode&S_IFLNK)+", "+std::to_string(static_cast<uint8_t>(type))
|
||||
((_type == fspp::Dir::EntryType::FILE) && S_ISREG(_mode) && !S_ISDIR(_mode) && !S_ISLNK(_mode)) ||
|
||||
((_type == fspp::Dir::EntryType::DIR) && !S_ISREG(_mode) && S_ISDIR(_mode) && !S_ISLNK(_mode)) ||
|
||||
((_type == fspp::Dir::EntryType::SYMLINK) && !S_ISREG(_mode) && !S_ISDIR(_mode) && S_ISLNK(_mode))
|
||||
, "Wrong mode bit set for this type: " + std::to_string(_mode & S_IFREG) + ", " + std::to_string(
|
||||
_mode & S_IFDIR) + ", " + std::to_string(_mode & S_IFLNK) + ", " + std::to_string(static_cast<uint8_t>(_type))
|
||||
);
|
||||
unsigned int offset = 0;
|
||||
offset += _serializeUint8(dest + offset, static_cast<uint8_t>(type));
|
||||
offset += _serializeUint32(dest + offset, mode);
|
||||
offset += _serializeUint32(dest + offset, uid);
|
||||
offset += _serializeUint32(dest + offset, gid);
|
||||
offset += _serializeTimeValue(dest + offset, lastAccessTime);
|
||||
offset += _serializeTimeValue(dest + offset, lastModificationTime);
|
||||
offset += _serializeTimeValue(dest + offset, lastMetadataChangeTime);
|
||||
offset += _serializeString(dest + offset, name);
|
||||
offset += _serializeKey(dest + offset, key);
|
||||
offset += _serializeUint8(dest + offset, static_cast<uint8_t>(_type));
|
||||
offset += _serializeUint32(dest + offset, _mode);
|
||||
offset += _serializeUint32(dest + offset, _uid);
|
||||
offset += _serializeUint32(dest + offset, _gid);
|
||||
offset += _serializeTimeValue(dest + offset, _lastAccessTime);
|
||||
offset += _serializeTimeValue(dest + offset, _lastModificationTime);
|
||||
offset += _serializeTimeValue(dest + offset, _lastMetadataChangeTime);
|
||||
offset += _serializeString(dest + offset, _name);
|
||||
offset += _serializeKey(dest + offset, _key);
|
||||
ASSERT(offset == serializedSize(), "Didn't write correct number of elements");
|
||||
}
|
||||
|
||||
@ -110,7 +111,8 @@ namespace cryfs {
|
||||
}
|
||||
|
||||
size_t DirEntry::serializedSize() const {
|
||||
return 1 + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) + 3*_serializedTimeValueSize() + (name.size() + 1) + key.BINARY_LENGTH;
|
||||
return 1 + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) + 3*_serializedTimeValueSize() + (
|
||||
_name.size() + 1) + _key.BINARY_LENGTH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,36 +4,48 @@
|
||||
|
||||
#include <blockstore/utils/Key.h>
|
||||
#include <fspp/fs_interface/Dir.h>
|
||||
#include "time.h"
|
||||
|
||||
namespace cryfs {
|
||||
namespace fsblobstore {
|
||||
|
||||
struct DirEntry final {
|
||||
DirEntry(fspp::Dir::EntryType type_, const std::string &name_, const blockstore::Key &key_, mode_t mode_,
|
||||
uid_t uid_, gid_t gid_, timespec lastAccessTime_, timespec lastModificationTime_,
|
||||
timespec lastMetadataChangeTime_) : type(type_), name(name_), key(key_), mode(mode_), uid(uid_),
|
||||
gid(gid_), lastAccessTime(lastAccessTime_),
|
||||
lastModificationTime(lastModificationTime_),
|
||||
lastMetadataChangeTime(lastMetadataChangeTime_) {
|
||||
switch (type) {
|
||||
case fspp::Dir::EntryType::FILE:
|
||||
mode |= S_IFREG;
|
||||
break;
|
||||
case fspp::Dir::EntryType::DIR:
|
||||
mode |= S_IFDIR;
|
||||
break;
|
||||
case fspp::Dir::EntryType::SYMLINK:
|
||||
mode |= S_IFLNK;
|
||||
break;
|
||||
}
|
||||
ASSERT((S_ISREG(mode) && type == fspp::Dir::EntryType::FILE) ||
|
||||
(S_ISDIR(mode) && type == fspp::Dir::EntryType::DIR) ||
|
||||
(S_ISLNK(mode) && type == fspp::Dir::EntryType::SYMLINK), "Unknown mode in entry");
|
||||
}
|
||||
class DirEntry final {
|
||||
public:
|
||||
DirEntry(fspp::Dir::EntryType type, const std::string &name, const blockstore::Key &key, mode_t mode,
|
||||
uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime,
|
||||
timespec lastMetadataChangeTime);
|
||||
|
||||
void serialize(uint8_t* dest) const;
|
||||
size_t serializedSize() const;
|
||||
static const char *deserializeAndAddToVector(const char *pos, std::vector<DirEntry> *result);
|
||||
|
||||
fspp::Dir::EntryType type() const;
|
||||
void setType(fspp::Dir::EntryType value);
|
||||
|
||||
const std::string &name() const;
|
||||
void setName(const std::string &value);
|
||||
|
||||
const blockstore::Key &key() const;
|
||||
|
||||
mode_t mode() const;
|
||||
void setMode(mode_t value);
|
||||
|
||||
uid_t uid() const;
|
||||
void setUid(uid_t value);
|
||||
|
||||
gid_t gid() const;
|
||||
void setGid(gid_t value);
|
||||
|
||||
timespec lastAccessTime() const;
|
||||
void setLastAccessTime(timespec value);
|
||||
|
||||
timespec lastModificationTime() const;
|
||||
void setLastModificationTime(timespec value);
|
||||
|
||||
timespec lastMetadataChangeTime() const;
|
||||
void setLastMetadataChangeTime(timespec value);
|
||||
|
||||
private:
|
||||
static size_t _serializedTimeValueSize();
|
||||
static unsigned int _serializeTimeValue(uint8_t *dest, timespec value);
|
||||
static unsigned int _serializeUint8(uint8_t *dest, uint8_t value);
|
||||
@ -46,17 +58,117 @@ namespace cryfs {
|
||||
static std::string _deserializeString(const char **pos);
|
||||
static blockstore::Key _deserializeKey(const char **pos);
|
||||
|
||||
fspp::Dir::EntryType type;
|
||||
std::string name;
|
||||
blockstore::Key key;
|
||||
mode_t mode;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
struct timespec lastAccessTime;
|
||||
struct timespec lastModificationTime;
|
||||
struct timespec lastMetadataChangeTime;
|
||||
void _updateLastMetadataChangeTime();
|
||||
|
||||
fspp::Dir::EntryType _type;
|
||||
std::string _name;
|
||||
blockstore::Key _key;
|
||||
mode_t _mode;
|
||||
uid_t _uid;
|
||||
gid_t _gid;
|
||||
timespec _lastAccessTime;
|
||||
timespec _lastModificationTime;
|
||||
timespec _lastMetadataChangeTime;
|
||||
};
|
||||
|
||||
inline DirEntry::DirEntry(fspp::Dir::EntryType type, const std::string &name, const blockstore::Key &key, mode_t mode,
|
||||
uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime,
|
||||
timespec lastMetadataChangeTime)
|
||||
: _type(type), _name(name), _key(key), _mode(mode), _uid(uid), _gid(gid), _lastAccessTime(lastAccessTime),
|
||||
_lastModificationTime(lastModificationTime), _lastMetadataChangeTime(lastMetadataChangeTime) {
|
||||
switch (_type) {
|
||||
case fspp::Dir::EntryType::FILE:
|
||||
_mode |= S_IFREG;
|
||||
break;
|
||||
case fspp::Dir::EntryType::DIR:
|
||||
_mode |= S_IFDIR;
|
||||
break;
|
||||
case fspp::Dir::EntryType::SYMLINK:
|
||||
_mode |= S_IFLNK;
|
||||
break;
|
||||
}
|
||||
ASSERT((S_ISREG(_mode) && _type == fspp::Dir::EntryType::FILE) ||
|
||||
(S_ISDIR(_mode) && _type == fspp::Dir::EntryType::DIR) ||
|
||||
(S_ISLNK(_mode) && _type == fspp::Dir::EntryType::SYMLINK), "Unknown mode in entry");
|
||||
}
|
||||
|
||||
inline fspp::Dir::EntryType DirEntry::type() const {
|
||||
return _type;
|
||||
}
|
||||
|
||||
inline const std::string &DirEntry::name() const {
|
||||
return _name;
|
||||
}
|
||||
|
||||
inline const blockstore::Key &DirEntry::key() const {
|
||||
return _key;
|
||||
}
|
||||
|
||||
inline mode_t DirEntry::mode() const {
|
||||
return _mode;
|
||||
}
|
||||
|
||||
inline uid_t DirEntry::uid() const {
|
||||
return _uid;
|
||||
}
|
||||
|
||||
inline gid_t DirEntry::gid() const {
|
||||
return _gid;
|
||||
}
|
||||
|
||||
inline timespec DirEntry::lastAccessTime() const {
|
||||
return _lastAccessTime;
|
||||
}
|
||||
|
||||
inline timespec DirEntry::lastModificationTime() const {
|
||||
return _lastModificationTime;
|
||||
}
|
||||
|
||||
inline timespec DirEntry::lastMetadataChangeTime() const {
|
||||
return _lastMetadataChangeTime;
|
||||
}
|
||||
|
||||
inline void DirEntry::setType(fspp::Dir::EntryType value) {
|
||||
_type = value;
|
||||
_updateLastMetadataChangeTime();
|
||||
}
|
||||
|
||||
inline void DirEntry::setName(const std::string &value) {
|
||||
_name = value;
|
||||
_updateLastMetadataChangeTime();
|
||||
}
|
||||
|
||||
inline void DirEntry::setMode(mode_t value) {
|
||||
_mode = value;
|
||||
_updateLastMetadataChangeTime();
|
||||
}
|
||||
|
||||
inline void DirEntry::setUid(uid_t value) {
|
||||
_uid = value;
|
||||
_updateLastMetadataChangeTime();
|
||||
}
|
||||
|
||||
inline void DirEntry::setGid(gid_t value) {
|
||||
_gid = value;
|
||||
_updateLastMetadataChangeTime();
|
||||
}
|
||||
|
||||
inline void DirEntry::setLastAccessTime(timespec value) {
|
||||
_lastAccessTime = value;
|
||||
}
|
||||
|
||||
inline void DirEntry::setLastModificationTime(timespec value) {
|
||||
_lastModificationTime = value;
|
||||
}
|
||||
|
||||
inline void DirEntry::setLastMetadataChangeTime(timespec value) {
|
||||
_lastMetadataChangeTime = value;
|
||||
}
|
||||
|
||||
inline void DirEntry::_updateLastMetadataChangeTime() {
|
||||
setLastMetadataChangeTime(time::now());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "DirEntryList.h"
|
||||
#include <limits>
|
||||
#include <cpp-utils/system/clock_gettime.h>
|
||||
#include "time.h"
|
||||
|
||||
//TODO Get rid of that in favor of better error handling
|
||||
#include <fspp/fuse/FuseErrnoException.h>
|
||||
@ -44,24 +44,23 @@ void DirEntryList::deserializeFrom(const void *data, uint64_t size) {
|
||||
|
||||
bool DirEntryList::_hasChild(const string &name) const {
|
||||
auto found = std::find_if(_entries.begin(), _entries.end(), [&name] (const DirEntry &entry) {
|
||||
return entry.name == name;
|
||||
return entry.name() == name;
|
||||
});
|
||||
return found != _entries.end();
|
||||
}
|
||||
|
||||
void DirEntryList::add(const string &name, const Key &blobKey, fspp::Dir::EntryType entryType, mode_t mode,
|
||||
uid_t uid, gid_t gid) {
|
||||
uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) {
|
||||
if (_hasChild(name)) {
|
||||
throw fspp::fuse::FuseErrnoException(EEXIST);
|
||||
}
|
||||
auto insert_pos = _findUpperBound(blobKey);
|
||||
auto now = _now();
|
||||
_entries.emplace(insert_pos, entryType, name, blobKey, mode, uid, gid, now, now, now);
|
||||
_entries.emplace(insert_pos, entryType, name, blobKey, mode, uid, gid, lastAccessTime, lastModificationTime, time::now());
|
||||
}
|
||||
|
||||
boost::optional<const DirEntry&> DirEntryList::get(const string &name) const {
|
||||
auto found = std::find_if(_entries.begin(), _entries.end(), [&name] (const DirEntry &entry) {
|
||||
return entry.name == name;
|
||||
return entry.name() == name;
|
||||
});
|
||||
if (found == _entries.end()) {
|
||||
return boost::none;
|
||||
@ -84,7 +83,7 @@ void DirEntryList::remove(const Key &key) {
|
||||
|
||||
vector<DirEntry>::iterator DirEntryList::_find(const Key &key) {
|
||||
auto found = _findLowerBound(key);
|
||||
if (found == _entries.end() || found->key != key) {
|
||||
if (found == _entries.end() || found->key() != key) {
|
||||
throw fspp::fuse::FuseErrnoException(ENOENT);
|
||||
}
|
||||
return found;
|
||||
@ -92,13 +91,13 @@ vector<DirEntry>::iterator DirEntryList::_find(const Key &key) {
|
||||
|
||||
vector<DirEntry>::iterator DirEntryList::_findLowerBound(const Key &key) {
|
||||
return _findFirst(key, [&key] (const DirEntry &entry) {
|
||||
return !std::less<Key>()(entry.key, key);
|
||||
return !std::less<Key>()(entry.key(), key);
|
||||
});
|
||||
}
|
||||
|
||||
vector<DirEntry>::iterator DirEntryList::_findUpperBound(const Key &key) {
|
||||
return _findFirst(key, [&key] (const DirEntry &entry) {
|
||||
return std::less<Key>()(key, entry.key);
|
||||
return std::less<Key>()(key, entry.key());
|
||||
});
|
||||
}
|
||||
|
||||
@ -137,39 +136,29 @@ DirEntryList::const_iterator DirEntryList::end() const {
|
||||
|
||||
void DirEntryList::setMode(const Key &key, mode_t mode) {
|
||||
auto found = _find(key);
|
||||
ASSERT ((S_ISREG(mode) && S_ISREG(found->mode)) || (S_ISDIR(mode) && S_ISDIR(found->mode)) || (S_ISLNK(mode)), "Unknown mode in entry");
|
||||
found->mode = mode;
|
||||
found->lastMetadataChangeTime = _now();
|
||||
ASSERT ((S_ISREG(mode) && S_ISREG(found->mode())) || (S_ISDIR(mode) && S_ISDIR(found->mode())) || (S_ISLNK(mode)), "Unknown mode in entry");
|
||||
found->setMode(mode);
|
||||
}
|
||||
|
||||
bool DirEntryList::setUidGid(const Key &key, uid_t uid, gid_t gid) {
|
||||
auto found = _find(key);
|
||||
bool changed = false;
|
||||
if (uid != (uid_t)-1) {
|
||||
found->uid = uid;
|
||||
found->lastMetadataChangeTime = _now();
|
||||
found->setUid(uid);
|
||||
changed = true;
|
||||
}
|
||||
if (gid != (gid_t)-1) {
|
||||
found->gid = gid;
|
||||
found->lastMetadataChangeTime = _now();
|
||||
found->setGid(gid);
|
||||
changed = true;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
timespec DirEntryList::_now() {
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_REALTIME, &now);
|
||||
return now;
|
||||
}
|
||||
|
||||
void DirEntryList::setAccessTimes(const blockstore::Key &key, timespec lastAccessTime, timespec lastModificationTime) {
|
||||
auto found = _find(key);
|
||||
found->lastAccessTime = lastAccessTime;
|
||||
found->lastModificationTime = lastModificationTime;
|
||||
found->lastMetadataChangeTime = lastModificationTime;
|
||||
found->setLastAccessTime(lastAccessTime);
|
||||
found->setLastModificationTime(lastModificationTime);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ namespace cryfs {
|
||||
void deserializeFrom(const void *data, uint64_t size);
|
||||
|
||||
void add(const std::string &name, const blockstore::Key &blobKey, fspp::Dir::EntryType entryType,
|
||||
mode_t mode, uid_t uid, gid_t gid);
|
||||
mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime);
|
||||
boost::optional<const DirEntry&> get(const std::string &name) const;
|
||||
boost::optional<const DirEntry&> get(const blockstore::Key &key) const;
|
||||
void remove(const blockstore::Key &key);
|
||||
@ -41,7 +41,6 @@ namespace cryfs {
|
||||
std::vector<DirEntry>::iterator _findUpperBound(const blockstore::Key &key);
|
||||
std::vector<DirEntry>::iterator _findLowerBound(const blockstore::Key &key);
|
||||
std::vector<DirEntry>::iterator _findFirst(const blockstore::Key &hint, std::function<bool (const DirEntry&)> pred);
|
||||
static timespec _now();
|
||||
|
||||
std::vector<DirEntry> _entries;
|
||||
|
||||
|
22
src/cryfs/filesystem/fsblobstore/utils/time.h
Normal file
22
src/cryfs/filesystem/fsblobstore/utils/time.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#ifndef MESSMER_CRYFS_FILESYTEM_FSBLOBSTORE_UTILS_TIME_H
|
||||
#define MESSMER_CRYFS_FILESYTEM_FSBLOBSTORE_UTILS_TIME_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <cpp-utils/system/clock_gettime.h>
|
||||
|
||||
namespace cryfs {
|
||||
namespace fsblobstore {
|
||||
namespace time {
|
||||
|
||||
inline timespec now() {
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_REALTIME, &now);
|
||||
return now;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -35,8 +35,8 @@ public:
|
||||
}
|
||||
|
||||
void AddChild(const std::string &name, const blockstore::Key &blobKey, fspp::Dir::EntryType type,
|
||||
mode_t mode, uid_t uid, gid_t gid) {
|
||||
return _base->AddChild(name, blobKey, type, mode, uid, gid);
|
||||
mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) {
|
||||
return _base->AddChild(name, blobKey, type, mode, uid, gid, lastAccessTime, lastModificationTime);
|
||||
}
|
||||
|
||||
void statChild(const blockstore::Key &key, struct ::stat *result) const {
|
||||
@ -55,16 +55,16 @@ public:
|
||||
return _base->utimensChild(key, lastAccessTime, lastModificationTime);
|
||||
}
|
||||
|
||||
void AddChildDir(const std::string &name, const blockstore::Key &blobKey, mode_t mode, uid_t uid, gid_t gid) {
|
||||
return _base->AddChildDir(name, blobKey, mode, uid, gid);
|
||||
void AddChildDir(const std::string &name, const blockstore::Key &blobKey, mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) {
|
||||
return _base->AddChildDir(name, blobKey, mode, uid, gid, lastAccessTime, lastModificationTime);
|
||||
}
|
||||
|
||||
void AddChildFile(const std::string &name, const blockstore::Key &blobKey, mode_t mode, uid_t uid, gid_t gid) {
|
||||
return _base->AddChildFile(name, blobKey, mode, uid, gid);
|
||||
void AddChildFile(const std::string &name, const blockstore::Key &blobKey, mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) {
|
||||
return _base->AddChildFile(name, blobKey, mode, uid, gid, lastAccessTime, lastModificationTime);
|
||||
}
|
||||
|
||||
void AddChildSymlink(const std::string &name, const blockstore::Key &blobKey, uid_t uid, gid_t gid) {
|
||||
return _base->AddChildSymlink(name, blobKey, uid, gid);
|
||||
void AddChildSymlink(const std::string &name, const blockstore::Key &blobKey, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) {
|
||||
return _base->AddChildSymlink(name, blobKey, uid, gid, lastAccessTime, lastModificationTime);
|
||||
}
|
||||
|
||||
void AppendChildrenTo(std::vector<fspp::Dir::Entry> *result) const {
|
||||
|
Loading…
x
Reference in New Issue
Block a user