libcryfs/src/cryfs/filesystem/fsblobstore/FsBlobStore.cpp

70 lines
2.7 KiB
C++
Raw Normal View History

2015-09-30 13:21:07 +02:00
#include "FsBlobStore.h"
#include "FileBlob.h"
#include "DirBlob.h"
#include "SymlinkBlob.h"
namespace bf = boost::filesystem;
using cpputils::unique_ref;
using cpputils::make_unique_ref;
using blobstore::BlobStore;
using blockstore::Key;
2015-09-30 13:21:07 +02:00
using boost::none;
using std::function;
using std::vector;
2015-09-30 13:21:07 +02:00
namespace cryfs {
namespace fsblobstore {
boost::optional<unique_ref<FsBlob>> FsBlobStore::load(const blockstore::Key &key) {
auto blob = _baseBlobStore->load(key);
if (blob == none) {
return none;
}
FsBlobView::BlobType blobType = FsBlobView::blobType(**blob);
if (blobType == FsBlobView::BlobType::FILE) {
return unique_ref<FsBlob>(make_unique_ref<FileBlob>(std::move(*blob)));
} else if (blobType == FsBlobView::BlobType::DIR) {
2016-03-08 23:47:31 +01:00
return unique_ref<FsBlob>(make_unique_ref<DirBlob>(this, std::move(*blob), _getLstatSize()));
} else if (blobType == FsBlobView::BlobType::SYMLINK) {
return unique_ref<FsBlob>(make_unique_ref<SymlinkBlob>(std::move(*blob)));
2015-09-30 13:21:07 +02:00
} else {
ASSERT(false, "Unknown magic number");
}
}
#ifndef CRYFS_NO_COMPATIBILITY
unique_ref<FsBlobStore> FsBlobStore::migrateIfNeeded(unique_ref<BlobStore> blobStore, const blockstore::Key &rootKey) {
auto rootBlob = blobStore->load(rootKey);
ASSERT(rootBlob != none, "Could not load root blob");
uint16_t format = FsBlobView::getFormatVersionHeader(**rootBlob);
auto fsBlobStore = make_unique_ref<FsBlobStore>(std::move(blobStore));
if (format == 0) {
// migration needed
std::cout << "Migrating file system for conflict resolution features. Please don't interrupt this process. This can take a while..." << std::flush;
fsBlobStore->_migrate(std::move(*rootBlob), blockstore::Key::Null());
std::cout << "done" << std::endl;
}
return fsBlobStore;
}
void FsBlobStore::_migrate(unique_ref<blobstore::Blob> node, const blockstore::Key &parentKey) {
FsBlobView::migrate(node.get(), parentKey);
if (FsBlobView::blobType(*node) == FsBlobView::BlobType::DIR) {
DirBlob dir(this, std::move(node), _getLstatSize());
vector<fspp::Dir::Entry> children;
dir.AppendChildrenTo(&children);
for (const auto &child : children) {
auto childEntry = dir.GetChild(child.name);
ASSERT(childEntry != none, "Couldn't load child, although it was returned as a child in the lsit.");
auto childBlob = _baseBlobStore->load(childEntry->key());
ASSERT(childBlob != none, "Couldn't load child blob");
_migrate(std::move(*childBlob), dir.key());
}
}
}
#endif
}
2015-09-30 13:21:07 +02:00
}