Created a simple mkdir/lsdir for cryfs, backed by blocks
This commit is contained in:
parent
51bcc2f191
commit
30ac3ab3cb
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue