Code Monkey home page Code Monkey logo

jnr-fuse's Introduction

jnr-fuse

Build Status Join the chat at https://gitter.im/SerCeMan/jnr-fuse

jnr-fuse is a FUSE implementation in java using Java Native Runtime (JNR).

Project Goals

The main goal of the project is to provide an easy way to create a high-performance filesystem in userspace.

About technologies

FUSE (Filesystem in Userspace) is an OS mechanism for unix-like OS that lets non-privileged users create their own file systems without editing kernel code.

Java Native Runtime (JNR) is high-performance Java API for binding native libraries and native memory.

Get it

Prior to 0.5.5, jnr-fuse was only available in JCenter. Due to sunsetting of JCenter, starting from 0.5.5 is available in maven central.

Gradle

dependencies {
    compile 'com.github.serceman:jnr-fuse:0.5.7'
}

Maven

<dependencies>
    <dependency>
        <groupId>com.github.serceman</groupId>
        <artifactId>jnr-fuse</artifactId>
        <version>0.5.7</version>
    </dependency>
</dependencies>

How to use

For implementing your own filesystem you just need to extend FuseStubFS class and implement methods you need.

See some examples.

See blog article about the implementation

Projects using jnr-fuse

  • Alluxio: Alluxio is a memory-centric distributed storage system
  • Cryptomator: A user-friendly encryption tool for cloud storage services
  • mux2fs: Muxes subtitles into Matroska files as a FUSE filesystem
  • healthcare-api-dicom-fuse: FUSE plugin for the Google Cloud Healthcare DICOM API

Supported platforms

Supported platforms
Linux x64 x86
MacOS (via osxfuse) x64 x86
Windows (via winfsp) x64 n/a

Installation and troubleshooting

See instructions.

jnr-fuse's People

Contributors

apayerl avatar arvgord avatar azhuk-softheme avatar dependabot-preview[bot] avatar dependabot[bot] avatar elecnix avatar erdengk avatar gitter-badger avatar jenschurchill avatar melix avatar mlhartme avatar overheadhunter avatar pavelsimo avatar serceman avatar tornaia avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jnr-fuse's Issues

Build failure

Hi, trying to build with gradle and getting the failure below (I only provided the bottom two stack frames). I am obviously doing something wrong her, but can not figure out what it is exactly.Thanks in advance.

gradle -v

------------------------------------------------------------
Gradle 2.13
------------------------------------------------------------

Build time:   2016-04-25 04:10:10 UTC
Build number: none
Revision:     3b427b1481e46232107303c90be7b05079b05b1c

Groovy:       2.4.4
Ant:          Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM:          1.8.0_65 (Oracle Corporation 25.65-b01)
OS:           Linux 4.1.19-v7+ arm

11:25:12.323 [ERROR] [org.gradle.BuildExceptionReporter] 
11:25:12.325 [ERROR] [org.gradle.BuildExceptionReporter] FAILURE: Build failed with an exception.
11:25:12.327 [ERROR] [org.gradle.BuildExceptionReporter] 
11:25:12.328 [ERROR] [org.gradle.BuildExceptionReporter] * Where:
11:25:12.329 [ERROR] [org.gradle.BuildExceptionReporter] Build file '/root/jnr-fuse/build.gradle' line: 2
11:25:12.331 [ERROR] [org.gradle.BuildExceptionReporter] 
11:25:12.333 [ERROR] [org.gradle.BuildExceptionReporter] * What went wrong:
11:25:12.334 [ERROR] [org.gradle.BuildExceptionReporter] An exception occurred applying plugin request [id: 'java']
11:25:12.335 [ERROR] [org.gradle.BuildExceptionReporter] > Failed to apply plugin [class 'com.github.jengelman.gradle.plugins.shadow.ShadowJavaPlugin']
11:25:12.337 [ERROR] [org.gradle.BuildExceptionReporter]    > Could not create task of type 'ShadowJar'.
11:25:12.338 [ERROR] [org.gradle.BuildExceptionReporter] 
11:25:12.339 [ERROR] [org.gradle.BuildExceptionReporter] * Try:
11:25:12.340 [ERROR] [org.gradle.BuildExceptionReporter] Run with --stacktrace option to get the stack trace. 
11:25:12.343 [LIFECYCLE] [org.gradle.BuildResultLogger] 
11:25:12.344 [LIFECYCLE] [org.gradle.BuildResultLogger] BUILD FAILED
11:25:12.346 [LIFECYCLE] [org.gradle.BuildResultLogger] 
11:25:12.347 [LIFECYCLE] [org.gradle.BuildResultLogger] Total time: 14.043 secs

Caused by: org.gradle.api.tasks.TaskInstantiationException: Could not create task of type 'ShadowJar'.
    at org.gradle.api.internal.project.taskfactory.TaskFactory$1.call(TaskFactory.java:123)
    at org.gradle.api.internal.project.taskfactory.TaskFactory$1.call(TaskFactory.java:118)
    at org.gradle.api.internal.AbstractTask.injectIntoNewInstance(AbstractTask.java:143)
    at org.gradle.api.internal.project.taskfactory.TaskFactory.create(TaskFactory.java:118)
    at org.gradle.api.internal.project.taskfactory.TaskFactory.createTask(TaskFactory.java:77)
    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory.createTask(AnnotationProcessingTaskFactory.java:101)
    at org.gradle.api.internal.project.taskfactory.DependencyAutoWireTaskFactory.createTask(DependencyAutoWireTaskFactory.java:39)
    at org.gradle.api.internal.tasks.DefaultTaskContainer.create(DefaultTaskContainer.java:62)
    at org.gradle.api.internal.tasks.DefaultTaskContainer.create(DefaultTaskContainer.java:97)
    at org.gradle.api.tasks.TaskContainer$create.call(Unknown Source)
    at com.github.jengelman.gradle.plugins.shadow.ShadowJavaPlugin.configureShadowTask(ShadowJavaPlugin.groovy:40)
    at com.github.jengelman.gradle.plugins.shadow.ShadowJavaPlugin.apply(ShadowJavaPlugin.groovy:35)
    at com.github.jengelman.gradle.plugins.shadow.ShadowJavaPlugin.apply(ShadowJavaPlugin.groovy)
    at org.gradle.api.internal.plugins.ImperativeOnlyPluginApplicator.applyImperative(ImperativeOnlyPluginApplicator.java:35)
    at org.gradle.api.internal.plugins.RuleBasedPluginApplicator.applyImperative(RuleBasedPluginApplicator.java:43)
    at org.gradle.api.internal.plugins.DefaultPluginManager.doApply(DefaultPluginManager.java:137)
    ... 60 more
