cryptomator / cryptofs

Java Filesystem Provider with integrated encryption
GNU Affero General Public License v3.0
94 stars 35 forks source link

Flush ciphertext channel before writing lastModified timestamp #206

Closed infeo closed 9 months ago

infeo commented 9 months ago

Fixes #205.

Unfortunately, the changes became bigger than anticipated. Reason is, that due to our ..."spaghetti" architecture, with the minimal fix could not exclude the possibility that the lastModified timestamp is not overwritten. The chunkCache uses an arbitrary ciphertext filechannel to write to a file via the ChunkIO class. It was theoretically possible to first get a writable channel but deregister this channel in a different thread. With my implementation one can either deregister channels to the same file or write into such channels, but cannot do both. Deregistering is prioritized to timely finish close actions.

With this PR we have now the guarantee, that between a ciphertext channels force(...) and close() method, no other thread can write to it, hence persisting the lastModified timestamp can only fail on the storage side. Additionally, i moved all IO-related things during close to the CleartextFileChannel (some were lingering around in OpenCryptoFile) and improved the unit tests.

Summary by CodeRabbit

coderabbitai[bot] commented 9 months ago

Walkthrough

The recent updates to the Cryptomator project focus on enhancing data integrity, synchronization, and file timestamp accuracy during file operations. A significant change is the adjustment in handling file channel closures, shifting from CleartextFileChannel to a broader FileChannel interface. The modifications also include better synchronization mechanisms through the introduction of a PriorityMutex and adjustments in channel management logic to maintain consistency and correctness, particularly in the context of last modified timestamps.

Changes

Files Change Summary
.../ch/ChannelCloseListener.java
.../fh/OpenCryptoFileTest.java
Updated parameter type in closed method; Adjusted test for new parameter type.
.../ch/CleartextFileChannel.java Added annotations for testing; Enhanced channel closing logic; Added comments.
.../fh/ChunkIO.java
.../fh/PriorityMutex.java
Introduced PriorityMutex for better synchronization; Refactored for simplicity and thread safety.
.../fh/OpenCryptoFile.java Shifted from ConcurrentHashMap to AtomicInteger for open channel tracking; Updated channel management logic.
.../ch/CleartextFileChannelTest.java Enhancements in testing, including handling IOException scenarios and refining method calls.

Assessment against linked issues

Objective Addressed Explanation
Address the issue where closing the cleartext file channel might change the lastModified timestamp due to the order of operations. (#205)
Ensure that the lastModified timestamp correction is not nullified by unwritten changes in the channel. (#205)
Implement explicit flushing of the ciphertext channel before setting the last modified time to prevent unintended changes. (#205)
Review the flush() method in CleartextFileChannel to consider all necessary write operations, not just for the chunk cache. (#205)
Evaluate the necessity of explicitly flushing the ciphertext channel to maintain data integrity and timestamp accuracy. (#205)

Poem

In the realm of encrypted files, Where data securely smiles, A rabbit hopped through code and style, Ensuring timestamps reconcile. 🐇💾

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share - [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai) - [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai) - [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai) - [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

Tips ### Chat There are 3 ways to chat with CodeRabbit: - Review comments: Directly reply to a review comment made by CodeRabbit. Example: - `I pushed a fix in commit .` - `Generate unit-tests for this file.` - Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples: - `@coderabbitai generate unit tests for this file.` - `@coderabbitai modularize this function.` - PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples: - `@coderabbitai generate interesting stats about this repository from git and render them as a table.` - `@coderabbitai show all the console.log statements in this repository.` - `@coderabbitai read src/utils.ts and generate unit tests.` - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.` Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. ### CodeRabbit Commands (invoked as PR comments) - `@coderabbitai pause` to pause the reviews on a PR. - `@coderabbitai resume` to resume the paused reviews. - `@coderabbitai review` to trigger a review. This is useful when automatic reviews are disabled for the repository. - `@coderabbitai resolve` resolve all the CodeRabbit review comments. - `@coderabbitai help` to get help. Additionally, you can add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed. ### CodeRabbit Configration File (`.coderabbit.yaml`) - You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository. - The JSON schema for the configuration file is available [here](https://coderabbit.ai/integrations/coderabbit-overrides.v2.json). - If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json` ### CodeRabbit Discord Community Join our [Discord Community](https://discord.com/invite/GsXnASn26c) to get help, request features, and share feedback.
infeo commented 9 months ago

I'll open a new PR with fewer changes.