Implemented chmod/chown and fixed some minor details
This commit is contained in:
parent
7b40e22279
commit
b96cc48639
@ -47,7 +47,7 @@ Key CryDevice::GetOrCreateRootKey(CryConfig *config) {
|
|||||||
Key CryDevice::CreateRootBlobAndReturnKey() {
|
Key CryDevice::CreateRootBlobAndReturnKey() {
|
||||||
auto rootBlob = _blobStore->create();
|
auto rootBlob = _blobStore->create();
|
||||||
Key rootBlobKey = rootBlob->key();
|
Key rootBlobKey = rootBlob->key();
|
||||||
DirBlob::InitializeEmptyDir(std::move(rootBlob));
|
DirBlob::InitializeEmptyDir(std::move(rootBlob), this);
|
||||||
return rootBlobKey;
|
return rootBlobKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,13 +81,13 @@ unique_ptr<DirBlob> CryDevice::LoadDirBlob(const bf::path &path) {
|
|||||||
//TODO Check whether the next path component is a dir.
|
//TODO Check whether the next path component is a dir.
|
||||||
// Right now, an assertion in DirBlob constructor will fail if it isn't.
|
// Right now, an assertion in DirBlob constructor will fail if it isn't.
|
||||||
// But fuse should rather return the correct error code.
|
// But fuse should rather return the correct error code.
|
||||||
unique_ptr<DirBlob> currentDir = make_unique<DirBlob>(std::move(currentBlob));
|
unique_ptr<DirBlob> currentDir = make_unique<DirBlob>(std::move(currentBlob), this);
|
||||||
|
|
||||||
Key childKey = currentDir->GetChild(component.c_str()).key;
|
Key childKey = currentDir->GetChild(component.c_str()).key;
|
||||||
currentBlob = _blobStore->load(childKey);
|
currentBlob = _blobStore->load(childKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
return make_unique<DirBlob>(std::move(currentBlob));
|
return make_unique<DirBlob>(std::move(currentBlob), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CryDevice::statfs(const bf::path &path, struct statvfs *fsstat) {
|
void CryDevice::statfs(const bf::path &path, struct statvfs *fsstat) {
|
||||||
|
@ -32,17 +32,11 @@ CryDir::CryDir(CryDevice *device, unique_ptr<DirBlob> parent, const Key &key)
|
|||||||
CryDir::~CryDir() {
|
CryDir::~CryDir() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CryDir::stat(struct ::stat *result) const {
|
|
||||||
result->st_mode = S_IFDIR | S_IRUSR | S_IXUSR | S_IWUSR;
|
|
||||||
return;
|
|
||||||
throw FuseErrnoException(ENOTSUP);
|
|
||||||
}
|
|
||||||
|
|
||||||
unique_ptr<fspp::OpenFile> CryDir::createAndOpenFile(const string &name, mode_t mode) {
|
unique_ptr<fspp::OpenFile> CryDir::createAndOpenFile(const string &name, mode_t mode) {
|
||||||
auto blob = LoadBlob();
|
auto blob = LoadBlob();
|
||||||
auto child = device()->CreateBlob();
|
auto child = device()->CreateBlob();
|
||||||
Key childkey = child->key();
|
Key childkey = child->key();
|
||||||
blob->AddChildFile(name, childkey);
|
blob->AddChildFile(name, childkey, mode);
|
||||||
//TODO Do we need a return value in createDir for fspp? If not, change fspp Dir interface!
|
//TODO Do we need a return value in createDir for fspp? If not, change fspp Dir interface!
|
||||||
auto childblob = FileBlob::InitializeEmptyFile(std::move(child));
|
auto childblob = FileBlob::InitializeEmptyFile(std::move(child));
|
||||||
return make_unique<CryOpenFile>(std::move(childblob));
|
return make_unique<CryOpenFile>(std::move(childblob));
|
||||||
@ -52,12 +46,13 @@ void CryDir::createDir(const string &name, mode_t mode) {
|
|||||||
auto blob = LoadBlob();
|
auto blob = LoadBlob();
|
||||||
auto child = device()->CreateBlob();
|
auto child = device()->CreateBlob();
|
||||||
Key childkey = child->key();
|
Key childkey = child->key();
|
||||||
blob->AddChildDir(name, childkey);
|
blob->AddChildDir(name, childkey, mode);
|
||||||
DirBlob::InitializeEmptyDir(std::move(child));
|
DirBlob::InitializeEmptyDir(std::move(child), device());
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DirBlob> CryDir::LoadBlob() const {
|
unique_ptr<DirBlob> CryDir::LoadBlob() const {
|
||||||
return make_unique<DirBlob>(CryNode::LoadBlob());
|
//TODO Without const_cast?
|
||||||
|
return make_unique<DirBlob>(CryNode::LoadBlob(), const_cast<CryDevice*>(device()));
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<vector<fspp::Dir::Entry>> CryDir::children() const {
|
unique_ptr<vector<fspp::Dir::Entry>> CryDir::children() const {
|
||||||
|
@ -13,7 +13,6 @@ public:
|
|||||||
CryDir(CryDevice *device, std::unique_ptr<DirBlob> parent, const blockstore::Key &key);
|
CryDir(CryDevice *device, std::unique_ptr<DirBlob> parent, const blockstore::Key &key);
|
||||||
virtual ~CryDir();
|
virtual ~CryDir();
|
||||||
|
|
||||||
void stat(struct ::stat *result) const override;
|
|
||||||
//TODO return type variance to CryFile/CryDir?
|
//TODO return type variance to CryFile/CryDir?
|
||||||
std::unique_ptr<fspp::OpenFile> createAndOpenFile(const std::string &name, mode_t mode) override;
|
std::unique_ptr<fspp::OpenFile> createAndOpenFile(const std::string &name, mode_t mode) override;
|
||||||
void createDir(const std::string &name, mode_t mode) override;
|
void createDir(const std::string &name, mode_t mode) override;
|
||||||
|
@ -31,14 +31,6 @@ unique_ptr<fspp::OpenFile> CryFile::open(int flags) const {
|
|||||||
return make_unique<CryOpenFile>(make_unique<FileBlob>(std::move(blob)));
|
return make_unique<CryOpenFile>(make_unique<FileBlob>(std::move(blob)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CryFile::stat(struct ::stat *result) const {
|
|
||||||
result->st_mode = S_IFREG | S_IRUSR | S_IXUSR | S_IWUSR;
|
|
||||||
//TODO Loading the blob for only getting the size is not very performant.
|
|
||||||
result->st_size = FileBlob(LoadBlob()).size();
|
|
||||||
return;
|
|
||||||
throw FuseErrnoException(ENOTSUP);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CryFile::truncate(off_t size) const {
|
void CryFile::truncate(off_t size) const {
|
||||||
FileBlob(LoadBlob()).resize(size);
|
FileBlob(LoadBlob()).resize(size);
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@ public:
|
|||||||
CryFile(CryDevice *device, std::unique_ptr<DirBlob> parent, const blockstore::Key &key);
|
CryFile(CryDevice *device, std::unique_ptr<DirBlob> parent, const blockstore::Key &key);
|
||||||
virtual ~CryFile();
|
virtual ~CryFile();
|
||||||
|
|
||||||
void stat(struct ::stat *result) const override;
|
|
||||||
std::unique_ptr<fspp::OpenFile> open(int flags) const override;
|
std::unique_ptr<fspp::OpenFile> open(int flags) const override;
|
||||||
void truncate(off_t size) const override;
|
void truncate(off_t size) const override;
|
||||||
fspp::Dir::EntryType getType() const override;
|
fspp::Dir::EntryType getType() const override;
|
||||||
|
@ -31,19 +31,23 @@ CryNode::~CryNode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CryNode::access(int mask) const {
|
void CryNode::access(int mask) const {
|
||||||
|
//TODO
|
||||||
return;
|
return;
|
||||||
throw FuseErrnoException(ENOTSUP);
|
throw FuseErrnoException(ENOTSUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CryNode::rename(const bf::path &to) {
|
void CryNode::rename(const bf::path &to) {
|
||||||
//TODO More efficient implementation possible: directly rename when it's actually not moved to a different directory
|
//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.
|
||||||
|
mode_t mode = _parent->GetChild(_key).mode;
|
||||||
_parent->RemoveChild(_key);
|
_parent->RemoveChild(_key);
|
||||||
_parent->flush();
|
_parent->flush();
|
||||||
auto targetDir = _device->LoadDirBlob(to.parent_path());
|
auto targetDir = _device->LoadDirBlob(to.parent_path());
|
||||||
targetDir->AddChild(to.filename().native(), _key, getType());
|
targetDir->AddChild(to.filename().native(), _key, getType(), mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CryNode::utimens(const timespec times[2]) {
|
void CryNode::utimens(const timespec times[2]) {
|
||||||
|
//TODO
|
||||||
throw FuseErrnoException(ENOTSUP);
|
throw FuseErrnoException(ENOTSUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,4 +68,22 @@ unique_ptr<Blob> CryNode::LoadBlob() const {
|
|||||||
return _device->LoadBlob(_key);
|
return _device->LoadBlob(_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CryNode::stat(struct ::stat *result) const {
|
||||||
|
if(_parent.get() == nullptr) {
|
||||||
|
//We arethe root directory.
|
||||||
|
//TODO What should we do?
|
||||||
|
result->st_mode = S_IFDIR;
|
||||||
|
} else {
|
||||||
|
_parent->statChild(_key, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CryNode::chmod(mode_t mode) {
|
||||||
|
_parent->chmodChild(_key, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CryNode::chown(uid_t uid, gid_t gid) {
|
||||||
|
_parent->chownChild(_key, uid, gid);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,9 @@ class CryNode: public virtual fspp::Node {
|
|||||||
public:
|
public:
|
||||||
CryNode(CryDevice *device, std::unique_ptr<DirBlob> parent, const blockstore::Key &key);
|
CryNode(CryDevice *device, std::unique_ptr<DirBlob> parent, const blockstore::Key &key);
|
||||||
void access(int mask) const override;
|
void access(int mask) const override;
|
||||||
|
void stat(struct ::stat *result) const override;
|
||||||
|
void chmod(mode_t mode) override;
|
||||||
|
void chown(uid_t uid, gid_t gid) override;
|
||||||
void rename(const boost::filesystem::path &to) override;
|
void rename(const boost::filesystem::path &to) override;
|
||||||
void utimens(const timespec times[2]) override;
|
void utimens(const timespec times[2]) override;
|
||||||
void remove() override;
|
void remove() override;
|
||||||
|
@ -5,7 +5,10 @@
|
|||||||
#include "messmer/fspp/fuse/FuseErrnoException.h"
|
#include "messmer/fspp/fuse/FuseErrnoException.h"
|
||||||
|
|
||||||
#include <messmer/blockstore/utils/Data.h>
|
#include <messmer/blockstore/utils/Data.h>
|
||||||
|
#include <messmer/blobstore/implementations/onblocks/utils/Math.h>
|
||||||
#include "MagicNumbers.h"
|
#include "MagicNumbers.h"
|
||||||
|
#include "../CryDevice.h"
|
||||||
|
#include "FileBlob.h"
|
||||||
|
|
||||||
using std::unique_ptr;
|
using std::unique_ptr;
|
||||||
using std::make_unique;
|
using std::make_unique;
|
||||||
@ -20,29 +23,26 @@ using blockstore::Data;
|
|||||||
|
|
||||||
namespace cryfs {
|
namespace cryfs {
|
||||||
|
|
||||||
DirBlob::DirBlob(unique_ptr<Blob> blob) :
|
DirBlob::DirBlob(unique_ptr<Blob> blob, CryDevice *device) :
|
||||||
_blob(std::move(blob)), _entries(), _changed(false) {
|
_device(device), _blob(std::move(blob)), _entries(), _changed(false) {
|
||||||
assert(magicNumber() == MagicNumbers::DIR);
|
assert(magicNumber() == MagicNumbers::DIR);
|
||||||
_readEntriesFromBlob();
|
_readEntriesFromBlob();
|
||||||
}
|
}
|
||||||
|
|
||||||
DirBlob::~DirBlob() {
|
DirBlob::~DirBlob() {
|
||||||
flush();
|
_writeEntriesToBlob();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirBlob::flush() {
|
void DirBlob::flush() {
|
||||||
if (_changed) {
|
_writeEntriesToBlob();
|
||||||
_writeEntriesToBlob();
|
|
||||||
_changed = false;
|
|
||||||
}
|
|
||||||
_blob->flush();
|
_blob->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DirBlob> DirBlob::InitializeEmptyDir(unique_ptr<Blob> blob) {
|
unique_ptr<DirBlob> DirBlob::InitializeEmptyDir(unique_ptr<Blob> blob, CryDevice *device) {
|
||||||
blob->resize(1);
|
blob->resize(1);
|
||||||
unsigned char magicNumber = MagicNumbers::DIR;
|
unsigned char magicNumber = MagicNumbers::DIR;
|
||||||
blob->write(&magicNumber, 0, 1);
|
blob->write(&magicNumber, 0, 1);
|
||||||
return make_unique < DirBlob > (std::move(blob));
|
return make_unique<DirBlob>(std::move(blob), device);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char DirBlob::magicNumber() const {
|
unsigned char DirBlob::magicNumber() const {
|
||||||
@ -52,18 +52,28 @@ unsigned char DirBlob::magicNumber() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DirBlob::_writeEntriesToBlob() {
|
void DirBlob::_writeEntriesToBlob() {
|
||||||
//TODO Resizing is imperformant
|
if (_changed) {
|
||||||
_blob->resize(1);
|
//TODO Resizing is imperformant
|
||||||
unsigned int offset = 1;
|
_blob->resize(1);
|
||||||
for (const auto &entry : _entries) {
|
unsigned int offset = 1;
|
||||||
unsigned char entryTypeMagicNumber = static_cast<unsigned char>(entry.type);
|
for (const auto &entry : _entries) {
|
||||||
_blob->write(&entryTypeMagicNumber, offset, 1);
|
unsigned char entryTypeMagicNumber = static_cast<unsigned char>(entry.type);
|
||||||
offset += 1;
|
_blob->write(&entryTypeMagicNumber, offset, 1);
|
||||||
_blob->write(entry.name.c_str(), offset, entry.name.size() + 1);
|
offset += 1;
|
||||||
offset += entry.name.size() + 1;
|
_blob->write(entry.name.c_str(), offset, entry.name.size() + 1);
|
||||||
string keystr = entry.key.ToString();
|
offset += entry.name.size() + 1;
|
||||||
_blob->write(keystr.c_str(), offset, keystr.size() + 1);
|
string keystr = entry.key.ToString();
|
||||||
offset += keystr.size() + 1;
|
_blob->write(keystr.c_str(), offset, keystr.size() + 1);
|
||||||
|
offset += keystr.size() + 1;
|
||||||
|
_blob->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);
|
||||||
|
}
|
||||||
|
_changed = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +103,18 @@ const char *DirBlob::readAndAddNextChild(const char *pos,
|
|||||||
std::string keystr(pos, keylength);
|
std::string keystr(pos, keylength);
|
||||||
pos += keylength + 1;
|
pos += keylength + 1;
|
||||||
|
|
||||||
result->emplace_back(type, name, Key::FromString(keystr));
|
//It might make sense to read all of them at once with a memcpy
|
||||||
|
|
||||||
|
uid_t uid = *(uid_t*)pos;
|
||||||
|
pos += sizeof(uid_t);
|
||||||
|
|
||||||
|
gid_t gid = *(gid_t*)pos;
|
||||||
|
pos += sizeof(gid_t);
|
||||||
|
|
||||||
|
mode_t mode = *(mode_t*)pos;
|
||||||
|
pos += sizeof(mode_t);
|
||||||
|
|
||||||
|
result->emplace_back(type, name, Key::FromString(keystr), mode, uid, gid);
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,21 +125,21 @@ bool DirBlob::hasChild(const string &name) const {
|
|||||||
return found != _entries.end();
|
return found != _entries.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirBlob::AddChildDir(const std::string &name, const Key &blobKey) {
|
void DirBlob::AddChildDir(const std::string &name, const Key &blobKey, mode_t mode) {
|
||||||
AddChild(name, blobKey, fspp::Dir::EntryType::DIR);
|
AddChild(name, blobKey, fspp::Dir::EntryType::DIR, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirBlob::AddChildFile(const std::string &name, const Key &blobKey) {
|
void DirBlob::AddChildFile(const std::string &name, const Key &blobKey, mode_t mode) {
|
||||||
AddChild(name, blobKey, fspp::Dir::EntryType::FILE);
|
AddChild(name, blobKey, fspp::Dir::EntryType::FILE, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirBlob::AddChild(const std::string &name, const Key &blobKey,
|
void DirBlob::AddChild(const std::string &name, const Key &blobKey,
|
||||||
fspp::Dir::EntryType entryType) {
|
fspp::Dir::EntryType entryType, mode_t mode) {
|
||||||
if (hasChild(name)) {
|
if (hasChild(name)) {
|
||||||
throw fspp::fuse::FuseErrnoException(EEXIST);
|
throw fspp::fuse::FuseErrnoException(EEXIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
_entries.emplace_back(entryType, name, blobKey);
|
_entries.emplace_back(entryType, name, blobKey, mode);
|
||||||
_changed = true;
|
_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,17 +153,33 @@ const DirBlob::Entry &DirBlob::GetChild(const string &name) const {
|
|||||||
return *found;
|
return *found;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirBlob::RemoveChild(const Key &key) {
|
const DirBlob::Entry &DirBlob::GetChild(const Key &key) const {
|
||||||
auto found = std::find_if(_entries.begin(), _entries.end(), [key] (const Entry &entry) {
|
auto found = std::find_if(_entries.begin(), _entries.end(), [key] (const Entry &entry) {
|
||||||
return entry.key == key;
|
return entry.key == key;
|
||||||
});
|
});
|
||||||
if (found == _entries.end()) {
|
if (found == _entries.end()) {
|
||||||
throw fspp::fuse::FuseErrnoException(ENOENT);
|
throw fspp::fuse::FuseErrnoException(ENOENT);
|
||||||
}
|
}
|
||||||
|
return *found;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirBlob::RemoveChild(const Key &key) {
|
||||||
|
auto found = _findChild(key);
|
||||||
_entries.erase(found);
|
_entries.erase(found);
|
||||||
_changed = true;
|
_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<DirBlob::Entry>::iterator DirBlob::_findChild(const Key &key) {
|
||||||
|
//TODO Code duplication with GetChild(key)
|
||||||
|
auto found = std::find_if(_entries.begin(), _entries.end(), [key] (const Entry &entry) {
|
||||||
|
return entry.key == key;
|
||||||
|
});
|
||||||
|
if (found == _entries.end()) {
|
||||||
|
throw fspp::fuse::FuseErrnoException(ENOENT);
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
void DirBlob::AppendChildrenTo(vector<fspp::Dir::Entry> *result) const {
|
void DirBlob::AppendChildrenTo(vector<fspp::Dir::Entry> *result) const {
|
||||||
result->reserve(result->size() + _entries.size());
|
result->reserve(result->size() + _entries.size());
|
||||||
for (const auto &entry : _entries) {
|
for (const auto &entry : _entries) {
|
||||||
@ -150,4 +187,45 @@ void DirBlob::AppendChildrenTo(vector<fspp::Dir::Entry> *result) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DirBlob::statChild(const Key &key, struct ::stat *result) const {
|
||||||
|
auto child = GetChild(key);
|
||||||
|
//TODO Loading the blob for only getting the size is not very performant.
|
||||||
|
// Furthermore, this is the only reason why DirBlob needs a pointer to CryDevice, which is ugly
|
||||||
|
result->st_mode = child.mode;
|
||||||
|
result->st_uid = child.uid;
|
||||||
|
result->st_gid = child.gid;
|
||||||
|
//TODO If possible without performance loss, then for a directory, st_nlink should return number of dir entries (including "." and "..")
|
||||||
|
result->st_nlink = 1;
|
||||||
|
//TODO Handle file access times
|
||||||
|
clock_gettime(CLOCK_REALTIME, &result->st_atim);
|
||||||
|
result->st_mtim = result->st_ctim = result->st_atim;
|
||||||
|
if (child.type == fspp::Dir::EntryType::FILE) {
|
||||||
|
result->st_size = FileBlob(_device->LoadBlob(key)).size();
|
||||||
|
} else {
|
||||||
|
result->st_size = 4096;
|
||||||
|
}
|
||||||
|
//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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirBlob::chmodChild(const Key &key, mode_t mode) {
|
||||||
|
auto found = _findChild(key);
|
||||||
|
assert ((S_ISREG(mode) && S_ISREG(found->mode)) || (S_ISDIR(mode) && S_ISDIR(found->mode)));
|
||||||
|
found->mode = mode;
|
||||||
|
_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirBlob::chownChild(const Key &key, uid_t uid, gid_t gid) {
|
||||||
|
auto found = _findChild(key);
|
||||||
|
if (uid != (uid_t)-1) {
|
||||||
|
found->uid = uid;
|
||||||
|
_changed = true;
|
||||||
|
}
|
||||||
|
if (gid != (gid_t)-1) {
|
||||||
|
found->gid = gid;
|
||||||
|
_changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,29 +11,50 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace cryfs{
|
namespace cryfs{
|
||||||
|
class CryDevice;
|
||||||
|
|
||||||
class DirBlob {
|
class DirBlob {
|
||||||
public:
|
public:
|
||||||
struct Entry {
|
struct Entry {
|
||||||
Entry(fspp::Dir::EntryType type_, const std::string &name_, const blockstore::Key &key_): type(type_), name(name_), key(key_) {}
|
//TODO Remove default value for parameters uid_ and gid_ and instead pass them in
|
||||||
|
Entry(fspp::Dir::EntryType type_, const std::string &name_, const blockstore::Key &key_, mode_t mode_, uid_t uid_=0, gid_t gid_=0): 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;
|
||||||
|
}
|
||||||
|
assert((S_ISREG(mode) && type == fspp::Dir::EntryType::FILE) || (S_ISDIR(mode) && type == fspp::Dir::EntryType::DIR));
|
||||||
|
}
|
||||||
|
|
||||||
fspp::Dir::EntryType type;
|
fspp::Dir::EntryType type;
|
||||||
std::string name;
|
std::string name;
|
||||||
blockstore::Key key;
|
blockstore::Key key;
|
||||||
|
uid_t uid;
|
||||||
|
gid_t gid;
|
||||||
|
mode_t mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::unique_ptr<DirBlob> InitializeEmptyDir(std::unique_ptr<blobstore::Blob> blob);
|
static std::unique_ptr<DirBlob> InitializeEmptyDir(std::unique_ptr<blobstore::Blob> blob, CryDevice *device);
|
||||||
|
|
||||||
DirBlob(std::unique_ptr<blobstore::Blob> blob);
|
DirBlob(std::unique_ptr<blobstore::Blob> blob, CryDevice *device);
|
||||||
virtual ~DirBlob();
|
virtual ~DirBlob();
|
||||||
|
|
||||||
void AppendChildrenTo(std::vector<fspp::Dir::Entry> *result) const;
|
void AppendChildrenTo(std::vector<fspp::Dir::Entry> *result) const;
|
||||||
const Entry &GetChild(const std::string &name) const;
|
const Entry &GetChild(const std::string &name) const;
|
||||||
void AddChildDir(const std::string &name, const blockstore::Key &blobKey);
|
const Entry &GetChild(const blockstore::Key &key) const;
|
||||||
void AddChildFile(const std::string &name, const blockstore::Key &blobKey);
|
void AddChildDir(const std::string &name, const blockstore::Key &blobKey, mode_t mode);
|
||||||
void AddChild(const std::string &name, const blockstore::Key &blobKey, fspp::Dir::EntryType type);
|
void AddChildFile(const std::string &name, const blockstore::Key &blobKey, mode_t mode);
|
||||||
|
void AddChild(const std::string &name, const blockstore::Key &blobKey, fspp::Dir::EntryType type, mode_t mode);
|
||||||
void RemoveChild(const blockstore::Key &key);
|
void RemoveChild(const blockstore::Key &key);
|
||||||
void flush();
|
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:
|
private:
|
||||||
unsigned char magicNumber() const;
|
unsigned char magicNumber() const;
|
||||||
|
|
||||||
@ -43,6 +64,9 @@ private:
|
|||||||
void _readEntriesFromBlob();
|
void _readEntriesFromBlob();
|
||||||
void _writeEntriesToBlob();
|
void _writeEntriesToBlob();
|
||||||
|
|
||||||
|
std::vector<DirBlob::Entry>::iterator _findChild(const blockstore::Key &key);
|
||||||
|
|
||||||
|
CryDevice *_device;
|
||||||
std::unique_ptr<blobstore::Blob> _blob;
|
std::unique_ptr<blobstore::Blob> _blob;
|
||||||
std::vector<Entry> _entries;
|
std::vector<Entry> _entries;
|
||||||
bool _changed;
|
bool _changed;
|
||||||
|
Loading…
Reference in New Issue
Block a user