Caused by: java.lang.NoSuchMethodError: org.gradle.api.java.archives.internal.DefaultManifest.<init>(Lorg/gradle/api/internal/file/FileResolver;)V
    at com.github.jengelman.gradle.plugins.shadow.tasks.DefaultInheritManifest.<init>(DefaultInheritManifest.groovy:15)
    at com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar.<init>(ShadowJar.java:44)
    at com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar_Decorated.<init>(Unknown Source)
    at org.gradle.api.internal.DependencyInjectingInstantiator.newInstance(DependencyInjectingInstantiator.java:48)
    at org.gradle.api.internal.ClassGeneratorBackedInstantiator.newInstance(ClassGeneratorBackedInstantiator.java:36)
    at org.gradle.api.internal.project.taskfactory.TaskFactory$1.call(TaskFactory.java:121)
    ... 75 more

UnsatisfiedLinkError when running MemoryFS on Windows with jnr-fuse 0.5.2

When I run ru.serce.jnrfuse.examples.MemoryFS on Windows (with WinFSP 1.3, in IDEA, in an SBT project with libraryDependencies += "com.github.serceman" % "jnr-fuse" % "0.5.1"), everything works fine.

When I update the dependency to 0.5.2, running MemoryFS results in an "java.lang.UnsatisfiedLinkError: could not load FFI provider jnr.ffi.provider.jffi.Provider".

I have tracked the problem down to the following thing: jffi-1.2.15-native.jar is automatically imported as dependency of jnr-fuse 0.5.1, but with jnr-fuse 0.5.2, no jffi-xxx-native.jar is imported as dependency.

I get jffi-1.2.17.jar in the depencencies, but not the native library. Any ideas?

seg-fault in utimens on linux-64

Firstly, many thanks for this very useful project!

However, when overriding utimens in FuseStubFS to set the last-modified time we see the seg-fault below when trying to access the tv_sec attribute of the modified time in the snippet below.

@Override
    public int utimens(String s, Timespec[] timespecs) {
        Timespec access = timespecs[0], modified = timespecs[1];
        long epochSeconds = modified.tv_sec.get();
}

Is this expected?

[junit] # An error report file with more information is saved as:
[junit] # /home/chrirs/software/Peergos/hs_err_pid13102.log
[junit] Compiled method (nm) 22930 150 n 0 sun.misc.Unsafe::getLong (native)
[junit] total in heap [0x00007fa63915eb50,0x00007fa63915ee98] = 840
[junit] relocation [0x00007fa63915ec78,0x00007fa63915ecc0] = 72
[junit] main code [0x00007fa63915ecc0,0x00007fa63915ee98] = 472
[junit] Compiled method (nm) 22930 150 n 0 sun.misc.Unsafe::getLong (native)
[junit] total in heap [0x00007fa63915eb50,0x00007fa63915ee98] = 840
[junit] relocation [0x00007fa63915ec78,0x00007fa63915ecc0] = 72
[junit] main code [0x00007fa63915ecc0,0x00007fa63915ee98] = 472
[junit] create[0] flags: 0x80c2 /test02/34da12df-7638-4a8a-aa32-772994a18dd5
[junit] fgetattr[0] /test02/34da12df-7638-4a8a-aa32-772994a18dd5
[junit] NODEID: 35
[junit] unique: 389, success, outsize: 160
[junit] unique: 390, opcode: FLUSH (25), nodeid: 35, insize: 64, pid: 13104
[junit] flush[0]
[junit] lock[0] F_SETLK F_UNLCK start: 0 len: 0 pid: 0
[junit] unique: 390, success, outsize: 16
[junit] unique: 391, opcode: RELEASE (18), nodeid: 35, insize: 64, pid: 0
[junit] unique: 391, success, outsize: 16
[junit] unique: 392, opcode: OPEN (14), nodeid: 35, insize: 48, pid: 13104
[junit] open flags: 0x8000 /test02/34da12df-7638-4a8a-aa32-772994a18dd5
[junit] open[0] flags: 0x8000 /test02/34da12df-7638-4a8a-aa32-772994a18dd5
[junit] unique: 392, success, outsize: 32
[junit] unique: 393, opcode: SETATTR (4), nodeid: 35, insize: 128, pid: 13104
[junit] utimens /test02/34da12df-7638-4a8a-aa32-772994a18dd5 0.000000000 1461698071.609000000

Serve a file as hidden file / system file

Is it possible with winfsp (fuse) to set a file as hidden and system?

The reason I am asking is that I would like to add a desktop.ini to the virtual drive, but that file is only being evaluated by windows, if it is a system file. In addition to that, hiding it from the user would be great.

https://superuser.com/questions/882442/self-created-desktop-ini-does-not-work

I searched your and libfuse API docs and although they are great, maybe I lack the experience to search for the right needle in the haystack.

Could we support *writeback_cache* option

The libfuse 3.X works good with jnr-fuse and I hope to know how could I enable writeback_cache option with jnr-fuse?

Any example or explanation is welcome.

Thanks a lot

How can I enable buffer operations?

The Javadoc for FuseFS#write_buf() references ru.serce.jnrfuse.AbstractFuseFS#isBufOperationsImplemented() for enabling, but it appears to not exist. Any help with this would be appreciated. Thank you!

Unable to report file creation time

