diff --git a/src/CryDevice.cpp b/src/CryDevice.cpp index 6c03d193..16f116d7 100644 --- a/src/CryDevice.cpp +++ b/src/CryDevice.cpp @@ -28,7 +28,9 @@ using blobstore::onblocks::BlobStoreOnBlocks; using blobstore::onblocks::BlobOnBlocks; using blockstore::caching::CachingBlockStore; using cpputils::unique_ref; +using cpputils::make_unique_ref; using boost::optional; +using boost::none; namespace bf = boost::filesystem; @@ -71,44 +73,48 @@ unique_ptr CryDevice::Load(const bf::path &path) { if (path.parent_path().empty()) { //We are asked to load the root directory '/'. - return make_unique(this, nullptr, _rootKey); + return make_unique(this, none, _rootKey); } auto parent = LoadDirBlob(path.parent_path()); - auto entry = parent->GetChild(path.filename().native()); + if (parent == none) { + //TODO Return correct fuse error + return nullptr; + } + auto entry = (*parent)->GetChild(path.filename().native()); if (entry.type == fspp::Dir::EntryType::DIR) { - return make_unique(this, std::move(parent), entry.key); + return make_unique(this, std::move(*parent), entry.key); } else if (entry.type == fspp::Dir::EntryType::FILE) { - return make_unique(this, std::move(parent), entry.key); + return make_unique(this, std::move(*parent), entry.key); } else if (entry.type == fspp::Dir::EntryType::SYMLINK) { - return make_unique(this, std::move(parent), entry.key); + return make_unique(this, std::move(*parent), entry.key); } else { throw FuseErrnoException(EIO); } } -unique_ptr CryDevice::LoadDirBlob(const bf::path &path) { +optional> CryDevice::LoadDirBlob(const bf::path &path) { auto currentBlob = _blobStore->load(_rootKey); - if(!currentBlob) { + if(currentBlob == none) { //TODO Return correct fuse error - return nullptr; + return none; } for (const bf::path &component : path.relative_path()) { //TODO Check whether the next path component is a dir. // Right now, an assertion in DirBlob constructor will fail if it isn't. // But fuse should rather return the correct error code. - unique_ptr currentDir = make_unique(std::move(*currentBlob), this); + unique_ref currentDir = make_unique_ref(std::move(*currentBlob), this); Key childKey = currentDir->GetChild(component.c_str()).key; currentBlob = _blobStore->load(childKey); - if(!currentBlob) { + if(currentBlob == none) { //TODO Return correct fuse error - return nullptr; + return none; } } - return make_unique(std::move(*currentBlob), this); + return make_unique_ref(std::move(*currentBlob), this); } void CryDevice::statfs(const bf::path &path, struct statvfs *fsstat) { diff --git a/src/CryDevice.h b/src/CryDevice.h index 0865d6a2..0bbf3e0b 100644 --- a/src/CryDevice.h +++ b/src/CryDevice.h @@ -31,7 +31,7 @@ public: std::unique_ptr Load(const boost::filesystem::path &path) override; - std::unique_ptr LoadDirBlob(const boost::filesystem::path &path); + boost::optional> LoadDirBlob(const boost::filesystem::path &path); private: blockstore::Key GetOrCreateRootKey(CryConfig *config); diff --git a/src/CryDir.cpp b/src/CryDir.cpp index 49da7b36..296f557c 100644 --- a/src/CryDir.cpp +++ b/src/CryDir.cpp @@ -29,7 +29,7 @@ using boost::none; namespace cryfs { -CryDir::CryDir(CryDevice *device, unique_ptr parent, const Key &key) +CryDir::CryDir(CryDevice *device, boost::optional> parent, const Key &key) : CryNode(device, std::move(parent), key) { } diff --git a/src/CryDir.h b/src/CryDir.h index d141becf..34b61e3b 100644 --- a/src/CryDir.h +++ b/src/CryDir.h @@ -10,7 +10,7 @@ namespace cryfs { class CryDir: public fspp::Dir, CryNode { public: - CryDir(CryDevice *device, std::unique_ptr parent, const blockstore::Key &key); + CryDir(CryDevice *device, boost::optional> parent, const blockstore::Key &key); virtual ~CryDir(); //TODO return type variance to CryFile/CryDir? diff --git a/src/CryFile.cpp b/src/CryFile.cpp index bc75d2dc..da3cf853 100644 --- a/src/CryFile.cpp +++ b/src/CryFile.cpp @@ -16,10 +16,12 @@ using std::make_unique; using blockstore::Key; using boost::none; +using cpputils::unique_ref; +using cpputils::make_unique_ref; namespace cryfs { -CryFile::CryFile(CryDevice *device, unique_ptr parent, const Key &key) +CryFile::CryFile(CryDevice *device, unique_ref parent, const Key &key) : CryNode(device, std::move(parent), key) { } @@ -29,7 +31,7 @@ CryFile::~CryFile() { unique_ptr CryFile::open(int flags) const { auto blob = LoadBlob(); assert(blob != none); - return make_unique(make_unique(std::move(*blob))); + return make_unique(make_unique_ref(std::move(*blob))); } void CryFile::truncate(off_t size) const { diff --git a/src/CryFile.h b/src/CryFile.h index b25334c7..7fef5820 100644 --- a/src/CryFile.h +++ b/src/CryFile.h @@ -11,7 +11,7 @@ namespace cryfs { class CryFile: public fspp::File, CryNode { public: - CryFile(CryDevice *device, std::unique_ptr parent, const blockstore::Key &key); + CryFile(CryDevice *device, cpputils::unique_ref parent, const blockstore::Key &key); virtual ~CryFile(); std::unique_ptr open(int flags) const override; diff --git a/src/CryNode.cpp b/src/CryNode.cpp index b12b021a..289023da 100644 --- a/src/CryNode.cpp +++ b/src/CryNode.cpp @@ -16,6 +16,7 @@ using blobstore::Blob; using cpputils::dynamic_pointer_move; using cpputils::unique_ref; using boost::optional; +using boost::none; //TODO Get rid of this in favor of an exception hierarchy using fspp::fuse::CHECK_RETVAL; @@ -23,7 +24,7 @@ using fspp::fuse::FuseErrnoException; namespace cryfs { -CryNode::CryNode(CryDevice *device, unique_ptr parent, const Key &key) +CryNode::CryNode(CryDevice *device, optional> parent, const Key &key) : _device(device), _parent(std::move(parent)), _key(key) { @@ -39,16 +40,25 @@ void CryNode::access(int mask) const { } void CryNode::rename(const bf::path &to) { + if (_parent == none) { + //We are the root direcory. + //TODO What should we do? + throw FuseErrnoException(EIO); + } //TODO More efficient implementation possible: directly rename when it's actually not moved to a different directory // It's also quite ugly code because in the parent==targetDir case, it depends on _parent not overriding the changes made by targetDir. - auto old = _parent->GetChild(_key); + auto old = (*_parent)->GetChild(_key); auto mode = old.mode; auto uid = old.uid; auto gid = old.gid; - _parent->RemoveChild(_key); - _parent->flush(); + (*_parent)->RemoveChild(_key); + (*_parent)->flush(); auto targetDir = _device->LoadDirBlob(to.parent_path()); - targetDir->AddChild(to.filename().native(), _key, getType(), mode, uid, gid); + if (targetDir == none) { + //TODO Return correct fuse error + throw FuseErrnoException(ENOSPC); + } + (*targetDir)->AddChild(to.filename().native(), _key, getType(), mode, uid, gid); } void CryNode::utimens(const timespec times[2]) { @@ -57,7 +67,13 @@ void CryNode::utimens(const timespec times[2]) { } void CryNode::remove() { - _parent->RemoveChild(_key); + //TODO Instead of all these if-else and having _parent being an optional, we could also introduce a CryRootDir which inherits from fspp::Dir. + if (_parent == none) { + //We are the root direcory. + //TODO What should we do? + throw FuseErrnoException(EIO); + } + (*_parent)->RemoveChild(_key); _device->RemoveBlob(_key); } @@ -74,31 +90,31 @@ optional> CryNode::LoadBlob() const { } void CryNode::stat(struct ::stat *result) const { - if(_parent.get() == nullptr) { + if(_parent == none) { //We are the root directory. //TODO What should we do? result->st_mode = S_IFDIR; } else { - _parent->statChild(_key, result); + (*_parent)->statChild(_key, result); } } void CryNode::chmod(mode_t mode) { - if (_parent.get() == nullptr) { + if (_parent == none) { //We are the root direcory. //TODO What should we do? throw FuseErrnoException(EIO); } - _parent->chmodChild(_key, mode); + (*_parent)->chmodChild(_key, mode); } void CryNode::chown(uid_t uid, gid_t gid) { - if (_parent.get() == nullptr) { + if (_parent == none) { //We are the root direcory. //TODO What should we do? throw FuseErrnoException(EIO); } - _parent->chownChild(_key, uid, gid); + (*_parent)->chownChild(_key, uid, gid); } } diff --git a/src/CryNode.h b/src/CryNode.h index 80d0d787..1b0511bf 100644 --- a/src/CryNode.h +++ b/src/CryNode.h @@ -12,7 +12,7 @@ namespace cryfs { class CryNode: public virtual fspp::Node { public: - CryNode(CryDevice *device, std::unique_ptr parent, const blockstore::Key &key); + CryNode(CryDevice *device, boost::optional> parent, const blockstore::Key &key); void access(int mask) const override; void stat(struct ::stat *result) const override; void chmod(mode_t mode) override; @@ -33,7 +33,7 @@ protected: private: CryDevice *_device; - std::unique_ptr _parent; + boost::optional> _parent; blockstore::Key _key; DISALLOW_COPY_AND_ASSIGN(CryNode); diff --git a/src/CryOpenFile.cpp b/src/CryOpenFile.cpp index 742ced24..33e861ee 100644 --- a/src/CryOpenFile.cpp +++ b/src/CryOpenFile.cpp @@ -9,7 +9,7 @@ namespace bf = boost::filesystem; -using std::unique_ptr; +using cpputils::unique_ref; using blobstore::Blob; //TODO Get rid of this in favor of a exception hierarchy @@ -18,7 +18,7 @@ using fspp::fuse::FuseErrnoException; namespace cryfs { -CryOpenFile::CryOpenFile(unique_ptr fileBlob) +CryOpenFile::CryOpenFile(unique_ref fileBlob) : _fileBlob(std::move(fileBlob)) { } diff --git a/src/CryOpenFile.h b/src/CryOpenFile.h index 8efcaf6b..c3f5eaf9 100644 --- a/src/CryOpenFile.h +++ b/src/CryOpenFile.h @@ -3,7 +3,8 @@ #define CRYFS_LIB_CRYOPENFILE_H_ #include "messmer/fspp/fs_interface/OpenFile.h" -#include "messmer/cpp-utils/macros.h" +#include +#include namespace cryfs { class CryDevice; @@ -11,7 +12,7 @@ class FileBlob; class CryOpenFile: public fspp::OpenFile { public: - explicit CryOpenFile(std::unique_ptr fileBlob); + explicit CryOpenFile(cpputils::unique_ref fileBlob); virtual ~CryOpenFile(); void stat(struct ::stat *result) const override; @@ -23,7 +24,7 @@ public: void fdatasync() override; private: - std::unique_ptr _fileBlob; + cpputils::unique_ref _fileBlob; DISALLOW_COPY_AND_ASSIGN(CryOpenFile); }; diff --git a/src/CrySymlink.cpp b/src/CrySymlink.cpp index 076db199..82d59e25 100644 --- a/src/CrySymlink.cpp +++ b/src/CrySymlink.cpp @@ -18,10 +18,11 @@ using std::vector; using blockstore::Key; using boost::none; +using cpputils::unique_ref; namespace cryfs { -CrySymlink::CrySymlink(CryDevice *device, unique_ptr parent, const Key &key) +CrySymlink::CrySymlink(CryDevice *device, unique_ref parent, const Key &key) : CryNode(device, std::move(parent), key) { } diff --git a/src/CrySymlink.h b/src/CrySymlink.h index 995ee873..e0190213 100644 --- a/src/CrySymlink.h +++ b/src/CrySymlink.h @@ -11,7 +11,7 @@ namespace cryfs { class CrySymlink: public fspp::Symlink, CryNode { public: - CrySymlink(CryDevice *device, std::unique_ptr parent, const blockstore::Key &key); + CrySymlink(CryDevice *device, cpputils::unique_ref parent, const blockstore::Key &key); virtual ~CrySymlink(); boost::filesystem::path target() const override; diff --git a/src/impl/DirBlob.cpp b/src/impl/DirBlob.cpp index c5d67fd5..2564da5e 100644 --- a/src/impl/DirBlob.cpp +++ b/src/impl/DirBlob.cpp @@ -22,6 +22,7 @@ using blobstore::Blob; using blockstore::Key; using cpputils::Data; using cpputils::unique_ref; +using cpputils::make_unique_ref; using boost::none; namespace cryfs { @@ -42,11 +43,11 @@ void DirBlob::flush() { _blob->flush(); } -unique_ptr DirBlob::InitializeEmptyDir(unique_ref blob, CryDevice *device) { +unique_ref DirBlob::InitializeEmptyDir(unique_ref blob, CryDevice *device) { blob->resize(1); unsigned char magicNumber = MagicNumbers::DIR; blob->write(&magicNumber, 0, 1); - return make_unique(std::move(blob), device); + return make_unique_ref(std::move(blob), device); } unsigned char DirBlob::magicNumber() const { diff --git a/src/impl/DirBlob.h b/src/impl/DirBlob.h index 143abd8f..39303354 100644 --- a/src/impl/DirBlob.h +++ b/src/impl/DirBlob.h @@ -40,7 +40,7 @@ public: gid_t gid; }; - static std::unique_ptr InitializeEmptyDir(cpputils::unique_ref blob, CryDevice *device); + static cpputils::unique_ref InitializeEmptyDir(cpputils::unique_ref blob, CryDevice *device); DirBlob(cpputils::unique_ref blob, CryDevice *device); virtual ~DirBlob(); diff --git a/src/impl/FileBlob.cpp b/src/impl/FileBlob.cpp index fe66843b..8d8966ea 100644 --- a/src/impl/FileBlob.cpp +++ b/src/impl/FileBlob.cpp @@ -8,6 +8,7 @@ using std::unique_ptr; using std::make_unique; using blobstore::Blob; using cpputils::unique_ref; +using cpputils::make_unique_ref; namespace cryfs { @@ -18,12 +19,12 @@ FileBlob::FileBlob(unique_ref blob) FileBlob::~FileBlob() { } -unique_ptr FileBlob::InitializeEmptyFile(unique_ref blob) { +unique_ref FileBlob::InitializeEmptyFile(unique_ref blob) { assert(blob.get() != nullptr); blob->resize(1); unsigned char magicNumber = MagicNumbers::FILE; blob->write(&magicNumber, 0, 1); - return make_unique(std::move(blob)); + return make_unique_ref(std::move(blob)); } unsigned char FileBlob::magicNumber() const { diff --git a/src/impl/FileBlob.h b/src/impl/FileBlob.h index 8e30b07a..57f50234 100644 --- a/src/impl/FileBlob.h +++ b/src/impl/FileBlob.h @@ -10,7 +10,7 @@ namespace cryfs { class FileBlob { public: - static std::unique_ptr InitializeEmptyFile(cpputils::unique_ref blob); + static cpputils::unique_ref InitializeEmptyFile(cpputils::unique_ref blob); FileBlob(cpputils::unique_ref blob); virtual ~FileBlob(); diff --git a/src/impl/SymlinkBlob.cpp b/src/impl/SymlinkBlob.cpp index aca639b0..7d90eaab 100644 --- a/src/impl/SymlinkBlob.cpp +++ b/src/impl/SymlinkBlob.cpp @@ -9,6 +9,7 @@ using std::make_unique; using std::string; using blobstore::Blob; using cpputils::unique_ref; +using cpputils::make_unique_ref; namespace bf = boost::filesystem; @@ -24,14 +25,14 @@ SymlinkBlob::SymlinkBlob(const bf::path &target) :_target(target) { SymlinkBlob::~SymlinkBlob() { } -unique_ptr SymlinkBlob::InitializeSymlink(unique_ref blob, const bf::path &target) { +unique_ref SymlinkBlob::InitializeSymlink(unique_ref blob, const bf::path &target) { assert(blob.get() != nullptr); string targetStr = target.native(); blob->resize(1 + targetStr.size()); unsigned char magicNumber = MagicNumbers::SYMLINK; blob->write(&magicNumber, 0, 1); blob->write(targetStr.c_str(), 1, targetStr.size()); - return make_unique(target); + return make_unique_ref(target); } void SymlinkBlob::_checkMagicNumber(const Blob &blob) { diff --git a/src/impl/SymlinkBlob.h b/src/impl/SymlinkBlob.h index ac88e6a2..a12b3dac 100644 --- a/src/impl/SymlinkBlob.h +++ b/src/impl/SymlinkBlob.h @@ -11,7 +11,7 @@ namespace cryfs { class SymlinkBlob { public: - static std::unique_ptr InitializeSymlink(cpputils::unique_ref blob, const boost::filesystem::path &target); + static cpputils::unique_ref InitializeSymlink(cpputils::unique_ref blob, const boost::filesystem::path &target); SymlinkBlob(cpputils::unique_ref blob); SymlinkBlob(const boost::filesystem::path &target);