cryptomator / fuse-nio-adapter

FUSE-based adapter to provide directory contents specified by a java.nio.file.Path
GNU Affero General Public License v3.0
24 stars 14 forks source link

Check for openFileHandles before regular unmount to cancel it #47

Closed infeo closed 4 years ago

infeo commented 4 years ago

If a file channel is still open when one executes the unmount method ( which in the end calls the linux helper command fusermount), the unmount fails with a CommandFailedException: https://github.com/cryptomator/fuse-nio-adapter/blob/4bb19ad6dd99598c6502944eedf4988445ba48a9/src/main/java/org/cryptomator/frontend/fuse/mount/AbstractMount.java#L46-L53

Nonetheless, with the call fuseAdapter.unmount() the actual filesystem is marked as not-mounted, make it impossible to recover from the failed regular unmount command: https://github.com/cryptomator/fuse-nio-adapter/blob/4bb19ad6dd99598c6502944eedf4988445ba48a9/src/main/java/org/cryptomator/frontend/fuse/ReadOnlyAdapter.java#L266-L273

Additionally, the CommandFailedException for the fusermount only means that the operation did not succeeded, but does not indicate for what reason.

I propose to change the regular unmount to only execute fusermount and marking the filesystem as unmounted, if no internal file channels are open and otherwise throw a different exception. If the filesystem need to be unmoutned, the unmountForced() method can be used.

Ideas how to implement can be taken from https://github.com/cryptomator/dokany-nio-adapter/commit/9a65c64169dc3662d9cd1bf699ad0207d4034f6d

overheadhunter commented 4 years ago

With 663ab4d, the mounted flag is no longer set atomically at the begin of execution but after successful unmount only. Note, there is no longer any protection against invoking unmount multiple times.

That said, there is not yet any "open file handle counter".

infeo commented 4 years ago

An easy way to implement the feature is to use the Read/Write-locks. These are applied before nearly every (important) method. hence only if currently no lock is accquired we give the green light to release.

overheadhunter commented 4 years ago

An easy way to implement the feature is to use the Read/Write-locks. These are applied before nearly every (important) method. hence only if currently no lock is accquired we give the green light to release.

True. If it is possible to create an exclusive (i.e. write) lock for the root path, we can be sure, no other operation holds a lock.

Problem is, that currently there is no "root". Locking starts one level below root, since there has never been the need for file operations on root.