On Windows, when I set the FileStat.st_ctim value in the getattr method, it has no effect. File manager still reports uninitialized creation time, i.e. โ€ŽJanuary 1st, 1970, โ€โ€Ž0:00:00 GMT. The FileStat.st_mtim value is correctly reported as modification time. Only for files, Windows do not display modification for directories, as they have no content so that they cannot be modified.

Is this jnr-fuse issue, or is it caused by something else?

It would be also nice to implement these attributes in the MemoryFS example so that it's proven that it works.

Fuse specific objects are missing the correct .toString() implementation

I kept having random segfaults on Windows (through WinFSP) because the FileInfo structure was not correctly transformed during a debug call. I think all user provided objects should properly implement the toString() function in a safe way. The way I worked around it is to provide my own getString() set of functions for each Fuse object such as FileInfo, FileStat, Timespec etc. I didn't have this problem on osxfuse. So it might be platform specific.

Unable to find WinFsp dynamically resulting in a crash

When WinFsp is not installed in C: (or any other non default location) on Windows jnr-fuse will crash since unable to find the library.
Should be changed to locate the install path dynamically instead of hardcoded string.
Row 64 in AbstractFuseFS.class in package ru.serce.jnrfuse.

jnr-fuse and mutithreading?

Hi SerCeman,

We see that when we open a new file operation in a mounted directory like copying two files, the amount of bandwidth is divided between the two operations. My understanding is that it is because of the jnr-fuse and that the libfuse library supports multithreading.

So is it possible to implement multithreading using jnr-fuse? Are there any limitations in jnr preventing that?

Thanks for any comments you make about the topic.

Compatibility with jnr-ffi 2.1.9

apparently, there was a change inside NativeClosureManager (jnr-ffi) between version 2.1.9 and 2.1.7. by having web3j v 4.1.0 as a dependency, i accidentally bumped jnr-ffi to 2.1.9 which caused jnr-fuse to break (but only for readdir). Fixed this via a custom resolutionStrategy in my build.gradle. It would be nice to have compatibility with jnr-ffi 2.1.9

The cause is the call

        Field classLoaderField = NativeClosureManager.class.getDeclaredField("classLoader");

which happens in ClosureHelper, NativeClosureManager appears to have changed in its internal structure.

This is an issue because it is easy to accidentally bump jnr-ffi to 2.1.9 f.ex. when depending on other libs that declare it.

Calls open method on Windows during searching for a file and viewing a file property

Hi, @SerCeMan !

Thanks for the useful FUSE library!
I've implemented the FUSE plugin for the Google Cloud Healthcare DICOM API. It works perfect on Linux but on Windows, I got an issue.
In the open method, I implemented a retrieving DICOM file from the server and cache it in the user's local storage on disk. When I open a file, I cache it and get file size from the server. I found that on Windows calls open method during searching for a file and viewing a file property(in jnr-fuse examples, it works similarly). This greatly reduces performance because I got unnecessary caching while searching for files. But in Linux open method calls only when I open a file. Could you help me with this issue?

Connection to WinFsp broken

When I try to run HelloFuse with the current WinFsp release (2019.2) on a fully updated Win 10 (1809), the drive is shown, but unavailable. The error message says "Location is not available".

I guess that some of WinFsp's headers have moved and are incompatible with the defined structs in ru.serce.jnrfuse.struct, but I am far too inexperienced with both libraries to attempt a fix.

WinFsp on its own does work โ€“ MemFS runs without a hitch and jnr-fuse also works to some extent, because I see some log messages, when I turn on the debug-option:

The service java has been started.
java[TID=1984]: FFFFC305C8D786D0: >>Create [UT---C] "\", FILE_OPEN, CreateOptions=21, FileAttributes=10, Security=NULL, AllocationSize=0:0, AccessToken=00000000000004A0[PID=f40], DesiredAccess=100000, GrantedAccess=0, ShareAccess=3
java[TID=1984]: FFFFC305C8D786D0: <<Create IoStatus=0[1] UserContext=0000000000000000:000000000089ED90, GrantedAccess=100000, FileInfo={FileAttributes=10, ReparseTag=0, AllocationSize=0:0, FileSize=0:0, CreationTime=1970-01-01T00:00:00.000Z, LastAccessTime=1970-01-01T00:00:00.000Z, LastWriteTime=1970-01-01T00:00:00.000Z, ChangeTime=1970-01-01T00:00:00.000Z, IndexNumber=0:0}
java[TID=1984]: FFFFC305C99379A0: >>QueryVolumeInformation
java[TID=1984]: FFFFC305C99379A0: <<QueryVolumeInformation IoStatus=0[0] VolumeInfo={TotalSize=0:40000000, FreeSize=0:40000000, VolumeLabel=""}
java[TID=1984]: FFFFC305C8D786D0: >>QueryVolumeInformation
java[TID=1984]: FFFFC305C8D786D0: <<QueryVolumeInformation IoStatus=0[0] VolumeInfo={TotalSize=0:40000000, FreeSize=0:40000000, VolumeLabel=""}
java[TID=1984]: FFFFC305C93BE9A0: >>Close 0000000000000000:000000000089ED90
java[TID=1984]: FFFFC305C93BE9A0: <<Close IoStatus=0[0]
java[TID=1984]: FFFFC305C8B4F990: >>Create [UT---C] "\", FILE_OPEN, CreateOptions=21, FileAttributes=10, Security=NULL, AllocationSize=0:0, AccessToken=0000000000000498[PID=198c], DesiredAccess=100000, GrantedAccess=0, ShareAccess=3
java[TID=1984]: FFFFC305C8B4F990: <<Create IoStatus=c0000034[0]
java[TID=1984]: FFFFC305C8B4F990: >>Create [UT---C] "\", FILE_OPEN, CreateOptions=21, FileAttributes=10, Security=NULL, AllocationSize=0:0, AccessToken=0000000000000488[PID=198c], DesiredAccess=100020, GrantedAccess=0, ShareAccess=3
java[TID=1984]: FFFFC305C8B4F990: <<Create IoStatus=c0000034[0]
java[TID=1984]: FFFFC305C8B4F990: >>Create [UT---C] "\", FILE_OPEN, CreateOptions=21, FileAttributes=10, Security=NULL, AllocationSize=0:0, AccessToken=0000000000000488[PID=198c], DesiredAccess=100020, GrantedAccess=0, ShareAccess=3
java[TID=1984]: FFFFC305C8B4F990: <<Create IoStatus=c0000034[0]
java[TID=02a4]: FFFFC305C6E2AE00: >>Create [UT---C] "\", FILE_OPEN, CreateOptions=21, FileAttributes=10, Security=NULL, AllocationSize=0:0, AccessToken=00000000000004C4[PID=f40], DesiredAccess=100000, GrantedAccess=0, ShareAccess=3
java[TID=02a4]: FFFFC305C6E2AE00: <<Create IoStatus=c0000034[0]
java[TID=02a4]: FFFFC305C6E2AE00: >>Create [UT---C] "\", FILE_OPEN, CreateOptions=21, FileAttributes=10, Security=NULL, AllocationSize=0:0, AccessToken=00000000000004C4[PID=f40], DesiredAccess=100000, GrantedAccess=0, ShareAccess=3
java[TID=02a4]: FFFFC305C6E2AE00: <<Create IoStatus=c0000034[0]
java[TID=02a4]: FFFFC305C8D786D0: >>Create [UT---C] "\", FILE_OPEN, CreateOptions=21, FileAttributes=10, Security=NULL, AllocationSize=0:0, AccessToken=0000000000000488[PID=f40], DesiredAccess=100000, GrantedAccess=0, ShareAccess=3
java[TID=02a4]: FFFFC305C8D786D0: <<Create IoStatus=c0000034[0]
java[TID=1984]: FFFFC305C9196760: >>Create [UT---C] "\", FILE_OPEN, CreateOptions=800021, FileAttributes=10, Security=NULL, AllocationSize=0:0, AccessToken=00000000000004C4[PID=f40], DesiredAccess=100000, GrantedAccess=0, ShareAccess=0
java[TID=1984]: FFFFC305C9196760: <<Create IoStatus=c0000034[0]
java[TID=02a4]: FFFFC305C87D27C0: >>Create [UT---C] "\", FILE_OPEN, CreateOptions=800021, FileAttributes=10, Security=NULL, AllocationSize=0:0, AccessToken=00000000000004C4[PID=f40], DesiredAccess=100000, GrantedAccess=0, ShareAccess=0
java[TID=02a4]: FFFFC305C87D27C0: <<Create IoStatus=c0000034[0]
java[TID=1984]: FFFFC305C9166D80: >>Create [UT---C] "\", FILE_OPEN, CreateOptions=21, FileAttributes=10, Security=NULL, AllocationSize=0:0, AccessToken=00000000000004C4[PID=f40], DesiredAccess=100000, GrantedAccess=0, ShareAccess=3
java[TID=1984]: FFFFC305C9166D80: <<Create IoStatus=c0000034[0]
The service java has been stopped.

NoClassDefFoundError: ru/serce/jnrfuse/FuseCallbacks$GetAttrCallback in multi-classloader setup

I'm attempting to run jnr-fuse in a Linux container as part of a larger piece of code that uses many ClassLoaders (assume one ClassLoader per jar). I have managed to get my custom filesystem to mount, but any operation on the mounted filesystem produces an Input/output error (per console with debug on).

Poking around with the debugger, I find that the main thread is suspended at Foreign.invokeN5O1 and that another thread pops up briefly and throws NoClassDefFoundError: ru/serce/jnrfuse/FuseCallbacks$GetAttrCallback. (That exception is never logged anywhere as far as I can tell so I can only see it in the debugger)

There is only one element in the stack for this thread, which is NativeClosureProxy$$impl$$0.invoke. Unfortunately that does not tell me where to look.

I would guess that something invoked by native code is attempting to look up this named class, and ends up looking in the wrong ClassLoader. (Wild guess.) Any advice where I should go look? Thanks!

Attempting to load liblibfuse.so.2.so

I just noticed that the lib prefix as well as the .so suffix is appended twice when you attempt to load the fuse library on Linux here:

case LINUX:
libFuse = loader.load("libfuse.so.2");
break;

You pass in the full file name to jnr.ffi, which will then try to find a file named liblibfuse.so.2.so(.[0-9]+)?.

I think it is best to just invoke loader.load("fuse"); on Linux.

At the same time I'm wondering how it could have ever been working before (which it did). This doesn't make any sense to me.

Workaround: ln -s libfuse.so.2 liblibfuse.so.2.so not feasible for endusers, but helps me during development until this is fixed ๐Ÿ˜‰

Logging

Hi! I noticed that when I mount a file system it blurts out loads of logs on the command line like the following

FUSE library version: 2.9.7
nullpath_ok: 0
nopath: 0
utime_omit_ok: 0
unique: 1, opcode: INIT (26), nodeid: 0, insize: 56, pid: 0
INIT: 7.26
flags=0x001ffffb
max_readahead=0x00020000
   INIT: 7.19
   flags=0x00000011
   max_readahead=0x00020000
   max_write=0x00020000
   max_background=0
   congestion_threshold=0
   unique: 1, success, outsize: 40
unique: 2, opcode: ACCESS (34), nodeid: 1, insize: 48, pid: 2340
   unique: 2, error: -38 (Function not implemented), outsize: 16
unique: 3, opcode: LOOKUP (1), nodeid: 1, insize: 47, pid: 2340
LOOKUP /.Trash
getattr /.Trash
   unique: 3, error: -2 (No such file or directory), outsize: 16

etc

