diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc1c38ee..55b9308f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,7 @@ jobs: ~/.cargo/registry/cache/ ~/.cargo/git/db/ target/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml', '.github/workflows/*.yml') }} + key: ${{ runner.os }}-cargo-compile-${{ matrix.libfuse }}-${{ matrix.features }}-${{ hashFiles('**/Cargo.toml', '.github/workflows/*.yml') }} - name: Install packages run: | @@ -61,7 +61,7 @@ jobs: ~/.cargo/registry/cache/ ~/.cargo/git/db/ target/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml', '.github/workflows/*.yml') }} + key: ${{ runner.os }}-cargo-ci-${{ hashFiles('**/Cargo.toml', '.github/workflows/*.yml') }} - name: Install packages run: | diff --git a/macos-rename-issue.md b/macos-rename-issue.md new file mode 100644 index 00000000..c47fd4f2 --- /dev/null +++ b/macos-rename-issue.md @@ -0,0 +1,95 @@ +# MacOS Rename Issue + +I've create a MemFS with `fuser` and I'm having issue with the rename operation on MacOS (using MacFuse@4.8) where the rename request is provided with empty filenames: + +```shell +touch bar +mv bar zar +``` + +Result in the following Request log: + +```txt +FUSE( 4) ino 0x00..01 RENAME src FilenameDir { dir: Inode(1), name: "" }, dest FilenameDir { dir: Inode(1), name: "" } +``` + +I've added a log that dump the content of `data` before it's decoded into the Rename Request: + +```txt +Parsing opcode FUSE_RENAME, data: AQAAAAAAAAAAAAAAAAAAAGJhcgB6YXIA +``` + +By decoding the data, we get: + +```shell +$ echo AQAAAAAAAAAAAAAAAAAAAGJhcgB6YXIA | base64 --decode | xxd +00000000: 0100 0000 0000 0000 0000 0000 0000 0000 ................ +00000010: 6261 7200 7a61 7200 bar.zar. +``` + +So we have the filenames that are provided, that mean the issue is during the parsing of the low-level request from macFuse. +`fuser` define the Rename request like so: + +```rust +#[derive(Debug)] +pub struct Rename<'a> { + header: &'a fuse_in_header, + arg: &'a fuse_rename_in, + name: &'a Path, + newname: &'a Path, +} +``` + +> [`Rename`](https://github.com/cberner/fuser/blob/424bbcaa30a586a6dc99b5019f5e9b9f7755a31f/src/ll/request.rs#L581-L587) + +```rust +#[repr(C)] +#[derive(Debug, FromBytes, FromZeroes)] +pub struct fuse_rename_in { + pub newdir: u64, +} +``` + +> [`fuse_rename_in`](https://github.com/cberner/fuser/blob/v0.14.0/src/ll/fuse_abi.rs#L584-L588) + +Parsing the provided data by MacFuse result in: + +```rst ++---------------------+------------+---------------+------------------------------------+ +| Rename | ++=====================+============+===============+====================================+ +| fuse_rename_in | | ++---------------------+------------+---------------+------------------------------------+ +| newdir: u64 | name: Path | newname: Path | _unused_ | ++---------------------+------------+---------------+------------------------------------+ +| 0100 0000 0000 0000 | 00 | 00 | 0000 0000 0000 6261 7200 7a61 7200 | ++---------------------+------------+---------------+------------------------------------+ +``` + +`fuse_rename_in` is defined as the following on MacFuse: + +```c +struct fuse_rename_in { + __u64 newdir; +#ifdef __APPLE__ + __u32 flags; + __u32 padding; +#endif +}; +``` + +> [`fuse_rename_in`](https://github.com/osxfuse/fuse/blob/6f7322893456f6ff9db145f096b9bfc2ba95d627/include/fuse_kernel.h#L446-L452) + +If we map the data received, everything seems to _click into place_: + +```rst ++---------------------+------------+--------------+------------+---------------+ +| Rename | ++=====================+============+==============+============+===============+ +| fuse_rename_in | | ++---------------------+------------+--------------+------------+---------------+ +| newdir: u64 | flags: u32 | padding: u32 | name: Path | newname: Path | ++---------------------+------------+--------------+------------+---------------+ +| 0100 0000 0000 0000 | 0000 0000 | 0000 0000 | 6261 7200 | 7a61 7200 | ++---------------------+------------+--------------+------------+---------------+ +```