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

FileStatLxInformation information class is used inconsistently for getting/setting mode/uid/gid #3865

Closed
DHowett opened this issue Feb 19, 2019 · 12 comments

Comments

@DHowett
Copy link
Member

DHowett commented Feb 19, 2019

  • Your Windows build number: 18837, but I reckon this is true in 17763 as well.

  • What you're doing and what's happening:

What I am doing

Implementing a filesystem driver.

Querying a file

WSL will use NtQueryInformationFile (-> IRP_MJ_QUERY_INFORMATION) with FileStatLxInformation to divine LX metadata from a file on drvfs/wslfs (v2). This works well enough.

Creating a file

When creating a new file with metadata=on, it looks like WSL calls NtCreateFile and passes an EaBuffer containing the following extended attributes:

  • $LXUID
  • $LXGID
  • $LXMOD
  • (it probably contains device major/minor for mknod(2) as well)

Updating a file

WSL emits an IRP_MJ_SET_EA setting the same extended attributes.

  • What's wrong / what should be happening instead:

It seems unusual to use NtQueryInformationFile for querying, but fall back to raw extended attributes for setting LX metadata.
I would expect WSL to prefer NtSetInformationFile with FileStatLxInformation and allow the actual extended attributes in use to remain an internal implementation detail.

This complicates the implementation of a filesystem that doesn't use EAs to store uid/gid/mode.

@billziss-gh
Copy link

billziss-gh commented Apr 4, 2019

@DHowett I am looking to implement FileStatLxInformation for my own file system driver and I am wondering if you have any insights on the EffectiveAccess field.

Is the file system supposed to fill this value during IRP_MJ_QUERY_INFORMATION or will NTOS fill it in (as it does for FileAccessInformation and FileAllInformation)?

@Biswa96
Copy link

Biswa96 commented Apr 4, 2019

@billziss-gh It is specified as ACCESS_MASK EffectiveAccess, same as in NtCreateFile.

@billziss-gh
Copy link

@Biswa96 I understand. My question is whether the field is already filled in by NTOS when receiving IRP_MJ_QUERY_INFORMATION. I currently do not have a kernel-debuggable Win10 with WSL installed and cannot check this myself.

@billziss-gh
Copy link

To answer my own question, I have found that a file system driver must fill this information and it is not prefilled by NTOS.

@therealkenc
Copy link
Collaborator

Migrated from #4022, because this one has the virtue of being a pretty valid question that remains open.

what I want is an honest response from the WSL developers, so I can decide whether it is worth to continue investing on their platform.

Some deductive reasoning can probably be applied. There are two possibilities I see:

  1. MSFT writes a Linux VFS clone with all the trimmings, including a dnode cache/inode cache/page cache, FUSE, a real (Windows) page cache based tmpfs, a Windows side IFS to talk to the WSL VFS layer. And then MSFT maintains all that until Sven gets a gold watch.
  2. They don't, because, as it turns out, all that works has been done already, and NIH is expensive.

You decide.

WSL2 will already support FUSE, as announced, so there is nothing to "do" there. The killer FUSE app, sshfd, will run fine. We'll almost certainly get /dev/loop too, because Linux loop driver is "self-contained" (if that's the word) in the Real Linux source. Which means (crazily) that we'll probably also get the other FUSE killer app, ntfs-3g.

That said, FUSE on Windows is still (incredibly) useful. Your query about setting WSL metadata (mode,uid:gid) is still completely valid, and will still be valid come WSL2. You want that. The Cygwin/MSYS2 people almost certainly want that. The ask is: "how do I do chown(2) on the Windows NTFS filesystem and the Windows 9P filesystem". Maybe in my imaginary unicorn alternate universe, Windows CIFS filesystem (with Unix extensions) too.

But that ask actually has little to do "with WSL", or how WSL goes about implementing the Linux syscall surface. You'll be fine, so long as your entirely valid question is answered, regardless of WSL2.

In comparison WSL2 feels like a copout

Yeah, it does, looked at from a certain angle. But if you can't beat em, join em.

