From 86c1daeda8a5980d39a30cb3e47ce1acec9bf903 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 19 Sep 2022 14:00:12 +0200 Subject: [PATCH 01/20] Set dev branch to SNAPSHOT --- jfuse-api/pom.xml | 2 +- jfuse-examples/pom.xml | 2 +- jfuse-linux-aarch64/pom.xml | 2 +- jfuse-linux-amd64/pom.xml | 2 +- jfuse-mac/pom.xml | 2 +- jfuse-tests/pom.xml | 2 +- jfuse-win-amd64/pom.xml | 2 +- pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/jfuse-api/pom.xml b/jfuse-api/pom.xml index 3e9421cd..9d938abe 100644 --- a/jfuse-api/pom.xml +++ b/jfuse-api/pom.xml @@ -5,7 +5,7 @@ org.cryptomator jfuse - 0.2.0 + 1.0.0-SNAPSHOT 4.0.0 jfuse-api diff --git a/jfuse-examples/pom.xml b/jfuse-examples/pom.xml index 95a756c7..136db794 100644 --- a/jfuse-examples/pom.xml +++ b/jfuse-examples/pom.xml @@ -5,7 +5,7 @@ org.cryptomator jfuse - 0.2.0 + 1.0.0-SNAPSHOT 4.0.0 jfuse-examples diff --git a/jfuse-linux-aarch64/pom.xml b/jfuse-linux-aarch64/pom.xml index 2f64bc68..7a06b16f 100644 --- a/jfuse-linux-aarch64/pom.xml +++ b/jfuse-linux-aarch64/pom.xml @@ -5,7 +5,7 @@ jfuse org.cryptomator - 0.2.0 + 1.0.0-SNAPSHOT 4.0.0 jfuse-linux-aarch64 diff --git a/jfuse-linux-amd64/pom.xml b/jfuse-linux-amd64/pom.xml index f8daae5b..ed578fb1 100644 --- a/jfuse-linux-amd64/pom.xml +++ b/jfuse-linux-amd64/pom.xml @@ -5,7 +5,7 @@ org.cryptomator jfuse - 0.2.0 + 1.0.0-SNAPSHOT 4.0.0 jfuse-linux-amd64 diff --git a/jfuse-mac/pom.xml b/jfuse-mac/pom.xml index 0b24fae9..d54e62c0 100644 --- a/jfuse-mac/pom.xml +++ b/jfuse-mac/pom.xml @@ -5,7 +5,7 @@ org.cryptomator jfuse - 0.2.0 + 1.0.0-SNAPSHOT 4.0.0 jfuse-mac diff --git a/jfuse-tests/pom.xml b/jfuse-tests/pom.xml index f995dbad..ec5e9a4f 100644 --- a/jfuse-tests/pom.xml +++ b/jfuse-tests/pom.xml @@ -5,7 +5,7 @@ org.cryptomator jfuse - 0.2.0 + 1.0.0-SNAPSHOT 4.0.0 jfuse-tests diff --git a/jfuse-win-amd64/pom.xml b/jfuse-win-amd64/pom.xml index f5dd7a61..8822ffc1 100644 --- a/jfuse-win-amd64/pom.xml +++ b/jfuse-win-amd64/pom.xml @@ -5,7 +5,7 @@ org.cryptomator jfuse - 0.2.0 + 1.0.0-SNAPSHOT 4.0.0 jfuse-win-amd64 diff --git a/pom.xml b/pom.xml index 6d2a3207..9f190d5b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.cryptomator jfuse pom - 0.2.0 + 1.0.0-SNAPSHOT jFUSE Java bindings for FUSE using foreign functions & memory API https://github.com/cryptomator/jfuse From aece53702c92ef6aade9ec27b2b05c7c366efa0d Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 19 Sep 2022 14:41:03 +0200 Subject: [PATCH 02/20] adjust version [ci skip] --- jfuse-api/pom.xml | 2 +- jfuse-examples/pom.xml | 2 +- jfuse-linux-aarch64/pom.xml | 2 +- jfuse-linux-amd64/pom.xml | 2 +- jfuse-mac/pom.xml | 2 +- jfuse-tests/pom.xml | 2 +- jfuse-win-amd64/pom.xml | 2 +- pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/jfuse-api/pom.xml b/jfuse-api/pom.xml index 9d938abe..4807c61e 100644 --- a/jfuse-api/pom.xml +++ b/jfuse-api/pom.xml @@ -5,7 +5,7 @@ org.cryptomator jfuse - 1.0.0-SNAPSHOT + 0.3.0-SNAPSHOT 4.0.0 jfuse-api diff --git a/jfuse-examples/pom.xml b/jfuse-examples/pom.xml index 136db794..8da63546 100644 --- a/jfuse-examples/pom.xml +++ b/jfuse-examples/pom.xml @@ -5,7 +5,7 @@ org.cryptomator jfuse - 1.0.0-SNAPSHOT + 0.3.0-SNAPSHOT 4.0.0 jfuse-examples diff --git a/jfuse-linux-aarch64/pom.xml b/jfuse-linux-aarch64/pom.xml index 7a06b16f..6381696b 100644 --- a/jfuse-linux-aarch64/pom.xml +++ b/jfuse-linux-aarch64/pom.xml @@ -5,7 +5,7 @@ jfuse org.cryptomator - 1.0.0-SNAPSHOT + 0.3.0-SNAPSHOT 4.0.0 jfuse-linux-aarch64 diff --git a/jfuse-linux-amd64/pom.xml b/jfuse-linux-amd64/pom.xml index ed578fb1..79bdde1f 100644 --- a/jfuse-linux-amd64/pom.xml +++ b/jfuse-linux-amd64/pom.xml @@ -5,7 +5,7 @@ org.cryptomator jfuse - 1.0.0-SNAPSHOT + 0.3.0-SNAPSHOT 4.0.0 jfuse-linux-amd64 diff --git a/jfuse-mac/pom.xml b/jfuse-mac/pom.xml index d54e62c0..fb006e51 100644 --- a/jfuse-mac/pom.xml +++ b/jfuse-mac/pom.xml @@ -5,7 +5,7 @@ org.cryptomator jfuse - 1.0.0-SNAPSHOT + 0.3.0-SNAPSHOT 4.0.0 jfuse-mac diff --git a/jfuse-tests/pom.xml b/jfuse-tests/pom.xml index ec5e9a4f..78c3ab9c 100644 --- a/jfuse-tests/pom.xml +++ b/jfuse-tests/pom.xml @@ -5,7 +5,7 @@ org.cryptomator jfuse - 1.0.0-SNAPSHOT + 0.3.0-SNAPSHOT 4.0.0 jfuse-tests diff --git a/jfuse-win-amd64/pom.xml b/jfuse-win-amd64/pom.xml index 8822ffc1..3cd9b02a 100644 --- a/jfuse-win-amd64/pom.xml +++ b/jfuse-win-amd64/pom.xml @@ -5,7 +5,7 @@ org.cryptomator jfuse - 1.0.0-SNAPSHOT + 0.3.0-SNAPSHOT 4.0.0 jfuse-win-amd64 diff --git a/pom.xml b/pom.xml index 9f190d5b..4f02c398 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.cryptomator jfuse pom - 1.0.0-SNAPSHOT + 0.3.0-SNAPSHOT jFUSE Java bindings for FUSE using foreign functions & memory API https://github.com/cryptomator/jfuse From 99c0bbc45354fd6da73d5f92b5b534dac02553ca Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 20 Sep 2022 10:10:04 +0200 Subject: [PATCH 03/20] no need for null check see https://github.com/winfsp/winfsp/discussions/445 --- .../cryptomator/jfuse/win/amd64/FuseImpl.java | 21 +++---- .../jfuse/win/amd64/FuseImplTest.java | 60 +++++++------------ 2 files changed, 27 insertions(+), 54 deletions(-) diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseImpl.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseImpl.java index 37ff1703..f84a891b 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseImpl.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseImpl.java @@ -259,20 +259,13 @@ private int unlink(MemoryAddress path) { @VisibleForTesting int utimens(MemoryAddress path, MemoryAddress times, MemoryAddress fi) { try (var scope = MemorySession.openConfined()) { - if (MemoryAddress.NULL.equals(times)) { - // set both times to current time (using on-heap memory segments) - var segment = MemorySegment.allocateNative(fuse_timespec.$LAYOUT().byteSize(), scope); - fuse_timespec.tv_sec$set(segment, 0); - fuse_timespec.tv_nsec$set(segment, 0); //FIXME: use hardcoded UTIME_NOW - var time = new TimeSpecImpl(segment); - return delegate.utimens(path.getUtf8String(0), time, time, new FileInfoImpl(fi, scope)); - } else { - var seq = MemoryLayout.sequenceLayout(2, fuse_timespec.$LAYOUT()); - var segment = MemorySegment.ofAddress(times, seq.byteSize(), scope); - var time0 = segment.asSlice(0, fuse_timespec.$LAYOUT().byteSize()); - var time1 = segment.asSlice(fuse_timespec.$LAYOUT().byteSize(), fuse_timespec.$LAYOUT().byteSize()); - return delegate.utimens(path.getUtf8String(0), new TimeSpecImpl(time0), new TimeSpecImpl(time1), new FileInfoImpl(fi, scope)); - } + // On Windows we know for sure that WinFSP will call this function only with + // valid times: https://github.com/winfsp/winfsp/discussions/445 + var seq = MemoryLayout.sequenceLayout(2, fuse_timespec.$LAYOUT()); + var segment = MemorySegment.ofAddress(times, seq.byteSize(), scope); + var time0 = segment.asSlice(0, fuse_timespec.$LAYOUT().byteSize()); + var time1 = segment.asSlice(fuse_timespec.$LAYOUT().byteSize(), fuse_timespec.$LAYOUT().byteSize()); + return delegate.utimens(path.getUtf8String(0), new TimeSpecImpl(time0), new TimeSpecImpl(time1), new FileInfoImpl(fi, scope)); } } diff --git a/jfuse-win-amd64/src/test/java/org/cryptomator/jfuse/win/amd64/FuseImplTest.java b/jfuse-win-amd64/src/test/java/org/cryptomator/jfuse/win/amd64/FuseImplTest.java index fad54afc..8942bfd3 100644 --- a/jfuse-win-amd64/src/test/java/org/cryptomator/jfuse/win/amd64/FuseImplTest.java +++ b/jfuse-win-amd64/src/test/java/org/cryptomator/jfuse/win/amd64/FuseImplTest.java @@ -188,48 +188,28 @@ public void testInit() { } } - @Nested - @DisplayName("utimens") - public class Utimens { - - @DisplayName("utimens(\"/foo\", UTIME_NOW, UTIME_NOW)") - @Test - public void testUtimensNow() { - try (var scope = MemorySession.openConfined()) { - var path = scope.allocateUtf8String("/foo"); - var times = MemoryAddress.NULL; - var fi = scope.allocate(fuse3_file_info.$LAYOUT()); - Mockito.doReturn(42).when(fuseOps).utimens(Mockito.eq("/foo"), Mockito.argThat(t -> t.get().getNano() == 0L), Mockito.argThat(t -> t.get().getNano() == 0L), Mockito.argThat(usesSameMemorySegement(fi))); - - var result = fuseImpl.utimens(path.address(), times, fi.address()); + @DisplayName("utimens(\"/foo\", ...)") + @ParameterizedTest + @CsvSource(value = { + "123456,789, 456789,123", + "111222,333, 444555,666", + }) + public void testUtimens(long sec0, long nsec0, long sec1, long nsec1) { + Instant expectedATime = Instant.ofEpochSecond(sec0, nsec0); + Instant expectedMTime = Instant.ofEpochSecond(sec1, nsec1); + try (var scope = MemorySession.openConfined()) { + var path = scope.allocateUtf8String("/foo"); + var times = fuse_timespec.allocateArray(2, scope); + var fi = scope.allocate(fuse3_file_info.$LAYOUT()); + fuse_timespec.tv_sec$set(times, 0, sec0); + fuse_timespec.tv_nsec$set(times, 0, nsec0); + fuse_timespec.tv_sec$set(times, 1, sec1); + fuse_timespec.tv_nsec$set(times, 1, nsec1); + Mockito.doReturn(42).when(fuseOps).utimens(Mockito.eq("/foo"), Mockito.argThat(t -> expectedATime.equals(t.get())), Mockito.argThat(t -> expectedMTime.equals(t.get())), Mockito.argThat(usesSameMemorySegement(fi))); - Assertions.assertEquals(42, result); - } - } + var result = fuseImpl.utimens(path.address(), times.address(), fi.address()); - @DisplayName("utimens(\"/foo\", ...)") - @ParameterizedTest - @CsvSource(value = { - "123456,789, 456789,123", - "111222,333, 444555,666", - }) - public void testUtimens(long sec0, long nsec0, long sec1, long nsec1) { - Instant expectedATime = Instant.ofEpochSecond(sec0, nsec0); - Instant expectedMTime = Instant.ofEpochSecond(sec1, nsec1); - try (var scope = MemorySession.openConfined()) { - var path = scope.allocateUtf8String("/foo"); - var times = fuse_timespec.allocateArray(2, scope); - var fi = scope.allocate(fuse3_file_info.$LAYOUT()); - fuse_timespec.tv_sec$set(times, 0, sec0); - fuse_timespec.tv_nsec$set(times, 0, nsec0); - fuse_timespec.tv_sec$set(times, 1, sec1); - fuse_timespec.tv_nsec$set(times, 1, nsec1); - Mockito.doReturn(42).when(fuseOps).utimens(Mockito.eq("/foo"), Mockito.argThat(t -> expectedATime.equals(t.get())), Mockito.argThat(t -> expectedMTime.equals(t.get())), Mockito.argThat(usesSameMemorySegement(fi))); - - var result = fuseImpl.utimens(path.address(), times.address(), fi.address()); - - Assertions.assertEquals(42, result); - } + Assertions.assertEquals(42, result); } } From b706044f57d55a9a1d16c808f2f14f3709dd0fc4 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 20 Sep 2022 20:30:16 +0200 Subject: [PATCH 04/20] build with JDK 19 GA --- .github/workflows/build.yml | 2 +- .github/workflows/publish-central.yml | 2 +- .github/workflows/publish-github.yml | 2 +- .idea/misc.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c68b003d..1544709f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,7 +12,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-java@v2 with: - java-version: 19-ea + java-version: 19 distribution: 'zulu' cache: 'maven' - name: Setup fuse diff --git a/.github/workflows/publish-central.yml b/.github/workflows/publish-central.yml index aa481b95..23fc7808 100644 --- a/.github/workflows/publish-central.yml +++ b/.github/workflows/publish-central.yml @@ -15,7 +15,7 @@ jobs: ref: "refs/tags/${{ github.event.inputs.tag }}" - uses: actions/setup-java@v2 with: - java-version: 19-ea + java-version: 19 distribution: 'zulu' cache: 'maven' server-id: ossrh # Value of the distributionManagement/repository/id field of the pom.xml diff --git a/.github/workflows/publish-github.yml b/.github/workflows/publish-github.yml index 63f46f8b..55fc586c 100644 --- a/.github/workflows/publish-github.yml +++ b/.github/workflows/publish-github.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-java@v2 with: - java-version: 19-ea + java-version: 19 distribution: 'zulu' cache: 'maven' gpg-private-key: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }} # Value of the GPG private key to import diff --git a/.idea/misc.xml b/.idea/misc.xml index 08abb3bb..301d9c4f 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -8,7 +8,7 @@ - + \ No newline at end of file From 8508d05723bd0d257c60f67583dfc7acb78dabc8 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Wed, 21 Sep 2022 16:51:46 +0200 Subject: [PATCH 05/20] disable chmod on Windows --- .../jfuse/examples/AbstractMirrorFileSystem.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/AbstractMirrorFileSystem.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/AbstractMirrorFileSystem.java index 1d021020..1eb78c62 100644 --- a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/AbstractMirrorFileSystem.java +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/AbstractMirrorFileSystem.java @@ -71,7 +71,6 @@ protected Path resolvePath(String absolutePath) { public Set supportedOperations() { return EnumSet.of( FuseOperations.Operation.ACCESS, - FuseOperations.Operation.CHMOD, FuseOperations.Operation.CREATE, FuseOperations.Operation.DESTROY, FuseOperations.Operation.GET_ATTR, @@ -216,18 +215,6 @@ private long countSubDirs(Path dir) throws IOException { } } - @Override - public int chmod(String path, int mode, FileInfo fi) { - LOG.trace("chmod {}", path); - Path node = resolvePath(path); - try { - Files.setPosixFilePermissions(node, FileModes.toPermissions(mode)); - return 0; - } catch (IOException e) { - return -errno.eio(); - } - } - @Override public int utimens(String path, TimeSpec atime, TimeSpec mtime, FileInfo fi) { LOG.trace("utimens {}", path); From 9f7ad41d4e950fd5709d7b5aca0f6c0b72991e15 Mon Sep 17 00:00:00 2001 From: Julian Raufelder Date: Thu, 29 Sep 2022 11:02:51 +0200 Subject: [PATCH 06/20] Fix linux-amd64 architecture in Maven POM profile --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4f02c398..6029b14f 100644 --- a/pom.xml +++ b/pom.xml @@ -210,7 +210,7 @@ unix linux - x86_64 + amd64 From cc9ce84b74d7d18e37cf688a40e1f18f0a0af6f6 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Fri, 30 Sep 2022 16:24:34 +0200 Subject: [PATCH 07/20] use libfuse 3.2 api on windows/winfsp --- jfuse-win-amd64/pom.xml | 3 +- .../jfuse/win/amd64/FuseMountImpl.java | 9 ++- .../jfuse/win/amd64/extr/constants$1.java | 10 ++-- .../win/amd64/extr/fuse3_loop_config.java | 59 +++++++++++++++++++ .../jfuse/win/amd64/extr/fuse_h.java | 10 ++-- 5 files changed, 79 insertions(+), 12 deletions(-) create mode 100644 jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_loop_config.java diff --git a/jfuse-win-amd64/pom.xml b/jfuse-win-amd64/pom.xml index 3cd9b02a..edd37bb9 100644 --- a/jfuse-win-amd64/pom.xml +++ b/jfuse-win-amd64/pom.xml @@ -100,7 +100,7 @@ fuse3_mount fuse3_get_session fuse3_loop - fuse3_loop_mt_31 + fuse3_loop_mt fuse3_exit fuse3_unmount fuse3_destroy @@ -115,6 +115,7 @@ fuse_statvfs fuse_timespec fuse3_conn_info + fuse3_loop_config diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseMountImpl.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseMountImpl.java index 755adefd..64eae74b 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseMountImpl.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseMountImpl.java @@ -1,16 +1,23 @@ package org.cryptomator.jfuse.win.amd64; import org.cryptomator.jfuse.api.FuseMount; +import org.cryptomator.jfuse.win.amd64.extr.fuse3_loop_config; import org.cryptomator.jfuse.win.amd64.extr.fuse_h; import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySession; record FuseMountImpl(MemoryAddress fuse, FuseArgs fuseArgs) implements FuseMount { @Override public int loop() { if (fuseArgs.multiThreaded()) { - return fuse_h.fuse3_loop_mt_31(fuse, 0); + try (var scope = MemorySession.openConfined()) { + var loopCfg = fuse3_loop_config.allocate(scope); + fuse3_loop_config.clone_fd$set(loopCfg, 0); + fuse3_loop_config.max_idle_threads$set(loopCfg, 10); + return fuse_h.fuse3_loop_mt(fuse, loopCfg); + } } else { return fuse_h.fuse3_loop(fuse); } diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$1.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$1.java index 318db787..acaa7a05 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$1.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$1.java @@ -23,13 +23,13 @@ class constants$1 { "fuse3_loop", constants$1.fuse3_loop$FUNC ); - static final FunctionDescriptor fuse3_loop_mt_31$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + static final FunctionDescriptor fuse3_loop_mt$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, Constants$root.C_POINTER$LAYOUT, - Constants$root.C_LONG$LAYOUT + Constants$root.C_POINTER$LAYOUT ); - static final MethodHandle fuse3_loop_mt_31$MH = RuntimeHelper.downcallHandle( - "fuse3_loop_mt_31", - constants$1.fuse3_loop_mt_31$FUNC + static final MethodHandle fuse3_loop_mt$MH = RuntimeHelper.downcallHandle( + "fuse3_loop_mt", + constants$1.fuse3_loop_mt$FUNC ); static final FunctionDescriptor fuse3_exit$FUNC = FunctionDescriptor.ofVoid( Constants$root.C_POINTER$LAYOUT diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_loop_config.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_loop_config.java new file mode 100644 index 00000000..9193a8af --- /dev/null +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_loop_config.java @@ -0,0 +1,59 @@ +// Generated by jextract + +package org.cryptomator.jfuse.win.amd64.extr; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.VarHandle; +import java.nio.ByteOrder; +import java.lang.foreign.*; +import static java.lang.foreign.ValueLayout.*; +public class fuse3_loop_config { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("clone_fd"), + Constants$root.C_LONG$LAYOUT.withName("max_idle_threads") + ).withName("fuse3_loop_config"); + public static MemoryLayout $LAYOUT() { + return fuse3_loop_config.$struct$LAYOUT; + } + static final VarHandle clone_fd$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("clone_fd")); + public static VarHandle clone_fd$VH() { + return fuse3_loop_config.clone_fd$VH; + } + public static int clone_fd$get(MemorySegment seg) { + return (int)fuse3_loop_config.clone_fd$VH.get(seg); + } + public static void clone_fd$set( MemorySegment seg, int x) { + fuse3_loop_config.clone_fd$VH.set(seg, x); + } + public static int clone_fd$get(MemorySegment seg, long index) { + return (int)fuse3_loop_config.clone_fd$VH.get(seg.asSlice(index*sizeof())); + } + public static void clone_fd$set(MemorySegment seg, long index, int x) { + fuse3_loop_config.clone_fd$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle max_idle_threads$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max_idle_threads")); + public static VarHandle max_idle_threads$VH() { + return fuse3_loop_config.max_idle_threads$VH; + } + public static int max_idle_threads$get(MemorySegment seg) { + return (int)fuse3_loop_config.max_idle_threads$VH.get(seg); + } + public static void max_idle_threads$set( MemorySegment seg, int x) { + fuse3_loop_config.max_idle_threads$VH.set(seg, x); + } + public static int max_idle_threads$get(MemorySegment seg, long index) { + return (int)fuse3_loop_config.max_idle_threads$VH.get(seg.asSlice(index*sizeof())); + } + public static void max_idle_threads$set(MemorySegment seg, long index, int x) { + fuse3_loop_config.max_idle_threads$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_h.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_h.java index a55dfb51..1071b669 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_h.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_h.java @@ -84,13 +84,13 @@ public static int fuse3_loop ( Addressable f) { throw new AssertionError("should not reach here", ex$); } } - public static MethodHandle fuse3_loop_mt_31$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse3_loop_mt_31$MH,"fuse3_loop_mt_31"); + public static MethodHandle fuse3_loop_mt$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse3_loop_mt$MH,"fuse3_loop_mt"); } - public static int fuse3_loop_mt_31 ( Addressable f, int clone_fd) { - var mh$ = fuse3_loop_mt_31$MH(); + public static int fuse3_loop_mt ( Addressable f, Addressable config) { + var mh$ = fuse3_loop_mt$MH(); try { - return (int)mh$.invokeExact(f, clone_fd); + return (int)mh$.invokeExact(f, config); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } From 681eefa5cc69c2750531874e43b19d96712a3746 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Tue, 4 Oct 2022 12:17:34 +0200 Subject: [PATCH 08/20] Revert "use libfuse 3.2 api on windows/winfsp" This reverts commit cc9ce84b74d7d18e37cf688a40e1f18f0a0af6f6. --- jfuse-win-amd64/pom.xml | 3 +- .../jfuse/win/amd64/FuseMountImpl.java | 9 +-- .../jfuse/win/amd64/extr/constants$1.java | 10 ++-- .../win/amd64/extr/fuse3_loop_config.java | 59 ------------------- .../jfuse/win/amd64/extr/fuse_h.java | 10 ++-- 5 files changed, 12 insertions(+), 79 deletions(-) delete mode 100644 jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_loop_config.java diff --git a/jfuse-win-amd64/pom.xml b/jfuse-win-amd64/pom.xml index edd37bb9..3cd9b02a 100644 --- a/jfuse-win-amd64/pom.xml +++ b/jfuse-win-amd64/pom.xml @@ -100,7 +100,7 @@ fuse3_mount fuse3_get_session fuse3_loop - fuse3_loop_mt + fuse3_loop_mt_31 fuse3_exit fuse3_unmount fuse3_destroy @@ -115,7 +115,6 @@ fuse_statvfs fuse_timespec fuse3_conn_info - fuse3_loop_config diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseMountImpl.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseMountImpl.java index 64eae74b..755adefd 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseMountImpl.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseMountImpl.java @@ -1,23 +1,16 @@ package org.cryptomator.jfuse.win.amd64; import org.cryptomator.jfuse.api.FuseMount; -import org.cryptomator.jfuse.win.amd64.extr.fuse3_loop_config; import org.cryptomator.jfuse.win.amd64.extr.fuse_h; import java.lang.foreign.MemoryAddress; -import java.lang.foreign.MemorySession; record FuseMountImpl(MemoryAddress fuse, FuseArgs fuseArgs) implements FuseMount { @Override public int loop() { if (fuseArgs.multiThreaded()) { - try (var scope = MemorySession.openConfined()) { - var loopCfg = fuse3_loop_config.allocate(scope); - fuse3_loop_config.clone_fd$set(loopCfg, 0); - fuse3_loop_config.max_idle_threads$set(loopCfg, 10); - return fuse_h.fuse3_loop_mt(fuse, loopCfg); - } + return fuse_h.fuse3_loop_mt_31(fuse, 0); } else { return fuse_h.fuse3_loop(fuse); } diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$1.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$1.java index acaa7a05..318db787 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$1.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$1.java @@ -23,13 +23,13 @@ class constants$1 { "fuse3_loop", constants$1.fuse3_loop$FUNC ); - static final FunctionDescriptor fuse3_loop_mt$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + static final FunctionDescriptor fuse3_loop_mt_31$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT + Constants$root.C_LONG$LAYOUT ); - static final MethodHandle fuse3_loop_mt$MH = RuntimeHelper.downcallHandle( - "fuse3_loop_mt", - constants$1.fuse3_loop_mt$FUNC + static final MethodHandle fuse3_loop_mt_31$MH = RuntimeHelper.downcallHandle( + "fuse3_loop_mt_31", + constants$1.fuse3_loop_mt_31$FUNC ); static final FunctionDescriptor fuse3_exit$FUNC = FunctionDescriptor.ofVoid( Constants$root.C_POINTER$LAYOUT diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_loop_config.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_loop_config.java deleted file mode 100644 index 9193a8af..00000000 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_loop_config.java +++ /dev/null @@ -1,59 +0,0 @@ -// Generated by jextract - -package org.cryptomator.jfuse.win.amd64.extr; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.VarHandle; -import java.nio.ByteOrder; -import java.lang.foreign.*; -import static java.lang.foreign.ValueLayout.*; -public class fuse3_loop_config { - - static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( - Constants$root.C_LONG$LAYOUT.withName("clone_fd"), - Constants$root.C_LONG$LAYOUT.withName("max_idle_threads") - ).withName("fuse3_loop_config"); - public static MemoryLayout $LAYOUT() { - return fuse3_loop_config.$struct$LAYOUT; - } - static final VarHandle clone_fd$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("clone_fd")); - public static VarHandle clone_fd$VH() { - return fuse3_loop_config.clone_fd$VH; - } - public static int clone_fd$get(MemorySegment seg) { - return (int)fuse3_loop_config.clone_fd$VH.get(seg); - } - public static void clone_fd$set( MemorySegment seg, int x) { - fuse3_loop_config.clone_fd$VH.set(seg, x); - } - public static int clone_fd$get(MemorySegment seg, long index) { - return (int)fuse3_loop_config.clone_fd$VH.get(seg.asSlice(index*sizeof())); - } - public static void clone_fd$set(MemorySegment seg, long index, int x) { - fuse3_loop_config.clone_fd$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle max_idle_threads$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max_idle_threads")); - public static VarHandle max_idle_threads$VH() { - return fuse3_loop_config.max_idle_threads$VH; - } - public static int max_idle_threads$get(MemorySegment seg) { - return (int)fuse3_loop_config.max_idle_threads$VH.get(seg); - } - public static void max_idle_threads$set( MemorySegment seg, int x) { - fuse3_loop_config.max_idle_threads$VH.set(seg, x); - } - public static int max_idle_threads$get(MemorySegment seg, long index) { - return (int)fuse3_loop_config.max_idle_threads$VH.get(seg.asSlice(index*sizeof())); - } - public static void max_idle_threads$set(MemorySegment seg, long index, int x) { - fuse3_loop_config.max_idle_threads$VH.set(seg.asSlice(index*sizeof()), x); - } - public static long sizeof() { return $LAYOUT().byteSize(); } - public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } - public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { - return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); - } - public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } -} - - diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_h.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_h.java index 1071b669..a55dfb51 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_h.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_h.java @@ -84,13 +84,13 @@ public static int fuse3_loop ( Addressable f) { throw new AssertionError("should not reach here", ex$); } } - public static MethodHandle fuse3_loop_mt$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse3_loop_mt$MH,"fuse3_loop_mt"); + public static MethodHandle fuse3_loop_mt_31$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse3_loop_mt_31$MH,"fuse3_loop_mt_31"); } - public static int fuse3_loop_mt ( Addressable f, Addressable config) { - var mh$ = fuse3_loop_mt$MH(); + public static int fuse3_loop_mt_31 ( Addressable f, int clone_fd) { + var mh$ = fuse3_loop_mt_31$MH(); try { - return (int)mh$.invokeExact(f, config); + return (int)mh$.invokeExact(f, clone_fd); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } From 5bbd1f0e114849d7769c3ca28a6c5dba1b48f3ae Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Tue, 4 Oct 2022 12:24:37 +0200 Subject: [PATCH 09/20] actually fix jextraction on windows --- jfuse-win-amd64/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jfuse-win-amd64/pom.xml b/jfuse-win-amd64/pom.xml index 3cd9b02a..82665348 100644 --- a/jfuse-win-amd64/pom.xml +++ b/jfuse-win-amd64/pom.xml @@ -92,7 +92,7 @@ fuse_h WINFSP_DLL_INTERNAL - FUSE_USE_VERSION=32 + FUSE_USE_VERSION=31 fuse3_lib_help From 09b6b810955b3834859f4039f81dd6e23a52e1dc Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 4 Oct 2022 12:49:38 +0200 Subject: [PATCH 10/20] update libfuse to 3.12 --- jfuse-linux-aarch64/pom.xml | 11 ++- .../jfuse/linux/aarch64/FuseImpl.java | 2 +- .../jfuse/linux/aarch64/FuseMountImpl.java | 12 ++-- .../jfuse/linux/aarch64/extr/constants$0.java | 58 ++++++++------- .../jfuse/linux/aarch64/extr/constants$1.java | 55 ++++++++------ .../jfuse/linux/aarch64/extr/constants$2.java | 43 +++++++++++ .../linux/aarch64/extr/fuse_fill_dir_t.java | 2 +- .../jfuse/linux/aarch64/extr/fuse_h.java | 71 ++++++++++++++++--- .../linux/aarch64/extr/ll/constants$0.java | 8 +-- .../aarch64/extr/ll/fuse_cmdline_opts.java | 20 +++++- .../aarch64/extr/ll/fuse_lowlevel_h.java | 8 +-- .../jfuse/linux/aarch64/extr/stat_h.java | 9 --- .../jfuse/linux/aarch64/FuseImplTest.java | 4 +- jfuse-linux-amd64/pom.xml | 11 ++- .../jfuse/linux/amd64/FuseImpl.java | 2 +- .../jfuse/linux/amd64/FuseMountImpl.java | 12 ++-- .../jfuse/linux/amd64/extr/constants$0.java | 58 ++++++++------- .../jfuse/linux/amd64/extr/constants$1.java | 55 ++++++++------ .../jfuse/linux/amd64/extr/constants$2.java | 43 +++++++++++ .../linux/amd64/extr/fuse_fill_dir_t.java | 2 +- .../jfuse/linux/amd64/extr/fuse_h.java | 71 ++++++++++++++++--- .../linux/amd64/extr/ll/constants$0.java | 8 +-- .../amd64/extr/ll/fuse_cmdline_opts.java | 20 +++++- .../linux/amd64/extr/ll/fuse_lowlevel_h.java | 8 +-- .../jfuse/linux/amd64/extr/stat_h.java | 9 --- .../jfuse/linux/amd64/FuseImplTest.java | 4 +- libfuse3 | 2 +- 27 files changed, 429 insertions(+), 179 deletions(-) create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/constants$2.java create mode 100644 jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/constants$2.java diff --git a/jfuse-linux-aarch64/pom.xml b/jfuse-linux-aarch64/pom.xml index 6381696b..96231d45 100644 --- a/jfuse-linux-aarch64/pom.xml +++ b/jfuse-linux-aarch64/pom.xml @@ -91,14 +91,19 @@ fuse_h _FILE_OFFSET_BITS=64 - FUSE_USE_VERSION=35 + FUSE_USE_VERSION=312 + fuse_version fuse_lib_help fuse_new fuse_mount fuse_get_session fuse_loop + fuse_loop_cfg_create + fuse_loop_cfg_set_clone_fd + fuse_loop_cfg_set_max_threads + fuse_loop_cfg_destroy fuse_loop_mt fuse_exit fuse_unmount @@ -130,10 +135,10 @@ fuse_lowlevel_h _FILE_OFFSET_BITS=64 - FUSE_USE_VERSION=35 + FUSE_USE_VERSION=312 - fuse_parse_cmdline + fuse_parse_cmdline_312 fuse_cmdline_opts diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseImpl.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseImpl.java index b7e084a0..a652fa5b 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseImpl.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseImpl.java @@ -61,7 +61,7 @@ FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { fuse_args.allocated$set(args, 0); var opts = fuse_cmdline_opts.allocate(fuseScope); - int parseResult = fuse_lowlevel_h.fuse_parse_cmdline(args, opts); + int parseResult = fuse_lowlevel_h.fuse_parse_cmdline_312(args, opts); // TODO: support fuse < 3.12 if (parseResult != 0) { throw new IllegalArgumentException("fuse_parse_cmdline failed to parse " + String.join(" ", cmdLineArgs)); } diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseMountImpl.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseMountImpl.java index f1dbf07b..a0ab1503 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseMountImpl.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseMountImpl.java @@ -11,12 +11,14 @@ record FuseMountImpl(MemoryAddress fuse, FuseArgs fuseArgs) implements FuseMount @Override public int loop() { - if (fuseArgs.multithreaded()) { - try (var scope = MemorySession.openConfined()) { - var loopCfg = fuse_loop_config.allocate(scope); - fuse_loop_config.clone_fd$set(loopCfg, 0); - fuse_loop_config.max_idle_threads$set(loopCfg, 10); + if (fuseArgs.multithreaded() && fuse_h.fuse_version() > 312) { // TODO: support fuse < 3.12 + var loopCfg = fuse_h.fuse_loop_cfg_create(); + try { + fuse_h.fuse_loop_cfg_set_clone_fd(loopCfg, 0); + fuse_h.fuse_loop_cfg_set_max_threads (loopCfg, 4); return fuse_h.fuse_loop_mt(fuse, loopCfg); + } finally { + fuse_h.fuse_loop_cfg_destroy(loopCfg); } } else { return fuse_h.fuse_loop(fuse); diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/constants$0.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/constants$0.java index 57a7d35a..0a84d9c3 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/constants$0.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/constants$0.java @@ -9,47 +9,45 @@ import static java.lang.foreign.ValueLayout.*; class constants$0 { - static final FunctionDescriptor fuse_fill_dir_t$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_LONG_LONG$LAYOUT, - Constants$root.C_INT$LAYOUT + static final FunctionDescriptor fuse_version$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT); + static final MethodHandle fuse_version$MH = RuntimeHelper.downcallHandle( + "fuse_version", + constants$0.fuse_version$FUNC ); - static final MethodHandle fuse_fill_dir_t$MH = RuntimeHelper.downcallHandle( - constants$0.fuse_fill_dir_t$FUNC + static final FunctionDescriptor fuse_loop_cfg_create$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT); + static final MethodHandle fuse_loop_cfg_create$MH = RuntimeHelper.downcallHandle( + "fuse_loop_cfg_create", + constants$0.fuse_loop_cfg_create$FUNC ); - static final FunctionDescriptor fuse_lib_help$FUNC = FunctionDescriptor.ofVoid( + static final FunctionDescriptor fuse_loop_cfg_destroy$FUNC = FunctionDescriptor.ofVoid( Constants$root.C_POINTER$LAYOUT ); - static final MethodHandle fuse_lib_help$MH = RuntimeHelper.downcallHandle( - "fuse_lib_help", - constants$0.fuse_lib_help$FUNC + static final MethodHandle fuse_loop_cfg_destroy$MH = RuntimeHelper.downcallHandle( + "fuse_loop_cfg_destroy", + constants$0.fuse_loop_cfg_destroy$FUNC ); - static final FunctionDescriptor fuse_new$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT, + static final FunctionDescriptor fuse_loop_cfg_set_max_threads$FUNC = FunctionDescriptor.ofVoid( Constants$root.C_POINTER$LAYOUT, - Constants$root.C_LONG_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT + Constants$root.C_INT$LAYOUT ); - static final MethodHandle fuse_new$MH = RuntimeHelper.downcallHandle( - "fuse_new", - constants$0.fuse_new$FUNC + static final MethodHandle fuse_loop_cfg_set_max_threads$MH = RuntimeHelper.downcallHandle( + "fuse_loop_cfg_set_max_threads", + constants$0.fuse_loop_cfg_set_max_threads$FUNC ); - static final FunctionDescriptor fuse_mount$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + static final FunctionDescriptor fuse_loop_cfg_set_clone_fd$FUNC = FunctionDescriptor.ofVoid( Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT + Constants$root.C_INT$LAYOUT ); - static final MethodHandle fuse_mount$MH = RuntimeHelper.downcallHandle( - "fuse_mount", - constants$0.fuse_mount$FUNC + static final MethodHandle fuse_loop_cfg_set_clone_fd$MH = RuntimeHelper.downcallHandle( + "fuse_loop_cfg_set_clone_fd", + constants$0.fuse_loop_cfg_set_clone_fd$FUNC ); - static final FunctionDescriptor fuse_unmount$FUNC = FunctionDescriptor.ofVoid( - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle fuse_unmount$MH = RuntimeHelper.downcallHandle( - "fuse_unmount", - constants$0.fuse_unmount$FUNC + static final FunctionDescriptor fuse_fill_dir_t$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_INT$LAYOUT ); } diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/constants$1.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/constants$1.java index 6640ad95..056d3622 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/constants$1.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/constants$1.java @@ -9,41 +9,54 @@ import static java.lang.foreign.ValueLayout.*; class constants$1 { - static final FunctionDescriptor fuse_destroy$FUNC = FunctionDescriptor.ofVoid( - Constants$root.C_POINTER$LAYOUT + static final FunctionDescriptor fuse_fill_dir_t$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_INT$LAYOUT ); - static final MethodHandle fuse_destroy$MH = RuntimeHelper.downcallHandle( - "fuse_destroy", - constants$1.fuse_destroy$FUNC + static final MethodHandle fuse_fill_dir_t$MH = RuntimeHelper.downcallHandle( + constants$1.fuse_fill_dir_t$FUNC ); - static final FunctionDescriptor fuse_loop$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + static final FunctionDescriptor fuse_lib_help$FUNC = FunctionDescriptor.ofVoid( Constants$root.C_POINTER$LAYOUT ); - static final MethodHandle fuse_loop$MH = RuntimeHelper.downcallHandle( - "fuse_loop", - constants$1.fuse_loop$FUNC + static final MethodHandle fuse_lib_help$MH = RuntimeHelper.downcallHandle( + "fuse_lib_help", + constants$1.fuse_lib_help$FUNC ); - static final FunctionDescriptor fuse_exit$FUNC = FunctionDescriptor.ofVoid( + static final FunctionDescriptor fuse_new$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, Constants$root.C_POINTER$LAYOUT ); - static final MethodHandle fuse_exit$MH = RuntimeHelper.downcallHandle( - "fuse_exit", - constants$1.fuse_exit$FUNC + static final MethodHandle fuse_new$MH = RuntimeHelper.downcallHandle( + "fuse_new", + constants$1.fuse_new$FUNC ); - static final FunctionDescriptor fuse_loop_mt$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + static final FunctionDescriptor fuse_mount$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT ); - static final MethodHandle fuse_loop_mt$MH = RuntimeHelper.downcallHandle( - "fuse_loop_mt", - constants$1.fuse_loop_mt$FUNC + static final MethodHandle fuse_mount$MH = RuntimeHelper.downcallHandle( + "fuse_mount", + constants$1.fuse_mount$FUNC + ); + static final FunctionDescriptor fuse_unmount$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_unmount$MH = RuntimeHelper.downcallHandle( + "fuse_unmount", + constants$1.fuse_unmount$FUNC ); - static final FunctionDescriptor fuse_get_session$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + static final FunctionDescriptor fuse_destroy$FUNC = FunctionDescriptor.ofVoid( Constants$root.C_POINTER$LAYOUT ); - static final MethodHandle fuse_get_session$MH = RuntimeHelper.downcallHandle( - "fuse_get_session", - constants$1.fuse_get_session$FUNC + static final MethodHandle fuse_destroy$MH = RuntimeHelper.downcallHandle( + "fuse_destroy", + constants$1.fuse_destroy$FUNC ); } diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/constants$2.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/constants$2.java new file mode 100644 index 00000000..5020cf17 --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/constants$2.java @@ -0,0 +1,43 @@ +// Generated by jextract + +package org.cryptomator.jfuse.linux.aarch64.extr; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.VarHandle; +import java.nio.ByteOrder; +import java.lang.foreign.*; +import static java.lang.foreign.ValueLayout.*; +class constants$2 { + + static final FunctionDescriptor fuse_loop$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_loop$MH = RuntimeHelper.downcallHandle( + "fuse_loop", + constants$2.fuse_loop$FUNC + ); + static final FunctionDescriptor fuse_exit$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_exit$MH = RuntimeHelper.downcallHandle( + "fuse_exit", + constants$2.fuse_exit$FUNC + ); + static final FunctionDescriptor fuse_loop_mt$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_loop_mt$MH = RuntimeHelper.downcallHandle( + "fuse_loop_mt", + constants$2.fuse_loop_mt$FUNC + ); + static final FunctionDescriptor fuse_get_session$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_get_session$MH = RuntimeHelper.downcallHandle( + "fuse_get_session", + constants$2.fuse_get_session$FUNC + ); +} + + diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_fill_dir_t.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_fill_dir_t.java index b0e952bc..9b199066 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_fill_dir_t.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_fill_dir_t.java @@ -17,7 +17,7 @@ static fuse_fill_dir_t ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress _buf, java.lang.foreign.MemoryAddress _name, java.lang.foreign.MemoryAddress _stbuf, long _off, int _flags) -> { try { - return (int)constants$0.fuse_fill_dir_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_buf, (java.lang.foreign.Addressable)_name, (java.lang.foreign.Addressable)_stbuf, _off, _flags); + return (int)constants$1.fuse_fill_dir_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_buf, (java.lang.foreign.Addressable)_name, (java.lang.foreign.Addressable)_stbuf, _off, _flags); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_h.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_h.java index c15911bd..abc89ff7 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_h.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_h.java @@ -18,8 +18,63 @@ public class fuse_h { public static OfFloat C_FLOAT = Constants$root.C_FLOAT$LAYOUT; public static OfDouble C_DOUBLE = Constants$root.C_DOUBLE$LAYOUT; public static OfAddress C_POINTER = Constants$root.C_POINTER$LAYOUT; + public static MethodHandle fuse_version$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_version$MH,"fuse_version"); + } + public static int fuse_version () { + var mh$ = fuse_version$MH(); + try { + return (int)mh$.invokeExact(); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_loop_cfg_create$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_loop_cfg_create$MH,"fuse_loop_cfg_create"); + } + public static MemoryAddress fuse_loop_cfg_create () { + var mh$ = fuse_loop_cfg_create$MH(); + try { + return (java.lang.foreign.MemoryAddress)mh$.invokeExact(); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_loop_cfg_destroy$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_loop_cfg_destroy$MH,"fuse_loop_cfg_destroy"); + } + public static void fuse_loop_cfg_destroy ( Addressable config) { + var mh$ = fuse_loop_cfg_destroy$MH(); + try { + mh$.invokeExact(config); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_loop_cfg_set_max_threads$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_loop_cfg_set_max_threads$MH,"fuse_loop_cfg_set_max_threads"); + } + public static void fuse_loop_cfg_set_max_threads ( Addressable config, int value) { + var mh$ = fuse_loop_cfg_set_max_threads$MH(); + try { + mh$.invokeExact(config, value); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_loop_cfg_set_clone_fd$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_loop_cfg_set_clone_fd$MH,"fuse_loop_cfg_set_clone_fd"); + } + public static void fuse_loop_cfg_set_clone_fd ( Addressable config, int value) { + var mh$ = fuse_loop_cfg_set_clone_fd$MH(); + try { + mh$.invokeExact(config, value); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } public static MethodHandle fuse_lib_help$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_lib_help$MH,"fuse_lib_help"); + return RuntimeHelper.requireNonNull(constants$1.fuse_lib_help$MH,"fuse_lib_help"); } public static void fuse_lib_help ( Addressable args) { var mh$ = fuse_lib_help$MH(); @@ -30,7 +85,7 @@ public static void fuse_lib_help ( Addressable args) { } } public static MethodHandle fuse_new$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_new$MH,"fuse_new"); + return RuntimeHelper.requireNonNull(constants$1.fuse_new$MH,"fuse_new"); } public static MemoryAddress fuse_new ( Addressable args, Addressable op, long op_size, Addressable private_data) { var mh$ = fuse_new$MH(); @@ -41,7 +96,7 @@ public static MemoryAddress fuse_new ( Addressable args, Addressable op, long } } public static MethodHandle fuse_mount$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_mount$MH,"fuse_mount"); + return RuntimeHelper.requireNonNull(constants$1.fuse_mount$MH,"fuse_mount"); } public static int fuse_mount ( Addressable f, Addressable mountpoint) { var mh$ = fuse_mount$MH(); @@ -52,7 +107,7 @@ public static int fuse_mount ( Addressable f, Addressable mountpoint) { } } public static MethodHandle fuse_unmount$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_unmount$MH,"fuse_unmount"); + return RuntimeHelper.requireNonNull(constants$1.fuse_unmount$MH,"fuse_unmount"); } public static void fuse_unmount ( Addressable f) { var mh$ = fuse_unmount$MH(); @@ -74,7 +129,7 @@ public static void fuse_destroy ( Addressable f) { } } public static MethodHandle fuse_loop$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse_loop$MH,"fuse_loop"); + return RuntimeHelper.requireNonNull(constants$2.fuse_loop$MH,"fuse_loop"); } public static int fuse_loop ( Addressable f) { var mh$ = fuse_loop$MH(); @@ -85,7 +140,7 @@ public static int fuse_loop ( Addressable f) { } } public static MethodHandle fuse_exit$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse_exit$MH,"fuse_exit"); + return RuntimeHelper.requireNonNull(constants$2.fuse_exit$MH,"fuse_exit"); } public static void fuse_exit ( Addressable f) { var mh$ = fuse_exit$MH(); @@ -96,7 +151,7 @@ public static void fuse_exit ( Addressable f) { } } public static MethodHandle fuse_loop_mt$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse_loop_mt$MH,"fuse_loop_mt"); + return RuntimeHelper.requireNonNull(constants$2.fuse_loop_mt$MH,"fuse_loop_mt"); } public static int fuse_loop_mt ( Addressable f, Addressable config) { var mh$ = fuse_loop_mt$MH(); @@ -107,7 +162,7 @@ public static int fuse_loop_mt ( Addressable f, Addressable config) { } } public static MethodHandle fuse_get_session$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse_get_session$MH,"fuse_get_session"); + return RuntimeHelper.requireNonNull(constants$2.fuse_get_session$MH,"fuse_get_session"); } public static MemoryAddress fuse_get_session ( Addressable f) { var mh$ = fuse_get_session$MH(); diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/constants$0.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/constants$0.java index 426dcc26..c422c085 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/constants$0.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/constants$0.java @@ -9,13 +9,13 @@ import static java.lang.foreign.ValueLayout.*; class constants$0 { - static final FunctionDescriptor fuse_parse_cmdline$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + static final FunctionDescriptor fuse_parse_cmdline_312$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT ); - static final MethodHandle fuse_parse_cmdline$MH = RuntimeHelper.downcallHandle( - "fuse_parse_cmdline", - constants$0.fuse_parse_cmdline$FUNC + static final MethodHandle fuse_parse_cmdline_312$MH = RuntimeHelper.downcallHandle( + "fuse_parse_cmdline_312", + constants$0.fuse_parse_cmdline_312$FUNC ); } diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/fuse_cmdline_opts.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/fuse_cmdline_opts.java index 34c36adb..39aba077 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/fuse_cmdline_opts.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/fuse_cmdline_opts.java @@ -18,7 +18,9 @@ public class fuse_cmdline_opts { Constants$root.C_INT$LAYOUT.withName("show_version"), Constants$root.C_INT$LAYOUT.withName("show_help"), Constants$root.C_INT$LAYOUT.withName("clone_fd"), - Constants$root.C_INT$LAYOUT.withName("max_idle_threads") + Constants$root.C_INT$LAYOUT.withName("max_idle_threads"), + Constants$root.C_INT$LAYOUT.withName("max_threads"), + MemoryLayout.paddingLayout(32) ).withName("fuse_cmdline_opts"); public static MemoryLayout $LAYOUT() { return fuse_cmdline_opts.$struct$LAYOUT; @@ -167,6 +169,22 @@ public class fuse_cmdline_opts { public static void max_idle_threads$set(MemorySegment seg, long index, int x) { fuse_cmdline_opts.max_idle_threads$VH.set(seg.asSlice(index*sizeof()), x); } + static final VarHandle max_threads$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max_threads")); + public static VarHandle max_threads$VH() { + return fuse_cmdline_opts.max_threads$VH; + } + public static int max_threads$get(MemorySegment seg) { + return (int)fuse_cmdline_opts.max_threads$VH.get(seg); + } + public static void max_threads$set( MemorySegment seg, int x) { + fuse_cmdline_opts.max_threads$VH.set(seg, x); + } + public static int max_threads$get(MemorySegment seg, long index) { + return (int)fuse_cmdline_opts.max_threads$VH.get(seg.asSlice(index*sizeof())); + } + public static void max_threads$set(MemorySegment seg, long index, int x) { + fuse_cmdline_opts.max_threads$VH.set(seg.asSlice(index*sizeof()), x); + } public static long sizeof() { return $LAYOUT().byteSize(); } public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/fuse_lowlevel_h.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/fuse_lowlevel_h.java index b6462f4d..07057767 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/fuse_lowlevel_h.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/fuse_lowlevel_h.java @@ -18,11 +18,11 @@ public class fuse_lowlevel_h { public static OfFloat C_FLOAT = Constants$root.C_FLOAT$LAYOUT; public static OfDouble C_DOUBLE = Constants$root.C_DOUBLE$LAYOUT; public static OfAddress C_POINTER = Constants$root.C_POINTER$LAYOUT; - public static MethodHandle fuse_parse_cmdline$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_parse_cmdline$MH,"fuse_parse_cmdline"); + public static MethodHandle fuse_parse_cmdline_312$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_parse_cmdline_312$MH,"fuse_parse_cmdline_312"); } - public static int fuse_parse_cmdline ( Addressable args, Addressable opts) { - var mh$ = fuse_parse_cmdline$MH(); + public static int fuse_parse_cmdline_312 ( Addressable args, Addressable opts) { + var mh$ = fuse_parse_cmdline_312$MH(); try { return (int)mh$.invokeExact(args, opts); } catch (Throwable ex$) { diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/stat_h.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/stat_h.java index 876229b4..45cb993c 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/stat_h.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/stat_h.java @@ -24,15 +24,6 @@ public static long UTIME_NOW() { public static long UTIME_OMIT() { return 1073741822L; } - public static int S_IFDIR() { - return (int)16384L; - } - public static int S_IFREG() { - return (int)32768L; - } - public static int S_IFLNK() { - return (int)40960L; - } } diff --git a/jfuse-linux-aarch64/src/test/java/org/cryptomator/jfuse/linux/aarch64/FuseImplTest.java b/jfuse-linux-aarch64/src/test/java/org/cryptomator/jfuse/linux/aarch64/FuseImplTest.java index 393d1569..92274e81 100644 --- a/jfuse-linux-aarch64/src/test/java/org/cryptomator/jfuse/linux/aarch64/FuseImplTest.java +++ b/jfuse-linux-aarch64/src/test/java/org/cryptomator/jfuse/linux/aarch64/FuseImplTest.java @@ -87,7 +87,7 @@ public void testParseArgsHelp(String arg) { var args = List.of("fusefs", arg); try (var fuseLowlevelH = Mockito.mockStatic(fuse_lowlevel_h.class); var fuseH = Mockito.mockStatic(fuse_h.class)) { - fuseLowlevelH.when(() -> fuse_lowlevel_h.fuse_parse_cmdline(Mockito.any(), Mockito.any())).then(invocation -> { + fuseLowlevelH.when(() -> fuse_lowlevel_h.fuse_parse_cmdline_312(Mockito.any(), Mockito.any())).then(invocation -> { MemorySegment opts = invocation.getArgument(1); fuse_cmdline_opts.show_help$set(opts, 1); return 0; @@ -104,7 +104,7 @@ public void testParseArgsHelp(String arg) { public void testParseArgs() { try (var fuseLowlevelH = Mockito.mockStatic(fuse_lowlevel_h.class); var scope = MemorySession.openConfined()) { - fuseLowlevelH.when(() -> fuse_lowlevel_h.fuse_parse_cmdline(Mockito.any(), Mockito.any())).then(invocation -> { + fuseLowlevelH.when(() -> fuse_lowlevel_h.fuse_parse_cmdline_312(Mockito.any(), Mockito.any())).then(invocation -> { MemorySegment opts = invocation.getArgument(1); fuse_cmdline_opts.singlethread$set(opts, 0); fuse_cmdline_opts.debug$set(opts, 1); diff --git a/jfuse-linux-amd64/pom.xml b/jfuse-linux-amd64/pom.xml index 79bdde1f..82945200 100644 --- a/jfuse-linux-amd64/pom.xml +++ b/jfuse-linux-amd64/pom.xml @@ -91,14 +91,19 @@ fuse_h _FILE_OFFSET_BITS=64 - FUSE_USE_VERSION=35 + FUSE_USE_VERSION=312 + fuse_version fuse_lib_help fuse_new fuse_mount fuse_get_session fuse_loop + fuse_loop_cfg_create + fuse_loop_cfg_set_clone_fd + fuse_loop_cfg_set_max_threads + fuse_loop_cfg_destroy fuse_loop_mt fuse_exit fuse_unmount @@ -130,10 +135,10 @@ fuse_lowlevel_h _FILE_OFFSET_BITS=64 - FUSE_USE_VERSION=35 + FUSE_USE_VERSION=312 - fuse_parse_cmdline + fuse_parse_cmdline_312 fuse_cmdline_opts diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseImpl.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseImpl.java index 55bdb212..5f0e47cb 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseImpl.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseImpl.java @@ -61,7 +61,7 @@ FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { fuse_args.allocated$set(args, 0); var opts = fuse_cmdline_opts.allocate(fuseScope); - int parseResult = fuse_lowlevel_h.fuse_parse_cmdline(args, opts); + int parseResult = fuse_lowlevel_h.fuse_parse_cmdline_312(args, opts); // TODO: support fuse < 3.12 if (parseResult != 0) { throw new IllegalArgumentException("fuse_parse_cmdline failed to parse " + String.join(" ", cmdLineArgs)); } diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseMountImpl.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseMountImpl.java index 60e9a2da..e1b07b7c 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseMountImpl.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseMountImpl.java @@ -11,12 +11,14 @@ record FuseMountImpl(MemoryAddress fuse, FuseArgs fuseArgs) implements FuseMount @Override public int loop() { - if (fuseArgs.multithreaded()) { - try (var scope = MemorySession.openConfined()) { - var loopCfg = fuse_loop_config.allocate(scope); - fuse_loop_config.clone_fd$set(loopCfg, 0); - fuse_loop_config.max_idle_threads$set(loopCfg, 10); + if (fuseArgs.multithreaded() && fuse_h.fuse_version() > 312) { // TODO: support fuse < 3.12 + var loopCfg = fuse_h.fuse_loop_cfg_create(); + try { + fuse_h.fuse_loop_cfg_set_clone_fd(loopCfg, 0); + fuse_h.fuse_loop_cfg_set_max_threads (loopCfg, 4); return fuse_h.fuse_loop_mt(fuse, loopCfg); + } finally { + fuse_h.fuse_loop_cfg_destroy(loopCfg); } } else { return fuse_h.fuse_loop(fuse); diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/constants$0.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/constants$0.java index 8ee42214..a3ea0512 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/constants$0.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/constants$0.java @@ -9,47 +9,45 @@ import static java.lang.foreign.ValueLayout.*; class constants$0 { - static final FunctionDescriptor fuse_fill_dir_t$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_LONG_LONG$LAYOUT, - Constants$root.C_INT$LAYOUT + static final FunctionDescriptor fuse_version$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT); + static final MethodHandle fuse_version$MH = RuntimeHelper.downcallHandle( + "fuse_version", + constants$0.fuse_version$FUNC ); - static final MethodHandle fuse_fill_dir_t$MH = RuntimeHelper.downcallHandle( - constants$0.fuse_fill_dir_t$FUNC + static final FunctionDescriptor fuse_loop_cfg_create$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT); + static final MethodHandle fuse_loop_cfg_create$MH = RuntimeHelper.downcallHandle( + "fuse_loop_cfg_create", + constants$0.fuse_loop_cfg_create$FUNC ); - static final FunctionDescriptor fuse_lib_help$FUNC = FunctionDescriptor.ofVoid( + static final FunctionDescriptor fuse_loop_cfg_destroy$FUNC = FunctionDescriptor.ofVoid( Constants$root.C_POINTER$LAYOUT ); - static final MethodHandle fuse_lib_help$MH = RuntimeHelper.downcallHandle( - "fuse_lib_help", - constants$0.fuse_lib_help$FUNC + static final MethodHandle fuse_loop_cfg_destroy$MH = RuntimeHelper.downcallHandle( + "fuse_loop_cfg_destroy", + constants$0.fuse_loop_cfg_destroy$FUNC ); - static final FunctionDescriptor fuse_new$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT, + static final FunctionDescriptor fuse_loop_cfg_set_max_threads$FUNC = FunctionDescriptor.ofVoid( Constants$root.C_POINTER$LAYOUT, - Constants$root.C_LONG_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT + Constants$root.C_INT$LAYOUT ); - static final MethodHandle fuse_new$MH = RuntimeHelper.downcallHandle( - "fuse_new", - constants$0.fuse_new$FUNC + static final MethodHandle fuse_loop_cfg_set_max_threads$MH = RuntimeHelper.downcallHandle( + "fuse_loop_cfg_set_max_threads", + constants$0.fuse_loop_cfg_set_max_threads$FUNC ); - static final FunctionDescriptor fuse_mount$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + static final FunctionDescriptor fuse_loop_cfg_set_clone_fd$FUNC = FunctionDescriptor.ofVoid( Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT + Constants$root.C_INT$LAYOUT ); - static final MethodHandle fuse_mount$MH = RuntimeHelper.downcallHandle( - "fuse_mount", - constants$0.fuse_mount$FUNC + static final MethodHandle fuse_loop_cfg_set_clone_fd$MH = RuntimeHelper.downcallHandle( + "fuse_loop_cfg_set_clone_fd", + constants$0.fuse_loop_cfg_set_clone_fd$FUNC ); - static final FunctionDescriptor fuse_unmount$FUNC = FunctionDescriptor.ofVoid( - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle fuse_unmount$MH = RuntimeHelper.downcallHandle( - "fuse_unmount", - constants$0.fuse_unmount$FUNC + static final FunctionDescriptor fuse_fill_dir_t$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_INT$LAYOUT ); } diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/constants$1.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/constants$1.java index a6d7fef2..b5e94157 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/constants$1.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/constants$1.java @@ -9,41 +9,54 @@ import static java.lang.foreign.ValueLayout.*; class constants$1 { - static final FunctionDescriptor fuse_destroy$FUNC = FunctionDescriptor.ofVoid( - Constants$root.C_POINTER$LAYOUT + static final FunctionDescriptor fuse_fill_dir_t$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_INT$LAYOUT ); - static final MethodHandle fuse_destroy$MH = RuntimeHelper.downcallHandle( - "fuse_destroy", - constants$1.fuse_destroy$FUNC + static final MethodHandle fuse_fill_dir_t$MH = RuntimeHelper.downcallHandle( + constants$1.fuse_fill_dir_t$FUNC ); - static final FunctionDescriptor fuse_loop$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + static final FunctionDescriptor fuse_lib_help$FUNC = FunctionDescriptor.ofVoid( Constants$root.C_POINTER$LAYOUT ); - static final MethodHandle fuse_loop$MH = RuntimeHelper.downcallHandle( - "fuse_loop", - constants$1.fuse_loop$FUNC + static final MethodHandle fuse_lib_help$MH = RuntimeHelper.downcallHandle( + "fuse_lib_help", + constants$1.fuse_lib_help$FUNC ); - static final FunctionDescriptor fuse_exit$FUNC = FunctionDescriptor.ofVoid( + static final FunctionDescriptor fuse_new$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, Constants$root.C_POINTER$LAYOUT ); - static final MethodHandle fuse_exit$MH = RuntimeHelper.downcallHandle( - "fuse_exit", - constants$1.fuse_exit$FUNC + static final MethodHandle fuse_new$MH = RuntimeHelper.downcallHandle( + "fuse_new", + constants$1.fuse_new$FUNC ); - static final FunctionDescriptor fuse_loop_mt$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + static final FunctionDescriptor fuse_mount$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT ); - static final MethodHandle fuse_loop_mt$MH = RuntimeHelper.downcallHandle( - "fuse_loop_mt", - constants$1.fuse_loop_mt$FUNC + static final MethodHandle fuse_mount$MH = RuntimeHelper.downcallHandle( + "fuse_mount", + constants$1.fuse_mount$FUNC + ); + static final FunctionDescriptor fuse_unmount$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_unmount$MH = RuntimeHelper.downcallHandle( + "fuse_unmount", + constants$1.fuse_unmount$FUNC ); - static final FunctionDescriptor fuse_get_session$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + static final FunctionDescriptor fuse_destroy$FUNC = FunctionDescriptor.ofVoid( Constants$root.C_POINTER$LAYOUT ); - static final MethodHandle fuse_get_session$MH = RuntimeHelper.downcallHandle( - "fuse_get_session", - constants$1.fuse_get_session$FUNC + static final MethodHandle fuse_destroy$MH = RuntimeHelper.downcallHandle( + "fuse_destroy", + constants$1.fuse_destroy$FUNC ); } diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/constants$2.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/constants$2.java new file mode 100644 index 00000000..5eb1f25a --- /dev/null +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/constants$2.java @@ -0,0 +1,43 @@ +// Generated by jextract + +package org.cryptomator.jfuse.linux.amd64.extr; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.VarHandle; +import java.nio.ByteOrder; +import java.lang.foreign.*; +import static java.lang.foreign.ValueLayout.*; +class constants$2 { + + static final FunctionDescriptor fuse_loop$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_loop$MH = RuntimeHelper.downcallHandle( + "fuse_loop", + constants$2.fuse_loop$FUNC + ); + static final FunctionDescriptor fuse_exit$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_exit$MH = RuntimeHelper.downcallHandle( + "fuse_exit", + constants$2.fuse_exit$FUNC + ); + static final FunctionDescriptor fuse_loop_mt$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_loop_mt$MH = RuntimeHelper.downcallHandle( + "fuse_loop_mt", + constants$2.fuse_loop_mt$FUNC + ); + static final FunctionDescriptor fuse_get_session$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_get_session$MH = RuntimeHelper.downcallHandle( + "fuse_get_session", + constants$2.fuse_get_session$FUNC + ); +} + + diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_fill_dir_t.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_fill_dir_t.java index e7fe2602..fac20ad9 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_fill_dir_t.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_fill_dir_t.java @@ -17,7 +17,7 @@ static fuse_fill_dir_t ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress _buf, java.lang.foreign.MemoryAddress _name, java.lang.foreign.MemoryAddress _stbuf, long _off, int _flags) -> { try { - return (int)constants$0.fuse_fill_dir_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_buf, (java.lang.foreign.Addressable)_name, (java.lang.foreign.Addressable)_stbuf, _off, _flags); + return (int)constants$1.fuse_fill_dir_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_buf, (java.lang.foreign.Addressable)_name, (java.lang.foreign.Addressable)_stbuf, _off, _flags); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_h.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_h.java index e188e1d8..d573932e 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_h.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_h.java @@ -18,8 +18,63 @@ public class fuse_h { public static OfFloat C_FLOAT = Constants$root.C_FLOAT$LAYOUT; public static OfDouble C_DOUBLE = Constants$root.C_DOUBLE$LAYOUT; public static OfAddress C_POINTER = Constants$root.C_POINTER$LAYOUT; + public static MethodHandle fuse_version$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_version$MH,"fuse_version"); + } + public static int fuse_version () { + var mh$ = fuse_version$MH(); + try { + return (int)mh$.invokeExact(); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_loop_cfg_create$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_loop_cfg_create$MH,"fuse_loop_cfg_create"); + } + public static MemoryAddress fuse_loop_cfg_create () { + var mh$ = fuse_loop_cfg_create$MH(); + try { + return (java.lang.foreign.MemoryAddress)mh$.invokeExact(); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_loop_cfg_destroy$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_loop_cfg_destroy$MH,"fuse_loop_cfg_destroy"); + } + public static void fuse_loop_cfg_destroy ( Addressable config) { + var mh$ = fuse_loop_cfg_destroy$MH(); + try { + mh$.invokeExact(config); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_loop_cfg_set_max_threads$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_loop_cfg_set_max_threads$MH,"fuse_loop_cfg_set_max_threads"); + } + public static void fuse_loop_cfg_set_max_threads ( Addressable config, int value) { + var mh$ = fuse_loop_cfg_set_max_threads$MH(); + try { + mh$.invokeExact(config, value); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_loop_cfg_set_clone_fd$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_loop_cfg_set_clone_fd$MH,"fuse_loop_cfg_set_clone_fd"); + } + public static void fuse_loop_cfg_set_clone_fd ( Addressable config, int value) { + var mh$ = fuse_loop_cfg_set_clone_fd$MH(); + try { + mh$.invokeExact(config, value); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } public static MethodHandle fuse_lib_help$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_lib_help$MH,"fuse_lib_help"); + return RuntimeHelper.requireNonNull(constants$1.fuse_lib_help$MH,"fuse_lib_help"); } public static void fuse_lib_help ( Addressable args) { var mh$ = fuse_lib_help$MH(); @@ -30,7 +85,7 @@ public static void fuse_lib_help ( Addressable args) { } } public static MethodHandle fuse_new$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_new$MH,"fuse_new"); + return RuntimeHelper.requireNonNull(constants$1.fuse_new$MH,"fuse_new"); } public static MemoryAddress fuse_new ( Addressable args, Addressable op, long op_size, Addressable private_data) { var mh$ = fuse_new$MH(); @@ -41,7 +96,7 @@ public static MemoryAddress fuse_new ( Addressable args, Addressable op, long } } public static MethodHandle fuse_mount$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_mount$MH,"fuse_mount"); + return RuntimeHelper.requireNonNull(constants$1.fuse_mount$MH,"fuse_mount"); } public static int fuse_mount ( Addressable f, Addressable mountpoint) { var mh$ = fuse_mount$MH(); @@ -52,7 +107,7 @@ public static int fuse_mount ( Addressable f, Addressable mountpoint) { } } public static MethodHandle fuse_unmount$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_unmount$MH,"fuse_unmount"); + return RuntimeHelper.requireNonNull(constants$1.fuse_unmount$MH,"fuse_unmount"); } public static void fuse_unmount ( Addressable f) { var mh$ = fuse_unmount$MH(); @@ -74,7 +129,7 @@ public static void fuse_destroy ( Addressable f) { } } public static MethodHandle fuse_loop$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse_loop$MH,"fuse_loop"); + return RuntimeHelper.requireNonNull(constants$2.fuse_loop$MH,"fuse_loop"); } public static int fuse_loop ( Addressable f) { var mh$ = fuse_loop$MH(); @@ -85,7 +140,7 @@ public static int fuse_loop ( Addressable f) { } } public static MethodHandle fuse_exit$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse_exit$MH,"fuse_exit"); + return RuntimeHelper.requireNonNull(constants$2.fuse_exit$MH,"fuse_exit"); } public static void fuse_exit ( Addressable f) { var mh$ = fuse_exit$MH(); @@ -96,7 +151,7 @@ public static void fuse_exit ( Addressable f) { } } public static MethodHandle fuse_loop_mt$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse_loop_mt$MH,"fuse_loop_mt"); + return RuntimeHelper.requireNonNull(constants$2.fuse_loop_mt$MH,"fuse_loop_mt"); } public static int fuse_loop_mt ( Addressable f, Addressable config) { var mh$ = fuse_loop_mt$MH(); @@ -107,7 +162,7 @@ public static int fuse_loop_mt ( Addressable f, Addressable config) { } } public static MethodHandle fuse_get_session$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse_get_session$MH,"fuse_get_session"); + return RuntimeHelper.requireNonNull(constants$2.fuse_get_session$MH,"fuse_get_session"); } public static MemoryAddress fuse_get_session ( Addressable f) { var mh$ = fuse_get_session$MH(); diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/constants$0.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/constants$0.java index 30f27df1..8cd11801 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/constants$0.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/constants$0.java @@ -9,13 +9,13 @@ import static java.lang.foreign.ValueLayout.*; class constants$0 { - static final FunctionDescriptor fuse_parse_cmdline$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + static final FunctionDescriptor fuse_parse_cmdline_312$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT ); - static final MethodHandle fuse_parse_cmdline$MH = RuntimeHelper.downcallHandle( - "fuse_parse_cmdline", - constants$0.fuse_parse_cmdline$FUNC + static final MethodHandle fuse_parse_cmdline_312$MH = RuntimeHelper.downcallHandle( + "fuse_parse_cmdline_312", + constants$0.fuse_parse_cmdline_312$FUNC ); } diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/fuse_cmdline_opts.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/fuse_cmdline_opts.java index 56734379..6d32e716 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/fuse_cmdline_opts.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/fuse_cmdline_opts.java @@ -18,7 +18,9 @@ public class fuse_cmdline_opts { Constants$root.C_INT$LAYOUT.withName("show_version"), Constants$root.C_INT$LAYOUT.withName("show_help"), Constants$root.C_INT$LAYOUT.withName("clone_fd"), - Constants$root.C_INT$LAYOUT.withName("max_idle_threads") + Constants$root.C_INT$LAYOUT.withName("max_idle_threads"), + Constants$root.C_INT$LAYOUT.withName("max_threads"), + MemoryLayout.paddingLayout(32) ).withName("fuse_cmdline_opts"); public static MemoryLayout $LAYOUT() { return fuse_cmdline_opts.$struct$LAYOUT; @@ -167,6 +169,22 @@ public class fuse_cmdline_opts { public static void max_idle_threads$set(MemorySegment seg, long index, int x) { fuse_cmdline_opts.max_idle_threads$VH.set(seg.asSlice(index*sizeof()), x); } + static final VarHandle max_threads$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max_threads")); + public static VarHandle max_threads$VH() { + return fuse_cmdline_opts.max_threads$VH; + } + public static int max_threads$get(MemorySegment seg) { + return (int)fuse_cmdline_opts.max_threads$VH.get(seg); + } + public static void max_threads$set( MemorySegment seg, int x) { + fuse_cmdline_opts.max_threads$VH.set(seg, x); + } + public static int max_threads$get(MemorySegment seg, long index) { + return (int)fuse_cmdline_opts.max_threads$VH.get(seg.asSlice(index*sizeof())); + } + public static void max_threads$set(MemorySegment seg, long index, int x) { + fuse_cmdline_opts.max_threads$VH.set(seg.asSlice(index*sizeof()), x); + } public static long sizeof() { return $LAYOUT().byteSize(); } public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/fuse_lowlevel_h.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/fuse_lowlevel_h.java index 2c3c67de..71596bec 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/fuse_lowlevel_h.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/fuse_lowlevel_h.java @@ -18,11 +18,11 @@ public class fuse_lowlevel_h { public static OfFloat C_FLOAT = Constants$root.C_FLOAT$LAYOUT; public static OfDouble C_DOUBLE = Constants$root.C_DOUBLE$LAYOUT; public static OfAddress C_POINTER = Constants$root.C_POINTER$LAYOUT; - public static MethodHandle fuse_parse_cmdline$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_parse_cmdline$MH,"fuse_parse_cmdline"); + public static MethodHandle fuse_parse_cmdline_312$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_parse_cmdline_312$MH,"fuse_parse_cmdline_312"); } - public static int fuse_parse_cmdline ( Addressable args, Addressable opts) { - var mh$ = fuse_parse_cmdline$MH(); + public static int fuse_parse_cmdline_312 ( Addressable args, Addressable opts) { + var mh$ = fuse_parse_cmdline_312$MH(); try { return (int)mh$.invokeExact(args, opts); } catch (Throwable ex$) { diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/stat_h.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/stat_h.java index ade9b80c..f627067c 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/stat_h.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/stat_h.java @@ -24,15 +24,6 @@ public static long UTIME_NOW() { public static long UTIME_OMIT() { return 1073741822L; } - public static int S_IFDIR() { - return (int)16384L; - } - public static int S_IFREG() { - return (int)32768L; - } - public static int S_IFLNK() { - return (int)40960L; - } } diff --git a/jfuse-linux-amd64/src/test/java/org/cryptomator/jfuse/linux/amd64/FuseImplTest.java b/jfuse-linux-amd64/src/test/java/org/cryptomator/jfuse/linux/amd64/FuseImplTest.java index 590a5155..9a37adf6 100644 --- a/jfuse-linux-amd64/src/test/java/org/cryptomator/jfuse/linux/amd64/FuseImplTest.java +++ b/jfuse-linux-amd64/src/test/java/org/cryptomator/jfuse/linux/amd64/FuseImplTest.java @@ -85,7 +85,7 @@ public void testParseArgsHelp(String arg) { var args = List.of("fusefs", arg); try (var fuseLowlevelH = Mockito.mockStatic(fuse_lowlevel_h.class); var fuseH = Mockito.mockStatic(fuse_h.class)) { - fuseLowlevelH.when(() -> fuse_lowlevel_h.fuse_parse_cmdline(Mockito.any(), Mockito.any())).then(invocation -> { + fuseLowlevelH.when(() -> fuse_lowlevel_h.fuse_parse_cmdline_312(Mockito.any(), Mockito.any())).then(invocation -> { MemorySegment opts = invocation.getArgument(1); fuse_cmdline_opts.show_help$set(opts, 1); return 0; @@ -102,7 +102,7 @@ public void testParseArgsHelp(String arg) { public void testParseArgs() { try (var fuseLowlevelH = Mockito.mockStatic(fuse_lowlevel_h.class); var scope = MemorySession.openConfined()) { - fuseLowlevelH.when(() -> fuse_lowlevel_h.fuse_parse_cmdline(Mockito.any(), Mockito.any())).then(invocation -> { + fuseLowlevelH.when(() -> fuse_lowlevel_h.fuse_parse_cmdline_312(Mockito.any(), Mockito.any())).then(invocation -> { MemorySegment opts = invocation.getArgument(1); fuse_cmdline_opts.singlethread$set(opts, 0); fuse_cmdline_opts.debug$set(opts, 1); diff --git a/libfuse3 b/libfuse3 index 7657ec15..b1290d4c 160000 --- a/libfuse3 +++ b/libfuse3 @@ -1 +1 @@ -Subproject commit 7657ec158becdc59656c59dff40346fefde78cb2 +Subproject commit b1290d4c091a5c590e61a6195e625eab33300673 From 1bb8dcaa3c9bbdacc29528474ecf967cc41670ba Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 4 Oct 2022 14:25:04 +0200 Subject: [PATCH 11/20] support fuse < 3.12 as well --- jfuse-linux-aarch64/pom.xml | 7 +- .../jfuse/linux/aarch64/FuseArgs.java | 2 +- .../jfuse/linux/aarch64/FuseFunctions.java | 42 ++++ .../jfuse/linux/aarch64/FuseImpl.java | 5 +- .../jfuse/linux/aarch64/FuseMountImpl.java | 21 +- .../aarch64/extr}/fuse_cmdline_opts.java | 2 +- ...p_config.java => fuse_loop_config_v1.java} | 26 +- .../linux/aarch64/extr}/fuse_lowlevel_h.java | 13 +- .../linux/aarch64/extr/ll/Constants$root.java | 23 -- .../linux/aarch64/extr/ll/RuntimeHelper.java | 233 ------------------ .../linux/aarch64/extr/ll/constants$0.java | 22 -- .../jfuse/linux/aarch64/FuseImplTest.java | 13 +- jfuse-linux-amd64/pom.xml | 7 +- .../jfuse/linux/amd64/FuseArgs.java | 2 +- .../jfuse/linux/amd64/FuseFunctions.java | 42 ++++ .../jfuse/linux/amd64/FuseImpl.java | 5 +- .../jfuse/linux/amd64/FuseMountImpl.java | 21 +- .../linux/amd64/extr}/fuse_cmdline_opts.java | 2 +- ...p_config.java => fuse_loop_config_v1.java} | 26 +- .../linux/amd64/extr}/fuse_lowlevel_h.java | 13 +- .../linux/amd64/extr/ll/Constants$root.java | 23 -- .../linux/amd64/extr/ll/RuntimeHelper.java | 233 ------------------ .../linux/amd64/extr/ll/constants$0.java | 22 -- .../jfuse/linux/amd64/FuseImplTest.java | 11 +- .../org/cryptomator/jfuse/tests/MirrorIT.java | 13 + 25 files changed, 179 insertions(+), 650 deletions(-) create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseFunctions.java rename {jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll => jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr}/fuse_cmdline_opts.java (99%) rename jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/{fuse_loop_config.java => fuse_loop_config_v1.java} (70%) rename {jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll => jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr}/fuse_lowlevel_h.java (60%) delete mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/Constants$root.java delete mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/RuntimeHelper.java delete mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/constants$0.java create mode 100644 jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseFunctions.java rename {jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll => jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr}/fuse_cmdline_opts.java (99%) rename jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/{fuse_loop_config.java => fuse_loop_config_v1.java} (70%) rename {jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll => jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr}/fuse_lowlevel_h.java (60%) delete mode 100644 jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/Constants$root.java delete mode 100644 jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/RuntimeHelper.java delete mode 100644 jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/constants$0.java diff --git a/jfuse-linux-aarch64/pom.xml b/jfuse-linux-aarch64/pom.xml index 96231d45..b25bc516 100644 --- a/jfuse-linux-aarch64/pom.xml +++ b/jfuse-linux-aarch64/pom.xml @@ -120,7 +120,7 @@ timespec fuse_conn_info fuse_args - fuse_loop_config + fuse_loop_config_v1 @@ -131,15 +131,12 @@ ${project.parent.basedir}/libfuse3/include/fuse_lowlevel.h - org.cryptomator.jfuse.linux.aarch64.extr.ll + org.cryptomator.jfuse.linux.aarch64.extr fuse_lowlevel_h _FILE_OFFSET_BITS=64 FUSE_USE_VERSION=312 - - fuse_parse_cmdline_312 - fuse_cmdline_opts diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseArgs.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseArgs.java index 9d4014e3..458a2f8e 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseArgs.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseArgs.java @@ -1,7 +1,7 @@ package org.cryptomator.jfuse.linux.aarch64; import org.cryptomator.jfuse.linux.aarch64.extr.fuse_args; -import org.cryptomator.jfuse.linux.aarch64.extr.ll.fuse_cmdline_opts; +import org.cryptomator.jfuse.linux.aarch64.extr.fuse_cmdline_opts; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemorySegment; diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseFunctions.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseFunctions.java new file mode 100644 index 00000000..b245e6ba --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseFunctions.java @@ -0,0 +1,42 @@ +package org.cryptomator.jfuse.linux.aarch64; + +import java.lang.foreign.Addressable; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.Linker; +import java.lang.invoke.MethodHandle; + +import static java.lang.foreign.ValueLayout.ADDRESS; +import static java.lang.foreign.ValueLayout.JAVA_INT; + +/** + * These method references can not be jextract'ed, partly due to jextract not being able to understand {@code #define}, + * partly due to slight differences in the FUSE API, which applies a versioning scheme via dlvsym, that Panama's default + * {@link java.lang.foreign.SymbolLookup} doesn't support. + */ +class FuseFunctions { + + // see https://github.com/libfuse/libfuse/blob/fuse-3.12.0/include/fuse_lowlevel.h#L1892-L1923 + private static FunctionDescriptor FUSE_PARSE_CMDLINE = FunctionDescriptor.of(JAVA_INT, ADDRESS, ADDRESS); + + private final MethodHandle fuse_parse_cmdline; + + private FuseFunctions() { + Linker linker = Linker.nativeLinker(); + this.fuse_parse_cmdline = linker.defaultLookup().lookup("fuse_parse_cmdline") + .map(symbol -> linker.downcallHandle(symbol, FUSE_PARSE_CMDLINE)) + .orElseThrow(() -> new UnsatisfiedLinkError("unresolved symbol fuse_parse_cmdline")); + } + + private static class Holder { + private static final FuseFunctions INSTANCE = new FuseFunctions(); + } + + public static int fuse_parse_cmdline( Addressable args, Addressable opts) { + try { + return (int) Holder.INSTANCE.fuse_parse_cmdline.invokeExact(args, opts); + } catch (Throwable e) { + throw new AssertionError("should not reach here", e); + } + } + +} diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseImpl.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseImpl.java index a652fa5b..fa20ca02 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseImpl.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseImpl.java @@ -8,8 +8,7 @@ import org.cryptomator.jfuse.linux.aarch64.extr.fuse_args; import org.cryptomator.jfuse.linux.aarch64.extr.fuse_h; import org.cryptomator.jfuse.linux.aarch64.extr.fuse_operations; -import org.cryptomator.jfuse.linux.aarch64.extr.ll.fuse_cmdline_opts; -import org.cryptomator.jfuse.linux.aarch64.extr.ll.fuse_lowlevel_h; +import org.cryptomator.jfuse.linux.aarch64.extr.fuse_cmdline_opts; import org.cryptomator.jfuse.linux.aarch64.extr.stat_h; import org.cryptomator.jfuse.linux.aarch64.extr.timespec; import org.jetbrains.annotations.VisibleForTesting; @@ -61,7 +60,7 @@ FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { fuse_args.allocated$set(args, 0); var opts = fuse_cmdline_opts.allocate(fuseScope); - int parseResult = fuse_lowlevel_h.fuse_parse_cmdline_312(args, opts); // TODO: support fuse < 3.12 + int parseResult = FuseFunctions.fuse_parse_cmdline(args, opts); if (parseResult != 0) { throw new IllegalArgumentException("fuse_parse_cmdline failed to parse " + String.join(" ", cmdLineArgs)); } diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseMountImpl.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseMountImpl.java index a0ab1503..1b8a95d6 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseMountImpl.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseMountImpl.java @@ -2,7 +2,7 @@ import org.cryptomator.jfuse.api.FuseMount; import org.cryptomator.jfuse.linux.aarch64.extr.fuse_h; -import org.cryptomator.jfuse.linux.aarch64.extr.fuse_loop_config; +import org.cryptomator.jfuse.linux.aarch64.extr.fuse_loop_config_v1; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemorySession; @@ -11,17 +11,28 @@ record FuseMountImpl(MemoryAddress fuse, FuseArgs fuseArgs) implements FuseMount @Override public int loop() { - if (fuseArgs.multithreaded() && fuse_h.fuse_version() > 312) { // TODO: support fuse < 3.12 + // depends on fuse version: https://github.com/libfuse/libfuse/blob/fuse-3.12.0/include/fuse.h#L1011-L1050 + if (!fuseArgs.multithreaded() || fuse_h.fuse_version() < 32) { + // FUSE 3.1: to keep things simple, we just don't support fuse_loop_mt + return fuse_h.fuse_loop(fuse); + } else if (fuse_h.fuse_version() < 312) { + // FUSE 3.2 + try (var scope = MemorySession.openConfined()) { + var loopCfg = fuse_loop_config_v1.allocate(scope); + fuse_loop_config_v1.clone_fd$set(loopCfg, 0); + fuse_loop_config_v1.max_idle_threads$set(loopCfg, 2); + return fuse_h.fuse_loop_mt(fuse, loopCfg); + } + } else { + // FUSE 3.12 var loopCfg = fuse_h.fuse_loop_cfg_create(); try { fuse_h.fuse_loop_cfg_set_clone_fd(loopCfg, 0); - fuse_h.fuse_loop_cfg_set_max_threads (loopCfg, 4); + fuse_h.fuse_loop_cfg_set_max_threads(loopCfg, 4); return fuse_h.fuse_loop_mt(fuse, loopCfg); } finally { fuse_h.fuse_loop_cfg_destroy(loopCfg); } - } else { - return fuse_h.fuse_loop(fuse); } } diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/fuse_cmdline_opts.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_cmdline_opts.java similarity index 99% rename from jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/fuse_cmdline_opts.java rename to jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_cmdline_opts.java index 6d32e716..9199946b 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/fuse_cmdline_opts.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_cmdline_opts.java @@ -1,6 +1,6 @@ // Generated by jextract -package org.cryptomator.jfuse.linux.amd64.extr.ll; +package org.cryptomator.jfuse.linux.aarch64.extr; import java.lang.invoke.MethodHandle; import java.lang.invoke.VarHandle; diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_loop_config.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_loop_config_v1.java similarity index 70% rename from jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_loop_config.java rename to jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_loop_config_v1.java index 1aeb84c4..469a8435 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_loop_config.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_loop_config_v1.java @@ -7,46 +7,46 @@ import java.nio.ByteOrder; import java.lang.foreign.*; import static java.lang.foreign.ValueLayout.*; -public class fuse_loop_config { +public class fuse_loop_config_v1 { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( Constants$root.C_INT$LAYOUT.withName("clone_fd"), Constants$root.C_INT$LAYOUT.withName("max_idle_threads") - ).withName("fuse_loop_config"); + ).withName("fuse_loop_config_v1"); public static MemoryLayout $LAYOUT() { - return fuse_loop_config.$struct$LAYOUT; + return fuse_loop_config_v1.$struct$LAYOUT; } static final VarHandle clone_fd$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("clone_fd")); public static VarHandle clone_fd$VH() { - return fuse_loop_config.clone_fd$VH; + return fuse_loop_config_v1.clone_fd$VH; } public static int clone_fd$get(MemorySegment seg) { - return (int)fuse_loop_config.clone_fd$VH.get(seg); + return (int)fuse_loop_config_v1.clone_fd$VH.get(seg); } public static void clone_fd$set( MemorySegment seg, int x) { - fuse_loop_config.clone_fd$VH.set(seg, x); + fuse_loop_config_v1.clone_fd$VH.set(seg, x); } public static int clone_fd$get(MemorySegment seg, long index) { - return (int)fuse_loop_config.clone_fd$VH.get(seg.asSlice(index*sizeof())); + return (int)fuse_loop_config_v1.clone_fd$VH.get(seg.asSlice(index*sizeof())); } public static void clone_fd$set(MemorySegment seg, long index, int x) { - fuse_loop_config.clone_fd$VH.set(seg.asSlice(index*sizeof()), x); + fuse_loop_config_v1.clone_fd$VH.set(seg.asSlice(index*sizeof()), x); } static final VarHandle max_idle_threads$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max_idle_threads")); public static VarHandle max_idle_threads$VH() { - return fuse_loop_config.max_idle_threads$VH; + return fuse_loop_config_v1.max_idle_threads$VH; } public static int max_idle_threads$get(MemorySegment seg) { - return (int)fuse_loop_config.max_idle_threads$VH.get(seg); + return (int)fuse_loop_config_v1.max_idle_threads$VH.get(seg); } public static void max_idle_threads$set( MemorySegment seg, int x) { - fuse_loop_config.max_idle_threads$VH.set(seg, x); + fuse_loop_config_v1.max_idle_threads$VH.set(seg, x); } public static int max_idle_threads$get(MemorySegment seg, long index) { - return (int)fuse_loop_config.max_idle_threads$VH.get(seg.asSlice(index*sizeof())); + return (int)fuse_loop_config_v1.max_idle_threads$VH.get(seg.asSlice(index*sizeof())); } public static void max_idle_threads$set(MemorySegment seg, long index, int x) { - fuse_loop_config.max_idle_threads$VH.set(seg.asSlice(index*sizeof()), x); + fuse_loop_config_v1.max_idle_threads$VH.set(seg.asSlice(index*sizeof()), x); } public static long sizeof() { return $LAYOUT().byteSize(); } public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/fuse_lowlevel_h.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_lowlevel_h.java similarity index 60% rename from jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/fuse_lowlevel_h.java rename to jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_lowlevel_h.java index 71596bec..a60515de 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/fuse_lowlevel_h.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_lowlevel_h.java @@ -1,6 +1,6 @@ // Generated by jextract -package org.cryptomator.jfuse.linux.amd64.extr.ll; +package org.cryptomator.jfuse.linux.aarch64.extr; import java.lang.invoke.MethodHandle; import java.lang.invoke.VarHandle; @@ -18,17 +18,6 @@ public class fuse_lowlevel_h { public static OfFloat C_FLOAT = Constants$root.C_FLOAT$LAYOUT; public static OfDouble C_DOUBLE = Constants$root.C_DOUBLE$LAYOUT; public static OfAddress C_POINTER = Constants$root.C_POINTER$LAYOUT; - public static MethodHandle fuse_parse_cmdline_312$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_parse_cmdline_312$MH,"fuse_parse_cmdline_312"); - } - public static int fuse_parse_cmdline_312 ( Addressable args, Addressable opts) { - var mh$ = fuse_parse_cmdline_312$MH(); - try { - return (int)mh$.invokeExact(args, opts); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - } } diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/Constants$root.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/Constants$root.java deleted file mode 100644 index 4fc85421..00000000 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/Constants$root.java +++ /dev/null @@ -1,23 +0,0 @@ -// Generated by jextract - -package org.cryptomator.jfuse.linux.aarch64.extr.ll; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.VarHandle; -import java.nio.ByteOrder; -import java.lang.foreign.*; -import static java.lang.foreign.ValueLayout.*; -public class Constants$root { - - static final OfBoolean C_BOOL$LAYOUT = JAVA_BOOLEAN; - static final OfByte C_CHAR$LAYOUT = JAVA_BYTE; - static final OfShort C_SHORT$LAYOUT = JAVA_SHORT.withBitAlignment(16); - static final OfInt C_INT$LAYOUT = JAVA_INT.withBitAlignment(32); - static final OfLong C_LONG$LAYOUT = JAVA_LONG.withBitAlignment(64); - static final OfLong C_LONG_LONG$LAYOUT = JAVA_LONG.withBitAlignment(64); - static final OfFloat C_FLOAT$LAYOUT = JAVA_FLOAT.withBitAlignment(32); - static final OfDouble C_DOUBLE$LAYOUT = JAVA_DOUBLE.withBitAlignment(64); - static final OfAddress C_POINTER$LAYOUT = ADDRESS.withBitAlignment(64); -} - - diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/RuntimeHelper.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/RuntimeHelper.java deleted file mode 100644 index 89a36033..00000000 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/RuntimeHelper.java +++ /dev/null @@ -1,233 +0,0 @@ -package org.cryptomator.jfuse.linux.aarch64.extr.ll; -// Generated by jextract - -import java.lang.foreign.Addressable; -import java.lang.foreign.Linker; -import java.lang.foreign.FunctionDescriptor; -import java.lang.foreign.GroupLayout; -import java.lang.foreign.SymbolLookup; -import java.lang.foreign.MemoryAddress; -import java.lang.foreign.MemoryLayout; -import java.lang.foreign.MemorySegment; -import java.lang.foreign.MemorySession; -import java.lang.foreign.SegmentAllocator; -import java.lang.foreign.ValueLayout; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import java.io.File; -import java.nio.file.Path; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Optional; -import java.util.stream.Stream; - -import static java.lang.foreign.Linker.*; -import static java.lang.foreign.ValueLayout.*; - -final class RuntimeHelper { - - private RuntimeHelper() {} - private final static Linker LINKER = Linker.nativeLinker(); - private final static ClassLoader LOADER = RuntimeHelper.class.getClassLoader(); - private final static MethodHandles.Lookup MH_LOOKUP = MethodHandles.lookup(); - private final static SymbolLookup SYMBOL_LOOKUP; - - final static SegmentAllocator CONSTANT_ALLOCATOR = - (size, align) -> MemorySegment.allocateNative(size, align, MemorySession.openImplicit()); - - static { - - SymbolLookup loaderLookup = SymbolLookup.loaderLookup(); - SYMBOL_LOOKUP = name -> loaderLookup.lookup(name).or(() -> LINKER.defaultLookup().lookup(name)); - } - - static T requireNonNull(T obj, String symbolName) { - if (obj == null) { - throw new UnsatisfiedLinkError("unresolved symbol: " + symbolName); - } - return obj; - } - - private final static SegmentAllocator THROWING_ALLOCATOR = (x, y) -> { throw new AssertionError("should not reach here"); }; - - static final MemorySegment lookupGlobalVariable(String name, MemoryLayout layout) { - return SYMBOL_LOOKUP.lookup(name).map(symbol -> MemorySegment.ofAddress(symbol.address(), layout.byteSize(), MemorySession.openShared())).orElse(null); - } - - static final MethodHandle downcallHandle(String name, FunctionDescriptor fdesc) { - return SYMBOL_LOOKUP.lookup(name). - map(addr -> LINKER.downcallHandle(addr, fdesc)). - orElse(null); - } - - static final MethodHandle downcallHandle(FunctionDescriptor fdesc) { - return LINKER.downcallHandle(fdesc); - } - - static final MethodHandle downcallHandleVariadic(String name, FunctionDescriptor fdesc) { - return SYMBOL_LOOKUP.lookup(name). - map(addr -> VarargsInvoker.make(addr, fdesc)). - orElse(null); - } - - static final MemorySegment upcallStub(Class fi, Z z, FunctionDescriptor fdesc, MemorySession session) { - try { - MethodHandle handle = MH_LOOKUP.findVirtual(fi, "apply", Linker.upcallType(fdesc)); - handle = handle.bindTo(z); - return LINKER.upcallStub(handle, fdesc, session); - } catch (Throwable ex) { - throw new AssertionError(ex); - } - } - - static MemorySegment asArray(MemoryAddress addr, MemoryLayout layout, int numElements, MemorySession session) { - return MemorySegment.ofAddress(addr, numElements * layout.byteSize(), session); - } - - // Internals only below this point - - private static class VarargsInvoker { - private static final MethodHandle INVOKE_MH; - private final MemorySegment symbol; - private final FunctionDescriptor function; - - private VarargsInvoker(MemorySegment symbol, FunctionDescriptor function) { - this.symbol = symbol; - this.function = function; - } - - static { - try { - INVOKE_MH = MethodHandles.lookup().findVirtual(VarargsInvoker.class, "invoke", MethodType.methodType(Object.class, SegmentAllocator.class, Object[].class)); - } catch (ReflectiveOperationException e) { - throw new RuntimeException(e); - } - } - - static MethodHandle make(MemorySegment symbol, FunctionDescriptor function) { - VarargsInvoker invoker = new VarargsInvoker(symbol, function); - MethodHandle handle = INVOKE_MH.bindTo(invoker).asCollector(Object[].class, function.argumentLayouts().size() + 1); - MethodType mtype = MethodType.methodType(function.returnLayout().isPresent() ? carrier(function.returnLayout().get(), true) : void.class); - for (MemoryLayout layout : function.argumentLayouts()) { - mtype = mtype.appendParameterTypes(carrier(layout, false)); - } - mtype = mtype.appendParameterTypes(Object[].class); - if (mtype.returnType().equals(MemorySegment.class)) { - mtype = mtype.insertParameterTypes(0, SegmentAllocator.class); - } else { - handle = MethodHandles.insertArguments(handle, 0, THROWING_ALLOCATOR); - } - return handle.asType(mtype); - } - - static Class carrier(MemoryLayout layout, boolean ret) { - if (layout instanceof ValueLayout valueLayout) { - return (ret || valueLayout.carrier() != MemoryAddress.class) ? - valueLayout.carrier() : Addressable.class; - } else if (layout instanceof GroupLayout) { - return MemorySegment.class; - } else { - throw new AssertionError("Cannot get here!"); - } - } - - private Object invoke(SegmentAllocator allocator, Object[] args) throws Throwable { - // one trailing Object[] - int nNamedArgs = function.argumentLayouts().size(); - assert(args.length == nNamedArgs + 1); - // The last argument is the array of vararg collector - Object[] unnamedArgs = (Object[]) args[args.length - 1]; - - int argsCount = nNamedArgs + unnamedArgs.length; - Class[] argTypes = new Class[argsCount]; - MemoryLayout[] argLayouts = new MemoryLayout[nNamedArgs + unnamedArgs.length]; - - int pos = 0; - for (pos = 0; pos < nNamedArgs; pos++) { - argLayouts[pos] = function.argumentLayouts().get(pos); - } - - assert pos == nNamedArgs; - for (Object o: unnamedArgs) { - argLayouts[pos] = variadicLayout(normalize(o.getClass())); - pos++; - } - assert pos == argsCount; - - FunctionDescriptor f = (function.returnLayout().isEmpty()) ? - FunctionDescriptor.ofVoid(argLayouts) : - FunctionDescriptor.of(function.returnLayout().get(), argLayouts); - MethodHandle mh = LINKER.downcallHandle(symbol, f); - if (mh.type().returnType() == MemorySegment.class) { - mh = mh.bindTo(allocator); - } - // flatten argument list so that it can be passed to an asSpreader MH - Object[] allArgs = new Object[nNamedArgs + unnamedArgs.length]; - System.arraycopy(args, 0, allArgs, 0, nNamedArgs); - System.arraycopy(unnamedArgs, 0, allArgs, nNamedArgs, unnamedArgs.length); - - return mh.asSpreader(Object[].class, argsCount).invoke(allArgs); - } - - private static Class unboxIfNeeded(Class clazz) { - if (clazz == Boolean.class) { - return boolean.class; - } else if (clazz == Void.class) { - return void.class; - } else if (clazz == Byte.class) { - return byte.class; - } else if (clazz == Character.class) { - return char.class; - } else if (clazz == Short.class) { - return short.class; - } else if (clazz == Integer.class) { - return int.class; - } else if (clazz == Long.class) { - return long.class; - } else if (clazz == Float.class) { - return float.class; - } else if (clazz == Double.class) { - return double.class; - } else { - return clazz; - } - } - - private Class promote(Class c) { - if (c == byte.class || c == char.class || c == short.class || c == int.class) { - return long.class; - } else if (c == float.class) { - return double.class; - } else { - return c; - } - } - - private Class normalize(Class c) { - c = unboxIfNeeded(c); - if (c.isPrimitive()) { - return promote(c); - } - if (MemoryAddress.class.isAssignableFrom(c)) { - return MemoryAddress.class; - } - if (MemorySegment.class.isAssignableFrom(c)) { - return MemorySegment.class; - } - throw new IllegalArgumentException("Invalid type for ABI: " + c.getTypeName()); - } - - private MemoryLayout variadicLayout(Class c) { - if (c == long.class) { - return JAVA_LONG; - } else if (c == double.class) { - return JAVA_DOUBLE; - } else if (MemoryAddress.class.isAssignableFrom(c)) { - return ADDRESS; - } else { - throw new IllegalArgumentException("Unhandled variadic argument class: " + c); - } - } - } -} diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/constants$0.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/constants$0.java deleted file mode 100644 index c422c085..00000000 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/constants$0.java +++ /dev/null @@ -1,22 +0,0 @@ -// Generated by jextract - -package org.cryptomator.jfuse.linux.aarch64.extr.ll; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.VarHandle; -import java.nio.ByteOrder; -import java.lang.foreign.*; -import static java.lang.foreign.ValueLayout.*; -class constants$0 { - - static final FunctionDescriptor fuse_parse_cmdline_312$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle fuse_parse_cmdline_312$MH = RuntimeHelper.downcallHandle( - "fuse_parse_cmdline_312", - constants$0.fuse_parse_cmdline_312$FUNC - ); -} - - diff --git a/jfuse-linux-aarch64/src/test/java/org/cryptomator/jfuse/linux/aarch64/FuseImplTest.java b/jfuse-linux-aarch64/src/test/java/org/cryptomator/jfuse/linux/aarch64/FuseImplTest.java index 92274e81..120d36ee 100644 --- a/jfuse-linux-aarch64/src/test/java/org/cryptomator/jfuse/linux/aarch64/FuseImplTest.java +++ b/jfuse-linux-aarch64/src/test/java/org/cryptomator/jfuse/linux/aarch64/FuseImplTest.java @@ -4,11 +4,10 @@ import org.cryptomator.jfuse.api.FuseOperations; import org.cryptomator.jfuse.api.MountFailedException; import org.cryptomator.jfuse.api.TimeSpec; +import org.cryptomator.jfuse.linux.aarch64.extr.fuse_cmdline_opts; import org.cryptomator.jfuse.linux.aarch64.extr.fuse_conn_info; import org.cryptomator.jfuse.linux.aarch64.extr.fuse_file_info; import org.cryptomator.jfuse.linux.aarch64.extr.fuse_h; -import org.cryptomator.jfuse.linux.aarch64.extr.ll.fuse_cmdline_opts; -import org.cryptomator.jfuse.linux.aarch64.extr.ll.fuse_lowlevel_h; import org.cryptomator.jfuse.linux.aarch64.extr.timespec; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -20,10 +19,8 @@ import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.ValueSource; import org.mockito.Answers; -import org.mockito.Mock; import org.mockito.MockedStatic; import org.mockito.Mockito; -import org.mockito.verification.VerificationMode; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemorySegment; @@ -85,9 +82,9 @@ public void testFuseMountFails() { @ValueSource(strings = {"--help", "-h"}) public void testParseArgsHelp(String arg) { var args = List.of("fusefs", arg); - try (var fuseLowlevelH = Mockito.mockStatic(fuse_lowlevel_h.class); + try (var fuseFunctionsClass = Mockito.mockStatic(FuseFunctions.class); var fuseH = Mockito.mockStatic(fuse_h.class)) { - fuseLowlevelH.when(() -> fuse_lowlevel_h.fuse_parse_cmdline_312(Mockito.any(), Mockito.any())).then(invocation -> { + fuseFunctionsClass.when(() -> FuseFunctions.fuse_parse_cmdline(Mockito.any(), Mockito.any())).then(invocation -> { MemorySegment opts = invocation.getArgument(1); fuse_cmdline_opts.show_help$set(opts, 1); return 0; @@ -102,9 +99,9 @@ public void testParseArgsHelp(String arg) { @Test @DisplayName("parseArgs") public void testParseArgs() { - try (var fuseLowlevelH = Mockito.mockStatic(fuse_lowlevel_h.class); + try (var fuseFunctionsClass = Mockito.mockStatic(FuseFunctions.class); var scope = MemorySession.openConfined()) { - fuseLowlevelH.when(() -> fuse_lowlevel_h.fuse_parse_cmdline_312(Mockito.any(), Mockito.any())).then(invocation -> { + fuseFunctionsClass.when(() -> FuseFunctions.fuse_parse_cmdline(Mockito.any(), Mockito.any())).then(invocation -> { MemorySegment opts = invocation.getArgument(1); fuse_cmdline_opts.singlethread$set(opts, 0); fuse_cmdline_opts.debug$set(opts, 1); diff --git a/jfuse-linux-amd64/pom.xml b/jfuse-linux-amd64/pom.xml index 82945200..f30d0fa8 100644 --- a/jfuse-linux-amd64/pom.xml +++ b/jfuse-linux-amd64/pom.xml @@ -120,7 +120,7 @@ timespec fuse_conn_info fuse_args - fuse_loop_config + fuse_loop_config_v1 @@ -131,15 +131,12 @@ ${project.parent.basedir}/libfuse3/include/fuse_lowlevel.h - org.cryptomator.jfuse.linux.amd64.extr.ll + org.cryptomator.jfuse.linux.amd64.extr fuse_lowlevel_h _FILE_OFFSET_BITS=64 FUSE_USE_VERSION=312 - - fuse_parse_cmdline_312 - fuse_cmdline_opts diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseArgs.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseArgs.java index 4c7c5099..d6a06dbe 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseArgs.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseArgs.java @@ -1,7 +1,7 @@ package org.cryptomator.jfuse.linux.amd64; import org.cryptomator.jfuse.linux.amd64.extr.fuse_args; -import org.cryptomator.jfuse.linux.amd64.extr.ll.fuse_cmdline_opts; +import org.cryptomator.jfuse.linux.amd64.extr.fuse_cmdline_opts; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemorySegment; diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseFunctions.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseFunctions.java new file mode 100644 index 00000000..d2cb808b --- /dev/null +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseFunctions.java @@ -0,0 +1,42 @@ +package org.cryptomator.jfuse.linux.amd64; + +import java.lang.foreign.Addressable; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.Linker; +import java.lang.invoke.MethodHandle; + +import static java.lang.foreign.ValueLayout.ADDRESS; +import static java.lang.foreign.ValueLayout.JAVA_INT; + +/** + * These method references can not be jextract'ed, partly due to jextract not being able to understand {@code #define}, + * partly due to slight differences in the FUSE API, which applies a versioning scheme via dlvsym, that Panama's default + * {@link java.lang.foreign.SymbolLookup} doesn't support. + */ +class FuseFunctions { + + // see https://github.com/libfuse/libfuse/blob/fuse-3.12.0/include/fuse_lowlevel.h#L1892-L1923 + private static FunctionDescriptor FUSE_PARSE_CMDLINE = FunctionDescriptor.of(JAVA_INT, ADDRESS, ADDRESS); + + private final MethodHandle fuse_parse_cmdline; + + private FuseFunctions() { + Linker linker = Linker.nativeLinker(); + this.fuse_parse_cmdline = linker.defaultLookup().lookup("fuse_parse_cmdline") + .map(symbol -> linker.downcallHandle(symbol, FUSE_PARSE_CMDLINE)) + .orElseThrow(() -> new UnsatisfiedLinkError("unresolved symbol fuse_parse_cmdline")); + } + + private static class Holder { + private static final FuseFunctions INSTANCE = new FuseFunctions(); + } + + public static int fuse_parse_cmdline( Addressable args, Addressable opts) { + try { + return (int) Holder.INSTANCE.fuse_parse_cmdline.invokeExact(args, opts); + } catch (Throwable e) { + throw new AssertionError("should not reach here", e); + } + } + +} diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseImpl.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseImpl.java index 5f0e47cb..44927cef 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseImpl.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseImpl.java @@ -8,8 +8,7 @@ import org.cryptomator.jfuse.linux.amd64.extr.fuse_args; import org.cryptomator.jfuse.linux.amd64.extr.fuse_h; import org.cryptomator.jfuse.linux.amd64.extr.fuse_operations; -import org.cryptomator.jfuse.linux.amd64.extr.ll.fuse_cmdline_opts; -import org.cryptomator.jfuse.linux.amd64.extr.ll.fuse_lowlevel_h; +import org.cryptomator.jfuse.linux.amd64.extr.fuse_cmdline_opts; import org.cryptomator.jfuse.linux.amd64.extr.stat_h; import org.cryptomator.jfuse.linux.amd64.extr.timespec; import org.jetbrains.annotations.VisibleForTesting; @@ -61,7 +60,7 @@ FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { fuse_args.allocated$set(args, 0); var opts = fuse_cmdline_opts.allocate(fuseScope); - int parseResult = fuse_lowlevel_h.fuse_parse_cmdline_312(args, opts); // TODO: support fuse < 3.12 + int parseResult = FuseFunctions.fuse_parse_cmdline(args, opts); if (parseResult != 0) { throw new IllegalArgumentException("fuse_parse_cmdline failed to parse " + String.join(" ", cmdLineArgs)); } diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseMountImpl.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseMountImpl.java index e1b07b7c..58bd8cac 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseMountImpl.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseMountImpl.java @@ -2,7 +2,7 @@ import org.cryptomator.jfuse.api.FuseMount; import org.cryptomator.jfuse.linux.amd64.extr.fuse_h; -import org.cryptomator.jfuse.linux.amd64.extr.fuse_loop_config; +import org.cryptomator.jfuse.linux.amd64.extr.fuse_loop_config_v1; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemorySession; @@ -11,17 +11,28 @@ record FuseMountImpl(MemoryAddress fuse, FuseArgs fuseArgs) implements FuseMount @Override public int loop() { - if (fuseArgs.multithreaded() && fuse_h.fuse_version() > 312) { // TODO: support fuse < 3.12 + // depends on fuse version: https://github.com/libfuse/libfuse/blob/fuse-3.12.0/include/fuse.h#L1011-L1050 + if (!fuseArgs.multithreaded() || fuse_h.fuse_version() < 32) { + // FUSE 3.1: to keep things simple, we just don't support fuse_loop_mt + return fuse_h.fuse_loop(fuse); + } else if (fuse_h.fuse_version() < 312) { + // FUSE 3.2 + try (var scope = MemorySession.openConfined()) { + var loopCfg = fuse_loop_config_v1.allocate(scope); + fuse_loop_config_v1.clone_fd$set(loopCfg, 0); + fuse_loop_config_v1.max_idle_threads$set(loopCfg, 2); + return fuse_h.fuse_loop_mt(fuse, loopCfg); + } + } else { + // FUSE 3.12 var loopCfg = fuse_h.fuse_loop_cfg_create(); try { fuse_h.fuse_loop_cfg_set_clone_fd(loopCfg, 0); - fuse_h.fuse_loop_cfg_set_max_threads (loopCfg, 4); + fuse_h.fuse_loop_cfg_set_max_threads(loopCfg, 4); return fuse_h.fuse_loop_mt(fuse, loopCfg); } finally { fuse_h.fuse_loop_cfg_destroy(loopCfg); } - } else { - return fuse_h.fuse_loop(fuse); } } diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/fuse_cmdline_opts.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_cmdline_opts.java similarity index 99% rename from jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/fuse_cmdline_opts.java rename to jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_cmdline_opts.java index 39aba077..7e8155a8 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/fuse_cmdline_opts.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_cmdline_opts.java @@ -1,6 +1,6 @@ // Generated by jextract -package org.cryptomator.jfuse.linux.aarch64.extr.ll; +package org.cryptomator.jfuse.linux.amd64.extr; import java.lang.invoke.MethodHandle; import java.lang.invoke.VarHandle; diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_loop_config.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_loop_config_v1.java similarity index 70% rename from jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_loop_config.java rename to jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_loop_config_v1.java index 093a4f0d..02f3b7ed 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_loop_config.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_loop_config_v1.java @@ -7,46 +7,46 @@ import java.nio.ByteOrder; import java.lang.foreign.*; import static java.lang.foreign.ValueLayout.*; -public class fuse_loop_config { +public class fuse_loop_config_v1 { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( Constants$root.C_INT$LAYOUT.withName("clone_fd"), Constants$root.C_INT$LAYOUT.withName("max_idle_threads") - ).withName("fuse_loop_config"); + ).withName("fuse_loop_config_v1"); public static MemoryLayout $LAYOUT() { - return fuse_loop_config.$struct$LAYOUT; + return fuse_loop_config_v1.$struct$LAYOUT; } static final VarHandle clone_fd$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("clone_fd")); public static VarHandle clone_fd$VH() { - return fuse_loop_config.clone_fd$VH; + return fuse_loop_config_v1.clone_fd$VH; } public static int clone_fd$get(MemorySegment seg) { - return (int)fuse_loop_config.clone_fd$VH.get(seg); + return (int)fuse_loop_config_v1.clone_fd$VH.get(seg); } public static void clone_fd$set( MemorySegment seg, int x) { - fuse_loop_config.clone_fd$VH.set(seg, x); + fuse_loop_config_v1.clone_fd$VH.set(seg, x); } public static int clone_fd$get(MemorySegment seg, long index) { - return (int)fuse_loop_config.clone_fd$VH.get(seg.asSlice(index*sizeof())); + return (int)fuse_loop_config_v1.clone_fd$VH.get(seg.asSlice(index*sizeof())); } public static void clone_fd$set(MemorySegment seg, long index, int x) { - fuse_loop_config.clone_fd$VH.set(seg.asSlice(index*sizeof()), x); + fuse_loop_config_v1.clone_fd$VH.set(seg.asSlice(index*sizeof()), x); } static final VarHandle max_idle_threads$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max_idle_threads")); public static VarHandle max_idle_threads$VH() { - return fuse_loop_config.max_idle_threads$VH; + return fuse_loop_config_v1.max_idle_threads$VH; } public static int max_idle_threads$get(MemorySegment seg) { - return (int)fuse_loop_config.max_idle_threads$VH.get(seg); + return (int)fuse_loop_config_v1.max_idle_threads$VH.get(seg); } public static void max_idle_threads$set( MemorySegment seg, int x) { - fuse_loop_config.max_idle_threads$VH.set(seg, x); + fuse_loop_config_v1.max_idle_threads$VH.set(seg, x); } public static int max_idle_threads$get(MemorySegment seg, long index) { - return (int)fuse_loop_config.max_idle_threads$VH.get(seg.asSlice(index*sizeof())); + return (int)fuse_loop_config_v1.max_idle_threads$VH.get(seg.asSlice(index*sizeof())); } public static void max_idle_threads$set(MemorySegment seg, long index, int x) { - fuse_loop_config.max_idle_threads$VH.set(seg.asSlice(index*sizeof()), x); + fuse_loop_config_v1.max_idle_threads$VH.set(seg.asSlice(index*sizeof()), x); } public static long sizeof() { return $LAYOUT().byteSize(); } public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/fuse_lowlevel_h.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_lowlevel_h.java similarity index 60% rename from jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/fuse_lowlevel_h.java rename to jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_lowlevel_h.java index 07057767..5eb7c15a 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/fuse_lowlevel_h.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_lowlevel_h.java @@ -1,6 +1,6 @@ // Generated by jextract -package org.cryptomator.jfuse.linux.aarch64.extr.ll; +package org.cryptomator.jfuse.linux.amd64.extr; import java.lang.invoke.MethodHandle; import java.lang.invoke.VarHandle; @@ -18,17 +18,6 @@ public class fuse_lowlevel_h { public static OfFloat C_FLOAT = Constants$root.C_FLOAT$LAYOUT; public static OfDouble C_DOUBLE = Constants$root.C_DOUBLE$LAYOUT; public static OfAddress C_POINTER = Constants$root.C_POINTER$LAYOUT; - public static MethodHandle fuse_parse_cmdline_312$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_parse_cmdline_312$MH,"fuse_parse_cmdline_312"); - } - public static int fuse_parse_cmdline_312 ( Addressable args, Addressable opts) { - var mh$ = fuse_parse_cmdline_312$MH(); - try { - return (int)mh$.invokeExact(args, opts); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - } } diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/Constants$root.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/Constants$root.java deleted file mode 100644 index 1985592f..00000000 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/Constants$root.java +++ /dev/null @@ -1,23 +0,0 @@ -// Generated by jextract - -package org.cryptomator.jfuse.linux.amd64.extr.ll; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.VarHandle; -import java.nio.ByteOrder; -import java.lang.foreign.*; -import static java.lang.foreign.ValueLayout.*; -public class Constants$root { - - static final OfBoolean C_BOOL$LAYOUT = JAVA_BOOLEAN; - static final OfByte C_CHAR$LAYOUT = JAVA_BYTE; - static final OfShort C_SHORT$LAYOUT = JAVA_SHORT.withBitAlignment(16); - static final OfInt C_INT$LAYOUT = JAVA_INT.withBitAlignment(32); - static final OfLong C_LONG$LAYOUT = JAVA_LONG.withBitAlignment(64); - static final OfLong C_LONG_LONG$LAYOUT = JAVA_LONG.withBitAlignment(64); - static final OfFloat C_FLOAT$LAYOUT = JAVA_FLOAT.withBitAlignment(32); - static final OfDouble C_DOUBLE$LAYOUT = JAVA_DOUBLE.withBitAlignment(64); - static final OfAddress C_POINTER$LAYOUT = ADDRESS.withBitAlignment(64); -} - - diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/RuntimeHelper.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/RuntimeHelper.java deleted file mode 100644 index 626b76e3..00000000 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/RuntimeHelper.java +++ /dev/null @@ -1,233 +0,0 @@ -package org.cryptomator.jfuse.linux.amd64.extr.ll; -// Generated by jextract - -import java.lang.foreign.Addressable; -import java.lang.foreign.Linker; -import java.lang.foreign.FunctionDescriptor; -import java.lang.foreign.GroupLayout; -import java.lang.foreign.SymbolLookup; -import java.lang.foreign.MemoryAddress; -import java.lang.foreign.MemoryLayout; -import java.lang.foreign.MemorySegment; -import java.lang.foreign.MemorySession; -import java.lang.foreign.SegmentAllocator; -import java.lang.foreign.ValueLayout; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import java.io.File; -import java.nio.file.Path; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Optional; -import java.util.stream.Stream; - -import static java.lang.foreign.Linker.*; -import static java.lang.foreign.ValueLayout.*; - -final class RuntimeHelper { - - private RuntimeHelper() {} - private final static Linker LINKER = Linker.nativeLinker(); - private final static ClassLoader LOADER = RuntimeHelper.class.getClassLoader(); - private final static MethodHandles.Lookup MH_LOOKUP = MethodHandles.lookup(); - private final static SymbolLookup SYMBOL_LOOKUP; - - final static SegmentAllocator CONSTANT_ALLOCATOR = - (size, align) -> MemorySegment.allocateNative(size, align, MemorySession.openImplicit()); - - static { - - SymbolLookup loaderLookup = SymbolLookup.loaderLookup(); - SYMBOL_LOOKUP = name -> loaderLookup.lookup(name).or(() -> LINKER.defaultLookup().lookup(name)); - } - - static T requireNonNull(T obj, String symbolName) { - if (obj == null) { - throw new UnsatisfiedLinkError("unresolved symbol: " + symbolName); - } - return obj; - } - - private final static SegmentAllocator THROWING_ALLOCATOR = (x, y) -> { throw new AssertionError("should not reach here"); }; - - static final MemorySegment lookupGlobalVariable(String name, MemoryLayout layout) { - return SYMBOL_LOOKUP.lookup(name).map(symbol -> MemorySegment.ofAddress(symbol.address(), layout.byteSize(), MemorySession.openShared())).orElse(null); - } - - static final MethodHandle downcallHandle(String name, FunctionDescriptor fdesc) { - return SYMBOL_LOOKUP.lookup(name). - map(addr -> LINKER.downcallHandle(addr, fdesc)). - orElse(null); - } - - static final MethodHandle downcallHandle(FunctionDescriptor fdesc) { - return LINKER.downcallHandle(fdesc); - } - - static final MethodHandle downcallHandleVariadic(String name, FunctionDescriptor fdesc) { - return SYMBOL_LOOKUP.lookup(name). - map(addr -> VarargsInvoker.make(addr, fdesc)). - orElse(null); - } - - static final MemorySegment upcallStub(Class fi, Z z, FunctionDescriptor fdesc, MemorySession session) { - try { - MethodHandle handle = MH_LOOKUP.findVirtual(fi, "apply", Linker.upcallType(fdesc)); - handle = handle.bindTo(z); - return LINKER.upcallStub(handle, fdesc, session); - } catch (Throwable ex) { - throw new AssertionError(ex); - } - } - - static MemorySegment asArray(MemoryAddress addr, MemoryLayout layout, int numElements, MemorySession session) { - return MemorySegment.ofAddress(addr, numElements * layout.byteSize(), session); - } - - // Internals only below this point - - private static class VarargsInvoker { - private static final MethodHandle INVOKE_MH; - private final MemorySegment symbol; - private final FunctionDescriptor function; - - private VarargsInvoker(MemorySegment symbol, FunctionDescriptor function) { - this.symbol = symbol; - this.function = function; - } - - static { - try { - INVOKE_MH = MethodHandles.lookup().findVirtual(VarargsInvoker.class, "invoke", MethodType.methodType(Object.class, SegmentAllocator.class, Object[].class)); - } catch (ReflectiveOperationException e) { - throw new RuntimeException(e); - } - } - - static MethodHandle make(MemorySegment symbol, FunctionDescriptor function) { - VarargsInvoker invoker = new VarargsInvoker(symbol, function); - MethodHandle handle = INVOKE_MH.bindTo(invoker).asCollector(Object[].class, function.argumentLayouts().size() + 1); - MethodType mtype = MethodType.methodType(function.returnLayout().isPresent() ? carrier(function.returnLayout().get(), true) : void.class); - for (MemoryLayout layout : function.argumentLayouts()) { - mtype = mtype.appendParameterTypes(carrier(layout, false)); - } - mtype = mtype.appendParameterTypes(Object[].class); - if (mtype.returnType().equals(MemorySegment.class)) { - mtype = mtype.insertParameterTypes(0, SegmentAllocator.class); - } else { - handle = MethodHandles.insertArguments(handle, 0, THROWING_ALLOCATOR); - } - return handle.asType(mtype); - } - - static Class carrier(MemoryLayout layout, boolean ret) { - if (layout instanceof ValueLayout valueLayout) { - return (ret || valueLayout.carrier() != MemoryAddress.class) ? - valueLayout.carrier() : Addressable.class; - } else if (layout instanceof GroupLayout) { - return MemorySegment.class; - } else { - throw new AssertionError("Cannot get here!"); - } - } - - private Object invoke(SegmentAllocator allocator, Object[] args) throws Throwable { - // one trailing Object[] - int nNamedArgs = function.argumentLayouts().size(); - assert(args.length == nNamedArgs + 1); - // The last argument is the array of vararg collector - Object[] unnamedArgs = (Object[]) args[args.length - 1]; - - int argsCount = nNamedArgs + unnamedArgs.length; - Class[] argTypes = new Class[argsCount]; - MemoryLayout[] argLayouts = new MemoryLayout[nNamedArgs + unnamedArgs.length]; - - int pos = 0; - for (pos = 0; pos < nNamedArgs; pos++) { - argLayouts[pos] = function.argumentLayouts().get(pos); - } - - assert pos == nNamedArgs; - for (Object o: unnamedArgs) { - argLayouts[pos] = variadicLayout(normalize(o.getClass())); - pos++; - } - assert pos == argsCount; - - FunctionDescriptor f = (function.returnLayout().isEmpty()) ? - FunctionDescriptor.ofVoid(argLayouts) : - FunctionDescriptor.of(function.returnLayout().get(), argLayouts); - MethodHandle mh = LINKER.downcallHandle(symbol, f); - if (mh.type().returnType() == MemorySegment.class) { - mh = mh.bindTo(allocator); - } - // flatten argument list so that it can be passed to an asSpreader MH - Object[] allArgs = new Object[nNamedArgs + unnamedArgs.length]; - System.arraycopy(args, 0, allArgs, 0, nNamedArgs); - System.arraycopy(unnamedArgs, 0, allArgs, nNamedArgs, unnamedArgs.length); - - return mh.asSpreader(Object[].class, argsCount).invoke(allArgs); - } - - private static Class unboxIfNeeded(Class clazz) { - if (clazz == Boolean.class) { - return boolean.class; - } else if (clazz == Void.class) { - return void.class; - } else if (clazz == Byte.class) { - return byte.class; - } else if (clazz == Character.class) { - return char.class; - } else if (clazz == Short.class) { - return short.class; - } else if (clazz == Integer.class) { - return int.class; - } else if (clazz == Long.class) { - return long.class; - } else if (clazz == Float.class) { - return float.class; - } else if (clazz == Double.class) { - return double.class; - } else { - return clazz; - } - } - - private Class promote(Class c) { - if (c == byte.class || c == char.class || c == short.class || c == int.class) { - return long.class; - } else if (c == float.class) { - return double.class; - } else { - return c; - } - } - - private Class normalize(Class c) { - c = unboxIfNeeded(c); - if (c.isPrimitive()) { - return promote(c); - } - if (MemoryAddress.class.isAssignableFrom(c)) { - return MemoryAddress.class; - } - if (MemorySegment.class.isAssignableFrom(c)) { - return MemorySegment.class; - } - throw new IllegalArgumentException("Invalid type for ABI: " + c.getTypeName()); - } - - private MemoryLayout variadicLayout(Class c) { - if (c == long.class) { - return JAVA_LONG; - } else if (c == double.class) { - return JAVA_DOUBLE; - } else if (MemoryAddress.class.isAssignableFrom(c)) { - return ADDRESS; - } else { - throw new IllegalArgumentException("Unhandled variadic argument class: " + c); - } - } - } -} diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/constants$0.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/constants$0.java deleted file mode 100644 index 8cd11801..00000000 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/constants$0.java +++ /dev/null @@ -1,22 +0,0 @@ -// Generated by jextract - -package org.cryptomator.jfuse.linux.amd64.extr.ll; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.VarHandle; -import java.nio.ByteOrder; -import java.lang.foreign.*; -import static java.lang.foreign.ValueLayout.*; -class constants$0 { - - static final FunctionDescriptor fuse_parse_cmdline_312$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle fuse_parse_cmdline_312$MH = RuntimeHelper.downcallHandle( - "fuse_parse_cmdline_312", - constants$0.fuse_parse_cmdline_312$FUNC - ); -} - - diff --git a/jfuse-linux-amd64/src/test/java/org/cryptomator/jfuse/linux/amd64/FuseImplTest.java b/jfuse-linux-amd64/src/test/java/org/cryptomator/jfuse/linux/amd64/FuseImplTest.java index 9a37adf6..bf14492c 100644 --- a/jfuse-linux-amd64/src/test/java/org/cryptomator/jfuse/linux/amd64/FuseImplTest.java +++ b/jfuse-linux-amd64/src/test/java/org/cryptomator/jfuse/linux/amd64/FuseImplTest.java @@ -4,11 +4,10 @@ import org.cryptomator.jfuse.api.FuseOperations; import org.cryptomator.jfuse.api.MountFailedException; import org.cryptomator.jfuse.api.TimeSpec; +import org.cryptomator.jfuse.linux.amd64.extr.fuse_cmdline_opts; import org.cryptomator.jfuse.linux.amd64.extr.fuse_conn_info; import org.cryptomator.jfuse.linux.amd64.extr.fuse_file_info; import org.cryptomator.jfuse.linux.amd64.extr.fuse_h; -import org.cryptomator.jfuse.linux.amd64.extr.ll.fuse_cmdline_opts; -import org.cryptomator.jfuse.linux.amd64.extr.ll.fuse_lowlevel_h; import org.cryptomator.jfuse.linux.amd64.extr.timespec; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -83,9 +82,9 @@ public void testFuseMountFails() { @ValueSource(strings = {"--help", "-h"}) public void testParseArgsHelp(String arg) { var args = List.of("fusefs", arg); - try (var fuseLowlevelH = Mockito.mockStatic(fuse_lowlevel_h.class); + try (var fuseFunctionsClass = Mockito.mockStatic(FuseFunctions.class); var fuseH = Mockito.mockStatic(fuse_h.class)) { - fuseLowlevelH.when(() -> fuse_lowlevel_h.fuse_parse_cmdline_312(Mockito.any(), Mockito.any())).then(invocation -> { + fuseFunctionsClass.when(() -> FuseFunctions.fuse_parse_cmdline(Mockito.any(), Mockito.any())).then(invocation -> { MemorySegment opts = invocation.getArgument(1); fuse_cmdline_opts.show_help$set(opts, 1); return 0; @@ -100,9 +99,9 @@ public void testParseArgsHelp(String arg) { @Test @DisplayName("parseArgs") public void testParseArgs() { - try (var fuseLowlevelH = Mockito.mockStatic(fuse_lowlevel_h.class); + try (var fuseFunctionsClass = Mockito.mockStatic(FuseFunctions.class); var scope = MemorySession.openConfined()) { - fuseLowlevelH.when(() -> fuse_lowlevel_h.fuse_parse_cmdline_312(Mockito.any(), Mockito.any())).then(invocation -> { + fuseFunctionsClass.when(() -> FuseFunctions.fuse_parse_cmdline(Mockito.any(), Mockito.any())).then(invocation -> { MemorySegment opts = invocation.getArgument(1); fuse_cmdline_opts.singlethread$set(opts, 0); fuse_cmdline_opts.debug$set(opts, 1); diff --git a/jfuse-tests/src/test/java/org/cryptomator/jfuse/tests/MirrorIT.java b/jfuse-tests/src/test/java/org/cryptomator/jfuse/tests/MirrorIT.java index 2484dda6..cdcce2cc 100644 --- a/jfuse-tests/src/test/java/org/cryptomator/jfuse/tests/MirrorIT.java +++ b/jfuse-tests/src/test/java/org/cryptomator/jfuse/tests/MirrorIT.java @@ -1,6 +1,7 @@ package org.cryptomator.jfuse.tests; import org.cryptomator.jfuse.api.Fuse; +import org.cryptomator.jfuse.api.FuseBuilder; import org.cryptomator.jfuse.api.MountFailedException; import org.cryptomator.jfuse.examples.AbstractMirrorFileSystem; import org.cryptomator.jfuse.examples.PosixMirrorFileSystem; @@ -16,6 +17,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.condition.EnabledIf; import org.junit.jupiter.api.condition.OS; import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.ParameterizedTest; @@ -32,6 +34,7 @@ import java.util.List; import java.util.concurrent.TimeUnit; +@EnabledIf("hasSupportedImplementation") @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class MirrorIT { @@ -39,6 +42,16 @@ public class MirrorIT { System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "TRACE"); } + // skip integration tests, if no implementation is available + static boolean hasSupportedImplementation() { + try { + FuseBuilder.getSupported(); + return true; + } catch (UnsupportedOperationException e) { + return false; + } + } + private Path orig; private Path mirror; private Fuse fuse; From bbb7627bba0bd637414c054a9d00fecb82eaa6fe Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 4 Oct 2022 14:31:01 +0200 Subject: [PATCH 12/20] bump external dependencies --- jfuse-examples/pom.xml | 2 +- jfuse-tests/pom.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/jfuse-examples/pom.xml b/jfuse-examples/pom.xml index 8da63546..d018e3e8 100644 --- a/jfuse-examples/pom.xml +++ b/jfuse-examples/pom.xml @@ -24,7 +24,7 @@ org.slf4j slf4j-simple - 2.0.0-alpha6 + 2.0.3 diff --git a/jfuse-tests/pom.xml b/jfuse-tests/pom.xml index 78c3ab9c..c17a8259 100644 --- a/jfuse-tests/pom.xml +++ b/jfuse-tests/pom.xml @@ -37,19 +37,19 @@ org.slf4j slf4j-simple - 2.0.0-alpha6 + 2.0.3 test org.openjdk.jmh jmh-core - 1.34 + 1.35 test org.openjdk.jmh jmh-generator-annprocess - 1.34 + 1.35 test From 4ba47e66d0489d7b4a58aea9590ee4f629b9f8ec Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 4 Oct 2022 14:37:48 +0200 Subject: [PATCH 13/20] use SymbolLookup.loaderLookup to find symbols in libfuse3.so --- .../cryptomator/jfuse/linux/aarch64/FuseFunctions.java | 8 +++++--- .../org/cryptomator/jfuse/linux/amd64/FuseFunctions.java | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseFunctions.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseFunctions.java index b245e6ba..2576a227 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseFunctions.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseFunctions.java @@ -3,6 +3,7 @@ import java.lang.foreign.Addressable; import java.lang.foreign.FunctionDescriptor; import java.lang.foreign.Linker; +import java.lang.foreign.SymbolLookup; import java.lang.invoke.MethodHandle; import static java.lang.foreign.ValueLayout.ADDRESS; @@ -21,8 +22,9 @@ class FuseFunctions { private final MethodHandle fuse_parse_cmdline; private FuseFunctions() { - Linker linker = Linker.nativeLinker(); - this.fuse_parse_cmdline = linker.defaultLookup().lookup("fuse_parse_cmdline") + var lookup = SymbolLookup.loaderLookup(); + var linker = Linker.nativeLinker(); + this.fuse_parse_cmdline = lookup.lookup("fuse_parse_cmdline") .map(symbol -> linker.downcallHandle(symbol, FUSE_PARSE_CMDLINE)) .orElseThrow(() -> new UnsatisfiedLinkError("unresolved symbol fuse_parse_cmdline")); } @@ -31,7 +33,7 @@ private static class Holder { private static final FuseFunctions INSTANCE = new FuseFunctions(); } - public static int fuse_parse_cmdline( Addressable args, Addressable opts) { + public static int fuse_parse_cmdline(Addressable args, Addressable opts) { try { return (int) Holder.INSTANCE.fuse_parse_cmdline.invokeExact(args, opts); } catch (Throwable e) { diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseFunctions.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseFunctions.java index d2cb808b..f2ff8d68 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseFunctions.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseFunctions.java @@ -3,6 +3,7 @@ import java.lang.foreign.Addressable; import java.lang.foreign.FunctionDescriptor; import java.lang.foreign.Linker; +import java.lang.foreign.SymbolLookup; import java.lang.invoke.MethodHandle; import static java.lang.foreign.ValueLayout.ADDRESS; @@ -21,8 +22,9 @@ class FuseFunctions { private final MethodHandle fuse_parse_cmdline; private FuseFunctions() { - Linker linker = Linker.nativeLinker(); - this.fuse_parse_cmdline = linker.defaultLookup().lookup("fuse_parse_cmdline") + var lookup = SymbolLookup.loaderLookup(); + var linker = Linker.nativeLinker(); + this.fuse_parse_cmdline = lookup.lookup("fuse_parse_cmdline") .map(symbol -> linker.downcallHandle(symbol, FUSE_PARSE_CMDLINE)) .orElseThrow(() -> new UnsatisfiedLinkError("unresolved symbol fuse_parse_cmdline")); } @@ -31,7 +33,7 @@ private static class Holder { private static final FuseFunctions INSTANCE = new FuseFunctions(); } - public static int fuse_parse_cmdline( Addressable args, Addressable opts) { + public static int fuse_parse_cmdline(Addressable args, Addressable opts) { try { return (int) Holder.INSTANCE.fuse_parse_cmdline.invokeExact(args, opts); } catch (Throwable e) { From a78b5798a61f6083f714a8d8acc45c0bd570a233 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 4 Oct 2022 15:13:55 +0200 Subject: [PATCH 14/20] read `clone_fd`, `max_idle_threads` and `max_threads` from cmd line options --- .../cryptomator/jfuse/linux/aarch64/FuseArgs.java | 12 ++++++++++++ .../jfuse/linux/aarch64/FuseFunctions.java | 2 +- .../jfuse/linux/aarch64/FuseMountImpl.java | 15 +++++++++------ .../cryptomator/jfuse/linux/amd64/FuseArgs.java | 12 ++++++++++++ .../jfuse/linux/amd64/FuseFunctions.java | 2 +- .../jfuse/linux/amd64/FuseMountImpl.java | 15 +++++++++------ 6 files changed, 44 insertions(+), 14 deletions(-) diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseArgs.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseArgs.java index 458a2f8e..f3257dda 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseArgs.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseArgs.java @@ -31,4 +31,16 @@ public MemoryAddress mountPoint() { public boolean multithreaded() { return fuse_cmdline_opts.singlethread$get(cmdLineOpts) == 0; } + + public int cloneFd() { + return fuse_cmdline_opts.clone_fd$get(cmdLineOpts); + } + + public int maxIdleThreads() { + return fuse_cmdline_opts.max_idle_threads$get(cmdLineOpts); + } + + public int maxThreads() { + return fuse_cmdline_opts.max_threads$get(cmdLineOpts); + } } diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseFunctions.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseFunctions.java index 2576a227..bafc8238 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseFunctions.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseFunctions.java @@ -17,7 +17,7 @@ class FuseFunctions { // see https://github.com/libfuse/libfuse/blob/fuse-3.12.0/include/fuse_lowlevel.h#L1892-L1923 - private static FunctionDescriptor FUSE_PARSE_CMDLINE = FunctionDescriptor.of(JAVA_INT, ADDRESS, ADDRESS); + private static final FunctionDescriptor FUSE_PARSE_CMDLINE = FunctionDescriptor.of(JAVA_INT, ADDRESS, ADDRESS); private final MethodHandle fuse_parse_cmdline; diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseMountImpl.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseMountImpl.java index 1b8a95d6..6caeeda0 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseMountImpl.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseMountImpl.java @@ -9,26 +9,29 @@ record FuseMountImpl(MemoryAddress fuse, FuseArgs fuseArgs) implements FuseMount { + private static final int FUSE_3_2 = 32; + private static final int FUSE_3_12 = 312; + @Override public int loop() { // depends on fuse version: https://github.com/libfuse/libfuse/blob/fuse-3.12.0/include/fuse.h#L1011-L1050 - if (!fuseArgs.multithreaded() || fuse_h.fuse_version() < 32) { + if (!fuseArgs.multithreaded() || fuse_h.fuse_version() < FUSE_3_2) { // FUSE 3.1: to keep things simple, we just don't support fuse_loop_mt return fuse_h.fuse_loop(fuse); - } else if (fuse_h.fuse_version() < 312) { + } else if (fuse_h.fuse_version() < FUSE_3_12) { // FUSE 3.2 try (var scope = MemorySession.openConfined()) { var loopCfg = fuse_loop_config_v1.allocate(scope); - fuse_loop_config_v1.clone_fd$set(loopCfg, 0); - fuse_loop_config_v1.max_idle_threads$set(loopCfg, 2); + fuse_loop_config_v1.clone_fd$set(loopCfg, fuseArgs.cloneFd()); + fuse_loop_config_v1.max_idle_threads$set(loopCfg, fuseArgs.maxIdleThreads()); return fuse_h.fuse_loop_mt(fuse, loopCfg); } } else { // FUSE 3.12 var loopCfg = fuse_h.fuse_loop_cfg_create(); try { - fuse_h.fuse_loop_cfg_set_clone_fd(loopCfg, 0); - fuse_h.fuse_loop_cfg_set_max_threads(loopCfg, 4); + fuse_h.fuse_loop_cfg_set_clone_fd(loopCfg, fuseArgs.cloneFd()); + fuse_h.fuse_loop_cfg_set_max_threads(loopCfg, fuseArgs.maxThreads()); return fuse_h.fuse_loop_mt(fuse, loopCfg); } finally { fuse_h.fuse_loop_cfg_destroy(loopCfg); diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseArgs.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseArgs.java index d6a06dbe..cb1f6ea9 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseArgs.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseArgs.java @@ -32,4 +32,16 @@ public boolean multithreaded() { return fuse_cmdline_opts.singlethread$get(cmdLineOpts) == 0; } + public int cloneFd() { + return fuse_cmdline_opts.clone_fd$get(cmdLineOpts); + } + + public int maxIdleThreads() { + return fuse_cmdline_opts.max_idle_threads$get(cmdLineOpts); + } + + public int maxThreads() { + return fuse_cmdline_opts.max_threads$get(cmdLineOpts); + } + } diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseFunctions.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseFunctions.java index f2ff8d68..b9ea2dd0 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseFunctions.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseFunctions.java @@ -17,7 +17,7 @@ class FuseFunctions { // see https://github.com/libfuse/libfuse/blob/fuse-3.12.0/include/fuse_lowlevel.h#L1892-L1923 - private static FunctionDescriptor FUSE_PARSE_CMDLINE = FunctionDescriptor.of(JAVA_INT, ADDRESS, ADDRESS); + private static final FunctionDescriptor FUSE_PARSE_CMDLINE = FunctionDescriptor.of(JAVA_INT, ADDRESS, ADDRESS); private final MethodHandle fuse_parse_cmdline; diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseMountImpl.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseMountImpl.java index 58bd8cac..dd2de259 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseMountImpl.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseMountImpl.java @@ -9,26 +9,29 @@ record FuseMountImpl(MemoryAddress fuse, FuseArgs fuseArgs) implements FuseMount { + private static final int FUSE_3_2 = 32; + private static final int FUSE_3_12 = 312; + @Override public int loop() { // depends on fuse version: https://github.com/libfuse/libfuse/blob/fuse-3.12.0/include/fuse.h#L1011-L1050 - if (!fuseArgs.multithreaded() || fuse_h.fuse_version() < 32) { + if (!fuseArgs.multithreaded() || fuse_h.fuse_version() < FUSE_3_2) { // FUSE 3.1: to keep things simple, we just don't support fuse_loop_mt return fuse_h.fuse_loop(fuse); - } else if (fuse_h.fuse_version() < 312) { + } else if (fuse_h.fuse_version() < FUSE_3_12) { // FUSE 3.2 try (var scope = MemorySession.openConfined()) { var loopCfg = fuse_loop_config_v1.allocate(scope); - fuse_loop_config_v1.clone_fd$set(loopCfg, 0); - fuse_loop_config_v1.max_idle_threads$set(loopCfg, 2); + fuse_loop_config_v1.clone_fd$set(loopCfg, fuseArgs.cloneFd()); + fuse_loop_config_v1.max_idle_threads$set(loopCfg, fuseArgs.maxIdleThreads()); return fuse_h.fuse_loop_mt(fuse, loopCfg); } } else { // FUSE 3.12 var loopCfg = fuse_h.fuse_loop_cfg_create(); try { - fuse_h.fuse_loop_cfg_set_clone_fd(loopCfg, 0); - fuse_h.fuse_loop_cfg_set_max_threads(loopCfg, 4); + fuse_h.fuse_loop_cfg_set_clone_fd(loopCfg, fuseArgs.cloneFd()); + fuse_h.fuse_loop_cfg_set_max_threads(loopCfg, fuseArgs.maxThreads()); return fuse_h.fuse_loop_mt(fuse, loopCfg); } finally { fuse_h.fuse_loop_cfg_destroy(loopCfg); From 48d729d9c4ec433428e1bf4c5ab7b94fcf019981 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 4 Oct 2022 15:14:05 +0200 Subject: [PATCH 15/20] added tests --- .../linux/aarch64/FuseMountImplTest.java | 88 +++++++++++++++++++ .../jfuse/linux/amd64/FuseMountImplTest.java | 88 +++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 jfuse-linux-aarch64/src/test/java/org/cryptomator/jfuse/linux/aarch64/FuseMountImplTest.java create mode 100644 jfuse-linux-amd64/src/test/java/org/cryptomator/jfuse/linux/amd64/FuseMountImplTest.java diff --git a/jfuse-linux-aarch64/src/test/java/org/cryptomator/jfuse/linux/aarch64/FuseMountImplTest.java b/jfuse-linux-aarch64/src/test/java/org/cryptomator/jfuse/linux/aarch64/FuseMountImplTest.java new file mode 100644 index 00000000..f507e2ba --- /dev/null +++ b/jfuse-linux-aarch64/src/test/java/org/cryptomator/jfuse/linux/aarch64/FuseMountImplTest.java @@ -0,0 +1,88 @@ +package org.cryptomator.jfuse.linux.aarch64; + +import org.cryptomator.jfuse.linux.aarch64.extr.fuse_h; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import java.lang.foreign.MemoryAddress; + +public class FuseMountImplTest { + + private MockedStatic fuseH; + private FuseArgs fuseArgs = Mockito.mock(FuseArgs.class); + private MemoryAddress fuse = MemoryAddress.ofLong(42L); + private FuseMountImpl fuseMount = new FuseMountImpl(fuse, fuseArgs); + + @BeforeEach + public void setup() { + this.fuseH = Mockito.mockStatic(fuse_h.class); + Mockito.doReturn(1).when(fuseArgs).cloneFd(); + Mockito.doReturn(2).when(fuseArgs).maxIdleThreads(); + Mockito.doReturn(3).when(fuseArgs).maxThreads(); + } + + @AfterEach + public void teardown() { + this.fuseH.close(); + } + + @Test + @DisplayName("mounting singlethreaded calls fuse_loop") + public void testLoopSingleThreaded() { + Mockito.doReturn(false).when(fuseArgs).multithreaded(); + + fuseMount.loop(); + + fuseH.verify(() -> fuse_h.fuse_loop(fuse)); + fuseH.verify(() -> fuse_h.fuse_loop_mt(Mockito.any(), Mockito.any()), Mockito.never()); + } + + @Test + @DisplayName("FUSE 3.1 calls fuse_loop") + public void testLoopMultiThreaded31() { + Mockito.doReturn(true).when(fuseArgs).multithreaded(); + fuseH.when(fuse_h::fuse_version).thenReturn(31); + + fuseMount.loop(); + + fuseH.verify(() -> fuse_h.fuse_loop(fuse)); + fuseH.verify(() -> fuse_h.fuse_loop_mt(Mockito.any(), Mockito.any()), Mockito.never()); + } + + @ParameterizedTest(name = "fuse_version() = {0}") + @ValueSource(ints = {32, 35, 310, 311}) + @DisplayName("FUSE 3.2 - 3.11 calls fuse_loop_mt") + public void testLoopMultiThreaded32(int fuseVersion) { + Mockito.doReturn(true).when(fuseArgs).multithreaded(); + fuseH.when(fuse_h::fuse_version).thenReturn(fuseVersion); + + fuseMount.loop(); + + fuseH.verify(() -> fuse_h.fuse_loop_mt(Mockito.eq(fuse), Mockito.any())); + fuseH.verify(() -> fuse_h.fuse_loop(Mockito.any()), Mockito.never()); + } + + @Test + @DisplayName("FUSE 3.12 calls fuse_loop_mt") + public void testLoopMultiThreaded312() { + var loopCfg = MemoryAddress.ofLong(1337L); + Mockito.doReturn(true).when(fuseArgs).multithreaded(); + fuseH.when(fuse_h::fuse_version).thenReturn(312); + fuseH.when(fuse_h::fuse_loop_cfg_create).thenReturn(loopCfg); + + fuseMount.loop(); + + fuseH.verify(() -> fuse_h.fuse_loop_cfg_set_clone_fd(loopCfg, 1)); + fuseH.verify(() -> fuse_h.fuse_loop_cfg_set_max_threads(loopCfg, 3)); + fuseH.verify(() -> fuse_h.fuse_loop_mt(fuse, loopCfg)); + fuseH.verify(() -> fuse_h.fuse_loop(Mockito.any()), Mockito.never()); + fuseH.verify(() -> fuse_h.fuse_loop_cfg_destroy(loopCfg)); + } + +} \ No newline at end of file diff --git a/jfuse-linux-amd64/src/test/java/org/cryptomator/jfuse/linux/amd64/FuseMountImplTest.java b/jfuse-linux-amd64/src/test/java/org/cryptomator/jfuse/linux/amd64/FuseMountImplTest.java new file mode 100644 index 00000000..7d836a51 --- /dev/null +++ b/jfuse-linux-amd64/src/test/java/org/cryptomator/jfuse/linux/amd64/FuseMountImplTest.java @@ -0,0 +1,88 @@ +package org.cryptomator.jfuse.linux.amd64; + +import org.cryptomator.jfuse.linux.amd64.extr.fuse_h; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import java.lang.foreign.MemoryAddress; + +public class FuseMountImplTest { + + private MockedStatic fuseH; + private FuseArgs fuseArgs = Mockito.mock(FuseArgs.class); + private MemoryAddress fuse = MemoryAddress.ofLong(42L); + private FuseMountImpl fuseMount = new FuseMountImpl(fuse, fuseArgs); + + @BeforeEach + public void setup() { + this.fuseH = Mockito.mockStatic(fuse_h.class); + Mockito.doReturn(1).when(fuseArgs).cloneFd(); + Mockito.doReturn(2).when(fuseArgs).maxIdleThreads(); + Mockito.doReturn(3).when(fuseArgs).maxThreads(); + } + + @AfterEach + public void teardown() { + this.fuseH.close(); + } + + @Test + @DisplayName("mounting singlethreaded calls fuse_loop") + public void testLoopSingleThreaded() { + Mockito.doReturn(false).when(fuseArgs).multithreaded(); + + fuseMount.loop(); + + fuseH.verify(() -> fuse_h.fuse_loop(fuse)); + fuseH.verify(() -> fuse_h.fuse_loop_mt(Mockito.any(), Mockito.any()), Mockito.never()); + } + + @Test + @DisplayName("FUSE 3.1 calls fuse_loop") + public void testLoopMultiThreaded31() { + Mockito.doReturn(true).when(fuseArgs).multithreaded(); + fuseH.when(fuse_h::fuse_version).thenReturn(31); + + fuseMount.loop(); + + fuseH.verify(() -> fuse_h.fuse_loop(fuse)); + fuseH.verify(() -> fuse_h.fuse_loop_mt(Mockito.any(), Mockito.any()), Mockito.never()); + } + + @ParameterizedTest(name = "fuse_version() = {0}") + @ValueSource(ints = {32, 35, 310, 311}) + @DisplayName("FUSE 3.2 - 3.11 calls fuse_loop_mt") + public void testLoopMultiThreaded32(int fuseVersion) { + Mockito.doReturn(true).when(fuseArgs).multithreaded(); + fuseH.when(fuse_h::fuse_version).thenReturn(fuseVersion); + + fuseMount.loop(); + + fuseH.verify(() -> fuse_h.fuse_loop_mt(Mockito.eq(fuse), Mockito.any())); + fuseH.verify(() -> fuse_h.fuse_loop(Mockito.any()), Mockito.never()); + } + + @Test + @DisplayName("FUSE 3.12 calls fuse_loop_mt") + public void testLoopMultiThreaded312() { + var loopCfg = MemoryAddress.ofLong(1337L); + Mockito.doReturn(true).when(fuseArgs).multithreaded(); + fuseH.when(fuse_h::fuse_version).thenReturn(312); + fuseH.when(fuse_h::fuse_loop_cfg_create).thenReturn(loopCfg); + + fuseMount.loop(); + + fuseH.verify(() -> fuse_h.fuse_loop_cfg_set_clone_fd(loopCfg, 1)); + fuseH.verify(() -> fuse_h.fuse_loop_cfg_set_max_threads(loopCfg, 3)); + fuseH.verify(() -> fuse_h.fuse_loop_mt(fuse, loopCfg)); + fuseH.verify(() -> fuse_h.fuse_loop(Mockito.any()), Mockito.never()); + fuseH.verify(() -> fuse_h.fuse_loop_cfg_destroy(loopCfg)); + } + +} \ No newline at end of file From 8b7f39fca8365e8b3eb181a802ae16bc5e8331c5 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 4 Oct 2022 15:44:06 +0200 Subject: [PATCH 16/20] undo unrelated change [ci skip] --- .../java/org/cryptomator/jfuse/tests/MirrorIT.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/jfuse-tests/src/test/java/org/cryptomator/jfuse/tests/MirrorIT.java b/jfuse-tests/src/test/java/org/cryptomator/jfuse/tests/MirrorIT.java index cdcce2cc..2484dda6 100644 --- a/jfuse-tests/src/test/java/org/cryptomator/jfuse/tests/MirrorIT.java +++ b/jfuse-tests/src/test/java/org/cryptomator/jfuse/tests/MirrorIT.java @@ -1,7 +1,6 @@ package org.cryptomator.jfuse.tests; import org.cryptomator.jfuse.api.Fuse; -import org.cryptomator.jfuse.api.FuseBuilder; import org.cryptomator.jfuse.api.MountFailedException; import org.cryptomator.jfuse.examples.AbstractMirrorFileSystem; import org.cryptomator.jfuse.examples.PosixMirrorFileSystem; @@ -17,7 +16,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestMethodOrder; -import org.junit.jupiter.api.condition.EnabledIf; import org.junit.jupiter.api.condition.OS; import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.ParameterizedTest; @@ -34,7 +32,6 @@ import java.util.List; import java.util.concurrent.TimeUnit; -@EnabledIf("hasSupportedImplementation") @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class MirrorIT { @@ -42,16 +39,6 @@ public class MirrorIT { System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "TRACE"); } - // skip integration tests, if no implementation is available - static boolean hasSupportedImplementation() { - try { - FuseBuilder.getSupported(); - return true; - } catch (UnsupportedOperationException e) { - return false; - } - } - private Path orig; private Path mirror; private Fuse fuse; From 61a3696fa28d969d6a2762b1b6b0aaf459dc5b9e Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 4 Oct 2022 15:45:44 +0200 Subject: [PATCH 17/20] fixed profile activation and integration tests in case of missing implementations --- jfuse-examples/pom.xml | 4 ++-- jfuse-tests/pom.xml | 4 ++-- .../java/org/cryptomator/jfuse/tests/MirrorIT.java | 13 +++++++++++++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/jfuse-examples/pom.xml b/jfuse-examples/pom.xml index d018e3e8..94eae6da 100644 --- a/jfuse-examples/pom.xml +++ b/jfuse-examples/pom.xml @@ -51,7 +51,7 @@ unix - Linux + linux x86_64 @@ -69,7 +69,7 @@ unix - Linux + linux aarch64 diff --git a/jfuse-tests/pom.xml b/jfuse-tests/pom.xml index c17a8259..785fecac 100644 --- a/jfuse-tests/pom.xml +++ b/jfuse-tests/pom.xml @@ -146,7 +146,7 @@ unix - Linux + linux x86_64 @@ -164,7 +164,7 @@ unix - Linux + linux aarch64 diff --git a/jfuse-tests/src/test/java/org/cryptomator/jfuse/tests/MirrorIT.java b/jfuse-tests/src/test/java/org/cryptomator/jfuse/tests/MirrorIT.java index 2484dda6..cdcce2cc 100644 --- a/jfuse-tests/src/test/java/org/cryptomator/jfuse/tests/MirrorIT.java +++ b/jfuse-tests/src/test/java/org/cryptomator/jfuse/tests/MirrorIT.java @@ -1,6 +1,7 @@ package org.cryptomator.jfuse.tests; import org.cryptomator.jfuse.api.Fuse; +import org.cryptomator.jfuse.api.FuseBuilder; import org.cryptomator.jfuse.api.MountFailedException; import org.cryptomator.jfuse.examples.AbstractMirrorFileSystem; import org.cryptomator.jfuse.examples.PosixMirrorFileSystem; @@ -16,6 +17,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.condition.EnabledIf; import org.junit.jupiter.api.condition.OS; import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.ParameterizedTest; @@ -32,6 +34,7 @@ import java.util.List; import java.util.concurrent.TimeUnit; +@EnabledIf("hasSupportedImplementation") @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class MirrorIT { @@ -39,6 +42,16 @@ public class MirrorIT { System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "TRACE"); } + // skip integration tests, if no implementation is available + static boolean hasSupportedImplementation() { + try { + FuseBuilder.getSupported(); + return true; + } catch (UnsupportedOperationException e) { + return false; + } + } + private Path orig; private Path mirror; private Fuse fuse; From bab2814ca4c4da9e0f3295ea91875af101a8573d Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 4 Oct 2022 15:50:46 +0200 Subject: [PATCH 18/20] really fixed profile activation on Linux now [ci skip] --- jfuse-examples/pom.xml | 2 +- jfuse-tests/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jfuse-examples/pom.xml b/jfuse-examples/pom.xml index 94eae6da..cdd0b1bd 100644 --- a/jfuse-examples/pom.xml +++ b/jfuse-examples/pom.xml @@ -52,7 +52,7 @@ unix linux - x86_64 + amd64 diff --git a/jfuse-tests/pom.xml b/jfuse-tests/pom.xml index 785fecac..d1c11ed7 100644 --- a/jfuse-tests/pom.xml +++ b/jfuse-tests/pom.xml @@ -147,7 +147,7 @@ unix linux - x86_64 + amd64 From 498be574f3f0b091a704a40273ecd8f024f1ea71 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Fri, 7 Oct 2022 14:21:27 +0200 Subject: [PATCH 19/20] missed some occurances in b706044 --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1544709f..601ffe80 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,7 +35,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-java@v2 with: - java-version: 19-ea + java-version: 19 distribution: 'zulu' cache: 'maven' - name: Setup fuse @@ -56,7 +56,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-java@v2 with: - java-version: 19-ea + java-version: 19 distribution: 'zulu' cache: 'maven' - name: Setup fuse @@ -79,7 +79,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-java@v2 with: - java-version: 19-ea + java-version: 19 distribution: 'zulu' cache: 'maven' - name: Cache SonarCloud packages From 184d161d08fb146d2d592f31fecaa01faddf16bd Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Fri, 7 Oct 2022 15:30:51 +0200 Subject: [PATCH 20/20] preparing 0.2.1 --- jfuse-api/pom.xml | 2 +- jfuse-examples/pom.xml | 2 +- jfuse-linux-aarch64/pom.xml | 2 +- jfuse-linux-amd64/pom.xml | 2 +- jfuse-mac/pom.xml | 2 +- jfuse-tests/pom.xml | 2 +- jfuse-win-amd64/pom.xml | 2 +- pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/jfuse-api/pom.xml b/jfuse-api/pom.xml index 4807c61e..e5ab7fb8 100644 --- a/jfuse-api/pom.xml +++ b/jfuse-api/pom.xml @@ -5,7 +5,7 @@ org.cryptomator jfuse - 0.3.0-SNAPSHOT + 0.2.1 4.0.0 jfuse-api diff --git a/jfuse-examples/pom.xml b/jfuse-examples/pom.xml index cdd0b1bd..c61ce606 100644 --- a/jfuse-examples/pom.xml +++ b/jfuse-examples/pom.xml @@ -5,7 +5,7 @@ org.cryptomator jfuse - 0.3.0-SNAPSHOT + 0.2.1 4.0.0 jfuse-examples diff --git a/jfuse-linux-aarch64/pom.xml b/jfuse-linux-aarch64/pom.xml index b25bc516..99f8d6de 100644 --- a/jfuse-linux-aarch64/pom.xml +++ b/jfuse-linux-aarch64/pom.xml @@ -5,7 +5,7 @@ jfuse org.cryptomator - 0.3.0-SNAPSHOT + 0.2.1 4.0.0 jfuse-linux-aarch64 diff --git a/jfuse-linux-amd64/pom.xml b/jfuse-linux-amd64/pom.xml index f30d0fa8..1ee56df3 100644 --- a/jfuse-linux-amd64/pom.xml +++ b/jfuse-linux-amd64/pom.xml @@ -5,7 +5,7 @@ org.cryptomator jfuse - 0.3.0-SNAPSHOT + 0.2.1 4.0.0 jfuse-linux-amd64 diff --git a/jfuse-mac/pom.xml b/jfuse-mac/pom.xml index fb006e51..b83fe0a4 100644 --- a/jfuse-mac/pom.xml +++ b/jfuse-mac/pom.xml @@ -5,7 +5,7 @@ org.cryptomator jfuse - 0.3.0-SNAPSHOT + 0.2.1 4.0.0 jfuse-mac diff --git a/jfuse-tests/pom.xml b/jfuse-tests/pom.xml index d1c11ed7..033974ea 100644 --- a/jfuse-tests/pom.xml +++ b/jfuse-tests/pom.xml @@ -5,7 +5,7 @@ org.cryptomator jfuse - 0.3.0-SNAPSHOT + 0.2.1 4.0.0 jfuse-tests diff --git a/jfuse-win-amd64/pom.xml b/jfuse-win-amd64/pom.xml index 82665348..12cee739 100644 --- a/jfuse-win-amd64/pom.xml +++ b/jfuse-win-amd64/pom.xml @@ -5,7 +5,7 @@ org.cryptomator jfuse - 0.3.0-SNAPSHOT + 0.2.1 4.0.0 jfuse-win-amd64 diff --git a/pom.xml b/pom.xml index 6029b14f..99bf238d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.cryptomator jfuse pom - 0.3.0-SNAPSHOT + 0.2.1 jFUSE Java bindings for FUSE using foreign functions & memory API https://github.com/cryptomator/jfuse