Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple O_RDONLY opens result in a single fuse lookup/open pair on OS X #199

Closed
jacobsa opened this issue Mar 16, 2015 · 6 comments
Closed
Assignees

Comments

@jacobsa
Copy link

jacobsa commented Mar 16, 2015

Here is a Go program that does the following:

  • Set up a minimal fuse file system type that can respond to open requests for a file named "foo" within the root directory, and logs the open request it receives. All entries and attributes are set as non-cacheable.
  • Mount an instance of the file system.
  • Open the file named "foo" with O_RDONLY twice.

The program is written in Go using a particular fuse library, but you should be able to write the equivalent in C using the official C library without too much trouble.

On Linux, the output is as expected:

File system: returning inode ID 17 for name: foo
File system: opened inode 17. Handle ID: 16
Main thread opened file with FD: 3
File system: returning inode ID 17 for name: foo
File system: opened inode 17. Handle ID: 17
Main thread opened file with FD: 4

In particular, note that each call to open resulted in a fuse lookup request followed by a fuse open request.

In contrast, this is the output I see on OS X 10.10.2:

File system: returning inode ID 17 for name: foo
File system: opened inode 17. Handle ID: 16
Main thread opened file with FD: 4
Main thread opened file with FD: 5

The first open results in a fuse lookup and fuse open, but the second one causes no requests to the program at all. This is unexpected—since the inode attributes are uncacheable, there should be a lookup. And I am led to believe that I should expect a fuse open request for each user call to open. If I change the second user open to use O_RDWR, then I get a fuse open request but not a fuse lookup request.

I don't know where to start looking to figure out if this is a problem with FUSE for OS X or with OS X itself. Help?

@jacobsa
Copy link
Author

jacobsa commented Mar 16, 2015

Note that mounting with the novncache option causes additional lookups to happen, but no second open request:

File system: returning inode ID 17 for name: foo
File system: returning inode ID 17 for name: foo
File system: opened inode 17. Handle ID: 16
Main thread opened file with FD: 4
File system: returning inode ID 17 for name: foo
File system: returning inode ID 17 for name: foo
Main thread opened file with FD: 5

But the original program sets the entry timeout for the inodes it returns to zero, so I expect the vnode cache to not be in the way.

So I guess there are two questions here:

  • Why does the vnode cache get in the way if I set the entry timeout to zero?
  • Regardless of whether the vnode cache hits, why doesn't a second open request come through? Isn't fuse supposed to send one open request per user open?

@bfleischer
Copy link
Member

  • Why does the vnode cache get in the way if I set the entry timeout to zero?

The entry_valid field is currently ignored by osxfuse. OS X does not support specifying timeouts for individual vnode name cache entries. This is usually only an issue if the file system can change remotely. In this case you need to disable the vnode name caching for the whole file system using option novncache.

  • Regardless of whether the vnode cache hits, why doesn't a second open request come through? Isn't fuse supposed to send one open request per user open?

Let me start by saying that OS X is not Linux. The VFS layer differs significantly in some places. On OS X file handles do not make their way to the VFS layer. This means on OS X VFS plugins like osxfuse have no way of knowing which file handle was used to perform a particular read or write operation.

We deal with this by "multiplexing" FUSE file handles. osxfuse will reuse open FUSE file handles provided that they are compatible. As a result you will only see one open callback when opening the same file twice (with O_RDONLY) without closing the first handle before the second open.

@bfleischer bfleischer self-assigned this Mar 16, 2015
@jacobsa
Copy link
Author

jacobsa commented Mar 16, 2015

Thank you so much for the quick and detailed response—it answers all of my questions. I have only one follow-up: are these things (no support for entry_valid, multiplexing of file handles) documented somewhere that I should look next time before filing a bug?

@jacobsa
Copy link
Author

jacobsa commented Mar 17, 2015

Oh sorry, one more follow-up: does osxfuse honor attr_valid?

jacobsa added a commit to jacobsa/fuse that referenced this issue Mar 17, 2015
…e it.

This fixes cachingfs tests on OS X, where the entry_valid field returned to
fuse is ignored and entries are cached potentially forever.

More info:
    #1
    osxfuse/osxfuse#199
@bfleischer
Copy link
Member

Thank you so much for the quick and detailed response—it answers all of my questions. I have only one follow-up: are these things (no support for entry_valid, multiplexing of file handles) documented somewhere that I should look next time before filing a bug?

Unfortunately there is not much documentation on the differences between FUSE on OS X and Linux. I believe this has not been documented before.

Oh sorry, one more follow-up: does osxfuse honor attr_valid?

Yes, attr_valid is honored on OS X.

@jacobsa
Copy link
Author

jacobsa commented Mar 19, 2015

Great, thanks for the reply. I will link to this thread when I need to cite documentation. :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants