sdk/rust: Fix overlayfs whiteout for base files in promoted dirs#316
Open
broady wants to merge 1 commit intotursodatabase:mainfrom
Open
sdk/rust: Fix overlayfs whiteout for base files in promoted dirs#316broady wants to merge 1 commit intotursodatabase:mainfrom
broady wants to merge 1 commit intotursodatabase:mainfrom
Conversation
f06ffb3 to
c80f682
Compare
Contributor
Author
|
ah, the test is failing because of a separate fuse issue - cached directory entries, I'll try to address that issue separately (bug/PR) |
Contributor
Author
|
FUSE cli integration test blocked on #317 |
c80f682 to
54e4a17
Compare
Contributor
Author
|
ready to review/merge @penberg |
When a base-layer file is unlinked or renamed inside a directory
that has been promoted from Base to Delta (via ensure_parent_dirs),
the old code walked the base HostFS to decide whether to create a
whiteout. For promoted directories the base inode mapping was
already removed by promote_to_delta(), so the walk silently
returned early -- skipping whiteout creation and leaving the base
file visible through the overlay.
This caused dpkg to fail with EEXIST during package installs:
unlink of /var/lib/dpkg/status-old succeeded in delta but never
created a whiteout, so the subsequent link("status", "status-old")
found the base-layer file and returned EEXIST.
Fix by:
1. Extracting resolve_delta_parent() that walks the delta layer
by path to find the parent inode, replacing 9 inline walk
patterns across lookup, mkdir, create_file, mknod, symlink,
unlink, rmdir, link, and rename. The walk validates that each
component is a directory to avoid shadowing by non-directory
entries (same class as tursodatabase#300).
2. Changing unlink/rmdir to remove from delta first, then use
self.lookup() to detect whether the file is still visible
-- if so, it must be from base and needs a whiteout.
3. Moving delta parent resolution in rename() after copy_up()
and ensure_parent_dirs() so the delta directories exist
before we try to resolve them.
Add 8 unit tests and extend the existing shell integration test
with base-file whiteout coverage.
54e4a17 to
8a7c44c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When a base-layer file is unlinked or renamed inside a directory that has been promoted from Base to Delta (via ensure_parent_dirs), the old code walked the base HostFS to decide whether to create a whiteout. For promoted directories the base inode mapping was already removed by promote_to_delta(), so the walk silently returned early -- skipping whiteout creation and leaving the base file visible through the overlay.
This caused dpkg to fail with EEXIST during package installs: unlink of /var/lib/dpkg/status-old succeeded in delta but never created a whiteout, so the subsequent link("status", "status-old") found the base-layer file and returned EEXIST.
Fix by:
Extracting resolve_delta_parent() that walks the delta layer by path to find the parent inode, replacing 9 inline walk patterns across lookup, mkdir, create_file, mknod, symlink, unlink, rmdir, link, and rename. The walk validates that each component is a directory to avoid shadowing by non-directory entries (same class as sdk/rust: Fix overlay lookup using wrong delta parent inode #300).
Changing unlink/rmdir to remove from delta first, then use self.lookup() to detect whether the file is still visible -- if so, it must be from base and needs a whiteout.
Moving delta parent resolution in rename() after copy_up() and ensure_parent_dirs() so the delta directories exist before we try to resolve them.
Add 8 unit tests and extend the existing shell integration test with base-file whiteout coverage.