-
Notifications
You must be signed in to change notification settings - Fork 94
Refactor storage #367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Refactor storage #367
Conversation
| } | ||
| defer lock.Unlock() | ||
|
|
||
| fi, err := os.Stat(historyPath) |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
This path depends on a
user-provided value
| return "", 0, storage.ErrorNotFound | ||
| } | ||
|
|
||
| fd, err := os.Open(historyPath) |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
This path depends on a
user-provided value
| defer lock.Unlock() | ||
|
|
||
| currentGen := int64(0) | ||
| fi, err := os.Stat(historyPath) |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
This path depends on a
user-provided value
This path depends on a
user-provided value
| return currentGen, storage.ErrorWrongGeneration | ||
| } | ||
|
|
||
| hist, err := os.OpenFile(historyPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600) |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
This path depends on a
user-provided value
This path depends on a
user-provided value
48f9109 to
7fda066
Compare
We know that reMarkable uses Google Storage as the backend for its sync service. Many features we observe are inherited directly from the capabilities provided by Google Storage.
In particular, routes like
/sync/v3/files/abcdef123456are effectively aliases for Google Storage routes. The logic behind these routes should remain independent from other routes, to allow using an object storage (e.g., S3) instead of a local filesystem.However, the routes
/sync/v3/rootand/sync/v4/rootare not tied to object storage. The "root" object, along with its generation number, is used to help merging concurrent modifications, something not handled by Google Storage itself.Currently, the generation number is returned by the
LoadBlobfunction, even though it's only meaningful for the root. Individual files don't have a generation number.The logic handling the root object and its history should be separated from the file storage logic. The current root index is closer to user state than to a file/blob.
What This PR Changes
I’ve extracted the root-specific logic from
LoadBloband introduced two new functions:GetRootandUpdateRoot. These operate on the user storage layer, not the blob storage layer.Some types from the
storagepackage were moved into themodelspackage to allow them to be shared across different storage implementations.The last commit introduces a new storage backend abstraction for the root index: the
RootStorerinterface, responsible for managing the root index, its generation number, and the cached tree.All abstractions are now cleanly separated to make it easier to implement alternative storage backends. For example: a database backend for user storage, or a S3-compatible blob storage.
All go interface could have a different implementation (users in database, root indexes in filesystem, blobs in S3, ...).
All filesystem-related calls are now isolated in the
fspackage. The top-levelstoragepackage now only contains interfaces and logic common to all storage implementations.Overall, this pull request should not change any user-facing behavior.
Please test it with your usual workflow and report any unexpected issues or regressions.