Is this something that can be stopped programmatically with jnr-fuse or it depends on the low level FUSE implementation?
(I'm using FUSE library 2.9.7, with Linux 4.11, on Arch Linux)

Allow mounting to non-existing mount points

During an attempt to mount, jnr-fuse checks whether the mount point is an existing directory. If it is not, an exception is thrown:

ru.serce.jnrfuse.FuseException: Mount point should be directory
	at ru.serce.jnrfuse.AbstractFuseFS.mount(AbstractFuseFS.java:263)
	... 15 common frames omitted

There is already an exception for winfsp:

if (!Platform.IS_WINDOWS) {
// winfsp requires non-existing directory to be provided
if (!Files.isDirectory(mountPoint)) {
throw new FuseException("Mount point should be directory");
}
}

There are, however, further cases in which it is desirable to mount to a non-existing directory. According to this commit to sshfs FUSE has certain workarounds:

In order to allow non-privileged users to mount FUSE volumes under /Volumes FUSE will create
non-existent mount points automatically.

Therefore I kindly request to either disable this check completely (let the software depending on jnr-fuse take care of it) or add an overloaded method, e.g. public void mount(Path mountPoint, boolean blocking, boolean debug, boolean requireMountPointToExist, String[] fuseOpts).

Thank you โค๏ธ

Unmounting on Windows (WinFsp)

Thanks for this great library. I just couldn't believe how quick one could get started! :-)

I am not sure whether this is a usage question or a bug report, so let's go:

When mounting, AbstractFuseFS uses the correct path to WinFsp to initialize communication with it:

String winFspPath = System.getProperty("jnrfuse.winfsp.path", "C:\\Program Files (x86)\\WinFsp\\bin\\winfsp-x64.dll");

For unmounting, it simply calls MountUtils which does not seem to be aware of WinFsp:

try {
new ProcessBuilder("fusermount", "-u", "-z", mountPath).start();
} catch (IOException e) {
new ProcessBuilder("umount", mountPath).start();
}

So unmounting fails and the device stays forever. Am I doing something wrong or does WinFsp not support unmounting? Thanks!

"mmap failed for CEN and END part of zip file" with direct_io

I implement a filesystem base on jnr-fuse. testing cp into my fs without direct_io option, write method called 18000 times per second and get 4k bytes every time (70M/s). while mounted with direct_io, write method called 3600 times per second and get 128k bytes every time (450M/s). so I add direct_io option in mount. but when i run java and other program using mmap , it fails and says "mmap failed for CEN and END part of zip file", how can I deal with it? or how can I improve non-direct_io performance? Thanks.

JVM crash in utimens

I get a JVM crash when I try to access the second TimeSpec parameter (timespec[1]) inside a utimens() call. It is difficult to debug, because the debugger also crashes in its attempt to call toString() to display the contents of the variable.

It appears to be a problem inside the getNativeLong() call. It doesn't happen with timespec[0].

I wonder whether it's something to do with one of the special parameters UTIME_OMIT and UTIME_NOW being passed? It's unclear to me how these would be handled. See this page:

http://man7.org/linux/man-pages/man2/utimensat.2.html

In any case, I've attached the log file that the JVM produced.
hs_err_pid6634.txt

"New File" under windows not showing

Not sure if this is an issue with jnr-fuse, winFSP or my Fuse implementation, but:

Mounting a drive under windows, the "New->(File type)" option in the context menu of windows explorer does not show up. "New Directory" does though. It also doesn't show with the example implementations listed in the readme, which makes me think the problem is probably not my implementation. Any idea how to make it show up? Are there certain permissions that need to be set or something? The drive seems to be writable in general - in the memory-file-example-implementation, I can e.g. just save a new text file to the drive, I just can't create a new one via the context menu...

Unreliable with custom ClassLoaders

I apologize that this is not a very actionable issue, but intended more as a placeholder for others who may come across the same thing.

I'm running jnr-fuse with the diet4j module framework, which, more or less, uses a different ClassLoader for each jar file. Other than that, it doesn't do anything that's relevant here, and so I suspect others with special ClassLoaders also may run into this:

jnr-fuse sort of works, but not reliably. For example, I just copy-pasted the MemoryFS example code into my project, and mounted that instead of my file system implementation, and here's the result:

  • ls -al on all directories always returns "total 0" (not even . or ..). From the debugger, it appears the code is not even invoked although the FUSE debug console output says that LOOKUP, OPENDIR, READDIR and RELEASEDIR were invoked.
  • ls -al on a file works
  • echo hi > hi works and cat hi works
  • the pre-configured files also can be read and written.

In my own code, the behavior is similar in that some of my overridden methods simply do not get invoked. Others are. What the difference might be methods that do get invoked and those that aren't I have no idea. Also, sometimes code is invoked, and data is returned, but the data never makes it back to the file system client. E.g. cat somefile causes the file content to be sent back from my code, but nothing prints to the console.

P.S. If there is a good way of debugging this, I'd very willing to try, but I very quickly seem to end up in part of the call stack that the debugger gets very confused by.

Update jnr-ffi to avoid illegal reflective access warning

Since jnr-ffi version 2.1.7 this warning is fixed. I verified compatibility by managing jnr-ffi to 2.1.8. Therefore I'd suggest to update the dependency.

Update: int readdir(String path, Pointer buf, FuseFillDir filter, @off_t long offset, FuseFileInfo fi) doesn't get called any longer, when I update jnr-ffi to 2.1.8 (but it does work with 2.1.7). So apparently you can not just bump the version without adjusting the code.

arm support

HI, I would like to make jnr-fuse run on an ARM 32-bit board. I can now compile it and start MemoryFS app. I can see the mount, directories, and files. But the file sizes are zero. Trying to copy a file into it creates a zero-size file. "rm" and "mkdir" work. So it looks like it is almost there, except for the file sizes at this time, although there could be more issues.
Two size tests are failing: testFlock (expected:<24> but was:<28>) & testFuseBufvec (expected:<36> but was:<40>).
I will make the changes and test myself if you provide some directions.

Unable to create multiple filesystems in Winfsp

After creating a filesystem and closing it with AbstractFuseFS#unmount(), any new filesystems created (with either the same path as the old filesystem or a new path) will fail with the error:
Exception in thread "main" ru.serce.jnrfuse.FuseException: Unable to mount FS at ru.serce.jnrfuse.AbstractFuseFS.mount(AbstractFuseFS.java:286) at ru.serce.jnrfuse.Mountable.mount(Mountable.java:20) at com.walkerknapp.FuseTesting.UnmountTest.main(UnmountTest.java:29) Caused by: ru.serce.jnrfuse.FuseException: Unable to mount FS, return code = 1 at ru.serce.jnrfuse.AbstractFuseFS.mount(AbstractFuseFS.java:282) ... 2 more

I am unable to replicate this on any linux platforms, so I can only assume it is an issue with Winfsp and jnr-fuse.
This may be an issue with Winfsp itself, but I don't have the means to test it.

Can anyone replicate this? Are there any issues with what I'm trying to do? Thanks!

FileStat contains garbage from uninitialized memory in getattr

In Cryptomator, we had this weirdest bug when using FUSE on macOS for the longest time. See issues cryptomator/cryptomator#659, cryptomator/cryptomator#705, cryptomator/cryptomator#742.

I tried to put down my findings in the actual repository of our FUSE library but was still completely clueless back then: cryptomator/fuse-nio-adapter#19

We finally found the issue some days ago! In getattr(), sometimes the stat object is already filled with garbage. Here is an example, I put a conditional breakpoint when stat.st_flags.get() != 0.

getattr-stat

In most cases, the stat object is correctly only filled with nil values. Btw, this was our fix. We didn't notice this bug earlier because we were already overriding most of the values but overlooked the macOS specific ones. And st_flags caused these permission issues.

Is this something that should be fixed in jnr-fuse? Are these even garbage values? We had no idea that stat could already filled with "anything" and it caused us a lot of headache... who knows, maybe also others that are using this library?

Edit: We noticed this bug throughout several versions of macOS (I personally used High Sierra and Mojave) and osxfuse (from 3.7.1 to 3.8.2). In FUSE-NIO-Adapter, we're using jnr-fuse in version 0.5.2.1 (but I guess we also noticed this bug beginning with 0.5.1 so it's probably not a "new" bug).

