BTW, I don't know when you started using FUSE on Linux, but it's been there on Linux at least since 2001. MacFUSE came out in 2007, so your surprise is surprising.
9P has been around for 20 years, what I find surprising is why anyone would bother with FUSE.
The subterfuge is intentional and necessary in the current design. The open() and close() vnode operations of MacFUSE *do not* have access to the file descriptor in question. The data structures involved are opaque, so it'd be quite ugly and unmaintainable to try to get at the descriptor by brute force. Given the lack of descriptor, you can't match opens and closes. Along the same lines, MacFUSE only can look at the vnode, and *not* at file structures, which are inaccessible. You can't track connections between file structures and FUSE file handles. Therefore, as a matter of feasibility and simplicity, MacFUSE shares file handles when possible, with reference counting. For multiple opens of a single given file, you won't see every open invocation go up to user space unless the open flags are different from a previous invocation.
The more I learn about FUSE, the more broken by design it seems. What is the point of userspace file systems if they can't even handle open() and close() in any meaningful way? Ah, the eternal re-invention of square wheels. How infinitely sad *sigh* uriel
