From 52d85f4de3504235cefc3b210e2fa5ec72916166 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Tue, 15 Mar 2016 21:06:12 +0000 Subject: [PATCH] Refactor DirEntries --- src/cryfs/filesystem/CryDevice.cpp | 18 +- src/cryfs/filesystem/CryDir.cpp | 10 +- src/cryfs/filesystem/CryNode.cpp | 10 +- .../cachingfsblobstore/DirBlobRef.h | 16 +- src/cryfs/filesystem/fsblobstore/DirBlob.cpp | 36 ++-- src/cryfs/filesystem/fsblobstore/DirBlob.h | 9 +- .../filesystem/fsblobstore/utils/DirEntry.cpp | 30 +-- .../filesystem/fsblobstore/utils/DirEntry.h | 174 ++++++++++++++---- .../fsblobstore/utils/DirEntryList.cpp | 41 ++--- .../fsblobstore/utils/DirEntryList.h | 3 +- src/cryfs/filesystem/fsblobstore/utils/time.h | 22 +++ .../parallelaccessfsblobstore/DirBlobRef.h | 16 +- 12 files changed, 257 insertions(+), 128 deletions(-) create mode 100644 src/cryfs/filesystem/fsblobstore/utils/time.h diff --git a/src/cryfs/filesystem/CryDevice.cpp b/src/cryfs/filesystem/CryDevice.cpp index 3fead795..1d010b08 100644 --- a/src/cryfs/filesystem/CryDevice.cpp +++ b/src/cryfs/filesystem/CryDevice.cpp @@ -82,15 +82,15 @@ optional> CryDevice::Load(const bf::path &path) { } const auto &entry = *optEntry; - if (entry.type == fspp::Dir::EntryType::DIR) { - return optional>(make_unique_ref(this, std::move(parent), entry.key)); - } else if (entry.type == fspp::Dir::EntryType::FILE) { - return optional>(make_unique_ref(this, std::move(parent), entry.key)); - } else if (entry.type == fspp::Dir::EntryType::SYMLINK) { - return optional>(make_unique_ref(this, std::move(parent), entry.key)); - } else { - ASSERT(false, "Unknown entry type"); + switch(entry.type()) { + case fspp::Dir::EntryType::DIR: + return optional>(make_unique_ref(this, std::move(parent), entry.key())); + case fspp::Dir::EntryType::FILE: + return optional>(make_unique_ref(this, std::move(parent), entry.key())); + case fspp::Dir::EntryType::SYMLINK: + return optional>(make_unique_ref(this, std::move(parent), entry.key())); } + ASSERT(false, "Switch/case not exhaustive"); } unique_ref CryDevice::LoadDirBlob(const bf::path &path) { @@ -119,7 +119,7 @@ unique_ref 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 diff --git a/src/cryfs/filesystem/CryDir.cpp b/src/cryfs/filesystem/CryDir.cpp index d0b92502..1ce6db2e 100644 --- a/src/cryfs/filesystem/CryDir.cpp +++ b/src/cryfs/filesystem/CryDir.cpp @@ -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 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(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 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() { diff --git a/src/cryfs/filesystem/CryNode.cpp b/src/cryfs/filesystem/CryNode.cpp index 3546d796..86885a23 100644 --- a/src/cryfs/filesystem/CryNode.cpp +++ b/src/cryfs/filesystem/CryNode.cpp @@ -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) { diff --git a/src/cryfs/filesystem/cachingfsblobstore/DirBlobRef.h b/src/cryfs/filesystem/cachingfsblobstore/DirBlobRef.h index b4ad5cf6..640289c2 100644 --- a/src/cryfs/filesystem/cachingfsblobstore/DirBlobRef.h +++ b/src/cryfs/filesystem/cachingfsblobstore/DirBlobRef.h @@ -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 *result) const { diff --git a/src/cryfs/filesystem/fsblobstore/DirBlob.cpp b/src/cryfs/filesystem/fsblobstore/DirBlob.cpp index 23101a2a..4b4cae47 100644 --- a/src/cryfs/filesystem/fsblobstore/DirBlob.cpp +++ b/src/cryfs/filesystem/fsblobstore/DirBlob.cpp @@ -64,22 +64,22 @@ void DirBlob::_readEntriesFromBlob() { _entries.deserializeFrom(static_cast(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 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 *result) const { std::unique_lock 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 diff --git a/src/cryfs/filesystem/fsblobstore/DirBlob.h b/src/cryfs/filesystem/fsblobstore/DirBlob.h index 92684a89..48669219 100644 --- a/src/cryfs/filesystem/fsblobstore/DirBlob.h +++ b/src/cryfs/filesystem/fsblobstore/DirBlob.h @@ -36,16 +36,15 @@ namespace cryfs { boost::optional 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); diff --git a/src/cryfs/filesystem/fsblobstore/utils/DirEntry.cpp b/src/cryfs/filesystem/fsblobstore/utils/DirEntry.cpp index f1dbae9f..69300c36 100644 --- a/src/cryfs/filesystem/fsblobstore/utils/DirEntry.cpp +++ b/src/cryfs/filesystem/fsblobstore/utils/DirEntry.cpp @@ -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(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(_type)) ); unsigned int offset = 0; - offset += _serializeUint8(dest + offset, static_cast(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(_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; } } } diff --git a/src/cryfs/filesystem/fsblobstore/utils/DirEntry.h b/src/cryfs/filesystem/fsblobstore/utils/DirEntry.h index b71ce9bb..88340371 100644 --- a/src/cryfs/filesystem/fsblobstore/utils/DirEntry.h +++ b/src/cryfs/filesystem/fsblobstore/utils/DirEntry.h @@ -4,36 +4,48 @@ #include #include +#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 *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()); + } + } } diff --git a/src/cryfs/filesystem/fsblobstore/utils/DirEntryList.cpp b/src/cryfs/filesystem/fsblobstore/utils/DirEntryList.cpp index 608ecf76..bc4ec303 100644 --- a/src/cryfs/filesystem/fsblobstore/utils/DirEntryList.cpp +++ b/src/cryfs/filesystem/fsblobstore/utils/DirEntryList.cpp @@ -1,6 +1,6 @@ #include "DirEntryList.h" #include -#include +#include "time.h" //TODO Get rid of that in favor of better error handling #include @@ -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 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::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::iterator DirEntryList::_find(const Key &key) { vector::iterator DirEntryList::_findLowerBound(const Key &key) { return _findFirst(key, [&key] (const DirEntry &entry) { - return !std::less()(entry.key, key); + return !std::less()(entry.key(), key); }); } vector::iterator DirEntryList::_findUpperBound(const Key &key) { return _findFirst(key, [&key] (const DirEntry &entry) { - return std::less()(key, entry.key); + return std::less()(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); } } -} \ No newline at end of file +} diff --git a/src/cryfs/filesystem/fsblobstore/utils/DirEntryList.h b/src/cryfs/filesystem/fsblobstore/utils/DirEntryList.h index 31d2bbc8..9d3bbed9 100644 --- a/src/cryfs/filesystem/fsblobstore/utils/DirEntryList.h +++ b/src/cryfs/filesystem/fsblobstore/utils/DirEntryList.h @@ -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 get(const std::string &name) const; boost::optional get(const blockstore::Key &key) const; void remove(const blockstore::Key &key); @@ -41,7 +41,6 @@ namespace cryfs { std::vector::iterator _findUpperBound(const blockstore::Key &key); std::vector::iterator _findLowerBound(const blockstore::Key &key); std::vector::iterator _findFirst(const blockstore::Key &hint, std::function pred); - static timespec _now(); std::vector _entries; diff --git a/src/cryfs/filesystem/fsblobstore/utils/time.h b/src/cryfs/filesystem/fsblobstore/utils/time.h new file mode 100644 index 00000000..f5311154 --- /dev/null +++ b/src/cryfs/filesystem/fsblobstore/utils/time.h @@ -0,0 +1,22 @@ +#pragma once +#ifndef MESSMER_CRYFS_FILESYTEM_FSBLOBSTORE_UTILS_TIME_H +#define MESSMER_CRYFS_FILESYTEM_FSBLOBSTORE_UTILS_TIME_H + +#include +#include + +namespace cryfs { + namespace fsblobstore { + namespace time { + + inline timespec now() { + struct timespec now; + clock_gettime(CLOCK_REALTIME, &now); + return now; + } + + } + } +} + +#endif diff --git a/src/cryfs/filesystem/parallelaccessfsblobstore/DirBlobRef.h b/src/cryfs/filesystem/parallelaccessfsblobstore/DirBlobRef.h index 3f93287e..87ce75c1 100644 --- a/src/cryfs/filesystem/parallelaccessfsblobstore/DirBlobRef.h +++ b/src/cryfs/filesystem/parallelaccessfsblobstore/DirBlobRef.h @@ -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 *result) const {