Created a simple mkdir/lsdir for cryfs, backed by blocks

This commit is contained in:
Sebastian Messmer 2014-12-07 10:42:16 +01:00
parent 51bcc2f191
commit 30ac3ab3cb
8 changed files with 189 additions and 8 deletions

View File

@ -1,3 +1,3 @@
add_library(cryfs_lib CryDevice.cpp CryDir.cpp CryFile.cpp CryNode.cpp CryOpenFile.cpp)
add_library(cryfs_lib CryDevice.cpp CryDir.cpp CryFile.cpp CryNode.cpp CryOpenFile.cpp impl/DirBlob.cpp)
target_link_libraries(cryfs_lib)

View File

@ -4,11 +4,13 @@
#include "CryFile.h"
#include "fspp/fuse/FuseErrnoException.h"
#include "impl/DirBlob.h"
using std::unique_ptr;
using std::unique_ptr;
using std::make_unique;
using std::string;
//TODO Get rid of this in favor of exception hierarchy
using fspp::fuse::CHECK_RETVAL;
@ -19,18 +21,34 @@ using blobstore::BlobStore;
namespace cryfs {
CryDevice::CryDevice(unique_ptr<BlobStore> blobStore)
: _blobStore(std::move(blobStore)) {
: _blob_store(std::move(blobStore)), _root_key() {
auto rootBlob = _blob_store->create(DIR_BLOBSIZE);
DirBlob rootDir(std::move(rootBlob.blob));
rootDir.InitializeEmptyDir();
_root_key = rootBlob.key;
}
CryDevice::~CryDevice() {
}
unique_ptr<fspp::Node> CryDevice::Load(const bf::path &path) {
throw FuseErrnoException(ENOTSUP);
printf("Loading %s\n", path.c_str());
unique_ptr<DirBlob> currentDir = make_unique<DirBlob>(_blob_store->load(_root_key));
assert(path.is_absolute());
for (const bf::path &component : path.relative_path()) {
printf("Component: %s\n", component.c_str());
string childKey = currentDir->GetBlobKeyForName(component.c_str());
currentDir = make_unique<DirBlob>(_blob_store->load(childKey));
}
return make_unique<CryDir>(this, std::move(currentDir));
}
void CryDevice::statfs(const bf::path &path, struct statvfs *fsstat) {
throw FuseErrnoException(ENOTSUP);
}
blobstore::BlobWithKey CryDevice::CreateBlob(size_t size) {
return _blob_store->create(size);
}
}

View File

@ -15,15 +15,23 @@ namespace bf = boost::filesystem;
class CryDevice: public fspp::Device {
public:
static constexpr size_t DIR_BLOBSIZE = 4096;
CryDevice(std::unique_ptr<blobstore::BlobStore> blobStore);
virtual ~CryDevice();
void statfs(const boost::filesystem::path &path, struct ::statvfs *fsstat) override;
blobstore::BlobWithKey CreateBlob(size_t size);
private:
std::unique_ptr<fspp::Node> Load(const bf::path &path) override;
std::unique_ptr<blobstore::BlobStore> _blobStore;
std::unique_ptr<blobstore::BlobStore> _blob_store;
//TODO This takes a new root key each run, the filesystem won't survive restarting the daemon...
// Find a way so that the next run will recognize the created root element.
std::string _root_key;
DISALLOW_COPY_AND_ASSIGN(CryDevice);
};

View File

@ -22,7 +22,8 @@ using std::vector;
namespace cryfs {
CryDir::CryDir() {
CryDir::CryDir(CryDevice *device, unique_ptr<DirBlob> blob)
: _device(device), _blob(std::move(blob)) {
}
CryDir::~CryDir() {
@ -33,7 +34,10 @@ unique_ptr<fspp::File> CryDir::createFile(const string &name, mode_t mode) {
}
unique_ptr<fspp::Dir> CryDir::createDir(const string &name, mode_t mode) {
throw FuseErrnoException(ENOTSUP);
auto child = _device->CreateBlob(CryDevice::DIR_BLOBSIZE);
_blob->AddChild(name, child.key);
//TODO I don't think we need a return value in createDir for fspp. Change fspp!
return make_unique<CryDir>(_device, make_unique<DirBlob>(std::move(child.blob)));
}
void CryDir::rmdir() {
@ -41,7 +45,7 @@ void CryDir::rmdir() {
}
unique_ptr<vector<string>> CryDir::children() const {
throw FuseErrnoException(ENOTSUP);
return _blob->GetChildren();
}
}

View File

@ -4,12 +4,13 @@
#include <fspp/fs_interface/Dir.h>
#include "CryNode.h"
#include "impl/DirBlob.h"
namespace cryfs {
class CryDir: public fspp::Dir, CryNode {
public:
CryDir();
CryDir(CryDevice *device, std::unique_ptr<DirBlob> blob);
virtual ~CryDir();
//TODO return type variance to CryFile/CryDir?
@ -20,6 +21,9 @@ public:
std::unique_ptr<std::vector<std::string>> children() const override;
private:
CryDevice *_device;
std::unique_ptr<DirBlob> _blob;
DISALLOW_COPY_AND_ASSIGN(CryDir);
};

View File

@ -20,10 +20,13 @@ CryNode::~CryNode() {
}
void CryNode::stat(struct ::stat *result) const {
result->st_mode = S_IFDIR | S_IRUSR | S_IXUSR | S_IWUSR;
return;
throw FuseErrnoException(ENOTSUP);
}
void CryNode::access(int mask) const {
return;
throw FuseErrnoException(ENOTSUP);
}

View File

@ -0,0 +1,104 @@
#include <cryfs_lib/impl/DirBlob.h>
#include <cassert>
//TODO Remove and replace with exception hierarchy
#include "fspp/fuse/FuseErrnoException.h"
using std::unique_ptr;
using std::make_unique;
using std::vector;
using std::string;
using blobstore::Blob;
namespace cryfs {
DirBlob::DirBlob(unique_ptr<Blob> blob)
: _blob(std::move(blob)) {
}
DirBlob::~DirBlob() {
}
void DirBlob::InitializeEmptyDir() {
*entryCounter() = 0;
}
unique_ptr<vector<string>> DirBlob::GetChildren() const {
auto result = make_unique<vector<string>>();
unsigned int entryCount = *entryCounter();
result->reserve(entryCount);
const char *pos = entriesBegin();
for (unsigned int i = 0; i < entryCount; ++i) {
pos = readAndAddNextChild(pos, result.get());
}
return result;
}
const char *DirBlob::readAndAddNextChild(const char *pos, vector<string> *result) const {
size_t length = strlen(pos);
result->emplace_back(pos, length);
const char *posAfterName = pos + length + 1;
const char *posAfterKey = posAfterName + strlen(posAfterName) + 1;
return posAfterKey;
}
void DirBlob::AddChild(const std::string &name, const std::string &blobKey) {
char *insertPos = entriesEnd();
assertEnoughSpaceLeft(insertPos, name.size() + 1 + blobKey.size() + 1);
memcpy(insertPos, name.c_str(), name.size()+1);
memcpy(insertPos + name.size()+1, blobKey.c_str(), blobKey.size()+1);
++(*entryCounter());
}
void DirBlob::assertEnoughSpaceLeft(char *insertPos, size_t insertSize) const {
size_t usedSize = insertPos - (char*)_blob->data();
assert(usedSize + insertSize <= _blob->size());
}
string DirBlob::GetBlobKeyForName(const string &name) const {
unsigned int entryCount = *entryCounter();
const char *pos = entriesBegin();
for(unsigned int i = 0; i < entryCount; ++i) {
size_t name_length = strlen(pos);
if (name_length == name.size() && 0==std::memcmp(pos, name.c_str(), name_length)) {
pos += strlen(pos) + 1; // Skip name
return pos; // Return key
}
pos += strlen(pos) + 1; // Skip name
pos += strlen(pos) + 1; // Skip key
}
throw fspp::fuse::FuseErrnoException(ENOENT);
}
unsigned int *DirBlob::entryCounter() {
return const_cast<unsigned int*>(const_cast<const DirBlob*>(this)->entryCounter());
}
const unsigned int *DirBlob::entryCounter() const {
return (unsigned int*)(_blob->data());
}
char *DirBlob::entriesBegin() {
return const_cast<char*>(const_cast<const DirBlob*>(this)->entriesBegin());
}
const char *DirBlob::entriesBegin() const {
return (char *)(_blob->data())+sizeof(unsigned int);
}
char *DirBlob::entriesEnd() {
unsigned int entryCount = *entryCounter();
char *pos = entriesBegin();
for(unsigned int i = 0; i < entryCount; ++i) {
pos += strlen(pos) + 1; // Skip entry name
pos += strlen(pos) + 1; // Skip entry key
}
return pos;
}
}

View File

@ -0,0 +1,40 @@
#pragma once
#ifndef CRYFS_LIB_IMPL_DIRBLOB_H_
#define CRYFS_LIB_IMPL_DIRBLOB_H_
#include "blobstore/interface/Blob.h"
#include "fspp/utils/macros.h"
#include <memory>
#include <vector>
namespace cryfs{
class DirBlob {
public:
DirBlob(std::unique_ptr<blobstore::Blob> blob);
virtual ~DirBlob();
void InitializeEmptyDir();
std::unique_ptr<std::vector<std::string>> GetChildren() const;
void AddChild(const std::string &name, const std::string &blobKey);
std::string GetBlobKeyForName(const std::string &name) const;
private:
unsigned int *entryCounter();
const unsigned int *entryCounter() const;
char *entriesBegin();
const char *entriesBegin() const;
char *entriesEnd();
const char *readAndAddNextChild(const char *pos, std::vector<std::string> *result) const;
void assertEnoughSpaceLeft(char *insertPos, size_t insertSize) const;
std::unique_ptr<blobstore::Blob> _blob;
DISALLOW_COPY_AND_ASSIGN(DirBlob);
};
}
#endif