Hi everyone,
I'd like to discuss the approach for fixing #9093 — leftover .crypted files that are never cleaned up in the resource directory.
The problem
When E2EE is enabled, .crypted files are created in two scenarios:
- Decryption (
Resource.decrypt()) — renames the encrypted blob to.crypted, decrypts it to plaintext, but never deletes the.cryptedfile afterward. - Sync upload (
Resource.fullPathForSyncUpload()) — encrypts a plaintext resource to.cryptedfor uploading, but never cleans it up after the sync completes.
Over time, these orphaned files accumulate and waste disk space.
Why runtime cleanup is risky
I initially submitted a PR that ran cleanup inside maintenance(), but as Laurent correctly pointed out, this creates race conditions:
- The
DecryptionWorkermay be actively reading a.cryptedfile during decryption. - The
Synchronizermay be about to upload a.cryptedfile created byfullPathForSyncUpload()— and in this case the local DB hasencryption_blob_encrypted = 0, so a database check alone isn't sufficient to protect it.
Proposed approach
Run the cleanup once at app startup, before the sync and decryption services start. At that point:
- No
DecryptionWorkeris running, so no.cryptedfile is being read. - No
Synchronizeris running, so no.cryptedfile is pending upload. - Any
.cryptedfile on disk is guaranteed to be a leftover from a previous session.
The only files we'd skip are those where encryption_blob_encrypted = 1 in the database, meaning the .crypted file is the primary data source (hasn't been decrypted yet).
Questions for the community
- Does running cleanup at startup (before sync/decryption) sound like the right timing?
- Should we also clean up
.cryptedfiles inline — i.e., delete them right afterResource.decrypt()finishes and afterSynchronizercompletes an upload — to prevent accumulation in the first place? - Any edge cases I might be missing?
Thanks for any feedback!