> I don't understand the comment about leaking memory, nfs file handles don't have to be persistent.
As long as the file the NFSv4 file handle refers to is still usable (i.e., linked into the file system), the NFSv4 file handle must remain usable. Note that this is not a universal requirement, but at least one that the macOS NFSv4 client enforces. It only implements FH4_PERSISTENT. This doesn't seem to be documented explicitly, but is somewhat revealed by this printf():
> Besides, how many FUSE filesystems implement FORGET?
Any file system that wants to remove files in the background (meaning: not by calling unlink() through the FUSE mount) must likely do proper refcounting on such files, and provide an implementation of FORGET.
For example, a file system that can give information on live football matches may want to remove files/directories belonging to matches that have already ended. In that case you want the node IDs to remain valid, but refer to files that have already been unlinked from the file system hierarchy. The FORGET operation allows you to determine when those files can be removed from the FUSE server's bookkeeping entirely.
Here is an implementation of FORGET that I wrote for Buildbarn:
I'm not sure I understand you point, if an inode gets removed, then GETATTR or LOOKUP would fail as it should unless you're talking about open files. In the latter case the inode will get removed when the last open handle to the file is closed
Sure, LOOKUP would obviously fail, as the object is no longer present in the file system under any name. GETATTR is a different story. Consider this sequence of operations:
Notice how we removed a directory, and were still able to obtain its attributes afterwards using GETATTR. In fact, I can even go ahead and modify some of its attributes using SETATTR:
So that's what FORGET is for. It allows the kernel to hold on to inodes, even if they have been unlinked from the underlying file system, regardless of whether they are opened or not.
I think it's important to realise that a FUSE nodeid _does not_ represent an identifier of an inode in the file system. Instead, they are identifiers of the inode in the kernel's inode cache. Every time the object is returned by LOOKUP, MKDIR, MKNOD, LINK, SYMLINK or CREATE, should their reference count be increased. FORGET is called to decrease it again.
As long as the file the NFSv4 file handle refers to is still usable (i.e., linked into the file system), the NFSv4 file handle must remain usable. Note that this is not a universal requirement, but at least one that the macOS NFSv4 client enforces. It only implements FH4_PERSISTENT. This doesn't seem to be documented explicitly, but is somewhat revealed by this printf():
https://github.com/apple/darwin-xnu/blob/main/bsd/nfs/nfs_vf...
> Besides, how many FUSE filesystems implement FORGET?
Any file system that wants to remove files in the background (meaning: not by calling unlink() through the FUSE mount) must likely do proper refcounting on such files, and provide an implementation of FORGET.
For example, a file system that can give information on live football matches may want to remove files/directories belonging to matches that have already ended. In that case you want the node IDs to remain valid, but refer to files that have already been unlinked from the file system hierarchy. The FORGET operation allows you to determine when those files can be removed from the FUSE server's bookkeeping entirely.
Here is an implementation of FORGET that I wrote for Buildbarn:
https://github.com/buildbarn/bb-remote-execution/blob/master...