diff --git a/src/cryfs-cli/program_options/Parser.cpp b/src/cryfs-cli/program_options/Parser.cpp index 0fcf652a..90649ac3 100644 --- a/src/cryfs-cli/program_options/Parser.cpp +++ b/src/cryfs-cli/program_options/Parser.cpp @@ -83,6 +83,9 @@ ProgramOptions Parser::parse(const vector &supportedCiphers) const { if (vm.count("fuse-option")) { auto options = vm["fuse-option"].as>(); for (const auto& option: options) { + if (option == "noatime" || option == "atime") { + LOG(WARN, "CryFS currently doesn't support noatime/atime flags. Using relatime behavior."); + } fuseOptions.push_back("-o"); fuseOptions.push_back(option); } diff --git a/src/cryfs/filesystem/CryDir.cpp b/src/cryfs/filesystem/CryDir.cpp index 34e0bf9d..a534709f 100644 --- a/src/cryfs/filesystem/CryDir.cpp +++ b/src/cryfs/filesystem/CryDir.cpp @@ -10,6 +10,7 @@ #include "CryFile.h" #include "CryOpenFile.h" #include +#include "fsblobstore/utils/TimestampUpdateBehavior.h" //TODO Get rid of this in favor of exception hierarchy using fspp::fuse::CHECK_RETVAL; @@ -73,7 +74,7 @@ unique_ref> CryDir::children() { device()->callFsActionCallbacks(); if (!isRootDir()) { //TODO Instead of doing nothing when we're the root directory, handle timestamps in the root dir correctly (and delete isRootDir() function) - parent()->updateAccessTimestampForChild(key()); + parent()->updateAccessTimestampForChild(key(), fsblobstore::TimestampUpdateBehavior::RELATIME); } auto children = make_unique_ref>(); children->push_back(fspp::Dir::Entry(fspp::Dir::EntryType::DIR, ".")); diff --git a/src/cryfs/filesystem/CryOpenFile.cpp b/src/cryfs/filesystem/CryOpenFile.cpp index e0b7483d..a35a40e7 100644 --- a/src/cryfs/filesystem/CryOpenFile.cpp +++ b/src/cryfs/filesystem/CryOpenFile.cpp @@ -47,7 +47,7 @@ void CryOpenFile::truncate(off_t size) const { size_t CryOpenFile::read(void *buf, size_t count, off_t offset) const { _device->callFsActionCallbacks(); - //_parent->updateAccessTimestampForChild(_fileBlob->key()); + _parent->updateAccessTimestampForChild(_fileBlob->key(), fsblobstore::TimestampUpdateBehavior::RELATIME); return _fileBlob->read(buf, offset, count); } diff --git a/src/cryfs/filesystem/CrySymlink.cpp b/src/cryfs/filesystem/CrySymlink.cpp index 531870fc..40d70717 100644 --- a/src/cryfs/filesystem/CrySymlink.cpp +++ b/src/cryfs/filesystem/CrySymlink.cpp @@ -4,6 +4,7 @@ #include "CryDevice.h" #include "CrySymlink.h" #include "parallelaccessfsblobstore/SymlinkBlobRef.h" +#include "fsblobstore/utils/TimestampUpdateBehavior.h" //TODO Get rid of this in favor of exception hierarchy using fspp::fuse::CHECK_RETVAL; @@ -46,7 +47,7 @@ fspp::Dir::EntryType CrySymlink::getType() const { bf::path CrySymlink::target() { device()->callFsActionCallbacks(); - parent()->updateAccessTimestampForChild(key()); + parent()->updateAccessTimestampForChild(key(), fsblobstore::TimestampUpdateBehavior::RELATIME); auto blob = LoadBlob(); return blob->target(); } diff --git a/src/cryfs/filesystem/cachingfsblobstore/DirBlobRef.h b/src/cryfs/filesystem/cachingfsblobstore/DirBlobRef.h index e9517b24..0b7b7bbb 100644 --- a/src/cryfs/filesystem/cachingfsblobstore/DirBlobRef.h +++ b/src/cryfs/filesystem/cachingfsblobstore/DirBlobRef.h @@ -4,6 +4,7 @@ #include "FsBlobRef.h" #include "../fsblobstore/DirBlob.h" +#include "../fsblobstore/utils/TimestampUpdateBehavior.h" namespace cryfs { namespace cachingfsblobstore { @@ -60,8 +61,8 @@ public: return _base->statChildWithSizeAlreadySet(key, result); } - void updateAccessTimestampForChild(const blockstore::Key &key) { - return _base->updateAccessTimestampForChild(key); + void updateAccessTimestampForChild(const blockstore::Key &key, fsblobstore::TimestampUpdateBehavior timestampUpdateBehavior) { + return _base->updateAccessTimestampForChild(key, timestampUpdateBehavior); } void updateModificationTimestampForChild(const blockstore::Key &key) { diff --git a/src/cryfs/filesystem/fsblobstore/DirBlob.cpp b/src/cryfs/filesystem/fsblobstore/DirBlob.cpp index b1ac27ec..bd24e173 100644 --- a/src/cryfs/filesystem/fsblobstore/DirBlob.cpp +++ b/src/cryfs/filesystem/fsblobstore/DirBlob.cpp @@ -158,9 +158,9 @@ void DirBlob::statChildWithSizeAlreadySet(const Key &key, struct ::stat *result) result->st_blksize = _fsBlobStore->virtualBlocksizeBytes(); } -void DirBlob::updateAccessTimestampForChild(const Key &key) { +void DirBlob::updateAccessTimestampForChild(const Key &key, TimestampUpdateBehavior timestampUpdateBehavior) { std::unique_lock lock(_mutex); - _entries.updateAccessTimestampForChild(key); + _entries.updateAccessTimestampForChild(key, timestampUpdateBehavior); _changed = true; } diff --git a/src/cryfs/filesystem/fsblobstore/DirBlob.h b/src/cryfs/filesystem/fsblobstore/DirBlob.h index 322d36cf..3b81c5da 100644 --- a/src/cryfs/filesystem/fsblobstore/DirBlob.h +++ b/src/cryfs/filesystem/fsblobstore/DirBlob.h @@ -60,7 +60,7 @@ namespace cryfs { void statChildWithSizeAlreadySet(const blockstore::Key &key, struct ::stat *result) const; - void updateAccessTimestampForChild(const blockstore::Key &key); + void updateAccessTimestampForChild(const blockstore::Key &key, TimestampUpdateBehavior timestampUpdateBehavior); void updateModificationTimestampForChild(const blockstore::Key &key); diff --git a/src/cryfs/filesystem/fsblobstore/utils/DirEntry.h b/src/cryfs/filesystem/fsblobstore/utils/DirEntry.h index 16a000a1..4f3f04a8 100644 --- a/src/cryfs/filesystem/fsblobstore/utils/DirEntry.h +++ b/src/cryfs/filesystem/fsblobstore/utils/DirEntry.h @@ -7,8 +7,6 @@ #include #include -// TODO Implement (and test) atime, noatime, strictatime, relatime mount options - namespace cryfs { namespace fsblobstore { diff --git a/src/cryfs/filesystem/fsblobstore/utils/DirEntryList.cpp b/src/cryfs/filesystem/fsblobstore/utils/DirEntryList.cpp index 819b1cda..ab40c938 100644 --- a/src/cryfs/filesystem/fsblobstore/utils/DirEntryList.cpp +++ b/src/cryfs/filesystem/fsblobstore/utils/DirEntryList.cpp @@ -228,10 +228,18 @@ void DirEntryList::setAccessTimes(const blockstore::Key &key, timespec lastAcces found->setLastModificationTime(lastModificationTime); } -void DirEntryList::updateAccessTimestampForChild(const blockstore::Key &key) { +void DirEntryList::updateAccessTimestampForChild(const blockstore::Key &key, TimestampUpdateBehavior timestampUpdateBehavior) { + ASSERT(timestampUpdateBehavior == TimestampUpdateBehavior::RELATIME, "Currently only relatime supported"); auto found = _findByKey(key); - // TODO Think about implementing relatime behavior. Currently, CryFS follows strictatime. - found->setLastAccessTime(cpputils::time::now()); + const timespec lastAccessTime = found->lastAccessTime(); + const timespec lastModificationTime = found->lastModificationTime(); + const timespec now = cpputils::time::now(); + const timespec yesterday { + .tv_sec = now.tv_sec - 60*60*24, + .tv_nsec = now.tv_nsec + }; + if (lastAccessTime < lastModificationTime || lastAccessTime < yesterday) + found->setLastAccessTime(now); } void DirEntryList::updateModificationTimestampForChild(const blockstore::Key &key) { diff --git a/src/cryfs/filesystem/fsblobstore/utils/DirEntryList.h b/src/cryfs/filesystem/fsblobstore/utils/DirEntryList.h index 8f3e98dc..9df2325b 100644 --- a/src/cryfs/filesystem/fsblobstore/utils/DirEntryList.h +++ b/src/cryfs/filesystem/fsblobstore/utils/DirEntryList.h @@ -6,6 +6,7 @@ #include "DirEntry.h" #include #include +#include "TimestampUpdateBehavior.h" //TODO Address elements by name instead of by key when accessing them. Who knows whether there is two hard links for the same blob. @@ -39,7 +40,7 @@ namespace cryfs { void setMode(const blockstore::Key &key, mode_t mode); bool setUidGid(const blockstore::Key &key, uid_t uid, gid_t gid); void setAccessTimes(const blockstore::Key &key, timespec lastAccessTime, timespec lastModificationTime); - void updateAccessTimestampForChild(const blockstore::Key &key); + void updateAccessTimestampForChild(const blockstore::Key &key, TimestampUpdateBehavior timestampUpdateBehavior); void updateModificationTimestampForChild(const blockstore::Key &key); private: diff --git a/src/cryfs/filesystem/fsblobstore/utils/TimestampUpdateBehavior.h b/src/cryfs/filesystem/fsblobstore/utils/TimestampUpdateBehavior.h new file mode 100644 index 00000000..2c78f8b7 --- /dev/null +++ b/src/cryfs/filesystem/fsblobstore/utils/TimestampUpdateBehavior.h @@ -0,0 +1,17 @@ +#pragma once + +#ifndef CRYFS_TIMESTAMPUPDATEBEHAVIOR_H +#define CRYFS_TIMESTAMPUPDATEBEHAVIOR_H + +namespace cryfs { +namespace fsblobstore { + +enum class TimestampUpdateBehavior : uint8_t { + // currently only relatime supported + RELATIME +}; + +} +} + +#endif diff --git a/src/cryfs/filesystem/parallelaccessfsblobstore/DirBlobRef.h b/src/cryfs/filesystem/parallelaccessfsblobstore/DirBlobRef.h index 284064f2..7aa5ff64 100644 --- a/src/cryfs/filesystem/parallelaccessfsblobstore/DirBlobRef.h +++ b/src/cryfs/filesystem/parallelaccessfsblobstore/DirBlobRef.h @@ -4,6 +4,7 @@ #include "FsBlobRef.h" #include "../cachingfsblobstore/DirBlobRef.h" +#include "../fsblobstore/utils/TimestampUpdateBehavior.h" namespace cryfs { namespace parallelaccessfsblobstore { @@ -56,8 +57,8 @@ public: return _base->statChildWithSizeAlreadySet(key, result); } - void updateAccessTimestampForChild(const blockstore::Key &key) { - return _base->updateAccessTimestampForChild(key); + void updateAccessTimestampForChild(const blockstore::Key &key, fsblobstore::TimestampUpdateBehavior timestampUpdateBehavior) { + return _base->updateAccessTimestampForChild(key, timestampUpdateBehavior); } void updateModificationTimestampForChild(const blockstore::Key &key) {