We don't actually need to calculate or store the ancestor chain unless we're renaming
This commit is contained in:
parent
222ef46d8d
commit
45895d8d4f
@ -191,17 +191,15 @@ optional<unique_ref<fspp::Node>> CryDevice::Load(const bf::path &path) {
|
|||||||
|
|
||||||
if (path.parent_path().empty()) {
|
if (path.parent_path().empty()) {
|
||||||
//We are asked to load the base directory '/'.
|
//We are asked to load the base directory '/'.
|
||||||
return optional<unique_ref<fspp::Node>>(make_unique_ref<CryDir>(this, none, none, _rootBlobId, std::vector<BlockId>()));
|
return optional<unique_ref<fspp::Node>>(make_unique_ref<CryDir>(this, none, none, _rootBlobId));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto parentWithAncestors = LoadDirBlobWithAncestors(path.parent_path());
|
auto parentWithAncestors = LoadDirBlobWithAncestors(path.parent_path(), none);
|
||||||
if (parentWithAncestors == none) {
|
if (parentWithAncestors == none) {
|
||||||
return none;
|
return none;
|
||||||
}
|
}
|
||||||
auto parent = std::move(parentWithAncestors->blob);
|
auto parent = std::move(parentWithAncestors->blob);
|
||||||
auto grandparent = std::move(parentWithAncestors->parent);
|
auto grandparent = std::move(parentWithAncestors->parent);
|
||||||
auto ancestors = std::move(parentWithAncestors->ancestors);
|
|
||||||
ancestors.push_back(parent->blockId()); // parent's ancestors don't contain parent yet, but parent is our ancestor
|
|
||||||
|
|
||||||
auto optEntry = parent->GetChild(path.filename().string());
|
auto optEntry = parent->GetChild(path.filename().string());
|
||||||
if (optEntry == boost::none) {
|
if (optEntry == boost::none) {
|
||||||
@ -211,17 +209,17 @@ optional<unique_ref<fspp::Node>> CryDevice::Load(const bf::path &path) {
|
|||||||
|
|
||||||
switch(entry.type()) {
|
switch(entry.type()) {
|
||||||
case fspp::Dir::EntryType::DIR:
|
case fspp::Dir::EntryType::DIR:
|
||||||
return optional<unique_ref<fspp::Node>>(make_unique_ref<CryDir>(this, std::move(parent), std::move(grandparent), entry.blockId(), std::move(ancestors)));
|
return optional<unique_ref<fspp::Node>>(make_unique_ref<CryDir>(this, std::move(parent), std::move(grandparent), entry.blockId()));
|
||||||
case fspp::Dir::EntryType::FILE:
|
case fspp::Dir::EntryType::FILE:
|
||||||
return optional<unique_ref<fspp::Node>>(make_unique_ref<CryFile>(this, std::move(parent), std::move(grandparent), entry.blockId(), std::move(ancestors)));
|
return optional<unique_ref<fspp::Node>>(make_unique_ref<CryFile>(this, std::move(parent), std::move(grandparent), entry.blockId()));
|
||||||
case fspp::Dir::EntryType::SYMLINK:
|
case fspp::Dir::EntryType::SYMLINK:
|
||||||
return optional<unique_ref<fspp::Node>>(make_unique_ref<CrySymlink>(this, std::move(parent), std::move(grandparent), entry.blockId(), std::move(ancestors)));
|
return optional<unique_ref<fspp::Node>>(make_unique_ref<CrySymlink>(this, std::move(parent), std::move(grandparent), entry.blockId()));
|
||||||
}
|
}
|
||||||
ASSERT(false, "Switch/case not exhaustive");
|
ASSERT(false, "Switch/case not exhaustive");
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<CryDevice::DirBlobWithAncestors> CryDevice::LoadDirBlobWithAncestors(const bf::path &path) {
|
optional<CryDevice::DirBlobWithAncestors> CryDevice::LoadDirBlobWithAncestors(const bf::path &path, boost::optional<std::vector<BlockId>*> append_ancestors_to) {
|
||||||
auto blob = LoadBlobWithAncestors(path);
|
auto blob = LoadBlobWithAncestors(path, std::move(append_ancestors_to));
|
||||||
if (blob == none) {
|
if (blob == none) {
|
||||||
return none;
|
return none;
|
||||||
}
|
}
|
||||||
@ -229,11 +227,10 @@ optional<CryDevice::DirBlobWithAncestors> CryDevice::LoadDirBlobWithAncestors(co
|
|||||||
if (dir == none) {
|
if (dir == none) {
|
||||||
throw FuseErrnoException(ENOTDIR); // Loaded blob is not a directory
|
throw FuseErrnoException(ENOTDIR); // Loaded blob is not a directory
|
||||||
}
|
}
|
||||||
return DirBlobWithAncestors{std::move(*dir), std::move(blob->parent), std::move(blob->ancestors)};
|
return DirBlobWithAncestors{std::move(*dir), std::move(blob->parent)};
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<CryDevice::BlobWithAncestors> CryDevice::LoadBlobWithAncestors(const bf::path &path) {
|
optional<CryDevice::BlobWithAncestors> CryDevice::LoadBlobWithAncestors(const bf::path &path, boost::optional<std::vector<BlockId>*> append_ancestors_to) {
|
||||||
std::vector<blockstore::BlockId> ancestors;
|
|
||||||
optional<unique_ref<DirBlobRef>> parentBlob = none;
|
optional<unique_ref<DirBlobRef>> parentBlob = none;
|
||||||
optional<unique_ref<FsBlobRef>> currentBlobOpt = _fsBlobStore->load(_rootBlobId);
|
optional<unique_ref<FsBlobRef>> currentBlobOpt = _fsBlobStore->load(_rootBlobId);
|
||||||
if (currentBlobOpt == none) {
|
if (currentBlobOpt == none) {
|
||||||
@ -244,7 +241,9 @@ optional<CryDevice::BlobWithAncestors> CryDevice::LoadBlobWithAncestors(const bf
|
|||||||
ASSERT(currentBlob->parentPointer() == BlockId::Null(), "Root Blob should have a nullptr as parent");
|
ASSERT(currentBlob->parentPointer() == BlockId::Null(), "Root Blob should have a nullptr as parent");
|
||||||
|
|
||||||
for (const bf::path &component : path.relative_path()) {
|
for (const bf::path &component : path.relative_path()) {
|
||||||
ancestors.push_back(currentBlob->blockId());
|
if (append_ancestors_to != boost::none) {
|
||||||
|
(*append_ancestors_to)->push_back(currentBlob->blockId());
|
||||||
|
}
|
||||||
auto currentDir = dynamic_pointer_move<DirBlobRef>(currentBlob);
|
auto currentDir = dynamic_pointer_move<DirBlobRef>(currentBlob);
|
||||||
if (currentDir == none) {
|
if (currentDir == none) {
|
||||||
throw FuseErrnoException(ENOTDIR); // Path component is not a dir
|
throw FuseErrnoException(ENOTDIR); // Path component is not a dir
|
||||||
@ -265,7 +264,7 @@ optional<CryDevice::BlobWithAncestors> CryDevice::LoadBlobWithAncestors(const bf
|
|||||||
ASSERT(currentBlob->parentPointer() == (*parentBlob)->blockId(), "Blob has wrong parent pointer");
|
ASSERT(currentBlob->parentPointer() == (*parentBlob)->blockId(), "Blob has wrong parent pointer");
|
||||||
}
|
}
|
||||||
|
|
||||||
return BlobWithAncestors{std::move(currentBlob), std::move(parentBlob), std::move(ancestors)};
|
return BlobWithAncestors{std::move(currentBlob), std::move(parentBlob)};
|
||||||
|
|
||||||
//TODO (I think this is resolved, but I should test it)
|
//TODO (I think this is resolved, but I should test it)
|
||||||
// Running the python script, waiting for "Create files in sequential order...", then going into dir ~/tmp/cryfs-mount-.../Bonnie.../ and calling "ls"
|
// Running the python script, waiting for "Create files in sequential order...", then going into dir ~/tmp/cryfs-mount-.../Bonnie.../ and calling "ls"
|
||||||
|
@ -31,9 +31,8 @@ public:
|
|||||||
struct DirBlobWithAncestors {
|
struct DirBlobWithAncestors {
|
||||||
cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef> blob;
|
cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef> blob;
|
||||||
boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent;
|
boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent;
|
||||||
std::vector<blockstore::BlockId> ancestors;
|
|
||||||
};
|
};
|
||||||
boost::optional<DirBlobWithAncestors> LoadDirBlobWithAncestors(const boost::filesystem::path &path);
|
boost::optional<DirBlobWithAncestors> LoadDirBlobWithAncestors(const boost::filesystem::path &path, boost::optional<std::vector<blockstore::BlockId>*> append_ancestors_to);
|
||||||
void RemoveBlob(const blockstore::BlockId &blockId);
|
void RemoveBlob(const blockstore::BlockId &blockId);
|
||||||
|
|
||||||
void onFsAction(std::function<void()> callback);
|
void onFsAction(std::function<void()> callback);
|
||||||
@ -69,9 +68,8 @@ private:
|
|||||||
struct BlobWithAncestors {
|
struct BlobWithAncestors {
|
||||||
cpputils::unique_ref<parallelaccessfsblobstore::FsBlobRef> blob;
|
cpputils::unique_ref<parallelaccessfsblobstore::FsBlobRef> blob;
|
||||||
boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent;
|
boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent;
|
||||||
std::vector<blockstore::BlockId> ancestors;
|
|
||||||
};
|
};
|
||||||
boost::optional<BlobWithAncestors> LoadBlobWithAncestors(const boost::filesystem::path &path);
|
boost::optional<BlobWithAncestors> LoadBlobWithAncestors(const boost::filesystem::path &path, boost::optional<std::vector<blockstore::BlockId>*> append_ancestors_to);
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(CryDevice);
|
DISALLOW_COPY_AND_ASSIGN(CryDevice);
|
||||||
};
|
};
|
||||||
|
@ -28,8 +28,8 @@ using cryfs::parallelaccessfsblobstore::DirBlobRef;
|
|||||||
|
|
||||||
namespace cryfs {
|
namespace cryfs {
|
||||||
|
|
||||||
CryDir::CryDir(CryDevice *device, optional<unique_ref<DirBlobRef>> parent, optional<unique_ref<DirBlobRef>> grandparent, const BlockId &blockId, std::vector<BlockId> ancestors)
|
CryDir::CryDir(CryDevice *device, optional<unique_ref<DirBlobRef>> parent, optional<unique_ref<DirBlobRef>> grandparent, const BlockId &blockId)
|
||||||
: CryNode(device, std::move(parent), std::move(grandparent), blockId, std::move(ancestors)) {
|
: CryNode(device, std::move(parent), std::move(grandparent), blockId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CryDir::~CryDir() {
|
CryDir::~CryDir() {
|
||||||
|
@ -10,7 +10,7 @@ namespace cryfs {
|
|||||||
|
|
||||||
class CryDir final: public fspp::Dir, public CryNode {
|
class CryDir final: public fspp::Dir, public CryNode {
|
||||||
public:
|
public:
|
||||||
CryDir(CryDevice *device, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> grandparent, const blockstore::BlockId &blockId, std::vector<blockstore::BlockId> ancestors);
|
CryDir(CryDevice *device, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> grandparent, const blockstore::BlockId &blockId);
|
||||||
~CryDir();
|
~CryDir();
|
||||||
|
|
||||||
//TODO return type variance to CryFile/CryDir?
|
//TODO return type variance to CryFile/CryDir?
|
||||||
|
@ -18,8 +18,8 @@ using cryfs::parallelaccessfsblobstore::FileBlobRef;
|
|||||||
|
|
||||||
namespace cryfs {
|
namespace cryfs {
|
||||||
|
|
||||||
CryFile::CryFile(CryDevice *device, unique_ref<DirBlobRef> parent, optional<unique_ref<DirBlobRef>> grandparent, const BlockId &blockId, std::vector<BlockId> ancestors)
|
CryFile::CryFile(CryDevice *device, unique_ref<DirBlobRef> parent, optional<unique_ref<DirBlobRef>> grandparent, const BlockId &blockId)
|
||||||
: CryNode(device, std::move(parent), std::move(grandparent), blockId, std::move(ancestors)) {
|
: CryNode(device, std::move(parent), std::move(grandparent), blockId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CryFile::~CryFile() {
|
CryFile::~CryFile() {
|
||||||
|
@ -11,7 +11,7 @@ namespace cryfs {
|
|||||||
|
|
||||||
class CryFile final: public fspp::File, public CryNode {
|
class CryFile final: public fspp::File, public CryNode {
|
||||||
public:
|
public:
|
||||||
CryFile(CryDevice *device, cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef> parent, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> grandparent, const blockstore::BlockId &blockId, std::vector<blockstore::BlockId> ancestors);
|
CryFile(CryDevice *device, cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef> parent, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> grandparent, const blockstore::BlockId &blockId);
|
||||||
~CryFile();
|
~CryFile();
|
||||||
|
|
||||||
cpputils::unique_ref<fspp::OpenFile> open(fspp::openflags_t flags) override;
|
cpputils::unique_ref<fspp::OpenFile> open(fspp::openflags_t flags) override;
|
||||||
|
@ -18,6 +18,7 @@ using cpputils::dynamic_pointer_move;
|
|||||||
using boost::optional;
|
using boost::optional;
|
||||||
using boost::none;
|
using boost::none;
|
||||||
using std::shared_ptr;
|
using std::shared_ptr;
|
||||||
|
using std::vector;
|
||||||
using cryfs::parallelaccessfsblobstore::FsBlobRef;
|
using cryfs::parallelaccessfsblobstore::FsBlobRef;
|
||||||
using cryfs::parallelaccessfsblobstore::DirBlobRef;
|
using cryfs::parallelaccessfsblobstore::DirBlobRef;
|
||||||
using namespace cpputils::logging;
|
using namespace cpputils::logging;
|
||||||
@ -27,11 +28,10 @@ using fspp::fuse::FuseErrnoException;
|
|||||||
|
|
||||||
namespace cryfs {
|
namespace cryfs {
|
||||||
|
|
||||||
CryNode::CryNode(CryDevice *device, optional<unique_ref<DirBlobRef>> parent, optional<unique_ref<DirBlobRef>> grandparent, const BlockId &blockId, std::vector<BlockId> ancestors)
|
CryNode::CryNode(CryDevice *device, optional<unique_ref<DirBlobRef>> parent, optional<unique_ref<DirBlobRef>> grandparent, const BlockId &blockId)
|
||||||
: _device(device),
|
: _device(device),
|
||||||
_parent(none),
|
_parent(none),
|
||||||
_grandparent(none),
|
_grandparent(none),
|
||||||
_ancestors(std::move(ancestors)),
|
|
||||||
_blockId(blockId) {
|
_blockId(blockId) {
|
||||||
|
|
||||||
ASSERT(parent != none || grandparent == none, "Grandparent can only be set when parent is not none");
|
ASSERT(parent != none || grandparent == none, "Grandparent can only be set when parent is not none");
|
||||||
@ -88,15 +88,15 @@ void CryNode::rename(const bf::path &to) {
|
|||||||
throw FuseErrnoException(EBUSY);
|
throw FuseErrnoException(EBUSY);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto targetParentAndAncestors = _device->LoadDirBlobWithAncestors(to.parent_path());
|
vector<BlockId> targetAncestors;
|
||||||
|
auto targetParentAndAncestors = _device->LoadDirBlobWithAncestors(to.parent_path(), &targetAncestors);
|
||||||
if (targetParentAndAncestors == none) {
|
if (targetParentAndAncestors == none) {
|
||||||
// Target parent directory doesn't exist
|
// Target parent directory doesn't exist
|
||||||
throw FuseErrnoException(ENOENT);
|
throw FuseErrnoException(ENOENT);
|
||||||
}
|
}
|
||||||
auto targetParent = std::move(targetParentAndAncestors->blob);
|
auto targetParent = std::move(targetParentAndAncestors->blob);
|
||||||
auto targetGrandparent = std::move(targetParentAndAncestors->parent);
|
auto targetGrandparent = std::move(targetParentAndAncestors->parent);
|
||||||
auto targetAncestors = std::move(targetParentAndAncestors->ancestors);
|
targetAncestors.push_back(targetParent->blockId()); // targetParent is not an ancestor of the targetParent, so it wasn't filled in, but it's a target ancestor
|
||||||
targetAncestors.push_back(targetParent->blockId()); // targetParent is not an ancestor of the targetParent, but it's a target ancestor
|
|
||||||
|
|
||||||
if (std::find(targetAncestors.begin(), targetAncestors.end(), _blockId) != targetAncestors.end()) {
|
if (std::find(targetAncestors.begin(), targetAncestors.end(), _blockId) != targetAncestors.end()) {
|
||||||
// We are trying to move a node into one of its subdirectories. This is not allowed.
|
// We are trying to move a node into one of its subdirectories. This is not allowed.
|
||||||
|
@ -15,7 +15,7 @@ public:
|
|||||||
virtual ~CryNode();
|
virtual ~CryNode();
|
||||||
|
|
||||||
// TODO grandparent is only needed to set the timestamps of the parent directory on rename and remove. Delete grandparent parameter once we store timestamps in the blob itself instead of in the directory listing.
|
// TODO grandparent is only needed to set the timestamps of the parent directory on rename and remove. Delete grandparent parameter once we store timestamps in the blob itself instead of in the directory listing.
|
||||||
CryNode(CryDevice *device, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> grandparent, const blockstore::BlockId &blockId, std::vector<blockstore::BlockId> ancestors);
|
CryNode(CryDevice *device, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> grandparent, const blockstore::BlockId &blockId);
|
||||||
|
|
||||||
void access(int mask) const override;
|
void access(int mask) const override;
|
||||||
stat_info stat() const override;
|
stat_info stat() const override;
|
||||||
@ -51,7 +51,6 @@ private:
|
|||||||
CryDevice *_device;
|
CryDevice *_device;
|
||||||
boost::optional<std::shared_ptr<parallelaccessfsblobstore::DirBlobRef>> _parent;
|
boost::optional<std::shared_ptr<parallelaccessfsblobstore::DirBlobRef>> _parent;
|
||||||
boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> _grandparent;
|
boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> _grandparent;
|
||||||
std::vector<blockstore::BlockId> _ancestors; // [n-1] is the parent, [n-2] is the grandparent, ..., [0] is the file system root,
|
|
||||||
blockstore::BlockId _blockId;
|
blockstore::BlockId _blockId;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(CryNode);
|
DISALLOW_COPY_AND_ASSIGN(CryNode);
|
||||||
|
@ -21,8 +21,8 @@ using cryfs::parallelaccessfsblobstore::DirBlobRef;
|
|||||||
|
|
||||||
namespace cryfs {
|
namespace cryfs {
|
||||||
|
|
||||||
CrySymlink::CrySymlink(CryDevice *device, unique_ref<DirBlobRef> parent, optional<unique_ref<DirBlobRef>> grandparent, const BlockId &blockId, std::vector<blockstore::BlockId> ancestors)
|
CrySymlink::CrySymlink(CryDevice *device, unique_ref<DirBlobRef> parent, optional<unique_ref<DirBlobRef>> grandparent, const BlockId &blockId)
|
||||||
: CryNode(device, std::move(parent), std::move(grandparent), blockId, std::move(ancestors)) {
|
: CryNode(device, std::move(parent), std::move(grandparent), blockId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CrySymlink::~CrySymlink() {
|
CrySymlink::~CrySymlink() {
|
||||||
|
@ -11,7 +11,7 @@ namespace cryfs {
|
|||||||
|
|
||||||
class CrySymlink final: public fspp::Symlink, public CryNode {
|
class CrySymlink final: public fspp::Symlink, public CryNode {
|
||||||
public:
|
public:
|
||||||
CrySymlink(CryDevice *device, cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef> parent, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> grandparent, const blockstore::BlockId &blockId, std::vector<blockstore::BlockId> ancestors);
|
CrySymlink(CryDevice *device, cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef> parent, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> grandparent, const blockstore::BlockId &blockId);
|
||||||
~CrySymlink();
|
~CrySymlink();
|
||||||
|
|
||||||
boost::filesystem::path target() override;
|
boost::filesystem::path target() override;
|
||||||
|
Loading…
Reference in New Issue
Block a user