Allow handling broken directory offsets #135
Merged
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.
FUSE-T is an implementation of FUSE for macOS, which is becoming popular. But squashfuse doesn't work with FUSE-T, erroring when directories are listed. This is due to FUSE-T supplying improper
offset
values to the FUSE readdir ops.Now, squashfuse can be built with
--enable-broken-directory-offsets
to fix this behavior.FUSE readdir ops (both high-level and low-level) return lists of directory entries. Each returned entry has an
off
field, whose value is arbitrary, entirely up to the filesystem. Subsequent calls to readdir can supply one of these offsets to continue reading from the middle of a directory.In squashfuse, we return as
off
an offset into the squashfs internal directory entries. This lets us quickly jump to the right entry using the squashfs directory index, without reading all intermediate entries.However, FUSE-T does NOT supply a previously-returned offset to readdir. Instead, it uses the size of the buffer that squashfuse returned from readdir. This is entirely outside of the FUSE spec! When FUSE-T does this, squashfuse can't find the supplied offset, and errors.
The fix is to simply not attempt to jump to the correct entry. When squashfuse is built with broken-directory-offsets enabled, we just read every entry from the start of the directory, until our buffer size reaches the provided offset. This is inefficient, but probably ok for reasonable directory sizes.
Unfortunately, we need the user to provide a
configure
argument to trigger this fix. FUSE-T attempts to exactly mirror the FUSE headers and API, so there doesn't seem to be a way to detect this behavior. Even at run-time, FUSE-T could provide a wrong offset that happens to be a valid value, so we can't just look for seek failures.