winfsp / winfsp

Windows File System Proxy - FUSE for Windows
https://winfsp.dev
Other
7.07k stars 514 forks source link

Calling fuse_unmount() results in crash #490

Closed stingray-11 closed 1 year ago

stingray-11 commented 1 year ago

Bug Report

I'm using the FUSE3 compatibility header. I am writing a Linux/Windows Qt GUI program that uses FUSE. FUSE runs in a background thread, blocking on fuse_loop(). Formerly, to implement the GUI's unmount function, I was calling fuse_exit(), which then results in fuse_loop() returning and then I call fuse_unmount(). This works, except in Linux it sometimes would hang for a bit before the loop exited. The issue (looking at the libfuse code) was that fuse_exit() merely flags the loop to stop, but does not actually interrupt it. So it will continue to wait until the next request it gets from the OS.

To fix this delay, I added a call to fuse_unmount() after fuse_exit(). So the unmount call is now on the main thread rather than the FUSE loop thread after fuse_loop() returns. On Linux, this seems to work and has the intended effect of waking up the loop, resulting in immediate unmount. In WinFSP however, the call to fuse_unmount() while another thread is in fuse_loop() causes a crash, always. I'm guessing the loop and exit semantics might be implemented a bit differently in WinFSP, as I also don't recall having the delay issue with WinFSP in the first place. It's also possible that this isn't actually valid in Linux and I'm just getting lucky (not sure if fuse_unmount on a separate thread is okay). FWIW this also doesn't work on OSXFUSE (doesn't unmount properly) so I may have to find another solution.

How to Reproduce

My implementation of the code is here, ignore the LIBFUSE2 sections.

Behaviors

Crashes within fuse3_loop(), should not crash.

Environment

image

stingray-11 commented 1 year ago

I'm looking at the comments in https://github.com/winfsp/cgofuse/issues/6 and they align with my findings. So maybe the best solution for Windows is just to call fuse_exit() and then we don't need to worry about the crash in fuse_loop().

billziss-gh commented 1 year ago

There is no easy cross platform way to unmount a FUSE file system.

Here is the technique I use in cgofuse, which works against multiple platforms:

https://github.com/winfsp/cgofuse/blob/v1.5.0/fuse/host_cgo.go#L590

stingray-11 commented 1 year ago

Okay. Based on what I see in winfsp/cgofuse#6 I think this can be closed as no-issue.