Implementing flush hangs the java process

I'm testing my FS in a junit test. This worked fine till I implemented the flush method. The flush method prevents the test process from terminating (I have to kill the process manually). My flush method is empty, i.e. it just returns 0. Any idea what can cause fuse to hang?

getattr on non-existing file return I/O error

If you try to getattr() and it fails, e.g. file does not exist, according to C stat() it should return ENOENT. If the return of getattr() is not 0 the system receives I/O error.

Actual

$ ls -l /mnt/myfuse/i-dont-exist
ls: cannot access '/mnt/myfuse/i-dont-exist': Input/output error

Expected

$ ls -l /mnt/myfuse/i-dont-exist
ls: cannot access '/mnt/myfuse/i-dont-exist': No such file or directory

Sample Code

@Override
public int getattr(String path, FileStat stat) {
  try {
    ...
  } catch (FileNotFoundException e) {
    return -ErrorCodes.ENOENT();
  }
}

Logs

unique: 5, opcode: LOOKUP (1), nodeid: 1, insize: 53, pid: 23107
LOOKUP /i-dont-exist
getattr /i-dont-exist

   NODEID: 4
   unique: 5, success, outsize: 144

mount sopport

Hi @SerCeMan I would like to put A machine on the /tmp directory mounted on the B machine /tmp under what should I do? Looked at your example, did not find the way I needed

Windows (dokany) support

Dokany (windows implementation of userspace filesystem) is currently support FUSE API. It means that jnr-fuse can use Docany as well as linux FUSE implementation. The problem is only in this line - library name. Docan library named as dokanfuse1. Think system property is good solution.

Windows winfsp support

Hi,

I am trying to use jnr-fuse on Windows platform with winfsp. I know that there is dokany but its not stable to use.

winfsp requires additional env argument to initialize fuse properly. Here is winfsp main method:
fsp_fuse_main_real(env, argc, argv, op, op_size, user_data)

env requires to implement malloc and free. As far as i know com.kenai.jffi.MemoryIO.allocateMemory and freeMemory is used for native memory managment.

Also env required two additonal empty callbacks to configure winfsp properly.

What do you think about this solution? Should i use MemoryIO class?

Thanks

Here is the releated issue to integrate jnr-fuse with winfsp.

The number of FUSE mounts is capped by the number of CPUs

I am implementing a multiple FUSE drives support and I found that I had issues mounting more than 7 drives. Turns out that the issue is in the global ForkJoinPool that jnr-fuse uses to execute asynchronously a mount(). So once the pool is full it doesn't accept more tasks to be submitted and the system blocks until one of the drives is unmounted.

There is a workaround to this. You can increase the global ForkJoinPool parallelism level on startup by using this JVM argument:

'-Djava.util.concurrent.ForkJoinPool.common.parallelism=24'

This way you can have up to 24 drives mounted. Having the ability to configure the parallelism size of the pool would be nice, or we can create a new forkjoinpool for each mount with size of 1. This way we guarantee that we'll always execute a new mount given that the system doesn't crash. I'll submit a PR with this soon.

