Refactor: Add fsblobstore layer
This commit is contained in:
parent
dd39f242a2
commit
e3d2fdb2fd
|
@ -1,6 +1,6 @@
|
|||
#include <messmer/blockstore/implementations/caching/CachingBlockStore.h>
|
||||
#include <messmer/blockstore/implementations/encrypted/ciphers/ciphers.h>
|
||||
#include "impl/DirBlob.h"
|
||||
#include "fsblobstore/DirBlob.h"
|
||||
#include "CryDevice.h"
|
||||
|
||||
#include "CryDir.h"
|
||||
|
@ -11,6 +11,7 @@
|
|||
#include "messmer/blobstore/implementations/onblocks/BlobStoreOnBlocks.h"
|
||||
#include "messmer/blobstore/implementations/onblocks/BlobOnBlocks.h"
|
||||
#include "messmer/blockstore/implementations/encrypted/EncryptedBlockStore.h"
|
||||
#include "fsblobstore/FsBlobStore.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
|
@ -27,8 +28,14 @@ using blobstore::onblocks::BlobOnBlocks;
|
|||
using blockstore::caching::CachingBlockStore;
|
||||
using cpputils::unique_ref;
|
||||
using cpputils::make_unique_ref;
|
||||
using cpputils::dynamic_pointer_move;
|
||||
using boost::optional;
|
||||
using boost::none;
|
||||
using cryfs::fsblobstore::FsBlobStore;
|
||||
using cryfs::fsblobstore::FileBlob;
|
||||
using cryfs::fsblobstore::DirBlob;
|
||||
using cryfs::fsblobstore::SymlinkBlob;
|
||||
using cryfs::fsblobstore::FsBlob;
|
||||
|
||||
namespace bf = boost::filesystem;
|
||||
|
||||
|
@ -37,14 +44,16 @@ namespace cryfs {
|
|||
constexpr uint32_t CryDevice::BLOCKSIZE_BYTES;
|
||||
|
||||
CryDevice::CryDevice(unique_ref<CryConfig> config, unique_ref<BlockStore> blockStore)
|
||||
: _blobStore(make_unique_ref<BlobStoreOnBlocks>(make_unique_ref<CachingBlockStore>(CreateEncryptedBlockStore(*config, std::move(blockStore))), BLOCKSIZE_BYTES)), _rootKey(GetOrCreateRootKey(config.get())) {
|
||||
: _fsBlobStore(make_unique_ref<FsBlobStore>(
|
||||
make_unique_ref<BlobStoreOnBlocks>(
|
||||
make_unique_ref<CachingBlockStore>(
|
||||
CreateEncryptedBlockStore(*config, std::move(blockStore))
|
||||
), BLOCKSIZE_BYTES))),
|
||||
_rootKey(GetOrCreateRootKey(config.get())) {
|
||||
}
|
||||
|
||||
Key CryDevice::CreateRootBlobAndReturnKey() {
|
||||
auto rootBlob = _blobStore->create();
|
||||
Key rootBlobKey = rootBlob->key();
|
||||
DirBlob::InitializeEmptyDir(std::move(rootBlob), this);
|
||||
return rootBlobKey;
|
||||
return _fsBlobStore->createDirBlob()->key();
|
||||
}
|
||||
|
||||
CryDevice::~CryDevice() {
|
||||
|
@ -58,63 +67,73 @@ optional<unique_ref<fspp::Node>> CryDevice::Load(const bf::path &path) {
|
|||
return optional<unique_ref<fspp::Node>>(make_unique_ref<CryDir>(this, none, _rootKey));
|
||||
}
|
||||
auto parent = LoadDirBlob(path.parent_path());
|
||||
if (parent == none) {
|
||||
//TODO Return correct fuse error
|
||||
return none;
|
||||
}
|
||||
auto entry = (*parent)->GetChild(path.filename().native());
|
||||
auto entry = parent->GetChild(path.filename().native());
|
||||
|
||||
if (entry.type == fspp::Dir::EntryType::DIR) {
|
||||
return optional<unique_ref<fspp::Node>>(make_unique_ref<CryDir>(this, std::move(*parent), entry.key));
|
||||
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));
|
||||
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));
|
||||
return optional<unique_ref<fspp::Node>>(make_unique_ref<CrySymlink>(this, std::move(parent), entry.key));
|
||||
} else {
|
||||
ASSERT(false, "Unknown entry type");
|
||||
}
|
||||
}
|
||||
|
||||
optional<unique_ref<DirBlob>> CryDevice::LoadDirBlob(const bf::path &path) {
|
||||
auto currentBlob = _blobStore->load(_rootKey);
|
||||
if(currentBlob == none) {
|
||||
//TODO Return correct fuse error
|
||||
return none;
|
||||
}
|
||||
unique_ref<DirBlob> CryDevice::LoadDirBlob(const bf::path &path) {
|
||||
auto blob = LoadBlob(path);
|
||||
auto dir = dynamic_pointer_move<DirBlob>(blob);
|
||||
ASSERT(dir != none, "Loaded blob is not a directory");
|
||||
return std::move(*dir);
|
||||
}
|
||||
|
||||
unique_ref<FsBlob> CryDevice::LoadBlob(const bf::path &path) {
|
||||
auto currentBlob = _fsBlobStore->load(_rootKey);
|
||||
//TODO Return correct fuse error
|
||||
ASSERT(currentBlob != none, "rootDir not found");
|
||||
|
||||
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_ref<DirBlob> currentDir = make_unique_ref<DirBlob>(std::move(*currentBlob), this);
|
||||
auto currentDir = dynamic_pointer_move<DirBlob>(*currentBlob);
|
||||
ASSERT(currentDir != none, "Path component is not a dir");
|
||||
|
||||
Key childKey = currentDir->GetChild(component.c_str()).key;
|
||||
currentBlob = _blobStore->load(childKey);
|
||||
if(currentBlob == none) {
|
||||
//TODO Return correct fuse error
|
||||
return none;
|
||||
}
|
||||
Key childKey = (*currentDir)->GetChild(component.c_str()).key;
|
||||
currentBlob = _fsBlobStore->load(childKey);
|
||||
ASSERT(currentBlob != none, "Blob for directory entry not found");
|
||||
}
|
||||
|
||||
return make_unique_ref<DirBlob>(std::move(*currentBlob), this);
|
||||
return std::move(*currentBlob);
|
||||
|
||||
//TODO Running the python script, waiting for "Create files in sequential order...", then going into dir ~/tmp/cryfs-mount-.../Bonnie.../ and calling "ls"
|
||||
// crashes cryfs with a sigsegv.
|
||||
// Possible reason: Many parallel changes to a directory blob are a race condition. Need something like ParallelAccessStore!
|
||||
}
|
||||
|
||||
void CryDevice::statfs(const bf::path &path, struct statvfs *fsstat) {
|
||||
throw FuseErrnoException(ENOTSUP);
|
||||
}
|
||||
|
||||
unique_ref<blobstore::Blob> CryDevice::CreateBlob() {
|
||||
return _blobStore->create();
|
||||
unique_ref<FileBlob> CryDevice::CreateFileBlob() {
|
||||
return _fsBlobStore->createFileBlob();
|
||||
}
|
||||
|
||||
optional<unique_ref<blobstore::Blob>> CryDevice::LoadBlob(const blockstore::Key &key) {
|
||||
return _blobStore->load(key);
|
||||
unique_ref<DirBlob> CryDevice::CreateDirBlob() {
|
||||
return _fsBlobStore->createDirBlob();
|
||||
}
|
||||
|
||||
unique_ref<SymlinkBlob> CryDevice::CreateSymlinkBlob(const bf::path &target) {
|
||||
return _fsBlobStore->createSymlinkBlob(target);
|
||||
}
|
||||
|
||||
unique_ref<FsBlob> CryDevice::LoadBlob(const blockstore::Key &key) {
|
||||
auto blob = _fsBlobStore->load(key);
|
||||
ASSERT(blob != none, "Blob not found");
|
||||
return std::move(*blob);
|
||||
}
|
||||
|
||||
void CryDevice::RemoveBlob(const blockstore::Key &key) {
|
||||
auto blob = _blobStore->load(key);
|
||||
auto blob = _fsBlobStore->load(key);
|
||||
ASSERT(blob != none, "Blob not found");
|
||||
_blobStore->remove(std::move(*blob));
|
||||
_fsBlobStore->remove(std::move(*blob));
|
||||
}
|
||||
|
||||
Key CryDevice::GetOrCreateRootKey(CryConfig *config) {
|
||||
|
|
|
@ -3,16 +3,17 @@
|
|||
#define CRYFS_LIB_CRYDEVICE_H_
|
||||
|
||||
#include <messmer/blockstore/interface/BlockStore.h>
|
||||
#include <messmer/blobstore/interface/BlobStore.h>
|
||||
#include "../config/CryConfigLoader.h"
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <messmer/fspp/fs_interface/Device.h>
|
||||
|
||||
#include "messmer/cpp-utils/macros.h"
|
||||
#include "fsblobstore/FsBlobStore.h"
|
||||
#include "fsblobstore/DirBlob.h"
|
||||
#include "fsblobstore/FileBlob.h"
|
||||
#include "fsblobstore/SymlinkBlob.h"
|
||||
|
||||
namespace cryfs {
|
||||
class DirBlob;
|
||||
|
||||
class CryDevice: public fspp::Device {
|
||||
public:
|
||||
|
@ -23,17 +24,20 @@ public:
|
|||
|
||||
void statfs(const boost::filesystem::path &path, struct ::statvfs *fsstat) override;
|
||||
|
||||
cpputils::unique_ref<blobstore::Blob> CreateBlob();
|
||||
boost::optional<cpputils::unique_ref<blobstore::Blob>> LoadBlob(const blockstore::Key &key);
|
||||
cpputils::unique_ref<fsblobstore::FileBlob> CreateFileBlob();
|
||||
cpputils::unique_ref<fsblobstore::DirBlob> CreateDirBlob();
|
||||
cpputils::unique_ref<fsblobstore::SymlinkBlob> CreateSymlinkBlob(const boost::filesystem::path &target);
|
||||
cpputils::unique_ref<fsblobstore::FsBlob> LoadBlob(const blockstore::Key &key); //TODO Do I still need this function?
|
||||
cpputils::unique_ref<fsblobstore::FsBlob> LoadBlob(const boost::filesystem::path &path);
|
||||
cpputils::unique_ref<fsblobstore::DirBlob> LoadDirBlob(const boost::filesystem::path &path);
|
||||
void RemoveBlob(const blockstore::Key &key);
|
||||
|
||||
boost::optional<cpputils::unique_ref<fspp::Node>> Load(const boost::filesystem::path &path) override;
|
||||
|
||||
boost::optional<cpputils::unique_ref<DirBlob>> LoadDirBlob(const boost::filesystem::path &path);
|
||||
|
||||
private:
|
||||
|
||||
cpputils::unique_ref<blobstore::BlobStore> _blobStore;
|
||||
cpputils::unique_ref<fsblobstore::FsBlobStore> _fsBlobStore;
|
||||
|
||||
blockstore::Key _rootKey;
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "CryDevice.h"
|
||||
#include "CryFile.h"
|
||||
#include "CryOpenFile.h"
|
||||
#include "impl/SymlinkBlob.h"
|
||||
#include "fsblobstore/SymlinkBlob.h"
|
||||
|
||||
//TODO Get rid of this in favor of exception hierarchy
|
||||
using fspp::fuse::CHECK_RETVAL;
|
||||
|
@ -23,8 +23,10 @@ using std::vector;
|
|||
using blockstore::Key;
|
||||
using cpputils::unique_ref;
|
||||
using cpputils::make_unique_ref;
|
||||
using cpputils::dynamic_pointer_move;
|
||||
using boost::optional;
|
||||
using boost::none;
|
||||
using cryfs::fsblobstore::DirBlob;
|
||||
|
||||
namespace cryfs {
|
||||
|
||||
|
@ -37,36 +39,22 @@ CryDir::~CryDir() {
|
|||
|
||||
unique_ref<fspp::OpenFile> CryDir::createAndOpenFile(const string &name, mode_t mode, uid_t uid, gid_t gid) {
|
||||
auto blob = LoadBlob();
|
||||
if (blob == none) {
|
||||
//TODO Return correct fuse error
|
||||
throw FuseErrnoException(EIO);
|
||||
}
|
||||
auto child = device()->CreateBlob();
|
||||
Key childkey = child->key();
|
||||
(*blob)->AddChildFile(name, childkey, mode, uid, gid);
|
||||
auto childblob = FileBlob::InitializeEmptyFile(std::move(child));
|
||||
return make_unique_ref<CryOpenFile>(std::move(childblob));
|
||||
auto child = device()->CreateFileBlob();
|
||||
blob->AddChildFile(name, child->key(), mode, uid, gid);
|
||||
return make_unique_ref<CryOpenFile>(std::move(child));
|
||||
}
|
||||
|
||||
void CryDir::createDir(const string &name, mode_t mode, uid_t uid, gid_t gid) {
|
||||
auto blob = LoadBlob();
|
||||
if (blob == none) {
|
||||
//TODO Return correct fuse error
|
||||
throw FuseErrnoException(EIO);
|
||||
}
|
||||
auto child = device()->CreateBlob();
|
||||
Key childkey = child->key();
|
||||
(*blob)->AddChildDir(name, childkey, mode, uid, gid);
|
||||
DirBlob::InitializeEmptyDir(std::move(child), device());
|
||||
auto child = device()->CreateDirBlob();
|
||||
blob->AddChildDir(name, child->key(), mode, uid, gid);
|
||||
}
|
||||
|
||||
optional<unique_ref<DirBlob>> CryDir::LoadBlob() const {
|
||||
unique_ref<DirBlob> CryDir::LoadBlob() const {
|
||||
auto blob = CryNode::LoadBlob();
|
||||
if(blob == none) {
|
||||
return none;
|
||||
}
|
||||
//TODO Without const_cast?
|
||||
return make_unique_ref<DirBlob>(std::move(*blob), const_cast<CryDevice*>(device()));
|
||||
auto dir_blob = dynamic_pointer_move<DirBlob>(blob);
|
||||
ASSERT(dir_blob != none, "Blob does not store a directory");
|
||||
return std::move(*dir_blob);
|
||||
}
|
||||
|
||||
unique_ref<vector<fspp::Dir::Entry>> CryDir::children() const {
|
||||
|
@ -74,11 +62,7 @@ unique_ref<vector<fspp::Dir::Entry>> CryDir::children() const {
|
|||
children->push_back(fspp::Dir::Entry(fspp::Dir::EntryType::DIR, "."));
|
||||
children->push_back(fspp::Dir::Entry(fspp::Dir::EntryType::DIR, ".."));
|
||||
auto blob = LoadBlob();
|
||||
if (blob == none) {
|
||||
//TODO Return correct fuse error
|
||||
throw FuseErrnoException(EIO);
|
||||
}
|
||||
(*blob)->AppendChildrenTo(children.get());
|
||||
blob->AppendChildrenTo(children.get());
|
||||
return children;
|
||||
}
|
||||
|
||||
|
@ -88,14 +72,8 @@ fspp::Dir::EntryType CryDir::getType() const {
|
|||
|
||||
void CryDir::createSymlink(const string &name, const bf::path &target, uid_t uid, gid_t gid) {
|
||||
auto blob = LoadBlob();
|
||||
if (blob == none) {
|
||||
//TODO Return correct fuse error
|
||||
throw FuseErrnoException(EIO);
|
||||
}
|
||||
auto child = device()->CreateBlob();
|
||||
Key childkey = child->key();
|
||||
(*blob)->AddChildSymlink(name, childkey, uid, gid);
|
||||
SymlinkBlob::InitializeSymlink(std::move(child), target);
|
||||
auto child = device()->CreateSymlinkBlob(target);
|
||||
blob->AddChildSymlink(name, child->key(), uid, gid);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
|
||||
#include <messmer/fspp/fs_interface/Dir.h>
|
||||
#include "CryNode.h"
|
||||
#include "impl/DirBlob.h"
|
||||
#include "fsblobstore/DirBlob.h"
|
||||
|
||||
namespace cryfs {
|
||||
|
||||
class CryDir: public fspp::Dir, CryNode {
|
||||
public:
|
||||
CryDir(CryDevice *device, boost::optional<cpputils::unique_ref<DirBlob>> parent, const blockstore::Key &key);
|
||||
CryDir(CryDevice *device, boost::optional<cpputils::unique_ref<fsblobstore::DirBlob>> parent, const blockstore::Key &key);
|
||||
virtual ~CryDir();
|
||||
|
||||
//TODO return type variance to CryFile/CryDir?
|
||||
|
@ -24,7 +24,7 @@ public:
|
|||
fspp::Dir::EntryType getType() const override;
|
||||
|
||||
private:
|
||||
boost::optional<cpputils::unique_ref<DirBlob>> LoadBlob() const;
|
||||
cpputils::unique_ref<fsblobstore::DirBlob> LoadBlob() const;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CryDir);
|
||||
};
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include "CryDevice.h"
|
||||
#include "CryOpenFile.h"
|
||||
#include "messmer/fspp/fuse/FuseErrnoException.h"
|
||||
#include "impl/DirBlob.h"
|
||||
|
||||
namespace bf = boost::filesystem;
|
||||
|
||||
|
@ -15,6 +14,9 @@ using blockstore::Key;
|
|||
using boost::none;
|
||||
using cpputils::unique_ref;
|
||||
using cpputils::make_unique_ref;
|
||||
using cpputils::dynamic_pointer_move;
|
||||
using cryfs::fsblobstore::DirBlob;
|
||||
using cryfs::fsblobstore::FileBlob;
|
||||
|
||||
namespace cryfs {
|
||||
|
||||
|
@ -25,19 +27,21 @@ CryFile::CryFile(CryDevice *device, unique_ref<DirBlob> parent, const Key &key)
|
|||
CryFile::~CryFile() {
|
||||
}
|
||||
|
||||
unique_ref<fsblobstore::FileBlob> CryFile::LoadBlob() const {
|
||||
auto blob = CryNode::LoadBlob();
|
||||
auto file_blob = dynamic_pointer_move<FileBlob>(blob);
|
||||
ASSERT(file_blob != none, "Blob does not store a file");
|
||||
return std::move(*file_blob);
|
||||
}
|
||||
|
||||
unique_ref<fspp::OpenFile> CryFile::open(int flags) const {
|
||||
auto blob = LoadBlob();
|
||||
ASSERT(blob != none, "Couldn't load blob");
|
||||
return make_unique_ref<CryOpenFile>(make_unique_ref<FileBlob>(std::move(*blob)));
|
||||
return make_unique_ref<CryOpenFile>(std::move(blob));
|
||||
}
|
||||
|
||||
void CryFile::truncate(off_t size) const {
|
||||
auto blob = LoadBlob();
|
||||
if (blob == none) {
|
||||
//TODO Log error
|
||||
return;
|
||||
}
|
||||
FileBlob(std::move(*blob)).resize(size);
|
||||
blob->resize(size);
|
||||
}
|
||||
|
||||
fspp::Dir::EntryType CryFile::getType() const {
|
||||
|
|
|
@ -2,16 +2,16 @@
|
|||
#ifndef CRYFS_LIB_CRYFILE_H_
|
||||
#define CRYFS_LIB_CRYFILE_H_
|
||||
|
||||
#include "impl/FileBlob.h"
|
||||
#include "fsblobstore/FileBlob.h"
|
||||
#include "fsblobstore/DirBlob.h"
|
||||
#include <messmer/fspp/fs_interface/File.h>
|
||||
#include "CryNode.h"
|
||||
|
||||
|
||||
namespace cryfs {
|
||||
|
||||
class CryFile: public fspp::File, CryNode {
|
||||
public:
|
||||
CryFile(CryDevice *device, cpputils::unique_ref<DirBlob> parent, const blockstore::Key &key);
|
||||
CryFile(CryDevice *device, cpputils::unique_ref<fsblobstore::DirBlob> parent, const blockstore::Key &key);
|
||||
virtual ~CryFile();
|
||||
|
||||
cpputils::unique_ref<fspp::OpenFile> open(int flags) const override;
|
||||
|
@ -19,6 +19,7 @@ public:
|
|||
fspp::Dir::EntryType getType() const override;
|
||||
|
||||
private:
|
||||
cpputils::unique_ref<fsblobstore::FileBlob> LoadBlob() const;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CryFile);
|
||||
};
|
||||
|
|
|
@ -16,6 +16,8 @@ using cpputils::dynamic_pointer_move;
|
|||
using cpputils::unique_ref;
|
||||
using boost::optional;
|
||||
using boost::none;
|
||||
using cryfs::fsblobstore::FsBlob;
|
||||
using cryfs::fsblobstore::DirBlob;
|
||||
|
||||
//TODO Get rid of this in favor of an exception hierarchy
|
||||
using fspp::fuse::CHECK_RETVAL;
|
||||
|
@ -53,11 +55,7 @@ void CryNode::rename(const bf::path &to) {
|
|||
(*_parent)->RemoveChild(_key);
|
||||
(*_parent)->flush();
|
||||
auto targetDir = _device->LoadDirBlob(to.parent_path());
|
||||
if (targetDir == none) {
|
||||
//TODO Return correct fuse error
|
||||
throw FuseErrnoException(ENOSPC);
|
||||
}
|
||||
(*targetDir)->AddChild(to.filename().native(), _key, getType(), mode, uid, gid);
|
||||
targetDir->AddChild(to.filename().native(), _key, getType(), mode, uid, gid);
|
||||
}
|
||||
|
||||
void CryNode::utimens(const timespec times[2]) {
|
||||
|
@ -84,7 +82,7 @@ const CryDevice *CryNode::device() const {
|
|||
return _device;
|
||||
}
|
||||
|
||||
optional<unique_ref<Blob>> CryNode::LoadBlob() const {
|
||||
unique_ref<FsBlob> CryNode::LoadBlob() const {
|
||||
return _device->LoadBlob(_key);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
#include <messmer/fspp/fs_interface/Node.h>
|
||||
#include "messmer/cpp-utils/macros.h"
|
||||
#include <messmer/fspp/fs_interface/Dir.h>
|
||||
|
||||
#include "fsblobstore/DirBlob.h"
|
||||
#include "CryDevice.h"
|
||||
|
||||
namespace cryfs {
|
||||
|
||||
class CryNode: public virtual fspp::Node {
|
||||
public:
|
||||
CryNode(CryDevice *device, boost::optional<cpputils::unique_ref<DirBlob>> parent, const blockstore::Key &key);
|
||||
CryNode(CryDevice *device, boost::optional<cpputils::unique_ref<fsblobstore::DirBlob>> parent, const blockstore::Key &key);
|
||||
void access(int mask) const override;
|
||||
void stat(struct ::stat *result) const override;
|
||||
void chmod(mode_t mode) override;
|
||||
|
@ -27,13 +27,13 @@ protected:
|
|||
|
||||
CryDevice *device();
|
||||
const CryDevice *device() const;
|
||||
boost::optional<cpputils::unique_ref<blobstore::Blob>> LoadBlob() const;
|
||||
cpputils::unique_ref<fsblobstore::FsBlob> LoadBlob() const;
|
||||
|
||||
virtual fspp::Dir::EntryType getType() const = 0;
|
||||
|
||||
private:
|
||||
CryDevice *_device;
|
||||
boost::optional<cpputils::unique_ref<DirBlob>> _parent;
|
||||
boost::optional<cpputils::unique_ref<fsblobstore::DirBlob>> _parent;
|
||||
blockstore::Key _key;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CryNode);
|
||||
|
|
|
@ -5,12 +5,11 @@
|
|||
|
||||
#include "CryDevice.h"
|
||||
#include "messmer/fspp/fuse/FuseErrnoException.h"
|
||||
#include "impl/FileBlob.h"
|
||||
|
||||
namespace bf = boost::filesystem;
|
||||
|
||||
using cpputils::unique_ref;
|
||||
using blobstore::Blob;
|
||||
using cryfs::fsblobstore::FileBlob;
|
||||
|
||||
//TODO Get rid of this in favor of a exception hierarchy
|
||||
using fspp::fuse::CHECK_RETVAL;
|
||||
|
|
|
@ -3,16 +3,14 @@
|
|||
#define CRYFS_LIB_CRYOPENFILE_H_
|
||||
|
||||
#include "messmer/fspp/fs_interface/OpenFile.h"
|
||||
#include <messmer/cpp-utils/macros.h>
|
||||
#include <messmer/cpp-utils/pointer/unique_ref.h>
|
||||
#include "fsblobstore/FileBlob.h"
|
||||
|
||||
namespace cryfs {
|
||||
class CryDevice;
|
||||
class FileBlob;
|
||||
|
||||
class CryOpenFile: public fspp::OpenFile {
|
||||
public:
|
||||
explicit CryOpenFile(cpputils::unique_ref<FileBlob> fileBlob);
|
||||
explicit CryOpenFile(cpputils::unique_ref<fsblobstore::FileBlob> fileBlob);
|
||||
virtual ~CryOpenFile();
|
||||
|
||||
void stat(struct ::stat *result) const override;
|
||||
|
@ -24,7 +22,7 @@ public:
|
|||
void fdatasync() override;
|
||||
|
||||
private:
|
||||
cpputils::unique_ref<FileBlob> _fileBlob;
|
||||
cpputils::unique_ref<fsblobstore::FileBlob> _fileBlob;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CryOpenFile);
|
||||
};
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "messmer/fspp/fuse/FuseErrnoException.h"
|
||||
#include "CryDevice.h"
|
||||
#include "CrySymlink.h"
|
||||
#include "impl/SymlinkBlob.h"
|
||||
#include "fsblobstore/SymlinkBlob.h"
|
||||
|
||||
//TODO Get rid of this in favor of exception hierarchy
|
||||
using fspp::fuse::CHECK_RETVAL;
|
||||
|
@ -19,6 +19,9 @@ using boost::none;
|
|||
using boost::optional;
|
||||
using cpputils::unique_ref;
|
||||
using cpputils::make_unique_ref;
|
||||
using cpputils::dynamic_pointer_move;
|
||||
using cryfs::fsblobstore::SymlinkBlob;
|
||||
using cryfs::fsblobstore::DirBlob;
|
||||
|
||||
namespace cryfs {
|
||||
|
||||
|
@ -29,12 +32,11 @@ CrySymlink::CrySymlink(CryDevice *device, unique_ref<DirBlob> parent, const Key
|
|||
CrySymlink::~CrySymlink() {
|
||||
}
|
||||
|
||||
optional<unique_ref<SymlinkBlob>> CrySymlink::LoadBlob() const {
|
||||
unique_ref<SymlinkBlob> CrySymlink::LoadBlob() const {
|
||||
auto blob = CryNode::LoadBlob();
|
||||
if (blob == none) {
|
||||
return none;
|
||||
}
|
||||
return make_unique_ref<SymlinkBlob>(std::move(*blob));
|
||||
auto symlink_blob = dynamic_pointer_move<SymlinkBlob>(blob);
|
||||
ASSERT(symlink_blob != none, "Blob does not store a symlink");
|
||||
return std::move(*symlink_blob);
|
||||
}
|
||||
|
||||
fspp::Dir::EntryType CrySymlink::getType() const {
|
||||
|
@ -43,11 +45,7 @@ fspp::Dir::EntryType CrySymlink::getType() const {
|
|||
|
||||
bf::path CrySymlink::target() const {
|
||||
auto blob = LoadBlob();
|
||||
if (blob == none) {
|
||||
//TODO Return correct fuse error
|
||||
throw FuseErrnoException(EIO);
|
||||
}
|
||||
return (*blob)->target();
|
||||
return blob->target();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,14 +4,14 @@
|
|||
|
||||
#include <messmer/fspp/fs_interface/Symlink.h>
|
||||
#include "CryNode.h"
|
||||
#include "impl/SymlinkBlob.h"
|
||||
#include "impl/DirBlob.h"
|
||||
#include "fsblobstore/SymlinkBlob.h"
|
||||
#include "fsblobstore/DirBlob.h"
|
||||
|
||||
namespace cryfs {
|
||||
|
||||
class CrySymlink: public fspp::Symlink, CryNode {
|
||||
public:
|
||||
CrySymlink(CryDevice *device, cpputils::unique_ref<DirBlob> parent, const blockstore::Key &key);
|
||||
CrySymlink(CryDevice *device, cpputils::unique_ref<fsblobstore::DirBlob> parent, const blockstore::Key &key);
|
||||
virtual ~CrySymlink();
|
||||
|
||||
boost::filesystem::path target() const override;
|
||||
|
@ -19,7 +19,7 @@ public:
|
|||
fspp::Dir::EntryType getType() const override;
|
||||
|
||||
private:
|
||||
boost::optional<cpputils::unique_ref<SymlinkBlob>> LoadBlob() const;
|
||||
cpputils::unique_ref<fsblobstore::SymlinkBlob> LoadBlob() const;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CrySymlink);
|
||||
};
|
||||
|
|
|
@ -24,9 +24,12 @@ using cpputils::make_unique_ref;
|
|||
using boost::none;
|
||||
|
||||
namespace cryfs {
|
||||
namespace fsblobstore {
|
||||
|
||||
DirBlob::DirBlob(unique_ref<Blob> blob, CryDevice *device) :
|
||||
_device(device), _blob(std::move(blob)), _entries(), _changed(false) {
|
||||
//TODO Factor out a DirEntryList class
|
||||
|
||||
DirBlob::DirBlob(unique_ref<Blob> blob, FsBlobStore *fsBlobStore) :
|
||||
FsBlob(std::move(blob)), _fsBlobStore(fsBlobStore), _entries(), _changed(false) {
|
||||
ASSERT(magicNumber() == MagicNumbers::DIR, "Loaded blob is not a directory");
|
||||
_readEntriesFromBlob();
|
||||
}
|
||||
|
@ -37,43 +40,35 @@ DirBlob::~DirBlob() {
|
|||
|
||||
void DirBlob::flush() {
|
||||
_writeEntriesToBlob();
|
||||
_blob->flush();
|
||||
baseBlob().flush();
|
||||
}
|
||||
|
||||
unique_ref<DirBlob> DirBlob::InitializeEmptyDir(unique_ref<Blob> blob, CryDevice *device) {
|
||||
blob->resize(1);
|
||||
unsigned char magicNumber = MagicNumbers::DIR;
|
||||
blob->write(&magicNumber, 0, 1);
|
||||
return make_unique_ref<DirBlob>(std::move(blob), device);
|
||||
}
|
||||
|
||||
unsigned char DirBlob::magicNumber() const {
|
||||
unsigned char number;
|
||||
_blob->read(&number, 0, 1);
|
||||
return number;
|
||||
unique_ref<DirBlob> DirBlob::InitializeEmptyDir(unique_ref<Blob> blob, FsBlobStore *fsBlobStore) {
|
||||
InitializeBlobWithMagicNumber(blob.get(), MagicNumbers::DIR);
|
||||
return make_unique_ref<DirBlob>(std::move(blob), fsBlobStore);
|
||||
}
|
||||
|
||||
void DirBlob::_writeEntriesToBlob() {
|
||||
if (_changed) {
|
||||
//TODO Resizing is imperformant
|
||||
_blob->resize(1);
|
||||
baseBlob().resize(1);
|
||||
unsigned int offset = 1;
|
||||
for (const auto &entry : _entries) {
|
||||
uint8_t entryTypeMagicNumber = static_cast<uint8_t>(entry.type);
|
||||
_blob->write(&entryTypeMagicNumber, offset, 1);
|
||||
baseBlob().write(&entryTypeMagicNumber, offset, 1);
|
||||
offset += 1;
|
||||
_blob->write(entry.name.c_str(), offset, entry.name.size() + 1);
|
||||
baseBlob().write(entry.name.c_str(), offset, entry.name.size() + 1);
|
||||
offset += entry.name.size() + 1;
|
||||
string keystr = entry.key.ToString();
|
||||
_blob->write(keystr.c_str(), offset, keystr.size() + 1);
|
||||
baseBlob().write(keystr.c_str(), offset, keystr.size() + 1);
|
||||
offset += keystr.size() + 1;
|
||||
_blob->write(&entry.uid, offset, sizeof(uid_t));
|
||||
baseBlob().write(&entry.uid, offset, sizeof(uid_t));
|
||||
//TODO Writing them all in separate write calls is maybe imperformant. We could write the whole entry in one write call instead.
|
||||
offset += sizeof(uid_t);
|
||||
_blob->write(&entry.gid, offset, sizeof(gid_t));
|
||||
offset += sizeof(gid_t);
|
||||
_blob->write(&entry.mode, offset, sizeof(mode_t));
|
||||
offset += sizeof(mode_t);
|
||||
baseBlob().write(&entry.gid, offset, sizeof(gid_t));
|
||||
offset += sizeof(gid_t);
|
||||
baseBlob().write(&entry.mode, offset, sizeof(mode_t));
|
||||
offset += sizeof(mode_t);
|
||||
}
|
||||
_changed = false;
|
||||
}
|
||||
|
@ -81,8 +76,9 @@ void DirBlob::_writeEntriesToBlob() {
|
|||
|
||||
void DirBlob::_readEntriesFromBlob() {
|
||||
_entries.clear();
|
||||
Data data(_blob->size() - 1);
|
||||
_blob->read(data.data(), 1, _blob->size() - 1);
|
||||
//TODO Getting size and then reading traverses tree twice. Something like readAll() would be faster.
|
||||
Data data(baseBlob().size() - 1);
|
||||
baseBlob().read(data.data(), 1, baseBlob().size() - 1);
|
||||
|
||||
const char *pos = (const char*) data.data();
|
||||
while (pos < (const char*) data.data() + data.size()) {
|
||||
|
@ -193,10 +189,15 @@ void DirBlob::AppendChildrenTo(vector<fspp::Dir::Entry> *result) const {
|
|||
}
|
||||
}
|
||||
|
||||
off_t DirBlob::lstat_size() const {
|
||||
//TODO Why do dirs have 4096 bytes in size? Does that make sense?
|
||||
return 4096;
|
||||
}
|
||||
|
||||
void DirBlob::statChild(const Key &key, struct ::stat *result) const {
|
||||
auto child = GetChild(key);
|
||||
//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 CryDevice, which is ugly
|
||||
// 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;
|
||||
|
@ -204,30 +205,12 @@ void DirBlob::statChild(const Key &key, struct ::stat *result) const {
|
|||
result->st_nlink = 1;
|
||||
//TODO Handle file access times
|
||||
result->st_mtime = result->st_ctime = result->st_atime = 0;
|
||||
if (child.type == fspp::Dir::EntryType::FILE) {
|
||||
auto blob = _device->LoadBlob(key);
|
||||
if (blob == none) {
|
||||
//TODO Log error
|
||||
} else {
|
||||
result->st_size = FileBlob(std::move(*blob)).size();
|
||||
}
|
||||
} else if (child.type == fspp::Dir::EntryType::DIR) {
|
||||
//TODO Why do dirs have 4096 bytes in size? Does that make sense?
|
||||
result->st_size = 4096;
|
||||
} else if (child.type == fspp::Dir::EntryType::SYMLINK) {
|
||||
//TODO Necessary with fuse or does fuse set this on symlinks anyhow?
|
||||
auto blob = _device->LoadBlob(key);
|
||||
if (blob == none) {
|
||||
//TODO Log error
|
||||
} else {
|
||||
result->st_size = SymlinkBlob(std::move(*blob)).target().native().size();
|
||||
}
|
||||
} else {
|
||||
ASSERT(false, "Unknown child type");
|
||||
}
|
||||
auto blob = _fsBlobStore->load(key);
|
||||
ASSERT(blob != none, "Blob for directory entry not found");
|
||||
result->st_size = (*blob)->lstat_size();
|
||||
//TODO Move ceilDivision to general utils which can be used by cryfs as well
|
||||
result->st_blocks = blobstore::onblocks::utils::ceilDivision(result->st_size, 512);
|
||||
result->st_blksize = _device->BLOCKSIZE_BYTES;
|
||||
result->st_blksize = CryDevice::BLOCKSIZE_BYTES; //TODO _fsBlobStore->BLOCKSIZE_BYTES would be cleaner
|
||||
}
|
||||
|
||||
void DirBlob::chmodChild(const Key &key, mode_t mode) {
|
||||
|
@ -250,3 +233,4 @@ void DirBlob::chownChild(const Key &key, uid_t uid, gid_t gid) {
|
|||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
#pragma once
|
||||
#ifndef CRYFS_FSBLOBSTORE_DIRBLOB_H_
|
||||
#define CRYFS_FSBLOBSTORE_DIRBLOB_H_
|
||||
|
||||
#include <messmer/blockstore/utils/Key.h>
|
||||
#include <messmer/cpp-utils/macros.h>
|
||||
#include <messmer/fspp/fs_interface/Dir.h>
|
||||
#include "FsBlob.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace cryfs {
|
||||
namespace fsblobstore {
|
||||
class FsBlobStore;
|
||||
|
||||
class DirBlob : public FsBlob {
|
||||
public:
|
||||
struct Entry {
|
||||
Entry(fspp::Dir::EntryType type_, const std::string &name_, const blockstore::Key &key_, mode_t mode_,
|
||||
uid_t uid_, gid_t gid_) : type(type_), name(name_), key(key_), mode(mode_), uid(uid_), gid(gid_) {
|
||||
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");
|
||||
}
|
||||
|
||||
fspp::Dir::EntryType type;
|
||||
std::string name;
|
||||
blockstore::Key key;
|
||||
mode_t mode;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
};
|
||||
|
||||
static cpputils::unique_ref<DirBlob> InitializeEmptyDir(cpputils::unique_ref<blobstore::Blob> blob,
|
||||
FsBlobStore *fsBlobStore);
|
||||
|
||||
DirBlob(cpputils::unique_ref<blobstore::Blob> blob, FsBlobStore *fsBlobStore);
|
||||
|
||||
virtual ~DirBlob();
|
||||
|
||||
off_t lstat_size() const override;
|
||||
|
||||
void AppendChildrenTo(std::vector<fspp::Dir::Entry> *result) const;
|
||||
|
||||
const Entry &GetChild(const std::string &name) const;
|
||||
|
||||
const Entry &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);
|
||||
|
||||
void AddChildFile(const std::string &name, const blockstore::Key &blobKey, mode_t mode, uid_t uid,
|
||||
gid_t gid);
|
||||
|
||||
void AddChildSymlink(const std::string &name, const blockstore::Key &blobKey, uid_t uid, gid_t gid);
|
||||
|
||||
void AddChild(const std::string &name, const blockstore::Key &blobKey, fspp::Dir::EntryType type,
|
||||
mode_t mode,
|
||||
uid_t uid, gid_t gid);
|
||||
|
||||
void RemoveChild(const blockstore::Key &key);
|
||||
|
||||
void flush();
|
||||
|
||||
void statChild(const blockstore::Key &key, struct ::stat *result) const;
|
||||
|
||||
void chmodChild(const blockstore::Key &key, mode_t mode);
|
||||
|
||||
void chownChild(const blockstore::Key &key, uid_t uid, gid_t gid);
|
||||
|
||||
private:
|
||||
|
||||
const char *readAndAddNextChild(const char *pos, std::vector<Entry> *result) const;
|
||||
|
||||
bool hasChild(const std::string &name) const;
|
||||
|
||||
void _readEntriesFromBlob();
|
||||
|
||||
void _writeEntriesToBlob();
|
||||
|
||||
std::vector<DirBlob::Entry>::iterator _findChild(const blockstore::Key &key);
|
||||
|
||||
FsBlobStore *_fsBlobStore;
|
||||
std::vector<Entry> _entries;
|
||||
bool _changed;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DirBlob);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -9,49 +9,45 @@ using cpputils::unique_ref;
|
|||
using cpputils::make_unique_ref;
|
||||
|
||||
namespace cryfs {
|
||||
namespace fsblobstore {
|
||||
|
||||
FileBlob::FileBlob(unique_ref<Blob> blob)
|
||||
: _blob(std::move(blob)) {
|
||||
}
|
||||
|
||||
FileBlob::~FileBlob() {
|
||||
: FsBlob(std::move(blob)) {
|
||||
}
|
||||
|
||||
unique_ref<FileBlob> FileBlob::InitializeEmptyFile(unique_ref<Blob> blob) {
|
||||
blob->resize(1);
|
||||
unsigned char magicNumber = MagicNumbers::FILE;
|
||||
blob->write(&magicNumber, 0, 1);
|
||||
InitializeBlobWithMagicNumber(blob.get(), MagicNumbers::FILE);
|
||||
return make_unique_ref<FileBlob>(std::move(blob));
|
||||
}
|
||||
|
||||
unsigned char FileBlob::magicNumber() const {
|
||||
unsigned char value;
|
||||
_blob->read(&value, 0, 1);
|
||||
return value;
|
||||
}
|
||||
|
||||
ssize_t FileBlob::read(void *target, uint64_t offset, uint64_t count) const {
|
||||
return _blob->tryRead(target, offset + 1, count);
|
||||
return baseBlob().tryRead(target, offset + 1, count);
|
||||
}
|
||||
|
||||
void FileBlob::write(const void *source, uint64_t offset, uint64_t count) {
|
||||
_blob->write(source, offset + 1, count);
|
||||
baseBlob().write(source, offset + 1, count);
|
||||
}
|
||||
|
||||
void FileBlob::flush() {
|
||||
_blob->flush();
|
||||
baseBlob().flush();
|
||||
}
|
||||
|
||||
blockstore::Key FileBlob::key() const {
|
||||
return _blob->key();
|
||||
return baseBlob().key();
|
||||
}
|
||||
|
||||
void FileBlob::resize(off_t size) {
|
||||
_blob->resize(size+1);
|
||||
baseBlob().resize(size+1);
|
||||
}
|
||||
|
||||
off_t FileBlob::lstat_size() const {
|
||||
return size();
|
||||
}
|
||||
|
||||
off_t FileBlob::size() const {
|
||||
return _blob->size()-1;
|
||||
return baseBlob().size()-1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
#ifndef CRYFS_FSBLOBSTORE_FILEBLOB_H_
|
||||
#define CRYFS_FSBLOBSTORE_FILEBLOB_H_
|
||||
|
||||
#include "FsBlob.h"
|
||||
|
||||
namespace cryfs {
|
||||
namespace fsblobstore {
|
||||
|
||||
class FileBlob: public FsBlob {
|
||||
public:
|
||||
static cpputils::unique_ref<FileBlob> InitializeEmptyFile(cpputils::unique_ref<blobstore::Blob> blob);
|
||||
|
||||
FileBlob(cpputils::unique_ref<blobstore::Blob> blob);
|
||||
|
||||
ssize_t read(void *target, uint64_t offset, uint64_t count) const;
|
||||
|
||||
void write(const void *source, uint64_t offset, uint64_t count);
|
||||
|
||||
void flush();
|
||||
|
||||
void resize(off_t size);
|
||||
|
||||
off_t lstat_size() const override;
|
||||
|
||||
off_t size() const;
|
||||
|
||||
blockstore::Key key() const;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1 @@
|
|||
#include "FsBlob.h"
|
|
@ -0,0 +1,75 @@
|
|||
#ifndef CRYFS_FSBLOBSTORE_FSBLOB_H
|
||||
#define CRYFS_FSBLOBSTORE_FSBLOB_H
|
||||
|
||||
#include <messmer/cpp-utils/pointer/unique_ref.h>
|
||||
#include <messmer/blobstore/interface/Blob.h>
|
||||
|
||||
namespace cryfs {
|
||||
namespace fsblobstore {
|
||||
class FsBlob {
|
||||
public:
|
||||
virtual ~FsBlob();
|
||||
|
||||
virtual off_t lstat_size() const = 0;
|
||||
blockstore::Key key() const;
|
||||
|
||||
protected:
|
||||
FsBlob(cpputils::unique_ref<blobstore::Blob> baseBlob);
|
||||
|
||||
blobstore::Blob &baseBlob();
|
||||
const blobstore::Blob &baseBlob() const;
|
||||
|
||||
unsigned char magicNumber() const;
|
||||
static unsigned char magicNumber(const blobstore::Blob &blob);
|
||||
|
||||
static void InitializeBlobWithMagicNumber(blobstore::Blob *blob, unsigned char magicNumber);
|
||||
|
||||
private:
|
||||
friend class FsBlobStore;
|
||||
cpputils::unique_ref<blobstore::Blob> releaseBaseBlob();
|
||||
|
||||
cpputils::unique_ref<blobstore::Blob> _baseBlob;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(FsBlob);
|
||||
};
|
||||
|
||||
inline FsBlob::FsBlob(cpputils::unique_ref<blobstore::Blob> baseBlob): _baseBlob(std::move(baseBlob)) {
|
||||
}
|
||||
|
||||
inline FsBlob::~FsBlob() {
|
||||
}
|
||||
|
||||
inline blockstore::Key FsBlob::key() const {
|
||||
return _baseBlob->key();
|
||||
}
|
||||
|
||||
inline const blobstore::Blob &FsBlob::baseBlob() const {
|
||||
return *_baseBlob;
|
||||
}
|
||||
|
||||
inline blobstore::Blob &FsBlob::baseBlob() {
|
||||
return *_baseBlob;
|
||||
}
|
||||
|
||||
inline unsigned char FsBlob::magicNumber(const blobstore::Blob &blob) {
|
||||
unsigned char value;
|
||||
blob.read(&value, 0, 1);
|
||||
return value;
|
||||
}
|
||||
|
||||
inline unsigned char FsBlob::magicNumber() const {
|
||||
return magicNumber(*_baseBlob);
|
||||
}
|
||||
|
||||
inline void FsBlob::InitializeBlobWithMagicNumber(blobstore::Blob *blob, unsigned char magicNumber) {
|
||||
blob->resize(1);
|
||||
blob->write(&magicNumber, 0, 1);
|
||||
}
|
||||
|
||||
inline cpputils::unique_ref<blobstore::Blob> FsBlob::releaseBaseBlob() {
|
||||
return std::move(_baseBlob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,55 @@
|
|||
#include "FsBlobStore.h"
|
||||
#include "FileBlob.h"
|
||||
#include "DirBlob.h"
|
||||
#include "SymlinkBlob.h"
|
||||
#include "MagicNumbers.h"
|
||||
|
||||
namespace bf = boost::filesystem;
|
||||
using cpputils::unique_ref;
|
||||
using cpputils::make_unique_ref;
|
||||
using blobstore::BlobStore;
|
||||
using boost::none;
|
||||
|
||||
namespace cryfs {
|
||||
namespace fsblobstore {
|
||||
|
||||
FsBlobStore::FsBlobStore(unique_ref<BlobStore> baseBlobStore): _baseBlobStore(std::move(baseBlobStore)) {
|
||||
}
|
||||
|
||||
unique_ref<FileBlob> FsBlobStore::createFileBlob() {
|
||||
return FileBlob::InitializeEmptyFile(_baseBlobStore->create());
|
||||
}
|
||||
|
||||
unique_ref<DirBlob> FsBlobStore::createDirBlob() {
|
||||
//TODO Passed in fsBlobStore should be ParallelAccessFsBlobStore later
|
||||
return DirBlob::InitializeEmptyDir(_baseBlobStore->create(), this);
|
||||
}
|
||||
|
||||
unique_ref<SymlinkBlob> FsBlobStore::createSymlinkBlob(const bf::path &target) {
|
||||
return SymlinkBlob::InitializeSymlink(_baseBlobStore->create(), target);
|
||||
}
|
||||
|
||||
boost::optional<unique_ref<FsBlob>> FsBlobStore::load(const blockstore::Key &key) {
|
||||
auto blob = _baseBlobStore->load(key);
|
||||
if (blob == none) {
|
||||
return none;
|
||||
}
|
||||
unsigned char magicNumber = FsBlob::magicNumber(**blob);
|
||||
if (magicNumber == MagicNumbers::FILE) {
|
||||
return unique_ref<FsBlob>(make_unique_ref<FileBlob>(std::move(*blob)));
|
||||
} else if (magicNumber == MagicNumbers::DIR) {
|
||||
//TODO Passed in fsBlobStore should be ParallelAccessFsBlobStore later
|
||||
return unique_ref<FsBlob>(make_unique_ref<DirBlob>(std::move(*blob), this));
|
||||
} else if (magicNumber == MagicNumbers::SYMLINK) {
|
||||
return unique_ref<FsBlob>(make_unique_ref<SymlinkBlob>(std::move(*blob)));
|
||||
} else {
|
||||
ASSERT(false, "Unknown magic number");
|
||||
}
|
||||
}
|
||||
|
||||
void FsBlobStore::remove(cpputils::unique_ref<FsBlob> blob) {
|
||||
_baseBlobStore->remove(blob->releaseBaseBlob());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef CRYFS_FSBLOBSTORE_FSBLOBSTORE_H
|
||||
#define CRYFS_FSBLOBSTORE_FSBLOBSTORE_H
|
||||
|
||||
#include <messmer/cpp-utils/pointer/unique_ref.h>
|
||||
#include <messmer/blobstore/interface/BlobStore.h>
|
||||
#include "FileBlob.h"
|
||||
#include "DirBlob.h"
|
||||
#include "SymlinkBlob.h"
|
||||
|
||||
namespace cryfs {
|
||||
namespace fsblobstore {
|
||||
class FsBlobStore {
|
||||
public:
|
||||
FsBlobStore(cpputils::unique_ref<blobstore::BlobStore> baseBlobStore);
|
||||
|
||||
cpputils::unique_ref<FileBlob> createFileBlob();
|
||||
cpputils::unique_ref<DirBlob> createDirBlob();
|
||||
cpputils::unique_ref<SymlinkBlob> createSymlinkBlob(const boost::filesystem::path &target);
|
||||
boost::optional<cpputils::unique_ref<FsBlob>> load(const blockstore::Key &key);
|
||||
void remove(cpputils::unique_ref<FsBlob> blob);
|
||||
|
||||
private:
|
||||
cpputils::unique_ref<blobstore::BlobStore> _baseBlobStore;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,8 +1,9 @@
|
|||
#pragma once
|
||||
#ifndef CRYFS_LIB_IMPL_MAGICNUMBERS_H_
|
||||
#define CRYFS_LIB_IMPL_MAGICNUMBERS_H_
|
||||
#ifndef CRYFS_FSBLOBSTORE_MAGICNUMBERS_H_
|
||||
#define CRYFS_FSBLOBSTORE_MAGICNUMBERS_H_
|
||||
|
||||
namespace cryfs {
|
||||
namespace fsblobstore {
|
||||
|
||||
//TODO enum class
|
||||
enum MagicNumbers {
|
||||
|
@ -12,6 +13,7 @@ enum MagicNumbers {
|
|||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -12,15 +12,10 @@ using cpputils::make_unique_ref;
|
|||
namespace bf = boost::filesystem;
|
||||
|
||||
namespace cryfs {
|
||||
namespace fsblobstore {
|
||||
|
||||
SymlinkBlob::SymlinkBlob(unique_ref<Blob> blob)
|
||||
: _target(_readTargetFromBlob(*blob)) {
|
||||
}
|
||||
|
||||
SymlinkBlob::SymlinkBlob(const bf::path &target) :_target(target) {
|
||||
}
|
||||
|
||||
SymlinkBlob::~SymlinkBlob() {
|
||||
: FsBlob(std::move(blob)), _target(_readTargetFromBlob(baseBlob())) {
|
||||
}
|
||||
|
||||
unique_ref<SymlinkBlob> SymlinkBlob::InitializeSymlink(unique_ref<Blob> blob, const bf::path &target) {
|
||||
|
@ -29,7 +24,7 @@ unique_ref<SymlinkBlob> SymlinkBlob::InitializeSymlink(unique_ref<Blob> blob, co
|
|||
unsigned char magicNumber = MagicNumbers::SYMLINK;
|
||||
blob->write(&magicNumber, 0, 1);
|
||||
blob->write(targetStr.c_str(), 1, targetStr.size());
|
||||
return make_unique_ref<SymlinkBlob>(target);
|
||||
return make_unique_ref<SymlinkBlob>(std::move(blob));
|
||||
}
|
||||
|
||||
void SymlinkBlob::_checkMagicNumber(const Blob &blob) {
|
||||
|
@ -51,4 +46,9 @@ const bf::path &SymlinkBlob::target() const {
|
|||
return _target;
|
||||
}
|
||||
|
||||
off_t SymlinkBlob::lstat_size() const {
|
||||
return target().native().size();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
#ifndef CRYFS_FSBLOBSTORE_SYMLINKBLOB_H_
|
||||
#define CRYFS_FSBLOBSTORE_SYMLINKBLOB_H_
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include "FsBlob.h"
|
||||
|
||||
namespace cryfs {
|
||||
namespace fsblobstore {
|
||||
|
||||
class SymlinkBlob: public FsBlob {
|
||||
public:
|
||||
static cpputils::unique_ref<SymlinkBlob> InitializeSymlink(cpputils::unique_ref<blobstore::Blob> blob,
|
||||
const boost::filesystem::path &target);
|
||||
|
||||
SymlinkBlob(cpputils::unique_ref<blobstore::Blob> blob);
|
||||
|
||||
const boost::filesystem::path &target() const;
|
||||
|
||||
off_t lstat_size() const override;
|
||||
|
||||
private:
|
||||
boost::filesystem::path _target;
|
||||
|
||||
static void _checkMagicNumber(const blobstore::Blob &blob);
|
||||
|
||||
static boost::filesystem::path _readTargetFromBlob(const blobstore::Blob &blob);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,82 +0,0 @@
|
|||
#pragma once
|
||||
#ifndef CRYFS_LIB_IMPL_DIRBLOB_H_
|
||||
#define CRYFS_LIB_IMPL_DIRBLOB_H_
|
||||
|
||||
#include <messmer/blobstore/interface/Blob.h>
|
||||
#include <messmer/blockstore/utils/Key.h>
|
||||
#include <messmer/cpp-utils/macros.h>
|
||||
#include <messmer/fspp/fs_interface/Dir.h>
|
||||
#include <messmer/cpp-utils/pointer/unique_ref.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace cryfs{
|
||||
class CryDevice;
|
||||
|
||||
class DirBlob {
|
||||
public:
|
||||
struct Entry {
|
||||
Entry(fspp::Dir::EntryType type_, const std::string &name_, const blockstore::Key &key_, mode_t mode_, uid_t uid_, gid_t gid_): type(type_), name(name_), key(key_), mode(mode_), uid(uid_), gid(gid_) {
|
||||
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");
|
||||
}
|
||||
|
||||
fspp::Dir::EntryType type;
|
||||
std::string name;
|
||||
blockstore::Key key;
|
||||
mode_t mode;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
};
|
||||
|
||||
static cpputils::unique_ref<DirBlob> InitializeEmptyDir(cpputils::unique_ref<blobstore::Blob> blob, CryDevice *device);
|
||||
|
||||
DirBlob(cpputils::unique_ref<blobstore::Blob> blob, CryDevice *device);
|
||||
virtual ~DirBlob();
|
||||
|
||||
void AppendChildrenTo(std::vector<fspp::Dir::Entry> *result) const;
|
||||
const Entry &GetChild(const std::string &name) const;
|
||||
const Entry &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);
|
||||
void AddChildFile(const std::string &name, const blockstore::Key &blobKey, mode_t mode, uid_t uid, gid_t gid);
|
||||
void AddChildSymlink(const std::string &name, const blockstore::Key &blobKey, uid_t uid, gid_t gid);
|
||||
void AddChild(const std::string &name, const blockstore::Key &blobKey, fspp::Dir::EntryType type, mode_t mode, uid_t uid, gid_t gid);
|
||||
void RemoveChild(const blockstore::Key &key);
|
||||
void flush();
|
||||
|
||||
void statChild(const blockstore::Key &key, struct ::stat *result) const;
|
||||
void chmodChild(const blockstore::Key &key, mode_t mode);
|
||||
void chownChild(const blockstore::Key &key, uid_t uid, gid_t gid);
|
||||
|
||||
private:
|
||||
unsigned char magicNumber() const;
|
||||
|
||||
const char *readAndAddNextChild(const char *pos, std::vector<Entry> *result) const;
|
||||
bool hasChild(const std::string &name) const;
|
||||
|
||||
void _readEntriesFromBlob();
|
||||
void _writeEntriesToBlob();
|
||||
|
||||
std::vector<DirBlob::Entry>::iterator _findChild(const blockstore::Key &key);
|
||||
|
||||
CryDevice *_device;
|
||||
cpputils::unique_ref<blobstore::Blob> _blob;
|
||||
std::vector<Entry> _entries;
|
||||
bool _changed;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DirBlob);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,34 +0,0 @@
|
|||
#pragma once
|
||||
#ifndef CRYFS_LIB_IMPL_FILEBLOB_H_
|
||||
#define CRYFS_LIB_IMPL_FILEBLOB_H_
|
||||
|
||||
#include <messmer/blobstore/interface/Blob.h>
|
||||
#include <messmer/cpp-utils/pointer/unique_ref.h>
|
||||
|
||||
namespace cryfs {
|
||||
|
||||
class FileBlob {
|
||||
public:
|
||||
static cpputils::unique_ref<FileBlob> InitializeEmptyFile(cpputils::unique_ref<blobstore::Blob> blob);
|
||||
|
||||
FileBlob(cpputils::unique_ref<blobstore::Blob> blob);
|
||||
virtual ~FileBlob();
|
||||
|
||||
ssize_t read(void *target, uint64_t offset, uint64_t count) const;
|
||||
void write(const void *source, uint64_t offset, uint64_t count);
|
||||
void flush();
|
||||
|
||||
void resize(off_t size);
|
||||
off_t size() const;
|
||||
|
||||
blockstore::Key key() const;
|
||||
|
||||
private:
|
||||
cpputils::unique_ref<blobstore::Blob> _blob;
|
||||
|
||||
unsigned char magicNumber() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,30 +0,0 @@
|
|||
#pragma once
|
||||
#ifndef CRYFS_LIB_IMPL_SYMLINKBLOB_H_
|
||||
#define CRYFS_LIB_IMPL_SYMLINKBLOB_H_
|
||||
|
||||
#include <messmer/blobstore/interface/Blob.h>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <messmer/cpp-utils/pointer/unique_ref.h>
|
||||
|
||||
namespace cryfs {
|
||||
|
||||
class SymlinkBlob {
|
||||
public:
|
||||
static cpputils::unique_ref<SymlinkBlob> InitializeSymlink(cpputils::unique_ref<blobstore::Blob> blob, const boost::filesystem::path &target);
|
||||
|
||||
SymlinkBlob(cpputils::unique_ref<blobstore::Blob> blob);
|
||||
SymlinkBlob(const boost::filesystem::path &target);
|
||||
virtual ~SymlinkBlob();
|
||||
|
||||
const boost::filesystem::path &target() const;
|
||||
|
||||
private:
|
||||
boost::filesystem::path _target;
|
||||
|
||||
static void _checkMagicNumber(const blobstore::Blob &blob);
|
||||
static boost::filesystem::path _readTargetFromBlob(const blobstore::Blob &blob);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue