Thanks for the suggestion, I have tried the novncache/nolocalcaches/noubc/noappledouble it seems there is no difference.
Using the loopback example for macFUSE I cannot reproduce the issue. I have also used the loopback example for cgofuse (the go fuse library from the winfsp project) and couldn't reproduce the example.
The underlying filesystem is just a regular folder in the users home directory. I don't keep file descriptors open to the underlying files, my FileNodes/DirectoryNodes keep track of the underlying path, and perform the operation on them. It's a loopbackFS with some encryption added on the underlying folder and some file metadata stored in a local database. I am not using directly the macFUSE demos. I use hanwen/go-fuse library for Linux/MacOS and cgofuse for Windows; the underlying logic is the same for all platforms, it's just some High level calls that interpret flags based on the platform, and some conversion on Windows. Until now the logic is solid on Linux - tested with different programs/ file integrity checkers, I also found no issues on Windows. Only OSX programs seem to me that rely on extended attributes, and rename with swap flag.
From my debugging this is what is happening during a rename swap my Inodes look like this:
ParentDirectoryNode = root;
ParentDirectoryNode.Child = FileNode(myFile.txt); // Target. - open on TextEdit
DirectoryNode = myFile.txt-sb.123.. // Folder created by text edit.
DirectoryNode.Child = FileNode(myFile.txt) // The file with edits from TextEdit
The initiator of the RenameSwap: DirectoryNode: oldName myFile.txt, targetDir: ParentDirectoryNode, newName myFile.txt, flag: RENAME_SWAP)
I lock the DirectoryNode, ParentNode, ParentDirectoryNode.Child
I atomically try to swap the underlying file DirectoryNode.Child with the ParentDirectoryNode.Child underlying file - no renamex_np call, just rename with retries and rollbacks
I also perform some metadata swap in the local database (the metadata swapped, it's just information on how to encrypt/decrypt the files).
The Inodes suffer the following modification:
ParentDirectoryNode.Child swaps attribute size and the metadata used for encryption with DirectoryNode.Child; I preserve the Inode ID, and pointers
Release the locks.
On every save in TextEdit, the swap happens and I can perform multiple saves and I can open from another program, or just cat the ParentDirectoryNode.Child (the original file under edit by TextEdit) and list it's contents without a problem.
The problem happens after I completely exit TextEdit. I can still cat the root/myFile.txt or edit it using nano or other programs; but open (1) on it fails.
I managed to trace the open (1) call; and the weird thing to me is that: getattrlist (2) is called on root/myFile.txt no error code - expected, and after that getattrlist (2) is called 3 times on root/myFile.txt-sb123../myFile.txt which fails with ENOENT, after which the fnfErr: File Not Found is thrown. - this is the unexpected part.
After all this if I perform a regular rename on root/myFile.txt (for example mv root/myFile.txt root/a.txt, and even - but not necessary - mv root/a.txt root/myFile.txt)- at the end of the rename the node get's inserted in my VFT "root" Directory node under a different name, and then the old entry is removed. (the Inode ID is unchanged), open (1) succeeds.
I feel the perspectives here refreshing as I am afraid I might be stuck in brain rot and miss something obvious.