As a general guidance we have 3 different limitations on the number of drives we could support:
osxfuse: 24 mounts (osxfuse/osxfuse#152)
libfuse: 1000 by default (probably can support a lot more)
WinFsp: Windows should be limitted by the number of dirve letters: 25 because C:\ is guaranteed to be taken?

Right click file cause reading the whole file

comment: I open the issue on the winfsp board, but can not got the clear clue.
Firstly, thanks for the great software, I encounter some issues when use winfsp with jnr-fuse. The mount, copy delete work well, but the response is quite slow. My issue is when I right click the file in the file explore, it will cost a lot of time. I check the winfsp log, seems that winfsp need to read the whole file and then it can popup the context menu: below is the log:

javaw[TID=1cd8]: FFFFBA8811D108F0: >>Create [UT---C] "\07_End_to_End_DevOps.pptx", FILE_OPEN, CreateOptions=200000, FileAttributes=0, Security=NULL, AllocationSize=0:0, AccessToken=0000000000000670[PID=2de4], DesiredAccess=20000, GrantedAccess=0, ShareAccess=7
javaw[TID=1cd8]: FFFFBA8811D108F0: <<Create IoStatus=0[1] UserContext=0000000000000000:0000000000D0ED50, GrantedAccess=20000, FileInfo={FileAttributes=0, ReparseTag=0, AllocationSize=0:227000, FileSize=0:226e9b, CreationTime=1970-01-01T00:00:00.000Z, LastAccessTime=2017-10-09T09:49:07.000Z, LastWriteTime=2017-10-09T09:49:07.000Z, ChangeTime=2017-10-09T09:49:07.000Z, IndexNumber=0:0}
javaw[TID=1cd8]: FFFFBA8811D108F0: >>QuerySecurity 0000000000000000:0000000000D0ED50
javaw[TID=1cd8]: FFFFBA8811D108F0: <<QuerySecurity IoStatus=0[0] Security="O:BAG:AUD:P(A;;0x1f01bf;;;BA)(A;;0x1201af;;;AU)(A;;0x120088;;;WD)"
javaw[TID=1cd8]: FFFFBA880E1651E0: >>Close 0000000000000000:0000000000D0ED50
javaw[TID=2a64]: FFFFBA880E8C4810: >>Create [UT---C] "\07_End_to_End_DevOps.pptx", FILE_OPEN, CreateOptions=200000, FileAttributes=0, Security=NULL, AllocationSize=0:0, AccessToken=00000000000005EC[PID=2de4], DesiredAccess=20000, GrantedAccess=0, ShareAccess=7
javaw[TID=1cd8]: FFFFBA880E1651E0: <<Close IoStatus=0[0]
javaw[TID=2a64]: FFFFBA880E8C4810: <<Create IoStatus=0[1] UserContext=0000000000000000:0000000000D3A210, GrantedAccess=20000, FileInfo={FileAttributes=0, ReparseTag=0, AllocationSize=0:227000, FileSize=0:226e9b, CreationTime=1970-01-01T00:00:00.000Z, LastAccessTime=2017-10-09T09:49:07.000Z, LastWriteTime=2017-10-09T09:49:07.000Z, ChangeTime=2017-10-09T09:49:07.000Z, IndexNumber=0:0}
javaw[TID=2a64]: FFFFBA880E8C4810: >>QuerySecurity 0000000000000000:0000000000D3A210
javaw[TID=2a64]: FFFFBA880E8C4810: <<QuerySecurity IoStatus=0[0] Security="O:BAG:AUD:P(A;;0x1f01bf;;;BA)(A;;0x1201af;;;AU)(A;;0x120088;;;WD)"
javaw[TID=2a64]: FFFFBA8811611B00: >>Close 0000000000000000:0000000000D3A210
javaw[TID=2a64]: FFFFBA8811611B00: <<Close IoStatus=0[0]
javaw[TID=2a64]: FFFFBA8813326AF0: >>Create [UT---C] "\07_End_to_End_DevOps.pptx", FILE_OPEN, CreateOptions=200000, FileAttributes=0, Security=NULL, AllocationSize=0:0, AccessToken=0000000000000660[PID=2de4], DesiredAccess=80, GrantedAccess=0, ShareAccess=7
javaw[TID=2a64]: FFFFBA8813326AF0: <<Create IoStatus=0[1] UserContext=0000000000000000:0000000000D39CA0, GrantedAccess=80, FileInfo={FileAttributes=0, ReparseTag=0, AllocationSize=0:227000, FileSize=0:226e9b, CreationTime=1970-01-01T00:00:00.000Z, LastAccessTime=2017-10-09T09:49:07.000Z, LastWriteTime=2017-10-09T09:49:07.000Z, ChangeTime=2017-10-09T09:49:07.000Z, IndexNumber=0:0}
javaw[TID=2a64]: FFFFBA8811611B00: >>Close 0000000000000000:0000000000D39CA0
javaw[TID=2a64]: FFFFBA8811611B00: <<Close IoStatus=0[0]
javaw[TID=6464]: FFFFBA8807BEA270: >>Create [UT---C] "\07_End_to_End_DevOps.pptx", FILE_OPEN, CreateOptions=200000, FileAttributes=0, Security=NULL, AllocationSize=0:0, AccessToken=0000000000000660[PID=2de4], DesiredAccess=80, GrantedAccess=0, ShareAccess=7
javaw[TID=6464]: FFFFBA8807BEA270: <<Create IoStatus=0[1] UserContext=0000000000000000:0000000000D3A210, GrantedAccess=80, FileInfo={FileAttributes=0, ReparseTag=0, AllocationSize=0:227000, FileSize=0:226e9b, CreationTime=1970-01-01T00:00:00.000Z, LastAccessTime=2017-10-09T09:49:07.000Z, LastWriteTime=2017-10-09T09:49:07.000Z, ChangeTime=2017-10-09T09:49:07.000Z, IndexNumber=0:0}
javaw[TID=6464]: FFFFBA8813326AF0: >>Close 0000000000000000:0000000000D3A210
javaw[TID=6464]: FFFFBA8813326AF0: <<Close IoStatus=0[0]
javaw[TID=6464]: FFFFBA8813326AF0: >>Create [UT---C] "\07_End_to_End_DevOps.pptx", FILE_OPEN, CreateOptions=60, FileAttributes=0, Security=NULL, AllocationSize=0:0, AccessToken=0000000000000684[PID=2de4], DesiredAccess=120089, GrantedAccess=0, ShareAccess=7
javaw[TID=6464]: FFFFBA8813326AF0: <<Create IoStatus=0[1] UserContext=0000000000000000:0000000000D3A120, GrantedAccess=120089, FileInfo={FileAttributes=0, ReparseTag=0, AllocationSize=0:227000, FileSize=0:226e9b, CreationTime=1970-01-01T00:00:00.000Z, LastAccessTime=2017-10-09T09:49:07.000Z, LastWriteTime=2017-10-09T09:49:07.000Z, ChangeTime=2017-10-09T09:49:07.000Z, IndexNumber=0:0}
javaw[TID=6464]: FFFFBA880D354C50: >>Read 0000000000000000:0000000000D3A120, Address=0000000022180000, Offset=0:0, Length=1048576, Key=0
javaw[TID=6464]: FFFFBA880D354C50: <<Read IoStatus=0[1048576]
javaw[TID=2858]: FFFFBA880F14FD70: >>Read 0000000000000000:0000000000D3A120, Address=0000000000DC0000, Offset=0:100000, Length=1048576, Key=0
javaw[TID=2858]: FFFFBA880F14FD70: <<Read IoStatus=0[1048576]
javaw[TID=6464]: FFFFBA880479F530: >>Read 0000000000000000:0000000000D3A120, Address=0000000000DC0000, Offset=0:200000, Length=159744, Key=0
javaw[TID=6464]: FFFFBA880479F530: <<Read IoStatus=0[159387]
javaw[TID=6464]: FFFFBA880A32B600: >>QueryInformation 0000000000000000:0000000000D3A120
javaw[TID=6464]: FFFFBA880A32B600: <<QueryInformation IoStatus=0[0] FileInfo={FileAttributes=0, ReparseTag=0, AllocationSize=0:227000, FileSize=0:226e9b, CreationTime=1970-01-01T00:00:00.000Z, LastAccessTime=2017-10-09T09:49:07.000Z, LastWriteTime=2017-10-09T09:49:07.000Z, ChangeTime=2017-10-09T09:49:07.000Z, IndexNumber=0:0}
javaw[TID=6464]: FFFFBA8813326AF0: >>Read 0000000000000000:0000000000D3A120, Address=000000001F5E0000, Offset=0:0, Length=4096, Key=0
javaw[TID=6464]: FFFFBA8813326AF0: <<Read IoStatus=0[4096]
javaw[TID=6464]: FFFFBA880CC63120: >>QueryInformation 0000000000000000:0000000000D3A120
javaw[TID=6464]: FFFFBA880CC63120: <<QueryInformation IoStatus=0[0] FileInfo={FileAttributes=0, ReparseTag=0, AllocationSize=0:227000, FileSize=0:226e9b, CreationTime=1970-01-01T00:00:00.000Z, LastAccessTime=2017-10-09T09:49:07.000Z, LastWriteTime=2017-10-09T09:49:07.000Z, ChangeTime=2017-10-09T09:49:07.000Z, IndexNumber=0:0}
javaw[TID=6464]: FFFFBA880CC63120: >>Read 0000000000000000:0000000000D3A120, Address=000000001F5E0000, Offset=0:0, Length=4096, Key=0

Any ideas for this issue? thanks in advance.

readdir is not called

I'm trying to get jnr-fuse (0.4.0) running on Ubuntu but have some trouble getting it working. I'm using the HelloFuse fs at the moment but the method readdir never gets called. The methods getattr, opendir, releasedir are working fine though. From the output I can see that fuse starts a READDIR request but it never gets through to the java code. Any idea why readdir is not working?

Get version string of fuse implementation

Some FUSE implementations provide a version string. For example osxfuse allows you to get its version as described here. For client applications it might be useful to get this information to avoid incompatibilities.

Could you add such a method, or do you want to keep jnr-fuse strictly limited on fuse.h, i.e. without any "vendor-specific addons"? If the latter is the case, please feel free to reject this feature request. I can easily access osxfuse-specific functions myself (as suggested here), but I want to avoid loading osxfuse twice, since I don't know the drawback of doing so via JNR.

HelloFuse.java wont run with WinFSP 1.3.18160

Tried 0.5.2 and 0.5.2.1 with and without all classifier

Path is correctly detected to "C:\Program Files (x86)\WinFsp\bin\winfsp-x64.dll"

LibraryLoader.java fails at 325

        try {
            return loadLibrary(interfaceClass, Collections.unmodifiableList(libraryNames), getSearchPaths(),
                Collections.unmodifiableMap(optionMap));
        
        } catch (LinkageError error) {
            if (failImmediately) throw error;
            return createErrorProxy(error);

with exception

Exception in thread "main" java.lang.UnsatisfiedLinkError: unknown
	at jnr.ffi.provider.jffi.NativeLibrary.loadNativeLibraries(NativeLibrary.java:87)
	at jnr.ffi.provider.jffi.NativeLibrary.getNativeLibraries(NativeLibrary.java:70)
	at jnr.ffi.provider.jffi.NativeLibrary.getSymbolAddress(NativeLibrary.java:49)
	at jnr.ffi.provider.jffi.NativeLibrary.findSymbolAddress(NativeLibrary.java:59)
	at jnr.ffi.provider.jffi.AsmLibraryLoader.generateInterfaceImpl(AsmLibraryLoader.java:158)
	at jnr.ffi.provider.jffi.AsmLibraryLoader.loadLibrary(AsmLibraryLoader.java:89)
	at jnr.ffi.provider.jffi.NativeLibraryLoader.loadLibrary(NativeLibraryLoader.java:44)
	at jnr.ffi.LibraryLoader.load(LibraryLoader.java:325)
	at jnr.ffi.LibraryLoader.load(LibraryLoader.java:304)
	at ru.serce.jnrfuse.AbstractFuseFS.<init>(AbstractFuseFS.java:66)
	at ru.serce.jnrfuse.FuseStubFS.<init>(FuseStubFS.java:23)
	at com.sitemule.db2fs.fuse.HelloFuse.<init>(HelloFuse.java:21)
	at com.sitemule.db2fs.fuse.HelloFuse.main(HelloFuse.java:83)

Note, examples in winfsp itself, run fine.

Extra error codes support for extended attributes

Looking at the man page on Mac OS X for getxattr() it lists the following errors as available, but those are not present in the ErrorCodes class:

 [ENOATTR]          The extended attribute does not exist.

 [ENOTSUP]          The file system does not support extended attributes or has the feature disabled.

 [EACCES]           Search permission is denied for a component of path or the attribute is not allowed to be read (e.g. an ACL prohibits reading the attributes of this file).

If the first one is not present, I can't tell the file system that the attribute name doesn't exist and it needs to be created.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.