From 652a95dd0d5ee1e98b897bc0f209a67d7a7583c3 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Mon, 21 Jan 2019 01:27:32 -0800 Subject: [PATCH] If a migration was interrupted, continue on next mount --- src/cryfs/config/CryConfig.cpp | 11 +++++++++++ src/cryfs/config/CryConfig.h | 6 ++++++ src/cryfs/filesystem/CryDevice.cpp | 10 +++++++++- src/cryfs/filesystem/fsblobstore/FsBlobStore.cpp | 1 + src/cryfs/filesystem/fsblobstore/FsBlobView.cpp | 6 +++++- 5 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/cryfs/config/CryConfig.cpp b/src/cryfs/config/CryConfig.cpp index 3558e693..01b49843 100644 --- a/src/cryfs/config/CryConfig.cpp +++ b/src/cryfs/config/CryConfig.cpp @@ -32,6 +32,7 @@ CryConfig::CryConfig() , _exclusiveClientId(none) #ifndef CRYFS_NO_COMPATIBILITY , _hasVersionNumbers(true) +, _hasParentPointers(true) #endif { } @@ -53,6 +54,7 @@ CryConfig CryConfig::load(const Data &data) { cfg._exclusiveClientId = pt.get_optional("cryfs.exclusiveClientId"); #ifndef CRYFS_NO_COMPATIBILITY cfg._hasVersionNumbers = pt.get("cryfs.migrations.hasVersionNumbers", false); + cfg._hasParentPointers = pt.get("cryfs.migrations.hasParentPointers", false); #endif optional filesystemIdOpt = pt.get_optional("cryfs.filesystemId"); @@ -81,6 +83,7 @@ Data CryConfig::save() const { } #ifndef CRYFS_NO_COMPATIBILITY pt.put("cryfs.migrations.hasVersionNumbers", _hasVersionNumbers); + pt.put("cryfs.migrations.hasParentPointers", _hasParentPointers); #endif stringstream stream; @@ -172,6 +175,14 @@ bool CryConfig::HasVersionNumbers() const { void CryConfig::SetHasVersionNumbers(bool value) { _hasVersionNumbers = value; } + +bool CryConfig::HasParentPointers() const { + return _hasParentPointers; +} + +void CryConfig::SetHasParentPointers(bool value) { + _hasParentPointers = value; +} #endif } diff --git a/src/cryfs/config/CryConfig.h b/src/cryfs/config/CryConfig.h index 26fdcaeb..618d67e3 100644 --- a/src/cryfs/config/CryConfig.h +++ b/src/cryfs/config/CryConfig.h @@ -56,6 +56,11 @@ public: // Version numbers cannot be disabled, but the file system will be migrated to version numbers automatically. bool HasVersionNumbers() const; void SetHasVersionNumbers(bool value); + + // This is a trigger to recognize old file systems that didn't have version numbers. + // Version numbers cannot be disabled, but the file system will be migrated to version numbers automatically. + bool HasParentPointers() const; + void SetHasParentPointers(bool value); #endif static CryConfig load(const cpputils::Data &data); @@ -73,6 +78,7 @@ private: boost::optional _exclusiveClientId; #ifndef CRYFS_NO_COMPATIBILITY bool _hasVersionNumbers; + bool _hasParentPointers; #endif CryConfig &operator=(const CryConfig &rhs) = delete; diff --git a/src/cryfs/filesystem/CryDevice.cpp b/src/cryfs/filesystem/CryDevice.cpp index c6d9ee7e..a27e684f 100644 --- a/src/cryfs/filesystem/CryDevice.cpp +++ b/src/cryfs/filesystem/CryDevice.cpp @@ -80,7 +80,14 @@ unique_ref CryDevice::MigrateOrCreateFsBlobStore(uniqu if ("" == rootBlobId) { return make_unique_ref(std::move(blobStore)); } - return FsBlobStore::migrateIfNeeded(std::move(blobStore), BlockId::FromString(rootBlobId)); + if (!configFile->config()->HasParentPointers()) { + auto result = FsBlobStore::migrateIfNeeded(std::move(blobStore), BlockId::FromString(rootBlobId)); + // Don't migrate again if it was successful + configFile->config()->SetHasParentPointers(true); + configFile->save(); + return result; + } + return make_unique_ref(std::move(blobStore)); } #endif @@ -106,6 +113,7 @@ unique_ref CryDevice::CreateIntegrityEncryptedBlockStore(unique_ref if (!configFile->config()->HasVersionNumbers()) { IntegrityBlockStore2::migrateFromBlockstoreWithoutVersionNumbers(encryptedBlockStore.get(), integrityFilePath, myClientId); configFile->config()->SetBlocksizeBytes(configFile->config()->BlocksizeBytes() + IntegrityBlockStore2::HEADER_LENGTH - blockstore::BlockId::BINARY_LENGTH); // Minus BlockId size because EncryptedBlockStore doesn't store the BlockId anymore (that was moved to IntegrityBlockStore) + // Don't migrate again if it was successful configFile->config()->SetHasVersionNumbers(true); configFile->save(); } diff --git a/src/cryfs/filesystem/fsblobstore/FsBlobStore.cpp b/src/cryfs/filesystem/fsblobstore/FsBlobStore.cpp index 6d116358..1a059d66 100644 --- a/src/cryfs/filesystem/fsblobstore/FsBlobStore.cpp +++ b/src/cryfs/filesystem/fsblobstore/FsBlobStore.cpp @@ -2,6 +2,7 @@ #include "FileBlob.h" #include "DirBlob.h" #include "SymlinkBlob.h" +#include using cpputils::unique_ref; using cpputils::make_unique_ref; diff --git a/src/cryfs/filesystem/fsblobstore/FsBlobView.cpp b/src/cryfs/filesystem/fsblobstore/FsBlobView.cpp index 32d59240..c1f7e57d 100644 --- a/src/cryfs/filesystem/fsblobstore/FsBlobView.cpp +++ b/src/cryfs/filesystem/fsblobstore/FsBlobView.cpp @@ -10,7 +10,11 @@ namespace cryfs { void FsBlobView::migrate(blobstore::Blob *blob, const blockstore::BlockId &parentId) { constexpr unsigned int OLD_HEADER_SIZE = sizeof(FORMAT_VERSION_HEADER) + sizeof(uint8_t); - ASSERT(FsBlobView::getFormatVersionHeader(*blob) == 0, "Block already migrated"); + if(FsBlobView::getFormatVersionHeader(*blob) != 0) { + // blob already migrated + return; + } + // Resize blob and move data back cpputils::Data data = blob->readAll(); blob->resize(blob->size() + blockstore::BlockId::BINARY_LENGTH);