[True story: I took a look at what this guy was doing back in 2016 when WSL first came out to see "what would it take" but at the time (at least) the project wasn't far along enough to make any kind of run at it, and anyway, doing WSL2 in 2016 wasn't/isn't exactly a one man time-sink project, and I was kidding myself for looking except for the fun thought experiment.]

@billziss-gh
Copy link

billziss-gh commented May 7, 2019

To clarify my ask here had to do with making WinFsp file systems available as first class citizens under WSL1. I was able to figure this one out. (The important bits are support for extended attributes, ATOMIC_CREATE_ECP_CONTEXT and FileStat*Information).

My ask in #4022 is related to the fact that I have started working on real FUSE support for WSL1. This is not necessarily relevant to WinFsp (although it might become, I have not decided yet). For this purpose I started "researching" WSL1 and built a development kit for it which I was (until this morning) testing. The kit currently lets you write real character device drivers on WSL1 and I was planning to use it to implement /dev/fuse.

Luckily I invested only about 2 weeks in this so far...

@billziss-gh
Copy link

Some deductive reasoning can probably be applied. There are two possibilities I see:

  1. MSFT writes a Linux VFS clone with all the trimmings, including a dnode cache/inode cache/page cache, FUSE, a real (Windows) page cache based tmpfs, a Windows side IFS to talk to the WSL VFS layer. And then MSFT maintains all that until Sven gets a gold watch.
  2. They don't, because, as it turns out, all that works has been done already, and NIH is expensive.

You decide.

Sadly I think you are right. And I say sadly because I found WSL1 genuinely interesting and innovative as a technology.

@therealkenc
Copy link
Collaborator

therealkenc commented May 7, 2019

The kit currently lets you write real character device drivers on WSL1 and I was planning to use it to implement /dev/fuse.

Cool. Notable that no one ever built on this that I know of. Not even a /dev/fb0 or /dev/snd/*, let alone /dev/fuse. /dev/usb/* has been doable for three years and no one has taken a run at that either. Doing a libusb shim à la the "guest additions" model has been doable forever too; not even significant work, or so I heard on the Internet. Also no takers.

My ask in #4022 is related to the fact that I have started working on real FUSE support for WSL1.

It's doable. You're going to have to take over /proc for /proc/mounts and /proc/<pid>/fd too, natch. Appears we've been obsoleted. That's not necessarily a bad thing.

@billziss-gh
Copy link

billziss-gh commented May 8, 2019

It's doable. You're going to have to take over /proc for /proc/mounts and /proc//fd too, natch. Appears we've been obsoleted. That's not necessarily a bad thing.

Cool!

I had been considering a number of approaches for this, but my preferred one might have been the following:

  • A /dev/fuse device that speaks the FUSE kernel protocol. This would be implemented as a driver on top of the LxDK.

  • The device would translate the FUSE low-level protocol to the necessary ioctl's to interact with the WinFsp I/O queues. (Every WinFsp file system gets an "I/O queue" which is effectively a queue of file system IRP's that originated with processes that do normal I/O, such as CreateFile, ReadFile, etc.)

  • WinFsp would handle all file system related issues.

This would effectively expose a Linux FUSE file system to all of Windows. WSL1 would then mount the file system using sudo mount -t drvfs ....

The advantages of this approach were:

  • Minimal work within the WSL1 kernel, which is not documented.
  • Exposing a Linux file system to all of Windows.

The obvious disadvantage of this approach is going through DrvFs to access a Linux FUSE file system.

@therealkenc
Copy link
Collaborator

therealkenc commented May 8, 2019

The device would translate the FUSE low-level protocol to the necessary ioctl's to interact with the WinFsp I/O queues.

You can still do that (or something like it) in WSL2. The devs have basically traded making the Windows host side (generically speaking, call it the Microsoft side) presenting a Linux syscall surface in WSL1, to presenting a Linux KVM surface in WSL2. Or the analogy thereof. Based on the limited information out there right now, it looks like they've done virtio-9p. Or the analogy thereof. You want virtio-fs, which uses the fuse protocol instead of the 9P protocol. Or the analogy thereof.

I call dibs on the first WSL2 bug report. Doing a CreateFileMapping() on the Windows side and a mmap() on the WSL2 side, and expecting memory coherency. Unless they got that working already. In which case... coming soon: HPC on Microsoft Windows Home Edition.

@billziss-gh
Copy link

Interesting. I have not followed Linux kernel developments in the past 10-15 years nor have I watched any of the new WSL2 presos. But yours are good pointers and I will follow up on them.

Copy link
Contributor

This issue has been automatically closed since it has not had any activity for the past year. If you're still experiencing this issue please re-file this as a new issue or feature request.

Thank you!

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

No branches or pull requests

5 participants