Post

Replies

Boosts

Views

Activity

Reply to Ten FSKit issues found building a network file system module (all filed with minimal repros)
Thanks for sharing your findings in this thread. I've been building an FSKit module for a source control filesystem and I hit many of the same things. I have some findings to share related to FB24419825 (the negative lookup that stays pinned for the lifetime of the directory vnode) in case they might be helpful, and also for visbility because if we end up depending on these workarounds, they would need to stay usable until FB24419825 is fixed. A workaround that I found is to revoke the parent directory instead of the file. setCacheState(for:cacheMode:coherencyType:action: .revoke) on the directory that contains the pinned name drops the directory's child dentries, including the pinned negative. Revoking the file itself doesn't work, the call fails with kIOReturnBadArgument (-536870206). As far as I can tell, revoke only succeeds on items the kernel has already looked up, and a file behind a pinned negative can never be looked up, since the pin answers every lookup for that name. The pin belongs to the parent directory, which the kernel has looked up, so revoking the parent works. That workaround doesn't work at the volume root, revoking the root always fails with kIOReturnBadArgument, meaning a file created at the root after something looked for it stays unopenable by name for the life of the mount, even though it shows up in listings. However, I came across a second workaround here. Opening the pinned name with O_CREAT|O_EXCL will clear the pin. This holds on 27.2, including at the root (unlike the first workaround). Without O_CREAT, the open fails with ENOENT from the kernel's cache. With O_CREAT, the kernel tries to create the file instead, so it skips lookupItem and sends createItem to the module. The module returns EEXIST because the name now exists in its tree, and after that the name opens normally. This second workaround has two problems, though. The module has to know exactly which names appeared, and if a name is gone again by the time the open runs, O_CREAT|O_EXCL creates an empty file in its place.
Topic: App & System Services SubTopic: Core OS Tags:
2h
Reply to Ten FSKit issues found building a network file system module (all filed with minimal repros)
Thanks for sharing your findings in this thread. I've been building an FSKit module for a source control filesystem and I hit many of the same things. I have some findings to share related to FB24419825 (the negative lookup that stays pinned for the lifetime of the directory vnode) in case they might be helpful, and also for visbility because if we end up depending on these workarounds, they would need to stay usable until FB24419825 is fixed. A workaround that I found is to revoke the parent directory instead of the file. setCacheState(for:cacheMode:coherencyType:action: .revoke) on the directory that contains the pinned name drops the directory's child dentries, including the pinned negative. Revoking the file itself doesn't work, the call fails with kIOReturnBadArgument (-536870206). As far as I can tell, revoke only succeeds on items the kernel has already looked up, and a file behind a pinned negative can never be looked up, since the pin answers every lookup for that name. The pin belongs to the parent directory, which the kernel has looked up, so revoking the parent works. That workaround doesn't work at the volume root, revoking the root always fails with kIOReturnBadArgument, meaning a file created at the root after something looked for it stays unopenable by name for the life of the mount, even though it shows up in listings. However, I came across a second workaround here. Opening the pinned name with O_CREAT|O_EXCL will clear the pin. This holds on 27.2, including at the root (unlike the first workaround). Without O_CREAT, the open fails with ENOENT from the kernel's cache. With O_CREAT, the kernel tries to create the file instead, so it skips lookupItem and sends createItem to the module. The module returns EEXIST because the name now exists in its tree, and after that the name opens normally. This second workaround has two problems, though. The module has to know exactly which names appeared, and if a name is gone again by the time the open runs, O_CREAT|O_EXCL creates an empty file in its place.
Topic: App & System Services SubTopic: Core OS Tags:
Replies
Boosts
Views
Activity
2h