No need to build a vector, we can check the block id immediately when we see it
This commit is contained in:
parent
8b02ff7cc5
commit
c039629721
@ -194,7 +194,7 @@ optional<unique_ref<fspp::Node>> CryDevice::Load(const bf::path &path) {
|
||||
return optional<unique_ref<fspp::Node>>(make_unique_ref<CryDir>(this, none, none, _rootBlobId));
|
||||
}
|
||||
|
||||
auto parentWithAncestors = LoadDirBlobWithAncestors(path.parent_path(), none);
|
||||
auto parentWithAncestors = LoadDirBlobWithAncestors(path.parent_path(), [](const BlockId&){});
|
||||
if (parentWithAncestors == none) {
|
||||
return none;
|
||||
}
|
||||
@ -218,8 +218,8 @@ optional<unique_ref<fspp::Node>> CryDevice::Load(const bf::path &path) {
|
||||
ASSERT(false, "Switch/case not exhaustive");
|
||||
}
|
||||
|
||||
optional<CryDevice::DirBlobWithAncestors> CryDevice::LoadDirBlobWithAncestors(const bf::path &path, boost::optional<std::vector<BlockId>*> append_ancestors_to) {
|
||||
auto blob = LoadBlobWithAncestors(path, std::move(append_ancestors_to));
|
||||
optional<CryDevice::DirBlobWithAncestors> CryDevice::LoadDirBlobWithAncestors(const bf::path &path, std::function<void (const blockstore::BlockId&)> ancestor_callback) {
|
||||
auto blob = LoadBlobWithAncestors(path, std::move(ancestor_callback));
|
||||
if (blob == none) {
|
||||
return none;
|
||||
}
|
||||
@ -230,7 +230,7 @@ optional<CryDevice::DirBlobWithAncestors> CryDevice::LoadDirBlobWithAncestors(co
|
||||
return DirBlobWithAncestors{std::move(*dir), std::move(blob->parent)};
|
||||
}
|
||||
|
||||
optional<CryDevice::BlobWithAncestors> CryDevice::LoadBlobWithAncestors(const bf::path &path, boost::optional<std::vector<BlockId>*> append_ancestors_to) {
|
||||
optional<CryDevice::BlobWithAncestors> CryDevice::LoadBlobWithAncestors(const bf::path &path, std::function<void (const blockstore::BlockId&)> ancestor_callback) {
|
||||
optional<unique_ref<DirBlobRef>> parentBlob = none;
|
||||
optional<unique_ref<FsBlobRef>> currentBlobOpt = _fsBlobStore->load(_rootBlobId);
|
||||
if (currentBlobOpt == none) {
|
||||
@ -241,9 +241,7 @@ optional<CryDevice::BlobWithAncestors> CryDevice::LoadBlobWithAncestors(const bf
|
||||
ASSERT(currentBlob->parentPointer() == BlockId::Null(), "Root Blob should have a nullptr as parent");
|
||||
|
||||
for (const bf::path &component : path.relative_path()) {
|
||||
if (append_ancestors_to != boost::none) {
|
||||
(*append_ancestors_to)->push_back(currentBlob->blockId());
|
||||
}
|
||||
ancestor_callback(currentBlob->blockId());
|
||||
auto currentDir = dynamic_pointer_move<DirBlobRef>(currentBlob);
|
||||
if (currentDir == none) {
|
||||
throw FuseErrnoException(ENOTDIR); // Path component is not a dir
|
||||
|
@ -29,10 +29,10 @@ public:
|
||||
cpputils::unique_ref<parallelaccessfsblobstore::SymlinkBlobRef> CreateSymlinkBlob(const boost::filesystem::path &target, const blockstore::BlockId &parent);
|
||||
cpputils::unique_ref<parallelaccessfsblobstore::FsBlobRef> LoadBlob(const blockstore::BlockId &blockId);
|
||||
struct DirBlobWithAncestors {
|
||||
cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef> blob;
|
||||
boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent;
|
||||
cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef> blob;
|
||||
boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent;
|
||||
};
|
||||
boost::optional<DirBlobWithAncestors> LoadDirBlobWithAncestors(const boost::filesystem::path &path, boost::optional<std::vector<blockstore::BlockId>*> append_ancestors_to);
|
||||
boost::optional<DirBlobWithAncestors> LoadDirBlobWithAncestors(const boost::filesystem::path &path, std::function<void (const blockstore::BlockId&)> ancestor_callback);
|
||||
void RemoveBlob(const blockstore::BlockId &blockId);
|
||||
|
||||
void onFsAction(std::function<void()> callback);
|
||||
@ -66,10 +66,10 @@ private:
|
||||
static cpputils::unique_ref<blockstore::BlockStore2> CreateEncryptedBlockStore(const CryConfig &config, cpputils::unique_ref<blockstore::BlockStore2> baseBlockStore);
|
||||
|
||||
struct BlobWithAncestors {
|
||||
cpputils::unique_ref<parallelaccessfsblobstore::FsBlobRef> blob;
|
||||
boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent;
|
||||
cpputils::unique_ref<parallelaccessfsblobstore::FsBlobRef> blob;
|
||||
boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent;
|
||||
};
|
||||
boost::optional<BlobWithAncestors> LoadBlobWithAncestors(const boost::filesystem::path &path, boost::optional<std::vector<blockstore::BlockId>*> append_ancestors_to);
|
||||
boost::optional<BlobWithAncestors> LoadBlobWithAncestors(const boost::filesystem::path &path, std::function<void (const blockstore::BlockId&)> ancestor_callback);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CryDevice);
|
||||
};
|
||||
|
@ -89,18 +89,21 @@ void CryNode::rename(const bf::path &to) {
|
||||
}
|
||||
|
||||
vector<BlockId> targetAncestors;
|
||||
auto targetParentAndAncestors = _device->LoadDirBlobWithAncestors(to.parent_path(), &targetAncestors);
|
||||
auto targetParentAndAncestors = _device->LoadDirBlobWithAncestors(to.parent_path(), [&] (const BlockId& ancestorId) {
|
||||
if (ancestorId == _blockId) {
|
||||
// We are trying to move a node into one of its subdirectories. This is not allowed.
|
||||
throw FuseErrnoException(EINVAL);
|
||||
}
|
||||
});
|
||||
if (targetParentAndAncestors == none) {
|
||||
// Target parent directory doesn't exist
|
||||
throw FuseErrnoException(ENOENT);
|
||||
}
|
||||
auto targetParent = std::move(targetParentAndAncestors->blob);
|
||||
auto targetGrandparent = std::move(targetParentAndAncestors->parent);
|
||||
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
|
||||
|
||||
if (std::find(targetAncestors.begin(), targetAncestors.end(), _blockId) != targetAncestors.end()) {
|
||||
if (targetParent->blockId() == _blockId) {
|
||||
// We are trying to move a node into one of its subdirectories. This is not allowed.
|
||||
throw FuseErrnoException(EINVAL);
|
||||
throw FuseErrnoException(EINVAL);
|
||||
}
|
||||
|
||||
auto old = (*_parent)->GetChild(_blockId);
|
||||
|
Loading…
x
Reference in New Issue
Block a user