Refactor DirEntries

This commit is contained in:
Sebastian Messmer 2016-03-15 21:06:12 +00:00
parent 5f8bf4cea4
commit 52d85f4de3
12 changed files with 257 additions and 128 deletions

View File

@ -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

View File

@ -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() {

View File

@ -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) {

View File

@ -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 {

View File

@ -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

View File

@ -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);

View File

@ -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;
}
}
}

View File

@ -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());
}
}
}

View File

@ -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);
}
}
}
}

View File

@ -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;

View 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

View File

@ -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 {