From 3c096bfb0f062ad4caccb84383608dbcf4bb539b Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Wed, 16 Feb 2022 13:48:10 +0100 Subject: [PATCH 01/98] replaced `fuse_main_real` on macOS + Linux replaced with `fuse_mount, fuse_new, fuse_loop, fuse_unmount, fuse_exit, fuse_destroy` --- .../java/org/cryptomator/jfuse/api/Fuse.java | 113 +++++++++++---- .../org/cryptomator/jfuse/api/FuseArgs.java | 6 + .../cryptomator/jfuse/api/FuseSession.java | 8 ++ jfuse-linux-aarch64/pom.xml | 14 ++ .../jfuse/linux/aarch64/FuseImpl.java | 128 ++++++++++++----- .../jfuse/linux/aarch64/extr/constants$0.java | 48 ++++--- .../jfuse/linux/aarch64/extr/constants$1.java | 51 +++++++ .../jfuse/linux/aarch64/extr/fuse_args.java | 82 +++++++++++ .../jfuse/linux/aarch64/extr/fuse_h.java | 78 +++++++++- jfuse-linux-amd64/pom.xml | 14 ++ .../jfuse/linux/amd64/FuseImpl.java | 136 +++++++++++++----- .../linux/amd64/extr/Constants$root.java | 4 + .../jfuse/linux/amd64/extr/RuntimeHelper.java | 9 +- .../jfuse/linux/amd64/extr/constants$0.java | 53 ++++--- .../jfuse/linux/amd64/extr/constants$1.java | 51 +++++++ .../jfuse/linux/amd64/extr/errno_h.java | 4 + .../jfuse/linux/amd64/extr/fcntl_h.java | 4 + .../jfuse/linux/amd64/extr/fuse_args.java | 82 +++++++++++ .../linux/amd64/extr/fuse_conn_info.java | 5 +- .../jfuse/linux/amd64/extr/fuse_context.java | 5 +- .../linux/amd64/extr/fuse_file_info.java | 5 +- .../linux/amd64/extr/fuse_fill_dir_t.java | 5 +- .../jfuse/linux/amd64/extr/fuse_h.java | 81 ++++++++++- .../linux/amd64/extr/fuse_operations.java | 4 +- .../jfuse/linux/amd64/extr/stat.java | 5 +- .../jfuse/linux/amd64/extr/stat_h.java | 4 + .../jfuse/linux/amd64/extr/statvfs.java | 5 +- .../jfuse/linux/amd64/extr/timespec.java | 5 +- jfuse-mac/pom.xml | 22 ++- .../org/cryptomator/jfuse/mac/FuseImpl.java | 136 +++++++++++++----- .../jfuse/mac/extr/Constants$root.java | 4 + .../jfuse/mac/extr/RuntimeHelper.java | 9 +- .../jfuse/mac/extr/constants$0.java | 53 ++++--- .../jfuse/mac/extr/constants$1.java | 51 +++++++ .../cryptomator/jfuse/mac/extr/errno_h.java | 4 + .../cryptomator/jfuse/mac/extr/fcntl_h.java | 4 + .../cryptomator/jfuse/mac/extr/fuse_args.java | 82 +++++++++++ .../jfuse/mac/extr/fuse_conn_info.java | 5 +- .../jfuse/mac/extr/fuse_context.java | 5 +- .../jfuse/mac/extr/fuse_file_info.java | 5 +- .../jfuse/mac/extr/fuse_fill_dir_t.java | 5 +- .../cryptomator/jfuse/mac/extr/fuse_h.java | 81 ++++++++++- .../jfuse/mac/extr/fuse_operations.java | 4 +- .../org/cryptomator/jfuse/mac/extr/stat.java | 5 +- .../cryptomator/jfuse/mac/extr/stat_h.java | 4 + .../cryptomator/jfuse/mac/extr/statvfs.java | 5 +- .../cryptomator/jfuse/mac/extr/timespec.java | 5 +- .../org/cryptomator/jfuse/tests/MirrorIT.java | 15 +- 48 files changed, 1251 insertions(+), 262 deletions(-) create mode 100644 jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseArgs.java create mode 100644 jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseSession.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/constants$1.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_args.java create mode 100644 jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/constants$1.java create mode 100644 jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_args.java create mode 100644 jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/constants$1.java create mode 100644 jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_args.java diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java index e61c8c46..86a3c8e2 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java @@ -1,9 +1,8 @@ package org.cryptomator.jfuse.api; -import jdk.incubator.foreign.MemorySegment; import jdk.incubator.foreign.ResourceScope; -import jdk.incubator.foreign.SegmentAllocator; -import jdk.incubator.foreign.ValueLayout; +import org.jetbrains.annotations.Blocking; +import org.jetbrains.annotations.MustBeInvokedByOverriders; import java.nio.file.Path; import java.util.ArrayList; @@ -11,11 +10,13 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReference; public abstract class Fuse implements AutoCloseable { protected final ResourceScope fuseScope = ResourceScope.newSharedScope(); - private final CountDownLatch mainExited = new CountDownLatch(1); + private final CountDownLatch loopExited = new CountDownLatch(1); + private final AtomicReference session = new AtomicReference<>(); protected Fuse() { } @@ -35,50 +36,102 @@ public static FuseBuilder builder() { * @return 0 if mounted successfully, or the result of fuse_main_real() in case of errors * @throws CompletionException wrapping exceptions thrown during init() or fuse_main_real() */ + @Blocking public int mount(String progName, Path mountPoint, String... flags) throws CompletionException { + final FuseSession lock = new FuseSession(null, null, null); + if (!session.compareAndSet(null, lock)) { + throw new IllegalStateException("Already mounted"); + } + List args = new ArrayList<>(); args.add(progName); args.addAll(List.of(flags)); - args.add("-f"); // foreground mode required, so fuse_main_real() blocks + // TODO remove?: args.add("-f"); // foreground mode required, so fuse_main_real() blocks args.add(mountPoint.toString()); - return mount(args); - } - - protected int mount(List args) throws CompletionException { - // fuseMain() will block (unless failing with return code != 0), therefore we need to wait for init() - // if any of these two completes, we know that mounting succeeded of failed. - var mountResult = CompletableFuture.supplyAsync(() -> fuseMain(args)); - var result = CompletableFuture.anyOf(mountResult, initialized()).join(); - if (result instanceof Integer i) { - return i; - } else { - throw new IllegalStateException("Expected Future"); - } - } - protected int fuseMain(List flags) { try (var scope = ResourceScope.newConfinedScope()) { - var allocator = SegmentAllocator.nativeAllocator(scope); - var argc = flags.size(); - var argv = allocator.allocateArray(ValueLayout.ADDRESS, argc); - for (int i = 0; i < argc; i++) { - var cString = allocator.allocateUtf8String(flags.get(i)); - argv.setAtIndex(ValueLayout.ADDRESS, i, cString); + var fuseArgs = parseCmdLine(args, scope); + var fuseSession = mount(fuseArgs, mountPoint); // TODO: specific exception + var isOnlySession = session.compareAndSet(lock, fuseSession); + assert isOnlySession : "unreachable code, as no other method can set this.session to SESSION_LOCK"; + + var mountResult = CompletableFuture + .supplyAsync(() -> loop(fuseSession, false)) // TODO: specify executor? + .whenComplete((result, error) -> loopExited.countDown()); + var result = CompletableFuture.anyOf(mountResult, initialized()).join(); + if (result instanceof Integer i) { + return i; + } else { + throw new IllegalStateException("Expected Future"); } - return fuseMain(argc, argv); } finally { - mainExited.countDown(); // make sure fuse_main finished before allowing to release fuseScope + session.compareAndSet(lock, null); // reset in case of error } } - protected abstract int fuseMain(int argc, MemorySegment argv); + /** + * Invokes {@code fuse_parse_cmdline}. + * + * @param args fuse flags + * @param scope memory session that the returned result is bound to + * @return Parsed flags ready to use for mounting + * @throws IllegalArgumentException If {@code fuse_parse_cmdline} returns -1. + */ + protected abstract FuseArgs parseCmdLine(List args, ResourceScope scope) throws IllegalArgumentException; + + /** + * Invokes {@code fuse_mount} and {@code fuse_new} to mount a new fuse file system. + * + * @param args The mount args + * @param mountPoint The mount point + * @return A new fuse session + */ + protected abstract FuseSession mount(FuseArgs args, Path mountPoint); + + /** + * Invokes {@code fuse_loop} or {@code fuse_loop_mt}, depending on {@code multithreaded}. + * + * @param session The fuse session + * @param multithreaded multi-threaded mode + * @return result passed through by {@code fuse_loop} or {@code fuse_loop_mt} + */ + @Blocking + protected abstract int loop(FuseSession session, boolean multithreaded); + + /** + * Unmounts the file system and exits any running loops. + *

+ * The implementation needs to be idempotent, i.e. repeated invokations must be no-ops. + * + * @param session The fuse session + */ + protected abstract void unmount(FuseSession session); + + /** + * Invokes {@code fuse_destroy}. + * + * @param session The fuse session + */ + protected abstract void destroy(FuseSession session); + /** + * @return A future that completes with {@code 0} as soon as {@link FuseOperations#init(FuseConnInfo) init} has been called. + */ protected abstract CompletableFuture initialized(); + /** + * Unmounts (if needed) this fuse file system and frees up system resources. + */ @Override + @MustBeInvokedByOverriders public void close() { try { - mainExited.await(); // TODO: check if main has been started first? + var session = this.session.getAndSet(null); + if (session != null) { + unmount(session); + loopExited.await(); + destroy(session); + } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseArgs.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseArgs.java new file mode 100644 index 00000000..5b44ec6d --- /dev/null +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseArgs.java @@ -0,0 +1,6 @@ +package org.cryptomator.jfuse.api; + +import jdk.incubator.foreign.MemorySegment; + +public record FuseArgs(MemorySegment args, boolean multithreaded, boolean foreground) { +} diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseSession.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseSession.java new file mode 100644 index 00000000..ed0a15cf --- /dev/null +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseSession.java @@ -0,0 +1,8 @@ +package org.cryptomator.jfuse.api; + +import jdk.incubator.foreign.MemoryAddress; + +import java.nio.file.Path; + +public record FuseSession(Path mountPoint, MemoryAddress ch, MemoryAddress fuse) { +} diff --git a/jfuse-linux-aarch64/pom.xml b/jfuse-linux-aarch64/pom.xml index 1cbc7f51..5780be1c 100644 --- a/jfuse-linux-aarch64/pom.xml +++ b/jfuse-linux-aarch64/pom.xml @@ -111,6 +111,8 @@ timespec --include-struct fuse_conn_info + --include-struct + fuse_args --include-typedef fuse_fill_dir_t @@ -120,7 +122,19 @@ --include-function fuse_get_context --include-function + fuse_parse_cmdline + --include-function + fuse_mount + --include-function + fuse_new + --include-function + fuse_loop + --include-function + fuse_unmount + --include-function fuse_exit + --include-function + fuse_destroy ${project.parent.basedir}/libfuse/include/fuse.h 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 5d773194..2701a20b 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 @@ -4,26 +4,35 @@ import jdk.incubator.foreign.MemoryLayout; import jdk.incubator.foreign.MemorySegment; import jdk.incubator.foreign.ResourceScope; +import jdk.incubator.foreign.SegmentAllocator; +import jdk.incubator.foreign.ValueLayout; import org.cryptomator.jfuse.api.Fuse; +import org.cryptomator.jfuse.api.FuseArgs; import org.cryptomator.jfuse.api.FuseOperations; +import org.cryptomator.jfuse.api.FuseSession; +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.stat_h; import org.cryptomator.jfuse.linux.aarch64.extr.timespec; import java.nio.ByteBuffer; +import java.nio.file.Path; +import java.util.List; import java.util.concurrent.CompletableFuture; +import static jdk.incubator.foreign.ValueLayout.JAVA_INT; + public final class FuseImpl extends Fuse { private final CompletableFuture initialized = new CompletableFuture<>(); private final FuseOperations delegate; - private final MemorySegment struct; + private final MemorySegment fuseOps; public FuseImpl(FuseOperations fuseOperations) { - this.struct = fuse_operations.allocate(fuseScope); + this.fuseOps = fuse_operations.allocate(fuseScope); this.delegate = fuseOperations; - fuse_operations.init$set(struct, fuse_operations.init.allocate(this::init, fuseScope).address()); + fuse_operations.init$set(fuseOps, fuse_operations.init.allocate(this::init, fuseScope).address()); fuseOperations.supportedOperations().forEach(this::bind); } @@ -45,42 +54,95 @@ protected CompletableFuture initialized() { } @Override - protected int fuseMain(int argc, MemorySegment argv) { - return fuse_h.fuse_main_real(argc, argv, struct, struct.byteSize(), MemoryAddress.NULL); + protected FuseArgs parseCmdLine(List args, ResourceScope scope) { + var allocator = SegmentAllocator.nativeAllocator(scope); + var multithreaded = allocator.allocate(JAVA_INT, 1); + var foreground = allocator.allocate(JAVA_INT, 1); + var fuseArgs = fuse_args.allocate(allocator); + var argc = args.size(); + var argv = allocator.allocateArray(ValueLayout.ADDRESS, argc); + for (int i = 0; i < argc; i++) { + var cString = allocator.allocateUtf8String(args.get(i)); + argv.setAtIndex(ValueLayout.ADDRESS, i, cString); + } + fuse_args.argc$set(fuseArgs, argc); + fuse_args.argv$set(fuseArgs, argv.address()); + fuse_args.allocated$set(fuseArgs, 0); + int parseResult = fuse_h.fuse_parse_cmdline(fuseArgs, MemoryAddress.NULL, multithreaded, foreground); + if (parseResult != 0) { + throw new IllegalArgumentException("fuse_parse_cmdline failed to parse " + String.join(" ", args)); + } + var isMultiThreaded = multithreaded.get(JAVA_INT, 0) == 1; + var isForeground = foreground.get(JAVA_INT, 0) == 1; + return new FuseArgs(fuseArgs, isMultiThreaded, isForeground); + } + + @Override + protected FuseSession mount(FuseArgs args, Path mountPoint) { + try (var scope = ResourceScope.newConfinedScope()) { + var allocator = SegmentAllocator.nativeAllocator(scope); + var mountPointStr = allocator.allocateUtf8String(mountPoint.toString()); + var ch = fuse_h.fuse_mount(mountPointStr, args.args()); + if (MemoryAddress.NULL.equals(ch)) { + // TODO any cleanup needed? + // TODO use explicit exception type + throw new IllegalArgumentException("Failed to mount to " + mountPoint + " with given args."); + } + var fuse = fuse_h.fuse_new(ch, args.args(), fuseOps, fuseOps.byteSize(), MemoryAddress.NULL); + if (MemoryAddress.NULL.equals(fuse)) { + fuse_h.fuse_unmount(mountPointStr, ch); + // TODO use explicit exception type + throw new IllegalArgumentException("fuse_new failed"); + } + return new FuseSession(mountPoint, ch, fuse); + } + } + + @Override + protected int loop(FuseSession session, boolean multithreaded) { + // TODO support fuse_loop_mt + return fuse_h.fuse_loop(session.fuse()); + } + + @Override + protected void unmount(FuseSession session) { + try (var scope = ResourceScope.newConfinedScope()) { + var allocator = SegmentAllocator.nativeAllocator(scope); + var mountPointStr = allocator.allocateUtf8String(session.mountPoint().toString()); + fuse_h.fuse_unmount(mountPointStr, session.ch()); + fuse_h.fuse_exit(session.fuse()); + } } -// private void exit() { -// try (var scope = ResourceScope.newConfinedScope()) { -// var ctx = fuse_context.ofAddress(fuse_h.fuse_get_context(), fuseScope); -// var fusePtr = fuse_context.fuse$get(ctx); -// fuse_h.fuse_exit(fusePtr); -// } -// } + @Override + protected void destroy(FuseSession session) { + fuse_h.fuse_destroy(session.fuse()); + } private void bind(FuseOperations.Operation operation) { switch (operation) { case INIT -> { /* handled already */ } - case ACCESS -> fuse_operations.access$set(struct, fuse_operations.access.allocate(this::access, fuseScope).address()); - case CHMOD -> fuse_operations.chmod$set(struct, fuse_operations.chmod.allocate(this::chmod, fuseScope).address()); - case CREATE -> fuse_operations.create$set(struct, fuse_operations.create.allocate(this::create, fuseScope).address()); - case DESTROY -> fuse_operations.destroy$set(struct, fuse_operations.destroy.allocate(this::destroy, fuseScope).address()); - case GET_ATTR -> fuse_operations.getattr$set(struct, fuse_operations.getattr.allocate(this::getattr, fuseScope).address()); - case MKDIR -> fuse_operations.mkdir$set(struct, fuse_operations.mkdir.allocate(this::mkdir, fuseScope).address()); - case OPEN -> fuse_operations.open$set(struct, fuse_operations.open.allocate(this::open, fuseScope).address()); - case OPEN_DIR -> fuse_operations.opendir$set(struct, fuse_operations.opendir.allocate(this::opendir, fuseScope).address()); - case READ -> fuse_operations.read$set(struct, fuse_operations.read.allocate(this::read, fuseScope).address()); - case READ_DIR -> fuse_operations.readdir$set(struct, fuse_operations.readdir.allocate(this::readdir, fuseScope).address()); - case READLINK -> fuse_operations.readlink$set(struct, fuse_operations.readlink.allocate(this::readlink, fuseScope).address()); - case RELEASE -> fuse_operations.release$set(struct, fuse_operations.release.allocate(this::release, fuseScope).address()); - case RELEASE_DIR -> fuse_operations.releasedir$set(struct, fuse_operations.releasedir.allocate(this::releasedir, fuseScope).address()); - case RENAME -> fuse_operations.rename$set(struct, fuse_operations.rename.allocate(this::rename, fuseScope).address()); - case RMDIR -> fuse_operations.rmdir$set(struct, fuse_operations.rmdir.allocate(this::rmdir, fuseScope).address()); - case STATFS -> fuse_operations.statfs$set(struct, fuse_operations.statfs.allocate(this::statfs, fuseScope).address()); - case SYMLINK -> fuse_operations.symlink$set(struct, fuse_operations.symlink.allocate(this::symlink, fuseScope).address()); - case TRUNCATE -> fuse_operations.truncate$set(struct, fuse_operations.truncate.allocate(this::truncate, fuseScope).address()); - case UNLINK -> fuse_operations.unlink$set(struct, fuse_operations.unlink.allocate(this::unlink, fuseScope).address()); - case UTIMENS -> fuse_operations.utimens$set(struct, fuse_operations.utimens.allocate(this::utimens, fuseScope).address()); - case WRITE -> fuse_operations.write$set(struct, fuse_operations.write.allocate(this::write, fuseScope).address()); + case ACCESS -> fuse_operations.access$set(fuseOps, fuse_operations.access.allocate(this::access, fuseScope).address()); + case CHMOD -> fuse_operations.chmod$set(fuseOps, fuse_operations.chmod.allocate(this::chmod, fuseScope).address()); + case CREATE -> fuse_operations.create$set(fuseOps, fuse_operations.create.allocate(this::create, fuseScope).address()); + case DESTROY -> fuse_operations.destroy$set(fuseOps, fuse_operations.destroy.allocate(this::destroy, fuseScope).address()); + case GET_ATTR -> fuse_operations.getattr$set(fuseOps, fuse_operations.getattr.allocate(this::getattr, fuseScope).address()); + case MKDIR -> fuse_operations.mkdir$set(fuseOps, fuse_operations.mkdir.allocate(this::mkdir, fuseScope).address()); + case OPEN -> fuse_operations.open$set(fuseOps, fuse_operations.open.allocate(this::open, fuseScope).address()); + case OPEN_DIR -> fuse_operations.opendir$set(fuseOps, fuse_operations.opendir.allocate(this::opendir, fuseScope).address()); + case READ -> fuse_operations.read$set(fuseOps, fuse_operations.read.allocate(this::read, fuseScope).address()); + case READ_DIR -> fuse_operations.readdir$set(fuseOps, fuse_operations.readdir.allocate(this::readdir, fuseScope).address()); + case READLINK -> fuse_operations.readlink$set(fuseOps, fuse_operations.readlink.allocate(this::readlink, fuseScope).address()); + case RELEASE -> fuse_operations.release$set(fuseOps, fuse_operations.release.allocate(this::release, fuseScope).address()); + case RELEASE_DIR -> fuse_operations.releasedir$set(fuseOps, fuse_operations.releasedir.allocate(this::releasedir, fuseScope).address()); + case RENAME -> fuse_operations.rename$set(fuseOps, fuse_operations.rename.allocate(this::rename, fuseScope).address()); + case RMDIR -> fuse_operations.rmdir$set(fuseOps, fuse_operations.rmdir.allocate(this::rmdir, fuseScope).address()); + case STATFS -> fuse_operations.statfs$set(fuseOps, fuse_operations.statfs.allocate(this::statfs, fuseScope).address()); + case SYMLINK -> fuse_operations.symlink$set(fuseOps, fuse_operations.symlink.allocate(this::symlink, fuseScope).address()); + case TRUNCATE -> fuse_operations.truncate$set(fuseOps, fuse_operations.truncate.allocate(this::truncate, fuseScope).address()); + case UNLINK -> fuse_operations.unlink$set(fuseOps, fuse_operations.unlink.allocate(this::unlink, fuseScope).address()); + case UTIMENS -> fuse_operations.utimens$set(fuseOps, fuse_operations.utimens.allocate(this::utimens, fuseScope).address()); + case WRITE -> fuse_operations.write$set(fuseOps, fuse_operations.write.allocate(this::write, fuseScope).address()); } } 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 bdeb7da6..ea9317d9 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,6 +9,32 @@ import static jdk.incubator.foreign.ValueLayout.*; class constants$0 { + static final FunctionDescriptor fuse_mount$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_mount$MH = RuntimeHelper.downcallHandle( + "fuse_mount", + constants$0.fuse_mount$FUNC, false + ); + static final FunctionDescriptor fuse_unmount$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_unmount$MH = RuntimeHelper.downcallHandle( + "fuse_unmount", + constants$0.fuse_unmount$FUNC, false + ); + static final FunctionDescriptor fuse_parse_cmdline$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_POINTER$LAYOUT + ); + static final MethodHandle fuse_parse_cmdline$MH = RuntimeHelper.downcallHandle( + "fuse_parse_cmdline", + constants$0.fuse_parse_cmdline$FUNC, false + ); 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, @@ -18,28 +44,16 @@ class constants$0 { static final MethodHandle fuse_fill_dir_t$MH = RuntimeHelper.downcallHandle( constants$0.fuse_fill_dir_t$FUNC, false ); - static final FunctionDescriptor fuse_exit$FUNC = FunctionDescriptor.ofVoid( - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle fuse_exit$MH = RuntimeHelper.downcallHandle( - "fuse_exit", - constants$0.fuse_exit$FUNC, false - ); - static final FunctionDescriptor fuse_get_context$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT); - static final MethodHandle fuse_get_context$MH = RuntimeHelper.downcallHandle( - "fuse_get_context", - constants$0.fuse_get_context$FUNC, false - ); - static final FunctionDescriptor fuse_main_real$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, - Constants$root.C_INT$LAYOUT, + 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_POINTER$LAYOUT, Constants$root.C_LONG_LONG$LAYOUT, Constants$root.C_POINTER$LAYOUT ); - static final MethodHandle fuse_main_real$MH = RuntimeHelper.downcallHandle( - "fuse_main_real", - constants$0.fuse_main_real$FUNC, false + static final MethodHandle fuse_new$MH = RuntimeHelper.downcallHandle( + "fuse_new", + constants$0.fuse_new$FUNC, false ); } 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 new file mode 100644 index 00000000..28171066 --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/constants$1.java @@ -0,0 +1,51 @@ +// 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 jdk.incubator.foreign.*; +import static jdk.incubator.foreign.ValueLayout.*; +class constants$1 { + + static final FunctionDescriptor fuse_destroy$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_destroy$MH = RuntimeHelper.downcallHandle( + "fuse_destroy", + constants$1.fuse_destroy$FUNC, false + ); + 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$1.fuse_loop$FUNC, false + ); + static final FunctionDescriptor fuse_exit$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_exit$MH = RuntimeHelper.downcallHandle( + "fuse_exit", + constants$1.fuse_exit$FUNC, false + ); + static final FunctionDescriptor fuse_get_context$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT); + static final MethodHandle fuse_get_context$MH = RuntimeHelper.downcallHandle( + "fuse_get_context", + constants$1.fuse_get_context$FUNC, false + ); + static final FunctionDescriptor fuse_main_real$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_INT$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_main_real$MH = RuntimeHelper.downcallHandle( + "fuse_main_real", + constants$1.fuse_main_real$FUNC, false + ); +} + + diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_args.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_args.java new file mode 100644 index 00000000..3646e596 --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_args.java @@ -0,0 +1,82 @@ +// 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 jdk.incubator.foreign.*; +import static jdk.incubator.foreign.ValueLayout.*; +public class fuse_args { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_INT$LAYOUT.withName("argc"), + MemoryLayout.paddingLayout(32), + Constants$root.C_POINTER$LAYOUT.withName("argv"), + Constants$root.C_INT$LAYOUT.withName("allocated"), + MemoryLayout.paddingLayout(32) + ).withName("fuse_args"); + public static MemoryLayout $LAYOUT() { + return fuse_args.$struct$LAYOUT; + } + static final VarHandle argc$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("argc")); + public static VarHandle argc$VH() { + return fuse_args.argc$VH; + } + public static int argc$get(MemorySegment seg) { + return (int)fuse_args.argc$VH.get(seg); + } + public static void argc$set( MemorySegment seg, int x) { + fuse_args.argc$VH.set(seg, x); + } + public static int argc$get(MemorySegment seg, long index) { + return (int)fuse_args.argc$VH.get(seg.asSlice(index*sizeof())); + } + public static void argc$set(MemorySegment seg, long index, int x) { + fuse_args.argc$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle argv$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("argv")); + public static VarHandle argv$VH() { + return fuse_args.argv$VH; + } + public static MemoryAddress argv$get(MemorySegment seg) { + return (jdk.incubator.foreign.MemoryAddress)fuse_args.argv$VH.get(seg); + } + public static void argv$set( MemorySegment seg, MemoryAddress x) { + fuse_args.argv$VH.set(seg, x); + } + public static MemoryAddress argv$get(MemorySegment seg, long index) { + return (jdk.incubator.foreign.MemoryAddress)fuse_args.argv$VH.get(seg.asSlice(index*sizeof())); + } + public static void argv$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_args.argv$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle allocated$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("allocated")); + public static VarHandle allocated$VH() { + return fuse_args.allocated$VH; + } + public static int allocated$get(MemorySegment seg) { + return (int)fuse_args.allocated$VH.get(seg); + } + public static void allocated$set( MemorySegment seg, int x) { + fuse_args.allocated$VH.set(seg, x); + } + public static int allocated$get(MemorySegment seg, long index) { + return (int)fuse_args.allocated$VH.get(seg.asSlice(index*sizeof())); + } + public static void allocated$set(MemorySegment seg, long index, int x) { + fuse_args.allocated$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 allocate(ResourceScope scope) { return allocate(SegmentAllocator.nativeAllocator(scope)); } + public static MemorySegment allocateArray(int len, ResourceScope scope) { + return allocateArray(len, SegmentAllocator.nativeAllocator(scope)); + } + public static MemorySegment ofAddress(MemoryAddress addr, ResourceScope scope) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, scope); } +} + + 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 fe1fd1bf..48b9618f 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,11 +18,77 @@ 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_mount$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_mount$MH,"fuse_mount"); + } + public static MemoryAddress fuse_mount ( Addressable mountpoint, Addressable args) { + var mh$ = RuntimeHelper.requireNonNull(constants$0.fuse_mount$MH, "fuse_mount"); + try { + return (jdk.incubator.foreign.MemoryAddress)mh$.invokeExact(mountpoint, args); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_unmount$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_unmount$MH,"fuse_unmount"); + } + public static void fuse_unmount ( Addressable mountpoint, Addressable ch) { + var mh$ = RuntimeHelper.requireNonNull(constants$0.fuse_unmount$MH, "fuse_unmount"); + try { + mh$.invokeExact(mountpoint, ch); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_parse_cmdline$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_parse_cmdline$MH,"fuse_parse_cmdline"); + } + public static int fuse_parse_cmdline ( Addressable args, Addressable mountpoint, Addressable multithreaded, Addressable foreground) { + var mh$ = RuntimeHelper.requireNonNull(constants$0.fuse_parse_cmdline$MH, "fuse_parse_cmdline"); + try { + return (int)mh$.invokeExact(args, mountpoint, multithreaded, foreground); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_new$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_new$MH,"fuse_new"); + } + public static MemoryAddress fuse_new ( Addressable ch, Addressable args, Addressable op, long op_size, Addressable user_data) { + var mh$ = RuntimeHelper.requireNonNull(constants$0.fuse_new$MH, "fuse_new"); + try { + return (jdk.incubator.foreign.MemoryAddress)mh$.invokeExact(ch, args, op, op_size, user_data); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_destroy$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse_destroy$MH,"fuse_destroy"); + } + public static void fuse_destroy ( Addressable f) { + var mh$ = RuntimeHelper.requireNonNull(constants$1.fuse_destroy$MH, "fuse_destroy"); + try { + mh$.invokeExact(f); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_loop$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse_loop$MH,"fuse_loop"); + } + public static int fuse_loop ( Addressable f) { + var mh$ = RuntimeHelper.requireNonNull(constants$1.fuse_loop$MH, "fuse_loop"); + try { + return (int)mh$.invokeExact(f); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } public static MethodHandle fuse_exit$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_exit$MH,"fuse_exit"); + return RuntimeHelper.requireNonNull(constants$1.fuse_exit$MH,"fuse_exit"); } public static void fuse_exit ( Addressable f) { - var mh$ = RuntimeHelper.requireNonNull(constants$0.fuse_exit$MH, "fuse_exit"); + var mh$ = RuntimeHelper.requireNonNull(constants$1.fuse_exit$MH, "fuse_exit"); try { mh$.invokeExact(f); } catch (Throwable ex$) { @@ -30,10 +96,10 @@ public static void fuse_exit ( Addressable f) { } } public static MethodHandle fuse_get_context$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_get_context$MH,"fuse_get_context"); + return RuntimeHelper.requireNonNull(constants$1.fuse_get_context$MH,"fuse_get_context"); } public static MemoryAddress fuse_get_context () { - var mh$ = RuntimeHelper.requireNonNull(constants$0.fuse_get_context$MH, "fuse_get_context"); + var mh$ = RuntimeHelper.requireNonNull(constants$1.fuse_get_context$MH, "fuse_get_context"); try { return (jdk.incubator.foreign.MemoryAddress)mh$.invokeExact(); } catch (Throwable ex$) { @@ -41,10 +107,10 @@ public static MemoryAddress fuse_get_context () { } } public static MethodHandle fuse_main_real$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_main_real$MH,"fuse_main_real"); + return RuntimeHelper.requireNonNull(constants$1.fuse_main_real$MH,"fuse_main_real"); } public static int fuse_main_real ( int argc, Addressable argv, Addressable op, long op_size, Addressable user_data) { - var mh$ = RuntimeHelper.requireNonNull(constants$0.fuse_main_real$MH, "fuse_main_real"); + var mh$ = RuntimeHelper.requireNonNull(constants$1.fuse_main_real$MH, "fuse_main_real"); try { return (int)mh$.invokeExact(argc, argv, op, op_size, user_data); } catch (Throwable ex$) { diff --git a/jfuse-linux-amd64/pom.xml b/jfuse-linux-amd64/pom.xml index eee9ca40..020401f6 100644 --- a/jfuse-linux-amd64/pom.xml +++ b/jfuse-linux-amd64/pom.xml @@ -112,6 +112,8 @@ timespec --include-struct fuse_conn_info + --include-struct + fuse_args --include-typedef fuse_fill_dir_t @@ -121,7 +123,19 @@ --include-function fuse_get_context --include-function + fuse_parse_cmdline + --include-function + fuse_mount + --include-function + fuse_new + --include-function + fuse_loop + --include-function + fuse_unmount + --include-function fuse_exit + --include-function + fuse_destroy ${project.parent.basedir}/libfuse/include/fuse.h 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 67ce145c..a5360de1 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 @@ -1,29 +1,38 @@ package org.cryptomator.jfuse.linux.amd64; +import jdk.incubator.foreign.MemoryAddress; +import jdk.incubator.foreign.MemoryLayout; +import jdk.incubator.foreign.MemorySegment; +import jdk.incubator.foreign.ResourceScope; +import jdk.incubator.foreign.SegmentAllocator; +import jdk.incubator.foreign.ValueLayout; import org.cryptomator.jfuse.api.Fuse; +import org.cryptomator.jfuse.api.FuseArgs; import org.cryptomator.jfuse.api.FuseOperations; +import org.cryptomator.jfuse.api.FuseSession; +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.stat_h; import org.cryptomator.jfuse.linux.amd64.extr.timespec; -import jdk.incubator.foreign.MemoryAddress; -import jdk.incubator.foreign.MemoryLayout; -import jdk.incubator.foreign.MemorySegment; -import jdk.incubator.foreign.ResourceScope; import java.nio.ByteBuffer; +import java.nio.file.Path; +import java.util.List; import java.util.concurrent.CompletableFuture; +import static jdk.incubator.foreign.ValueLayout.JAVA_INT; + public final class FuseImpl extends Fuse { private final CompletableFuture initialized = new CompletableFuture<>(); private final FuseOperations delegate; - private final MemorySegment struct; + private final MemorySegment fuseOps; public FuseImpl(FuseOperations fuseOperations) { - this.struct = fuse_operations.allocate(fuseScope); + this.fuseOps = fuse_operations.allocate(fuseScope); this.delegate = fuseOperations; - fuse_operations.init$set(struct, fuse_operations.init.allocate(this::init, fuseScope).address()); + fuse_operations.init$set(fuseOps, fuse_operations.init.allocate(this::init, fuseScope).address()); fuseOperations.supportedOperations().forEach(this::bind); } @@ -45,42 +54,95 @@ protected CompletableFuture initialized() { } @Override - protected int fuseMain(int argc, MemorySegment argv) { - return fuse_h.fuse_main_real(argc, argv, struct, struct.byteSize(), MemoryAddress.NULL); + protected FuseArgs parseCmdLine(List args, ResourceScope scope) { + var allocator = SegmentAllocator.nativeAllocator(scope); + var multithreaded = allocator.allocate(JAVA_INT, 1); + var foreground = allocator.allocate(JAVA_INT, 1); + var fuseArgs = fuse_args.allocate(allocator); + var argc = args.size(); + var argv = allocator.allocateArray(ValueLayout.ADDRESS, argc); + for (int i = 0; i < argc; i++) { + var cString = allocator.allocateUtf8String(args.get(i)); + argv.setAtIndex(ValueLayout.ADDRESS, i, cString); + } + fuse_args.argc$set(fuseArgs, argc); + fuse_args.argv$set(fuseArgs, argv.address()); + fuse_args.allocated$set(fuseArgs, 0); + int parseResult = fuse_h.fuse_parse_cmdline(fuseArgs, MemoryAddress.NULL, multithreaded, foreground); + if (parseResult != 0) { + throw new IllegalArgumentException("fuse_parse_cmdline failed to parse " + String.join(" ", args)); + } + var isMultiThreaded = multithreaded.get(JAVA_INT, 0) == 1; + var isForeground = foreground.get(JAVA_INT, 0) == 1; + return new FuseArgs(fuseArgs, isMultiThreaded, isForeground); + } + + @Override + protected FuseSession mount(FuseArgs args, Path mountPoint) { + try (var scope = ResourceScope.newConfinedScope()) { + var allocator = SegmentAllocator.nativeAllocator(scope); + var mountPointStr = allocator.allocateUtf8String(mountPoint.toString()); + var ch = fuse_h.fuse_mount(mountPointStr, args.args()); + if (MemoryAddress.NULL.equals(ch)) { + // TODO any cleanup needed? + // TODO use explicit exception type + throw new IllegalArgumentException("Failed to mount to " + mountPoint + " with given args."); + } + var fuse = fuse_h.fuse_new(ch, args.args(), fuseOps, fuseOps.byteSize(), MemoryAddress.NULL); + if (MemoryAddress.NULL.equals(fuse)) { + fuse_h.fuse_unmount(mountPointStr, ch); + // TODO use explicit exception type + throw new IllegalArgumentException("fuse_new failed"); + } + return new FuseSession(mountPoint, ch, fuse); + } + } + + @Override + protected int loop(FuseSession session, boolean multithreaded) { + // TODO support fuse_loop_mt + return fuse_h.fuse_loop(session.fuse()); } -// private void exit() { -// try (var scope = ResourceScope.newConfinedScope()) { -// var ctx = fuse_context.ofAddress(fuse_h.fuse_get_context(), fuseScope); -// var fusePtr = fuse_context.fuse$get(ctx); -// fuse_h.fuse_exit(fusePtr); -// } -// } + @Override + protected void unmount(FuseSession session) { + try (var scope = ResourceScope.newConfinedScope()) { + var allocator = SegmentAllocator.nativeAllocator(scope); + var mountPointStr = allocator.allocateUtf8String(session.mountPoint().toString()); + fuse_h.fuse_unmount(mountPointStr, session.ch()); + fuse_h.fuse_exit(session.fuse()); + } + } + + @Override + protected void destroy(FuseSession session) { + fuse_h.fuse_destroy(session.fuse()); + } private void bind(FuseOperations.Operation operation) { switch (operation) { case INIT -> { /* handled already */ } - case ACCESS -> fuse_operations.access$set(struct, fuse_operations.access.allocate(this::access, fuseScope).address()); - case CHMOD -> fuse_operations.chmod$set(struct, fuse_operations.chmod.allocate(this::chmod, fuseScope).address()); - case CREATE -> fuse_operations.create$set(struct, fuse_operations.create.allocate(this::create, fuseScope).address()); - case DESTROY -> fuse_operations.destroy$set(struct, fuse_operations.destroy.allocate(this::destroy, fuseScope).address()); - case GET_ATTR -> fuse_operations.getattr$set(struct, fuse_operations.getattr.allocate(this::getattr, fuseScope).address()); - case MKDIR -> fuse_operations.mkdir$set(struct, fuse_operations.mkdir.allocate(this::mkdir, fuseScope).address()); - case OPEN -> fuse_operations.open$set(struct, fuse_operations.open.allocate(this::open, fuseScope).address()); - case OPEN_DIR -> fuse_operations.opendir$set(struct, fuse_operations.opendir.allocate(this::opendir, fuseScope).address()); - case READ -> fuse_operations.read$set(struct, fuse_operations.read.allocate(this::read, fuseScope).address()); - case READ_DIR -> fuse_operations.readdir$set(struct, fuse_operations.readdir.allocate(this::readdir, fuseScope).address()); - case READLINK -> fuse_operations.readlink$set(struct, fuse_operations.readlink.allocate(this::readlink, fuseScope).address()); - case RELEASE -> fuse_operations.release$set(struct, fuse_operations.release.allocate(this::release, fuseScope).address()); - case RELEASE_DIR -> fuse_operations.releasedir$set(struct, fuse_operations.releasedir.allocate(this::releasedir, fuseScope).address()); - case RENAME -> fuse_operations.rename$set(struct, fuse_operations.rename.allocate(this::rename, fuseScope).address()); - case RMDIR -> fuse_operations.rmdir$set(struct, fuse_operations.rmdir.allocate(this::rmdir, fuseScope).address()); - case STATFS -> fuse_operations.statfs$set(struct, fuse_operations.statfs.allocate(this::statfs, fuseScope).address()); - case SYMLINK -> fuse_operations.symlink$set(struct, fuse_operations.symlink.allocate(this::symlink, fuseScope).address()); - case TRUNCATE -> fuse_operations.truncate$set(struct, fuse_operations.truncate.allocate(this::truncate, fuseScope).address()); - case UNLINK -> fuse_operations.unlink$set(struct, fuse_operations.unlink.allocate(this::unlink, fuseScope).address()); - case UTIMENS -> fuse_operations.utimens$set(struct, fuse_operations.utimens.allocate(this::utimens, fuseScope).address()); - case WRITE -> fuse_operations.write$set(struct, fuse_operations.write.allocate(this::write, fuseScope).address()); + case ACCESS -> fuse_operations.access$set(fuseOps, fuse_operations.access.allocate(this::access, fuseScope).address()); + case CHMOD -> fuse_operations.chmod$set(fuseOps, fuse_operations.chmod.allocate(this::chmod, fuseScope).address()); + case CREATE -> fuse_operations.create$set(fuseOps, fuse_operations.create.allocate(this::create, fuseScope).address()); + case DESTROY -> fuse_operations.destroy$set(fuseOps, fuse_operations.destroy.allocate(this::destroy, fuseScope).address()); + case GET_ATTR -> fuse_operations.getattr$set(fuseOps, fuse_operations.getattr.allocate(this::getattr, fuseScope).address()); + case MKDIR -> fuse_operations.mkdir$set(fuseOps, fuse_operations.mkdir.allocate(this::mkdir, fuseScope).address()); + case OPEN -> fuse_operations.open$set(fuseOps, fuse_operations.open.allocate(this::open, fuseScope).address()); + case OPEN_DIR -> fuse_operations.opendir$set(fuseOps, fuse_operations.opendir.allocate(this::opendir, fuseScope).address()); + case READ -> fuse_operations.read$set(fuseOps, fuse_operations.read.allocate(this::read, fuseScope).address()); + case READ_DIR -> fuse_operations.readdir$set(fuseOps, fuse_operations.readdir.allocate(this::readdir, fuseScope).address()); + case READLINK -> fuse_operations.readlink$set(fuseOps, fuse_operations.readlink.allocate(this::readlink, fuseScope).address()); + case RELEASE -> fuse_operations.release$set(fuseOps, fuse_operations.release.allocate(this::release, fuseScope).address()); + case RELEASE_DIR -> fuse_operations.releasedir$set(fuseOps, fuse_operations.releasedir.allocate(this::releasedir, fuseScope).address()); + case RENAME -> fuse_operations.rename$set(fuseOps, fuse_operations.rename.allocate(this::rename, fuseScope).address()); + case RMDIR -> fuse_operations.rmdir$set(fuseOps, fuse_operations.rmdir.allocate(this::rmdir, fuseScope).address()); + case STATFS -> fuse_operations.statfs$set(fuseOps, fuse_operations.statfs.allocate(this::statfs, fuseScope).address()); + case SYMLINK -> fuse_operations.symlink$set(fuseOps, fuse_operations.symlink.allocate(this::symlink, fuseScope).address()); + case TRUNCATE -> fuse_operations.truncate$set(fuseOps, fuse_operations.truncate.allocate(this::truncate, fuseScope).address()); + case UNLINK -> fuse_operations.unlink$set(fuseOps, fuse_operations.unlink.allocate(this::unlink, fuseScope).address()); + case UTIMENS -> fuse_operations.utimens$set(fuseOps, fuse_operations.utimens.allocate(this::utimens, fuseScope).address()); + case WRITE -> fuse_operations.write$set(fuseOps, fuse_operations.write.allocate(this::write, fuseScope).address()); } } diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/Constants$root.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/Constants$root.java index 1e4e360d..ebf5a501 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/Constants$root.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/Constants$root.java @@ -2,6 +2,10 @@ package org.cryptomator.jfuse.linux.amd64.extr; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.VarHandle; +import java.nio.ByteOrder; +import jdk.incubator.foreign.*; import static jdk.incubator.foreign.ValueLayout.*; public class Constants$root { diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/RuntimeHelper.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/RuntimeHelper.java index 565b64d3..52ccb2ca 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/RuntimeHelper.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/RuntimeHelper.java @@ -16,7 +16,14 @@ 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 jdk.incubator.foreign.CLinker.*; import static jdk.incubator.foreign.ValueLayout.*; final class RuntimeHelper { 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 f1497925..2f507e39 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 @@ -3,11 +3,38 @@ package org.cryptomator.jfuse.linux.amd64.extr; import java.lang.invoke.MethodHandle; - +import java.lang.invoke.VarHandle; +import java.nio.ByteOrder; import jdk.incubator.foreign.*; - +import static jdk.incubator.foreign.ValueLayout.*; class constants$0 { + static final FunctionDescriptor fuse_mount$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_mount$MH = RuntimeHelper.downcallHandle( + "fuse_mount", + constants$0.fuse_mount$FUNC, false + ); + static final FunctionDescriptor fuse_unmount$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_unmount$MH = RuntimeHelper.downcallHandle( + "fuse_unmount", + constants$0.fuse_unmount$FUNC, false + ); + static final FunctionDescriptor fuse_parse_cmdline$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_POINTER$LAYOUT + ); + static final MethodHandle fuse_parse_cmdline$MH = RuntimeHelper.downcallHandle( + "fuse_parse_cmdline", + constants$0.fuse_parse_cmdline$FUNC, false + ); 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, @@ -17,28 +44,16 @@ class constants$0 { static final MethodHandle fuse_fill_dir_t$MH = RuntimeHelper.downcallHandle( constants$0.fuse_fill_dir_t$FUNC, false ); - static final FunctionDescriptor fuse_exit$FUNC = FunctionDescriptor.ofVoid( - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle fuse_exit$MH = RuntimeHelper.downcallHandle( - "fuse_exit", - constants$0.fuse_exit$FUNC, false - ); - static final FunctionDescriptor fuse_get_context$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT); - static final MethodHandle fuse_get_context$MH = RuntimeHelper.downcallHandle( - "fuse_get_context", - constants$0.fuse_get_context$FUNC, false - ); - static final FunctionDescriptor fuse_main_real$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, - Constants$root.C_INT$LAYOUT, + 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_POINTER$LAYOUT, Constants$root.C_LONG_LONG$LAYOUT, Constants$root.C_POINTER$LAYOUT ); - static final MethodHandle fuse_main_real$MH = RuntimeHelper.downcallHandle( - "fuse_main_real", - constants$0.fuse_main_real$FUNC, false + static final MethodHandle fuse_new$MH = RuntimeHelper.downcallHandle( + "fuse_new", + constants$0.fuse_new$FUNC, false ); } 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 new file mode 100644 index 00000000..c097b0fc --- /dev/null +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/constants$1.java @@ -0,0 +1,51 @@ +// 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 jdk.incubator.foreign.*; +import static jdk.incubator.foreign.ValueLayout.*; +class constants$1 { + + static final FunctionDescriptor fuse_destroy$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_destroy$MH = RuntimeHelper.downcallHandle( + "fuse_destroy", + constants$1.fuse_destroy$FUNC, false + ); + 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$1.fuse_loop$FUNC, false + ); + static final FunctionDescriptor fuse_exit$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_exit$MH = RuntimeHelper.downcallHandle( + "fuse_exit", + constants$1.fuse_exit$FUNC, false + ); + static final FunctionDescriptor fuse_get_context$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT); + static final MethodHandle fuse_get_context$MH = RuntimeHelper.downcallHandle( + "fuse_get_context", + constants$1.fuse_get_context$FUNC, false + ); + static final FunctionDescriptor fuse_main_real$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_INT$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_main_real$MH = RuntimeHelper.downcallHandle( + "fuse_main_real", + constants$1.fuse_main_real$FUNC, false + ); +} + + diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/errno_h.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/errno_h.java index c21a425c..813b4053 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/errno_h.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/errno_h.java @@ -2,6 +2,10 @@ package org.cryptomator.jfuse.linux.amd64.extr; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.VarHandle; +import java.nio.ByteOrder; +import jdk.incubator.foreign.*; import static jdk.incubator.foreign.ValueLayout.*; public class errno_h { diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fcntl_h.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fcntl_h.java index b0affd07..87e7f865 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fcntl_h.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fcntl_h.java @@ -2,6 +2,10 @@ package org.cryptomator.jfuse.linux.amd64.extr; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.VarHandle; +import java.nio.ByteOrder; +import jdk.incubator.foreign.*; import static jdk.incubator.foreign.ValueLayout.*; public class fcntl_h { diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_args.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_args.java new file mode 100644 index 00000000..3a544bb5 --- /dev/null +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_args.java @@ -0,0 +1,82 @@ +// 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 jdk.incubator.foreign.*; +import static jdk.incubator.foreign.ValueLayout.*; +public class fuse_args { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_INT$LAYOUT.withName("argc"), + MemoryLayout.paddingLayout(32), + Constants$root.C_POINTER$LAYOUT.withName("argv"), + Constants$root.C_INT$LAYOUT.withName("allocated"), + MemoryLayout.paddingLayout(32) + ).withName("fuse_args"); + public static MemoryLayout $LAYOUT() { + return fuse_args.$struct$LAYOUT; + } + static final VarHandle argc$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("argc")); + public static VarHandle argc$VH() { + return fuse_args.argc$VH; + } + public static int argc$get(MemorySegment seg) { + return (int)fuse_args.argc$VH.get(seg); + } + public static void argc$set( MemorySegment seg, int x) { + fuse_args.argc$VH.set(seg, x); + } + public static int argc$get(MemorySegment seg, long index) { + return (int)fuse_args.argc$VH.get(seg.asSlice(index*sizeof())); + } + public static void argc$set(MemorySegment seg, long index, int x) { + fuse_args.argc$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle argv$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("argv")); + public static VarHandle argv$VH() { + return fuse_args.argv$VH; + } + public static MemoryAddress argv$get(MemorySegment seg) { + return (jdk.incubator.foreign.MemoryAddress)fuse_args.argv$VH.get(seg); + } + public static void argv$set( MemorySegment seg, MemoryAddress x) { + fuse_args.argv$VH.set(seg, x); + } + public static MemoryAddress argv$get(MemorySegment seg, long index) { + return (jdk.incubator.foreign.MemoryAddress)fuse_args.argv$VH.get(seg.asSlice(index*sizeof())); + } + public static void argv$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_args.argv$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle allocated$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("allocated")); + public static VarHandle allocated$VH() { + return fuse_args.allocated$VH; + } + public static int allocated$get(MemorySegment seg) { + return (int)fuse_args.allocated$VH.get(seg); + } + public static void allocated$set( MemorySegment seg, int x) { + fuse_args.allocated$VH.set(seg, x); + } + public static int allocated$get(MemorySegment seg, long index) { + return (int)fuse_args.allocated$VH.get(seg.asSlice(index*sizeof())); + } + public static void allocated$set(MemorySegment seg, long index, int x) { + fuse_args.allocated$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 allocate(ResourceScope scope) { return allocate(SegmentAllocator.nativeAllocator(scope)); } + public static MemorySegment allocateArray(int len, ResourceScope scope) { + return allocateArray(len, SegmentAllocator.nativeAllocator(scope)); + } + public static MemorySegment ofAddress(MemoryAddress addr, ResourceScope scope) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, scope); } +} + + diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_conn_info.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_conn_info.java index 7c5465b5..c59d9a0a 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_conn_info.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_conn_info.java @@ -2,10 +2,11 @@ package org.cryptomator.jfuse.linux.amd64.extr; +import java.lang.invoke.MethodHandle; import java.lang.invoke.VarHandle; - +import java.nio.ByteOrder; import jdk.incubator.foreign.*; - +import static jdk.incubator.foreign.ValueLayout.*; public class fuse_conn_info { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_context.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_context.java index dae8cf63..79cc3e49 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_context.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_context.java @@ -2,10 +2,11 @@ package org.cryptomator.jfuse.linux.amd64.extr; +import java.lang.invoke.MethodHandle; import java.lang.invoke.VarHandle; - +import java.nio.ByteOrder; import jdk.incubator.foreign.*; - +import static jdk.incubator.foreign.ValueLayout.*; public class fuse_context { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_file_info.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_file_info.java index 41100fc9..73767378 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_file_info.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_file_info.java @@ -2,10 +2,11 @@ package org.cryptomator.jfuse.linux.amd64.extr; +import java.lang.invoke.MethodHandle; import java.lang.invoke.VarHandle; - +import java.nio.ByteOrder; import jdk.incubator.foreign.*; - +import static jdk.incubator.foreign.ValueLayout.*; public class fuse_file_info { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( 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 e775d8dd..b38111bc 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 @@ -2,8 +2,11 @@ package org.cryptomator.jfuse.linux.amd64.extr; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.VarHandle; +import java.nio.ByteOrder; import jdk.incubator.foreign.*; - +import static jdk.incubator.foreign.ValueLayout.*; public interface fuse_fill_dir_t { int apply(jdk.incubator.foreign.MemoryAddress x0, jdk.incubator.foreign.MemoryAddress x1, jdk.incubator.foreign.MemoryAddress x2, long x3); 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 32711209..1ec97535 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 @@ -3,7 +3,8 @@ package org.cryptomator.jfuse.linux.amd64.extr; import java.lang.invoke.MethodHandle; - +import java.lang.invoke.VarHandle; +import java.nio.ByteOrder; import jdk.incubator.foreign.*; import static jdk.incubator.foreign.ValueLayout.*; public class fuse_h { @@ -17,11 +18,77 @@ 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_mount$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_mount$MH,"fuse_mount"); + } + public static MemoryAddress fuse_mount ( Addressable mountpoint, Addressable args) { + var mh$ = RuntimeHelper.requireNonNull(constants$0.fuse_mount$MH, "fuse_mount"); + try { + return (jdk.incubator.foreign.MemoryAddress)mh$.invokeExact(mountpoint, args); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_unmount$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_unmount$MH,"fuse_unmount"); + } + public static void fuse_unmount ( Addressable mountpoint, Addressable ch) { + var mh$ = RuntimeHelper.requireNonNull(constants$0.fuse_unmount$MH, "fuse_unmount"); + try { + mh$.invokeExact(mountpoint, ch); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_parse_cmdline$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_parse_cmdline$MH,"fuse_parse_cmdline"); + } + public static int fuse_parse_cmdline ( Addressable args, Addressable mountpoint, Addressable multithreaded, Addressable foreground) { + var mh$ = RuntimeHelper.requireNonNull(constants$0.fuse_parse_cmdline$MH, "fuse_parse_cmdline"); + try { + return (int)mh$.invokeExact(args, mountpoint, multithreaded, foreground); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_new$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_new$MH,"fuse_new"); + } + public static MemoryAddress fuse_new ( Addressable ch, Addressable args, Addressable op, long op_size, Addressable user_data) { + var mh$ = RuntimeHelper.requireNonNull(constants$0.fuse_new$MH, "fuse_new"); + try { + return (jdk.incubator.foreign.MemoryAddress)mh$.invokeExact(ch, args, op, op_size, user_data); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_destroy$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse_destroy$MH,"fuse_destroy"); + } + public static void fuse_destroy ( Addressable f) { + var mh$ = RuntimeHelper.requireNonNull(constants$1.fuse_destroy$MH, "fuse_destroy"); + try { + mh$.invokeExact(f); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_loop$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse_loop$MH,"fuse_loop"); + } + public static int fuse_loop ( Addressable f) { + var mh$ = RuntimeHelper.requireNonNull(constants$1.fuse_loop$MH, "fuse_loop"); + try { + return (int)mh$.invokeExact(f); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } public static MethodHandle fuse_exit$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_exit$MH,"fuse_exit"); + return RuntimeHelper.requireNonNull(constants$1.fuse_exit$MH,"fuse_exit"); } public static void fuse_exit ( Addressable f) { - var mh$ = RuntimeHelper.requireNonNull(constants$0.fuse_exit$MH, "fuse_exit"); + var mh$ = RuntimeHelper.requireNonNull(constants$1.fuse_exit$MH, "fuse_exit"); try { mh$.invokeExact(f); } catch (Throwable ex$) { @@ -29,10 +96,10 @@ public static void fuse_exit ( Addressable f) { } } public static MethodHandle fuse_get_context$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_get_context$MH,"fuse_get_context"); + return RuntimeHelper.requireNonNull(constants$1.fuse_get_context$MH,"fuse_get_context"); } public static MemoryAddress fuse_get_context () { - var mh$ = RuntimeHelper.requireNonNull(constants$0.fuse_get_context$MH, "fuse_get_context"); + var mh$ = RuntimeHelper.requireNonNull(constants$1.fuse_get_context$MH, "fuse_get_context"); try { return (jdk.incubator.foreign.MemoryAddress)mh$.invokeExact(); } catch (Throwable ex$) { @@ -40,10 +107,10 @@ public static MemoryAddress fuse_get_context () { } } public static MethodHandle fuse_main_real$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_main_real$MH,"fuse_main_real"); + return RuntimeHelper.requireNonNull(constants$1.fuse_main_real$MH,"fuse_main_real"); } public static int fuse_main_real ( int argc, Addressable argv, Addressable op, long op_size, Addressable user_data) { - var mh$ = RuntimeHelper.requireNonNull(constants$0.fuse_main_real$MH, "fuse_main_real"); + var mh$ = RuntimeHelper.requireNonNull(constants$1.fuse_main_real$MH, "fuse_main_real"); try { return (int)mh$.invokeExact(argc, argv, op, op_size, user_data); } catch (Throwable ex$) { diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_operations.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_operations.java index ce80cfa9..12e3b781 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_operations.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_operations.java @@ -4,9 +4,9 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.VarHandle; - +import java.nio.ByteOrder; import jdk.incubator.foreign.*; - +import static jdk.incubator.foreign.ValueLayout.*; public class fuse_operations { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/stat.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/stat.java index bd3feef7..8f8f68ee 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/stat.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/stat.java @@ -2,10 +2,11 @@ package org.cryptomator.jfuse.linux.amd64.extr; +import java.lang.invoke.MethodHandle; import java.lang.invoke.VarHandle; - +import java.nio.ByteOrder; import jdk.incubator.foreign.*; - +import static jdk.incubator.foreign.ValueLayout.*; public class stat { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( 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 bfe795ff..7ab6d9f0 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 @@ -2,6 +2,10 @@ package org.cryptomator.jfuse.linux.amd64.extr; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.VarHandle; +import java.nio.ByteOrder; +import jdk.incubator.foreign.*; import static jdk.incubator.foreign.ValueLayout.*; public class stat_h { diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/statvfs.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/statvfs.java index aa7a997c..f8d85d91 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/statvfs.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/statvfs.java @@ -2,10 +2,11 @@ package org.cryptomator.jfuse.linux.amd64.extr; +import java.lang.invoke.MethodHandle; import java.lang.invoke.VarHandle; - +import java.nio.ByteOrder; import jdk.incubator.foreign.*; - +import static jdk.incubator.foreign.ValueLayout.*; public class statvfs { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/timespec.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/timespec.java index 2ccc06bb..874c824a 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/timespec.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/timespec.java @@ -2,10 +2,11 @@ package org.cryptomator.jfuse.linux.amd64.extr; +import java.lang.invoke.MethodHandle; import java.lang.invoke.VarHandle; - +import java.nio.ByteOrder; import jdk.incubator.foreign.*; - +import static jdk.incubator.foreign.ValueLayout.*; public class timespec { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( diff --git a/jfuse-mac/pom.xml b/jfuse-mac/pom.xml index 3184725e..86c17645 100644 --- a/jfuse-mac/pom.xml +++ b/jfuse-mac/pom.xml @@ -90,7 +90,7 @@ -d ${project.build.sourceDirectory} -t - org.cryptomator.jfuse.win.amd64.extr + org.cryptomator.jfuse.mac.extr -I /usr/local/include -I @@ -112,6 +112,8 @@ timespec --include-struct fuse_conn_info + --include-struct + fuse_args --include-typedef fuse_fill_dir_t @@ -121,7 +123,19 @@ --include-function fuse_get_context --include-function + fuse_parse_cmdline + --include-function + fuse_mount + --include-function + fuse_new + --include-function + fuse_loop + --include-function + fuse_unmount + --include-function fuse_exit + --include-function + fuse_destroy ${project.parent.basedir}/libfuse/include/fuse.h @@ -141,7 +155,7 @@ -d ${project.build.sourceDirectory} -t - org.cryptomator.jfuse.win.amd64.extr + org.cryptomator.jfuse.mac.extr -I ${mac.headerSearchPath} @@ -188,7 +202,7 @@ -d ${project.build.sourceDirectory} -t - org.cryptomator.jfuse.win.amd64.extr + org.cryptomator.jfuse.mac.extr -I ${mac.headerSearchPath} @@ -222,7 +236,7 @@ -d ${project.build.sourceDirectory} -t - org.cryptomator.jfuse.win.amd64.extr + org.cryptomator.jfuse.mac.extr -I ${mac.headerSearchPath} diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java index 87d77888..22266b5d 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java @@ -1,29 +1,38 @@ package org.cryptomator.jfuse.mac; +import jdk.incubator.foreign.MemoryAddress; +import jdk.incubator.foreign.MemoryLayout; +import jdk.incubator.foreign.MemorySegment; +import jdk.incubator.foreign.ResourceScope; +import jdk.incubator.foreign.SegmentAllocator; +import jdk.incubator.foreign.ValueLayout; import org.cryptomator.jfuse.api.Fuse; +import org.cryptomator.jfuse.api.FuseArgs; import org.cryptomator.jfuse.api.FuseOperations; +import org.cryptomator.jfuse.api.FuseSession; +import org.cryptomator.jfuse.mac.extr.fuse_args; import org.cryptomator.jfuse.mac.extr.fuse_h; import org.cryptomator.jfuse.mac.extr.fuse_operations; import org.cryptomator.jfuse.mac.extr.stat_h; import org.cryptomator.jfuse.mac.extr.timespec; -import jdk.incubator.foreign.MemoryAddress; -import jdk.incubator.foreign.MemoryLayout; -import jdk.incubator.foreign.MemorySegment; -import jdk.incubator.foreign.ResourceScope; import java.nio.ByteBuffer; +import java.nio.file.Path; +import java.util.List; import java.util.concurrent.CompletableFuture; +import static jdk.incubator.foreign.ValueLayout.JAVA_INT; + public final class FuseImpl extends Fuse { private final CompletableFuture initialized = new CompletableFuture<>(); private final FuseOperations delegate; - private final MemorySegment struct; + private final MemorySegment fuseOps; public FuseImpl(FuseOperations fuseOperations) { - this.struct = fuse_operations.allocate(fuseScope); + this.fuseOps = fuse_operations.allocate(fuseScope); this.delegate = fuseOperations; - fuse_operations.init$set(struct, fuse_operations.init.allocate(this::init, fuseScope).address()); + fuse_operations.init$set(fuseOps, fuse_operations.init.allocate(this::init, fuseScope).address()); fuseOperations.supportedOperations().forEach(this::bind); } @@ -45,42 +54,95 @@ protected CompletableFuture initialized() { } @Override - protected int fuseMain(int argc, MemorySegment argv) { - return fuse_h.fuse_main_real(argc, argv, struct, struct.byteSize(), MemoryAddress.NULL); + protected FuseArgs parseCmdLine(List args, ResourceScope scope) { + var allocator = SegmentAllocator.nativeAllocator(scope); + var multithreaded = allocator.allocate(JAVA_INT, 1); + var foreground = allocator.allocate(JAVA_INT, 1); + var fuseArgs = fuse_args.allocate(allocator); + var argc = args.size(); + var argv = allocator.allocateArray(ValueLayout.ADDRESS, argc); + for (int i = 0; i < argc; i++) { + var cString = allocator.allocateUtf8String(args.get(i)); + argv.setAtIndex(ValueLayout.ADDRESS, i, cString); + } + fuse_args.argc$set(fuseArgs, argc); + fuse_args.argv$set(fuseArgs, argv.address()); + fuse_args.allocated$set(fuseArgs, 0); + int parseResult = fuse_h.fuse_parse_cmdline(fuseArgs, MemoryAddress.NULL, multithreaded, foreground); + if (parseResult != 0) { + throw new IllegalArgumentException("fuse_parse_cmdline failed to parse " + String.join(" ", args)); + } + var isMultiThreaded = multithreaded.get(JAVA_INT, 0) == 1; + var isForeground = foreground.get(JAVA_INT, 0) == 1; + return new FuseArgs(fuseArgs, isMultiThreaded, isForeground); + } + + @Override + protected FuseSession mount(FuseArgs args, Path mountPoint) { + try (var scope = ResourceScope.newConfinedScope()) { + var allocator = SegmentAllocator.nativeAllocator(scope); + var mountPointStr = allocator.allocateUtf8String(mountPoint.toString()); + var ch = fuse_h.fuse_mount(mountPointStr, args.args()); + if (MemoryAddress.NULL.equals(ch)) { + // TODO any cleanup needed? + // TODO use explicit exception type + throw new IllegalArgumentException("Failed to mount to " + mountPoint + " with given args."); + } + var fuse = fuse_h.fuse_new(ch, args.args(), fuseOps, fuseOps.byteSize(), MemoryAddress.NULL); + if (MemoryAddress.NULL.equals(fuse)) { + fuse_h.fuse_unmount(mountPointStr, ch); + // TODO use explicit exception type + throw new IllegalArgumentException("fuse_new failed"); + } + return new FuseSession(mountPoint, ch, fuse); + } + } + + @Override + protected int loop(FuseSession session, boolean multithreaded) { + // TODO support fuse_loop_mt + return fuse_h.fuse_loop(session.fuse()); } -// private void exit() { -// try (var scope = ResourceScope.newConfinedScope()) { -// var ctx = fuse_context.ofAddress(fuse_h.fuse_get_context(), fuseScope); -// var fusePtr = fuse_context.fuse$get(ctx); -// fuse_h.fuse_exit(fusePtr); -// } -// } + @Override + protected void unmount(FuseSession session) { + try (var scope = ResourceScope.newConfinedScope()) { + var allocator = SegmentAllocator.nativeAllocator(scope); + var mountPointStr = allocator.allocateUtf8String(session.mountPoint().toString()); + fuse_h.fuse_unmount(mountPointStr, session.ch()); + fuse_h.fuse_exit(session.fuse()); + } + } + + @Override + protected void destroy(FuseSession session) { + fuse_h.fuse_destroy(session.fuse()); + } private void bind(FuseOperations.Operation operation) { switch (operation) { case INIT -> { /* handled already */ } - case ACCESS -> fuse_operations.access$set(struct, fuse_operations.access.allocate(this::access, fuseScope).address()); - case CHMOD -> fuse_operations.chmod$set(struct, fuse_operations.chmod.allocate(this::chmod, fuseScope).address()); - case CREATE -> fuse_operations.create$set(struct, fuse_operations.create.allocate(this::create, fuseScope).address()); - case DESTROY -> fuse_operations.destroy$set(struct, fuse_operations.destroy.allocate(this::destroy, fuseScope).address()); - case GET_ATTR -> fuse_operations.getattr$set(struct, fuse_operations.getattr.allocate(this::getattr, fuseScope).address()); - case MKDIR -> fuse_operations.mkdir$set(struct, fuse_operations.mkdir.allocate(this::mkdir, fuseScope).address()); - case OPEN -> fuse_operations.open$set(struct, fuse_operations.open.allocate(this::open, fuseScope).address()); - case OPEN_DIR -> fuse_operations.opendir$set(struct, fuse_operations.opendir.allocate(this::opendir, fuseScope).address()); - case READ -> fuse_operations.read$set(struct, fuse_operations.read.allocate(this::read, fuseScope).address()); - case READ_DIR -> fuse_operations.readdir$set(struct, fuse_operations.readdir.allocate(this::readdir, fuseScope).address()); - case READLINK -> fuse_operations.readlink$set(struct, fuse_operations.readlink.allocate(this::readlink, fuseScope).address()); - case RELEASE -> fuse_operations.release$set(struct, fuse_operations.release.allocate(this::release, fuseScope).address()); - case RELEASE_DIR -> fuse_operations.releasedir$set(struct, fuse_operations.releasedir.allocate(this::releasedir, fuseScope).address()); - case RENAME -> fuse_operations.rename$set(struct, fuse_operations.rename.allocate(this::rename, fuseScope).address()); - case RMDIR -> fuse_operations.rmdir$set(struct, fuse_operations.rmdir.allocate(this::rmdir, fuseScope).address()); - case STATFS -> fuse_operations.statfs$set(struct, fuse_operations.statfs.allocate(this::statfs, fuseScope).address()); - case SYMLINK -> fuse_operations.symlink$set(struct, fuse_operations.symlink.allocate(this::symlink, fuseScope).address()); - case TRUNCATE -> fuse_operations.truncate$set(struct, fuse_operations.truncate.allocate(this::truncate, fuseScope).address()); - case UNLINK -> fuse_operations.unlink$set(struct, fuse_operations.unlink.allocate(this::unlink, fuseScope).address()); - case UTIMENS -> fuse_operations.utimens$set(struct, fuse_operations.utimens.allocate(this::utimens, fuseScope).address()); - case WRITE -> fuse_operations.write$set(struct, fuse_operations.write.allocate(this::write, fuseScope).address()); + case ACCESS -> fuse_operations.access$set(fuseOps, fuse_operations.access.allocate(this::access, fuseScope).address()); + case CHMOD -> fuse_operations.chmod$set(fuseOps, fuse_operations.chmod.allocate(this::chmod, fuseScope).address()); + case CREATE -> fuse_operations.create$set(fuseOps, fuse_operations.create.allocate(this::create, fuseScope).address()); + case DESTROY -> fuse_operations.destroy$set(fuseOps, fuse_operations.destroy.allocate(this::destroy, fuseScope).address()); + case GET_ATTR -> fuse_operations.getattr$set(fuseOps, fuse_operations.getattr.allocate(this::getattr, fuseScope).address()); + case MKDIR -> fuse_operations.mkdir$set(fuseOps, fuse_operations.mkdir.allocate(this::mkdir, fuseScope).address()); + case OPEN -> fuse_operations.open$set(fuseOps, fuse_operations.open.allocate(this::open, fuseScope).address()); + case OPEN_DIR -> fuse_operations.opendir$set(fuseOps, fuse_operations.opendir.allocate(this::opendir, fuseScope).address()); + case READ -> fuse_operations.read$set(fuseOps, fuse_operations.read.allocate(this::read, fuseScope).address()); + case READ_DIR -> fuse_operations.readdir$set(fuseOps, fuse_operations.readdir.allocate(this::readdir, fuseScope).address()); + case READLINK -> fuse_operations.readlink$set(fuseOps, fuse_operations.readlink.allocate(this::readlink, fuseScope).address()); + case RELEASE -> fuse_operations.release$set(fuseOps, fuse_operations.release.allocate(this::release, fuseScope).address()); + case RELEASE_DIR -> fuse_operations.releasedir$set(fuseOps, fuse_operations.releasedir.allocate(this::releasedir, fuseScope).address()); + case RENAME -> fuse_operations.rename$set(fuseOps, fuse_operations.rename.allocate(this::rename, fuseScope).address()); + case RMDIR -> fuse_operations.rmdir$set(fuseOps, fuse_operations.rmdir.allocate(this::rmdir, fuseScope).address()); + case STATFS -> fuse_operations.statfs$set(fuseOps, fuse_operations.statfs.allocate(this::statfs, fuseScope).address()); + case SYMLINK -> fuse_operations.symlink$set(fuseOps, fuse_operations.symlink.allocate(this::symlink, fuseScope).address()); + case TRUNCATE -> fuse_operations.truncate$set(fuseOps, fuse_operations.truncate.allocate(this::truncate, fuseScope).address()); + case UNLINK -> fuse_operations.unlink$set(fuseOps, fuse_operations.unlink.allocate(this::unlink, fuseScope).address()); + case UTIMENS -> fuse_operations.utimens$set(fuseOps, fuse_operations.utimens.allocate(this::utimens, fuseScope).address()); + case WRITE -> fuse_operations.write$set(fuseOps, fuse_operations.write.allocate(this::write, fuseScope).address()); } } diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/Constants$root.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/Constants$root.java index 4aae0ed3..6d19d074 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/Constants$root.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/Constants$root.java @@ -2,6 +2,10 @@ package org.cryptomator.jfuse.mac.extr; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.VarHandle; +import java.nio.ByteOrder; +import jdk.incubator.foreign.*; import static jdk.incubator.foreign.ValueLayout.*; public class Constants$root { diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/RuntimeHelper.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/RuntimeHelper.java index bf5572fb..2dea33b1 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/RuntimeHelper.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/RuntimeHelper.java @@ -16,7 +16,14 @@ 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 jdk.incubator.foreign.CLinker.*; import static jdk.incubator.foreign.ValueLayout.*; final class RuntimeHelper { diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/constants$0.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/constants$0.java index ff0a0845..2704afb0 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/constants$0.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/constants$0.java @@ -3,11 +3,38 @@ package org.cryptomator.jfuse.mac.extr; import java.lang.invoke.MethodHandle; - +import java.lang.invoke.VarHandle; +import java.nio.ByteOrder; import jdk.incubator.foreign.*; - +import static jdk.incubator.foreign.ValueLayout.*; class constants$0 { + static final FunctionDescriptor fuse_mount$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_mount$MH = RuntimeHelper.downcallHandle( + "fuse_mount", + constants$0.fuse_mount$FUNC, false + ); + static final FunctionDescriptor fuse_unmount$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_unmount$MH = RuntimeHelper.downcallHandle( + "fuse_unmount", + constants$0.fuse_unmount$FUNC, false + ); + static final FunctionDescriptor fuse_parse_cmdline$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_POINTER$LAYOUT + ); + static final MethodHandle fuse_parse_cmdline$MH = RuntimeHelper.downcallHandle( + "fuse_parse_cmdline", + constants$0.fuse_parse_cmdline$FUNC, false + ); 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, @@ -17,28 +44,16 @@ class constants$0 { static final MethodHandle fuse_fill_dir_t$MH = RuntimeHelper.downcallHandle( constants$0.fuse_fill_dir_t$FUNC, false ); - static final FunctionDescriptor fuse_exit$FUNC = FunctionDescriptor.ofVoid( - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle fuse_exit$MH = RuntimeHelper.downcallHandle( - "fuse_exit", - constants$0.fuse_exit$FUNC, false - ); - static final FunctionDescriptor fuse_get_context$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT); - static final MethodHandle fuse_get_context$MH = RuntimeHelper.downcallHandle( - "fuse_get_context", - constants$0.fuse_get_context$FUNC, false - ); - static final FunctionDescriptor fuse_main_real$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, - Constants$root.C_INT$LAYOUT, + 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_POINTER$LAYOUT, Constants$root.C_LONG_LONG$LAYOUT, Constants$root.C_POINTER$LAYOUT ); - static final MethodHandle fuse_main_real$MH = RuntimeHelper.downcallHandle( - "fuse_main_real", - constants$0.fuse_main_real$FUNC, false + static final MethodHandle fuse_new$MH = RuntimeHelper.downcallHandle( + "fuse_new", + constants$0.fuse_new$FUNC, false ); } diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/constants$1.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/constants$1.java new file mode 100644 index 00000000..9f22a172 --- /dev/null +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/constants$1.java @@ -0,0 +1,51 @@ +// Generated by jextract + +package org.cryptomator.jfuse.mac.extr; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.VarHandle; +import java.nio.ByteOrder; +import jdk.incubator.foreign.*; +import static jdk.incubator.foreign.ValueLayout.*; +class constants$1 { + + static final FunctionDescriptor fuse_destroy$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_destroy$MH = RuntimeHelper.downcallHandle( + "fuse_destroy", + constants$1.fuse_destroy$FUNC, false + ); + 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$1.fuse_loop$FUNC, false + ); + static final FunctionDescriptor fuse_exit$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_exit$MH = RuntimeHelper.downcallHandle( + "fuse_exit", + constants$1.fuse_exit$FUNC, false + ); + static final FunctionDescriptor fuse_get_context$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT); + static final MethodHandle fuse_get_context$MH = RuntimeHelper.downcallHandle( + "fuse_get_context", + constants$1.fuse_get_context$FUNC, false + ); + static final FunctionDescriptor fuse_main_real$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_INT$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_main_real$MH = RuntimeHelper.downcallHandle( + "fuse_main_real", + constants$1.fuse_main_real$FUNC, false + ); +} + + diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/errno_h.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/errno_h.java index f75695b9..e3863e47 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/errno_h.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/errno_h.java @@ -2,6 +2,10 @@ package org.cryptomator.jfuse.mac.extr; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.VarHandle; +import java.nio.ByteOrder; +import jdk.incubator.foreign.*; import static jdk.incubator.foreign.ValueLayout.*; public class errno_h { diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fcntl_h.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fcntl_h.java index bd690025..9c32078b 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fcntl_h.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fcntl_h.java @@ -2,6 +2,10 @@ package org.cryptomator.jfuse.mac.extr; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.VarHandle; +import java.nio.ByteOrder; +import jdk.incubator.foreign.*; import static jdk.incubator.foreign.ValueLayout.*; public class fcntl_h { diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_args.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_args.java new file mode 100644 index 00000000..d23751f6 --- /dev/null +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_args.java @@ -0,0 +1,82 @@ +// Generated by jextract + +package org.cryptomator.jfuse.mac.extr; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.VarHandle; +import java.nio.ByteOrder; +import jdk.incubator.foreign.*; +import static jdk.incubator.foreign.ValueLayout.*; +public class fuse_args { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_INT$LAYOUT.withName("argc"), + MemoryLayout.paddingLayout(32), + Constants$root.C_POINTER$LAYOUT.withName("argv"), + Constants$root.C_INT$LAYOUT.withName("allocated"), + MemoryLayout.paddingLayout(32) + ).withName("fuse_args"); + public static MemoryLayout $LAYOUT() { + return fuse_args.$struct$LAYOUT; + } + static final VarHandle argc$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("argc")); + public static VarHandle argc$VH() { + return fuse_args.argc$VH; + } + public static int argc$get(MemorySegment seg) { + return (int)fuse_args.argc$VH.get(seg); + } + public static void argc$set( MemorySegment seg, int x) { + fuse_args.argc$VH.set(seg, x); + } + public static int argc$get(MemorySegment seg, long index) { + return (int)fuse_args.argc$VH.get(seg.asSlice(index*sizeof())); + } + public static void argc$set(MemorySegment seg, long index, int x) { + fuse_args.argc$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle argv$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("argv")); + public static VarHandle argv$VH() { + return fuse_args.argv$VH; + } + public static MemoryAddress argv$get(MemorySegment seg) { + return (jdk.incubator.foreign.MemoryAddress)fuse_args.argv$VH.get(seg); + } + public static void argv$set( MemorySegment seg, MemoryAddress x) { + fuse_args.argv$VH.set(seg, x); + } + public static MemoryAddress argv$get(MemorySegment seg, long index) { + return (jdk.incubator.foreign.MemoryAddress)fuse_args.argv$VH.get(seg.asSlice(index*sizeof())); + } + public static void argv$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_args.argv$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle allocated$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("allocated")); + public static VarHandle allocated$VH() { + return fuse_args.allocated$VH; + } + public static int allocated$get(MemorySegment seg) { + return (int)fuse_args.allocated$VH.get(seg); + } + public static void allocated$set( MemorySegment seg, int x) { + fuse_args.allocated$VH.set(seg, x); + } + public static int allocated$get(MemorySegment seg, long index) { + return (int)fuse_args.allocated$VH.get(seg.asSlice(index*sizeof())); + } + public static void allocated$set(MemorySegment seg, long index, int x) { + fuse_args.allocated$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 allocate(ResourceScope scope) { return allocate(SegmentAllocator.nativeAllocator(scope)); } + public static MemorySegment allocateArray(int len, ResourceScope scope) { + return allocateArray(len, SegmentAllocator.nativeAllocator(scope)); + } + public static MemorySegment ofAddress(MemoryAddress addr, ResourceScope scope) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, scope); } +} + + diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_conn_info.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_conn_info.java index 23c10d72..30561ff6 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_conn_info.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_conn_info.java @@ -2,10 +2,11 @@ package org.cryptomator.jfuse.mac.extr; +import java.lang.invoke.MethodHandle; import java.lang.invoke.VarHandle; - +import java.nio.ByteOrder; import jdk.incubator.foreign.*; - +import static jdk.incubator.foreign.ValueLayout.*; public class fuse_conn_info { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_context.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_context.java index 0f13e6ac..42bf8eca 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_context.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_context.java @@ -2,10 +2,11 @@ package org.cryptomator.jfuse.mac.extr; +import java.lang.invoke.MethodHandle; import java.lang.invoke.VarHandle; - +import java.nio.ByteOrder; import jdk.incubator.foreign.*; - +import static jdk.incubator.foreign.ValueLayout.*; public class fuse_context { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_file_info.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_file_info.java index 844c369e..23e53250 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_file_info.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_file_info.java @@ -2,10 +2,11 @@ package org.cryptomator.jfuse.mac.extr; +import java.lang.invoke.MethodHandle; import java.lang.invoke.VarHandle; - +import java.nio.ByteOrder; import jdk.incubator.foreign.*; - +import static jdk.incubator.foreign.ValueLayout.*; public class fuse_file_info { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_fill_dir_t.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_fill_dir_t.java index d35e3fe9..9342eeec 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_fill_dir_t.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_fill_dir_t.java @@ -2,8 +2,11 @@ package org.cryptomator.jfuse.mac.extr; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.VarHandle; +import java.nio.ByteOrder; import jdk.incubator.foreign.*; - +import static jdk.incubator.foreign.ValueLayout.*; public interface fuse_fill_dir_t { int apply(jdk.incubator.foreign.MemoryAddress x0, jdk.incubator.foreign.MemoryAddress x1, jdk.incubator.foreign.MemoryAddress x2, long x3); diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_h.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_h.java index 00f28bda..fc2f693b 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_h.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_h.java @@ -3,7 +3,8 @@ package org.cryptomator.jfuse.mac.extr; import java.lang.invoke.MethodHandle; - +import java.lang.invoke.VarHandle; +import java.nio.ByteOrder; import jdk.incubator.foreign.*; import static jdk.incubator.foreign.ValueLayout.*; public class fuse_h { @@ -17,11 +18,77 @@ 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_mount$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_mount$MH,"fuse_mount"); + } + public static MemoryAddress fuse_mount ( Addressable mountpoint, Addressable args) { + var mh$ = RuntimeHelper.requireNonNull(constants$0.fuse_mount$MH, "fuse_mount"); + try { + return (jdk.incubator.foreign.MemoryAddress)mh$.invokeExact(mountpoint, args); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_unmount$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_unmount$MH,"fuse_unmount"); + } + public static void fuse_unmount ( Addressable mountpoint, Addressable ch) { + var mh$ = RuntimeHelper.requireNonNull(constants$0.fuse_unmount$MH, "fuse_unmount"); + try { + mh$.invokeExact(mountpoint, ch); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_parse_cmdline$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_parse_cmdline$MH,"fuse_parse_cmdline"); + } + public static int fuse_parse_cmdline ( Addressable args, Addressable mountpoint, Addressable multithreaded, Addressable foreground) { + var mh$ = RuntimeHelper.requireNonNull(constants$0.fuse_parse_cmdline$MH, "fuse_parse_cmdline"); + try { + return (int)mh$.invokeExact(args, mountpoint, multithreaded, foreground); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_new$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_new$MH,"fuse_new"); + } + public static MemoryAddress fuse_new ( Addressable ch, Addressable args, Addressable op, long op_size, Addressable user_data) { + var mh$ = RuntimeHelper.requireNonNull(constants$0.fuse_new$MH, "fuse_new"); + try { + return (jdk.incubator.foreign.MemoryAddress)mh$.invokeExact(ch, args, op, op_size, user_data); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_destroy$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse_destroy$MH,"fuse_destroy"); + } + public static void fuse_destroy ( Addressable f) { + var mh$ = RuntimeHelper.requireNonNull(constants$1.fuse_destroy$MH, "fuse_destroy"); + try { + mh$.invokeExact(f); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_loop$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse_loop$MH,"fuse_loop"); + } + public static int fuse_loop ( Addressable f) { + var mh$ = RuntimeHelper.requireNonNull(constants$1.fuse_loop$MH, "fuse_loop"); + try { + return (int)mh$.invokeExact(f); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } public static MethodHandle fuse_exit$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_exit$MH,"fuse_exit"); + return RuntimeHelper.requireNonNull(constants$1.fuse_exit$MH,"fuse_exit"); } public static void fuse_exit ( Addressable f) { - var mh$ = RuntimeHelper.requireNonNull(constants$0.fuse_exit$MH, "fuse_exit"); + var mh$ = RuntimeHelper.requireNonNull(constants$1.fuse_exit$MH, "fuse_exit"); try { mh$.invokeExact(f); } catch (Throwable ex$) { @@ -29,10 +96,10 @@ public static void fuse_exit ( Addressable f) { } } public static MethodHandle fuse_get_context$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_get_context$MH,"fuse_get_context"); + return RuntimeHelper.requireNonNull(constants$1.fuse_get_context$MH,"fuse_get_context"); } public static MemoryAddress fuse_get_context () { - var mh$ = RuntimeHelper.requireNonNull(constants$0.fuse_get_context$MH, "fuse_get_context"); + var mh$ = RuntimeHelper.requireNonNull(constants$1.fuse_get_context$MH, "fuse_get_context"); try { return (jdk.incubator.foreign.MemoryAddress)mh$.invokeExact(); } catch (Throwable ex$) { @@ -40,10 +107,10 @@ public static MemoryAddress fuse_get_context () { } } public static MethodHandle fuse_main_real$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_main_real$MH,"fuse_main_real"); + return RuntimeHelper.requireNonNull(constants$1.fuse_main_real$MH,"fuse_main_real"); } public static int fuse_main_real ( int argc, Addressable argv, Addressable op, long op_size, Addressable user_data) { - var mh$ = RuntimeHelper.requireNonNull(constants$0.fuse_main_real$MH, "fuse_main_real"); + var mh$ = RuntimeHelper.requireNonNull(constants$1.fuse_main_real$MH, "fuse_main_real"); try { return (int)mh$.invokeExact(argc, argv, op, op_size, user_data); } catch (Throwable ex$) { diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_operations.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_operations.java index 709866b4..fd0c4375 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_operations.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_operations.java @@ -4,9 +4,9 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.VarHandle; - +import java.nio.ByteOrder; import jdk.incubator.foreign.*; - +import static jdk.incubator.foreign.ValueLayout.*; public class fuse_operations { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/stat.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/stat.java index 50eab6f7..579b5024 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/stat.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/stat.java @@ -2,10 +2,11 @@ package org.cryptomator.jfuse.mac.extr; +import java.lang.invoke.MethodHandle; import java.lang.invoke.VarHandle; - +import java.nio.ByteOrder; import jdk.incubator.foreign.*; - +import static jdk.incubator.foreign.ValueLayout.*; public class stat { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/stat_h.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/stat_h.java index 947624a8..aac76157 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/stat_h.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/stat_h.java @@ -2,6 +2,10 @@ package org.cryptomator.jfuse.mac.extr; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.VarHandle; +import java.nio.ByteOrder; +import jdk.incubator.foreign.*; import static jdk.incubator.foreign.ValueLayout.*; public class stat_h { diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/statvfs.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/statvfs.java index 78be2670..0e4144f7 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/statvfs.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/statvfs.java @@ -2,10 +2,11 @@ package org.cryptomator.jfuse.mac.extr; +import java.lang.invoke.MethodHandle; import java.lang.invoke.VarHandle; - +import java.nio.ByteOrder; import jdk.incubator.foreign.*; - +import static jdk.incubator.foreign.ValueLayout.*; public class statvfs { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/timespec.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/timespec.java index 33d10a96..8ae2840b 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/timespec.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/timespec.java @@ -2,10 +2,11 @@ package org.cryptomator.jfuse.mac.extr; +import java.lang.invoke.MethodHandle; import java.lang.invoke.VarHandle; - +import java.nio.ByteOrder; import jdk.incubator.foreign.*; - +import static jdk.incubator.foreign.ValueLayout.*; public class timespec { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( 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 9b85dbcf..07532e04 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 @@ -26,7 +26,6 @@ import java.nio.file.Path; import java.nio.file.StandardOpenOption; import java.time.Duration; -import java.util.concurrent.TimeUnit; @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class MirrorIT { @@ -56,19 +55,7 @@ public void setup(@TempDir Path tmpDir) throws IOException { } @AfterAll - public void teardown() throws IOException, InterruptedException { - if (OS.MAC.isCurrentOs()) { - ProcessBuilder command = new ProcessBuilder("umount", "-f", "--", mirror.getFileName().toString()); - command.directory(mirror.getParent().toFile()); - Process p = command.start(); - p.waitFor(10, TimeUnit.SECONDS); - } else if (OS.LINUX.isCurrentOs()) { - ProcessBuilder command = new ProcessBuilder("fusermount", "-u", "--", mirror.getFileName().toString()); - command.directory(mirror.getParent().toFile()); - Process p = command.start(); - p.waitFor(10, TimeUnit.SECONDS); - } - // TODO add win-specific unmount code + public void teardown() { if (fuse != null) { Assertions.assertTimeoutPreemptively(Duration.ofSeconds(10), fuse::close, "file system still active"); } From 4a5b612ca2ed12249b1d3d025132eee69753b506 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Wed, 2 Mar 2022 14:03:40 +0100 Subject: [PATCH 02/98] always use `-f` flag --- jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java index 86a3c8e2..1f6b2df1 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java @@ -46,7 +46,7 @@ public int mount(String progName, Path mountPoint, String... flags) throws Compl List args = new ArrayList<>(); args.add(progName); args.addAll(List.of(flags)); - // TODO remove?: args.add("-f"); // foreground mode required, so fuse_main_real() blocks + args.add("-f"); // always stay in foreground. don't fork & kill this process via `fuse_daemonize` args.add(mountPoint.toString()); try (var scope = ResourceScope.newConfinedScope()) { From a240d15092b9cb7abff3adab0a123076304c9d04 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Wed, 2 Mar 2022 14:11:16 +0100 Subject: [PATCH 03/98] finer logging & graceful unmount in integration test --- .../java/org/cryptomator/jfuse/api/Fuse.java | 2 ++ .../org/cryptomator/jfuse/tests/MirrorIT.java | 22 +++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java index 1f6b2df1..79fe52e2 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java @@ -121,6 +121,8 @@ public int mount(String progName, Path mountPoint, String... flags) throws Compl /** * Unmounts (if needed) this fuse file system and frees up system resources. + *

+ * Important: Before closing, a graceful unmount via system tools (e.g. {@code fusermount -u}) should be attempted. */ @Override @MustBeInvokedByOverriders 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 07532e04..03036b12 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 @@ -26,10 +26,15 @@ import java.nio.file.Path; import java.nio.file.StandardOpenOption; import java.time.Duration; +import java.util.concurrent.TimeUnit; @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class MirrorIT { + static { + System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "TRACE"); + } + private Path orig; private Path mirror; private Fuse fuse; @@ -50,12 +55,25 @@ public void setup(@TempDir Path tmpDir) throws IOException { fs = new PosixMirrorFileSystem(orig, builder.errno()); } fuse = builder.build(fs); - int result = fuse.mount("mirror-it", mirror, "-s"); + int result = fuse.mount("mirror-it", mirror, "-s", "-d"); Assumptions.assumeTrue(result == 0, "mount failed"); } @AfterAll - public void teardown() { + public void teardown() throws IOException, InterruptedException { + // attempt graceful unmount before closing + if (OS.MAC.isCurrentOs()) { + ProcessBuilder command = new ProcessBuilder("umount", "-f", "--", mirror.getFileName().toString()); + command.directory(mirror.getParent().toFile()); + Process p = command.start(); + p.waitFor(10, TimeUnit.SECONDS); + } else if (OS.LINUX.isCurrentOs()) { + ProcessBuilder command = new ProcessBuilder("fusermount", "-u", "--", mirror.getFileName().toString()); + command.directory(mirror.getParent().toFile()); + Process p = command.start(); + p.waitFor(10, TimeUnit.SECONDS); + } + // TODO add win-specific unmount code? if (fuse != null) { Assertions.assertTimeoutPreemptively(Duration.ofSeconds(10), fuse::close, "file system still active"); } From 3a0350f9940eee0436c0665ee0fd528d2002afba Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Wed, 16 Mar 2022 08:47:52 +0100 Subject: [PATCH 04/98] attempt to replace NULL pointer on fuse_parse_cmdline on Linux --- .../java/org/cryptomator/jfuse/linux/aarch64/FuseImpl.java | 4 +++- .../java/org/cryptomator/jfuse/linux/amd64/FuseImpl.java | 5 ++++- .../src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java | 4 +++- 3 files changed, 10 insertions(+), 3 deletions(-) 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 2701a20b..368c5da4 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 @@ -68,10 +68,12 @@ protected FuseArgs parseCmdLine(List args, ResourceScope scope) { fuse_args.argc$set(fuseArgs, argc); fuse_args.argv$set(fuseArgs, argv.address()); fuse_args.allocated$set(fuseArgs, 0); - int parseResult = fuse_h.fuse_parse_cmdline(fuseArgs, MemoryAddress.NULL, multithreaded, foreground); + var mountPointPtr = allocator.allocate(ValueLayout.ADDRESS); + int parseResult = fuse_h.fuse_parse_cmdline(fuseArgs, mountPointPtr, multithreaded, foreground); if (parseResult != 0) { throw new IllegalArgumentException("fuse_parse_cmdline failed to parse " + String.join(" ", args)); } + var mountPoint = mountPointPtr.get(ValueLayout.ADDRESS, 0).getUtf8String(0); var isMultiThreaded = multithreaded.get(JAVA_INT, 0) == 1; var isForeground = foreground.get(JAVA_INT, 0) == 1; return new FuseArgs(fuseArgs, isMultiThreaded, isForeground); 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 a5360de1..ccfa6664 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 @@ -68,12 +68,15 @@ protected FuseArgs parseCmdLine(List args, ResourceScope scope) { fuse_args.argc$set(fuseArgs, argc); fuse_args.argv$set(fuseArgs, argv.address()); fuse_args.allocated$set(fuseArgs, 0); - int parseResult = fuse_h.fuse_parse_cmdline(fuseArgs, MemoryAddress.NULL, multithreaded, foreground); + var mountPointPtr = allocator.allocate(ValueLayout.ADDRESS); + int parseResult = fuse_h.fuse_parse_cmdline(fuseArgs, mountPointPtr, multithreaded, foreground); if (parseResult != 0) { throw new IllegalArgumentException("fuse_parse_cmdline failed to parse " + String.join(" ", args)); } + var mountPoint = mountPointPtr.get(ValueLayout.ADDRESS, 0).getUtf8String(0); var isMultiThreaded = multithreaded.get(JAVA_INT, 0) == 1; var isForeground = foreground.get(JAVA_INT, 0) == 1; + System.out.println("parsed args mp=" + mountPoint + ", mt=" + isMultiThreaded + ", f=" + isForeground); return new FuseArgs(fuseArgs, isMultiThreaded, isForeground); } diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java index 22266b5d..d801747b 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java @@ -68,10 +68,12 @@ protected FuseArgs parseCmdLine(List args, ResourceScope scope) { fuse_args.argc$set(fuseArgs, argc); fuse_args.argv$set(fuseArgs, argv.address()); fuse_args.allocated$set(fuseArgs, 0); - int parseResult = fuse_h.fuse_parse_cmdline(fuseArgs, MemoryAddress.NULL, multithreaded, foreground); + var mountPointPtr = allocator.allocate(ValueLayout.ADDRESS); + int parseResult = fuse_h.fuse_parse_cmdline(fuseArgs, mountPointPtr, multithreaded, foreground); if (parseResult != 0) { throw new IllegalArgumentException("fuse_parse_cmdline failed to parse " + String.join(" ", args)); } + var mountPoint = mountPointPtr.get(ValueLayout.ADDRESS, 0).getUtf8String(0); var isMultiThreaded = multithreaded.get(JAVA_INT, 0) == 1; var isForeground = foreground.get(JAVA_INT, 0) == 1; return new FuseArgs(fuseArgs, isMultiThreaded, isForeground); From 5a79238b57ba361cb7e389071579990f5b145848 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Wed, 16 Mar 2022 08:56:21 +0100 Subject: [PATCH 05/98] temporary debug logging --- .../org/cryptomator/jfuse/linux/amd64/FuseImpl.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) 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 ccfa6664..ffae8c70 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 @@ -68,6 +68,7 @@ protected FuseArgs parseCmdLine(List args, ResourceScope scope) { fuse_args.argc$set(fuseArgs, argc); fuse_args.argv$set(fuseArgs, argv.address()); fuse_args.allocated$set(fuseArgs, 0); + System.out.println("args: " + String.join(" ", args)); var mountPointPtr = allocator.allocate(ValueLayout.ADDRESS); int parseResult = fuse_h.fuse_parse_cmdline(fuseArgs, mountPointPtr, multithreaded, foreground); if (parseResult != 0) { @@ -76,7 +77,15 @@ protected FuseArgs parseCmdLine(List args, ResourceScope scope) { var mountPoint = mountPointPtr.get(ValueLayout.ADDRESS, 0).getUtf8String(0); var isMultiThreaded = multithreaded.get(JAVA_INT, 0) == 1; var isForeground = foreground.get(JAVA_INT, 0) == 1; - System.out.println("parsed args mp=" + mountPoint + ", mt=" + isMultiThreaded + ", f=" + isForeground); + { + var parsedArgc = fuse_args.argc$get(fuseArgs); + var parsedArgv = fuse_args.argv$get(fuseArgs); + System.out.println("parsed args mp=" + mountPoint + ", mt=" + isMultiThreaded + ", f=" + isForeground + ", argc=" + parsedArgc); + for (int i = 0; i < parsedArgc; i++) { + var cString = parsedArgv.getAtIndex(ValueLayout.ADDRESS, i).getUtf8String(0); + System.out.println("arg[" + i + "]: " + cString); + } + } return new FuseArgs(fuseArgs, isMultiThreaded, isForeground); } From 5419a8b38303a3b8862837ef3f6af887c9a1cfdf Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Wed, 16 Mar 2022 17:00:50 +0100 Subject: [PATCH 06/98] try using fuse_opt_add_arg() to assemble fuse_args --- jfuse-linux-amd64/pom.xml | 2 ++ .../jfuse/linux/amd64/FuseImpl.java | 25 +++++++++++++------ .../jfuse/linux/amd64/extr/constants$0.java | 19 ++++++-------- .../jfuse/linux/amd64/extr/constants$1.java | 11 ++++++++ .../jfuse/linux/amd64/extr/fuse_h.java | 15 +++++++++-- 5 files changed, 51 insertions(+), 21 deletions(-) diff --git a/jfuse-linux-amd64/pom.xml b/jfuse-linux-amd64/pom.xml index 020401f6..b2d9e8a4 100644 --- a/jfuse-linux-amd64/pom.xml +++ b/jfuse-linux-amd64/pom.xml @@ -123,6 +123,8 @@ --include-function fuse_get_context --include-function + fuse_opt_add_arg + --include-function fuse_parse_cmdline --include-function fuse_mount 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 ffae8c70..945e8a8c 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 @@ -59,15 +59,24 @@ protected FuseArgs parseCmdLine(List args, ResourceScope scope) { var multithreaded = allocator.allocate(JAVA_INT, 1); var foreground = allocator.allocate(JAVA_INT, 1); var fuseArgs = fuse_args.allocate(allocator); - var argc = args.size(); - var argv = allocator.allocateArray(ValueLayout.ADDRESS, argc); - for (int i = 0; i < argc; i++) { - var cString = allocator.allocateUtf8String(args.get(i)); - argv.setAtIndex(ValueLayout.ADDRESS, i, cString); - } - fuse_args.argc$set(fuseArgs, argc); + var argv = allocator.allocateArray(ValueLayout.ADDRESS, 1); + argv.setAtIndex(ValueLayout.ADDRESS, 0, MemoryAddress.NULL); + fuse_args.argc$set(fuseArgs, 0); fuse_args.argv$set(fuseArgs, argv.address()); - fuse_args.allocated$set(fuseArgs, 0); + fuse_args.allocated$set(fuseArgs, 1); + for (var arg : args) { + var cString = allocator.allocateUtf8String(arg); + fuse_h.fuse_opt_add_arg(fuseArgs, cString); + } +// var argc = args.size(); +// var argv = allocator.allocateArray(ValueLayout.ADDRESS, argc); +// for (int i = 0; i < argc; i++) { +// var cString = allocator.allocateUtf8String(args.get(i)); +// argv.setAtIndex(ValueLayout.ADDRESS, i, cString); +// } +// fuse_args.argc$set(fuseArgs, argc); +// fuse_args.argv$set(fuseArgs, argv.address()); +// fuse_args.allocated$set(fuseArgs, 0); System.out.println("args: " + String.join(" ", args)); var mountPointPtr = allocator.allocate(ValueLayout.ADDRESS); int parseResult = fuse_h.fuse_parse_cmdline(fuseArgs, mountPointPtr, multithreaded, foreground); 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 2f507e39..0b59d99c 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,6 +9,14 @@ import static jdk.incubator.foreign.ValueLayout.*; class constants$0 { + static final FunctionDescriptor fuse_opt_add_arg$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_opt_add_arg$MH = RuntimeHelper.downcallHandle( + "fuse_opt_add_arg", + constants$0.fuse_opt_add_arg$FUNC, false + ); static final FunctionDescriptor fuse_mount$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT @@ -44,17 +52,6 @@ class constants$0 { static final MethodHandle fuse_fill_dir_t$MH = RuntimeHelper.downcallHandle( constants$0.fuse_fill_dir_t$FUNC, false ); - 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_POINTER$LAYOUT, - Constants$root.C_LONG_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle fuse_new$MH = RuntimeHelper.downcallHandle( - "fuse_new", - constants$0.fuse_new$FUNC, false - ); } 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 c097b0fc..d3a66366 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,6 +9,17 @@ import static jdk.incubator.foreign.ValueLayout.*; class constants$1 { + 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_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_new$MH = RuntimeHelper.downcallHandle( + "fuse_new", + constants$1.fuse_new$FUNC, false + ); static final FunctionDescriptor fuse_destroy$FUNC = FunctionDescriptor.ofVoid( Constants$root.C_POINTER$LAYOUT ); 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 1ec97535..310d07b5 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,6 +18,17 @@ 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_opt_add_arg$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_opt_add_arg$MH,"fuse_opt_add_arg"); + } + public static int fuse_opt_add_arg ( Addressable args, Addressable arg) { + var mh$ = RuntimeHelper.requireNonNull(constants$0.fuse_opt_add_arg$MH, "fuse_opt_add_arg"); + try { + return (int)mh$.invokeExact(args, arg); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } public static MethodHandle fuse_mount$MH() { return RuntimeHelper.requireNonNull(constants$0.fuse_mount$MH,"fuse_mount"); } @@ -52,10 +63,10 @@ public static int fuse_parse_cmdline ( Addressable args, Addressable mountpoint } } 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 ch, Addressable args, Addressable op, long op_size, Addressable user_data) { - var mh$ = RuntimeHelper.requireNonNull(constants$0.fuse_new$MH, "fuse_new"); + var mh$ = RuntimeHelper.requireNonNull(constants$1.fuse_new$MH, "fuse_new"); try { return (jdk.incubator.foreign.MemoryAddress)mh$.invokeExact(ch, args, op, op_size, user_data); } catch (Throwable ex$) { From 48e7c56b765d3b61235d3887b71167dcd9e22d22 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Wed, 16 Mar 2022 17:09:28 +0100 Subject: [PATCH 07/98] simplified fuse_args creation --- .../java/org/cryptomator/jfuse/linux/amd64/FuseImpl.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) 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 945e8a8c..e9ddf3fd 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 @@ -59,11 +59,9 @@ protected FuseArgs parseCmdLine(List args, ResourceScope scope) { var multithreaded = allocator.allocate(JAVA_INT, 1); var foreground = allocator.allocate(JAVA_INT, 1); var fuseArgs = fuse_args.allocate(allocator); - var argv = allocator.allocateArray(ValueLayout.ADDRESS, 1); - argv.setAtIndex(ValueLayout.ADDRESS, 0, MemoryAddress.NULL); fuse_args.argc$set(fuseArgs, 0); - fuse_args.argv$set(fuseArgs, argv.address()); - fuse_args.allocated$set(fuseArgs, 1); + fuse_args.argv$set(fuseArgs, MemoryAddress.NULL); + fuse_args.allocated$set(fuseArgs, 0); for (var arg : args) { var cString = allocator.allocateUtf8String(arg); fuse_h.fuse_opt_add_arg(fuseArgs, cString); From 83280cdaf319454d1c4bef48758da5c0082f8a9f Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Thu, 25 Aug 2022 14:56:25 +0200 Subject: [PATCH 08/98] updated git submodules --- .gitmodules | 2 +- libfuse | 2 +- winfsp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index c16f993b..b8866683 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,7 @@ [submodule "libfuse"] path = libfuse url = https://github.com/libfuse/libfuse.git - branch = fuse-2_9_bugfix + branch = fuse_2_9_bugfix [submodule "winfsp"] path = winfsp diff --git a/libfuse b/libfuse index df499bf1..5a43d0f7 160000 --- a/libfuse +++ b/libfuse @@ -1 +1 @@ -Subproject commit df499bf1ce634f6e67d4d366c4475d32143f00f0 +Subproject commit 5a43d0f724c56f8836f3f92411e0de1b5f82db32 diff --git a/winfsp b/winfsp index 6720dfac..ec832b45 160000 --- a/winfsp +++ b/winfsp @@ -1 +1 @@ -Subproject commit 6720dfacbc3b114a04030c68e392b249f40e4374 +Subproject commit ec832b45ff690ce4c4f9d4c4c66808fdd790ab7f From fab8454ae16181788dc4bef104894146ce5130f2 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Thu, 25 Aug 2022 16:33:36 +0200 Subject: [PATCH 09/98] exit session before unmount MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit see docs of fuse_lowlevel.h → fuse_session_unmount() --- .../main/java/org/cryptomator/jfuse/linux/aarch64/FuseImpl.java | 2 +- .../main/java/org/cryptomator/jfuse/linux/amd64/FuseImpl.java | 2 +- jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) 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 6edc3347..0a574c8c 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 @@ -109,8 +109,8 @@ protected void unmount(FuseSession session) { try (var scope = ResourceScope.newConfinedScope()) { var allocator = SegmentAllocator.nativeAllocator(scope); var mountPointStr = allocator.allocateUtf8String(session.mountPoint().toString()); - fuse_h.fuse_unmount(mountPointStr, session.ch()); fuse_h.fuse_exit(session.fuse()); + fuse_h.fuse_unmount(mountPointStr, session.ch()); } } 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 596637d1..fc37689e 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 @@ -132,8 +132,8 @@ protected void unmount(FuseSession session) { try (var scope = ResourceScope.newConfinedScope()) { var allocator = SegmentAllocator.nativeAllocator(scope); var mountPointStr = allocator.allocateUtf8String(session.mountPoint().toString()); - fuse_h.fuse_unmount(mountPointStr, session.ch()); fuse_h.fuse_exit(session.fuse()); + fuse_h.fuse_unmount(mountPointStr, session.ch()); } } diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java index 6f754c47..78ac1b20 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java @@ -109,8 +109,8 @@ protected void unmount(FuseSession session) { var mountPointStr = scope.allocateUtf8String(session.mountPoint().toString()); //var s = fuse_h.fuse_get_session(session.fuse()); //fuse_lowlevel_h.fuse_session_exit(s); - fuse_h.fuse_unmount(mountPointStr, session.ch()); fuse_h.fuse_exit(session.fuse()); + fuse_h.fuse_unmount(mountPointStr, session.ch()); } } From d3fd16cee72fdf63582ea0a192a46ebc4a792fa1 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Thu, 25 Aug 2022 16:50:59 +0200 Subject: [PATCH 10/98] fixed messed up merge 7ce4a6b --- jfuse-linux-aarch64/pom.xml | 1 + .../jfuse/linux/aarch64/FuseImpl.java | 28 +- .../linux/aarch64/extr/Constants$root.java | 23 + .../linux/aarch64/extr/RuntimeHelper.java | 233 ++ .../jfuse/linux/aarch64/extr/constants$0.java | 60 + .../jfuse/linux/aarch64/extr/constants$1.java | 51 + .../jfuse/linux/aarch64/extr/errno_h.java | 59 + .../jfuse/linux/aarch64/extr/fcntl_h.java | 50 + .../jfuse/linux/aarch64/extr/fuse_args.java | 78 + .../linux/aarch64/extr/fuse_conn_info.java | 182 ++ .../linux/aarch64/extr/fuse_context.java | 129 ++ .../linux/aarch64/extr/fuse_file_info.java | 119 + .../linux/aarch64/extr/fuse_fill_dir_t.java | 28 + .../jfuse/linux/aarch64/extr/fuse_h.java | 122 + .../linux/aarch64/extr/fuse_operations.java | 2050 +++++++++++++++++ .../jfuse/linux/aarch64/extr/stat.java | 254 ++ .../jfuse/linux/aarch64/extr/stat_h.java | 38 + .../jfuse/linux/aarch64/extr/statvfs.java | 216 ++ .../jfuse/linux/aarch64/extr/timespec.java | 59 + jfuse-linux-amd64/pom.xml | 2 + .../jfuse/linux/amd64/FuseImpl.java | 32 +- .../jfuse/linux/amd64/extr/constants$0.java | 19 +- .../jfuse/linux/amd64/extr/constants$1.java | 11 + .../jfuse/linux/amd64/extr/fuse_args.java | 78 + .../jfuse/linux/amd64/extr/fuse_h.java | 13 +- 25 files changed, 3888 insertions(+), 47 deletions(-) create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/Constants$root.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/RuntimeHelper.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/constants$0.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/constants$1.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/errno_h.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fcntl_h.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_args.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_conn_info.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_context.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_file_info.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_fill_dir_t.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_h.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_operations.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/stat.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/stat_h.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/statvfs.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/timespec.java create mode 100644 jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_args.java diff --git a/jfuse-linux-aarch64/pom.xml b/jfuse-linux-aarch64/pom.xml index ddbbc6aa..3236ae43 100644 --- a/jfuse-linux-aarch64/pom.xml +++ b/jfuse-linux-aarch64/pom.xml @@ -117,6 +117,7 @@ statvfs timespec fuse_conn_info + fuse_args 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 0a574c8c..30c2c389 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 @@ -14,12 +14,13 @@ import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; import java.lang.foreign.MemorySession; +import java.lang.foreign.ValueLayout; import java.nio.ByteBuffer; import java.nio.file.Path; import java.util.List; import java.util.concurrent.CompletableFuture; -import static jdk.incubator.foreign.ValueLayout.JAVA_INT; +import static java.lang.foreign.ValueLayout.JAVA_INT; public final class FuseImpl extends Fuse { @@ -52,21 +53,20 @@ protected CompletableFuture initialized() { } @Override - protected FuseArgs parseCmdLine(List args, ResourceScope scope) { - var allocator = SegmentAllocator.nativeAllocator(scope); - var multithreaded = allocator.allocate(JAVA_INT, 1); - var foreground = allocator.allocate(JAVA_INT, 1); - var fuseArgs = fuse_args.allocate(allocator); + protected FuseArgs parseCmdLine(List args, MemorySession scope) { + var multithreaded = scope.allocate(JAVA_INT, 1); + var foreground = scope.allocate(JAVA_INT, 1); + var fuseArgs = fuse_args.allocate(scope); var argc = args.size(); - var argv = allocator.allocateArray(ValueLayout.ADDRESS, argc); + var argv = scope.allocateArray(ValueLayout.ADDRESS, argc); for (int i = 0; i < argc; i++) { - var cString = allocator.allocateUtf8String(args.get(i)); + var cString = scope.allocateUtf8String(args.get(i)); argv.setAtIndex(ValueLayout.ADDRESS, i, cString); } fuse_args.argc$set(fuseArgs, argc); fuse_args.argv$set(fuseArgs, argv.address()); fuse_args.allocated$set(fuseArgs, 0); - var mountPointPtr = allocator.allocate(ValueLayout.ADDRESS); + var mountPointPtr = scope.allocate(ValueLayout.ADDRESS); int parseResult = fuse_h.fuse_parse_cmdline(fuseArgs, mountPointPtr, multithreaded, foreground); if (parseResult != 0) { throw new IllegalArgumentException("fuse_parse_cmdline failed to parse " + String.join(" ", args)); @@ -79,9 +79,8 @@ protected FuseArgs parseCmdLine(List args, ResourceScope scope) { @Override protected FuseSession mount(FuseArgs args, Path mountPoint) { - try (var scope = ResourceScope.newConfinedScope()) { - var allocator = SegmentAllocator.nativeAllocator(scope); - var mountPointStr = allocator.allocateUtf8String(mountPoint.toString()); + try (var scope = MemorySession.openConfined()) { + var mountPointStr = scope.allocateUtf8String(mountPoint.toString()); var ch = fuse_h.fuse_mount(mountPointStr, args.args()); if (MemoryAddress.NULL.equals(ch)) { // TODO any cleanup needed? @@ -106,9 +105,8 @@ protected int loop(FuseSession session, boolean multithreaded) { @Override protected void unmount(FuseSession session) { - try (var scope = ResourceScope.newConfinedScope()) { - var allocator = SegmentAllocator.nativeAllocator(scope); - var mountPointStr = allocator.allocateUtf8String(session.mountPoint().toString()); + try (var scope = MemorySession.openConfined()) { + var mountPointStr = scope.allocateUtf8String(session.mountPoint().toString()); fuse_h.fuse_exit(session.fuse()); fuse_h.fuse_unmount(mountPointStr, session.ch()); } diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/Constants$root.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/Constants$root.java new file mode 100644 index 00000000..b88d269d --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/Constants$root.java @@ -0,0 +1,23 @@ +// 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.*; +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/RuntimeHelper.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/RuntimeHelper.java new file mode 100644 index 00000000..a3dca24c --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/RuntimeHelper.java @@ -0,0 +1,233 @@ +package org.cryptomator.jfuse.linux.aarch64.extr; +// 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/constants$0.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/constants$0.java new file mode 100644 index 00000000..be13a141 --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/constants$0.java @@ -0,0 +1,60 @@ +// 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$0 { + + static final FunctionDescriptor fuse_mount$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_mount$MH = RuntimeHelper.downcallHandle( + "fuse_mount", + constants$0.fuse_mount$FUNC + ); + static final FunctionDescriptor fuse_unmount$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_unmount$MH = RuntimeHelper.downcallHandle( + "fuse_unmount", + constants$0.fuse_unmount$FUNC + ); + static final FunctionDescriptor fuse_parse_cmdline$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_POINTER$LAYOUT + ); + static final MethodHandle fuse_parse_cmdline$MH = RuntimeHelper.downcallHandle( + "fuse_parse_cmdline", + constants$0.fuse_parse_cmdline$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 + ); + static final MethodHandle fuse_fill_dir_t$MH = RuntimeHelper.downcallHandle( + constants$0.fuse_fill_dir_t$FUNC + ); + 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_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_new$MH = RuntimeHelper.downcallHandle( + "fuse_new", + constants$0.fuse_new$FUNC + ); +} + + 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 new file mode 100644 index 00000000..83169215 --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/constants$1.java @@ -0,0 +1,51 @@ +// 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$1 { + + static final FunctionDescriptor fuse_destroy$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_destroy$MH = RuntimeHelper.downcallHandle( + "fuse_destroy", + constants$1.fuse_destroy$FUNC + ); + 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$1.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$1.fuse_exit$FUNC + ); + static final FunctionDescriptor fuse_get_context$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT); + static final MethodHandle fuse_get_context$MH = RuntimeHelper.downcallHandle( + "fuse_get_context", + constants$1.fuse_get_context$FUNC + ); + static final FunctionDescriptor fuse_main_real$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_INT$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_main_real$MH = RuntimeHelper.downcallHandle( + "fuse_main_real", + constants$1.fuse_main_real$FUNC + ); +} + + diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/errno_h.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/errno_h.java new file mode 100644 index 00000000..e7ff1f2e --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/errno_h.java @@ -0,0 +1,59 @@ +// 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.*; +public class errno_h { + + /* package-private */ errno_h() {} + public static OfByte C_CHAR = Constants$root.C_CHAR$LAYOUT; + public static OfShort C_SHORT = Constants$root.C_SHORT$LAYOUT; + public static OfInt C_INT = Constants$root.C_INT$LAYOUT; + public static OfLong C_LONG = Constants$root.C_LONG_LONG$LAYOUT; + public static OfLong C_LONG_LONG = Constants$root.C_LONG_LONG$LAYOUT; + 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 int ENOENT() { + return (int)2L; + } + public static int EIO() { + return (int)5L; + } + public static int EBADF() { + return (int)9L; + } + public static int ENOMEM() { + return (int)12L; + } + public static int EACCES() { + return (int)13L; + } + public static int EEXIST() { + return (int)17L; + } + public static int ENOTDIR() { + return (int)20L; + } + public static int EISDIR() { + return (int)21L; + } + public static int EINVAL() { + return (int)22L; + } + public static int EROFS() { + return (int)30L; + } + public static int ENOSYS() { + return (int)38L; + } + public static int ENOTEMPTY() { + return (int)39L; + } +} + + diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fcntl_h.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fcntl_h.java new file mode 100644 index 00000000..fb3a269b --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fcntl_h.java @@ -0,0 +1,50 @@ +// 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.*; +public class fcntl_h { + + /* package-private */ fcntl_h() {} + public static OfByte C_CHAR = Constants$root.C_CHAR$LAYOUT; + public static OfShort C_SHORT = Constants$root.C_SHORT$LAYOUT; + public static OfInt C_INT = Constants$root.C_INT$LAYOUT; + public static OfLong C_LONG = Constants$root.C_LONG_LONG$LAYOUT; + public static OfLong C_LONG_LONG = Constants$root.C_LONG_LONG$LAYOUT; + 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 int O_RDONLY() { + return (int)0L; + } + public static int O_WRONLY() { + return (int)1L; + } + public static int O_RDWR() { + return (int)2L; + } + public static int O_CREAT() { + return (int)64L; + } + public static int O_EXCL() { + return (int)128L; + } + public static int O_TRUNC() { + return (int)512L; + } + public static int O_APPEND() { + return (int)1024L; + } + public static int O_SYNC() { + return (int)1052672L; + } + public static int O_DSYNC() { + return (int)4096L; + } +} + + diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_args.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_args.java new file mode 100644 index 00000000..6cc3f68c --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_args.java @@ -0,0 +1,78 @@ +// 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.*; +public class fuse_args { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_INT$LAYOUT.withName("argc"), + MemoryLayout.paddingLayout(32), + Constants$root.C_POINTER$LAYOUT.withName("argv"), + Constants$root.C_INT$LAYOUT.withName("allocated"), + MemoryLayout.paddingLayout(32) + ).withName("fuse_args"); + public static MemoryLayout $LAYOUT() { + return fuse_args.$struct$LAYOUT; + } + static final VarHandle argc$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("argc")); + public static VarHandle argc$VH() { + return fuse_args.argc$VH; + } + public static int argc$get(MemorySegment seg) { + return (int)fuse_args.argc$VH.get(seg); + } + public static void argc$set( MemorySegment seg, int x) { + fuse_args.argc$VH.set(seg, x); + } + public static int argc$get(MemorySegment seg, long index) { + return (int)fuse_args.argc$VH.get(seg.asSlice(index*sizeof())); + } + public static void argc$set(MemorySegment seg, long index, int x) { + fuse_args.argc$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle argv$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("argv")); + public static VarHandle argv$VH() { + return fuse_args.argv$VH; + } + public static MemoryAddress argv$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_args.argv$VH.get(seg); + } + public static void argv$set( MemorySegment seg, MemoryAddress x) { + fuse_args.argv$VH.set(seg, x); + } + public static MemoryAddress argv$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_args.argv$VH.get(seg.asSlice(index*sizeof())); + } + public static void argv$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_args.argv$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle allocated$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("allocated")); + public static VarHandle allocated$VH() { + return fuse_args.allocated$VH; + } + public static int allocated$get(MemorySegment seg) { + return (int)fuse_args.allocated$VH.get(seg); + } + public static void allocated$set( MemorySegment seg, int x) { + fuse_args.allocated$VH.set(seg, x); + } + public static int allocated$get(MemorySegment seg, long index) { + return (int)fuse_args.allocated$VH.get(seg.asSlice(index*sizeof())); + } + public static void allocated$set(MemorySegment seg, long index, int x) { + fuse_args.allocated$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-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_conn_info.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_conn_info.java new file mode 100644 index 00000000..10fbc252 --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_conn_info.java @@ -0,0 +1,182 @@ +// 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.*; +public class fuse_conn_info { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_INT$LAYOUT.withName("proto_major"), + Constants$root.C_INT$LAYOUT.withName("proto_minor"), + Constants$root.C_INT$LAYOUT.withName("async_read"), + Constants$root.C_INT$LAYOUT.withName("max_write"), + Constants$root.C_INT$LAYOUT.withName("max_readahead"), + Constants$root.C_INT$LAYOUT.withName("capable"), + Constants$root.C_INT$LAYOUT.withName("want"), + Constants$root.C_INT$LAYOUT.withName("max_background"), + Constants$root.C_INT$LAYOUT.withName("congestion_threshold"), + MemoryLayout.sequenceLayout(23, Constants$root.C_INT$LAYOUT).withName("reserved") + ).withName("fuse_conn_info"); + public static MemoryLayout $LAYOUT() { + return fuse_conn_info.$struct$LAYOUT; + } + static final VarHandle proto_major$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("proto_major")); + public static VarHandle proto_major$VH() { + return fuse_conn_info.proto_major$VH; + } + public static int proto_major$get(MemorySegment seg) { + return (int)fuse_conn_info.proto_major$VH.get(seg); + } + public static void proto_major$set( MemorySegment seg, int x) { + fuse_conn_info.proto_major$VH.set(seg, x); + } + public static int proto_major$get(MemorySegment seg, long index) { + return (int)fuse_conn_info.proto_major$VH.get(seg.asSlice(index*sizeof())); + } + public static void proto_major$set(MemorySegment seg, long index, int x) { + fuse_conn_info.proto_major$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle proto_minor$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("proto_minor")); + public static VarHandle proto_minor$VH() { + return fuse_conn_info.proto_minor$VH; + } + public static int proto_minor$get(MemorySegment seg) { + return (int)fuse_conn_info.proto_minor$VH.get(seg); + } + public static void proto_minor$set( MemorySegment seg, int x) { + fuse_conn_info.proto_minor$VH.set(seg, x); + } + public static int proto_minor$get(MemorySegment seg, long index) { + return (int)fuse_conn_info.proto_minor$VH.get(seg.asSlice(index*sizeof())); + } + public static void proto_minor$set(MemorySegment seg, long index, int x) { + fuse_conn_info.proto_minor$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle async_read$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("async_read")); + public static VarHandle async_read$VH() { + return fuse_conn_info.async_read$VH; + } + public static int async_read$get(MemorySegment seg) { + return (int)fuse_conn_info.async_read$VH.get(seg); + } + public static void async_read$set( MemorySegment seg, int x) { + fuse_conn_info.async_read$VH.set(seg, x); + } + public static int async_read$get(MemorySegment seg, long index) { + return (int)fuse_conn_info.async_read$VH.get(seg.asSlice(index*sizeof())); + } + public static void async_read$set(MemorySegment seg, long index, int x) { + fuse_conn_info.async_read$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle max_write$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max_write")); + public static VarHandle max_write$VH() { + return fuse_conn_info.max_write$VH; + } + public static int max_write$get(MemorySegment seg) { + return (int)fuse_conn_info.max_write$VH.get(seg); + } + public static void max_write$set( MemorySegment seg, int x) { + fuse_conn_info.max_write$VH.set(seg, x); + } + public static int max_write$get(MemorySegment seg, long index) { + return (int)fuse_conn_info.max_write$VH.get(seg.asSlice(index*sizeof())); + } + public static void max_write$set(MemorySegment seg, long index, int x) { + fuse_conn_info.max_write$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle max_readahead$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max_readahead")); + public static VarHandle max_readahead$VH() { + return fuse_conn_info.max_readahead$VH; + } + public static int max_readahead$get(MemorySegment seg) { + return (int)fuse_conn_info.max_readahead$VH.get(seg); + } + public static void max_readahead$set( MemorySegment seg, int x) { + fuse_conn_info.max_readahead$VH.set(seg, x); + } + public static int max_readahead$get(MemorySegment seg, long index) { + return (int)fuse_conn_info.max_readahead$VH.get(seg.asSlice(index*sizeof())); + } + public static void max_readahead$set(MemorySegment seg, long index, int x) { + fuse_conn_info.max_readahead$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle capable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("capable")); + public static VarHandle capable$VH() { + return fuse_conn_info.capable$VH; + } + public static int capable$get(MemorySegment seg) { + return (int)fuse_conn_info.capable$VH.get(seg); + } + public static void capable$set( MemorySegment seg, int x) { + fuse_conn_info.capable$VH.set(seg, x); + } + public static int capable$get(MemorySegment seg, long index) { + return (int)fuse_conn_info.capable$VH.get(seg.asSlice(index*sizeof())); + } + public static void capable$set(MemorySegment seg, long index, int x) { + fuse_conn_info.capable$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle want$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("want")); + public static VarHandle want$VH() { + return fuse_conn_info.want$VH; + } + public static int want$get(MemorySegment seg) { + return (int)fuse_conn_info.want$VH.get(seg); + } + public static void want$set( MemorySegment seg, int x) { + fuse_conn_info.want$VH.set(seg, x); + } + public static int want$get(MemorySegment seg, long index) { + return (int)fuse_conn_info.want$VH.get(seg.asSlice(index*sizeof())); + } + public static void want$set(MemorySegment seg, long index, int x) { + fuse_conn_info.want$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle max_background$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max_background")); + public static VarHandle max_background$VH() { + return fuse_conn_info.max_background$VH; + } + public static int max_background$get(MemorySegment seg) { + return (int)fuse_conn_info.max_background$VH.get(seg); + } + public static void max_background$set( MemorySegment seg, int x) { + fuse_conn_info.max_background$VH.set(seg, x); + } + public static int max_background$get(MemorySegment seg, long index) { + return (int)fuse_conn_info.max_background$VH.get(seg.asSlice(index*sizeof())); + } + public static void max_background$set(MemorySegment seg, long index, int x) { + fuse_conn_info.max_background$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle congestion_threshold$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("congestion_threshold")); + public static VarHandle congestion_threshold$VH() { + return fuse_conn_info.congestion_threshold$VH; + } + public static int congestion_threshold$get(MemorySegment seg) { + return (int)fuse_conn_info.congestion_threshold$VH.get(seg); + } + public static void congestion_threshold$set( MemorySegment seg, int x) { + fuse_conn_info.congestion_threshold$VH.set(seg, x); + } + public static int congestion_threshold$get(MemorySegment seg, long index) { + return (int)fuse_conn_info.congestion_threshold$VH.get(seg.asSlice(index*sizeof())); + } + public static void congestion_threshold$set(MemorySegment seg, long index, int x) { + fuse_conn_info.congestion_threshold$VH.set(seg.asSlice(index*sizeof()), x); + } + public static MemorySegment reserved$slice(MemorySegment seg) { + return seg.asSlice(36, 92); + } + 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-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_context.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_context.java new file mode 100644 index 00000000..a2f1d546 --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_context.java @@ -0,0 +1,129 @@ +// 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.*; +public class fuse_context { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_POINTER$LAYOUT.withName("fuse"), + Constants$root.C_INT$LAYOUT.withName("uid"), + Constants$root.C_INT$LAYOUT.withName("gid"), + Constants$root.C_INT$LAYOUT.withName("pid"), + MemoryLayout.paddingLayout(32), + Constants$root.C_POINTER$LAYOUT.withName("private_data"), + Constants$root.C_INT$LAYOUT.withName("umask"), + MemoryLayout.paddingLayout(32) + ).withName("fuse_context"); + public static MemoryLayout $LAYOUT() { + return fuse_context.$struct$LAYOUT; + } + static final VarHandle fuse$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fuse")); + public static VarHandle fuse$VH() { + return fuse_context.fuse$VH; + } + public static MemoryAddress fuse$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_context.fuse$VH.get(seg); + } + public static void fuse$set( MemorySegment seg, MemoryAddress x) { + fuse_context.fuse$VH.set(seg, x); + } + public static MemoryAddress fuse$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_context.fuse$VH.get(seg.asSlice(index*sizeof())); + } + public static void fuse$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_context.fuse$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle uid$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("uid")); + public static VarHandle uid$VH() { + return fuse_context.uid$VH; + } + public static int uid$get(MemorySegment seg) { + return (int)fuse_context.uid$VH.get(seg); + } + public static void uid$set( MemorySegment seg, int x) { + fuse_context.uid$VH.set(seg, x); + } + public static int uid$get(MemorySegment seg, long index) { + return (int)fuse_context.uid$VH.get(seg.asSlice(index*sizeof())); + } + public static void uid$set(MemorySegment seg, long index, int x) { + fuse_context.uid$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle gid$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("gid")); + public static VarHandle gid$VH() { + return fuse_context.gid$VH; + } + public static int gid$get(MemorySegment seg) { + return (int)fuse_context.gid$VH.get(seg); + } + public static void gid$set( MemorySegment seg, int x) { + fuse_context.gid$VH.set(seg, x); + } + public static int gid$get(MemorySegment seg, long index) { + return (int)fuse_context.gid$VH.get(seg.asSlice(index*sizeof())); + } + public static void gid$set(MemorySegment seg, long index, int x) { + fuse_context.gid$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle pid$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("pid")); + public static VarHandle pid$VH() { + return fuse_context.pid$VH; + } + public static int pid$get(MemorySegment seg) { + return (int)fuse_context.pid$VH.get(seg); + } + public static void pid$set( MemorySegment seg, int x) { + fuse_context.pid$VH.set(seg, x); + } + public static int pid$get(MemorySegment seg, long index) { + return (int)fuse_context.pid$VH.get(seg.asSlice(index*sizeof())); + } + public static void pid$set(MemorySegment seg, long index, int x) { + fuse_context.pid$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle private_data$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("private_data")); + public static VarHandle private_data$VH() { + return fuse_context.private_data$VH; + } + public static MemoryAddress private_data$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_context.private_data$VH.get(seg); + } + public static void private_data$set( MemorySegment seg, MemoryAddress x) { + fuse_context.private_data$VH.set(seg, x); + } + public static MemoryAddress private_data$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_context.private_data$VH.get(seg.asSlice(index*sizeof())); + } + public static void private_data$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_context.private_data$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle umask$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("umask")); + public static VarHandle umask$VH() { + return fuse_context.umask$VH; + } + public static int umask$get(MemorySegment seg) { + return (int)fuse_context.umask$VH.get(seg); + } + public static void umask$set( MemorySegment seg, int x) { + fuse_context.umask$VH.set(seg, x); + } + public static int umask$get(MemorySegment seg, long index) { + return (int)fuse_context.umask$VH.get(seg.asSlice(index*sizeof())); + } + public static void umask$set(MemorySegment seg, long index, int x) { + fuse_context.umask$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-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_file_info.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_file_info.java new file mode 100644 index 00000000..7a727e71 --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_file_info.java @@ -0,0 +1,119 @@ +// 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.*; +public class fuse_file_info { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_INT$LAYOUT.withName("flags"), + MemoryLayout.paddingLayout(32), + Constants$root.C_LONG_LONG$LAYOUT.withName("fh_old"), + Constants$root.C_INT$LAYOUT.withName("writepage"), + MemoryLayout.structLayout( + MemoryLayout.paddingLayout(1).withName("direct_io"), + MemoryLayout.paddingLayout(1).withName("keep_cache"), + MemoryLayout.paddingLayout(1).withName("flush"), + MemoryLayout.paddingLayout(1).withName("nonseekable"), + MemoryLayout.paddingLayout(1).withName("flock_release"), + MemoryLayout.paddingLayout(27).withName("padding") + ), + Constants$root.C_LONG_LONG$LAYOUT.withName("fh"), + Constants$root.C_LONG_LONG$LAYOUT.withName("lock_owner") + ).withName("fuse_file_info"); + public static MemoryLayout $LAYOUT() { + return fuse_file_info.$struct$LAYOUT; + } + static final VarHandle flags$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("flags")); + public static VarHandle flags$VH() { + return fuse_file_info.flags$VH; + } + public static int flags$get(MemorySegment seg) { + return (int)fuse_file_info.flags$VH.get(seg); + } + public static void flags$set( MemorySegment seg, int x) { + fuse_file_info.flags$VH.set(seg, x); + } + public static int flags$get(MemorySegment seg, long index) { + return (int)fuse_file_info.flags$VH.get(seg.asSlice(index*sizeof())); + } + public static void flags$set(MemorySegment seg, long index, int x) { + fuse_file_info.flags$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle fh_old$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fh_old")); + public static VarHandle fh_old$VH() { + return fuse_file_info.fh_old$VH; + } + public static long fh_old$get(MemorySegment seg) { + return (long)fuse_file_info.fh_old$VH.get(seg); + } + public static void fh_old$set( MemorySegment seg, long x) { + fuse_file_info.fh_old$VH.set(seg, x); + } + public static long fh_old$get(MemorySegment seg, long index) { + return (long)fuse_file_info.fh_old$VH.get(seg.asSlice(index*sizeof())); + } + public static void fh_old$set(MemorySegment seg, long index, long x) { + fuse_file_info.fh_old$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle writepage$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("writepage")); + public static VarHandle writepage$VH() { + return fuse_file_info.writepage$VH; + } + public static int writepage$get(MemorySegment seg) { + return (int)fuse_file_info.writepage$VH.get(seg); + } + public static void writepage$set( MemorySegment seg, int x) { + fuse_file_info.writepage$VH.set(seg, x); + } + public static int writepage$get(MemorySegment seg, long index) { + return (int)fuse_file_info.writepage$VH.get(seg.asSlice(index*sizeof())); + } + public static void writepage$set(MemorySegment seg, long index, int x) { + fuse_file_info.writepage$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle fh$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fh")); + public static VarHandle fh$VH() { + return fuse_file_info.fh$VH; + } + public static long fh$get(MemorySegment seg) { + return (long)fuse_file_info.fh$VH.get(seg); + } + public static void fh$set( MemorySegment seg, long x) { + fuse_file_info.fh$VH.set(seg, x); + } + public static long fh$get(MemorySegment seg, long index) { + return (long)fuse_file_info.fh$VH.get(seg.asSlice(index*sizeof())); + } + public static void fh$set(MemorySegment seg, long index, long x) { + fuse_file_info.fh$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle lock_owner$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("lock_owner")); + public static VarHandle lock_owner$VH() { + return fuse_file_info.lock_owner$VH; + } + public static long lock_owner$get(MemorySegment seg) { + return (long)fuse_file_info.lock_owner$VH.get(seg); + } + public static void lock_owner$set( MemorySegment seg, long x) { + fuse_file_info.lock_owner$VH.set(seg, x); + } + public static long lock_owner$get(MemorySegment seg, long index) { + return (long)fuse_file_info.lock_owner$VH.get(seg.asSlice(index*sizeof())); + } + public static void lock_owner$set(MemorySegment seg, long index, long x) { + fuse_file_info.lock_owner$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-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 new file mode 100644 index 00000000..b3ae19d2 --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_fill_dir_t.java @@ -0,0 +1,28 @@ +// 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.*; +public interface fuse_fill_dir_t { + + int apply(java.lang.foreign.MemoryAddress buf, java.lang.foreign.MemoryAddress name, java.lang.foreign.MemoryAddress stbuf, long off); + static MemorySegment allocate(fuse_fill_dir_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(fuse_fill_dir_t.class, fi, constants$0.fuse_fill_dir_t$FUNC, session); + } + 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) -> { + 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); + } 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 new file mode 100644 index 00000000..61847818 --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_h.java @@ -0,0 +1,122 @@ +// 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.*; +public class fuse_h { + + /* package-private */ fuse_h() {} + public static OfByte C_CHAR = Constants$root.C_CHAR$LAYOUT; + public static OfShort C_SHORT = Constants$root.C_SHORT$LAYOUT; + public static OfInt C_INT = Constants$root.C_INT$LAYOUT; + public static OfLong C_LONG = Constants$root.C_LONG_LONG$LAYOUT; + public static OfLong C_LONG_LONG = Constants$root.C_LONG_LONG$LAYOUT; + 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_mount$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_mount$MH,"fuse_mount"); + } + public static MemoryAddress fuse_mount ( Addressable mountpoint, Addressable args) { + var mh$ = fuse_mount$MH(); + try { + return (java.lang.foreign.MemoryAddress)mh$.invokeExact(mountpoint, args); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_unmount$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_unmount$MH,"fuse_unmount"); + } + public static void fuse_unmount ( Addressable mountpoint, Addressable ch) { + var mh$ = fuse_unmount$MH(); + try { + mh$.invokeExact(mountpoint, ch); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_parse_cmdline$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_parse_cmdline$MH,"fuse_parse_cmdline"); + } + public static int fuse_parse_cmdline ( Addressable args, Addressable mountpoint, Addressable multithreaded, Addressable foreground) { + var mh$ = fuse_parse_cmdline$MH(); + try { + return (int)mh$.invokeExact(args, mountpoint, multithreaded, foreground); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_new$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_new$MH,"fuse_new"); + } + public static MemoryAddress fuse_new ( Addressable ch, Addressable args, Addressable op, long op_size, Addressable user_data) { + var mh$ = fuse_new$MH(); + try { + return (java.lang.foreign.MemoryAddress)mh$.invokeExact(ch, args, op, op_size, user_data); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_destroy$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse_destroy$MH,"fuse_destroy"); + } + public static void fuse_destroy ( Addressable f) { + var mh$ = fuse_destroy$MH(); + try { + mh$.invokeExact(f); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_loop$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse_loop$MH,"fuse_loop"); + } + public static int fuse_loop ( Addressable f) { + var mh$ = fuse_loop$MH(); + try { + return (int)mh$.invokeExact(f); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_exit$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse_exit$MH,"fuse_exit"); + } + public static void fuse_exit ( Addressable f) { + var mh$ = fuse_exit$MH(); + try { + mh$.invokeExact(f); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_get_context$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse_get_context$MH,"fuse_get_context"); + } + public static MemoryAddress fuse_get_context () { + var mh$ = fuse_get_context$MH(); + try { + return (java.lang.foreign.MemoryAddress)mh$.invokeExact(); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_main_real$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse_main_real$MH,"fuse_main_real"); + } + public static int fuse_main_real ( int argc, Addressable argv, Addressable op, long op_size, Addressable user_data) { + var mh$ = fuse_main_real$MH(); + try { + return (int)mh$.invokeExact(argc, argv, op, op_size, user_data); + } 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_operations.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_operations.java new file mode 100644 index 00000000..a8338096 --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_operations.java @@ -0,0 +1,2050 @@ +// 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.*; +public class fuse_operations { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_POINTER$LAYOUT.withName("getattr"), + Constants$root.C_POINTER$LAYOUT.withName("readlink"), + Constants$root.C_POINTER$LAYOUT.withName("getdir"), + Constants$root.C_POINTER$LAYOUT.withName("mknod"), + Constants$root.C_POINTER$LAYOUT.withName("mkdir"), + Constants$root.C_POINTER$LAYOUT.withName("unlink"), + Constants$root.C_POINTER$LAYOUT.withName("rmdir"), + Constants$root.C_POINTER$LAYOUT.withName("symlink"), + Constants$root.C_POINTER$LAYOUT.withName("rename"), + Constants$root.C_POINTER$LAYOUT.withName("link"), + Constants$root.C_POINTER$LAYOUT.withName("chmod"), + Constants$root.C_POINTER$LAYOUT.withName("chown"), + Constants$root.C_POINTER$LAYOUT.withName("truncate"), + Constants$root.C_POINTER$LAYOUT.withName("utime"), + Constants$root.C_POINTER$LAYOUT.withName("open"), + Constants$root.C_POINTER$LAYOUT.withName("read"), + Constants$root.C_POINTER$LAYOUT.withName("write"), + Constants$root.C_POINTER$LAYOUT.withName("statfs"), + Constants$root.C_POINTER$LAYOUT.withName("flush"), + Constants$root.C_POINTER$LAYOUT.withName("release"), + Constants$root.C_POINTER$LAYOUT.withName("fsync"), + Constants$root.C_POINTER$LAYOUT.withName("setxattr"), + Constants$root.C_POINTER$LAYOUT.withName("getxattr"), + Constants$root.C_POINTER$LAYOUT.withName("listxattr"), + Constants$root.C_POINTER$LAYOUT.withName("removexattr"), + Constants$root.C_POINTER$LAYOUT.withName("opendir"), + Constants$root.C_POINTER$LAYOUT.withName("readdir"), + Constants$root.C_POINTER$LAYOUT.withName("releasedir"), + Constants$root.C_POINTER$LAYOUT.withName("fsyncdir"), + Constants$root.C_POINTER$LAYOUT.withName("init"), + Constants$root.C_POINTER$LAYOUT.withName("destroy"), + Constants$root.C_POINTER$LAYOUT.withName("access"), + Constants$root.C_POINTER$LAYOUT.withName("create"), + Constants$root.C_POINTER$LAYOUT.withName("ftruncate"), + Constants$root.C_POINTER$LAYOUT.withName("fgetattr"), + Constants$root.C_POINTER$LAYOUT.withName("lock"), + Constants$root.C_POINTER$LAYOUT.withName("utimens"), + Constants$root.C_POINTER$LAYOUT.withName("bmap"), + MemoryLayout.structLayout( + MemoryLayout.paddingLayout(1).withName("flag_nullpath_ok"), + MemoryLayout.paddingLayout(1).withName("flag_nopath"), + MemoryLayout.paddingLayout(1).withName("flag_utime_omit_ok"), + MemoryLayout.paddingLayout(29).withName("flag_reserved"), + MemoryLayout.paddingLayout(32) + ), + Constants$root.C_POINTER$LAYOUT.withName("ioctl"), + Constants$root.C_POINTER$LAYOUT.withName("poll"), + Constants$root.C_POINTER$LAYOUT.withName("write_buf"), + Constants$root.C_POINTER$LAYOUT.withName("read_buf"), + Constants$root.C_POINTER$LAYOUT.withName("flock"), + Constants$root.C_POINTER$LAYOUT.withName("fallocate") + ).withName("fuse_operations"); + public static MemoryLayout $LAYOUT() { + return fuse_operations.$struct$LAYOUT; + } + static final FunctionDescriptor getattr$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle getattr$MH = RuntimeHelper.downcallHandle( + fuse_operations.getattr$FUNC + ); + public interface getattr { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); + static MemorySegment allocate(getattr fi, MemorySession session) { + return RuntimeHelper.upcallStub(getattr.class, fi, fuse_operations.getattr$FUNC, session); + } + static getattr ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { + try { + return (int)fuse_operations.getattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle getattr$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("getattr")); + public static VarHandle getattr$VH() { + return fuse_operations.getattr$VH; + } + public static MemoryAddress getattr$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.getattr$VH.get(seg); + } + public static void getattr$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.getattr$VH.set(seg, x); + } + public static MemoryAddress getattr$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.getattr$VH.get(seg.asSlice(index*sizeof())); + } + public static void getattr$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.getattr$VH.set(seg.asSlice(index*sizeof()), x); + } + public static getattr getattr (MemorySegment segment, MemorySession session) { + return getattr.ofAddress(getattr$get(segment), session); + } + static final FunctionDescriptor readlink$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT + ); + static final MethodHandle readlink$MH = RuntimeHelper.downcallHandle( + fuse_operations.readlink$FUNC + ); + public interface readlink { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, long _x2); + static MemorySegment allocate(readlink fi, MemorySession session) { + return RuntimeHelper.upcallStub(readlink.class, fi, fuse_operations.readlink$FUNC, session); + } + static readlink ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, long __x2) -> { + try { + return (int)fuse_operations.readlink$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle readlink$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("readlink")); + public static VarHandle readlink$VH() { + return fuse_operations.readlink$VH; + } + public static MemoryAddress readlink$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.readlink$VH.get(seg); + } + public static void readlink$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.readlink$VH.set(seg, x); + } + public static MemoryAddress readlink$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.readlink$VH.get(seg.asSlice(index*sizeof())); + } + public static void readlink$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.readlink$VH.set(seg.asSlice(index*sizeof()), x); + } + public static readlink readlink (MemorySegment segment, MemorySession session) { + return readlink.ofAddress(readlink$get(segment), session); + } + static final FunctionDescriptor getdir$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle getdir$MH = RuntimeHelper.downcallHandle( + fuse_operations.getdir$FUNC + ); + public interface getdir { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2); + static MemorySegment allocate(getdir fi, MemorySession session) { + return RuntimeHelper.upcallStub(getdir.class, fi, fuse_operations.getdir$FUNC, session); + } + static getdir ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2) -> { + try { + return (int)fuse_operations.getdir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle getdir$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("getdir")); + public static VarHandle getdir$VH() { + return fuse_operations.getdir$VH; + } + public static MemoryAddress getdir$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.getdir$VH.get(seg); + } + public static void getdir$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.getdir$VH.set(seg, x); + } + public static MemoryAddress getdir$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.getdir$VH.get(seg.asSlice(index*sizeof())); + } + public static void getdir$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.getdir$VH.set(seg.asSlice(index*sizeof()), x); + } + public static getdir getdir (MemorySegment segment, MemorySession session) { + return getdir.ofAddress(getdir$get(segment), session); + } + static final FunctionDescriptor mknod$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_INT$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT + ); + static final MethodHandle mknod$MH = RuntimeHelper.downcallHandle( + fuse_operations.mknod$FUNC + ); + public interface mknod { + + int apply(java.lang.foreign.MemoryAddress _x0, int _x1, long _x2); + static MemorySegment allocate(mknod fi, MemorySession session) { + return RuntimeHelper.upcallStub(mknod.class, fi, fuse_operations.mknod$FUNC, session); + } + static mknod ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, int __x1, long __x2) -> { + try { + return (int)fuse_operations.mknod$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, __x2); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle mknod$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("mknod")); + public static VarHandle mknod$VH() { + return fuse_operations.mknod$VH; + } + public static MemoryAddress mknod$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.mknod$VH.get(seg); + } + public static void mknod$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.mknod$VH.set(seg, x); + } + public static MemoryAddress mknod$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.mknod$VH.get(seg.asSlice(index*sizeof())); + } + public static void mknod$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.mknod$VH.set(seg.asSlice(index*sizeof()), x); + } + public static mknod mknod (MemorySegment segment, MemorySession session) { + return mknod.ofAddress(mknod$get(segment), session); + } + static final FunctionDescriptor mkdir$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_INT$LAYOUT + ); + static final MethodHandle mkdir$MH = RuntimeHelper.downcallHandle( + fuse_operations.mkdir$FUNC + ); + public interface mkdir { + + int apply(java.lang.foreign.MemoryAddress _x0, int _x1); + static MemorySegment allocate(mkdir fi, MemorySession session) { + return RuntimeHelper.upcallStub(mkdir.class, fi, fuse_operations.mkdir$FUNC, session); + } + static mkdir ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, int __x1) -> { + try { + return (int)fuse_operations.mkdir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle mkdir$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("mkdir")); + public static VarHandle mkdir$VH() { + return fuse_operations.mkdir$VH; + } + public static MemoryAddress mkdir$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.mkdir$VH.get(seg); + } + public static void mkdir$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.mkdir$VH.set(seg, x); + } + public static MemoryAddress mkdir$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.mkdir$VH.get(seg.asSlice(index*sizeof())); + } + public static void mkdir$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.mkdir$VH.set(seg.asSlice(index*sizeof()), x); + } + public static mkdir mkdir (MemorySegment segment, MemorySession session) { + return mkdir.ofAddress(mkdir$get(segment), session); + } + static final FunctionDescriptor unlink$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle unlink$MH = RuntimeHelper.downcallHandle( + fuse_operations.unlink$FUNC + ); + public interface unlink { + + int apply(java.lang.foreign.MemoryAddress _x0); + static MemorySegment allocate(unlink fi, MemorySession session) { + return RuntimeHelper.upcallStub(unlink.class, fi, fuse_operations.unlink$FUNC, session); + } + static unlink ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0) -> { + try { + return (int)fuse_operations.unlink$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle unlink$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("unlink")); + public static VarHandle unlink$VH() { + return fuse_operations.unlink$VH; + } + public static MemoryAddress unlink$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.unlink$VH.get(seg); + } + public static void unlink$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.unlink$VH.set(seg, x); + } + public static MemoryAddress unlink$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.unlink$VH.get(seg.asSlice(index*sizeof())); + } + public static void unlink$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.unlink$VH.set(seg.asSlice(index*sizeof()), x); + } + public static unlink unlink (MemorySegment segment, MemorySession session) { + return unlink.ofAddress(unlink$get(segment), session); + } + static final FunctionDescriptor rmdir$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle rmdir$MH = RuntimeHelper.downcallHandle( + fuse_operations.rmdir$FUNC + ); + public interface rmdir { + + int apply(java.lang.foreign.MemoryAddress _x0); + static MemorySegment allocate(rmdir fi, MemorySession session) { + return RuntimeHelper.upcallStub(rmdir.class, fi, fuse_operations.rmdir$FUNC, session); + } + static rmdir ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0) -> { + try { + return (int)fuse_operations.rmdir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle rmdir$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rmdir")); + public static VarHandle rmdir$VH() { + return fuse_operations.rmdir$VH; + } + public static MemoryAddress rmdir$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.rmdir$VH.get(seg); + } + public static void rmdir$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.rmdir$VH.set(seg, x); + } + public static MemoryAddress rmdir$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.rmdir$VH.get(seg.asSlice(index*sizeof())); + } + public static void rmdir$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.rmdir$VH.set(seg.asSlice(index*sizeof()), x); + } + public static rmdir rmdir (MemorySegment segment, MemorySession session) { + return rmdir.ofAddress(rmdir$get(segment), session); + } + static final FunctionDescriptor symlink$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle symlink$MH = RuntimeHelper.downcallHandle( + fuse_operations.symlink$FUNC + ); + public interface symlink { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); + static MemorySegment allocate(symlink fi, MemorySession session) { + return RuntimeHelper.upcallStub(symlink.class, fi, fuse_operations.symlink$FUNC, session); + } + static symlink ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { + try { + return (int)fuse_operations.symlink$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle symlink$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("symlink")); + public static VarHandle symlink$VH() { + return fuse_operations.symlink$VH; + } + public static MemoryAddress symlink$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.symlink$VH.get(seg); + } + public static void symlink$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.symlink$VH.set(seg, x); + } + public static MemoryAddress symlink$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.symlink$VH.get(seg.asSlice(index*sizeof())); + } + public static void symlink$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.symlink$VH.set(seg.asSlice(index*sizeof()), x); + } + public static symlink symlink (MemorySegment segment, MemorySession session) { + return symlink.ofAddress(symlink$get(segment), session); + } + static final FunctionDescriptor rename$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle rename$MH = RuntimeHelper.downcallHandle( + fuse_operations.rename$FUNC + ); + public interface rename { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); + static MemorySegment allocate(rename fi, MemorySession session) { + return RuntimeHelper.upcallStub(rename.class, fi, fuse_operations.rename$FUNC, session); + } + static rename ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { + try { + return (int)fuse_operations.rename$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle rename$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rename")); + public static VarHandle rename$VH() { + return fuse_operations.rename$VH; + } + public static MemoryAddress rename$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.rename$VH.get(seg); + } + public static void rename$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.rename$VH.set(seg, x); + } + public static MemoryAddress rename$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.rename$VH.get(seg.asSlice(index*sizeof())); + } + public static void rename$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.rename$VH.set(seg.asSlice(index*sizeof()), x); + } + public static rename rename (MemorySegment segment, MemorySession session) { + return rename.ofAddress(rename$get(segment), session); + } + static final FunctionDescriptor link$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle link$MH = RuntimeHelper.downcallHandle( + fuse_operations.link$FUNC + ); + public interface link { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); + static MemorySegment allocate(link fi, MemorySession session) { + return RuntimeHelper.upcallStub(link.class, fi, fuse_operations.link$FUNC, session); + } + static link ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { + try { + return (int)fuse_operations.link$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle link$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("link")); + public static VarHandle link$VH() { + return fuse_operations.link$VH; + } + public static MemoryAddress link$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.link$VH.get(seg); + } + public static void link$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.link$VH.set(seg, x); + } + public static MemoryAddress link$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.link$VH.get(seg.asSlice(index*sizeof())); + } + public static void link$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.link$VH.set(seg.asSlice(index*sizeof()), x); + } + public static link link (MemorySegment segment, MemorySession session) { + return link.ofAddress(link$get(segment), session); + } + static final FunctionDescriptor chmod$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_INT$LAYOUT + ); + static final MethodHandle chmod$MH = RuntimeHelper.downcallHandle( + fuse_operations.chmod$FUNC + ); + public interface chmod { + + int apply(java.lang.foreign.MemoryAddress _x0, int _x1); + static MemorySegment allocate(chmod fi, MemorySession session) { + return RuntimeHelper.upcallStub(chmod.class, fi, fuse_operations.chmod$FUNC, session); + } + static chmod ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, int __x1) -> { + try { + return (int)fuse_operations.chmod$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle chmod$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("chmod")); + public static VarHandle chmod$VH() { + return fuse_operations.chmod$VH; + } + public static MemoryAddress chmod$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.chmod$VH.get(seg); + } + public static void chmod$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.chmod$VH.set(seg, x); + } + public static MemoryAddress chmod$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.chmod$VH.get(seg.asSlice(index*sizeof())); + } + public static void chmod$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.chmod$VH.set(seg.asSlice(index*sizeof()), x); + } + public static chmod chmod (MemorySegment segment, MemorySession session) { + return chmod.ofAddress(chmod$get(segment), session); + } + static final FunctionDescriptor chown$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_INT$LAYOUT, + Constants$root.C_INT$LAYOUT + ); + static final MethodHandle chown$MH = RuntimeHelper.downcallHandle( + fuse_operations.chown$FUNC + ); + public interface chown { + + int apply(java.lang.foreign.MemoryAddress _x0, int _x1, int _x2); + static MemorySegment allocate(chown fi, MemorySession session) { + return RuntimeHelper.upcallStub(chown.class, fi, fuse_operations.chown$FUNC, session); + } + static chown ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, int __x1, int __x2) -> { + try { + return (int)fuse_operations.chown$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, __x2); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle chown$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("chown")); + public static VarHandle chown$VH() { + return fuse_operations.chown$VH; + } + public static MemoryAddress chown$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.chown$VH.get(seg); + } + public static void chown$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.chown$VH.set(seg, x); + } + public static MemoryAddress chown$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.chown$VH.get(seg.asSlice(index*sizeof())); + } + public static void chown$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.chown$VH.set(seg.asSlice(index*sizeof()), x); + } + public static chown chown (MemorySegment segment, MemorySession session) { + return chown.ofAddress(chown$get(segment), session); + } + static final FunctionDescriptor truncate$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT + ); + static final MethodHandle truncate$MH = RuntimeHelper.downcallHandle( + fuse_operations.truncate$FUNC + ); + public interface truncate { + + int apply(java.lang.foreign.MemoryAddress _x0, long _x1); + static MemorySegment allocate(truncate fi, MemorySession session) { + return RuntimeHelper.upcallStub(truncate.class, fi, fuse_operations.truncate$FUNC, session); + } + static truncate ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, long __x1) -> { + try { + return (int)fuse_operations.truncate$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle truncate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("truncate")); + public static VarHandle truncate$VH() { + return fuse_operations.truncate$VH; + } + public static MemoryAddress truncate$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.truncate$VH.get(seg); + } + public static void truncate$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.truncate$VH.set(seg, x); + } + public static MemoryAddress truncate$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.truncate$VH.get(seg.asSlice(index*sizeof())); + } + public static void truncate$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.truncate$VH.set(seg.asSlice(index*sizeof()), x); + } + public static truncate truncate (MemorySegment segment, MemorySession session) { + return truncate.ofAddress(truncate$get(segment), session); + } + static final FunctionDescriptor utime$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle utime$MH = RuntimeHelper.downcallHandle( + fuse_operations.utime$FUNC + ); + public interface utime { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); + static MemorySegment allocate(utime fi, MemorySession session) { + return RuntimeHelper.upcallStub(utime.class, fi, fuse_operations.utime$FUNC, session); + } + static utime ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { + try { + return (int)fuse_operations.utime$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle utime$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("utime")); + public static VarHandle utime$VH() { + return fuse_operations.utime$VH; + } + public static MemoryAddress utime$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.utime$VH.get(seg); + } + public static void utime$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.utime$VH.set(seg, x); + } + public static MemoryAddress utime$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.utime$VH.get(seg.asSlice(index*sizeof())); + } + public static void utime$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.utime$VH.set(seg.asSlice(index*sizeof()), x); + } + public static utime utime (MemorySegment segment, MemorySession session) { + return utime.ofAddress(utime$get(segment), session); + } + static final FunctionDescriptor open$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle open$MH = RuntimeHelper.downcallHandle( + fuse_operations.open$FUNC + ); + public interface open { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); + static MemorySegment allocate(open fi, MemorySession session) { + return RuntimeHelper.upcallStub(open.class, fi, fuse_operations.open$FUNC, session); + } + static open ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { + try { + return (int)fuse_operations.open$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle open$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("open")); + public static VarHandle open$VH() { + return fuse_operations.open$VH; + } + public static MemoryAddress open$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.open$VH.get(seg); + } + public static void open$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.open$VH.set(seg, x); + } + public static MemoryAddress open$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.open$VH.get(seg.asSlice(index*sizeof())); + } + public static void open$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.open$VH.set(seg.asSlice(index*sizeof()), x); + } + public static open open (MemorySegment segment, MemorySession session) { + return open.ofAddress(open$get(segment), session); + } + static final FunctionDescriptor read$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle read$MH = RuntimeHelper.downcallHandle( + fuse_operations.read$FUNC + ); + public interface read { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, long _x2, long _x3, java.lang.foreign.MemoryAddress _x4); + static MemorySegment allocate(read fi, MemorySession session) { + return RuntimeHelper.upcallStub(read.class, fi, fuse_operations.read$FUNC, session); + } + static read ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, long __x2, long __x3, java.lang.foreign.MemoryAddress __x4) -> { + try { + return (int)fuse_operations.read$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2, __x3, (java.lang.foreign.Addressable)__x4); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle read$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("read")); + public static VarHandle read$VH() { + return fuse_operations.read$VH; + } + public static MemoryAddress read$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.read$VH.get(seg); + } + public static void read$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.read$VH.set(seg, x); + } + public static MemoryAddress read$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.read$VH.get(seg.asSlice(index*sizeof())); + } + public static void read$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.read$VH.set(seg.asSlice(index*sizeof()), x); + } + public static read read (MemorySegment segment, MemorySession session) { + return read.ofAddress(read$get(segment), session); + } + static final FunctionDescriptor write$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle write$MH = RuntimeHelper.downcallHandle( + fuse_operations.write$FUNC + ); + public interface write { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, long _x2, long _x3, java.lang.foreign.MemoryAddress _x4); + static MemorySegment allocate(write fi, MemorySession session) { + return RuntimeHelper.upcallStub(write.class, fi, fuse_operations.write$FUNC, session); + } + static write ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, long __x2, long __x3, java.lang.foreign.MemoryAddress __x4) -> { + try { + return (int)fuse_operations.write$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2, __x3, (java.lang.foreign.Addressable)__x4); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle write$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("write")); + public static VarHandle write$VH() { + return fuse_operations.write$VH; + } + public static MemoryAddress write$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.write$VH.get(seg); + } + public static void write$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.write$VH.set(seg, x); + } + public static MemoryAddress write$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.write$VH.get(seg.asSlice(index*sizeof())); + } + public static void write$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.write$VH.set(seg.asSlice(index*sizeof()), x); + } + public static write write (MemorySegment segment, MemorySession session) { + return write.ofAddress(write$get(segment), session); + } + static final FunctionDescriptor statfs$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle statfs$MH = RuntimeHelper.downcallHandle( + fuse_operations.statfs$FUNC + ); + public interface statfs { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); + static MemorySegment allocate(statfs fi, MemorySession session) { + return RuntimeHelper.upcallStub(statfs.class, fi, fuse_operations.statfs$FUNC, session); + } + static statfs ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { + try { + return (int)fuse_operations.statfs$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle statfs$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("statfs")); + public static VarHandle statfs$VH() { + return fuse_operations.statfs$VH; + } + public static MemoryAddress statfs$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.statfs$VH.get(seg); + } + public static void statfs$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.statfs$VH.set(seg, x); + } + public static MemoryAddress statfs$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.statfs$VH.get(seg.asSlice(index*sizeof())); + } + public static void statfs$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.statfs$VH.set(seg.asSlice(index*sizeof()), x); + } + public static statfs statfs (MemorySegment segment, MemorySession session) { + return statfs.ofAddress(statfs$get(segment), session); + } + static final FunctionDescriptor flush$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle flush$MH = RuntimeHelper.downcallHandle( + fuse_operations.flush$FUNC + ); + public interface flush { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); + static MemorySegment allocate(flush fi, MemorySession session) { + return RuntimeHelper.upcallStub(flush.class, fi, fuse_operations.flush$FUNC, session); + } + static flush ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { + try { + return (int)fuse_operations.flush$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle flush$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("flush")); + public static VarHandle flush$VH() { + return fuse_operations.flush$VH; + } + public static MemoryAddress flush$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.flush$VH.get(seg); + } + public static void flush$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.flush$VH.set(seg, x); + } + public static MemoryAddress flush$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.flush$VH.get(seg.asSlice(index*sizeof())); + } + public static void flush$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.flush$VH.set(seg.asSlice(index*sizeof()), x); + } + public static flush flush (MemorySegment segment, MemorySession session) { + return flush.ofAddress(flush$get(segment), session); + } + static final FunctionDescriptor release$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle release$MH = RuntimeHelper.downcallHandle( + fuse_operations.release$FUNC + ); + public interface release { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); + static MemorySegment allocate(release fi, MemorySession session) { + return RuntimeHelper.upcallStub(release.class, fi, fuse_operations.release$FUNC, session); + } + static release ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { + try { + return (int)fuse_operations.release$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle release$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("release")); + public static VarHandle release$VH() { + return fuse_operations.release$VH; + } + public static MemoryAddress release$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.release$VH.get(seg); + } + public static void release$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.release$VH.set(seg, x); + } + public static MemoryAddress release$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.release$VH.get(seg.asSlice(index*sizeof())); + } + public static void release$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.release$VH.set(seg.asSlice(index*sizeof()), x); + } + public static release release (MemorySegment segment, MemorySession session) { + return release.ofAddress(release$get(segment), session); + } + static final FunctionDescriptor fsync$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fsync$MH = RuntimeHelper.downcallHandle( + fuse_operations.fsync$FUNC + ); + public interface fsync { + + int apply(java.lang.foreign.MemoryAddress _x0, int _x1, java.lang.foreign.MemoryAddress _x2); + static MemorySegment allocate(fsync fi, MemorySession session) { + return RuntimeHelper.upcallStub(fsync.class, fi, fuse_operations.fsync$FUNC, session); + } + static fsync ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, int __x1, java.lang.foreign.MemoryAddress __x2) -> { + try { + return (int)fuse_operations.fsync$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle fsync$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fsync")); + public static VarHandle fsync$VH() { + return fuse_operations.fsync$VH; + } + public static MemoryAddress fsync$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.fsync$VH.get(seg); + } + public static void fsync$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.fsync$VH.set(seg, x); + } + public static MemoryAddress fsync$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.fsync$VH.get(seg.asSlice(index*sizeof())); + } + public static void fsync$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.fsync$VH.set(seg.asSlice(index*sizeof()), x); + } + public static fsync fsync (MemorySegment segment, MemorySession session) { + return fsync.ofAddress(fsync$get(segment), session); + } + static final FunctionDescriptor setxattr$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 setxattr$MH = RuntimeHelper.downcallHandle( + fuse_operations.setxattr$FUNC + ); + public interface setxattr { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2, long _x3, int _x4); + static MemorySegment allocate(setxattr fi, MemorySession session) { + return RuntimeHelper.upcallStub(setxattr.class, fi, fuse_operations.setxattr$FUNC, session); + } + static setxattr ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2, long __x3, int __x4) -> { + try { + return (int)fuse_operations.setxattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2, __x3, __x4); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle setxattr$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("setxattr")); + public static VarHandle setxattr$VH() { + return fuse_operations.setxattr$VH; + } + public static MemoryAddress setxattr$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.setxattr$VH.get(seg); + } + public static void setxattr$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.setxattr$VH.set(seg, x); + } + public static MemoryAddress setxattr$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.setxattr$VH.get(seg.asSlice(index*sizeof())); + } + public static void setxattr$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.setxattr$VH.set(seg.asSlice(index*sizeof()), x); + } + public static setxattr setxattr (MemorySegment segment, MemorySession session) { + return setxattr.ofAddress(setxattr$get(segment), session); + } + static final FunctionDescriptor getxattr$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 + ); + static final MethodHandle getxattr$MH = RuntimeHelper.downcallHandle( + fuse_operations.getxattr$FUNC + ); + public interface getxattr { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2, long _x3); + static MemorySegment allocate(getxattr fi, MemorySession session) { + return RuntimeHelper.upcallStub(getxattr.class, fi, fuse_operations.getxattr$FUNC, session); + } + static getxattr ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2, long __x3) -> { + try { + return (int)fuse_operations.getxattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2, __x3); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle getxattr$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("getxattr")); + public static VarHandle getxattr$VH() { + return fuse_operations.getxattr$VH; + } + public static MemoryAddress getxattr$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.getxattr$VH.get(seg); + } + public static void getxattr$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.getxattr$VH.set(seg, x); + } + public static MemoryAddress getxattr$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.getxattr$VH.get(seg.asSlice(index*sizeof())); + } + public static void getxattr$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.getxattr$VH.set(seg.asSlice(index*sizeof()), x); + } + public static getxattr getxattr (MemorySegment segment, MemorySession session) { + return getxattr.ofAddress(getxattr$get(segment), session); + } + static final FunctionDescriptor listxattr$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT + ); + static final MethodHandle listxattr$MH = RuntimeHelper.downcallHandle( + fuse_operations.listxattr$FUNC + ); + public interface listxattr { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, long _x2); + static MemorySegment allocate(listxattr fi, MemorySession session) { + return RuntimeHelper.upcallStub(listxattr.class, fi, fuse_operations.listxattr$FUNC, session); + } + static listxattr ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, long __x2) -> { + try { + return (int)fuse_operations.listxattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle listxattr$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("listxattr")); + public static VarHandle listxattr$VH() { + return fuse_operations.listxattr$VH; + } + public static MemoryAddress listxattr$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.listxattr$VH.get(seg); + } + public static void listxattr$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.listxattr$VH.set(seg, x); + } + public static MemoryAddress listxattr$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.listxattr$VH.get(seg.asSlice(index*sizeof())); + } + public static void listxattr$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.listxattr$VH.set(seg.asSlice(index*sizeof()), x); + } + public static listxattr listxattr (MemorySegment segment, MemorySession session) { + return listxattr.ofAddress(listxattr$get(segment), session); + } + static final FunctionDescriptor removexattr$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle removexattr$MH = RuntimeHelper.downcallHandle( + fuse_operations.removexattr$FUNC + ); + public interface removexattr { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); + static MemorySegment allocate(removexattr fi, MemorySession session) { + return RuntimeHelper.upcallStub(removexattr.class, fi, fuse_operations.removexattr$FUNC, session); + } + static removexattr ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { + try { + return (int)fuse_operations.removexattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle removexattr$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("removexattr")); + public static VarHandle removexattr$VH() { + return fuse_operations.removexattr$VH; + } + public static MemoryAddress removexattr$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.removexattr$VH.get(seg); + } + public static void removexattr$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.removexattr$VH.set(seg, x); + } + public static MemoryAddress removexattr$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.removexattr$VH.get(seg.asSlice(index*sizeof())); + } + public static void removexattr$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.removexattr$VH.set(seg.asSlice(index*sizeof()), x); + } + public static removexattr removexattr (MemorySegment segment, MemorySession session) { + return removexattr.ofAddress(removexattr$get(segment), session); + } + static final FunctionDescriptor opendir$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle opendir$MH = RuntimeHelper.downcallHandle( + fuse_operations.opendir$FUNC + ); + public interface opendir { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); + static MemorySegment allocate(opendir fi, MemorySession session) { + return RuntimeHelper.upcallStub(opendir.class, fi, fuse_operations.opendir$FUNC, session); + } + static opendir ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { + try { + return (int)fuse_operations.opendir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle opendir$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("opendir")); + public static VarHandle opendir$VH() { + return fuse_operations.opendir$VH; + } + public static MemoryAddress opendir$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.opendir$VH.get(seg); + } + public static void opendir$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.opendir$VH.set(seg, x); + } + public static MemoryAddress opendir$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.opendir$VH.get(seg.asSlice(index*sizeof())); + } + public static void opendir$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.opendir$VH.set(seg.asSlice(index*sizeof()), x); + } + public static opendir opendir (MemorySegment segment, MemorySession session) { + return opendir.ofAddress(opendir$get(segment), session); + } + static final FunctionDescriptor readdir$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_POINTER$LAYOUT + ); + static final MethodHandle readdir$MH = RuntimeHelper.downcallHandle( + fuse_operations.readdir$FUNC + ); + public interface readdir { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2, long _x3, java.lang.foreign.MemoryAddress _x4); + static MemorySegment allocate(readdir fi, MemorySession session) { + return RuntimeHelper.upcallStub(readdir.class, fi, fuse_operations.readdir$FUNC, session); + } + static readdir ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2, long __x3, java.lang.foreign.MemoryAddress __x4) -> { + try { + return (int)fuse_operations.readdir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2, __x3, (java.lang.foreign.Addressable)__x4); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle readdir$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("readdir")); + public static VarHandle readdir$VH() { + return fuse_operations.readdir$VH; + } + public static MemoryAddress readdir$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.readdir$VH.get(seg); + } + public static void readdir$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.readdir$VH.set(seg, x); + } + public static MemoryAddress readdir$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.readdir$VH.get(seg.asSlice(index*sizeof())); + } + public static void readdir$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.readdir$VH.set(seg.asSlice(index*sizeof()), x); + } + public static readdir readdir (MemorySegment segment, MemorySession session) { + return readdir.ofAddress(readdir$get(segment), session); + } + static final FunctionDescriptor releasedir$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle releasedir$MH = RuntimeHelper.downcallHandle( + fuse_operations.releasedir$FUNC + ); + public interface releasedir { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); + static MemorySegment allocate(releasedir fi, MemorySession session) { + return RuntimeHelper.upcallStub(releasedir.class, fi, fuse_operations.releasedir$FUNC, session); + } + static releasedir ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { + try { + return (int)fuse_operations.releasedir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle releasedir$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("releasedir")); + public static VarHandle releasedir$VH() { + return fuse_operations.releasedir$VH; + } + public static MemoryAddress releasedir$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.releasedir$VH.get(seg); + } + public static void releasedir$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.releasedir$VH.set(seg, x); + } + public static MemoryAddress releasedir$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.releasedir$VH.get(seg.asSlice(index*sizeof())); + } + public static void releasedir$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.releasedir$VH.set(seg.asSlice(index*sizeof()), x); + } + public static releasedir releasedir (MemorySegment segment, MemorySession session) { + return releasedir.ofAddress(releasedir$get(segment), session); + } + static final FunctionDescriptor fsyncdir$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fsyncdir$MH = RuntimeHelper.downcallHandle( + fuse_operations.fsyncdir$FUNC + ); + public interface fsyncdir { + + int apply(java.lang.foreign.MemoryAddress _x0, int _x1, java.lang.foreign.MemoryAddress _x2); + static MemorySegment allocate(fsyncdir fi, MemorySession session) { + return RuntimeHelper.upcallStub(fsyncdir.class, fi, fuse_operations.fsyncdir$FUNC, session); + } + static fsyncdir ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, int __x1, java.lang.foreign.MemoryAddress __x2) -> { + try { + return (int)fuse_operations.fsyncdir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle fsyncdir$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fsyncdir")); + public static VarHandle fsyncdir$VH() { + return fuse_operations.fsyncdir$VH; + } + public static MemoryAddress fsyncdir$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.fsyncdir$VH.get(seg); + } + public static void fsyncdir$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.fsyncdir$VH.set(seg, x); + } + public static MemoryAddress fsyncdir$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.fsyncdir$VH.get(seg.asSlice(index*sizeof())); + } + public static void fsyncdir$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.fsyncdir$VH.set(seg.asSlice(index*sizeof()), x); + } + public static fsyncdir fsyncdir (MemorySegment segment, MemorySession session) { + return fsyncdir.ofAddress(fsyncdir$get(segment), session); + } + static final FunctionDescriptor init$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle init$MH = RuntimeHelper.downcallHandle( + fuse_operations.init$FUNC + ); + public interface init { + + java.lang.foreign.Addressable apply(java.lang.foreign.MemoryAddress _x0); + static MemorySegment allocate(init fi, MemorySession session) { + return RuntimeHelper.upcallStub(init.class, fi, fuse_operations.init$FUNC, session); + } + static init ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0) -> { + try { + return (java.lang.foreign.Addressable)(java.lang.foreign.MemoryAddress)fuse_operations.init$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle init$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("init")); + public static VarHandle init$VH() { + return fuse_operations.init$VH; + } + public static MemoryAddress init$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.init$VH.get(seg); + } + public static void init$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.init$VH.set(seg, x); + } + public static MemoryAddress init$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.init$VH.get(seg.asSlice(index*sizeof())); + } + public static void init$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.init$VH.set(seg.asSlice(index*sizeof()), x); + } + public static init init (MemorySegment segment, MemorySession session) { + return init.ofAddress(init$get(segment), session); + } + static final FunctionDescriptor destroy$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle destroy$MH = RuntimeHelper.downcallHandle( + fuse_operations.destroy$FUNC + ); + public interface destroy { + + void apply(java.lang.foreign.MemoryAddress _x0); + static MemorySegment allocate(destroy fi, MemorySession session) { + return RuntimeHelper.upcallStub(destroy.class, fi, fuse_operations.destroy$FUNC, session); + } + static destroy ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0) -> { + try { + fuse_operations.destroy$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle destroy$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("destroy")); + public static VarHandle destroy$VH() { + return fuse_operations.destroy$VH; + } + public static MemoryAddress destroy$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.destroy$VH.get(seg); + } + public static void destroy$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.destroy$VH.set(seg, x); + } + public static MemoryAddress destroy$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.destroy$VH.get(seg.asSlice(index*sizeof())); + } + public static void destroy$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.destroy$VH.set(seg.asSlice(index*sizeof()), x); + } + public static destroy destroy (MemorySegment segment, MemorySession session) { + return destroy.ofAddress(destroy$get(segment), session); + } + static final FunctionDescriptor access$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_INT$LAYOUT + ); + static final MethodHandle access$MH = RuntimeHelper.downcallHandle( + fuse_operations.access$FUNC + ); + public interface access { + + int apply(java.lang.foreign.MemoryAddress _x0, int _x1); + static MemorySegment allocate(access fi, MemorySession session) { + return RuntimeHelper.upcallStub(access.class, fi, fuse_operations.access$FUNC, session); + } + static access ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, int __x1) -> { + try { + return (int)fuse_operations.access$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle access$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("access")); + public static VarHandle access$VH() { + return fuse_operations.access$VH; + } + public static MemoryAddress access$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.access$VH.get(seg); + } + public static void access$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.access$VH.set(seg, x); + } + public static MemoryAddress access$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.access$VH.get(seg.asSlice(index*sizeof())); + } + public static void access$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.access$VH.set(seg.asSlice(index*sizeof()), x); + } + public static access access (MemorySegment segment, MemorySession session) { + return access.ofAddress(access$get(segment), session); + } + static final FunctionDescriptor create$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle create$MH = RuntimeHelper.downcallHandle( + fuse_operations.create$FUNC + ); + public interface create { + + int apply(java.lang.foreign.MemoryAddress _x0, int _x1, java.lang.foreign.MemoryAddress _x2); + static MemorySegment allocate(create fi, MemorySession session) { + return RuntimeHelper.upcallStub(create.class, fi, fuse_operations.create$FUNC, session); + } + static create ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, int __x1, java.lang.foreign.MemoryAddress __x2) -> { + try { + return (int)fuse_operations.create$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle create$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("create")); + public static VarHandle create$VH() { + return fuse_operations.create$VH; + } + public static MemoryAddress create$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.create$VH.get(seg); + } + public static void create$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.create$VH.set(seg, x); + } + public static MemoryAddress create$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.create$VH.get(seg.asSlice(index*sizeof())); + } + public static void create$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.create$VH.set(seg.asSlice(index*sizeof()), x); + } + public static create create (MemorySegment segment, MemorySession session) { + return create.ofAddress(create$get(segment), session); + } + static final FunctionDescriptor ftruncate$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle ftruncate$MH = RuntimeHelper.downcallHandle( + fuse_operations.ftruncate$FUNC + ); + public interface ftruncate { + + int apply(java.lang.foreign.MemoryAddress _x0, long _x1, java.lang.foreign.MemoryAddress _x2); + static MemorySegment allocate(ftruncate fi, MemorySession session) { + return RuntimeHelper.upcallStub(ftruncate.class, fi, fuse_operations.ftruncate$FUNC, session); + } + static ftruncate ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, long __x1, java.lang.foreign.MemoryAddress __x2) -> { + try { + return (int)fuse_operations.ftruncate$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle ftruncate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("ftruncate")); + public static VarHandle ftruncate$VH() { + return fuse_operations.ftruncate$VH; + } + public static MemoryAddress ftruncate$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.ftruncate$VH.get(seg); + } + public static void ftruncate$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.ftruncate$VH.set(seg, x); + } + public static MemoryAddress ftruncate$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.ftruncate$VH.get(seg.asSlice(index*sizeof())); + } + public static void ftruncate$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.ftruncate$VH.set(seg.asSlice(index*sizeof()), x); + } + public static ftruncate ftruncate (MemorySegment segment, MemorySession session) { + return ftruncate.ofAddress(ftruncate$get(segment), session); + } + static final FunctionDescriptor fgetattr$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fgetattr$MH = RuntimeHelper.downcallHandle( + fuse_operations.fgetattr$FUNC + ); + public interface fgetattr { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2); + static MemorySegment allocate(fgetattr fi, MemorySession session) { + return RuntimeHelper.upcallStub(fgetattr.class, fi, fuse_operations.fgetattr$FUNC, session); + } + static fgetattr ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2) -> { + try { + return (int)fuse_operations.fgetattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle fgetattr$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fgetattr")); + public static VarHandle fgetattr$VH() { + return fuse_operations.fgetattr$VH; + } + public static MemoryAddress fgetattr$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.fgetattr$VH.get(seg); + } + public static void fgetattr$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.fgetattr$VH.set(seg, x); + } + public static MemoryAddress fgetattr$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.fgetattr$VH.get(seg.asSlice(index*sizeof())); + } + public static void fgetattr$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.fgetattr$VH.set(seg.asSlice(index*sizeof()), x); + } + public static fgetattr fgetattr (MemorySegment segment, MemorySession session) { + return fgetattr.ofAddress(fgetattr$get(segment), session); + } + static final FunctionDescriptor lock$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle lock$MH = RuntimeHelper.downcallHandle( + fuse_operations.lock$FUNC + ); + public interface lock { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, int _x2, java.lang.foreign.MemoryAddress _x3); + static MemorySegment allocate(lock fi, MemorySession session) { + return RuntimeHelper.upcallStub(lock.class, fi, fuse_operations.lock$FUNC, session); + } + static lock ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, int __x2, java.lang.foreign.MemoryAddress __x3) -> { + try { + return (int)fuse_operations.lock$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2, (java.lang.foreign.Addressable)__x3); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle lock$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("lock")); + public static VarHandle lock$VH() { + return fuse_operations.lock$VH; + } + public static MemoryAddress lock$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.lock$VH.get(seg); + } + public static void lock$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.lock$VH.set(seg, x); + } + public static MemoryAddress lock$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.lock$VH.get(seg.asSlice(index*sizeof())); + } + public static void lock$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.lock$VH.set(seg.asSlice(index*sizeof()), x); + } + public static lock lock (MemorySegment segment, MemorySession session) { + return lock.ofAddress(lock$get(segment), session); + } + static final FunctionDescriptor utimens$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle utimens$MH = RuntimeHelper.downcallHandle( + fuse_operations.utimens$FUNC + ); + public interface utimens { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); + static MemorySegment allocate(utimens fi, MemorySession session) { + return RuntimeHelper.upcallStub(utimens.class, fi, fuse_operations.utimens$FUNC, session); + } + static utimens ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { + try { + return (int)fuse_operations.utimens$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle utimens$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("utimens")); + public static VarHandle utimens$VH() { + return fuse_operations.utimens$VH; + } + public static MemoryAddress utimens$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.utimens$VH.get(seg); + } + public static void utimens$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.utimens$VH.set(seg, x); + } + public static MemoryAddress utimens$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.utimens$VH.get(seg.asSlice(index*sizeof())); + } + public static void utimens$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.utimens$VH.set(seg.asSlice(index*sizeof()), x); + } + public static utimens utimens (MemorySegment segment, MemorySession session) { + return utimens.ofAddress(utimens$get(segment), session); + } + static final FunctionDescriptor bmap$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle bmap$MH = RuntimeHelper.downcallHandle( + fuse_operations.bmap$FUNC + ); + public interface bmap { + + int apply(java.lang.foreign.MemoryAddress _x0, long _x1, java.lang.foreign.MemoryAddress _x2); + static MemorySegment allocate(bmap fi, MemorySession session) { + return RuntimeHelper.upcallStub(bmap.class, fi, fuse_operations.bmap$FUNC, session); + } + static bmap ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, long __x1, java.lang.foreign.MemoryAddress __x2) -> { + try { + return (int)fuse_operations.bmap$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle bmap$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("bmap")); + public static VarHandle bmap$VH() { + return fuse_operations.bmap$VH; + } + public static MemoryAddress bmap$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.bmap$VH.get(seg); + } + public static void bmap$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.bmap$VH.set(seg, x); + } + public static MemoryAddress bmap$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.bmap$VH.get(seg.asSlice(index*sizeof())); + } + public static void bmap$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.bmap$VH.set(seg.asSlice(index*sizeof()), x); + } + public static bmap bmap (MemorySegment segment, MemorySession session) { + return bmap.ofAddress(bmap$get(segment), session); + } + static final FunctionDescriptor ioctl$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle ioctl$MH = RuntimeHelper.downcallHandle( + fuse_operations.ioctl$FUNC + ); + public interface ioctl { + + int apply(java.lang.foreign.MemoryAddress _x0, int _x1, java.lang.foreign.MemoryAddress _x2, java.lang.foreign.MemoryAddress _x3, int _x4, java.lang.foreign.MemoryAddress _x5); + static MemorySegment allocate(ioctl fi, MemorySession session) { + return RuntimeHelper.upcallStub(ioctl.class, fi, fuse_operations.ioctl$FUNC, session); + } + static ioctl ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, int __x1, java.lang.foreign.MemoryAddress __x2, java.lang.foreign.MemoryAddress __x3, int __x4, java.lang.foreign.MemoryAddress __x5) -> { + try { + return (int)fuse_operations.ioctl$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2, (java.lang.foreign.Addressable)__x3, __x4, (java.lang.foreign.Addressable)__x5); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle ioctl$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("ioctl")); + public static VarHandle ioctl$VH() { + return fuse_operations.ioctl$VH; + } + public static MemoryAddress ioctl$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.ioctl$VH.get(seg); + } + public static void ioctl$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.ioctl$VH.set(seg, x); + } + public static MemoryAddress ioctl$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.ioctl$VH.get(seg.asSlice(index*sizeof())); + } + public static void ioctl$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.ioctl$VH.set(seg.asSlice(index*sizeof()), x); + } + public static ioctl ioctl (MemorySegment segment, MemorySession session) { + return ioctl.ofAddress(ioctl$get(segment), session); + } + static final FunctionDescriptor poll$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_POINTER$LAYOUT + ); + static final MethodHandle poll$MH = RuntimeHelper.downcallHandle( + fuse_operations.poll$FUNC + ); + public interface poll { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2, java.lang.foreign.MemoryAddress _x3); + static MemorySegment allocate(poll fi, MemorySession session) { + return RuntimeHelper.upcallStub(poll.class, fi, fuse_operations.poll$FUNC, session); + } + static poll ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2, java.lang.foreign.MemoryAddress __x3) -> { + try { + return (int)fuse_operations.poll$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2, (java.lang.foreign.Addressable)__x3); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle poll$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("poll")); + public static VarHandle poll$VH() { + return fuse_operations.poll$VH; + } + public static MemoryAddress poll$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.poll$VH.get(seg); + } + public static void poll$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.poll$VH.set(seg, x); + } + public static MemoryAddress poll$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.poll$VH.get(seg.asSlice(index*sizeof())); + } + public static void poll$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.poll$VH.set(seg.asSlice(index*sizeof()), x); + } + public static poll poll (MemorySegment segment, MemorySession session) { + return poll.ofAddress(poll$get(segment), session); + } + static final FunctionDescriptor write_buf$FUNC = FunctionDescriptor.of(Constants$root.C_INT$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 write_buf$MH = RuntimeHelper.downcallHandle( + fuse_operations.write_buf$FUNC + ); + public interface write_buf { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, long _x2, java.lang.foreign.MemoryAddress _x3); + static MemorySegment allocate(write_buf fi, MemorySession session) { + return RuntimeHelper.upcallStub(write_buf.class, fi, fuse_operations.write_buf$FUNC, session); + } + static write_buf ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, long __x2, java.lang.foreign.MemoryAddress __x3) -> { + try { + return (int)fuse_operations.write_buf$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2, (java.lang.foreign.Addressable)__x3); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle write_buf$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("write_buf")); + public static VarHandle write_buf$VH() { + return fuse_operations.write_buf$VH; + } + public static MemoryAddress write_buf$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.write_buf$VH.get(seg); + } + public static void write_buf$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.write_buf$VH.set(seg, x); + } + public static MemoryAddress write_buf$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.write_buf$VH.get(seg.asSlice(index*sizeof())); + } + public static void write_buf$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.write_buf$VH.set(seg.asSlice(index*sizeof()), x); + } + public static write_buf write_buf (MemorySegment segment, MemorySession session) { + return write_buf.ofAddress(write_buf$get(segment), session); + } + static final FunctionDescriptor read_buf$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle read_buf$MH = RuntimeHelper.downcallHandle( + fuse_operations.read_buf$FUNC + ); + public interface read_buf { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, long _x2, long _x3, java.lang.foreign.MemoryAddress _x4); + static MemorySegment allocate(read_buf fi, MemorySession session) { + return RuntimeHelper.upcallStub(read_buf.class, fi, fuse_operations.read_buf$FUNC, session); + } + static read_buf ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, long __x2, long __x3, java.lang.foreign.MemoryAddress __x4) -> { + try { + return (int)fuse_operations.read_buf$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2, __x3, (java.lang.foreign.Addressable)__x4); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle read_buf$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("read_buf")); + public static VarHandle read_buf$VH() { + return fuse_operations.read_buf$VH; + } + public static MemoryAddress read_buf$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.read_buf$VH.get(seg); + } + public static void read_buf$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.read_buf$VH.set(seg, x); + } + public static MemoryAddress read_buf$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.read_buf$VH.get(seg.asSlice(index*sizeof())); + } + public static void read_buf$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.read_buf$VH.set(seg.asSlice(index*sizeof()), x); + } + public static read_buf read_buf (MemorySegment segment, MemorySession session) { + return read_buf.ofAddress(read_buf$get(segment), session); + } + static final FunctionDescriptor flock$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_INT$LAYOUT + ); + static final MethodHandle flock$MH = RuntimeHelper.downcallHandle( + fuse_operations.flock$FUNC + ); + public interface flock { + + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, int _x2); + static MemorySegment allocate(flock fi, MemorySession session) { + return RuntimeHelper.upcallStub(flock.class, fi, fuse_operations.flock$FUNC, session); + } + static flock ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, int __x2) -> { + try { + return (int)fuse_operations.flock$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle flock$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("flock")); + public static VarHandle flock$VH() { + return fuse_operations.flock$VH; + } + public static MemoryAddress flock$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.flock$VH.get(seg); + } + public static void flock$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.flock$VH.set(seg, x); + } + public static MemoryAddress flock$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.flock$VH.get(seg.asSlice(index*sizeof())); + } + public static void flock$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.flock$VH.set(seg.asSlice(index*sizeof()), x); + } + public static flock flock (MemorySegment segment, MemorySession session) { + return flock.ofAddress(flock$get(segment), session); + } + static final FunctionDescriptor fallocate$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_INT$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fallocate$MH = RuntimeHelper.downcallHandle( + fuse_operations.fallocate$FUNC + ); + public interface fallocate { + + int apply(java.lang.foreign.MemoryAddress _x0, int _x1, long _x2, long _x3, java.lang.foreign.MemoryAddress _x4); + static MemorySegment allocate(fallocate fi, MemorySession session) { + return RuntimeHelper.upcallStub(fallocate.class, fi, fuse_operations.fallocate$FUNC, session); + } + static fallocate ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, int __x1, long __x2, long __x3, java.lang.foreign.MemoryAddress __x4) -> { + try { + return (int)fuse_operations.fallocate$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, __x2, __x3, (java.lang.foreign.Addressable)__x4); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle fallocate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fallocate")); + public static VarHandle fallocate$VH() { + return fuse_operations.fallocate$VH; + } + public static MemoryAddress fallocate$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.fallocate$VH.get(seg); + } + public static void fallocate$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.fallocate$VH.set(seg, x); + } + public static MemoryAddress fallocate$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.fallocate$VH.get(seg.asSlice(index*sizeof())); + } + public static void fallocate$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.fallocate$VH.set(seg.asSlice(index*sizeof()), x); + } + public static fallocate fallocate (MemorySegment segment, MemorySession session) { + return fallocate.ofAddress(fallocate$get(segment), session); + } + 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-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/stat.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/stat.java new file mode 100644 index 00000000..38997d0e --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/stat.java @@ -0,0 +1,254 @@ +// 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.*; +public class stat { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG_LONG$LAYOUT.withName("st_dev"), + Constants$root.C_LONG_LONG$LAYOUT.withName("st_ino"), + Constants$root.C_INT$LAYOUT.withName("st_mode"), + Constants$root.C_INT$LAYOUT.withName("st_nlink"), + Constants$root.C_INT$LAYOUT.withName("st_uid"), + Constants$root.C_INT$LAYOUT.withName("st_gid"), + Constants$root.C_LONG_LONG$LAYOUT.withName("st_rdev"), + Constants$root.C_LONG_LONG$LAYOUT.withName("__pad1"), + Constants$root.C_LONG_LONG$LAYOUT.withName("st_size"), + Constants$root.C_INT$LAYOUT.withName("st_blksize"), + Constants$root.C_INT$LAYOUT.withName("__pad2"), + Constants$root.C_LONG_LONG$LAYOUT.withName("st_blocks"), + MemoryLayout.structLayout( + Constants$root.C_LONG_LONG$LAYOUT.withName("tv_sec"), + Constants$root.C_LONG_LONG$LAYOUT.withName("tv_nsec") + ).withName("st_atim"), + MemoryLayout.structLayout( + Constants$root.C_LONG_LONG$LAYOUT.withName("tv_sec"), + Constants$root.C_LONG_LONG$LAYOUT.withName("tv_nsec") + ).withName("st_mtim"), + MemoryLayout.structLayout( + Constants$root.C_LONG_LONG$LAYOUT.withName("tv_sec"), + Constants$root.C_LONG_LONG$LAYOUT.withName("tv_nsec") + ).withName("st_ctim"), + MemoryLayout.sequenceLayout(2, Constants$root.C_INT$LAYOUT).withName("__glibc_reserved") + ).withName("stat"); + public static MemoryLayout $LAYOUT() { + return stat.$struct$LAYOUT; + } + static final VarHandle st_dev$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("st_dev")); + public static VarHandle st_dev$VH() { + return stat.st_dev$VH; + } + public static long st_dev$get(MemorySegment seg) { + return (long)stat.st_dev$VH.get(seg); + } + public static void st_dev$set( MemorySegment seg, long x) { + stat.st_dev$VH.set(seg, x); + } + public static long st_dev$get(MemorySegment seg, long index) { + return (long)stat.st_dev$VH.get(seg.asSlice(index*sizeof())); + } + public static void st_dev$set(MemorySegment seg, long index, long x) { + stat.st_dev$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle st_ino$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("st_ino")); + public static VarHandle st_ino$VH() { + return stat.st_ino$VH; + } + public static long st_ino$get(MemorySegment seg) { + return (long)stat.st_ino$VH.get(seg); + } + public static void st_ino$set( MemorySegment seg, long x) { + stat.st_ino$VH.set(seg, x); + } + public static long st_ino$get(MemorySegment seg, long index) { + return (long)stat.st_ino$VH.get(seg.asSlice(index*sizeof())); + } + public static void st_ino$set(MemorySegment seg, long index, long x) { + stat.st_ino$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle st_mode$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("st_mode")); + public static VarHandle st_mode$VH() { + return stat.st_mode$VH; + } + public static int st_mode$get(MemorySegment seg) { + return (int)stat.st_mode$VH.get(seg); + } + public static void st_mode$set( MemorySegment seg, int x) { + stat.st_mode$VH.set(seg, x); + } + public static int st_mode$get(MemorySegment seg, long index) { + return (int)stat.st_mode$VH.get(seg.asSlice(index*sizeof())); + } + public static void st_mode$set(MemorySegment seg, long index, int x) { + stat.st_mode$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle st_nlink$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("st_nlink")); + public static VarHandle st_nlink$VH() { + return stat.st_nlink$VH; + } + public static int st_nlink$get(MemorySegment seg) { + return (int)stat.st_nlink$VH.get(seg); + } + public static void st_nlink$set( MemorySegment seg, int x) { + stat.st_nlink$VH.set(seg, x); + } + public static int st_nlink$get(MemorySegment seg, long index) { + return (int)stat.st_nlink$VH.get(seg.asSlice(index*sizeof())); + } + public static void st_nlink$set(MemorySegment seg, long index, int x) { + stat.st_nlink$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle st_uid$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("st_uid")); + public static VarHandle st_uid$VH() { + return stat.st_uid$VH; + } + public static int st_uid$get(MemorySegment seg) { + return (int)stat.st_uid$VH.get(seg); + } + public static void st_uid$set( MemorySegment seg, int x) { + stat.st_uid$VH.set(seg, x); + } + public static int st_uid$get(MemorySegment seg, long index) { + return (int)stat.st_uid$VH.get(seg.asSlice(index*sizeof())); + } + public static void st_uid$set(MemorySegment seg, long index, int x) { + stat.st_uid$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle st_gid$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("st_gid")); + public static VarHandle st_gid$VH() { + return stat.st_gid$VH; + } + public static int st_gid$get(MemorySegment seg) { + return (int)stat.st_gid$VH.get(seg); + } + public static void st_gid$set( MemorySegment seg, int x) { + stat.st_gid$VH.set(seg, x); + } + public static int st_gid$get(MemorySegment seg, long index) { + return (int)stat.st_gid$VH.get(seg.asSlice(index*sizeof())); + } + public static void st_gid$set(MemorySegment seg, long index, int x) { + stat.st_gid$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle st_rdev$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("st_rdev")); + public static VarHandle st_rdev$VH() { + return stat.st_rdev$VH; + } + public static long st_rdev$get(MemorySegment seg) { + return (long)stat.st_rdev$VH.get(seg); + } + public static void st_rdev$set( MemorySegment seg, long x) { + stat.st_rdev$VH.set(seg, x); + } + public static long st_rdev$get(MemorySegment seg, long index) { + return (long)stat.st_rdev$VH.get(seg.asSlice(index*sizeof())); + } + public static void st_rdev$set(MemorySegment seg, long index, long x) { + stat.st_rdev$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle __pad1$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("__pad1")); + public static VarHandle __pad1$VH() { + return stat.__pad1$VH; + } + public static long __pad1$get(MemorySegment seg) { + return (long)stat.__pad1$VH.get(seg); + } + public static void __pad1$set( MemorySegment seg, long x) { + stat.__pad1$VH.set(seg, x); + } + public static long __pad1$get(MemorySegment seg, long index) { + return (long)stat.__pad1$VH.get(seg.asSlice(index*sizeof())); + } + public static void __pad1$set(MemorySegment seg, long index, long x) { + stat.__pad1$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle st_size$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("st_size")); + public static VarHandle st_size$VH() { + return stat.st_size$VH; + } + public static long st_size$get(MemorySegment seg) { + return (long)stat.st_size$VH.get(seg); + } + public static void st_size$set( MemorySegment seg, long x) { + stat.st_size$VH.set(seg, x); + } + public static long st_size$get(MemorySegment seg, long index) { + return (long)stat.st_size$VH.get(seg.asSlice(index*sizeof())); + } + public static void st_size$set(MemorySegment seg, long index, long x) { + stat.st_size$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle st_blksize$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("st_blksize")); + public static VarHandle st_blksize$VH() { + return stat.st_blksize$VH; + } + public static int st_blksize$get(MemorySegment seg) { + return (int)stat.st_blksize$VH.get(seg); + } + public static void st_blksize$set( MemorySegment seg, int x) { + stat.st_blksize$VH.set(seg, x); + } + public static int st_blksize$get(MemorySegment seg, long index) { + return (int)stat.st_blksize$VH.get(seg.asSlice(index*sizeof())); + } + public static void st_blksize$set(MemorySegment seg, long index, int x) { + stat.st_blksize$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle __pad2$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("__pad2")); + public static VarHandle __pad2$VH() { + return stat.__pad2$VH; + } + public static int __pad2$get(MemorySegment seg) { + return (int)stat.__pad2$VH.get(seg); + } + public static void __pad2$set( MemorySegment seg, int x) { + stat.__pad2$VH.set(seg, x); + } + public static int __pad2$get(MemorySegment seg, long index) { + return (int)stat.__pad2$VH.get(seg.asSlice(index*sizeof())); + } + public static void __pad2$set(MemorySegment seg, long index, int x) { + stat.__pad2$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle st_blocks$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("st_blocks")); + public static VarHandle st_blocks$VH() { + return stat.st_blocks$VH; + } + public static long st_blocks$get(MemorySegment seg) { + return (long)stat.st_blocks$VH.get(seg); + } + public static void st_blocks$set( MemorySegment seg, long x) { + stat.st_blocks$VH.set(seg, x); + } + public static long st_blocks$get(MemorySegment seg, long index) { + return (long)stat.st_blocks$VH.get(seg.asSlice(index*sizeof())); + } + public static void st_blocks$set(MemorySegment seg, long index, long x) { + stat.st_blocks$VH.set(seg.asSlice(index*sizeof()), x); + } + public static MemorySegment st_atim$slice(MemorySegment seg) { + return seg.asSlice(72, 16); + } + public static MemorySegment st_mtim$slice(MemorySegment seg) { + return seg.asSlice(88, 16); + } + public static MemorySegment st_ctim$slice(MemorySegment seg) { + return seg.asSlice(104, 16); + } + public static MemorySegment __glibc_reserved$slice(MemorySegment seg) { + return seg.asSlice(120, 8); + } + 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-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 new file mode 100644 index 00000000..876229b4 --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/stat_h.java @@ -0,0 +1,38 @@ +// 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.*; +public class stat_h { + + /* package-private */ stat_h() {} + public static OfByte C_CHAR = Constants$root.C_CHAR$LAYOUT; + public static OfShort C_SHORT = Constants$root.C_SHORT$LAYOUT; + public static OfInt C_INT = Constants$root.C_INT$LAYOUT; + public static OfLong C_LONG = Constants$root.C_LONG_LONG$LAYOUT; + public static OfLong C_LONG_LONG = Constants$root.C_LONG_LONG$LAYOUT; + 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 long UTIME_NOW() { + return 1073741823L; + } + 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/main/java/org/cryptomator/jfuse/linux/aarch64/extr/statvfs.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/statvfs.java new file mode 100644 index 00000000..4e118783 --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/statvfs.java @@ -0,0 +1,216 @@ +// 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.*; +public class statvfs { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG_LONG$LAYOUT.withName("f_bsize"), + Constants$root.C_LONG_LONG$LAYOUT.withName("f_frsize"), + Constants$root.C_LONG_LONG$LAYOUT.withName("f_blocks"), + Constants$root.C_LONG_LONG$LAYOUT.withName("f_bfree"), + Constants$root.C_LONG_LONG$LAYOUT.withName("f_bavail"), + Constants$root.C_LONG_LONG$LAYOUT.withName("f_files"), + Constants$root.C_LONG_LONG$LAYOUT.withName("f_ffree"), + Constants$root.C_LONG_LONG$LAYOUT.withName("f_favail"), + Constants$root.C_LONG_LONG$LAYOUT.withName("f_fsid"), + Constants$root.C_LONG_LONG$LAYOUT.withName("f_flag"), + Constants$root.C_LONG_LONG$LAYOUT.withName("f_namemax"), + MemoryLayout.sequenceLayout(6, Constants$root.C_INT$LAYOUT).withName("__f_spare") + ).withName("statvfs"); + public static MemoryLayout $LAYOUT() { + return statvfs.$struct$LAYOUT; + } + static final VarHandle f_bsize$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("f_bsize")); + public static VarHandle f_bsize$VH() { + return statvfs.f_bsize$VH; + } + public static long f_bsize$get(MemorySegment seg) { + return (long)statvfs.f_bsize$VH.get(seg); + } + public static void f_bsize$set( MemorySegment seg, long x) { + statvfs.f_bsize$VH.set(seg, x); + } + public static long f_bsize$get(MemorySegment seg, long index) { + return (long)statvfs.f_bsize$VH.get(seg.asSlice(index*sizeof())); + } + public static void f_bsize$set(MemorySegment seg, long index, long x) { + statvfs.f_bsize$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle f_frsize$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("f_frsize")); + public static VarHandle f_frsize$VH() { + return statvfs.f_frsize$VH; + } + public static long f_frsize$get(MemorySegment seg) { + return (long)statvfs.f_frsize$VH.get(seg); + } + public static void f_frsize$set( MemorySegment seg, long x) { + statvfs.f_frsize$VH.set(seg, x); + } + public static long f_frsize$get(MemorySegment seg, long index) { + return (long)statvfs.f_frsize$VH.get(seg.asSlice(index*sizeof())); + } + public static void f_frsize$set(MemorySegment seg, long index, long x) { + statvfs.f_frsize$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle f_blocks$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("f_blocks")); + public static VarHandle f_blocks$VH() { + return statvfs.f_blocks$VH; + } + public static long f_blocks$get(MemorySegment seg) { + return (long)statvfs.f_blocks$VH.get(seg); + } + public static void f_blocks$set( MemorySegment seg, long x) { + statvfs.f_blocks$VH.set(seg, x); + } + public static long f_blocks$get(MemorySegment seg, long index) { + return (long)statvfs.f_blocks$VH.get(seg.asSlice(index*sizeof())); + } + public static void f_blocks$set(MemorySegment seg, long index, long x) { + statvfs.f_blocks$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle f_bfree$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("f_bfree")); + public static VarHandle f_bfree$VH() { + return statvfs.f_bfree$VH; + } + public static long f_bfree$get(MemorySegment seg) { + return (long)statvfs.f_bfree$VH.get(seg); + } + public static void f_bfree$set( MemorySegment seg, long x) { + statvfs.f_bfree$VH.set(seg, x); + } + public static long f_bfree$get(MemorySegment seg, long index) { + return (long)statvfs.f_bfree$VH.get(seg.asSlice(index*sizeof())); + } + public static void f_bfree$set(MemorySegment seg, long index, long x) { + statvfs.f_bfree$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle f_bavail$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("f_bavail")); + public static VarHandle f_bavail$VH() { + return statvfs.f_bavail$VH; + } + public static long f_bavail$get(MemorySegment seg) { + return (long)statvfs.f_bavail$VH.get(seg); + } + public static void f_bavail$set( MemorySegment seg, long x) { + statvfs.f_bavail$VH.set(seg, x); + } + public static long f_bavail$get(MemorySegment seg, long index) { + return (long)statvfs.f_bavail$VH.get(seg.asSlice(index*sizeof())); + } + public static void f_bavail$set(MemorySegment seg, long index, long x) { + statvfs.f_bavail$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle f_files$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("f_files")); + public static VarHandle f_files$VH() { + return statvfs.f_files$VH; + } + public static long f_files$get(MemorySegment seg) { + return (long)statvfs.f_files$VH.get(seg); + } + public static void f_files$set( MemorySegment seg, long x) { + statvfs.f_files$VH.set(seg, x); + } + public static long f_files$get(MemorySegment seg, long index) { + return (long)statvfs.f_files$VH.get(seg.asSlice(index*sizeof())); + } + public static void f_files$set(MemorySegment seg, long index, long x) { + statvfs.f_files$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle f_ffree$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("f_ffree")); + public static VarHandle f_ffree$VH() { + return statvfs.f_ffree$VH; + } + public static long f_ffree$get(MemorySegment seg) { + return (long)statvfs.f_ffree$VH.get(seg); + } + public static void f_ffree$set( MemorySegment seg, long x) { + statvfs.f_ffree$VH.set(seg, x); + } + public static long f_ffree$get(MemorySegment seg, long index) { + return (long)statvfs.f_ffree$VH.get(seg.asSlice(index*sizeof())); + } + public static void f_ffree$set(MemorySegment seg, long index, long x) { + statvfs.f_ffree$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle f_favail$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("f_favail")); + public static VarHandle f_favail$VH() { + return statvfs.f_favail$VH; + } + public static long f_favail$get(MemorySegment seg) { + return (long)statvfs.f_favail$VH.get(seg); + } + public static void f_favail$set( MemorySegment seg, long x) { + statvfs.f_favail$VH.set(seg, x); + } + public static long f_favail$get(MemorySegment seg, long index) { + return (long)statvfs.f_favail$VH.get(seg.asSlice(index*sizeof())); + } + public static void f_favail$set(MemorySegment seg, long index, long x) { + statvfs.f_favail$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle f_fsid$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("f_fsid")); + public static VarHandle f_fsid$VH() { + return statvfs.f_fsid$VH; + } + public static long f_fsid$get(MemorySegment seg) { + return (long)statvfs.f_fsid$VH.get(seg); + } + public static void f_fsid$set( MemorySegment seg, long x) { + statvfs.f_fsid$VH.set(seg, x); + } + public static long f_fsid$get(MemorySegment seg, long index) { + return (long)statvfs.f_fsid$VH.get(seg.asSlice(index*sizeof())); + } + public static void f_fsid$set(MemorySegment seg, long index, long x) { + statvfs.f_fsid$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle f_flag$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("f_flag")); + public static VarHandle f_flag$VH() { + return statvfs.f_flag$VH; + } + public static long f_flag$get(MemorySegment seg) { + return (long)statvfs.f_flag$VH.get(seg); + } + public static void f_flag$set( MemorySegment seg, long x) { + statvfs.f_flag$VH.set(seg, x); + } + public static long f_flag$get(MemorySegment seg, long index) { + return (long)statvfs.f_flag$VH.get(seg.asSlice(index*sizeof())); + } + public static void f_flag$set(MemorySegment seg, long index, long x) { + statvfs.f_flag$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle f_namemax$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("f_namemax")); + public static VarHandle f_namemax$VH() { + return statvfs.f_namemax$VH; + } + public static long f_namemax$get(MemorySegment seg) { + return (long)statvfs.f_namemax$VH.get(seg); + } + public static void f_namemax$set( MemorySegment seg, long x) { + statvfs.f_namemax$VH.set(seg, x); + } + public static long f_namemax$get(MemorySegment seg, long index) { + return (long)statvfs.f_namemax$VH.get(seg.asSlice(index*sizeof())); + } + public static void f_namemax$set(MemorySegment seg, long index, long x) { + statvfs.f_namemax$VH.set(seg.asSlice(index*sizeof()), x); + } + public static MemorySegment __f_spare$slice(MemorySegment seg) { + return seg.asSlice(88, 24); + } + 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-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/timespec.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/timespec.java new file mode 100644 index 00000000..7b5ceb93 --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/timespec.java @@ -0,0 +1,59 @@ +// 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.*; +public class timespec { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG_LONG$LAYOUT.withName("tv_sec"), + Constants$root.C_LONG_LONG$LAYOUT.withName("tv_nsec") + ).withName("timespec"); + public static MemoryLayout $LAYOUT() { + return timespec.$struct$LAYOUT; + } + static final VarHandle tv_sec$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("tv_sec")); + public static VarHandle tv_sec$VH() { + return timespec.tv_sec$VH; + } + public static long tv_sec$get(MemorySegment seg) { + return (long)timespec.tv_sec$VH.get(seg); + } + public static void tv_sec$set( MemorySegment seg, long x) { + timespec.tv_sec$VH.set(seg, x); + } + public static long tv_sec$get(MemorySegment seg, long index) { + return (long)timespec.tv_sec$VH.get(seg.asSlice(index*sizeof())); + } + public static void tv_sec$set(MemorySegment seg, long index, long x) { + timespec.tv_sec$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle tv_nsec$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("tv_nsec")); + public static VarHandle tv_nsec$VH() { + return timespec.tv_nsec$VH; + } + public static long tv_nsec$get(MemorySegment seg) { + return (long)timespec.tv_nsec$VH.get(seg); + } + public static void tv_nsec$set( MemorySegment seg, long x) { + timespec.tv_nsec$VH.set(seg, x); + } + public static long tv_nsec$get(MemorySegment seg, long index) { + return (long)timespec.tv_nsec$VH.get(seg.asSlice(index*sizeof())); + } + public static void tv_nsec$set(MemorySegment seg, long index, long x) { + timespec.tv_nsec$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-linux-amd64/pom.xml b/jfuse-linux-amd64/pom.xml index 7e9f5f54..1aee61e0 100644 --- a/jfuse-linux-amd64/pom.xml +++ b/jfuse-linux-amd64/pom.xml @@ -101,6 +101,7 @@ fuse_exit fuse_parse_cmdline + fuse_opt_add_arg fuse_mount fuse_new fuse_loop @@ -118,6 +119,7 @@ statvfs timespec fuse_conn_info + fuse_args 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 fc37689e..8807e991 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 @@ -1,11 +1,5 @@ package org.cryptomator.jfuse.linux.amd64; -import jdk.incubator.foreign.MemoryAddress; -import jdk.incubator.foreign.MemoryLayout; -import jdk.incubator.foreign.MemorySegment; -import jdk.incubator.foreign.ResourceScope; -import jdk.incubator.foreign.SegmentAllocator; -import jdk.incubator.foreign.ValueLayout; import org.cryptomator.jfuse.api.Fuse; import org.cryptomator.jfuse.api.FuseArgs; import org.cryptomator.jfuse.api.FuseOperations; @@ -20,12 +14,13 @@ import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; import java.lang.foreign.MemorySession; +import java.lang.foreign.ValueLayout; import java.nio.ByteBuffer; import java.nio.file.Path; import java.util.List; import java.util.concurrent.CompletableFuture; -import static jdk.incubator.foreign.ValueLayout.JAVA_INT; +import static java.lang.foreign.ValueLayout.JAVA_INT; public final class FuseImpl extends Fuse { @@ -58,16 +53,15 @@ protected CompletableFuture initialized() { } @Override - protected FuseArgs parseCmdLine(List args, ResourceScope scope) { - var allocator = SegmentAllocator.nativeAllocator(scope); - var multithreaded = allocator.allocate(JAVA_INT, 1); - var foreground = allocator.allocate(JAVA_INT, 1); - var fuseArgs = fuse_args.allocate(allocator); + protected FuseArgs parseCmdLine(List args, MemorySession scope) { + var multithreaded = scope.allocate(JAVA_INT, 1); + var foreground = scope.allocate(JAVA_INT, 1); + var fuseArgs = fuse_args.allocate(scope); fuse_args.argc$set(fuseArgs, 0); fuse_args.argv$set(fuseArgs, MemoryAddress.NULL); fuse_args.allocated$set(fuseArgs, 0); for (var arg : args) { - var cString = allocator.allocateUtf8String(arg); + var cString = scope.allocateUtf8String(arg); fuse_h.fuse_opt_add_arg(fuseArgs, cString); } // var argc = args.size(); @@ -80,7 +74,7 @@ protected FuseArgs parseCmdLine(List args, ResourceScope scope) { // fuse_args.argv$set(fuseArgs, argv.address()); // fuse_args.allocated$set(fuseArgs, 0); System.out.println("args: " + String.join(" ", args)); - var mountPointPtr = allocator.allocate(ValueLayout.ADDRESS); + var mountPointPtr = scope.allocate(ValueLayout.ADDRESS); int parseResult = fuse_h.fuse_parse_cmdline(fuseArgs, mountPointPtr, multithreaded, foreground); if (parseResult != 0) { throw new IllegalArgumentException("fuse_parse_cmdline failed to parse " + String.join(" ", args)); @@ -102,9 +96,8 @@ protected FuseArgs parseCmdLine(List args, ResourceScope scope) { @Override protected FuseSession mount(FuseArgs args, Path mountPoint) { - try (var scope = ResourceScope.newConfinedScope()) { - var allocator = SegmentAllocator.nativeAllocator(scope); - var mountPointStr = allocator.allocateUtf8String(mountPoint.toString()); + try (var scope = MemorySession.openConfined()) { + var mountPointStr = scope.allocateUtf8String(mountPoint.toString()); var ch = fuse_h.fuse_mount(mountPointStr, args.args()); if (MemoryAddress.NULL.equals(ch)) { // TODO any cleanup needed? @@ -129,9 +122,8 @@ protected int loop(FuseSession session, boolean multithreaded) { @Override protected void unmount(FuseSession session) { - try (var scope = ResourceScope.newConfinedScope()) { - var allocator = SegmentAllocator.nativeAllocator(scope); - var mountPointStr = allocator.allocateUtf8String(session.mountPoint().toString()); + try (var scope = MemorySession.openConfined()) { + var mountPointStr = scope.allocateUtf8String(session.mountPoint().toString()); fuse_h.fuse_exit(session.fuse()); fuse_h.fuse_unmount(mountPointStr, session.ch()); } 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 ff624d27..e7f10519 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,6 +9,14 @@ import static java.lang.foreign.ValueLayout.*; class constants$0 { + static final FunctionDescriptor fuse_opt_add_arg$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_opt_add_arg$MH = RuntimeHelper.downcallHandle( + "fuse_opt_add_arg", + constants$0.fuse_opt_add_arg$FUNC + ); static final FunctionDescriptor fuse_mount$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT @@ -44,17 +52,6 @@ class constants$0 { static final MethodHandle fuse_fill_dir_t$MH = RuntimeHelper.downcallHandle( constants$0.fuse_fill_dir_t$FUNC ); - 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_POINTER$LAYOUT, - Constants$root.C_LONG_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle fuse_new$MH = RuntimeHelper.downcallHandle( - "fuse_new", - constants$0.fuse_new$FUNC - ); } 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 b05d7ed8..89a2f64c 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,6 +9,17 @@ import static java.lang.foreign.ValueLayout.*; class constants$1 { + 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_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_new$MH = RuntimeHelper.downcallHandle( + "fuse_new", + constants$1.fuse_new$FUNC + ); static final FunctionDescriptor fuse_destroy$FUNC = FunctionDescriptor.ofVoid( Constants$root.C_POINTER$LAYOUT ); diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_args.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_args.java new file mode 100644 index 00000000..ad44b601 --- /dev/null +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_args.java @@ -0,0 +1,78 @@ +// 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.*; +public class fuse_args { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_INT$LAYOUT.withName("argc"), + MemoryLayout.paddingLayout(32), + Constants$root.C_POINTER$LAYOUT.withName("argv"), + Constants$root.C_INT$LAYOUT.withName("allocated"), + MemoryLayout.paddingLayout(32) + ).withName("fuse_args"); + public static MemoryLayout $LAYOUT() { + return fuse_args.$struct$LAYOUT; + } + static final VarHandle argc$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("argc")); + public static VarHandle argc$VH() { + return fuse_args.argc$VH; + } + public static int argc$get(MemorySegment seg) { + return (int)fuse_args.argc$VH.get(seg); + } + public static void argc$set( MemorySegment seg, int x) { + fuse_args.argc$VH.set(seg, x); + } + public static int argc$get(MemorySegment seg, long index) { + return (int)fuse_args.argc$VH.get(seg.asSlice(index*sizeof())); + } + public static void argc$set(MemorySegment seg, long index, int x) { + fuse_args.argc$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle argv$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("argv")); + public static VarHandle argv$VH() { + return fuse_args.argv$VH; + } + public static MemoryAddress argv$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_args.argv$VH.get(seg); + } + public static void argv$set( MemorySegment seg, MemoryAddress x) { + fuse_args.argv$VH.set(seg, x); + } + public static MemoryAddress argv$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_args.argv$VH.get(seg.asSlice(index*sizeof())); + } + public static void argv$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_args.argv$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle allocated$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("allocated")); + public static VarHandle allocated$VH() { + return fuse_args.allocated$VH; + } + public static int allocated$get(MemorySegment seg) { + return (int)fuse_args.allocated$VH.get(seg); + } + public static void allocated$set( MemorySegment seg, int x) { + fuse_args.allocated$VH.set(seg, x); + } + public static int allocated$get(MemorySegment seg, long index) { + return (int)fuse_args.allocated$VH.get(seg.asSlice(index*sizeof())); + } + public static void allocated$set(MemorySegment seg, long index, int x) { + fuse_args.allocated$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-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 537b515f..82ebdb73 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,6 +18,17 @@ 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_opt_add_arg$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_opt_add_arg$MH,"fuse_opt_add_arg"); + } + public static int fuse_opt_add_arg ( Addressable args, Addressable arg) { + var mh$ = fuse_opt_add_arg$MH(); + try { + return (int)mh$.invokeExact(args, arg); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } public static MethodHandle fuse_mount$MH() { return RuntimeHelper.requireNonNull(constants$0.fuse_mount$MH,"fuse_mount"); } @@ -52,7 +63,7 @@ public static int fuse_parse_cmdline ( Addressable args, Addressable mountpoint } } 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 ch, Addressable args, Addressable op, long op_size, Addressable user_data) { var mh$ = fuse_new$MH(); From 5a693ca0b5b81bcf30d7a1043b67775e0dbfd968 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Thu, 25 Aug 2022 17:03:27 +0200 Subject: [PATCH 11/98] try saving fuse_args --- .../src/main/java/org/cryptomator/jfuse/api/Fuse.java | 2 +- .../java/org/cryptomator/jfuse/linux/amd64/FuseImpl.java | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java index 6f656b4c..c246aa16 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java @@ -76,7 +76,7 @@ public int mount(String progName, Path mountPoint, String... flags) throws Compl args.add(mountPoint.toString()); try (var scope = MemorySession.openConfined()) { - var fuseArgs = parseCmdLine(args, scope); + var fuseArgs = parseCmdLine(args, MemorySession.global()); var fuseSession = mount(fuseArgs, mountPoint); // TODO: specific exception var isOnlySession = session.compareAndSet(lock, fuseSession); assert isOnlySession : "unreachable code, as no other method can set this.session to SESSION_LOCK"; 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 8807e991..c3a9f2a2 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 @@ -98,13 +98,17 @@ protected FuseArgs parseCmdLine(List args, MemorySession scope) { protected FuseSession mount(FuseArgs args, Path mountPoint) { try (var scope = MemorySession.openConfined()) { var mountPointStr = scope.allocateUtf8String(mountPoint.toString()); - var ch = fuse_h.fuse_mount(mountPointStr, args.args()); + var argsCopy1 = MemorySegment.allocateNative(args.args().byteSize(), scope); + var argsCopy2 = MemorySegment.allocateNative(args.args().byteSize(), scope); + MemorySegment.copy(args.args(), 0, argsCopy1, 0, args.args().byteSize()); + MemorySegment.copy(args.args(), 0, argsCopy2, 0, args.args().byteSize()); + var ch = fuse_h.fuse_mount(mountPointStr, argsCopy1); if (MemoryAddress.NULL.equals(ch)) { // TODO any cleanup needed? // TODO use explicit exception type throw new IllegalArgumentException("Failed to mount to " + mountPoint + " with given args."); } - var fuse = fuse_h.fuse_new(ch, args.args(), fuseOps, fuseOps.byteSize(), MemoryAddress.NULL); + var fuse = fuse_h.fuse_new(ch, argsCopy2, fuseOps, fuseOps.byteSize(), MemoryAddress.NULL); if (MemoryAddress.NULL.equals(fuse)) { fuse_h.fuse_unmount(mountPointStr, ch); // TODO use explicit exception type From ce9bdb58803ee0a4fdeb1dcdbf5a7e0fa6bfc338 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 30 Aug 2022 15:48:10 +0200 Subject: [PATCH 12/98] =?UTF-8?q?renamed=20libfuse=20=E2=86=92=20libfuse2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitmodules | 4 ++-- jfuse-linux-aarch64/pom.xml | 2 +- jfuse-linux-amd64/pom.xml | 2 +- jfuse-mac/pom.xml | 2 +- libfuse => libfuse2 | 0 winfsp | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) rename libfuse => libfuse2 (100%) diff --git a/.gitmodules b/.gitmodules index b8866683..446387b9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,5 +1,5 @@ -[submodule "libfuse"] - path = libfuse +[submodule "libfuse2"] + path = libfuse2 url = https://github.com/libfuse/libfuse.git branch = fuse_2_9_bugfix diff --git a/jfuse-linux-aarch64/pom.xml b/jfuse-linux-aarch64/pom.xml index 72560b90..a79b8abe 100644 --- a/jfuse-linux-aarch64/pom.xml +++ b/jfuse-linux-aarch64/pom.xml @@ -88,7 +88,7 @@ sources - ${project.parent.basedir}/libfuse/include/fuse.h + ${project.parent.basedir}/libfuse2/include/fuse.h fuse_h _FILE_OFFSET_BITS=64 diff --git a/jfuse-linux-amd64/pom.xml b/jfuse-linux-amd64/pom.xml index 1102074a..9e3d6119 100644 --- a/jfuse-linux-amd64/pom.xml +++ b/jfuse-linux-amd64/pom.xml @@ -88,7 +88,7 @@ sources - ${project.parent.basedir}/libfuse/include/fuse.h + ${project.parent.basedir}/libfuse2/include/fuse.h fuse_h _FILE_OFFSET_BITS=64 diff --git a/jfuse-mac/pom.xml b/jfuse-mac/pom.xml index 193d1919..cae0d425 100644 --- a/jfuse-mac/pom.xml +++ b/jfuse-mac/pom.xml @@ -87,7 +87,7 @@ sources - ${project.parent.basedir}/libfuse/include/fuse.h + ${project.parent.basedir}/libfuse2/include/fuse.h fuse_h _FILE_OFFSET_BITS=64 diff --git a/libfuse b/libfuse2 similarity index 100% rename from libfuse rename to libfuse2 diff --git a/winfsp b/winfsp index ec832b45..deee7edd 160000 --- a/winfsp +++ b/winfsp @@ -1 +1 @@ -Subproject commit ec832b45ff690ce4c4f9d4c4c66808fdd790ab7f +Subproject commit deee7eddedb24ba58c741cbb1421baf2e37fe5d4 From 126e90ffb7e9f1bf28a364e290e9c03cd65fed73 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 30 Aug 2022 15:50:18 +0200 Subject: [PATCH 13/98] added libfuse3 and adjusted API --- .gitmodules | 5 +++++ .../org/cryptomator/jfuse/api/FuseOperations.java | 12 +++++++----- .../jfuse/examples/AbstractMirrorFileSystem.java | 10 +++++----- .../jfuse/examples/HelloWorldFileSystem.java | 2 +- .../jfuse/examples/PosixMirrorFileSystem.java | 3 ++- libfuse3 | 1 + 6 files changed, 21 insertions(+), 12 deletions(-) create mode 160000 libfuse3 diff --git a/.gitmodules b/.gitmodules index 446387b9..3d1b5e73 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,6 +3,11 @@ url = https://github.com/libfuse/libfuse.git branch = fuse_2_9_bugfix +[submodule "libfuse3"] + path = libfuse3 + url = https://github.com/libfuse/libfuse.git + branch = master + [submodule "winfsp"] path = winfsp url = https://github.com/billziss-gh/winfsp.git diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java index 463d388f..c433a286 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java @@ -1,5 +1,7 @@ package org.cryptomator.jfuse.api; +import org.jetbrains.annotations.Nullable; + import java.nio.ByteBuffer; import java.util.Set; @@ -54,7 +56,7 @@ enum Operation { * ignored. The 'st_ino' field is ignored except if the 'use_ino' * mount option is given. */ - default int getattr(String path, Stat stat) { + default int getattr(String path, Stat stat, @Nullable FileInfo fi) { return -errno().enosys(); } @@ -125,7 +127,7 @@ default int symlink(String linkname, String target) { /** * Rename a file */ - default int rename(String oldpath, String newpath) { + default int rename(String oldpath, String newpath, int flags) { return -errno().enosys(); } @@ -139,7 +141,7 @@ default int link(String linkname, String target) { /** * Change the permission bits of a file */ - default int chmod(String path, int mode) { + default int chmod(String path, int mode, @Nullable FileInfo fi) { return -errno().enosys(); } @@ -153,7 +155,7 @@ default int chown(String path, int uid, int gid) { /** * Change the size of a file */ - default int truncate(String path, long size) { + default int truncate(String path, long size, @Nullable FileInfo fi) { return -errno().enosys(); } @@ -514,7 +516,7 @@ default int fgetattr(String path, Stat stat, FileInfo fi) { *

* Introduced in version 2.6 */ - default int utimens(String path, TimeSpec atime, TimeSpec mtime) { + default int utimens(String path, TimeSpec atime, TimeSpec mtime, @Nullable FileInfo fi) { return -errno().enosys(); } 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 8328ff85..2ee0f3df 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 @@ -169,7 +169,7 @@ public int readlink(String path, ByteBuffer buf, long len) { @SuppressWarnings("OctalInteger") @Override - public int getattr(String path, Stat stat) { + public int getattr(String path, Stat stat, FileInfo fi) { LOG.trace("getattr {}", path); Path node = resolvePath(path); try { @@ -213,7 +213,7 @@ private long countSubDirs(Path dir) throws IOException { } @Override - public int chmod(String path, int mode) { + public int chmod(String path, int mode, FileInfo fi) { LOG.trace("chmod {}", path); Path node = resolvePath(path); try { @@ -225,7 +225,7 @@ public int chmod(String path, int mode) { } @Override - public int utimens(String path, TimeSpec atime, TimeSpec mtime) { + public int utimens(String path, TimeSpec atime, TimeSpec mtime, FileInfo fi) { LOG.trace("utimens {}", path); Path node = resolvePath(path); var view = Files.getFileAttributeView(node, BasicFileAttributeView.class, LinkOption.NOFOLLOW_LINKS); @@ -367,7 +367,7 @@ public int write(String path, ByteBuffer buf, long size, long offset, FileInfo f } @Override - public int truncate(String path, long size) { + public int truncate(String path, long size, FileInfo fi) { LOG.trace("truncate {} to size {}", path, size); Path node = resolvePath(path); try (FileChannel fc = FileChannel.open(node, StandardOpenOption.WRITE)) { @@ -413,7 +413,7 @@ public int unlink(String path) { } @Override - public int rename(String oldpath, String newpath) { + public int rename(String oldpath, String newpath, int flags) { LOG.trace("rename {} -> {}", oldpath, newpath); Path nodeOld = resolvePath(oldpath); Path nodeNew = resolvePath(newpath); diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java index b40bef81..cb10403a 100644 --- a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java @@ -73,7 +73,7 @@ public int access(String path, int mask) { } @Override - public int getattr(String path, Stat stat) { + public int getattr(String path, Stat stat, FileInfo fi) { LOG.debug("getattr() {}", path); if ("/".equals(path)) { stat.setMode(S_IFDIR | 0755); diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/PosixMirrorFileSystem.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/PosixMirrorFileSystem.java index 4f503cbd..bee18789 100644 --- a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/PosixMirrorFileSystem.java +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/PosixMirrorFileSystem.java @@ -1,6 +1,7 @@ package org.cryptomator.jfuse.examples; import org.cryptomator.jfuse.api.Errno; +import org.cryptomator.jfuse.api.FileInfo; import org.cryptomator.jfuse.api.FileModes; import org.cryptomator.jfuse.api.Fuse; import org.slf4j.Logger; @@ -66,7 +67,7 @@ protected PosixFileAttributes readAttributes(Path node) throws IOException { } @Override - public int chmod(String path, int mode) { + public int chmod(String path, int mode, FileInfo fi) { LOG.trace("chmod {}", path); Path node = resolvePath(path); try { diff --git a/libfuse3 b/libfuse3 new file mode 160000 index 00000000..7657ec15 --- /dev/null +++ b/libfuse3 @@ -0,0 +1 @@ +Subproject commit 7657ec158becdc59656c59dff40346fefde78cb2 From 58edb349a03e08391afb426c39b4d15ddd80e27c Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 30 Aug 2022 15:51:33 +0200 Subject: [PATCH 14/98] adjusted jfuse-mac to new API --- .../java/org/cryptomator/jfuse/mac/FuseImpl.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java index ca58fd30..2293cdff 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java @@ -89,7 +89,7 @@ private int access(MemoryAddress path, int mask) { } private int chmod(MemoryAddress path, short mode) { - return delegate.chmod(path.getUtf8String(0), mode); + return delegate.chmod(path.getUtf8String(0), mode, null); } private int create(MemoryAddress path, short mode, MemoryAddress fi) { @@ -104,7 +104,7 @@ private void destroy(MemoryAddress addr) { private int getattr(MemoryAddress path, MemoryAddress stat) { try (var scope = MemorySession.openConfined()) { - return delegate.getattr(path.getUtf8String(0), new StatImpl(stat, scope)); + return delegate.getattr(path.getUtf8String(0), new StatImpl(stat, scope), null); } } @@ -157,7 +157,7 @@ private int releasedir(MemoryAddress path, MemoryAddress fi) { } private int rename(MemoryAddress oldpath, MemoryAddress newpath) { - return delegate.rename(oldpath.getUtf8String(0), newpath.getUtf8String(0)); + return delegate.rename(oldpath.getUtf8String(0), newpath.getUtf8String(0), 0); } private int rmdir(MemoryAddress path) { @@ -175,7 +175,7 @@ private int symlink(MemoryAddress linkname, MemoryAddress target) { } private int truncate(MemoryAddress path, long size) { - return delegate.truncate(path.getUtf8String(0), size); + return delegate.truncate(path.getUtf8String(0), size, null); } private int unlink(MemoryAddress path) { @@ -189,7 +189,7 @@ private int utimens(MemoryAddress path, MemoryAddress times) { timespec.tv_sec$set(segment, 0); timespec.tv_nsec$set(segment, stat_h.UTIME_NOW()); var time = new TimeSpecImpl(segment); - return delegate.utimens(path.getUtf8String(0), time, time); + return delegate.utimens(path.getUtf8String(0), time, time, null); } else { try (var scope = MemorySession.openConfined()) { var seq = MemoryLayout.sequenceLayout(2, timespec.$LAYOUT()); @@ -197,7 +197,7 @@ private int utimens(MemoryAddress path, MemoryAddress times) { var time0 = segment.asSlice(0, timespec.$LAYOUT().byteSize()); var time1 = segment.asSlice(timespec.$LAYOUT().byteSize(), timespec.$LAYOUT().byteSize()); // var timeSpecs = segment.elements(seq.elementLayout()).map(MacTimeSpec::new).toArray(MacTimeSpec[]::new); - return delegate.utimens(path.getUtf8String(0), new TimeSpecImpl(time0), new TimeSpecImpl(time1)); + return delegate.utimens(path.getUtf8String(0), new TimeSpecImpl(time0), new TimeSpecImpl(time1), null); } } } From c2c9063c561f3e18cd2e5b193a1aa75d9669ff94 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 30 Aug 2022 15:53:59 +0200 Subject: [PATCH 15/98] adjusted jfuse-linux-amd64 to new API, using libfuse3 --- .github/workflows/build.yml | 2 +- jfuse-linux-amd64/pom.xml | 25 +- .../jfuse/linux/amd64/DirFillerImpl.java | 2 +- .../jfuse/linux/amd64/FuseImpl.java | 46 +-- .../jfuse/linux/amd64/extr/constants$0.java | 3 +- .../linux/amd64/extr/fuse_conn_info.java | 55 ++- .../linux/amd64/extr/fuse_file_info.java | 62 ++- .../linux/amd64/extr/fuse_fill_dir_t.java | 6 +- .../jfuse/linux/amd64/extr/fuse_h.java | 10 +- .../linux/amd64/extr/fuse_operations.java | 356 +++++++----------- .../jfuse/linux/amd64/extr/stdio_h.java | 32 ++ 11 files changed, 293 insertions(+), 306 deletions(-) create mode 100644 jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/stdio_h.java diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d0e6215d..c68b003d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,7 +18,7 @@ jobs: - name: Setup fuse run: | sudo apt-get update - sudo apt-get install fuse libfuse-dev + sudo apt-get install fuse3 libfuse3-dev - name: Maven build run: mvn -B verify -Plinux-amd64 - uses: actions/upload-artifact@v2 diff --git a/jfuse-linux-amd64/pom.xml b/jfuse-linux-amd64/pom.xml index 9e3d6119..26b05d39 100644 --- a/jfuse-linux-amd64/pom.xml +++ b/jfuse-linux-amd64/pom.xml @@ -92,7 +92,7 @@ fuse_h _FILE_OFFSET_BITS=64 - FUSE_USE_VERSION=29 + FUSE_USE_VERSION=35 fuse_main_real @@ -111,6 +111,10 @@ timespec fuse_conn_info + + FUSE_FILL_DIR_PLUS + FUSE_READDIR_PLUS + @@ -175,6 +179,25 @@ + + jextract-stdio + + sources + + + ${linux.headerSearchPath}/stdio.h + stdio_h + + _GNU_SOURCE=1 + + + + RENAME_NOREPLACE + RENAME_EXCHANGE + RENAME_WHITEOUT + + + diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/DirFillerImpl.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/DirFillerImpl.java index ce3b1bb8..6c587644 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/DirFillerImpl.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/DirFillerImpl.java @@ -16,7 +16,7 @@ record DirFillerImpl(MemoryAddress buf, fuse_fill_dir_t callback, MemorySession @Override public int fill(String name, Stat stat, long offset) { var statAddr = stat instanceof StatImpl s ? s.segment().address() : MemoryAddress.NULL; - return callback.apply(buf, scope.allocateUtf8String(name).address(), statAddr, offset); + return callback.apply(buf, scope.allocateUtf8String(name).address(), statAddr, offset, 0); // TODO readdir plus } } \ No newline at end of file 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 b84d63a8..afd3b8ff 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 @@ -27,7 +27,7 @@ public FuseImpl(FuseOperations fuseOperations) { fuseOperations.supportedOperations().forEach(this::bind); } - private MemoryAddress init(MemoryAddress conn) { + private MemoryAddress init(MemoryAddress conn, MemoryAddress fuseConfig) { try (var scope = MemorySession.openConfined()) { if (delegate.supportedOperations().contains(FuseOperations.Operation.INIT)) { delegate.init(new FuseConnInfoImpl(conn, scope)); @@ -88,8 +88,10 @@ private int access(MemoryAddress path, int mask) { return delegate.access(path.getUtf8String(0), mask); } - private int chmod(MemoryAddress path, int mode) { - return delegate.chmod(path.getUtf8String(0), mode); + private int chmod(MemoryAddress path, int mode, MemoryAddress fi) { + try (var scope = MemorySession.openConfined()) { + return delegate.chmod(path.getUtf8String(0), mode, new FileInfoImpl(fi, scope)); + } } private int create(MemoryAddress path, int mode, MemoryAddress fi) { @@ -102,9 +104,9 @@ private void destroy(MemoryAddress addr) { delegate.destroy(); } - private int getattr(MemoryAddress path, MemoryAddress stat) { + private int getattr(MemoryAddress path, MemoryAddress stat, MemoryAddress fi) { try (var scope = MemorySession.openConfined()) { - return delegate.getattr(path.getUtf8String(0), new StatImpl(stat, scope)); + return delegate.getattr(path.getUtf8String(0), new StatImpl(stat, scope), new FileInfoImpl(fi, scope)); } } @@ -131,7 +133,7 @@ private int read(MemoryAddress path, MemoryAddress buf, long size, long offset, } } - private int readdir(MemoryAddress path, MemoryAddress buf, MemoryAddress filler, long offset, MemoryAddress fi) { + private int readdir(MemoryAddress path, MemoryAddress buf, MemoryAddress filler, long offset, MemoryAddress fi, int flags) { // TODO: readdir plus try (var scope = MemorySession.openConfined()) { return delegate.readdir(path.getUtf8String(0), new DirFillerImpl(buf, filler, scope), offset, new FileInfoImpl(fi, scope)); } @@ -156,8 +158,8 @@ private int releasedir(MemoryAddress path, MemoryAddress fi) { } } - private int rename(MemoryAddress oldpath, MemoryAddress newpath) { - return delegate.rename(oldpath.getUtf8String(0), newpath.getUtf8String(0)); + private int rename(MemoryAddress oldpath, MemoryAddress newpath, int flags) { + return delegate.rename(oldpath.getUtf8String(0), newpath.getUtf8String(0), flags); } private int rmdir(MemoryAddress path) { @@ -174,30 +176,32 @@ private int symlink(MemoryAddress linkname, MemoryAddress target) { return delegate.symlink(linkname.getUtf8String(0), target.getUtf8String(0)); } - private int truncate(MemoryAddress path, long size) { - return delegate.truncate(path.getUtf8String(0), size); + private int truncate(MemoryAddress path, long size, MemoryAddress fi) { + try (var scope = MemorySession.openConfined()) { + return delegate.truncate(path.getUtf8String(0), size, new FileInfoImpl(fi, scope)); + } } private int unlink(MemoryAddress path) { return delegate.unlink(path.getUtf8String(0)); } - private int utimens(MemoryAddress path, MemoryAddress times) { - if (MemoryAddress.NULL.equals(times)) { - // set both times to current time (using on-heap memory segments) - var segment = MemorySegment.ofBuffer(ByteBuffer.allocate((int) timespec.$LAYOUT().byteSize())); - timespec.tv_sec$set(segment, 0); - timespec.tv_nsec$set(segment, stat_h.UTIME_NOW()); - var time = new TimeSpecImpl(segment); - return delegate.utimens(path.getUtf8String(0), time, time); - } else { - try (var scope = MemorySession.openConfined()) { + private 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.ofBuffer(ByteBuffer.allocate((int) timespec.$LAYOUT().byteSize())); + timespec.tv_sec$set(segment, 0); + timespec.tv_nsec$set(segment, stat_h.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, timespec.$LAYOUT()); var segment = MemorySegment.ofAddress(times, seq.byteSize(), scope); var time0 = segment.asSlice(0, timespec.$LAYOUT().byteSize()); var time1 = segment.asSlice(timespec.$LAYOUT().byteSize(), timespec.$LAYOUT().byteSize()); // var timeSpecs = segment.elements(seq.elementLayout()).map(MacTimeSpec::new).toArray(MacTimeSpec[]::new); - return delegate.utimens(path.getUtf8String(0), new TimeSpecImpl(time0), new TimeSpecImpl(time1)); + return delegate.utimens(path.getUtf8String(0), new TimeSpecImpl(time0), new TimeSpecImpl(time1), new FileInfoImpl(fi, scope)); } } } 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 a7a3b33c..433b1d98 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 @@ -13,7 +13,8 @@ class constants$0 { Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, - Constants$root.C_LONG_LONG$LAYOUT + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_INT$LAYOUT ); static final MethodHandle fuse_fill_dir_t$MH = RuntimeHelper.downcallHandle( constants$0.fuse_fill_dir_t$FUNC diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_conn_info.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_conn_info.java index e1142c51..1dda6cea 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_conn_info.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_conn_info.java @@ -12,14 +12,15 @@ public class fuse_conn_info { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( Constants$root.C_INT$LAYOUT.withName("proto_major"), Constants$root.C_INT$LAYOUT.withName("proto_minor"), - Constants$root.C_INT$LAYOUT.withName("async_read"), Constants$root.C_INT$LAYOUT.withName("max_write"), + Constants$root.C_INT$LAYOUT.withName("max_read"), Constants$root.C_INT$LAYOUT.withName("max_readahead"), Constants$root.C_INT$LAYOUT.withName("capable"), Constants$root.C_INT$LAYOUT.withName("want"), Constants$root.C_INT$LAYOUT.withName("max_background"), Constants$root.C_INT$LAYOUT.withName("congestion_threshold"), - MemoryLayout.sequenceLayout(23, Constants$root.C_INT$LAYOUT).withName("reserved") + Constants$root.C_INT$LAYOUT.withName("time_gran"), + MemoryLayout.sequenceLayout(22, Constants$root.C_INT$LAYOUT).withName("reserved") ).withName("fuse_conn_info"); public static MemoryLayout $LAYOUT() { return fuse_conn_info.$struct$LAYOUT; @@ -56,22 +57,6 @@ public class fuse_conn_info { public static void proto_minor$set(MemorySegment seg, long index, int x) { fuse_conn_info.proto_minor$VH.set(seg.asSlice(index*sizeof()), x); } - static final VarHandle async_read$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("async_read")); - public static VarHandle async_read$VH() { - return fuse_conn_info.async_read$VH; - } - public static int async_read$get(MemorySegment seg) { - return (int)fuse_conn_info.async_read$VH.get(seg); - } - public static void async_read$set( MemorySegment seg, int x) { - fuse_conn_info.async_read$VH.set(seg, x); - } - public static int async_read$get(MemorySegment seg, long index) { - return (int)fuse_conn_info.async_read$VH.get(seg.asSlice(index*sizeof())); - } - public static void async_read$set(MemorySegment seg, long index, int x) { - fuse_conn_info.async_read$VH.set(seg.asSlice(index*sizeof()), x); - } static final VarHandle max_write$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max_write")); public static VarHandle max_write$VH() { return fuse_conn_info.max_write$VH; @@ -88,6 +73,22 @@ public class fuse_conn_info { public static void max_write$set(MemorySegment seg, long index, int x) { fuse_conn_info.max_write$VH.set(seg.asSlice(index*sizeof()), x); } + static final VarHandle max_read$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max_read")); + public static VarHandle max_read$VH() { + return fuse_conn_info.max_read$VH; + } + public static int max_read$get(MemorySegment seg) { + return (int)fuse_conn_info.max_read$VH.get(seg); + } + public static void max_read$set( MemorySegment seg, int x) { + fuse_conn_info.max_read$VH.set(seg, x); + } + public static int max_read$get(MemorySegment seg, long index) { + return (int)fuse_conn_info.max_read$VH.get(seg.asSlice(index*sizeof())); + } + public static void max_read$set(MemorySegment seg, long index, int x) { + fuse_conn_info.max_read$VH.set(seg.asSlice(index*sizeof()), x); + } static final VarHandle max_readahead$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max_readahead")); public static VarHandle max_readahead$VH() { return fuse_conn_info.max_readahead$VH; @@ -168,8 +169,24 @@ public class fuse_conn_info { public static void congestion_threshold$set(MemorySegment seg, long index, int x) { fuse_conn_info.congestion_threshold$VH.set(seg.asSlice(index*sizeof()), x); } + static final VarHandle time_gran$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("time_gran")); + public static VarHandle time_gran$VH() { + return fuse_conn_info.time_gran$VH; + } + public static int time_gran$get(MemorySegment seg) { + return (int)fuse_conn_info.time_gran$VH.get(seg); + } + public static void time_gran$set( MemorySegment seg, int x) { + fuse_conn_info.time_gran$VH.set(seg, x); + } + public static int time_gran$get(MemorySegment seg, long index) { + return (int)fuse_conn_info.time_gran$VH.get(seg.asSlice(index*sizeof())); + } + public static void time_gran$set(MemorySegment seg, long index, int x) { + fuse_conn_info.time_gran$VH.set(seg.asSlice(index*sizeof()), x); + } public static MemorySegment reserved$slice(MemorySegment seg) { - return seg.asSlice(36, 92); + return seg.asSlice(40, 88); } 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/fuse_file_info.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_file_info.java index 4665a84b..60c07e93 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_file_info.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_file_info.java @@ -11,19 +11,23 @@ public class fuse_file_info { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( Constants$root.C_INT$LAYOUT.withName("flags"), - MemoryLayout.paddingLayout(32), - Constants$root.C_LONG_LONG$LAYOUT.withName("fh_old"), - Constants$root.C_INT$LAYOUT.withName("writepage"), MemoryLayout.structLayout( + MemoryLayout.paddingLayout(1).withName("writepage"), MemoryLayout.paddingLayout(1).withName("direct_io"), MemoryLayout.paddingLayout(1).withName("keep_cache"), MemoryLayout.paddingLayout(1).withName("flush"), MemoryLayout.paddingLayout(1).withName("nonseekable"), MemoryLayout.paddingLayout(1).withName("flock_release"), - MemoryLayout.paddingLayout(27).withName("padding") + MemoryLayout.paddingLayout(1).withName("cache_readdir"), + MemoryLayout.paddingLayout(1).withName("noflush"), + MemoryLayout.paddingLayout(24).withName("padding"), + MemoryLayout.paddingLayout(32).withName("padding2"), + MemoryLayout.paddingLayout(32) ), Constants$root.C_LONG_LONG$LAYOUT.withName("fh"), - Constants$root.C_LONG_LONG$LAYOUT.withName("lock_owner") + Constants$root.C_LONG_LONG$LAYOUT.withName("lock_owner"), + Constants$root.C_INT$LAYOUT.withName("poll_events"), + MemoryLayout.paddingLayout(32) ).withName("fuse_file_info"); public static MemoryLayout $LAYOUT() { return fuse_file_info.$struct$LAYOUT; @@ -44,38 +48,6 @@ public class fuse_file_info { public static void flags$set(MemorySegment seg, long index, int x) { fuse_file_info.flags$VH.set(seg.asSlice(index*sizeof()), x); } - static final VarHandle fh_old$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fh_old")); - public static VarHandle fh_old$VH() { - return fuse_file_info.fh_old$VH; - } - public static long fh_old$get(MemorySegment seg) { - return (long)fuse_file_info.fh_old$VH.get(seg); - } - public static void fh_old$set( MemorySegment seg, long x) { - fuse_file_info.fh_old$VH.set(seg, x); - } - public static long fh_old$get(MemorySegment seg, long index) { - return (long)fuse_file_info.fh_old$VH.get(seg.asSlice(index*sizeof())); - } - public static void fh_old$set(MemorySegment seg, long index, long x) { - fuse_file_info.fh_old$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle writepage$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("writepage")); - public static VarHandle writepage$VH() { - return fuse_file_info.writepage$VH; - } - public static int writepage$get(MemorySegment seg) { - return (int)fuse_file_info.writepage$VH.get(seg); - } - public static void writepage$set( MemorySegment seg, int x) { - fuse_file_info.writepage$VH.set(seg, x); - } - public static int writepage$get(MemorySegment seg, long index) { - return (int)fuse_file_info.writepage$VH.get(seg.asSlice(index*sizeof())); - } - public static void writepage$set(MemorySegment seg, long index, int x) { - fuse_file_info.writepage$VH.set(seg.asSlice(index*sizeof()), x); - } static final VarHandle fh$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fh")); public static VarHandle fh$VH() { return fuse_file_info.fh$VH; @@ -108,6 +80,22 @@ public class fuse_file_info { public static void lock_owner$set(MemorySegment seg, long index, long x) { fuse_file_info.lock_owner$VH.set(seg.asSlice(index*sizeof()), x); } + static final VarHandle poll_events$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("poll_events")); + public static VarHandle poll_events$VH() { + return fuse_file_info.poll_events$VH; + } + public static int poll_events$get(MemorySegment seg) { + return (int)fuse_file_info.poll_events$VH.get(seg); + } + public static void poll_events$set( MemorySegment seg, int x) { + fuse_file_info.poll_events$VH.set(seg, x); + } + public static int poll_events$get(MemorySegment seg, long index) { + return (int)fuse_file_info.poll_events$VH.get(seg.asSlice(index*sizeof())); + } + public static void poll_events$set(MemorySegment seg, long index, int x) { + fuse_file_info.poll_events$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/fuse_fill_dir_t.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_fill_dir_t.java index fe18e103..e7fe2602 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 @@ -9,15 +9,15 @@ import static java.lang.foreign.ValueLayout.*; public interface fuse_fill_dir_t { - int apply(java.lang.foreign.MemoryAddress buf, java.lang.foreign.MemoryAddress name, java.lang.foreign.MemoryAddress stbuf, long off); + int apply(java.lang.foreign.MemoryAddress buf, java.lang.foreign.MemoryAddress name, java.lang.foreign.MemoryAddress stbuf, long off, int flags); static MemorySegment allocate(fuse_fill_dir_t fi, MemorySession session) { return RuntimeHelper.upcallStub(fuse_fill_dir_t.class, fi, constants$0.fuse_fill_dir_t$FUNC, session); } 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) -> { + 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); + 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); } 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 7480a376..e4e6499a 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,6 +18,12 @@ 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 int FUSE_READDIR_PLUS() { + return (int)1L; + } + public static int FUSE_FILL_DIR_PLUS() { + return (int)2L; + } public static MethodHandle fuse_exit$MH() { return RuntimeHelper.requireNonNull(constants$0.fuse_exit$MH,"fuse_exit"); } @@ -43,10 +49,10 @@ public static MemoryAddress fuse_get_context () { public static MethodHandle fuse_main_real$MH() { return RuntimeHelper.requireNonNull(constants$0.fuse_main_real$MH,"fuse_main_real"); } - public static int fuse_main_real ( int argc, Addressable argv, Addressable op, long op_size, Addressable user_data) { + public static int fuse_main_real ( int argc, Addressable argv, Addressable op, long op_size, Addressable private_data) { var mh$ = fuse_main_real$MH(); try { - return (int)mh$.invokeExact(argc, argv, op, op_size, user_data); + return (int)mh$.invokeExact(argc, argv, op, op_size, private_data); } 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_operations.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_operations.java index 5bb84475..37795014 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_operations.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_operations.java @@ -12,7 +12,6 @@ public class fuse_operations { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( Constants$root.C_POINTER$LAYOUT.withName("getattr"), Constants$root.C_POINTER$LAYOUT.withName("readlink"), - Constants$root.C_POINTER$LAYOUT.withName("getdir"), Constants$root.C_POINTER$LAYOUT.withName("mknod"), Constants$root.C_POINTER$LAYOUT.withName("mkdir"), Constants$root.C_POINTER$LAYOUT.withName("unlink"), @@ -23,7 +22,6 @@ public class fuse_operations { Constants$root.C_POINTER$LAYOUT.withName("chmod"), Constants$root.C_POINTER$LAYOUT.withName("chown"), Constants$root.C_POINTER$LAYOUT.withName("truncate"), - Constants$root.C_POINTER$LAYOUT.withName("utime"), Constants$root.C_POINTER$LAYOUT.withName("open"), Constants$root.C_POINTER$LAYOUT.withName("read"), Constants$root.C_POINTER$LAYOUT.withName("write"), @@ -43,29 +41,23 @@ public class fuse_operations { Constants$root.C_POINTER$LAYOUT.withName("destroy"), Constants$root.C_POINTER$LAYOUT.withName("access"), Constants$root.C_POINTER$LAYOUT.withName("create"), - Constants$root.C_POINTER$LAYOUT.withName("ftruncate"), - Constants$root.C_POINTER$LAYOUT.withName("fgetattr"), Constants$root.C_POINTER$LAYOUT.withName("lock"), Constants$root.C_POINTER$LAYOUT.withName("utimens"), Constants$root.C_POINTER$LAYOUT.withName("bmap"), - MemoryLayout.structLayout( - MemoryLayout.paddingLayout(1).withName("flag_nullpath_ok"), - MemoryLayout.paddingLayout(1).withName("flag_nopath"), - MemoryLayout.paddingLayout(1).withName("flag_utime_omit_ok"), - MemoryLayout.paddingLayout(29).withName("flag_reserved"), - MemoryLayout.paddingLayout(32) - ), Constants$root.C_POINTER$LAYOUT.withName("ioctl"), Constants$root.C_POINTER$LAYOUT.withName("poll"), Constants$root.C_POINTER$LAYOUT.withName("write_buf"), Constants$root.C_POINTER$LAYOUT.withName("read_buf"), Constants$root.C_POINTER$LAYOUT.withName("flock"), - Constants$root.C_POINTER$LAYOUT.withName("fallocate") + Constants$root.C_POINTER$LAYOUT.withName("fallocate"), + Constants$root.C_POINTER$LAYOUT.withName("copy_file_range"), + Constants$root.C_POINTER$LAYOUT.withName("lseek") ).withName("fuse_operations"); public static MemoryLayout $LAYOUT() { return fuse_operations.$struct$LAYOUT; } static final FunctionDescriptor getattr$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT ); @@ -74,15 +66,15 @@ public class fuse_operations { ); public interface getattr { - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2); static MemorySegment allocate(getattr fi, MemorySession session) { return RuntimeHelper.upcallStub(getattr.class, fi, fuse_operations.getattr$FUNC, session); } static getattr ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2) -> { try { - return (int)fuse_operations.getattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + return (int)fuse_operations.getattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -154,51 +146,6 @@ static readlink ofAddress(MemoryAddress addr, MemorySession session) { public static readlink readlink (MemorySegment segment, MemorySession session) { return readlink.ofAddress(readlink$get(segment), session); } - static final FunctionDescriptor getdir$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle getdir$MH = RuntimeHelper.downcallHandle( - fuse_operations.getdir$FUNC - ); - public interface getdir { - - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2); - static MemorySegment allocate(getdir fi, MemorySession session) { - return RuntimeHelper.upcallStub(getdir.class, fi, fuse_operations.getdir$FUNC, session); - } - static getdir ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2) -> { - try { - return (int)fuse_operations.getdir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle getdir$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("getdir")); - public static VarHandle getdir$VH() { - return fuse_operations.getdir$VH; - } - public static MemoryAddress getdir$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.getdir$VH.get(seg); - } - public static void getdir$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.getdir$VH.set(seg, x); - } - public static MemoryAddress getdir$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.getdir$VH.get(seg.asSlice(index*sizeof())); - } - public static void getdir$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.getdir$VH.set(seg.asSlice(index*sizeof()), x); - } - public static getdir getdir (MemorySegment segment, MemorySession session) { - return getdir.ofAddress(getdir$get(segment), session); - } static final FunctionDescriptor mknod$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_INT$LAYOUT, @@ -420,22 +367,23 @@ public static symlink symlink (MemorySegment segment, MemorySession session) { } static final FunctionDescriptor rename$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_INT$LAYOUT ); static final MethodHandle rename$MH = RuntimeHelper.downcallHandle( fuse_operations.rename$FUNC ); public interface rename { - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, int _x2); static MemorySegment allocate(rename fi, MemorySession session) { return RuntimeHelper.upcallStub(rename.class, fi, fuse_operations.rename$FUNC, session); } static rename ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, int __x2) -> { try { - return (int)fuse_operations.rename$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + return (int)fuse_operations.rename$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -508,22 +456,23 @@ public static link link (MemorySegment segment, MemorySession session) { } static final FunctionDescriptor chmod$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, Constants$root.C_POINTER$LAYOUT, - Constants$root.C_INT$LAYOUT + Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT ); static final MethodHandle chmod$MH = RuntimeHelper.downcallHandle( fuse_operations.chmod$FUNC ); public interface chmod { - int apply(java.lang.foreign.MemoryAddress _x0, int _x1); + int apply(java.lang.foreign.MemoryAddress _x0, int _x1, java.lang.foreign.MemoryAddress _x2); static MemorySegment allocate(chmod fi, MemorySession session) { return RuntimeHelper.upcallStub(chmod.class, fi, fuse_operations.chmod$FUNC, session); } static chmod ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, int __x1) -> { + return (java.lang.foreign.MemoryAddress __x0, int __x1, java.lang.foreign.MemoryAddress __x2) -> { try { - return (int)fuse_operations.chmod$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1); + return (int)fuse_operations.chmod$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -553,22 +502,23 @@ public static chmod chmod (MemorySegment segment, MemorySession session) { static final FunctionDescriptor chown$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_INT$LAYOUT, - Constants$root.C_INT$LAYOUT + Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT ); static final MethodHandle chown$MH = RuntimeHelper.downcallHandle( fuse_operations.chown$FUNC ); public interface chown { - int apply(java.lang.foreign.MemoryAddress _x0, int _x1, int _x2); + int apply(java.lang.foreign.MemoryAddress _x0, int _x1, int _x2, java.lang.foreign.MemoryAddress _x3); static MemorySegment allocate(chown fi, MemorySession session) { return RuntimeHelper.upcallStub(chown.class, fi, fuse_operations.chown$FUNC, session); } static chown ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, int __x1, int __x2) -> { + return (java.lang.foreign.MemoryAddress __x0, int __x1, int __x2, java.lang.foreign.MemoryAddress __x3) -> { try { - return (int)fuse_operations.chown$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, __x2); + return (int)fuse_operations.chown$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, __x2, (java.lang.foreign.Addressable)__x3); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -597,22 +547,23 @@ public static chown chown (MemorySegment segment, MemorySession session) { } static final FunctionDescriptor truncate$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, Constants$root.C_POINTER$LAYOUT, - Constants$root.C_LONG_LONG$LAYOUT + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT ); static final MethodHandle truncate$MH = RuntimeHelper.downcallHandle( fuse_operations.truncate$FUNC ); public interface truncate { - int apply(java.lang.foreign.MemoryAddress _x0, long _x1); + int apply(java.lang.foreign.MemoryAddress _x0, long _x1, java.lang.foreign.MemoryAddress _x2); static MemorySegment allocate(truncate fi, MemorySession session) { return RuntimeHelper.upcallStub(truncate.class, fi, fuse_operations.truncate$FUNC, session); } static truncate ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, long __x1) -> { + return (java.lang.foreign.MemoryAddress __x0, long __x1, java.lang.foreign.MemoryAddress __x2) -> { try { - return (int)fuse_operations.truncate$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1); + return (int)fuse_operations.truncate$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -639,50 +590,6 @@ static truncate ofAddress(MemoryAddress addr, MemorySession session) { public static truncate truncate (MemorySegment segment, MemorySession session) { return truncate.ofAddress(truncate$get(segment), session); } - static final FunctionDescriptor utime$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle utime$MH = RuntimeHelper.downcallHandle( - fuse_operations.utime$FUNC - ); - public interface utime { - - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); - static MemorySegment allocate(utime fi, MemorySession session) { - return RuntimeHelper.upcallStub(utime.class, fi, fuse_operations.utime$FUNC, session); - } - static utime ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { - try { - return (int)fuse_operations.utime$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle utime$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("utime")); - public static VarHandle utime$VH() { - return fuse_operations.utime$VH; - } - public static MemoryAddress utime$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.utime$VH.get(seg); - } - public static void utime$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.utime$VH.set(seg, x); - } - public static MemoryAddress utime$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.utime$VH.get(seg.asSlice(index*sizeof())); - } - public static void utime$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.utime$VH.set(seg.asSlice(index*sizeof()), x); - } - public static utime utime (MemorySegment segment, MemorySession session) { - return utime.ofAddress(utime$get(segment), session); - } static final FunctionDescriptor open$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT @@ -1229,22 +1136,23 @@ public static opendir opendir (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_LONG_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_INT$LAYOUT ); static final MethodHandle readdir$MH = RuntimeHelper.downcallHandle( fuse_operations.readdir$FUNC ); public interface readdir { - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2, long _x3, java.lang.foreign.MemoryAddress _x4); + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2, long _x3, java.lang.foreign.MemoryAddress _x4, int _x5); static MemorySegment allocate(readdir fi, MemorySession session) { return RuntimeHelper.upcallStub(readdir.class, fi, fuse_operations.readdir$FUNC, session); } static readdir ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2, long __x3, java.lang.foreign.MemoryAddress __x4) -> { + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2, long __x3, java.lang.foreign.MemoryAddress __x4, int __x5) -> { try { - return (int)fuse_operations.readdir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2, __x3, (java.lang.foreign.Addressable)__x4); + return (int)fuse_operations.readdir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2, __x3, (java.lang.foreign.Addressable)__x4, __x5); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1361,6 +1269,7 @@ public static fsyncdir fsyncdir (MemorySegment segment, MemorySession session) { return fsyncdir.ofAddress(fsyncdir$get(segment), session); } static final FunctionDescriptor init$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT ); static final MethodHandle init$MH = RuntimeHelper.downcallHandle( @@ -1368,15 +1277,15 @@ public static fsyncdir fsyncdir (MemorySegment segment, MemorySession session) { ); public interface init { - java.lang.foreign.Addressable apply(java.lang.foreign.MemoryAddress _x0); + java.lang.foreign.Addressable apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); static MemorySegment allocate(init fi, MemorySession session) { return RuntimeHelper.upcallStub(init.class, fi, fuse_operations.init$FUNC, session); } static init ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0) -> { + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { try { - return (java.lang.foreign.Addressable)(java.lang.foreign.MemoryAddress)fuse_operations.init$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0); + return (java.lang.foreign.Addressable)(java.lang.foreign.MemoryAddress)fuse_operations.init$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1535,96 +1444,6 @@ static create ofAddress(MemoryAddress addr, MemorySession session) { public static create create (MemorySegment segment, MemorySession session) { return create.ofAddress(create$get(segment), session); } - static final FunctionDescriptor ftruncate$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_LONG_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle ftruncate$MH = RuntimeHelper.downcallHandle( - fuse_operations.ftruncate$FUNC - ); - public interface ftruncate { - - int apply(java.lang.foreign.MemoryAddress _x0, long _x1, java.lang.foreign.MemoryAddress _x2); - static MemorySegment allocate(ftruncate fi, MemorySession session) { - return RuntimeHelper.upcallStub(ftruncate.class, fi, fuse_operations.ftruncate$FUNC, session); - } - static ftruncate ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, long __x1, java.lang.foreign.MemoryAddress __x2) -> { - try { - return (int)fuse_operations.ftruncate$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle ftruncate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("ftruncate")); - public static VarHandle ftruncate$VH() { - return fuse_operations.ftruncate$VH; - } - public static MemoryAddress ftruncate$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.ftruncate$VH.get(seg); - } - public static void ftruncate$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.ftruncate$VH.set(seg, x); - } - public static MemoryAddress ftruncate$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.ftruncate$VH.get(seg.asSlice(index*sizeof())); - } - public static void ftruncate$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.ftruncate$VH.set(seg.asSlice(index*sizeof()), x); - } - public static ftruncate ftruncate (MemorySegment segment, MemorySession session) { - return ftruncate.ofAddress(ftruncate$get(segment), session); - } - static final FunctionDescriptor fgetattr$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle fgetattr$MH = RuntimeHelper.downcallHandle( - fuse_operations.fgetattr$FUNC - ); - public interface fgetattr { - - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2); - static MemorySegment allocate(fgetattr fi, MemorySession session) { - return RuntimeHelper.upcallStub(fgetattr.class, fi, fuse_operations.fgetattr$FUNC, session); - } - static fgetattr ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2) -> { - try { - return (int)fuse_operations.fgetattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle fgetattr$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fgetattr")); - public static VarHandle fgetattr$VH() { - return fuse_operations.fgetattr$VH; - } - public static MemoryAddress fgetattr$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.fgetattr$VH.get(seg); - } - public static void fgetattr$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.fgetattr$VH.set(seg, x); - } - public static MemoryAddress fgetattr$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.fgetattr$VH.get(seg.asSlice(index*sizeof())); - } - public static void fgetattr$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.fgetattr$VH.set(seg.asSlice(index*sizeof()), x); - } - public static fgetattr fgetattr (MemorySegment segment, MemorySession session) { - return fgetattr.ofAddress(fgetattr$get(segment), session); - } static final FunctionDescriptor lock$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, @@ -1672,6 +1491,7 @@ public static lock lock (MemorySegment segment, MemorySession session) { return lock.ofAddress(lock$get(segment), session); } static final FunctionDescriptor utimens$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT ); @@ -1680,15 +1500,15 @@ public static lock lock (MemorySegment segment, MemorySession session) { ); public interface utimens { - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2); static MemorySegment allocate(utimens fi, MemorySession session) { return RuntimeHelper.upcallStub(utimens.class, fi, fuse_operations.utimens$FUNC, session); } static utimens ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2) -> { try { - return (int)fuse_operations.utimens$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + return (int)fuse_operations.utimens$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -2039,6 +1859,102 @@ static fallocate ofAddress(MemoryAddress addr, MemorySession session) { public static fallocate fallocate (MemorySegment segment, MemorySession session) { return fallocate.ofAddress(fallocate$get(segment), session); } + static final FunctionDescriptor copy_file_range$FUNC = FunctionDescriptor.of(Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_INT$LAYOUT + ); + static final MethodHandle copy_file_range$MH = RuntimeHelper.downcallHandle( + fuse_operations.copy_file_range$FUNC + ); + public interface copy_file_range { + + long apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, long _x2, java.lang.foreign.MemoryAddress _x3, java.lang.foreign.MemoryAddress _x4, long _x5, long _x6, int _x7); + static MemorySegment allocate(copy_file_range fi, MemorySession session) { + return RuntimeHelper.upcallStub(copy_file_range.class, fi, fuse_operations.copy_file_range$FUNC, session); + } + static copy_file_range ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, long __x2, java.lang.foreign.MemoryAddress __x3, java.lang.foreign.MemoryAddress __x4, long __x5, long __x6, int __x7) -> { + try { + return (long)fuse_operations.copy_file_range$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2, (java.lang.foreign.Addressable)__x3, (java.lang.foreign.Addressable)__x4, __x5, __x6, __x7); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle copy_file_range$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("copy_file_range")); + public static VarHandle copy_file_range$VH() { + return fuse_operations.copy_file_range$VH; + } + public static MemoryAddress copy_file_range$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.copy_file_range$VH.get(seg); + } + public static void copy_file_range$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.copy_file_range$VH.set(seg, x); + } + public static MemoryAddress copy_file_range$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.copy_file_range$VH.get(seg.asSlice(index*sizeof())); + } + public static void copy_file_range$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.copy_file_range$VH.set(seg.asSlice(index*sizeof()), x); + } + public static copy_file_range copy_file_range (MemorySegment segment, MemorySession session) { + return copy_file_range.ofAddress(copy_file_range$get(segment), session); + } + static final FunctionDescriptor lseek$FUNC = FunctionDescriptor.of(Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle lseek$MH = RuntimeHelper.downcallHandle( + fuse_operations.lseek$FUNC + ); + public interface lseek { + + long apply(java.lang.foreign.MemoryAddress _x0, long _x1, int _x2, java.lang.foreign.MemoryAddress _x3); + static MemorySegment allocate(lseek fi, MemorySession session) { + return RuntimeHelper.upcallStub(lseek.class, fi, fuse_operations.lseek$FUNC, session); + } + static lseek ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, long __x1, int __x2, java.lang.foreign.MemoryAddress __x3) -> { + try { + return (long)fuse_operations.lseek$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, __x2, (java.lang.foreign.Addressable)__x3); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle lseek$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("lseek")); + public static VarHandle lseek$VH() { + return fuse_operations.lseek$VH; + } + public static MemoryAddress lseek$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.lseek$VH.get(seg); + } + public static void lseek$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.lseek$VH.set(seg, x); + } + public static MemoryAddress lseek$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.lseek$VH.get(seg.asSlice(index*sizeof())); + } + public static void lseek$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.lseek$VH.set(seg.asSlice(index*sizeof()), x); + } + public static lseek lseek (MemorySegment segment, MemorySession session) { + return lseek.ofAddress(lseek$get(segment), session); + } 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/stdio_h.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/stdio_h.java new file mode 100644 index 00000000..5e7c828c --- /dev/null +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/stdio_h.java @@ -0,0 +1,32 @@ +// 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.*; +public class stdio_h { + + /* package-private */ stdio_h() {} + public static OfByte C_CHAR = Constants$root.C_CHAR$LAYOUT; + public static OfShort C_SHORT = Constants$root.C_SHORT$LAYOUT; + public static OfInt C_INT = Constants$root.C_INT$LAYOUT; + public static OfLong C_LONG = Constants$root.C_LONG_LONG$LAYOUT; + public static OfLong C_LONG_LONG = Constants$root.C_LONG_LONG$LAYOUT; + 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 int RENAME_NOREPLACE() { + return (int)1L; + } + public static int RENAME_EXCHANGE() { + return (int)2L; + } + public static int RENAME_WHITEOUT() { + return (int)4L; + } +} + + From 07a8c903da1c0b7e04b77e7cfad988a7c1d40cc6 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 30 Aug 2022 16:01:36 +0200 Subject: [PATCH 16/98] adjusted jfuse-linux-aarch64 to new API, using libfuse3 --- jfuse-linux-aarch64/pom.xml | 27 +- .../jfuse/linux/aarch64/DirFillerImpl.java | 2 +- .../jfuse/linux/aarch64/FuseImpl.java | 47 +-- .../jfuse/linux/aarch64/extr/constants$0.java | 3 +- .../linux/aarch64/extr/fuse_conn_info.java | 55 ++- .../linux/aarch64/extr/fuse_file_info.java | 62 ++- .../linux/aarch64/extr/fuse_fill_dir_t.java | 6 +- .../jfuse/linux/aarch64/extr/fuse_h.java | 10 +- .../linux/aarch64/extr/fuse_operations.java | 356 +++++++----------- .../jfuse/linux/aarch64/extr/stdio_h.java | 32 ++ 10 files changed, 294 insertions(+), 306 deletions(-) create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/stdio_h.java diff --git a/jfuse-linux-aarch64/pom.xml b/jfuse-linux-aarch64/pom.xml index a79b8abe..5a8ba546 100644 --- a/jfuse-linux-aarch64/pom.xml +++ b/jfuse-linux-aarch64/pom.xml @@ -88,11 +88,11 @@ sources - ${project.parent.basedir}/libfuse2/include/fuse.h + ${project.parent.basedir}/libfuse3/include/fuse.h fuse_h _FILE_OFFSET_BITS=64 - FUSE_USE_VERSION=29 + FUSE_USE_VERSION=35 fuse_main_real @@ -111,6 +111,10 @@ timespec fuse_conn_info + + FUSE_FILL_DIR_PLUS + FUSE_READDIR_PLUS + @@ -175,6 +179,25 @@ + + jextract-stdio + + sources + + + ${linux.headerSearchPath}/stdio.h + stdio_h + + _GNU_SOURCE=1 + + + + RENAME_NOREPLACE + RENAME_EXCHANGE + RENAME_WHITEOUT + + + diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/DirFillerImpl.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/DirFillerImpl.java index f86a7826..3850e0c2 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/DirFillerImpl.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/DirFillerImpl.java @@ -16,7 +16,7 @@ record DirFillerImpl(MemoryAddress buf, fuse_fill_dir_t callback, MemorySession @Override public int fill(String name, Stat stat, long offset) { var statAddr = stat instanceof StatImpl s ? s.segment().address() : MemoryAddress.NULL; - return callback.apply(buf, scope.allocateUtf8String(name).address(), statAddr, offset); + return callback.apply(buf, scope.allocateUtf8String(name).address(), statAddr, offset, 0); // TODO readdir plus } } \ No newline at end of file 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 136202a3..4f440d5c 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 @@ -27,7 +27,7 @@ public FuseImpl(FuseOperations fuseOperations) { fuseOperations.supportedOperations().forEach(this::bind); } - private MemoryAddress init(MemoryAddress conn) { + private MemoryAddress init(MemoryAddress conn, MemoryAddress fuseConfig) { try (var scope = MemorySession.openConfined()) { if (delegate.supportedOperations().contains(FuseOperations.Operation.INIT)) { delegate.init(new FuseConnInfoImpl(conn, scope)); @@ -88,8 +88,10 @@ private int access(MemoryAddress path, int mask) { return delegate.access(path.getUtf8String(0), mask); } - private int chmod(MemoryAddress path, int mode) { - return delegate.chmod(path.getUtf8String(0), mode); + private int chmod(MemoryAddress path, int mode, MemoryAddress fi) { + try (var scope = MemorySession.openConfined()) { + return delegate.chmod(path.getUtf8String(0), mode, new FileInfoImpl(fi, scope)); + } } private int create(MemoryAddress path, int mode, MemoryAddress fi) { @@ -102,9 +104,9 @@ private void destroy(MemoryAddress addr) { delegate.destroy(); } - private int getattr(MemoryAddress path, MemoryAddress stat) { + private int getattr(MemoryAddress path, MemoryAddress stat, MemoryAddress fi) { try (var scope = MemorySession.openConfined()) { - return delegate.getattr(path.getUtf8String(0), new StatImpl(stat, scope)); + return delegate.getattr(path.getUtf8String(0), new StatImpl(stat, scope), new FileInfoImpl(fi, scope)); } } @@ -131,7 +133,7 @@ private int read(MemoryAddress path, MemoryAddress buf, long size, long offset, } } - private int readdir(MemoryAddress path, MemoryAddress buf, MemoryAddress filler, long offset, MemoryAddress fi) { + private int readdir(MemoryAddress path, MemoryAddress buf, MemoryAddress filler, long offset, MemoryAddress fi, int flags) { // TODO: readdir plus try (var scope = MemorySession.openConfined()) { return delegate.readdir(path.getUtf8String(0), new DirFillerImpl(buf, filler, scope), offset, new FileInfoImpl(fi, scope)); } @@ -156,8 +158,8 @@ private int releasedir(MemoryAddress path, MemoryAddress fi) { } } - private int rename(MemoryAddress oldpath, MemoryAddress newpath) { - return delegate.rename(oldpath.getUtf8String(0), newpath.getUtf8String(0)); + private int rename(MemoryAddress oldpath, MemoryAddress newpath, int flags) { + return delegate.rename(oldpath.getUtf8String(0), newpath.getUtf8String(0), flags); } private int rmdir(MemoryAddress path) { @@ -174,30 +176,33 @@ private int symlink(MemoryAddress linkname, MemoryAddress target) { return delegate.symlink(linkname.getUtf8String(0), target.getUtf8String(0)); } - private int truncate(MemoryAddress path, long size) { - return delegate.truncate(path.getUtf8String(0), size); + private int truncate(MemoryAddress path, long size, MemoryAddress fi) { + try (var scope = MemorySession.openConfined()) { + return delegate.truncate(path.getUtf8String(0), size, new FileInfoImpl(fi, scope)); + } } + private int unlink(MemoryAddress path) { return delegate.unlink(path.getUtf8String(0)); } - private int utimens(MemoryAddress path, MemoryAddress times) { - if (MemoryAddress.NULL.equals(times)) { - // set both times to current time (using on-heap memory segments) - var segment = MemorySegment.ofBuffer(ByteBuffer.allocate((int) timespec.$LAYOUT().byteSize())); - timespec.tv_sec$set(segment, 0); - timespec.tv_nsec$set(segment, stat_h.UTIME_NOW()); - var time = new TimeSpecImpl(segment); - return delegate.utimens(path.getUtf8String(0), time, time); - } else { - try (var scope = MemorySession.openConfined()) { + private 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.ofBuffer(ByteBuffer.allocate((int) timespec.$LAYOUT().byteSize())); + timespec.tv_sec$set(segment, 0); + timespec.tv_nsec$set(segment, stat_h.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, timespec.$LAYOUT()); var segment = MemorySegment.ofAddress(times, seq.byteSize(), scope); var time0 = segment.asSlice(0, timespec.$LAYOUT().byteSize()); var time1 = segment.asSlice(timespec.$LAYOUT().byteSize(), timespec.$LAYOUT().byteSize()); // var timeSpecs = segment.elements(seq.elementLayout()).map(MacTimeSpec::new).toArray(MacTimeSpec[]::new); - return delegate.utimens(path.getUtf8String(0), new TimeSpecImpl(time0), new TimeSpecImpl(time1)); + return delegate.utimens(path.getUtf8String(0), new TimeSpecImpl(time0), new TimeSpecImpl(time1), new FileInfoImpl(fi, scope)); } } } 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 fccd980b..540b0c3e 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 @@ -13,7 +13,8 @@ class constants$0 { Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, - Constants$root.C_LONG_LONG$LAYOUT + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_INT$LAYOUT ); static final MethodHandle fuse_fill_dir_t$MH = RuntimeHelper.downcallHandle( constants$0.fuse_fill_dir_t$FUNC diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_conn_info.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_conn_info.java index 10fbc252..d03be0f1 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_conn_info.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_conn_info.java @@ -12,14 +12,15 @@ public class fuse_conn_info { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( Constants$root.C_INT$LAYOUT.withName("proto_major"), Constants$root.C_INT$LAYOUT.withName("proto_minor"), - Constants$root.C_INT$LAYOUT.withName("async_read"), Constants$root.C_INT$LAYOUT.withName("max_write"), + Constants$root.C_INT$LAYOUT.withName("max_read"), Constants$root.C_INT$LAYOUT.withName("max_readahead"), Constants$root.C_INT$LAYOUT.withName("capable"), Constants$root.C_INT$LAYOUT.withName("want"), Constants$root.C_INT$LAYOUT.withName("max_background"), Constants$root.C_INT$LAYOUT.withName("congestion_threshold"), - MemoryLayout.sequenceLayout(23, Constants$root.C_INT$LAYOUT).withName("reserved") + Constants$root.C_INT$LAYOUT.withName("time_gran"), + MemoryLayout.sequenceLayout(22, Constants$root.C_INT$LAYOUT).withName("reserved") ).withName("fuse_conn_info"); public static MemoryLayout $LAYOUT() { return fuse_conn_info.$struct$LAYOUT; @@ -56,22 +57,6 @@ public class fuse_conn_info { public static void proto_minor$set(MemorySegment seg, long index, int x) { fuse_conn_info.proto_minor$VH.set(seg.asSlice(index*sizeof()), x); } - static final VarHandle async_read$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("async_read")); - public static VarHandle async_read$VH() { - return fuse_conn_info.async_read$VH; - } - public static int async_read$get(MemorySegment seg) { - return (int)fuse_conn_info.async_read$VH.get(seg); - } - public static void async_read$set( MemorySegment seg, int x) { - fuse_conn_info.async_read$VH.set(seg, x); - } - public static int async_read$get(MemorySegment seg, long index) { - return (int)fuse_conn_info.async_read$VH.get(seg.asSlice(index*sizeof())); - } - public static void async_read$set(MemorySegment seg, long index, int x) { - fuse_conn_info.async_read$VH.set(seg.asSlice(index*sizeof()), x); - } static final VarHandle max_write$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max_write")); public static VarHandle max_write$VH() { return fuse_conn_info.max_write$VH; @@ -88,6 +73,22 @@ public class fuse_conn_info { public static void max_write$set(MemorySegment seg, long index, int x) { fuse_conn_info.max_write$VH.set(seg.asSlice(index*sizeof()), x); } + static final VarHandle max_read$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max_read")); + public static VarHandle max_read$VH() { + return fuse_conn_info.max_read$VH; + } + public static int max_read$get(MemorySegment seg) { + return (int)fuse_conn_info.max_read$VH.get(seg); + } + public static void max_read$set( MemorySegment seg, int x) { + fuse_conn_info.max_read$VH.set(seg, x); + } + public static int max_read$get(MemorySegment seg, long index) { + return (int)fuse_conn_info.max_read$VH.get(seg.asSlice(index*sizeof())); + } + public static void max_read$set(MemorySegment seg, long index, int x) { + fuse_conn_info.max_read$VH.set(seg.asSlice(index*sizeof()), x); + } static final VarHandle max_readahead$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max_readahead")); public static VarHandle max_readahead$VH() { return fuse_conn_info.max_readahead$VH; @@ -168,8 +169,24 @@ public class fuse_conn_info { public static void congestion_threshold$set(MemorySegment seg, long index, int x) { fuse_conn_info.congestion_threshold$VH.set(seg.asSlice(index*sizeof()), x); } + static final VarHandle time_gran$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("time_gran")); + public static VarHandle time_gran$VH() { + return fuse_conn_info.time_gran$VH; + } + public static int time_gran$get(MemorySegment seg) { + return (int)fuse_conn_info.time_gran$VH.get(seg); + } + public static void time_gran$set( MemorySegment seg, int x) { + fuse_conn_info.time_gran$VH.set(seg, x); + } + public static int time_gran$get(MemorySegment seg, long index) { + return (int)fuse_conn_info.time_gran$VH.get(seg.asSlice(index*sizeof())); + } + public static void time_gran$set(MemorySegment seg, long index, int x) { + fuse_conn_info.time_gran$VH.set(seg.asSlice(index*sizeof()), x); + } public static MemorySegment reserved$slice(MemorySegment seg) { - return seg.asSlice(36, 92); + return seg.asSlice(40, 88); } 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/fuse_file_info.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_file_info.java index 7a727e71..02ff4c6f 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_file_info.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_file_info.java @@ -11,19 +11,23 @@ public class fuse_file_info { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( Constants$root.C_INT$LAYOUT.withName("flags"), - MemoryLayout.paddingLayout(32), - Constants$root.C_LONG_LONG$LAYOUT.withName("fh_old"), - Constants$root.C_INT$LAYOUT.withName("writepage"), MemoryLayout.structLayout( + MemoryLayout.paddingLayout(1).withName("writepage"), MemoryLayout.paddingLayout(1).withName("direct_io"), MemoryLayout.paddingLayout(1).withName("keep_cache"), MemoryLayout.paddingLayout(1).withName("flush"), MemoryLayout.paddingLayout(1).withName("nonseekable"), MemoryLayout.paddingLayout(1).withName("flock_release"), - MemoryLayout.paddingLayout(27).withName("padding") + MemoryLayout.paddingLayout(1).withName("cache_readdir"), + MemoryLayout.paddingLayout(1).withName("noflush"), + MemoryLayout.paddingLayout(24).withName("padding"), + MemoryLayout.paddingLayout(32).withName("padding2"), + MemoryLayout.paddingLayout(32) ), Constants$root.C_LONG_LONG$LAYOUT.withName("fh"), - Constants$root.C_LONG_LONG$LAYOUT.withName("lock_owner") + Constants$root.C_LONG_LONG$LAYOUT.withName("lock_owner"), + Constants$root.C_INT$LAYOUT.withName("poll_events"), + MemoryLayout.paddingLayout(32) ).withName("fuse_file_info"); public static MemoryLayout $LAYOUT() { return fuse_file_info.$struct$LAYOUT; @@ -44,38 +48,6 @@ public class fuse_file_info { public static void flags$set(MemorySegment seg, long index, int x) { fuse_file_info.flags$VH.set(seg.asSlice(index*sizeof()), x); } - static final VarHandle fh_old$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fh_old")); - public static VarHandle fh_old$VH() { - return fuse_file_info.fh_old$VH; - } - public static long fh_old$get(MemorySegment seg) { - return (long)fuse_file_info.fh_old$VH.get(seg); - } - public static void fh_old$set( MemorySegment seg, long x) { - fuse_file_info.fh_old$VH.set(seg, x); - } - public static long fh_old$get(MemorySegment seg, long index) { - return (long)fuse_file_info.fh_old$VH.get(seg.asSlice(index*sizeof())); - } - public static void fh_old$set(MemorySegment seg, long index, long x) { - fuse_file_info.fh_old$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle writepage$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("writepage")); - public static VarHandle writepage$VH() { - return fuse_file_info.writepage$VH; - } - public static int writepage$get(MemorySegment seg) { - return (int)fuse_file_info.writepage$VH.get(seg); - } - public static void writepage$set( MemorySegment seg, int x) { - fuse_file_info.writepage$VH.set(seg, x); - } - public static int writepage$get(MemorySegment seg, long index) { - return (int)fuse_file_info.writepage$VH.get(seg.asSlice(index*sizeof())); - } - public static void writepage$set(MemorySegment seg, long index, int x) { - fuse_file_info.writepage$VH.set(seg.asSlice(index*sizeof()), x); - } static final VarHandle fh$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fh")); public static VarHandle fh$VH() { return fuse_file_info.fh$VH; @@ -108,6 +80,22 @@ public class fuse_file_info { public static void lock_owner$set(MemorySegment seg, long index, long x) { fuse_file_info.lock_owner$VH.set(seg.asSlice(index*sizeof()), x); } + static final VarHandle poll_events$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("poll_events")); + public static VarHandle poll_events$VH() { + return fuse_file_info.poll_events$VH; + } + public static int poll_events$get(MemorySegment seg) { + return (int)fuse_file_info.poll_events$VH.get(seg); + } + public static void poll_events$set( MemorySegment seg, int x) { + fuse_file_info.poll_events$VH.set(seg, x); + } + public static int poll_events$get(MemorySegment seg, long index) { + return (int)fuse_file_info.poll_events$VH.get(seg.asSlice(index*sizeof())); + } + public static void poll_events$set(MemorySegment seg, long index, int x) { + fuse_file_info.poll_events$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/fuse_fill_dir_t.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_fill_dir_t.java index b3ae19d2..b0e952bc 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 @@ -9,15 +9,15 @@ import static java.lang.foreign.ValueLayout.*; public interface fuse_fill_dir_t { - int apply(java.lang.foreign.MemoryAddress buf, java.lang.foreign.MemoryAddress name, java.lang.foreign.MemoryAddress stbuf, long off); + int apply(java.lang.foreign.MemoryAddress buf, java.lang.foreign.MemoryAddress name, java.lang.foreign.MemoryAddress stbuf, long off, int flags); static MemorySegment allocate(fuse_fill_dir_t fi, MemorySession session) { return RuntimeHelper.upcallStub(fuse_fill_dir_t.class, fi, constants$0.fuse_fill_dir_t$FUNC, session); } 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) -> { + 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); + 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); } 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 a1f12898..74dc5284 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,6 +18,12 @@ 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 int FUSE_READDIR_PLUS() { + return (int)1L; + } + public static int FUSE_FILL_DIR_PLUS() { + return (int)2L; + } public static MethodHandle fuse_exit$MH() { return RuntimeHelper.requireNonNull(constants$0.fuse_exit$MH,"fuse_exit"); } @@ -43,10 +49,10 @@ public static MemoryAddress fuse_get_context () { public static MethodHandle fuse_main_real$MH() { return RuntimeHelper.requireNonNull(constants$0.fuse_main_real$MH,"fuse_main_real"); } - public static int fuse_main_real ( int argc, Addressable argv, Addressable op, long op_size, Addressable user_data) { + public static int fuse_main_real ( int argc, Addressable argv, Addressable op, long op_size, Addressable private_data) { var mh$ = fuse_main_real$MH(); try { - return (int)mh$.invokeExact(argc, argv, op, op_size, user_data); + return (int)mh$.invokeExact(argc, argv, op, op_size, private_data); } 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_operations.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_operations.java index a8338096..d0f09f89 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_operations.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_operations.java @@ -12,7 +12,6 @@ public class fuse_operations { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( Constants$root.C_POINTER$LAYOUT.withName("getattr"), Constants$root.C_POINTER$LAYOUT.withName("readlink"), - Constants$root.C_POINTER$LAYOUT.withName("getdir"), Constants$root.C_POINTER$LAYOUT.withName("mknod"), Constants$root.C_POINTER$LAYOUT.withName("mkdir"), Constants$root.C_POINTER$LAYOUT.withName("unlink"), @@ -23,7 +22,6 @@ public class fuse_operations { Constants$root.C_POINTER$LAYOUT.withName("chmod"), Constants$root.C_POINTER$LAYOUT.withName("chown"), Constants$root.C_POINTER$LAYOUT.withName("truncate"), - Constants$root.C_POINTER$LAYOUT.withName("utime"), Constants$root.C_POINTER$LAYOUT.withName("open"), Constants$root.C_POINTER$LAYOUT.withName("read"), Constants$root.C_POINTER$LAYOUT.withName("write"), @@ -43,29 +41,23 @@ public class fuse_operations { Constants$root.C_POINTER$LAYOUT.withName("destroy"), Constants$root.C_POINTER$LAYOUT.withName("access"), Constants$root.C_POINTER$LAYOUT.withName("create"), - Constants$root.C_POINTER$LAYOUT.withName("ftruncate"), - Constants$root.C_POINTER$LAYOUT.withName("fgetattr"), Constants$root.C_POINTER$LAYOUT.withName("lock"), Constants$root.C_POINTER$LAYOUT.withName("utimens"), Constants$root.C_POINTER$LAYOUT.withName("bmap"), - MemoryLayout.structLayout( - MemoryLayout.paddingLayout(1).withName("flag_nullpath_ok"), - MemoryLayout.paddingLayout(1).withName("flag_nopath"), - MemoryLayout.paddingLayout(1).withName("flag_utime_omit_ok"), - MemoryLayout.paddingLayout(29).withName("flag_reserved"), - MemoryLayout.paddingLayout(32) - ), Constants$root.C_POINTER$LAYOUT.withName("ioctl"), Constants$root.C_POINTER$LAYOUT.withName("poll"), Constants$root.C_POINTER$LAYOUT.withName("write_buf"), Constants$root.C_POINTER$LAYOUT.withName("read_buf"), Constants$root.C_POINTER$LAYOUT.withName("flock"), - Constants$root.C_POINTER$LAYOUT.withName("fallocate") + Constants$root.C_POINTER$LAYOUT.withName("fallocate"), + Constants$root.C_POINTER$LAYOUT.withName("copy_file_range"), + Constants$root.C_POINTER$LAYOUT.withName("lseek") ).withName("fuse_operations"); public static MemoryLayout $LAYOUT() { return fuse_operations.$struct$LAYOUT; } static final FunctionDescriptor getattr$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT ); @@ -74,15 +66,15 @@ public class fuse_operations { ); public interface getattr { - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2); static MemorySegment allocate(getattr fi, MemorySession session) { return RuntimeHelper.upcallStub(getattr.class, fi, fuse_operations.getattr$FUNC, session); } static getattr ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2) -> { try { - return (int)fuse_operations.getattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + return (int)fuse_operations.getattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -154,51 +146,6 @@ static readlink ofAddress(MemoryAddress addr, MemorySession session) { public static readlink readlink (MemorySegment segment, MemorySession session) { return readlink.ofAddress(readlink$get(segment), session); } - static final FunctionDescriptor getdir$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle getdir$MH = RuntimeHelper.downcallHandle( - fuse_operations.getdir$FUNC - ); - public interface getdir { - - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2); - static MemorySegment allocate(getdir fi, MemorySession session) { - return RuntimeHelper.upcallStub(getdir.class, fi, fuse_operations.getdir$FUNC, session); - } - static getdir ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2) -> { - try { - return (int)fuse_operations.getdir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle getdir$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("getdir")); - public static VarHandle getdir$VH() { - return fuse_operations.getdir$VH; - } - public static MemoryAddress getdir$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.getdir$VH.get(seg); - } - public static void getdir$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.getdir$VH.set(seg, x); - } - public static MemoryAddress getdir$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.getdir$VH.get(seg.asSlice(index*sizeof())); - } - public static void getdir$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.getdir$VH.set(seg.asSlice(index*sizeof()), x); - } - public static getdir getdir (MemorySegment segment, MemorySession session) { - return getdir.ofAddress(getdir$get(segment), session); - } static final FunctionDescriptor mknod$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_INT$LAYOUT, @@ -420,22 +367,23 @@ public static symlink symlink (MemorySegment segment, MemorySession session) { } static final FunctionDescriptor rename$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_INT$LAYOUT ); static final MethodHandle rename$MH = RuntimeHelper.downcallHandle( fuse_operations.rename$FUNC ); public interface rename { - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, int _x2); static MemorySegment allocate(rename fi, MemorySession session) { return RuntimeHelper.upcallStub(rename.class, fi, fuse_operations.rename$FUNC, session); } static rename ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, int __x2) -> { try { - return (int)fuse_operations.rename$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + return (int)fuse_operations.rename$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -508,22 +456,23 @@ public static link link (MemorySegment segment, MemorySession session) { } static final FunctionDescriptor chmod$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, Constants$root.C_POINTER$LAYOUT, - Constants$root.C_INT$LAYOUT + Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT ); static final MethodHandle chmod$MH = RuntimeHelper.downcallHandle( fuse_operations.chmod$FUNC ); public interface chmod { - int apply(java.lang.foreign.MemoryAddress _x0, int _x1); + int apply(java.lang.foreign.MemoryAddress _x0, int _x1, java.lang.foreign.MemoryAddress _x2); static MemorySegment allocate(chmod fi, MemorySession session) { return RuntimeHelper.upcallStub(chmod.class, fi, fuse_operations.chmod$FUNC, session); } static chmod ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, int __x1) -> { + return (java.lang.foreign.MemoryAddress __x0, int __x1, java.lang.foreign.MemoryAddress __x2) -> { try { - return (int)fuse_operations.chmod$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1); + return (int)fuse_operations.chmod$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -553,22 +502,23 @@ public static chmod chmod (MemorySegment segment, MemorySession session) { static final FunctionDescriptor chown$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_INT$LAYOUT, - Constants$root.C_INT$LAYOUT + Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT ); static final MethodHandle chown$MH = RuntimeHelper.downcallHandle( fuse_operations.chown$FUNC ); public interface chown { - int apply(java.lang.foreign.MemoryAddress _x0, int _x1, int _x2); + int apply(java.lang.foreign.MemoryAddress _x0, int _x1, int _x2, java.lang.foreign.MemoryAddress _x3); static MemorySegment allocate(chown fi, MemorySession session) { return RuntimeHelper.upcallStub(chown.class, fi, fuse_operations.chown$FUNC, session); } static chown ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, int __x1, int __x2) -> { + return (java.lang.foreign.MemoryAddress __x0, int __x1, int __x2, java.lang.foreign.MemoryAddress __x3) -> { try { - return (int)fuse_operations.chown$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, __x2); + return (int)fuse_operations.chown$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, __x2, (java.lang.foreign.Addressable)__x3); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -597,22 +547,23 @@ public static chown chown (MemorySegment segment, MemorySession session) { } static final FunctionDescriptor truncate$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, Constants$root.C_POINTER$LAYOUT, - Constants$root.C_LONG_LONG$LAYOUT + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT ); static final MethodHandle truncate$MH = RuntimeHelper.downcallHandle( fuse_operations.truncate$FUNC ); public interface truncate { - int apply(java.lang.foreign.MemoryAddress _x0, long _x1); + int apply(java.lang.foreign.MemoryAddress _x0, long _x1, java.lang.foreign.MemoryAddress _x2); static MemorySegment allocate(truncate fi, MemorySession session) { return RuntimeHelper.upcallStub(truncate.class, fi, fuse_operations.truncate$FUNC, session); } static truncate ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, long __x1) -> { + return (java.lang.foreign.MemoryAddress __x0, long __x1, java.lang.foreign.MemoryAddress __x2) -> { try { - return (int)fuse_operations.truncate$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1); + return (int)fuse_operations.truncate$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -639,50 +590,6 @@ static truncate ofAddress(MemoryAddress addr, MemorySession session) { public static truncate truncate (MemorySegment segment, MemorySession session) { return truncate.ofAddress(truncate$get(segment), session); } - static final FunctionDescriptor utime$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle utime$MH = RuntimeHelper.downcallHandle( - fuse_operations.utime$FUNC - ); - public interface utime { - - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); - static MemorySegment allocate(utime fi, MemorySession session) { - return RuntimeHelper.upcallStub(utime.class, fi, fuse_operations.utime$FUNC, session); - } - static utime ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { - try { - return (int)fuse_operations.utime$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle utime$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("utime")); - public static VarHandle utime$VH() { - return fuse_operations.utime$VH; - } - public static MemoryAddress utime$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.utime$VH.get(seg); - } - public static void utime$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.utime$VH.set(seg, x); - } - public static MemoryAddress utime$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.utime$VH.get(seg.asSlice(index*sizeof())); - } - public static void utime$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.utime$VH.set(seg.asSlice(index*sizeof()), x); - } - public static utime utime (MemorySegment segment, MemorySession session) { - return utime.ofAddress(utime$get(segment), session); - } static final FunctionDescriptor open$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT @@ -1229,22 +1136,23 @@ public static opendir opendir (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_LONG_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_INT$LAYOUT ); static final MethodHandle readdir$MH = RuntimeHelper.downcallHandle( fuse_operations.readdir$FUNC ); public interface readdir { - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2, long _x3, java.lang.foreign.MemoryAddress _x4); + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2, long _x3, java.lang.foreign.MemoryAddress _x4, int _x5); static MemorySegment allocate(readdir fi, MemorySession session) { return RuntimeHelper.upcallStub(readdir.class, fi, fuse_operations.readdir$FUNC, session); } static readdir ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2, long __x3, java.lang.foreign.MemoryAddress __x4) -> { + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2, long __x3, java.lang.foreign.MemoryAddress __x4, int __x5) -> { try { - return (int)fuse_operations.readdir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2, __x3, (java.lang.foreign.Addressable)__x4); + return (int)fuse_operations.readdir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2, __x3, (java.lang.foreign.Addressable)__x4, __x5); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1361,6 +1269,7 @@ public static fsyncdir fsyncdir (MemorySegment segment, MemorySession session) { return fsyncdir.ofAddress(fsyncdir$get(segment), session); } static final FunctionDescriptor init$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT ); static final MethodHandle init$MH = RuntimeHelper.downcallHandle( @@ -1368,15 +1277,15 @@ public static fsyncdir fsyncdir (MemorySegment segment, MemorySession session) { ); public interface init { - java.lang.foreign.Addressable apply(java.lang.foreign.MemoryAddress _x0); + java.lang.foreign.Addressable apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); static MemorySegment allocate(init fi, MemorySession session) { return RuntimeHelper.upcallStub(init.class, fi, fuse_operations.init$FUNC, session); } static init ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0) -> { + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { try { - return (java.lang.foreign.Addressable)(java.lang.foreign.MemoryAddress)fuse_operations.init$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0); + return (java.lang.foreign.Addressable)(java.lang.foreign.MemoryAddress)fuse_operations.init$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1535,96 +1444,6 @@ static create ofAddress(MemoryAddress addr, MemorySession session) { public static create create (MemorySegment segment, MemorySession session) { return create.ofAddress(create$get(segment), session); } - static final FunctionDescriptor ftruncate$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_LONG_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle ftruncate$MH = RuntimeHelper.downcallHandle( - fuse_operations.ftruncate$FUNC - ); - public interface ftruncate { - - int apply(java.lang.foreign.MemoryAddress _x0, long _x1, java.lang.foreign.MemoryAddress _x2); - static MemorySegment allocate(ftruncate fi, MemorySession session) { - return RuntimeHelper.upcallStub(ftruncate.class, fi, fuse_operations.ftruncate$FUNC, session); - } - static ftruncate ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, long __x1, java.lang.foreign.MemoryAddress __x2) -> { - try { - return (int)fuse_operations.ftruncate$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle ftruncate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("ftruncate")); - public static VarHandle ftruncate$VH() { - return fuse_operations.ftruncate$VH; - } - public static MemoryAddress ftruncate$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.ftruncate$VH.get(seg); - } - public static void ftruncate$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.ftruncate$VH.set(seg, x); - } - public static MemoryAddress ftruncate$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.ftruncate$VH.get(seg.asSlice(index*sizeof())); - } - public static void ftruncate$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.ftruncate$VH.set(seg.asSlice(index*sizeof()), x); - } - public static ftruncate ftruncate (MemorySegment segment, MemorySession session) { - return ftruncate.ofAddress(ftruncate$get(segment), session); - } - static final FunctionDescriptor fgetattr$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle fgetattr$MH = RuntimeHelper.downcallHandle( - fuse_operations.fgetattr$FUNC - ); - public interface fgetattr { - - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2); - static MemorySegment allocate(fgetattr fi, MemorySession session) { - return RuntimeHelper.upcallStub(fgetattr.class, fi, fuse_operations.fgetattr$FUNC, session); - } - static fgetattr ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2) -> { - try { - return (int)fuse_operations.fgetattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle fgetattr$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fgetattr")); - public static VarHandle fgetattr$VH() { - return fuse_operations.fgetattr$VH; - } - public static MemoryAddress fgetattr$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.fgetattr$VH.get(seg); - } - public static void fgetattr$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.fgetattr$VH.set(seg, x); - } - public static MemoryAddress fgetattr$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.fgetattr$VH.get(seg.asSlice(index*sizeof())); - } - public static void fgetattr$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.fgetattr$VH.set(seg.asSlice(index*sizeof()), x); - } - public static fgetattr fgetattr (MemorySegment segment, MemorySession session) { - return fgetattr.ofAddress(fgetattr$get(segment), session); - } static final FunctionDescriptor lock$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, @@ -1672,6 +1491,7 @@ public static lock lock (MemorySegment segment, MemorySession session) { return lock.ofAddress(lock$get(segment), session); } static final FunctionDescriptor utimens$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT ); @@ -1680,15 +1500,15 @@ public static lock lock (MemorySegment segment, MemorySession session) { ); public interface utimens { - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2); static MemorySegment allocate(utimens fi, MemorySession session) { return RuntimeHelper.upcallStub(utimens.class, fi, fuse_operations.utimens$FUNC, session); } static utimens ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2) -> { try { - return (int)fuse_operations.utimens$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + return (int)fuse_operations.utimens$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -2039,6 +1859,102 @@ static fallocate ofAddress(MemoryAddress addr, MemorySession session) { public static fallocate fallocate (MemorySegment segment, MemorySession session) { return fallocate.ofAddress(fallocate$get(segment), session); } + static final FunctionDescriptor copy_file_range$FUNC = FunctionDescriptor.of(Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_INT$LAYOUT + ); + static final MethodHandle copy_file_range$MH = RuntimeHelper.downcallHandle( + fuse_operations.copy_file_range$FUNC + ); + public interface copy_file_range { + + long apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, long _x2, java.lang.foreign.MemoryAddress _x3, java.lang.foreign.MemoryAddress _x4, long _x5, long _x6, int _x7); + static MemorySegment allocate(copy_file_range fi, MemorySession session) { + return RuntimeHelper.upcallStub(copy_file_range.class, fi, fuse_operations.copy_file_range$FUNC, session); + } + static copy_file_range ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, long __x2, java.lang.foreign.MemoryAddress __x3, java.lang.foreign.MemoryAddress __x4, long __x5, long __x6, int __x7) -> { + try { + return (long)fuse_operations.copy_file_range$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2, (java.lang.foreign.Addressable)__x3, (java.lang.foreign.Addressable)__x4, __x5, __x6, __x7); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle copy_file_range$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("copy_file_range")); + public static VarHandle copy_file_range$VH() { + return fuse_operations.copy_file_range$VH; + } + public static MemoryAddress copy_file_range$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.copy_file_range$VH.get(seg); + } + public static void copy_file_range$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.copy_file_range$VH.set(seg, x); + } + public static MemoryAddress copy_file_range$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.copy_file_range$VH.get(seg.asSlice(index*sizeof())); + } + public static void copy_file_range$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.copy_file_range$VH.set(seg.asSlice(index*sizeof()), x); + } + public static copy_file_range copy_file_range (MemorySegment segment, MemorySession session) { + return copy_file_range.ofAddress(copy_file_range$get(segment), session); + } + static final FunctionDescriptor lseek$FUNC = FunctionDescriptor.of(Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_INT$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle lseek$MH = RuntimeHelper.downcallHandle( + fuse_operations.lseek$FUNC + ); + public interface lseek { + + long apply(java.lang.foreign.MemoryAddress _x0, long _x1, int _x2, java.lang.foreign.MemoryAddress _x3); + static MemorySegment allocate(lseek fi, MemorySession session) { + return RuntimeHelper.upcallStub(lseek.class, fi, fuse_operations.lseek$FUNC, session); + } + static lseek ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress __x0, long __x1, int __x2, java.lang.foreign.MemoryAddress __x3) -> { + try { + return (long)fuse_operations.lseek$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, __x2, (java.lang.foreign.Addressable)__x3); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } + } + + static final VarHandle lseek$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("lseek")); + public static VarHandle lseek$VH() { + return fuse_operations.lseek$VH; + } + public static MemoryAddress lseek$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.lseek$VH.get(seg); + } + public static void lseek$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.lseek$VH.set(seg, x); + } + public static MemoryAddress lseek$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.lseek$VH.get(seg.asSlice(index*sizeof())); + } + public static void lseek$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.lseek$VH.set(seg.asSlice(index*sizeof()), x); + } + public static lseek lseek (MemorySegment segment, MemorySession session) { + return lseek.ofAddress(lseek$get(segment), session); + } 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/stdio_h.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/stdio_h.java new file mode 100644 index 00000000..df67ea8d --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/stdio_h.java @@ -0,0 +1,32 @@ +// 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.*; +public class stdio_h { + + /* package-private */ stdio_h() {} + public static OfByte C_CHAR = Constants$root.C_CHAR$LAYOUT; + public static OfShort C_SHORT = Constants$root.C_SHORT$LAYOUT; + public static OfInt C_INT = Constants$root.C_INT$LAYOUT; + public static OfLong C_LONG = Constants$root.C_LONG_LONG$LAYOUT; + public static OfLong C_LONG_LONG = Constants$root.C_LONG_LONG$LAYOUT; + 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 int RENAME_NOREPLACE() { + return (int)1L; + } + public static int RENAME_EXCHANGE() { + return (int)2L; + } + public static int RENAME_WHITEOUT() { + return (int)4L; + } +} + + From 1fe95daaecae74a87eb4357c9452261854f774e4 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 30 Aug 2022 16:03:30 +0200 Subject: [PATCH 17/98] adjusted jfuse-win-amd64 to new API --- .../org/cryptomator/jfuse/win/amd64/FuseImpl.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 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 a07ee981..96ef3ad9 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 @@ -109,7 +109,7 @@ private int access(MemoryAddress path, int mask) { } private int chmod(MemoryAddress path, int mode) { - return delegate.chmod(path.getUtf8String(0), mode); + return delegate.chmod(path.getUtf8String(0), mode, null); } private int create(MemoryAddress path, int mode, MemoryAddress fi) { @@ -124,7 +124,7 @@ private void destroy(MemoryAddress addr) { private int getattr(MemoryAddress path, MemoryAddress stat) { try (var scope = MemorySession.openConfined()) { - return delegate.getattr(path.getUtf8String(0), new StatImpl(stat, scope)); + return delegate.getattr(path.getUtf8String(0), new StatImpl(stat, scope), null); } } @@ -177,7 +177,7 @@ private int releasedir(MemoryAddress path, MemoryAddress fi) { } private int rename(MemoryAddress oldpath, MemoryAddress newpath) { - return delegate.rename(oldpath.getUtf8String(0), newpath.getUtf8String(0)); + return delegate.rename(oldpath.getUtf8String(0), newpath.getUtf8String(0), 0); } private int rmdir(MemoryAddress path) { @@ -195,7 +195,7 @@ private int symlink(MemoryAddress linkname, MemoryAddress target) { } private int truncate(MemoryAddress path, long size) { - return delegate.truncate(path.getUtf8String(0), size); + return delegate.truncate(path.getUtf8String(0), size, null); } private int unlink(MemoryAddress path) { @@ -209,14 +209,14 @@ private int utimens(MemoryAddress path, MemoryAddress times) { fuse_timespec.tv_sec$set(segment, 0); fuse_timespec.tv_nsec$set(segment, 0); // FIXME use hard-coded UTIME_NOW var time = new TimeSpecImpl(segment); - return delegate.utimens(path.getUtf8String(0), time, time); + return delegate.utimens(path.getUtf8String(0), time, time, null); } else { try (var scope = MemorySession.openConfined()) { 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)); + return delegate.utimens(path.getUtf8String(0), new TimeSpecImpl(time0), new TimeSpecImpl(time1), null); } } } From 0a87b6ac1d637088ac630aa92a941942163a7a75 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 30 Aug 2022 18:07:10 +0200 Subject: [PATCH 18/98] load libfuse3.so --- .../org/cryptomator/jfuse/linux/aarch64/LinuxFuseBuilder.java | 2 +- .../org/cryptomator/jfuse/linux/amd64/LinuxFuseBuilder.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/LinuxFuseBuilder.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/LinuxFuseBuilder.java index 7a1d5153..221c138f 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/LinuxFuseBuilder.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/LinuxFuseBuilder.java @@ -11,7 +11,7 @@ @SupportedPlatform(os = OperatingSystem.LINUX, arch = Architecture.ARM64) public class LinuxFuseBuilder implements FuseBuilder { - private static final String DEFAULT_LIB_PATH = "/lib/aarch64-linux-gnu/libfuse.so.2.9.9"; + private static final String DEFAULT_LIB_PATH = "/lib/aarch64-linux-gnu/libfuse3.so.3"; private static final Errno ERRNO = new LinuxErrno(); private String libraryPath; diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/LinuxFuseBuilder.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/LinuxFuseBuilder.java index d4803ed5..b9dd262e 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/LinuxFuseBuilder.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/LinuxFuseBuilder.java @@ -11,7 +11,7 @@ @SupportedPlatform(os = OperatingSystem.LINUX, arch = Architecture.AMD64) public class LinuxFuseBuilder implements FuseBuilder { - private static final String DEFAULT_LIB_PATH = "/lib/x86_64-linux-gnu/libfuse.so.2.9.9"; + private static final String DEFAULT_LIB_PATH = "/lib/x86_64-linux-gnu/libfuse3.so.3"; private static final Errno ERRNO = new LinuxErrno(); private String libraryPath; From e555c345c30545ae1b1246736e5f5fb27dd2c14c Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Wed, 31 Aug 2022 15:06:41 +0200 Subject: [PATCH 19/98] fix utimens(path, NULL) and added tests --- .../src/main/java/module-info.java | 2 + .../jfuse/linux/aarch64/FuseImpl.java | 23 +++---- .../jfuse/linux/aarch64/FuseImplTest.java | 66 +++++++++++++++++++ .../src/main/java/module-info.java | 2 + .../jfuse/linux/amd64/FuseImpl.java | 23 +++---- .../jfuse/linux/amd64/FuseImplTest.java | 66 +++++++++++++++++++ jfuse-mac/src/main/java/module-info.java | 2 + .../org/cryptomator/jfuse/mac/FuseImpl.java | 24 +++---- .../cryptomator/jfuse/mac/FuseImplTest.java | 66 +++++++++++++++++++ .../src/main/java/module-info.java | 2 + .../cryptomator/jfuse/win/amd64/FuseImpl.java | 22 ++++--- .../jfuse/win/amd64/FuseImplTest.java | 66 +++++++++++++++++++ 12 files changed, 320 insertions(+), 44 deletions(-) create mode 100644 jfuse-linux-aarch64/src/test/java/org/cryptomator/jfuse/linux/aarch64/FuseImplTest.java create mode 100644 jfuse-linux-amd64/src/test/java/org/cryptomator/jfuse/linux/amd64/FuseImplTest.java create mode 100644 jfuse-mac/src/test/java/org/cryptomator/jfuse/mac/FuseImplTest.java create mode 100644 jfuse-win-amd64/src/test/java/org/cryptomator/jfuse/win/amd64/FuseImplTest.java diff --git a/jfuse-linux-aarch64/src/main/java/module-info.java b/jfuse-linux-aarch64/src/main/java/module-info.java index dc6638c7..ef615d22 100644 --- a/jfuse-linux-aarch64/src/main/java/module-info.java +++ b/jfuse-linux-aarch64/src/main/java/module-info.java @@ -3,6 +3,8 @@ @SuppressWarnings("JavaModuleNaming") // 64 is not a "version", see https://bugs.openjdk.java.net/browse/JDK-8264488 module org.cryptomator.jfuse.linux.aarch64 { + requires static org.jetbrains.annotations; + requires org.cryptomator.jfuse.api; provides FuseBuilder with LinuxFuseBuilder; 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 136202a3..d9601b2a 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 @@ -6,6 +6,7 @@ import org.cryptomator.jfuse.linux.aarch64.extr.fuse_operations; import org.cryptomator.jfuse.linux.aarch64.extr.stat_h; import org.cryptomator.jfuse.linux.aarch64.extr.timespec; +import org.jetbrains.annotations.VisibleForTesting; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemoryLayout; @@ -182,21 +183,21 @@ private int unlink(MemoryAddress path) { return delegate.unlink(path.getUtf8String(0)); } - private int utimens(MemoryAddress path, MemoryAddress times) { - if (MemoryAddress.NULL.equals(times)) { - // set both times to current time (using on-heap memory segments) - var segment = MemorySegment.ofBuffer(ByteBuffer.allocate((int) timespec.$LAYOUT().byteSize())); - timespec.tv_sec$set(segment, 0); - timespec.tv_nsec$set(segment, stat_h.UTIME_NOW()); - var time = new TimeSpecImpl(segment); - return delegate.utimens(path.getUtf8String(0), time, time); - } else { - try (var scope = MemorySession.openConfined()) { + @VisibleForTesting + int utimens(MemoryAddress path, MemoryAddress times) { + 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(timespec.$LAYOUT().byteSize(), scope); + timespec.tv_sec$set(segment, 0); + timespec.tv_nsec$set(segment, stat_h.UTIME_NOW()); + var time = new TimeSpecImpl(segment); + return delegate.utimens(path.getUtf8String(0), time, time); + } else { var seq = MemoryLayout.sequenceLayout(2, timespec.$LAYOUT()); var segment = MemorySegment.ofAddress(times, seq.byteSize(), scope); var time0 = segment.asSlice(0, timespec.$LAYOUT().byteSize()); var time1 = segment.asSlice(timespec.$LAYOUT().byteSize(), timespec.$LAYOUT().byteSize()); -// var timeSpecs = segment.elements(seq.elementLayout()).map(MacTimeSpec::new).toArray(MacTimeSpec[]::new); return delegate.utimens(path.getUtf8String(0), new TimeSpecImpl(time0), new TimeSpecImpl(time1)); } } 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 new file mode 100644 index 00000000..13e31637 --- /dev/null +++ b/jfuse-linux-aarch64/src/test/java/org/cryptomator/jfuse/linux/aarch64/FuseImplTest.java @@ -0,0 +1,66 @@ +package org.cryptomator.jfuse.linux.aarch64; + +import org.cryptomator.jfuse.api.FuseOperations; +import org.cryptomator.jfuse.api.TimeSpec; +import org.cryptomator.jfuse.linux.aarch64.extr.timespec; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.mockito.Mockito; + +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySession; +import java.time.Instant; + +public class FuseImplTest { + + private FuseOperations fuseOps = Mockito.mock(FuseOperations.class); + private FuseImpl fuseImpl = new FuseImpl(fuseOps); + + @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; + Mockito.doReturn(42).when(fuseOps).utimens(Mockito.eq("/foo"), Mockito.argThat(TimeSpec::isUtimeNow), Mockito.argThat(TimeSpec::isUtimeNow)); + + var result = fuseImpl.utimens(path.address(), times); + + Assertions.assertEquals(42, result); + } + } + + @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 = timespec.allocateArray(2, scope); + timespec.tv_sec$set(times, 0, sec0); + timespec.tv_nsec$set(times, 0, nsec0); + timespec.tv_sec$set(times, 1, sec1); + 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()))); + + var result = fuseImpl.utimens(path.address(), times.address()); + + Assertions.assertEquals(42, result); + } + } + } + +} \ No newline at end of file diff --git a/jfuse-linux-amd64/src/main/java/module-info.java b/jfuse-linux-amd64/src/main/java/module-info.java index 8e834c0b..1b8d5029 100644 --- a/jfuse-linux-amd64/src/main/java/module-info.java +++ b/jfuse-linux-amd64/src/main/java/module-info.java @@ -3,6 +3,8 @@ @SuppressWarnings("JavaModuleNaming") // 64 is not a "version", see https://bugs.openjdk.java.net/browse/JDK-8264488 module org.cryptomator.jfuse.linux.amd64 { + requires static org.jetbrains.annotations; + requires org.cryptomator.jfuse.api; provides FuseBuilder with LinuxFuseBuilder; 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 b84d63a8..71868767 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 @@ -6,6 +6,7 @@ import org.cryptomator.jfuse.linux.amd64.extr.fuse_operations; import org.cryptomator.jfuse.linux.amd64.extr.stat_h; import org.cryptomator.jfuse.linux.amd64.extr.timespec; +import org.jetbrains.annotations.VisibleForTesting; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemoryLayout; @@ -182,21 +183,21 @@ private int unlink(MemoryAddress path) { return delegate.unlink(path.getUtf8String(0)); } - private int utimens(MemoryAddress path, MemoryAddress times) { - if (MemoryAddress.NULL.equals(times)) { - // set both times to current time (using on-heap memory segments) - var segment = MemorySegment.ofBuffer(ByteBuffer.allocate((int) timespec.$LAYOUT().byteSize())); - timespec.tv_sec$set(segment, 0); - timespec.tv_nsec$set(segment, stat_h.UTIME_NOW()); - var time = new TimeSpecImpl(segment); - return delegate.utimens(path.getUtf8String(0), time, time); - } else { - try (var scope = MemorySession.openConfined()) { + @VisibleForTesting + int utimens(MemoryAddress path, MemoryAddress times) { + 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(timespec.$LAYOUT().byteSize(), scope); + timespec.tv_sec$set(segment, 0); + timespec.tv_nsec$set(segment, stat_h.UTIME_NOW()); + var time = new TimeSpecImpl(segment); + return delegate.utimens(path.getUtf8String(0), time, time); + } else { var seq = MemoryLayout.sequenceLayout(2, timespec.$LAYOUT()); var segment = MemorySegment.ofAddress(times, seq.byteSize(), scope); var time0 = segment.asSlice(0, timespec.$LAYOUT().byteSize()); var time1 = segment.asSlice(timespec.$LAYOUT().byteSize(), timespec.$LAYOUT().byteSize()); -// var timeSpecs = segment.elements(seq.elementLayout()).map(MacTimeSpec::new).toArray(MacTimeSpec[]::new); return delegate.utimens(path.getUtf8String(0), new TimeSpecImpl(time0), new TimeSpecImpl(time1)); } } 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 new file mode 100644 index 00000000..d2f37736 --- /dev/null +++ b/jfuse-linux-amd64/src/test/java/org/cryptomator/jfuse/linux/amd64/FuseImplTest.java @@ -0,0 +1,66 @@ +package org.cryptomator.jfuse.linux.amd64; + +import org.cryptomator.jfuse.api.FuseOperations; +import org.cryptomator.jfuse.api.TimeSpec; +import org.cryptomator.jfuse.linux.amd64.extr.timespec; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.mockito.Mockito; + +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySession; +import java.time.Instant; + +public class FuseImplTest { + + private FuseOperations fuseOps = Mockito.mock(FuseOperations.class); + private FuseImpl fuseImpl = new FuseImpl(fuseOps); + + @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; + Mockito.doReturn(42).when(fuseOps).utimens(Mockito.eq("/foo"), Mockito.argThat(TimeSpec::isUtimeNow), Mockito.argThat(TimeSpec::isUtimeNow)); + + var result = fuseImpl.utimens(path.address(), times); + + Assertions.assertEquals(42, result); + } + } + + @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 = timespec.allocateArray(2, scope); + timespec.tv_sec$set(times, 0, sec0); + timespec.tv_nsec$set(times, 0, nsec0); + timespec.tv_sec$set(times, 1, sec1); + 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()))); + + var result = fuseImpl.utimens(path.address(), times.address()); + + Assertions.assertEquals(42, result); + } + } + } + +} \ No newline at end of file diff --git a/jfuse-mac/src/main/java/module-info.java b/jfuse-mac/src/main/java/module-info.java index 459f103a..a3191a75 100644 --- a/jfuse-mac/src/main/java/module-info.java +++ b/jfuse-mac/src/main/java/module-info.java @@ -2,6 +2,8 @@ import org.cryptomator.jfuse.mac.MacFuseBuilder; module org.cryptomator.jfuse.mac { + requires static org.jetbrains.annotations; + requires org.cryptomator.jfuse.api; provides FuseBuilder with MacFuseBuilder; diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java index ca58fd30..b2f46283 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java @@ -6,12 +6,12 @@ import org.cryptomator.jfuse.mac.extr.fuse_operations; import org.cryptomator.jfuse.mac.extr.stat_h; import org.cryptomator.jfuse.mac.extr.timespec; +import org.jetbrains.annotations.VisibleForTesting; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; import java.lang.foreign.MemorySession; -import java.nio.ByteBuffer; import java.util.concurrent.CompletableFuture; public final class FuseImpl extends Fuse { @@ -182,21 +182,21 @@ private int unlink(MemoryAddress path) { return delegate.unlink(path.getUtf8String(0)); } - private int utimens(MemoryAddress path, MemoryAddress times) { - if (MemoryAddress.NULL.equals(times)) { - // set both times to current time (using on-heap memory segments) - var segment = MemorySegment.ofBuffer(ByteBuffer.allocate((int) timespec.$LAYOUT().byteSize())); - timespec.tv_sec$set(segment, 0); - timespec.tv_nsec$set(segment, stat_h.UTIME_NOW()); - var time = new TimeSpecImpl(segment); - return delegate.utimens(path.getUtf8String(0), time, time); - } else { - try (var scope = MemorySession.openConfined()) { + @VisibleForTesting + int utimens(MemoryAddress path, MemoryAddress times) { + 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(timespec.$LAYOUT().byteSize(), scope); + timespec.tv_sec$set(segment, 0); + timespec.tv_nsec$set(segment, stat_h.UTIME_NOW()); + var time = new TimeSpecImpl(segment); + return delegate.utimens(path.getUtf8String(0), time, time); + } else { var seq = MemoryLayout.sequenceLayout(2, timespec.$LAYOUT()); var segment = MemorySegment.ofAddress(times, seq.byteSize(), scope); var time0 = segment.asSlice(0, timespec.$LAYOUT().byteSize()); var time1 = segment.asSlice(timespec.$LAYOUT().byteSize(), timespec.$LAYOUT().byteSize()); -// var timeSpecs = segment.elements(seq.elementLayout()).map(MacTimeSpec::new).toArray(MacTimeSpec[]::new); return delegate.utimens(path.getUtf8String(0), new TimeSpecImpl(time0), new TimeSpecImpl(time1)); } } diff --git a/jfuse-mac/src/test/java/org/cryptomator/jfuse/mac/FuseImplTest.java b/jfuse-mac/src/test/java/org/cryptomator/jfuse/mac/FuseImplTest.java new file mode 100644 index 00000000..8af02986 --- /dev/null +++ b/jfuse-mac/src/test/java/org/cryptomator/jfuse/mac/FuseImplTest.java @@ -0,0 +1,66 @@ +package org.cryptomator.jfuse.mac; + +import org.cryptomator.jfuse.api.FuseOperations; +import org.cryptomator.jfuse.api.TimeSpec; +import org.cryptomator.jfuse.mac.extr.timespec; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.mockito.Mockito; + +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySession; +import java.time.Instant; + +public class FuseImplTest { + + private FuseOperations fuseOps = Mockito.mock(FuseOperations.class); + private FuseImpl fuseImpl = new FuseImpl(fuseOps); + + @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; + Mockito.doReturn(42).when(fuseOps).utimens(Mockito.eq("/foo"), Mockito.argThat(TimeSpec::isUtimeNow), Mockito.argThat(TimeSpec::isUtimeNow)); + + var result = fuseImpl.utimens(path.address(), times); + + Assertions.assertEquals(42, result); + } + } + + @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 = timespec.allocateArray(2, scope); + timespec.tv_sec$set(times, 0, sec0); + timespec.tv_nsec$set(times, 0, nsec0); + timespec.tv_sec$set(times, 1, sec1); + 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()))); + + var result = fuseImpl.utimens(path.address(), times.address()); + + Assertions.assertEquals(42, result); + } + } + } + +} \ No newline at end of file diff --git a/jfuse-win-amd64/src/main/java/module-info.java b/jfuse-win-amd64/src/main/java/module-info.java index d310f1c7..0067f1cd 100644 --- a/jfuse-win-amd64/src/main/java/module-info.java +++ b/jfuse-win-amd64/src/main/java/module-info.java @@ -3,6 +3,8 @@ @SuppressWarnings("JavaModuleNaming") // 64 is not a "version", see https://bugs.openjdk.java.net/browse/JDK-8264488 module org.cryptomator.jfuse.win.amd64 { + requires static org.jetbrains.annotations; + requires org.cryptomator.jfuse.api; provides FuseBuilder with WinFuseBuilder; 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 a07ee981..e9bb4bd1 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 @@ -6,6 +6,7 @@ import org.cryptomator.jfuse.win.amd64.extr.fuse_h; import org.cryptomator.jfuse.win.amd64.extr.fuse_operations; import org.cryptomator.jfuse.win.amd64.extr.fuse_timespec; +import org.jetbrains.annotations.VisibleForTesting; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemoryLayout; @@ -202,16 +203,17 @@ private int unlink(MemoryAddress path) { return delegate.unlink(path.getUtf8String(0)); } - private int utimens(MemoryAddress path, MemoryAddress times) { - if (MemoryAddress.NULL.equals(times)) { - // set both times to current time (using on-heap memory segments) - var segment = MemorySegment.ofBuffer(ByteBuffer.allocate((int) fuse_timespec.$LAYOUT().byteSize())); - fuse_timespec.tv_sec$set(segment, 0); - fuse_timespec.tv_nsec$set(segment, 0); // FIXME use hard-coded UTIME_NOW - var time = new TimeSpecImpl(segment); - return delegate.utimens(path.getUtf8String(0), time, time); - } else { - try (var scope = MemorySession.openConfined()) { + @VisibleForTesting + int utimens(MemoryAddress path, MemoryAddress times) { + 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 hard-coded UTIME_NOW + var time = new TimeSpecImpl(segment); + return delegate.utimens(path.getUtf8String(0), time, time); + } 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()); 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 new file mode 100644 index 00000000..0a67a37c --- /dev/null +++ b/jfuse-win-amd64/src/test/java/org/cryptomator/jfuse/win/amd64/FuseImplTest.java @@ -0,0 +1,66 @@ +package org.cryptomator.jfuse.win.amd64; + +import org.cryptomator.jfuse.api.FuseOperations; +import org.cryptomator.jfuse.api.TimeSpec; +import org.cryptomator.jfuse.win.amd64.extr.fuse_timespec; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.mockito.Mockito; + +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySession; +import java.time.Instant; + +public class FuseImplTest { + + private FuseOperations fuseOps = Mockito.mock(FuseOperations.class); + private FuseImpl fuseImpl = new FuseImpl(fuseOps); + + @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; + Mockito.doReturn(42).when(fuseOps).utimens(Mockito.eq("/foo"), Mockito.argThat(t -> t.get().getNano() == 0L), Mockito.argThat(t -> t.get().getNano() == 0L)); + + var result = fuseImpl.utimens(path.address(), times); + + Assertions.assertEquals(42, result); + } + } + + @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); + 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()))); + + var result = fuseImpl.utimens(path.address(), times.address()); + + Assertions.assertEquals(42, result); + } + } + } + +} \ No newline at end of file From 66acd154aa964e2e21d847fe9647e12aa25e88b5 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Wed, 31 Aug 2022 18:41:42 +0200 Subject: [PATCH 20/98] fixed file path [ci skip] --- jfuse-linux-amd64/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jfuse-linux-amd64/pom.xml b/jfuse-linux-amd64/pom.xml index 26b05d39..55270016 100644 --- a/jfuse-linux-amd64/pom.xml +++ b/jfuse-linux-amd64/pom.xml @@ -88,7 +88,7 @@ sources - ${project.parent.basedir}/libfuse2/include/fuse.h + ${project.parent.basedir}/libfuse3/include/fuse.h fuse_h _FILE_OFFSET_BITS=64 From b4f97db2a0c674b62392499a0c70a6f69ee9208f Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Fri, 2 Sep 2022 10:32:25 +0200 Subject: [PATCH 21/98] mount + unmount working on linux --- .../org/cryptomator/jfuse/api/FuseArgs.java | 2 +- jfuse-linux-aarch64/pom.xml | 21 ++ .../jfuse/linux/aarch64/FuseImpl.java | 23 +- .../linux/aarch64/extr/ll/Constants$root.java | 23 ++ .../linux/aarch64/extr/ll/RuntimeHelper.java | 233 ++++++++++++++++++ .../linux/aarch64/extr/ll/constants$0.java | 22 ++ .../aarch64/extr/ll/fuse_cmdline_opts.java | 178 +++++++++++++ .../aarch64/extr/ll/fuse_lowlevel_h.java | 34 +++ jfuse-linux-amd64/pom.xml | 21 ++ .../jfuse/linux/amd64/FuseImpl.java | 25 +- .../linux/amd64/extr/ll/Constants$root.java | 23 ++ .../linux/amd64/extr/ll/RuntimeHelper.java | 233 ++++++++++++++++++ .../linux/amd64/extr/ll/constants$0.java | 22 ++ .../amd64/extr/ll/fuse_cmdline_opts.java | 178 +++++++++++++ .../linux/amd64/extr/ll/fuse_lowlevel_h.java | 34 +++ 15 files changed, 1052 insertions(+), 20 deletions(-) create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/Constants$root.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/RuntimeHelper.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/constants$0.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/fuse_cmdline_opts.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/fuse_lowlevel_h.java create mode 100644 jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/Constants$root.java create mode 100644 jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/RuntimeHelper.java create mode 100644 jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/constants$0.java create mode 100644 jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/fuse_cmdline_opts.java create mode 100644 jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/fuse_lowlevel_h.java diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseArgs.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseArgs.java index e4d80b2b..b0be8bda 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseArgs.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseArgs.java @@ -2,5 +2,5 @@ import java.lang.foreign.MemorySegment; -public record FuseArgs(MemorySegment args, boolean multithreaded, boolean foreground) { +public record FuseArgs(MemorySegment args, MemorySegment opts) { } diff --git a/jfuse-linux-aarch64/pom.xml b/jfuse-linux-aarch64/pom.xml index 73f9e523..4690d2f4 100644 --- a/jfuse-linux-aarch64/pom.xml +++ b/jfuse-linux-aarch64/pom.xml @@ -125,6 +125,27 @@ + + jextract-fuse-lowlevel + + sources + + + ${project.parent.basedir}/libfuse3/include/fuse_lowlevel.h + org.cryptomator.jfuse.linux.aarch64.extr.ll + fuse_lowlevel_h + + _FILE_OFFSET_BITS=64 + FUSE_USE_VERSION=35 + + + fuse_parse_cmdline + + + fuse_cmdline_opts + + + jextract-errno 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 6a18ea33..7a2dcb0c 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 @@ -7,6 +7,8 @@ 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.stat_h; import org.cryptomator.jfuse.linux.aarch64.extr.timespec; import org.jetbrains.annotations.VisibleForTesting; @@ -20,8 +22,6 @@ import java.util.List; import java.util.concurrent.CompletableFuture; -import static java.lang.foreign.ValueLayout.JAVA_INT; - public final class FuseImpl extends Fuse { private final CompletableFuture initialized = new CompletableFuture<>(); @@ -56,14 +56,19 @@ protected CompletableFuture initialized() { protected FuseArgs parseCmdLine(List args, MemorySession scope) { var fuseArgs = fuse_args.allocate(scope); var argc = args.size(); - var argv = scope.allocateArray(ValueLayout.ADDRESS, argc); + var argv = scope.allocateArray(ValueLayout.ADDRESS, argc + 1); for (int i = 0; i < argc; i++) { var cString = scope.allocateUtf8String(args.get(i)); argv.setAtIndex(ValueLayout.ADDRESS, i, cString); } + argv.setAtIndex(ValueLayout.ADDRESS, argc, MemoryAddress.NULL); fuse_args.argc$set(fuseArgs, argc); fuse_args.argv$set(fuseArgs, argv.address()); fuse_args.allocated$set(fuseArgs, 0); + + var opts = fuse_cmdline_opts.allocate(scope); + fuse_lowlevel_h.fuse_parse_cmdline(fuseArgs.address(), opts.address()); + System.out.println("args: " + String.join(" ", args)); { var parsedArgc = fuse_args.argc$get(fuseArgs); @@ -73,7 +78,7 @@ protected FuseArgs parseCmdLine(List args, MemorySession scope) { System.out.println("arg[" + i + "]: " + cString); } } - return new FuseArgs(fuseArgs, false, true); + return new FuseArgs(fuseArgs, opts); } @Override @@ -81,16 +86,16 @@ protected FuseSession mount(FuseArgs args, Path mountPoint) { try (var scope = MemorySession.openConfined()) { var mountPointStr = scope.allocateUtf8String(mountPoint.toString()); var fuse = fuse_h.fuse_new(args.args(), fuseOps, fuseOps.byteSize(), MemoryAddress.NULL); - var session = fuse_h.fuse_get_session(fuse); if (MemoryAddress.NULL.equals(fuse)) { - fuse_h.fuse_unmount(session); // TODO use explicit exception type throw new IllegalArgumentException("fuse_new failed"); } - if (fuse_h.fuse_mount(session, mountPointStr) != 0) { + var session = fuse_h.fuse_get_session(fuse); + //var mountPointStr = fuse_cmdline_opts.mountpoint$get(args.opts()); + if (fuse_h.fuse_mount(fuse, mountPointStr) != 0) { // TODO any cleanup needed? // TODO use explicit exception type - throw new IllegalArgumentException("Failed to mount to " + mountPoint + " with given args."); + throw new IllegalArgumentException("fuse_mount failed for mount point " + mountPoint); } return new FuseSession(fuse, session); } @@ -104,7 +109,7 @@ protected int loop(FuseSession session, boolean multithreaded) { @Override protected void unmount(FuseSession session) { - fuse_h.fuse_unmount(session.session()); + fuse_h.fuse_unmount(session.fuse()); } @Override 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 new file mode 100644 index 00000000..4fc85421 --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/Constants$root.java @@ -0,0 +1,23 @@ +// 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 new file mode 100644 index 00000000..89a36033 --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/RuntimeHelper.java @@ -0,0 +1,233 @@ +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 new file mode 100644 index 00000000..426dcc26 --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/constants$0.java @@ -0,0 +1,22 @@ +// 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$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 + ); +} + + 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 new file mode 100644 index 00000000..34c36adb --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/fuse_cmdline_opts.java @@ -0,0 +1,178 @@ +// 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 fuse_cmdline_opts { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_INT$LAYOUT.withName("singlethread"), + Constants$root.C_INT$LAYOUT.withName("foreground"), + Constants$root.C_INT$LAYOUT.withName("debug"), + Constants$root.C_INT$LAYOUT.withName("nodefault_subtype"), + Constants$root.C_POINTER$LAYOUT.withName("mountpoint"), + 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") + ).withName("fuse_cmdline_opts"); + public static MemoryLayout $LAYOUT() { + return fuse_cmdline_opts.$struct$LAYOUT; + } + static final VarHandle singlethread$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("singlethread")); + public static VarHandle singlethread$VH() { + return fuse_cmdline_opts.singlethread$VH; + } + public static int singlethread$get(MemorySegment seg) { + return (int)fuse_cmdline_opts.singlethread$VH.get(seg); + } + public static void singlethread$set( MemorySegment seg, int x) { + fuse_cmdline_opts.singlethread$VH.set(seg, x); + } + public static int singlethread$get(MemorySegment seg, long index) { + return (int)fuse_cmdline_opts.singlethread$VH.get(seg.asSlice(index*sizeof())); + } + public static void singlethread$set(MemorySegment seg, long index, int x) { + fuse_cmdline_opts.singlethread$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle foreground$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("foreground")); + public static VarHandle foreground$VH() { + return fuse_cmdline_opts.foreground$VH; + } + public static int foreground$get(MemorySegment seg) { + return (int)fuse_cmdline_opts.foreground$VH.get(seg); + } + public static void foreground$set( MemorySegment seg, int x) { + fuse_cmdline_opts.foreground$VH.set(seg, x); + } + public static int foreground$get(MemorySegment seg, long index) { + return (int)fuse_cmdline_opts.foreground$VH.get(seg.asSlice(index*sizeof())); + } + public static void foreground$set(MemorySegment seg, long index, int x) { + fuse_cmdline_opts.foreground$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle debug$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("debug")); + public static VarHandle debug$VH() { + return fuse_cmdline_opts.debug$VH; + } + public static int debug$get(MemorySegment seg) { + return (int)fuse_cmdline_opts.debug$VH.get(seg); + } + public static void debug$set( MemorySegment seg, int x) { + fuse_cmdline_opts.debug$VH.set(seg, x); + } + public static int debug$get(MemorySegment seg, long index) { + return (int)fuse_cmdline_opts.debug$VH.get(seg.asSlice(index*sizeof())); + } + public static void debug$set(MemorySegment seg, long index, int x) { + fuse_cmdline_opts.debug$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle nodefault_subtype$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("nodefault_subtype")); + public static VarHandle nodefault_subtype$VH() { + return fuse_cmdline_opts.nodefault_subtype$VH; + } + public static int nodefault_subtype$get(MemorySegment seg) { + return (int)fuse_cmdline_opts.nodefault_subtype$VH.get(seg); + } + public static void nodefault_subtype$set( MemorySegment seg, int x) { + fuse_cmdline_opts.nodefault_subtype$VH.set(seg, x); + } + public static int nodefault_subtype$get(MemorySegment seg, long index) { + return (int)fuse_cmdline_opts.nodefault_subtype$VH.get(seg.asSlice(index*sizeof())); + } + public static void nodefault_subtype$set(MemorySegment seg, long index, int x) { + fuse_cmdline_opts.nodefault_subtype$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle mountpoint$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("mountpoint")); + public static VarHandle mountpoint$VH() { + return fuse_cmdline_opts.mountpoint$VH; + } + public static MemoryAddress mountpoint$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_cmdline_opts.mountpoint$VH.get(seg); + } + public static void mountpoint$set( MemorySegment seg, MemoryAddress x) { + fuse_cmdline_opts.mountpoint$VH.set(seg, x); + } + public static MemoryAddress mountpoint$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_cmdline_opts.mountpoint$VH.get(seg.asSlice(index*sizeof())); + } + public static void mountpoint$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_cmdline_opts.mountpoint$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle show_version$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("show_version")); + public static VarHandle show_version$VH() { + return fuse_cmdline_opts.show_version$VH; + } + public static int show_version$get(MemorySegment seg) { + return (int)fuse_cmdline_opts.show_version$VH.get(seg); + } + public static void show_version$set( MemorySegment seg, int x) { + fuse_cmdline_opts.show_version$VH.set(seg, x); + } + public static int show_version$get(MemorySegment seg, long index) { + return (int)fuse_cmdline_opts.show_version$VH.get(seg.asSlice(index*sizeof())); + } + public static void show_version$set(MemorySegment seg, long index, int x) { + fuse_cmdline_opts.show_version$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle show_help$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("show_help")); + public static VarHandle show_help$VH() { + return fuse_cmdline_opts.show_help$VH; + } + public static int show_help$get(MemorySegment seg) { + return (int)fuse_cmdline_opts.show_help$VH.get(seg); + } + public static void show_help$set( MemorySegment seg, int x) { + fuse_cmdline_opts.show_help$VH.set(seg, x); + } + public static int show_help$get(MemorySegment seg, long index) { + return (int)fuse_cmdline_opts.show_help$VH.get(seg.asSlice(index*sizeof())); + } + public static void show_help$set(MemorySegment seg, long index, int x) { + fuse_cmdline_opts.show_help$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle clone_fd$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("clone_fd")); + public static VarHandle clone_fd$VH() { + return fuse_cmdline_opts.clone_fd$VH; + } + public static int clone_fd$get(MemorySegment seg) { + return (int)fuse_cmdline_opts.clone_fd$VH.get(seg); + } + public static void clone_fd$set( MemorySegment seg, int x) { + fuse_cmdline_opts.clone_fd$VH.set(seg, x); + } + public static int clone_fd$get(MemorySegment seg, long index) { + return (int)fuse_cmdline_opts.clone_fd$VH.get(seg.asSlice(index*sizeof())); + } + public static void clone_fd$set(MemorySegment seg, long index, int x) { + fuse_cmdline_opts.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_cmdline_opts.max_idle_threads$VH; + } + public static int max_idle_threads$get(MemorySegment seg) { + return (int)fuse_cmdline_opts.max_idle_threads$VH.get(seg); + } + public static void max_idle_threads$set( MemorySegment seg, int x) { + fuse_cmdline_opts.max_idle_threads$VH.set(seg, x); + } + public static int max_idle_threads$get(MemorySegment seg, long index) { + return (int)fuse_cmdline_opts.max_idle_threads$VH.get(seg.asSlice(index*sizeof())); + } + 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); + } + 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-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 new file mode 100644 index 00000000..b6462f4d --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/ll/fuse_lowlevel_h.java @@ -0,0 +1,34 @@ +// 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 fuse_lowlevel_h { + + /* package-private */ fuse_lowlevel_h() {} + public static OfByte C_CHAR = Constants$root.C_CHAR$LAYOUT; + public static OfShort C_SHORT = Constants$root.C_SHORT$LAYOUT; + public static OfInt C_INT = Constants$root.C_INT$LAYOUT; + public static OfLong C_LONG = Constants$root.C_LONG_LONG$LAYOUT; + public static OfLong C_LONG_LONG = Constants$root.C_LONG_LONG$LAYOUT; + 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 int fuse_parse_cmdline ( Addressable args, Addressable opts) { + var mh$ = fuse_parse_cmdline$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/pom.xml b/jfuse-linux-amd64/pom.xml index 622f34db..744aa986 100644 --- a/jfuse-linux-amd64/pom.xml +++ b/jfuse-linux-amd64/pom.xml @@ -125,6 +125,27 @@ + + jextract-fuse-lowlevel + + sources + + + ${project.parent.basedir}/libfuse3/include/fuse_lowlevel.h + org.cryptomator.jfuse.linux.amd64.extr.ll + fuse_lowlevel_h + + _FILE_OFFSET_BITS=64 + FUSE_USE_VERSION=35 + + + fuse_parse_cmdline + + + fuse_cmdline_opts + + + jextract-errno 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 3f71a1a0..c0f5febe 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 @@ -7,6 +7,8 @@ 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.stat_h; import org.cryptomator.jfuse.linux.amd64.extr.timespec; import org.jetbrains.annotations.VisibleForTesting; @@ -20,8 +22,6 @@ import java.util.List; import java.util.concurrent.CompletableFuture; -import static java.lang.foreign.ValueLayout.JAVA_INT; - public final class FuseImpl extends Fuse { private final CompletableFuture initialized = new CompletableFuture<>(); @@ -56,14 +56,19 @@ protected CompletableFuture initialized() { protected FuseArgs parseCmdLine(List args, MemorySession scope) { var fuseArgs = fuse_args.allocate(scope); var argc = args.size(); - var argv = scope.allocateArray(ValueLayout.ADDRESS, argc); + var argv = scope.allocateArray(ValueLayout.ADDRESS, argc + 1); for (int i = 0; i < argc; i++) { var cString = scope.allocateUtf8String(args.get(i)); argv.setAtIndex(ValueLayout.ADDRESS, i, cString); } + argv.setAtIndex(ValueLayout.ADDRESS, argc, MemoryAddress.NULL); fuse_args.argc$set(fuseArgs, argc); fuse_args.argv$set(fuseArgs, argv.address()); fuse_args.allocated$set(fuseArgs, 0); + + var opts = fuse_cmdline_opts.allocate(scope); + fuse_lowlevel_h.fuse_parse_cmdline(fuseArgs.address(), opts.address()); + System.out.println("args: " + String.join(" ", args)); { var parsedArgc = fuse_args.argc$get(fuseArgs); @@ -73,7 +78,7 @@ protected FuseArgs parseCmdLine(List args, MemorySession scope) { System.out.println("arg[" + i + "]: " + cString); } } - return new FuseArgs(fuseArgs, false, true); + return new FuseArgs(fuseArgs, opts); } @Override @@ -81,16 +86,16 @@ protected FuseSession mount(FuseArgs args, Path mountPoint) { try (var scope = MemorySession.openConfined()) { var mountPointStr = scope.allocateUtf8String(mountPoint.toString()); var fuse = fuse_h.fuse_new(args.args(), fuseOps, fuseOps.byteSize(), MemoryAddress.NULL); - var session = fuse_h.fuse_get_session(fuse); if (MemoryAddress.NULL.equals(fuse)) { - fuse_h.fuse_unmount(session); // TODO use explicit exception type throw new IllegalArgumentException("fuse_new failed"); } - if (fuse_h.fuse_mount(session, mountPointStr) != 0) { + var session = fuse_h.fuse_get_session(fuse); + //var mountPointStr = fuse_cmdline_opts.mountpoint$get(args.opts()); + if (fuse_h.fuse_mount(fuse, mountPointStr) != 0) { // TODO any cleanup needed? // TODO use explicit exception type - throw new IllegalArgumentException("Failed to mount to " + mountPoint + " with given args."); + throw new IllegalArgumentException("fuse_mount failed for mount point " + mountPoint); } return new FuseSession(fuse, session); } @@ -104,7 +109,7 @@ protected int loop(FuseSession session, boolean multithreaded) { @Override protected void unmount(FuseSession session) { - fuse_h.fuse_unmount(session.session()); + fuse_h.fuse_unmount(session.fuse()); } @Override @@ -268,4 +273,4 @@ private int write(MemoryAddress path, MemoryAddress buf, long size, long offset, } } -} +} \ No newline at end of file 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 new file mode 100644 index 00000000..1985592f --- /dev/null +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/Constants$root.java @@ -0,0 +1,23 @@ +// 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 new file mode 100644 index 00000000..626b76e3 --- /dev/null +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/RuntimeHelper.java @@ -0,0 +1,233 @@ +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 new file mode 100644 index 00000000..30f27df1 --- /dev/null +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/constants$0.java @@ -0,0 +1,22 @@ +// 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$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 + ); +} + + 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 new file mode 100644 index 00000000..56734379 --- /dev/null +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/fuse_cmdline_opts.java @@ -0,0 +1,178 @@ +// 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 fuse_cmdline_opts { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_INT$LAYOUT.withName("singlethread"), + Constants$root.C_INT$LAYOUT.withName("foreground"), + Constants$root.C_INT$LAYOUT.withName("debug"), + Constants$root.C_INT$LAYOUT.withName("nodefault_subtype"), + Constants$root.C_POINTER$LAYOUT.withName("mountpoint"), + 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") + ).withName("fuse_cmdline_opts"); + public static MemoryLayout $LAYOUT() { + return fuse_cmdline_opts.$struct$LAYOUT; + } + static final VarHandle singlethread$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("singlethread")); + public static VarHandle singlethread$VH() { + return fuse_cmdline_opts.singlethread$VH; + } + public static int singlethread$get(MemorySegment seg) { + return (int)fuse_cmdline_opts.singlethread$VH.get(seg); + } + public static void singlethread$set( MemorySegment seg, int x) { + fuse_cmdline_opts.singlethread$VH.set(seg, x); + } + public static int singlethread$get(MemorySegment seg, long index) { + return (int)fuse_cmdline_opts.singlethread$VH.get(seg.asSlice(index*sizeof())); + } + public static void singlethread$set(MemorySegment seg, long index, int x) { + fuse_cmdline_opts.singlethread$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle foreground$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("foreground")); + public static VarHandle foreground$VH() { + return fuse_cmdline_opts.foreground$VH; + } + public static int foreground$get(MemorySegment seg) { + return (int)fuse_cmdline_opts.foreground$VH.get(seg); + } + public static void foreground$set( MemorySegment seg, int x) { + fuse_cmdline_opts.foreground$VH.set(seg, x); + } + public static int foreground$get(MemorySegment seg, long index) { + return (int)fuse_cmdline_opts.foreground$VH.get(seg.asSlice(index*sizeof())); + } + public static void foreground$set(MemorySegment seg, long index, int x) { + fuse_cmdline_opts.foreground$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle debug$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("debug")); + public static VarHandle debug$VH() { + return fuse_cmdline_opts.debug$VH; + } + public static int debug$get(MemorySegment seg) { + return (int)fuse_cmdline_opts.debug$VH.get(seg); + } + public static void debug$set( MemorySegment seg, int x) { + fuse_cmdline_opts.debug$VH.set(seg, x); + } + public static int debug$get(MemorySegment seg, long index) { + return (int)fuse_cmdline_opts.debug$VH.get(seg.asSlice(index*sizeof())); + } + public static void debug$set(MemorySegment seg, long index, int x) { + fuse_cmdline_opts.debug$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle nodefault_subtype$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("nodefault_subtype")); + public static VarHandle nodefault_subtype$VH() { + return fuse_cmdline_opts.nodefault_subtype$VH; + } + public static int nodefault_subtype$get(MemorySegment seg) { + return (int)fuse_cmdline_opts.nodefault_subtype$VH.get(seg); + } + public static void nodefault_subtype$set( MemorySegment seg, int x) { + fuse_cmdline_opts.nodefault_subtype$VH.set(seg, x); + } + public static int nodefault_subtype$get(MemorySegment seg, long index) { + return (int)fuse_cmdline_opts.nodefault_subtype$VH.get(seg.asSlice(index*sizeof())); + } + public static void nodefault_subtype$set(MemorySegment seg, long index, int x) { + fuse_cmdline_opts.nodefault_subtype$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle mountpoint$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("mountpoint")); + public static VarHandle mountpoint$VH() { + return fuse_cmdline_opts.mountpoint$VH; + } + public static MemoryAddress mountpoint$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_cmdline_opts.mountpoint$VH.get(seg); + } + public static void mountpoint$set( MemorySegment seg, MemoryAddress x) { + fuse_cmdline_opts.mountpoint$VH.set(seg, x); + } + public static MemoryAddress mountpoint$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_cmdline_opts.mountpoint$VH.get(seg.asSlice(index*sizeof())); + } + public static void mountpoint$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_cmdline_opts.mountpoint$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle show_version$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("show_version")); + public static VarHandle show_version$VH() { + return fuse_cmdline_opts.show_version$VH; + } + public static int show_version$get(MemorySegment seg) { + return (int)fuse_cmdline_opts.show_version$VH.get(seg); + } + public static void show_version$set( MemorySegment seg, int x) { + fuse_cmdline_opts.show_version$VH.set(seg, x); + } + public static int show_version$get(MemorySegment seg, long index) { + return (int)fuse_cmdline_opts.show_version$VH.get(seg.asSlice(index*sizeof())); + } + public static void show_version$set(MemorySegment seg, long index, int x) { + fuse_cmdline_opts.show_version$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle show_help$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("show_help")); + public static VarHandle show_help$VH() { + return fuse_cmdline_opts.show_help$VH; + } + public static int show_help$get(MemorySegment seg) { + return (int)fuse_cmdline_opts.show_help$VH.get(seg); + } + public static void show_help$set( MemorySegment seg, int x) { + fuse_cmdline_opts.show_help$VH.set(seg, x); + } + public static int show_help$get(MemorySegment seg, long index) { + return (int)fuse_cmdline_opts.show_help$VH.get(seg.asSlice(index*sizeof())); + } + public static void show_help$set(MemorySegment seg, long index, int x) { + fuse_cmdline_opts.show_help$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle clone_fd$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("clone_fd")); + public static VarHandle clone_fd$VH() { + return fuse_cmdline_opts.clone_fd$VH; + } + public static int clone_fd$get(MemorySegment seg) { + return (int)fuse_cmdline_opts.clone_fd$VH.get(seg); + } + public static void clone_fd$set( MemorySegment seg, int x) { + fuse_cmdline_opts.clone_fd$VH.set(seg, x); + } + public static int clone_fd$get(MemorySegment seg, long index) { + return (int)fuse_cmdline_opts.clone_fd$VH.get(seg.asSlice(index*sizeof())); + } + public static void clone_fd$set(MemorySegment seg, long index, int x) { + fuse_cmdline_opts.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_cmdline_opts.max_idle_threads$VH; + } + public static int max_idle_threads$get(MemorySegment seg) { + return (int)fuse_cmdline_opts.max_idle_threads$VH.get(seg); + } + public static void max_idle_threads$set( MemorySegment seg, int x) { + fuse_cmdline_opts.max_idle_threads$VH.set(seg, x); + } + public static int max_idle_threads$get(MemorySegment seg, long index) { + return (int)fuse_cmdline_opts.max_idle_threads$VH.get(seg.asSlice(index*sizeof())); + } + 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); + } + 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-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 new file mode 100644 index 00000000..2c3c67de --- /dev/null +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/ll/fuse_lowlevel_h.java @@ -0,0 +1,34 @@ +// 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 fuse_lowlevel_h { + + /* package-private */ fuse_lowlevel_h() {} + public static OfByte C_CHAR = Constants$root.C_CHAR$LAYOUT; + public static OfShort C_SHORT = Constants$root.C_SHORT$LAYOUT; + public static OfInt C_INT = Constants$root.C_INT$LAYOUT; + public static OfLong C_LONG = Constants$root.C_LONG_LONG$LAYOUT; + public static OfLong C_LONG_LONG = Constants$root.C_LONG_LONG$LAYOUT; + 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 int fuse_parse_cmdline ( Addressable args, Addressable opts) { + var mh$ = fuse_parse_cmdline$MH(); + try { + return (int)mh$.invokeExact(args, opts); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } +} + + From d6756815b7c9c3f3e685908b36c1200de320e411 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Fri, 2 Sep 2022 11:32:23 +0200 Subject: [PATCH 22/98] cleanup [ci skip] --- .../org/cryptomator/jfuse/api/Architecture.java | 15 +++++++++++---- .../cryptomator/jfuse/api/OperatingSystem.java | 17 +++++++++++++---- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Architecture.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Architecture.java index 352e759f..ab4cc13a 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Architecture.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Architecture.java @@ -6,9 +6,16 @@ public enum Architecture { UNKNOWN; private static final String OS_ARCH = System.getProperty("os.arch").toLowerCase(); - public static final Architecture CURRENT = OS_ARCH.contains("x86_64") ? AMD64 // - : OS_ARCH.contains("amd64") ? AMD64 // - : OS_ARCH.contains("aarch64") ? ARM64 // - : UNKNOWN; + public static final Architecture CURRENT = getCurrent(); + + private static Architecture getCurrent() { + if (OS_ARCH.contains("x86_64") || OS_ARCH.contains("amd64")) { + return AMD64; + } else if (OS_ARCH.contains("aarch64")) { + return ARM64; + } else { + return UNKNOWN; + } + } } diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/OperatingSystem.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/OperatingSystem.java index 4023b108..6812e26f 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/OperatingSystem.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/OperatingSystem.java @@ -7,9 +7,18 @@ public enum OperatingSystem { UNKNOWN; private static final String OS_NAME = System.getProperty("os.name").toLowerCase(); - public static final OperatingSystem CURRENT = OS_NAME.contains("linux") ? LINUX - : OS_NAME.contains("mac") ? MAC - : OS_NAME.contains("windows") ? WINDOWS - : UNKNOWN; + public static final OperatingSystem CURRENT = getCurrent(); + + private static OperatingSystem getCurrent() { + if (OS_NAME.contains("linux")) { + return LINUX; + } else if (OS_NAME.contains("mac")) { + return MAC; + } else if (OS_NAME.contains("windows")) { + return WINDOWS; + } else { + return UNKNOWN; + } + } } From 3418950d49cc127a6b6cafbd3c258a65f386af02 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Fri, 2 Sep 2022 11:32:48 +0200 Subject: [PATCH 23/98] Marking API as experimental [ci skip] --- .../src/main/java/org/cryptomator/jfuse/api/package-info.java | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 jfuse-api/src/main/java/org/cryptomator/jfuse/api/package-info.java diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/package-info.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/package-info.java new file mode 100644 index 00000000..a3525a6c --- /dev/null +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/package-info.java @@ -0,0 +1,4 @@ +@ApiStatus.Experimental +package org.cryptomator.jfuse.api; + +import org.jetbrains.annotations.ApiStatus; \ No newline at end of file From 5d7c7b6bb148fbe573272e3481865984ea81221f Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Fri, 2 Sep 2022 14:09:08 +0200 Subject: [PATCH 24/98] changed API to keep implementation details about mounting/unmounting hidden --- .../java/org/cryptomator/jfuse/api/Fuse.java | 118 +++------------- .../org/cryptomator/jfuse/api/FuseArgs.java | 6 - .../org/cryptomator/jfuse/api/FuseMount.java | 11 ++ .../cryptomator/jfuse/api/FuseOperations.java | 2 +- .../cryptomator/jfuse/api/FuseSession.java | 7 - .../jfuse/api/UnmountedFuseMount.java | 18 +++ .../jfuse/linux/aarch64/FuseArgs.java | 31 +++++ .../jfuse/linux/aarch64/FuseImpl.java | 119 ++++++----------- .../jfuse/linux/aarch64/FuseMountImpl.java | 26 ++++ .../jfuse/linux/amd64/FuseArgs.java | 31 +++++ .../jfuse/linux/amd64/FuseImpl.java | 119 ++++++----------- .../jfuse/linux/amd64/FuseMountImpl.java | 26 ++++ .../org/cryptomator/jfuse/mac/FuseArgs.java | 24 ++++ .../org/cryptomator/jfuse/mac/FuseImpl.java | 126 ++++++------------ .../cryptomator/jfuse/mac/FuseMountImpl.java | 25 ++++ .../cryptomator/jfuse/win/amd64/FuseImpl.java | 57 +++++--- .../jfuse/win/amd64/FuseMountImpl.java | 27 ++++ 17 files changed, 397 insertions(+), 376 deletions(-) delete mode 100644 jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseArgs.java create mode 100644 jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseMount.java delete mode 100644 jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseSession.java create mode 100644 jfuse-api/src/main/java/org/cryptomator/jfuse/api/UnmountedFuseMount.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseArgs.java create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseMountImpl.java create mode 100644 jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseArgs.java create mode 100644 jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseMountImpl.java create mode 100644 jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseArgs.java create mode 100644 jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseMountImpl.java create mode 100644 jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseMountImpl.java diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java index f50314eb..a5b22f20 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java @@ -2,27 +2,19 @@ import org.jetbrains.annotations.Blocking; -import org.jetbrains.annotations.MustBeInvokedByOverriders; - import org.jetbrains.annotations.BlockingExecutor; +import org.jetbrains.annotations.MustBeInvokedByOverriders; import java.lang.foreign.MemorySession; -import java.lang.foreign.ValueLayout; - import java.nio.file.Path; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.CancellationException; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; - -import java.util.concurrent.ExecutionException; -import java.util.concurrent.atomic.AtomicReference; - import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicReference; /** @@ -33,8 +25,10 @@ */ public abstract class Fuse implements AutoCloseable { + private static final FuseMount UNMOUNTED = new UnmountedFuseMount(); + protected final MemorySession fuseScope = MemorySession.openShared(); - private final AtomicReference session = new AtomicReference<>(); + private final AtomicReference mount = new AtomicReference<>(UNMOUNTED); @BlockingExecutor private final ExecutorService executor; @@ -64,8 +58,8 @@ public static FuseBuilder builder() { */ @Blocking public int mount(String progName, Path mountPoint, String... flags) throws CompletionException, TimeoutException { - final FuseSession lock = new FuseSession(null, null); - if (!session.compareAndSet(null, lock)) { + FuseMount lock = new UnmountedFuseMount(); + if (!mount.compareAndSet(UNMOUNTED, lock)) { throw new IllegalStateException("Already mounted"); } @@ -75,92 +69,18 @@ public int mount(String progName, Path mountPoint, String... flags) throws Compl args.add("-f"); // always stay in foreground. don't fork & kill this process via `fuse_daemonize` args.add(mountPoint.toString()); - try (var scope = MemorySession.openConfined()) { - var fuseArgs = parseCmdLine(args, scope); - var fuseSession = mount(fuseArgs, mountPoint); // TODO: specific exception - var isOnlySession = session.compareAndSet(lock, fuseSession); - assert isOnlySession : "unreachable code, as no other method can set this.session to SESSION_LOCK"; - - // TODO get multithreaded flag from fuseSession - var mountResult = CompletableFuture.supplyAsync(() -> loop(fuseSession, false), executor); - var result = CompletableFuture.anyOf(mountResult, initialized()).get(10, TimeUnit.SECONDS); - if (result instanceof Integer i) { - return i; - } else { - throw new IllegalStateException("Expected Future"); - } - } catch (CancellationException | ExecutionException e) { - return 1; - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - return 1; + try { + var fuseMount = this.mount(args); + var isOnlySession = mount.compareAndSet(lock, fuseMount); + assert isOnlySession : "unreachable code, as no other method can set this.mount to lock"; + executor.submit(fuseMount::loop); // TODO keep reference of future? } finally { - session.compareAndSet(lock, null); // reset in case of error + mount.compareAndSet(lock, UNMOUNTED); // if value is still `lock`, mount has failed. } + return 0; // TODO make this void and use proper exceptions } - /** - * Invokes {@code fuse_parse_cmdline}. - * - * @param args fuse flags - * @param scope memory session that the returned result is bound to - * @return Parsed flags ready to use for mounting - * @throws IllegalArgumentException If {@code fuse_parse_cmdline} returns -1. - */ - protected abstract FuseArgs parseCmdLine(List args, MemorySession scope) throws IllegalArgumentException; - - /** - * Invokes {@code fuse_mount} and {@code fuse_new} to mount a new fuse file system. - * - * @param args The mount args - * @param mountPoint The mount point - * @return A new fuse session - */ - protected abstract FuseSession mount(FuseArgs args, Path mountPoint); -// @Blocking -// protected int fuseMain(List flags) { -// try (var scope = MemorySession.openConfined()) { -// //var allocator = SegmentAllocator.nativeAllocator(scope); -// var argc = flags.size(); -// var argv = scope.allocateArray(ValueLayout.ADDRESS, argc); -// for (int i = 0; i < argc; i++) { -// var cString = scope.allocateUtf8String(flags.get(i)); -// argv.setAtIndex(ValueLayout.ADDRESS, i, cString); -// } -// return fuseMain(argc, argv); -// } -// } - - /** - * Invokes {@code fuse_loop} or {@code fuse_loop_mt}, depending on {@code multithreaded}. - * - * @param session The fuse session - * @param multithreaded multi-threaded mode - * @return result passed through by {@code fuse_loop} or {@code fuse_loop_mt} - */ - @Blocking - protected abstract int loop(FuseSession session, boolean multithreaded); - - /** - * Unmounts the file system and exits any running loops. - *

- * The implementation needs to be idempotent, i.e. repeated invokations must be no-ops. - * - * @param session The fuse session - */ - protected abstract void unmount(FuseSession session); - - /** - * Invokes {@code fuse_destroy}. - * - * @param session The fuse session - */ - protected abstract void destroy(FuseSession session); - - /** - * @return A future that completes with {@code 0} as soon as {@link FuseOperations#init(FuseConnInfo) init} has been called. - */ - protected abstract CompletableFuture initialized(); + protected abstract FuseMount mount(List args); /** * Unmounts (if needed) this fuse file system and frees up system resources. @@ -171,15 +91,15 @@ public int mount(String progName, Path mountPoint, String... flags) throws Compl @MustBeInvokedByOverriders public void close() throws TimeoutException { try { - var session = this.session.getAndSet(null); - if (session != null) { - unmount(session); + var mount = this.mount.getAndSet(null); + if (mount != null) { + mount.unmount(); executor.shutdown(); boolean exited = executor.awaitTermination(10, TimeUnit.SECONDS); if (!exited) { throw new TimeoutException("fuse main loop continued runn"); } - destroy(session); + mount.destroy(); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseArgs.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseArgs.java deleted file mode 100644 index b0be8bda..00000000 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseArgs.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.cryptomator.jfuse.api; - -import java.lang.foreign.MemorySegment; - -public record FuseArgs(MemorySegment args, MemorySegment opts) { -} diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseMount.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseMount.java new file mode 100644 index 00000000..b39e6337 --- /dev/null +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseMount.java @@ -0,0 +1,11 @@ +package org.cryptomator.jfuse.api; + +public interface FuseMount { + + void loop(); + + void unmount() ; + + void destroy(); + +} diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java index c433a286..170c4bae 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java @@ -391,7 +391,7 @@ default int fsyncdir(String path, int datasync, FileInfo fi) { * Introduced in version 2.3 * Changed in version 2.6 */ - default void init(FuseConnInfo conn) { + default void init(FuseConnInfo conn) { // TODO: add @Nullable FuseConfig for libfuse3 // no-op } diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseSession.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseSession.java deleted file mode 100644 index aaaf018d..00000000 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseSession.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.cryptomator.jfuse.api; - -import java.lang.foreign.MemoryAddress; -import java.nio.file.Path; - -public record FuseSession(MemoryAddress fuse, MemoryAddress session) { -} diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/UnmountedFuseMount.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/UnmountedFuseMount.java new file mode 100644 index 00000000..a21cf6de --- /dev/null +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/UnmountedFuseMount.java @@ -0,0 +1,18 @@ +package org.cryptomator.jfuse.api; + +class UnmountedFuseMount implements FuseMount { + @Override + public void loop() { + // no-op + } + + @Override + public void unmount() { + // no-op + } + + @Override + public void destroy() { + // no-op + } +} 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 new file mode 100644 index 00000000..fcb7d561 --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseArgs.java @@ -0,0 +1,31 @@ +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 java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; + +public record FuseArgs(MemorySegment args, MemorySegment cmdLineOpts) { + + @Override + public String toString() { + var sb = new StringBuilder(); + var argc = fuse_args.argc$get(args); + var argv = fuse_args.argv$get(args); + for (int i = 0; i < argc; i++) { + var cString = argv.getAtIndex(ValueLayout.ADDRESS, i); + sb.append("arg[").append(i).append("] = ").append(cString.getUtf8String(0)).append(", "); + } + sb.append("mountPoint = ").append(mountPoint().getUtf8String(0)); + sb.append("debug = ").append(fuse_cmdline_opts.debug$get(cmdLineOpts)); + sb.append("singlethreaded = ").append(fuse_cmdline_opts.singlethread$get(cmdLineOpts)); + return sb.toString(); + } + + public MemoryAddress mountPoint() { + return fuse_cmdline_opts.mountpoint$get(cmdLineOpts); + } + +} 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 7a2dcb0c..eb94b008 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 @@ -1,9 +1,8 @@ package org.cryptomator.jfuse.linux.aarch64; import org.cryptomator.jfuse.api.Fuse; -import org.cryptomator.jfuse.api.FuseArgs; +import org.cryptomator.jfuse.api.FuseMount; import org.cryptomator.jfuse.api.FuseOperations; -import org.cryptomator.jfuse.api.FuseSession; 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; @@ -13,113 +12,66 @@ import org.cryptomator.jfuse.linux.aarch64.extr.timespec; import org.jetbrains.annotations.VisibleForTesting; +import java.lang.foreign.Addressable; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; import java.lang.foreign.MemorySession; import java.lang.foreign.ValueLayout; -import java.nio.file.Path; import java.util.List; -import java.util.concurrent.CompletableFuture; public final class FuseImpl extends Fuse { - private final CompletableFuture initialized = new CompletableFuture<>(); private final FuseOperations delegate; private final MemorySegment fuseOps; public FuseImpl(FuseOperations fuseOperations) { this.fuseOps = fuse_operations.allocate(fuseScope); this.delegate = fuseOperations; - fuse_operations.init$set(fuseOps, fuse_operations.init.allocate(this::init, fuseScope).address()); fuseOperations.supportedOperations().forEach(this::bind); } - private MemoryAddress init(MemoryAddress conn, MemoryAddress fuseConfig) { - try (var scope = MemorySession.openConfined()) { - if (delegate.supportedOperations().contains(FuseOperations.Operation.INIT)) { - delegate.init(new FuseConnInfoImpl(conn, scope)); - } - initialized.complete(0); - } catch (Exception e) { - initialized.completeExceptionally(e); - } - return MemoryAddress.NULL; - } - @Override - protected CompletableFuture initialized() { - return initialized; - } - - @Override - protected FuseArgs parseCmdLine(List args, MemorySession scope) { - var fuseArgs = fuse_args.allocate(scope); - var argc = args.size(); - var argv = scope.allocateArray(ValueLayout.ADDRESS, argc + 1); + protected FuseMount mount(List args) { + var fuseArgs = parseArgs(args); + var fuse = fuse_h.fuse_new(fuseArgs.args(), fuseOps, fuseOps.byteSize(), MemoryAddress.NULL); + if (MemoryAddress.NULL.equals(fuse)) { + // TODO use explicit exception type + throw new IllegalArgumentException("fuse_new failed"); + } + //var session = fuse_h.fuse_get_session(fuse); + //var mountPointStr = fuse_cmdline_opts.mountpoint$get(args.opts()); + if (fuse_h.fuse_mount(fuse, fuseArgs.mountPoint()) != 0) { + // TODO use explicit exception type + throw new IllegalArgumentException("fuse_mount failed "); + } + return new FuseMountImpl(fuse, fuseArgs); + } + + private FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { + var args = fuse_args.allocate(fuseScope); + var argc = cmdLineArgs.size(); + var argv = fuseScope.allocateArray(ValueLayout.ADDRESS, argc + 1); for (int i = 0; i < argc; i++) { - var cString = scope.allocateUtf8String(args.get(i)); + var cString = fuseScope.allocateUtf8String(cmdLineArgs.get(i)); argv.setAtIndex(ValueLayout.ADDRESS, i, cString); } argv.setAtIndex(ValueLayout.ADDRESS, argc, MemoryAddress.NULL); - fuse_args.argc$set(fuseArgs, argc); - fuse_args.argv$set(fuseArgs, argv.address()); - fuse_args.allocated$set(fuseArgs, 0); - - var opts = fuse_cmdline_opts.allocate(scope); - fuse_lowlevel_h.fuse_parse_cmdline(fuseArgs.address(), opts.address()); - - System.out.println("args: " + String.join(" ", args)); - { - var parsedArgc = fuse_args.argc$get(fuseArgs); - var parsedArgv = fuse_args.argv$get(fuseArgs); - for (int i = 0; i < parsedArgc; i++) { - var cString = parsedArgv.getAtIndex(ValueLayout.ADDRESS, i).getUtf8String(0); - System.out.println("arg[" + i + "]: " + cString); - } - } - return new FuseArgs(fuseArgs, opts); - } + fuse_args.argc$set(args, argc); + fuse_args.argv$set(args, argv.address()); + fuse_args.allocated$set(args, 0); - @Override - protected FuseSession mount(FuseArgs args, Path mountPoint) { - try (var scope = MemorySession.openConfined()) { - var mountPointStr = scope.allocateUtf8String(mountPoint.toString()); - var fuse = fuse_h.fuse_new(args.args(), fuseOps, fuseOps.byteSize(), MemoryAddress.NULL); - if (MemoryAddress.NULL.equals(fuse)) { - // TODO use explicit exception type - throw new IllegalArgumentException("fuse_new failed"); - } - var session = fuse_h.fuse_get_session(fuse); - //var mountPointStr = fuse_cmdline_opts.mountpoint$get(args.opts()); - if (fuse_h.fuse_mount(fuse, mountPointStr) != 0) { - // TODO any cleanup needed? - // TODO use explicit exception type - throw new IllegalArgumentException("fuse_mount failed for mount point " + mountPoint); - } - return new FuseSession(fuse, session); + var opts = fuse_cmdline_opts.allocate(fuseScope); + int parseResult = fuse_lowlevel_h.fuse_parse_cmdline(args, opts); + if (parseResult != 0) { + throw new IllegalArgumentException("fuse_parse_cmdline failed to parse " + String.join(" ", cmdLineArgs)); } - } - - @Override - protected int loop(FuseSession session, boolean multithreaded) { - // TODO support fuse_loop_mt - return fuse_h.fuse_loop(session.fuse()); - } - - @Override - protected void unmount(FuseSession session) { - fuse_h.fuse_unmount(session.fuse()); - } - - @Override - protected void destroy(FuseSession session) { - fuse_h.fuse_destroy(session.fuse()); + return new FuseArgs(args, opts); } private void bind(FuseOperations.Operation operation) { switch (operation) { - case INIT -> { /* handled already */ } + case INIT -> fuse_operations.access$set(fuseOps, fuse_operations.init.allocate(this::init, fuseScope).address()); case ACCESS -> fuse_operations.access$set(fuseOps, fuse_operations.access.allocate(this::access, fuseScope).address()); case CHMOD -> fuse_operations.chmod$set(fuseOps, fuse_operations.chmod.allocate(this::chmod, fuseScope).address()); case CREATE -> fuse_operations.create$set(fuseOps, fuse_operations.create.allocate(this::create, fuseScope).address()); @@ -144,6 +96,13 @@ private void bind(FuseOperations.Operation operation) { } } + private Addressable init(MemoryAddress conn, MemoryAddress fuseConfig) { + try (var scope = MemorySession.openConfined()) { + delegate.init(new FuseConnInfoImpl(conn, scope)); + } + return MemoryAddress.NULL; + } + private int access(MemoryAddress path, int mask) { return delegate.access(path.getUtf8String(0), mask); } 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 new file mode 100644 index 00000000..2e451b5c --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseMountImpl.java @@ -0,0 +1,26 @@ +package org.cryptomator.jfuse.linux.aarch64; + +import org.cryptomator.jfuse.api.FuseMount; +import org.cryptomator.jfuse.linux.aarch64.extr.fuse_h; + +import java.lang.foreign.MemoryAddress; + +record FuseMountImpl(MemoryAddress fuse, FuseArgs fuseArgs) implements FuseMount { + @Override + public void loop() { + // TODO support fuse_loop_mt if args.multiThreaded() + fuse_h.fuse_loop(fuse); + System.out.println("fuse_loop finished"); // TODO remove + } + + @Override + public void unmount() { + fuse_h.fuse_exit(fuse); + fuse_h.fuse_unmount(fuse); + } + + @Override + public void destroy() { + fuse_h.fuse_destroy(fuse); + } +} 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 new file mode 100644 index 00000000..097c92e7 --- /dev/null +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseArgs.java @@ -0,0 +1,31 @@ +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 java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; + +public record FuseArgs(MemorySegment args, MemorySegment cmdLineOpts) { + + @Override + public String toString() { + var sb = new StringBuilder(); + var argc = fuse_args.argc$get(args); + var argv = fuse_args.argv$get(args); + for (int i = 0; i < argc; i++) { + var cString = argv.getAtIndex(ValueLayout.ADDRESS, i); + sb.append("arg[").append(i).append("] = ").append(cString.getUtf8String(0)).append(", "); + } + sb.append("mountPoint = ").append(mountPoint().getUtf8String(0)); + sb.append("debug = ").append(fuse_cmdline_opts.debug$get(cmdLineOpts)); + sb.append("singlethreaded = ").append(fuse_cmdline_opts.singlethread$get(cmdLineOpts)); + return sb.toString(); + } + + public MemoryAddress mountPoint() { + return fuse_cmdline_opts.mountpoint$get(cmdLineOpts); + } + +} 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 c0f5febe..ad5bccf5 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 @@ -1,9 +1,8 @@ package org.cryptomator.jfuse.linux.amd64; import org.cryptomator.jfuse.api.Fuse; -import org.cryptomator.jfuse.api.FuseArgs; +import org.cryptomator.jfuse.api.FuseMount; import org.cryptomator.jfuse.api.FuseOperations; -import org.cryptomator.jfuse.api.FuseSession; 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; @@ -13,113 +12,66 @@ import org.cryptomator.jfuse.linux.amd64.extr.timespec; import org.jetbrains.annotations.VisibleForTesting; +import java.lang.foreign.Addressable; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; import java.lang.foreign.MemorySession; import java.lang.foreign.ValueLayout; -import java.nio.file.Path; import java.util.List; -import java.util.concurrent.CompletableFuture; public final class FuseImpl extends Fuse { - private final CompletableFuture initialized = new CompletableFuture<>(); private final FuseOperations delegate; private final MemorySegment fuseOps; public FuseImpl(FuseOperations fuseOperations) { this.fuseOps = fuse_operations.allocate(fuseScope); this.delegate = fuseOperations; - fuse_operations.init$set(fuseOps, fuse_operations.init.allocate(this::init, fuseScope).address()); fuseOperations.supportedOperations().forEach(this::bind); } - private MemoryAddress init(MemoryAddress conn, MemoryAddress fuseConfig) { - try (var scope = MemorySession.openConfined()) { - if (delegate.supportedOperations().contains(FuseOperations.Operation.INIT)) { - delegate.init(new FuseConnInfoImpl(conn, scope)); - } - initialized.complete(0); - } catch (Exception e) { - initialized.completeExceptionally(e); - } - return MemoryAddress.NULL; - } - @Override - protected CompletableFuture initialized() { - return initialized; - } - - @Override - protected FuseArgs parseCmdLine(List args, MemorySession scope) { - var fuseArgs = fuse_args.allocate(scope); - var argc = args.size(); - var argv = scope.allocateArray(ValueLayout.ADDRESS, argc + 1); + protected FuseMount mount(List args) { + var fuseArgs = parseArgs(args); + var fuse = fuse_h.fuse_new(fuseArgs.args(), fuseOps, fuseOps.byteSize(), MemoryAddress.NULL); + if (MemoryAddress.NULL.equals(fuse)) { + // TODO use explicit exception type + throw new IllegalArgumentException("fuse_new failed"); + } + //var session = fuse_h.fuse_get_session(fuse); + //var mountPointStr = fuse_cmdline_opts.mountpoint$get(args.opts()); + if (fuse_h.fuse_mount(fuse, fuseArgs.mountPoint()) != 0) { + // TODO use explicit exception type + throw new IllegalArgumentException("fuse_mount failed "); + } + return new FuseMountImpl(fuse, fuseArgs); + } + + private FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { + var args = fuse_args.allocate(fuseScope); + var argc = cmdLineArgs.size(); + var argv = fuseScope.allocateArray(ValueLayout.ADDRESS, argc + 1); for (int i = 0; i < argc; i++) { - var cString = scope.allocateUtf8String(args.get(i)); + var cString = fuseScope.allocateUtf8String(cmdLineArgs.get(i)); argv.setAtIndex(ValueLayout.ADDRESS, i, cString); } argv.setAtIndex(ValueLayout.ADDRESS, argc, MemoryAddress.NULL); - fuse_args.argc$set(fuseArgs, argc); - fuse_args.argv$set(fuseArgs, argv.address()); - fuse_args.allocated$set(fuseArgs, 0); - - var opts = fuse_cmdline_opts.allocate(scope); - fuse_lowlevel_h.fuse_parse_cmdline(fuseArgs.address(), opts.address()); - - System.out.println("args: " + String.join(" ", args)); - { - var parsedArgc = fuse_args.argc$get(fuseArgs); - var parsedArgv = fuse_args.argv$get(fuseArgs); - for (int i = 0; i < parsedArgc; i++) { - var cString = parsedArgv.getAtIndex(ValueLayout.ADDRESS, i).getUtf8String(0); - System.out.println("arg[" + i + "]: " + cString); - } - } - return new FuseArgs(fuseArgs, opts); - } + fuse_args.argc$set(args, argc); + fuse_args.argv$set(args, argv.address()); + fuse_args.allocated$set(args, 0); - @Override - protected FuseSession mount(FuseArgs args, Path mountPoint) { - try (var scope = MemorySession.openConfined()) { - var mountPointStr = scope.allocateUtf8String(mountPoint.toString()); - var fuse = fuse_h.fuse_new(args.args(), fuseOps, fuseOps.byteSize(), MemoryAddress.NULL); - if (MemoryAddress.NULL.equals(fuse)) { - // TODO use explicit exception type - throw new IllegalArgumentException("fuse_new failed"); - } - var session = fuse_h.fuse_get_session(fuse); - //var mountPointStr = fuse_cmdline_opts.mountpoint$get(args.opts()); - if (fuse_h.fuse_mount(fuse, mountPointStr) != 0) { - // TODO any cleanup needed? - // TODO use explicit exception type - throw new IllegalArgumentException("fuse_mount failed for mount point " + mountPoint); - } - return new FuseSession(fuse, session); + var opts = fuse_cmdline_opts.allocate(fuseScope); + int parseResult = fuse_lowlevel_h.fuse_parse_cmdline(args, opts); + if (parseResult != 0) { + throw new IllegalArgumentException("fuse_parse_cmdline failed to parse " + String.join(" ", cmdLineArgs)); } - } - - @Override - protected int loop(FuseSession session, boolean multithreaded) { - // TODO support fuse_loop_mt - return fuse_h.fuse_loop(session.fuse()); - } - - @Override - protected void unmount(FuseSession session) { - fuse_h.fuse_unmount(session.fuse()); - } - - @Override - protected void destroy(FuseSession session) { - fuse_h.fuse_destroy(session.fuse()); + return new FuseArgs(args, opts); } private void bind(FuseOperations.Operation operation) { switch (operation) { - case INIT -> { /* handled already */ } + case INIT -> fuse_operations.access$set(fuseOps, fuse_operations.init.allocate(this::init, fuseScope).address()); case ACCESS -> fuse_operations.access$set(fuseOps, fuse_operations.access.allocate(this::access, fuseScope).address()); case CHMOD -> fuse_operations.chmod$set(fuseOps, fuse_operations.chmod.allocate(this::chmod, fuseScope).address()); case CREATE -> fuse_operations.create$set(fuseOps, fuse_operations.create.allocate(this::create, fuseScope).address()); @@ -144,6 +96,13 @@ private void bind(FuseOperations.Operation operation) { } } + private Addressable init(MemoryAddress conn, MemoryAddress fuseConfig) { + try (var scope = MemorySession.openConfined()) { + delegate.init(new FuseConnInfoImpl(conn, scope)); + } + return MemoryAddress.NULL; + } + private int access(MemoryAddress path, int mask) { return delegate.access(path.getUtf8String(0), mask); } 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 new file mode 100644 index 00000000..c72fc0ea --- /dev/null +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseMountImpl.java @@ -0,0 +1,26 @@ +package org.cryptomator.jfuse.linux.amd64; + +import org.cryptomator.jfuse.api.FuseMount; +import org.cryptomator.jfuse.linux.amd64.extr.fuse_h; + +import java.lang.foreign.MemoryAddress; + +record FuseMountImpl(MemoryAddress fuse, FuseArgs fuseArgs) implements FuseMount { + @Override + public void loop() { + // TODO support fuse_loop_mt if args.multiThreaded() + fuse_h.fuse_loop(fuse); + System.out.println("fuse_loop finished"); // TODO remove + } + + @Override + public void unmount() { + fuse_h.fuse_exit(fuse); + fuse_h.fuse_unmount(fuse); + } + + @Override + public void destroy() { + fuse_h.fuse_destroy(fuse); + } +} diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseArgs.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseArgs.java new file mode 100644 index 00000000..1690e3f3 --- /dev/null +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseArgs.java @@ -0,0 +1,24 @@ +package org.cryptomator.jfuse.mac; + +import org.cryptomator.jfuse.mac.extr.fuse_args; + +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; + +public record FuseArgs(MemorySegment args, MemoryAddress mountPoint, boolean multiThreaded) { + + @Override + public String toString() { + var sb = new StringBuilder(); + var argc = fuse_args.argc$get(args); + var argv = fuse_args.argv$get(args); + for (int i = 0; i < argc; i++) { + var cString = argv.getAtIndex(ValueLayout.ADDRESS, i); + sb.append("arg[").append(i).append("] = ").append(cString.getUtf8String(0)).append(", "); + } + sb.append("mountPoint = ").append(mountPoint.getUtf8String(0)).append(", "); + sb.append("multiThreaded = ").append(multiThreaded); + return sb.toString(); + } +} diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java index 750ec5eb..a6751fbb 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java @@ -1,9 +1,8 @@ package org.cryptomator.jfuse.mac; import org.cryptomator.jfuse.api.Fuse; -import org.cryptomator.jfuse.api.FuseArgs; +import org.cryptomator.jfuse.api.FuseMount; import org.cryptomator.jfuse.api.FuseOperations; -import org.cryptomator.jfuse.api.FuseSession; import org.cryptomator.jfuse.mac.extr.fuse_args; import org.cryptomator.jfuse.mac.extr.fuse_h; import org.cryptomator.jfuse.mac.extr.fuse_operations; @@ -11,117 +10,73 @@ import org.cryptomator.jfuse.mac.extr.timespec; import org.jetbrains.annotations.VisibleForTesting; +import java.lang.foreign.Addressable; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; import java.lang.foreign.MemorySession; import java.lang.foreign.ValueLayout; -import java.nio.file.Path; import java.util.List; -import java.util.concurrent.CompletableFuture; import static java.lang.foreign.ValueLayout.JAVA_INT; public final class FuseImpl extends Fuse { - private final CompletableFuture initialized = new CompletableFuture<>(); private final FuseOperations delegate; private final MemorySegment fuseOps; public FuseImpl(FuseOperations fuseOperations) { this.fuseOps = fuse_operations.allocate(fuseScope); this.delegate = fuseOperations; - fuse_operations.init$set(fuseOps, fuse_operations.init.allocate(this::init, fuseScope).address()); fuseOperations.supportedOperations().forEach(this::bind); } - private MemoryAddress init(MemoryAddress conn) { - try (var scope = MemorySession.openConfined()) { - if (delegate.supportedOperations().contains(FuseOperations.Operation.INIT)) { - delegate.init(new FuseConnInfoImpl(conn, scope)); - } - initialized.complete(0); - } catch (Exception e) { - initialized.completeExceptionally(e); - } - return MemoryAddress.NULL; - } - - @Override - protected CompletableFuture initialized() { - return initialized; - } - @Override - protected FuseArgs parseCmdLine(List args, MemorySession scope) { - var multithreaded = scope.allocate(JAVA_INT, 1); - var foreground = scope.allocate(JAVA_INT, 1); - var fuseArgs = fuse_args.allocate(scope); - var argc = args.size(); - var argv = scope.allocateArray(ValueLayout.ADDRESS, argc); + protected FuseMount mount(List args) { + var fuseArgs = parseArgs(args); + var ch = fuse_h.fuse_mount(fuseArgs.mountPoint(), fuseArgs.args()); + if (MemoryAddress.NULL.equals(ch)) { + // TODO any cleanup needed? + // TODO use explicit exception type + throw new IllegalArgumentException("fuse_mount failed"); + } + var fuse = fuse_h.fuse_new(ch, fuseArgs.args(), fuseOps, fuseOps.byteSize(), MemoryAddress.NULL); + if (MemoryAddress.NULL.equals(fuse)) { + fuse_h.fuse_unmount(fuseArgs.mountPoint(), ch); + // TODO use explicit exception type + throw new IllegalArgumentException("fuse_new failed"); + } + return new FuseMountImpl(fuse, ch, fuseArgs); + } + + private FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { + var args = fuse_args.allocate(fuseScope); + var argc = cmdLineArgs.size(); + var argv = fuseScope.allocateArray(ValueLayout.ADDRESS, argc + 1); for (int i = 0; i < argc; i++) { - var cString = scope.allocateUtf8String(args.get(i)); + var cString = fuseScope.allocateUtf8String(cmdLineArgs.get(i)); argv.setAtIndex(ValueLayout.ADDRESS, i, cString); } - fuse_args.argc$set(fuseArgs, argc); - fuse_args.argv$set(fuseArgs, argv.address()); - fuse_args.allocated$set(fuseArgs, 0); - var mountPointPtr = scope.allocate(ValueLayout.ADDRESS); - int parseResult = fuse_h.fuse_parse_cmdline(fuseArgs, mountPointPtr, multithreaded, foreground); + argv.setAtIndex(ValueLayout.ADDRESS, argc, MemoryAddress.NULL); + fuse_args.argc$set(args, argc); + fuse_args.argv$set(args, argv.address()); + fuse_args.allocated$set(args, 0); + + var multithreaded = fuseScope.allocate(JAVA_INT, 1); + var foreground = fuseScope.allocate(JAVA_INT, 1); + var mountPointPtr = fuseScope.allocate(ValueLayout.ADDRESS); + int parseResult = fuse_h.fuse_parse_cmdline(args, mountPointPtr, multithreaded, foreground); if (parseResult != 0) { - throw new IllegalArgumentException("fuse_parse_cmdline failed to parse " + String.join(" ", args)); + throw new IllegalArgumentException("fuse_parse_cmdline failed to parse " + String.join(" ", cmdLineArgs)); } - var mountPoint = mountPointPtr.get(ValueLayout.ADDRESS, 0).getUtf8String(0); var isMultiThreaded = multithreaded.get(JAVA_INT, 0) == 1; - var isForeground = foreground.get(JAVA_INT, 0) == 1; - return new FuseArgs(fuseArgs, isMultiThreaded, isForeground); - } - - @Override - protected FuseSession mount(FuseArgs args, Path mountPoint) { - try (var scope = MemorySession.openConfined()) { - var mountPointStr = scope.allocateUtf8String(mountPoint.toString()); - var ch = fuse_h.fuse_mount(mountPointStr, args.args()); - if (MemoryAddress.NULL.equals(ch)) { - // TODO any cleanup needed? - // TODO use explicit exception type - throw new IllegalArgumentException("Failed to mount to " + mountPoint + " with given args."); - } - var fuse = fuse_h.fuse_new(ch, args.args(), fuseOps, fuseOps.byteSize(), MemoryAddress.NULL); - if (MemoryAddress.NULL.equals(fuse)) { - fuse_h.fuse_unmount(mountPointStr, ch); - // TODO use explicit exception type - throw new IllegalArgumentException("fuse_new failed"); - } - return new FuseSession(mountPoint, ch, fuse); - } - } - - @Override - protected int loop(FuseSession session, boolean multithreaded) { - // TODO support fuse_loop_mt - return fuse_h.fuse_loop(session.fuse()); - } - - @Override - protected void unmount(FuseSession session) { - try (var scope = MemorySession.openConfined()) { - var mountPointStr = scope.allocateUtf8String(session.mountPoint().toString()); - //var s = fuse_h.fuse_get_session(session.fuse()); - //fuse_lowlevel_h.fuse_session_exit(s); - fuse_h.fuse_exit(session.fuse()); - fuse_h.fuse_unmount(mountPointStr, session.ch()); - } - } - - @Override - protected void destroy(FuseSession session) { - fuse_h.fuse_destroy(session.fuse()); + var mountPoint = mountPointPtr.get(ValueLayout.ADDRESS, 0); + return new FuseArgs(args, mountPoint, isMultiThreaded); } private void bind(FuseOperations.Operation operation) { switch (operation) { - case INIT -> { /* handled already */ } + case INIT -> fuse_operations.access$set(fuseOps, fuse_operations.init.allocate(this::init, fuseScope).address()); case ACCESS -> fuse_operations.access$set(fuseOps, fuse_operations.access.allocate(this::access, fuseScope).address()); case CHMOD -> fuse_operations.chmod$set(fuseOps, fuse_operations.chmod.allocate(this::chmod, fuseScope).address()); case CREATE -> fuse_operations.create$set(fuseOps, fuse_operations.create.allocate(this::create, fuseScope).address()); @@ -146,6 +101,13 @@ private void bind(FuseOperations.Operation operation) { } } + private Addressable init(MemoryAddress conn) { + try (var scope = MemorySession.openConfined()) { + delegate.init(new FuseConnInfoImpl(conn, scope)); + } + return MemoryAddress.NULL; + } + private int access(MemoryAddress path, int mask) { return delegate.access(path.getUtf8String(0), mask); } diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseMountImpl.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseMountImpl.java new file mode 100644 index 00000000..91f632ee --- /dev/null +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseMountImpl.java @@ -0,0 +1,25 @@ +package org.cryptomator.jfuse.mac; + +import org.cryptomator.jfuse.api.FuseMount; +import org.cryptomator.jfuse.mac.extr.fuse_h; + +import java.lang.foreign.MemoryAddress; + +record FuseMountImpl(MemoryAddress fuse, MemoryAddress ch, FuseArgs args) implements FuseMount { + + public void loop() { + // TODO support fuse_loop_mt if args.multiThreaded() + fuse_h.fuse_loop(fuse); + System.out.println("fuse_loop finished"); // TODO remove + } + + public void unmount() { + fuse_h.fuse_exit(fuse); + fuse_h.fuse_unmount(args.mountPoint(), ch); + } + + public void destroy() { + fuse_h.fuse_destroy(fuse); + } + +} 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 d390fc5a..a2e570fa 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 @@ -1,6 +1,7 @@ package org.cryptomator.jfuse.win.amd64; import org.cryptomator.jfuse.api.Fuse; +import org.cryptomator.jfuse.api.FuseMount; import org.cryptomator.jfuse.api.FuseOperations; import org.cryptomator.jfuse.win.amd64.extr.fuse_context; import org.cryptomator.jfuse.win.amd64.extr.fuse_h; @@ -12,11 +13,17 @@ import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; import java.lang.foreign.MemorySession; +import java.lang.foreign.ValueLayout; import java.nio.file.Path; +import java.util.List; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicReference; +import static java.lang.foreign.ValueLayout.JAVA_INT; + public final class FuseImpl extends Fuse { private final CompletableFuture initialized = new CompletableFuture<>(); @@ -60,21 +67,36 @@ public int mount(String progName, Path mountPoint, String... flags) throws Timeo } @Override - protected CompletableFuture initialized() { - return initialized; - } - - @Override - protected int fuseMain(int argc, MemorySegment argv) { - return fuse_h.fuse_main_real(argc, argv, struct, struct.byteSize(), MemoryAddress.NULL); - } - - //TODO: subject to change - private void fuseExit() { - var actualHandle = fuseHandle.getAndSet(null); - if (actualHandle != null) { - fuse_h.fuse_exit(actualHandle); + protected FuseMount mount(List args) { + var argc = args.size(); + var argv = fuseScope.allocateArray(ValueLayout.ADDRESS, argc); + for (int i = 0; i < argc; i++) { + var cString = fuseScope.allocateUtf8String(args.get(i)); + argv.setAtIndex(ValueLayout.ADDRESS, i, cString); + } + + try { + var mountResult = CompletableFuture.supplyAsync(() -> fuse_h.fuse_main_real(argc, argv, struct, struct.byteSize(), MemoryAddress.NULL)); + var result = CompletableFuture.anyOf(mountResult, initialized).get(10, TimeUnit.SECONDS); + if (result instanceof Integer i) { + if (i != 0) { + // TODO use explicit exception type + throw new IllegalArgumentException("fuse_main_real returned with exit code " + i); + } else { + // good + } + } else { + throw new IllegalStateException("Expected result to be an Integer"); + } + } catch (ExecutionException | TimeoutException e) { + // TODO use explicit exception type + throw new IllegalArgumentException("failed to mount"); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new IllegalArgumentException("mounting interrupted"); } + + return new FuseMountImpl(fuseHandle); } private void bind(FuseOperations.Operation operation) { @@ -229,11 +251,4 @@ private int write(MemoryAddress path, MemoryAddress buf, long size, long offset, } } - //TODO: subject to change - @Override - public void close() throws TimeoutException { - fuseExit(); - super.close(); - } - } 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 new file mode 100644 index 00000000..fa94117f --- /dev/null +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseMountImpl.java @@ -0,0 +1,27 @@ +package org.cryptomator.jfuse.win.amd64; + +import org.cryptomator.jfuse.api.FuseMount; +import org.cryptomator.jfuse.win.amd64.extr.fuse_h; + +import java.lang.foreign.MemoryAddress; +import java.util.concurrent.atomic.AtomicReference; + +record FuseMountImpl(AtomicReference fuseHandle) implements FuseMount { + @Override + public void loop() { + // no-op + } + + @Override + public void unmount() { + var actualHandle = fuseHandle.getAndSet(null); + if (actualHandle != null) { + fuse_h.fuse_exit(actualHandle); + } + } + + @Override + public void destroy() { + // no-op + } +} From b065fc574ab8881a2de31c099e735c34434c3ffc Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Fri, 2 Sep 2022 16:32:38 +0200 Subject: [PATCH 25/98] replace call to fuse_main_real by high level fuse_new part for windows --- jfuse-win-amd64/pom.xml | 24 ++--- .../cryptomator/jfuse/win/amd64/FuseArgs.java | 24 +++++ .../cryptomator/jfuse/win/amd64/FuseImpl.java | 95 +++++++++---------- .../jfuse/win/amd64/FuseMountImpl.java | 22 ++--- .../jfuse/win/amd64/extr/constants$0.java | 38 +++++--- .../jfuse/win/amd64/extr/constants$1.java | 51 ++++++++++ .../jfuse/win/amd64/extr/fuse_args.java | 78 +++++++++++++++ .../jfuse/win/amd64/extr/fuse_h.java | 70 +++++++++++++- .../jfuse/win/amd64/extr/fuse_operations.java | 53 ++++++----- .../jfuse/win/amd64/extr/winfsp_fuse_h.java | 23 ----- 10 files changed, 340 insertions(+), 138 deletions(-) create mode 100644 jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseArgs.java create mode 100644 jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$1.java create mode 100644 jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_args.java delete mode 100644 jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/winfsp_fuse_h.java diff --git a/jfuse-win-amd64/pom.xml b/jfuse-win-amd64/pom.xml index b0906abe..5ea9ed7c 100644 --- a/jfuse-win-amd64/pom.xml +++ b/jfuse-win-amd64/pom.xml @@ -76,7 +76,7 @@ jextract-maven-plugin 0.2.0 - C:\Program Files\JDK\jextract-19\bin\jextract.bat + C:\Users\Arbeit\Programs\jextract-19\bin\jextract.bat ${win.ucrtHeaderPath} ${project.build.sourceDirectory} org.cryptomator.jfuse.win.amd64.extr @@ -94,6 +94,13 @@ fuse_main_real fuse_get_context fuse_exit + + fuse_parse_cmdline + fuse_mount + fuse_new + fuse_loop + fuse_unmount + fuse_destroy fuse_fill_dir_t @@ -102,22 +109,11 @@ fuse_operations fuse_file_info fuse_context - fuse_conn_info - - - - - jextract-winfsp-fuse - - sources - - - ${project.parent.basedir}/winfsp/inc/fuse/winfsp_fuse.h - winfsp_fuse_h - fuse_stat fuse_statvfs fuse_timespec + fuse_conn_info + fuse_args diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseArgs.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseArgs.java new file mode 100644 index 00000000..2b26b5e3 --- /dev/null +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseArgs.java @@ -0,0 +1,24 @@ +package org.cryptomator.jfuse.win.amd64; + +import org.cryptomator.jfuse.win.amd64.extr.fuse_args; + +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; + +public record FuseArgs(MemorySegment args, MemoryAddress mountPoint, boolean multiThreaded) { + + @Override + public String toString() { + var sb = new StringBuilder(); + var argc = fuse_args.argc$get(args); + var argv = fuse_args.argv$get(args); + for (int i = 0; i < argc; i++) { + var cString = argv.getAtIndex(ValueLayout.ADDRESS, i); + sb.append("arg[").append(i).append("] = ").append(cString.getUtf8String(0)).append(", "); + } + sb.append("mountPoint = ").append(mountPoint.getUtf8String(0)).append(", "); + sb.append("multiThreaded = ").append(multiThreaded); + return sb.toString(); + } +} \ No newline at end of file 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 a2e570fa..422cee34 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 @@ -3,12 +3,13 @@ import org.cryptomator.jfuse.api.Fuse; import org.cryptomator.jfuse.api.FuseMount; import org.cryptomator.jfuse.api.FuseOperations; -import org.cryptomator.jfuse.win.amd64.extr.fuse_context; +import org.cryptomator.jfuse.win.amd64.extr.fuse_args; import org.cryptomator.jfuse.win.amd64.extr.fuse_h; import org.cryptomator.jfuse.win.amd64.extr.fuse_operations; import org.cryptomator.jfuse.win.amd64.extr.fuse_timespec; import org.jetbrains.annotations.VisibleForTesting; +import java.lang.foreign.Addressable; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; @@ -16,44 +17,19 @@ import java.lang.foreign.ValueLayout; import java.nio.file.Path; import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicReference; import static java.lang.foreign.ValueLayout.JAVA_INT; public final class FuseImpl extends Fuse { - private final CompletableFuture initialized = new CompletableFuture<>(); private final FuseOperations delegate; private final MemorySegment struct; - private final AtomicReference fuseHandle; - public FuseImpl(FuseOperations fuseOperations) { this.struct = fuse_operations.allocate(fuseScope); this.delegate = fuseOperations; - fuse_operations.init$set(struct, fuse_operations.init.allocate(this::init, fuseScope).address()); fuseOperations.supportedOperations().forEach(this::bind); - fuseHandle = new AtomicReference<>(); - } - - private MemoryAddress init(MemoryAddress conn) { - try (var scope = MemorySession.openConfined()) { - if (delegate.supportedOperations().contains(FuseOperations.Operation.INIT)) { - delegate.init(new FuseConnInfoImpl(conn, scope)); - } - //store fuse handle to be used in fuse_exit() - var ctx = fuse_context.ofAddress(fuse_h.fuse_get_context(), scope); - this.fuseHandle.set(fuse_context.fuse$get(ctx)); - - initialized.complete(0); - } catch (Exception e) { - initialized.completeExceptionally(e); - } - return MemoryAddress.NULL; } @Override @@ -68,40 +44,50 @@ public int mount(String progName, Path mountPoint, String... flags) throws Timeo @Override protected FuseMount mount(List args) { - var argc = args.size(); - var argv = fuseScope.allocateArray(ValueLayout.ADDRESS, argc); + var fuseArgs = parseArgs(args); + var ch = fuse_h.fuse_mount(fuseArgs.mountPoint(), fuseArgs.args()); + if (MemoryAddress.NULL.equals(ch)) { + // TODO any cleanup needed? + // TODO use explicit exception type + throw new IllegalArgumentException("fuse_mount failed"); + } + var fuse = fuse_h.fuse_new(ch, fuseArgs.args(), struct, struct.byteSize(), MemoryAddress.NULL); + if (MemoryAddress.NULL.equals(fuse)) { + fuse_h.fuse_unmount(fuseArgs.mountPoint(), ch); + // TODO use explicit exception type + throw new IllegalArgumentException("fuse_new failed"); + } + return new FuseMountImpl(fuse, ch, fuseArgs); + } + + private FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { + var args = fuse_args.allocate(fuseScope); + var argc = cmdLineArgs.size(); + var argv = fuseScope.allocateArray(ValueLayout.ADDRESS, argc + 1); for (int i = 0; i < argc; i++) { - var cString = fuseScope.allocateUtf8String(args.get(i)); + var cString = fuseScope.allocateUtf8String(cmdLineArgs.get(i)); argv.setAtIndex(ValueLayout.ADDRESS, i, cString); } + argv.setAtIndex(ValueLayout.ADDRESS, argc, MemoryAddress.NULL); + fuse_args.argc$set(args, argc); + fuse_args.argv$set(args, argv.address()); + fuse_args.allocated$set(args, 0); - try { - var mountResult = CompletableFuture.supplyAsync(() -> fuse_h.fuse_main_real(argc, argv, struct, struct.byteSize(), MemoryAddress.NULL)); - var result = CompletableFuture.anyOf(mountResult, initialized).get(10, TimeUnit.SECONDS); - if (result instanceof Integer i) { - if (i != 0) { - // TODO use explicit exception type - throw new IllegalArgumentException("fuse_main_real returned with exit code " + i); - } else { - // good - } - } else { - throw new IllegalStateException("Expected result to be an Integer"); - } - } catch (ExecutionException | TimeoutException e) { - // TODO use explicit exception type - throw new IllegalArgumentException("failed to mount"); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new IllegalArgumentException("mounting interrupted"); + var multithreaded = fuseScope.allocate(JAVA_INT, 1); + var foreground = fuseScope.allocate(JAVA_INT, 1); + var mountPointPtr = fuseScope.allocate(ValueLayout.ADDRESS); + int parseResult = fuse_h.fuse_parse_cmdline(args, mountPointPtr, multithreaded, foreground); + if (parseResult != 0) { + throw new IllegalArgumentException("fuse_parse_cmdline failed to parse " + String.join(" ", cmdLineArgs)); } - - return new FuseMountImpl(fuseHandle); + var isMultiThreaded = multithreaded.get(JAVA_INT, 0) == 1; + var mountPoint = mountPointPtr.get(ValueLayout.ADDRESS, 0); + return new FuseArgs(args, mountPoint, isMultiThreaded); } private void bind(FuseOperations.Operation operation) { switch (operation) { - case INIT -> { /* handled already */ } + case INIT -> fuse_operations.access$set(struct, fuse_operations.init.allocate(this::init, fuseScope).address()); case ACCESS -> fuse_operations.access$set(struct, fuse_operations.access.allocate(this::access, fuseScope).address()); case CHMOD -> fuse_operations.chmod$set(struct, fuse_operations.chmod.allocate(this::chmod, fuseScope).address()); case CREATE -> fuse_operations.create$set(struct, fuse_operations.create.allocate(this::create, fuseScope).address()); @@ -126,6 +112,13 @@ private void bind(FuseOperations.Operation operation) { } } + private Addressable init(MemoryAddress conn) { + try (var scope = MemorySession.openConfined()) { + delegate.init(new FuseConnInfoImpl(conn, scope)); + } + return MemoryAddress.NULL; + } + private int access(MemoryAddress path, int mask) { return delegate.access(path.getUtf8String(0), mask); } 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 fa94117f..3417d8c3 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 @@ -4,24 +4,22 @@ import org.cryptomator.jfuse.win.amd64.extr.fuse_h; import java.lang.foreign.MemoryAddress; -import java.util.concurrent.atomic.AtomicReference; -record FuseMountImpl(AtomicReference fuseHandle) implements FuseMount { - @Override +record FuseMountImpl(MemoryAddress fuse, MemoryAddress ch, FuseArgs args) implements FuseMount { + public void loop() { - // no-op + // TODO support fuse_loop_mt if args.multiThreaded() + fuse_h.fuse_loop(fuse); + System.out.println("fuse_loop finished"); // TODO remove } - @Override public void unmount() { - var actualHandle = fuseHandle.getAndSet(null); - if (actualHandle != null) { - fuse_h.fuse_exit(actualHandle); - } + fuse_h.fuse_exit(fuse); + fuse_h.fuse_unmount(args.mountPoint(), ch); } - @Override public void destroy() { - // no-op + fuse_h.fuse_destroy(fuse); } -} + +} \ No newline at end of file diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$0.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$0.java index 48156317..9f4d5bad 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$0.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$0.java @@ -9,6 +9,32 @@ import static java.lang.foreign.ValueLayout.*; class constants$0 { + static final FunctionDescriptor fuse_mount$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_mount$MH = RuntimeHelper.downcallHandle( + "fuse_mount", + constants$0.fuse_mount$FUNC + ); + static final FunctionDescriptor fuse_unmount$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_unmount$MH = RuntimeHelper.downcallHandle( + "fuse_unmount", + constants$0.fuse_unmount$FUNC + ); + static final FunctionDescriptor fuse_parse_cmdline$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$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 FunctionDescriptor fuse_fill_dir_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, @@ -29,18 +55,6 @@ class constants$0 { "fuse_main_real", constants$0.fuse_main_real$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$0.fuse_exit$FUNC - ); - static final FunctionDescriptor fuse_get_context$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT); - static final MethodHandle fuse_get_context$MH = RuntimeHelper.downcallHandle( - "fuse_get_context", - constants$0.fuse_get_context$FUNC - ); } 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 new file mode 100644 index 00000000..779718c2 --- /dev/null +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$1.java @@ -0,0 +1,51 @@ +// 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.*; +class constants$1 { + + 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_POINTER$LAYOUT, + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_new$MH = RuntimeHelper.downcallHandle( + "fuse_new", + constants$1.fuse_new$FUNC + ); + static final FunctionDescriptor fuse_destroy$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_destroy$MH = RuntimeHelper.downcallHandle( + "fuse_destroy", + constants$1.fuse_destroy$FUNC + ); + static final FunctionDescriptor fuse_loop$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_loop$MH = RuntimeHelper.downcallHandle( + "fuse_loop", + constants$1.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$1.fuse_exit$FUNC + ); + static final FunctionDescriptor fuse_get_context$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT); + static final MethodHandle fuse_get_context$MH = RuntimeHelper.downcallHandle( + "fuse_get_context", + constants$1.fuse_get_context$FUNC + ); +} + + diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_args.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_args.java new file mode 100644 index 00000000..a7103250 --- /dev/null +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_args.java @@ -0,0 +1,78 @@ +// 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 fuse_args { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("argc"), + MemoryLayout.paddingLayout(32), + Constants$root.C_POINTER$LAYOUT.withName("argv"), + Constants$root.C_LONG$LAYOUT.withName("allocated"), + MemoryLayout.paddingLayout(32) + ).withName("fuse_args"); + public static MemoryLayout $LAYOUT() { + return fuse_args.$struct$LAYOUT; + } + static final VarHandle argc$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("argc")); + public static VarHandle argc$VH() { + return fuse_args.argc$VH; + } + public static int argc$get(MemorySegment seg) { + return (int)fuse_args.argc$VH.get(seg); + } + public static void argc$set( MemorySegment seg, int x) { + fuse_args.argc$VH.set(seg, x); + } + public static int argc$get(MemorySegment seg, long index) { + return (int)fuse_args.argc$VH.get(seg.asSlice(index*sizeof())); + } + public static void argc$set(MemorySegment seg, long index, int x) { + fuse_args.argc$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle argv$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("argv")); + public static VarHandle argv$VH() { + return fuse_args.argv$VH; + } + public static MemoryAddress argv$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_args.argv$VH.get(seg); + } + public static void argv$set( MemorySegment seg, MemoryAddress x) { + fuse_args.argv$VH.set(seg, x); + } + public static MemoryAddress argv$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_args.argv$VH.get(seg.asSlice(index*sizeof())); + } + public static void argv$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_args.argv$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle allocated$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("allocated")); + public static VarHandle allocated$VH() { + return fuse_args.allocated$VH; + } + public static int allocated$get(MemorySegment seg) { + return (int)fuse_args.allocated$VH.get(seg); + } + public static void allocated$set( MemorySegment seg, int x) { + fuse_args.allocated$VH.set(seg, x); + } + public static int allocated$get(MemorySegment seg, long index) { + return (int)fuse_args.allocated$VH.get(seg.asSlice(index*sizeof())); + } + public static void allocated$set(MemorySegment seg, long index, int x) { + fuse_args.allocated$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 29484497..f8ed78ab 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 @@ -18,6 +18,39 @@ 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_mount$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_mount$MH,"fuse_mount"); + } + public static MemoryAddress fuse_mount ( Addressable mountpoint, Addressable args) { + var mh$ = fuse_mount$MH(); + try { + return (java.lang.foreign.MemoryAddress)mh$.invokeExact(mountpoint, args); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_unmount$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_unmount$MH,"fuse_unmount"); + } + public static void fuse_unmount ( Addressable mountpoint, Addressable ch) { + var mh$ = fuse_unmount$MH(); + try { + mh$.invokeExact(mountpoint, ch); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_parse_cmdline$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_parse_cmdline$MH,"fuse_parse_cmdline"); + } + public static int fuse_parse_cmdline ( Addressable args, Addressable mountpoint, Addressable multithreaded, Addressable foreground) { + var mh$ = fuse_parse_cmdline$MH(); + try { + return (int)mh$.invokeExact(args, mountpoint, multithreaded, foreground); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } public static MethodHandle fuse_main_real$MH() { return RuntimeHelper.requireNonNull(constants$0.fuse_main_real$MH,"fuse_main_real"); } @@ -29,8 +62,41 @@ public static int fuse_main_real ( int argc, Addressable argv, Addressable ops throw new AssertionError("should not reach here", ex$); } } + public static MethodHandle fuse_new$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse_new$MH,"fuse_new"); + } + public static MemoryAddress fuse_new ( Addressable ch, Addressable args, Addressable ops, long opsize, Addressable data) { + var mh$ = fuse_new$MH(); + try { + return (java.lang.foreign.MemoryAddress)mh$.invokeExact(ch, args, ops, opsize, data); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_destroy$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse_destroy$MH,"fuse_destroy"); + } + public static void fuse_destroy ( Addressable f) { + var mh$ = fuse_destroy$MH(); + try { + mh$.invokeExact(f); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle fuse_loop$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse_loop$MH,"fuse_loop"); + } + public static int fuse_loop ( Addressable f) { + var mh$ = fuse_loop$MH(); + try { + return (int)mh$.invokeExact(f); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } public static MethodHandle fuse_exit$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_exit$MH,"fuse_exit"); + return RuntimeHelper.requireNonNull(constants$1.fuse_exit$MH,"fuse_exit"); } public static void fuse_exit ( Addressable f) { var mh$ = fuse_exit$MH(); @@ -41,7 +107,7 @@ public static void fuse_exit ( Addressable f) { } } public static MethodHandle fuse_get_context$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_get_context$MH,"fuse_get_context"); + return RuntimeHelper.requireNonNull(constants$1.fuse_get_context$MH,"fuse_get_context"); } public static MemoryAddress fuse_get_context () { var mh$ = fuse_get_context$MH(); diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_operations.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_operations.java index 0ae47be8..0cad3184 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_operations.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_operations.java @@ -61,7 +61,7 @@ public class fuse_operations { Constants$root.C_POINTER$LAYOUT.withName("read_buf"), Constants$root.C_POINTER$LAYOUT.withName("flock"), Constants$root.C_POINTER$LAYOUT.withName("fallocate"), - Constants$root.C_POINTER$LAYOUT.withName("reserved00"), + Constants$root.C_POINTER$LAYOUT.withName("getpath"), Constants$root.C_POINTER$LAYOUT.withName("reserved01"), Constants$root.C_POINTER$LAYOUT.withName("reserved02"), Constants$root.C_POINTER$LAYOUT.withName("statfs_x"), @@ -2052,21 +2052,26 @@ static fallocate ofAddress(MemoryAddress addr, MemorySession session) { public static fallocate fallocate (MemorySegment segment, MemorySession session) { return fallocate.ofAddress(fallocate$get(segment), session); } - static final FunctionDescriptor reserved00$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); - static final MethodHandle reserved00$MH = RuntimeHelper.downcallHandle( - fuse_operations.reserved00$FUNC + static final FunctionDescriptor getpath$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$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 getpath$MH = RuntimeHelper.downcallHandle( + fuse_operations.getpath$FUNC ); - public interface reserved00 { + public interface getpath { - int apply(); - static MemorySegment allocate(reserved00 fi, MemorySession session) { - return RuntimeHelper.upcallStub(reserved00.class, fi, fuse_operations.reserved00$FUNC, session); + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, long _x2, java.lang.foreign.MemoryAddress _x3); + static MemorySegment allocate(getpath fi, MemorySession session) { + return RuntimeHelper.upcallStub(getpath.class, fi, fuse_operations.getpath$FUNC, session); } - static reserved00 ofAddress(MemoryAddress addr, MemorySession session) { + static getpath ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return () -> { + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, long __x2, java.lang.foreign.MemoryAddress __x3) -> { try { - return (int)fuse_operations.reserved00$MH.invokeExact((Addressable)symbol); + return (int)fuse_operations.getpath$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2, (java.lang.foreign.Addressable)__x3); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -2074,24 +2079,24 @@ static reserved00 ofAddress(MemoryAddress addr, MemorySession session) { } } - static final VarHandle reserved00$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("reserved00")); - public static VarHandle reserved00$VH() { - return fuse_operations.reserved00$VH; + static final VarHandle getpath$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("getpath")); + public static VarHandle getpath$VH() { + return fuse_operations.getpath$VH; } - public static MemoryAddress reserved00$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.reserved00$VH.get(seg); + public static MemoryAddress getpath$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_operations.getpath$VH.get(seg); } - public static void reserved00$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.reserved00$VH.set(seg, x); + public static void getpath$set( MemorySegment seg, MemoryAddress x) { + fuse_operations.getpath$VH.set(seg, x); } - public static MemoryAddress reserved00$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.reserved00$VH.get(seg.asSlice(index*sizeof())); + public static MemoryAddress getpath$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_operations.getpath$VH.get(seg.asSlice(index*sizeof())); } - public static void reserved00$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.reserved00$VH.set(seg.asSlice(index*sizeof()), x); + public static void getpath$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_operations.getpath$VH.set(seg.asSlice(index*sizeof()), x); } - public static reserved00 reserved00 (MemorySegment segment, MemorySession session) { - return reserved00.ofAddress(reserved00$get(segment), session); + public static getpath getpath (MemorySegment segment, MemorySession session) { + return getpath.ofAddress(getpath$get(segment), session); } static final FunctionDescriptor reserved01$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); static final MethodHandle reserved01$MH = RuntimeHelper.downcallHandle( diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/winfsp_fuse_h.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/winfsp_fuse_h.java deleted file mode 100644 index 8469bc8b..00000000 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/winfsp_fuse_h.java +++ /dev/null @@ -1,23 +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 winfsp_fuse_h { - - /* package-private */ winfsp_fuse_h() {} - public static OfByte C_CHAR = Constants$root.C_CHAR$LAYOUT; - public static OfShort C_SHORT = Constants$root.C_SHORT$LAYOUT; - public static OfInt C_INT = Constants$root.C_LONG$LAYOUT; - public static OfInt C_LONG = Constants$root.C_LONG$LAYOUT; - public static OfLong C_LONG_LONG = Constants$root.C_LONG_LONG$LAYOUT; - 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; -} - - From 39a9c2d21b0ae45bce6af84361f3cfef57e8e63d Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Fri, 2 Sep 2022 18:03:54 +0200 Subject: [PATCH 26/98] cleanup --- .../java/org/cryptomator/jfuse/api/Fuse.java | 39 +++++++++++++------ .../org/cryptomator/jfuse/api/FuseMount.java | 18 ++++++++- .../jfuse/api/UnmountedFuseMount.java | 4 +- .../jfuse/examples/HelloWorldFileSystem.java | 15 ++++--- .../jfuse/examples/PosixMirrorFileSystem.java | 8 +--- .../examples/WindowsMirrorFileSystem.java | 8 +--- .../jfuse/linux/aarch64/FuseMountImpl.java | 6 +-- .../jfuse/linux/amd64/FuseMountImpl.java | 5 +-- .../cryptomator/jfuse/mac/FuseMountImpl.java | 5 +-- .../org/cryptomator/jfuse/tests/MirrorIT.java | 5 +-- .../cryptomator/jfuse/win/amd64/FuseImpl.java | 4 +- .../jfuse/win/amd64/FuseMountImpl.java | 5 +-- 12 files changed, 71 insertions(+), 51 deletions(-) diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java index a5b22f20..01d09d6d 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java @@ -14,6 +14,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; @@ -57,7 +58,8 @@ public static FuseBuilder builder() { * @throws CompletionException wrapping exceptions thrown during init() or fuse_main_real() */ @Blocking - public int mount(String progName, Path mountPoint, String... flags) throws CompletionException, TimeoutException { + @MustBeInvokedByOverriders + public void mount(String progName, Path mountPoint, String... flags) throws CompletionException, TimeoutException { FuseMount lock = new UnmountedFuseMount(); if (!mount.compareAndSet(UNMOUNTED, lock)) { throw new IllegalStateException("Already mounted"); @@ -73,13 +75,27 @@ public int mount(String progName, Path mountPoint, String... flags) throws Compl var fuseMount = this.mount(args); var isOnlySession = mount.compareAndSet(lock, fuseMount); assert isOnlySession : "unreachable code, as no other method can set this.mount to lock"; - executor.submit(fuseMount::loop); // TODO keep reference of future? + executor.submit(this::fuseLoop); // TODO keep reference of future and report result } finally { mount.compareAndSet(lock, UNMOUNTED); // if value is still `lock`, mount has failed. } - return 0; // TODO make this void and use proper exceptions } + @Blocking + private int fuseLoop() { + AtomicInteger result = new AtomicInteger(); + fuseScope.whileAlive(() -> { + var mount = this.mount.get(); + try { + result.set(mount.loop()); + } finally { + System.out.println("fuse_loop finished with result " + result.get()); + } + }); + return result.get(); + } + + @Blocking protected abstract FuseMount mount(List args); /** @@ -88,19 +104,18 @@ public int mount(String progName, Path mountPoint, String... flags) throws Compl * Important: Before closing, a graceful unmount via system tools (e.g. {@code fusermount -u}) should be attempted. */ @Override + @Blocking @MustBeInvokedByOverriders public void close() throws TimeoutException { try { - var mount = this.mount.getAndSet(null); - if (mount != null) { - mount.unmount(); - executor.shutdown(); - boolean exited = executor.awaitTermination(10, TimeUnit.SECONDS); - if (!exited) { - throw new TimeoutException("fuse main loop continued runn"); - } - mount.destroy(); + var mount = this.mount.getAndSet(UNMOUNTED); + mount.unmount(); + executor.shutdown(); + boolean exited = executor.awaitTermination(10, TimeUnit.SECONDS); + if (!exited) { + throw new TimeoutException("fuse main loop continued runn"); } + mount.destroy(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseMount.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseMount.java index b39e6337..29cba034 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseMount.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseMount.java @@ -1,11 +1,27 @@ package org.cryptomator.jfuse.api; +import org.jetbrains.annotations.Blocking; + public interface FuseMount { - void loop(); + /** + * Runs fuse_loop or fuse_loop_mt, + * depending on the implementation and requested options. + * + * @return exit code returned by the fuse_loop(_mt) + */ + @Blocking + int loop(); + /** + * Perform actions required to stop the {@link #loop() run loop}, e.g. fuse_exit + * and to unmount the volume, e.g. fuse_unmount. + */ void unmount() ; + /** + * Cleans up resources after the {@link #loop() run loop} exited. + */ void destroy(); } diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/UnmountedFuseMount.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/UnmountedFuseMount.java index a21cf6de..5baac06f 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/UnmountedFuseMount.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/UnmountedFuseMount.java @@ -2,8 +2,8 @@ class UnmountedFuseMount implements FuseMount { @Override - public void loop() { - // no-op + public int loop() { + return 0; } @Override diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java index cb10403a..51807d55 100644 --- a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java @@ -11,6 +11,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.nio.file.Path; @@ -20,6 +21,7 @@ import java.util.concurrent.TimeoutException; import java.util.stream.Stream; +@SuppressWarnings("OctalInteger") public class HelloWorldFileSystem implements FuseOperations { private static final int S_IFDIR = 0040000; @@ -40,15 +42,16 @@ public static void main(String[] args) { var fuseOps = new HelloWorldFileSystem(builder.errno()); try (var fuse = builder.build(fuseOps)) { LOG.info("Mounting at {}...", mountPoint); - int result = fuse.mount("jfuse", mountPoint, "-s"); - if (result == 0) { - LOG.info("Mounted to {}. Unmount to terminate this process", mountPoint); - } else { - LOG.error("Failed to mount to {}. Exit code: {}", mountPoint, result); - } + fuse.mount("jfuse", mountPoint, "-s"); + LOG.info("Mounted to {}.", mountPoint); + LOG.info("Enter a anything to unmount..."); + System.in.read(); } catch (TimeoutException | CompletionException e) { LOG.error("Un/Mounting failed. ", e); System.exit(1); + } catch (IOException e) { + LOG.error("Failed to create mirror", e); + System.exit(1); } } diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/PosixMirrorFileSystem.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/PosixMirrorFileSystem.java index bee18789..2bf5a8fa 100644 --- a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/PosixMirrorFileSystem.java +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/PosixMirrorFileSystem.java @@ -33,12 +33,8 @@ public static void main(String[] args) { var builder = Fuse.builder(); try (var fuse = builder.build(new PosixMirrorFileSystem(mirrored, builder.errno()))) { LOG.info("Mounting at {}...", mountPoint); - int result = fuse.mount("jfuse", mountPoint, "-s", "-ovolname=mirror"); - if (result == 0) { - LOG.info("Mounted to {}. Unmount to terminate this process", mountPoint); - } else { - LOG.error("Failed to mount to {}. Exit code: {}", mountPoint, result); - } + fuse.mount("jfuse", mountPoint, "-s"); + LOG.info("Mounted to {}.", mountPoint); LOG.info("Enter a anything to unmount..."); System.in.read(); } catch (TimeoutException | CompletionException e) { diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/WindowsMirrorFileSystem.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/WindowsMirrorFileSystem.java index 8ccb5e18..5a1249c1 100644 --- a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/WindowsMirrorFileSystem.java +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/WindowsMirrorFileSystem.java @@ -31,12 +31,8 @@ public static void main(String[] args) { var builder = Fuse.builder(); try (var fuse = builder.build(new WindowsMirrorFileSystem(mirrored, builder.errno()))) { LOG.info("Mounting at {}...", mountPoint); - int result = fuse.mount("jfuse", mountPoint, "-s", "-ouid=-1", "-ogid=11", "-ovolname=mirror"); - if (result == 0) { - LOG.info("Mounted to {}. Unmount to terminate this process", mountPoint); - } else { - LOG.error("Failed to mount to {}. Exit code: {}", mountPoint, result); - } + fuse.mount("jfuse", mountPoint, "-s", "-ouid=-1", "-ogid=11", "-ovolname=mirror"); + LOG.info("Mounted to {}.", mountPoint); LOG.info("Enter a anything to unmount..."); System.in.read(); } catch (TimeoutException | CompletionException e) { 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 2e451b5c..f9c57a6b 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 @@ -6,11 +6,9 @@ import java.lang.foreign.MemoryAddress; record FuseMountImpl(MemoryAddress fuse, FuseArgs fuseArgs) implements FuseMount { - @Override - public void loop() { + public int loop() { // TODO support fuse_loop_mt if args.multiThreaded() - fuse_h.fuse_loop(fuse); - System.out.println("fuse_loop finished"); // TODO remove + return fuse_h.fuse_loop(fuse); } @Override 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 c72fc0ea..1e558a4a 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 @@ -7,10 +7,9 @@ record FuseMountImpl(MemoryAddress fuse, FuseArgs fuseArgs) implements FuseMount { @Override - public void loop() { + public int loop() { // TODO support fuse_loop_mt if args.multiThreaded() - fuse_h.fuse_loop(fuse); - System.out.println("fuse_loop finished"); // TODO remove + return fuse_h.fuse_loop(fuse); } @Override diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseMountImpl.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseMountImpl.java index 91f632ee..5d694841 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseMountImpl.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseMountImpl.java @@ -7,10 +7,9 @@ record FuseMountImpl(MemoryAddress fuse, MemoryAddress ch, FuseArgs args) implements FuseMount { - public void loop() { + public int loop() { // TODO support fuse_loop_mt if args.multiThreaded() - fuse_h.fuse_loop(fuse); - System.out.println("fuse_loop finished"); // TODO remove + return fuse_h.fuse_loop(fuse); } public void unmount() { 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 ef63b021..54f9688a 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 @@ -61,15 +61,14 @@ public void setup(@TempDir Path tmpDir) throws IOException, TimeoutException { fs = new PosixMirrorFileSystem(orig, builder.errno()); } fuse = builder.build(fs); - int result = fuse.mount("mirror-it", mirror, flags.toArray(String[]::new)); - Assertions.assertEquals(0, result, "mount failed"); + fuse.mount("mirror-it", mirror, flags.toArray(String[]::new)); } @AfterAll public void teardown() throws IOException, InterruptedException { // attempt graceful unmount before closing if (OS.MAC.isCurrentOs()) { - ProcessBuilder command = new ProcessBuilder("umount", "-f", "--", mirror.getFileName().toString()); + ProcessBuilder command = new ProcessBuilder("umount", "--", mirror.getFileName().toString()); command.directory(mirror.getParent().toFile()); Process p = command.start(); p.waitFor(10, TimeUnit.SECONDS); 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 422cee34..2fafdc42 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 @@ -33,13 +33,13 @@ public FuseImpl(FuseOperations fuseOperations) { } @Override - public int mount(String progName, Path mountPoint, String... flags) throws TimeoutException { + public void mount(String progName, Path mountPoint, String... flags) throws TimeoutException { var adjustedMP = mountPoint; if (mountPoint.compareTo(mountPoint.getRoot()) == 0 && mountPoint.isAbsolute()) { //winfsp accepts only drive letters written in drive relative notation adjustedMP = Path.of(mountPoint.toString().charAt(0) + ":"); } - return super.mount(progName, adjustedMP, flags); + super.mount(progName, adjustedMP, flags); } @Override 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 3417d8c3..ab38d8ff 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 @@ -7,10 +7,9 @@ record FuseMountImpl(MemoryAddress fuse, MemoryAddress ch, FuseArgs args) implements FuseMount { - public void loop() { + public int loop() { // TODO support fuse_loop_mt if args.multiThreaded() - fuse_h.fuse_loop(fuse); - System.out.println("fuse_loop finished"); // TODO remove + return fuse_h.fuse_loop(fuse); } public void unmount() { From c9788f6fcc58ab9dcb4e489c55efcd266cb83a28 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Fri, 2 Sep 2022 18:04:20 +0200 Subject: [PATCH 27/98] implemented fuse_loop_mt on Mac + Linux --- jfuse-linux-aarch64/pom.xml | 1 + .../jfuse/linux/aarch64/FuseArgs.java | 3 + .../jfuse/linux/aarch64/FuseMountImpl.java | 14 ++++- .../linux/aarch64/extr/fuse_loop_config.java | 59 +++++++++++++++++++ jfuse-linux-amd64/pom.xml | 1 + .../jfuse/linux/amd64/FuseArgs.java | 4 ++ .../jfuse/linux/amd64/FuseMountImpl.java | 14 ++++- .../linux/amd64/extr/fuse_loop_config.java | 59 +++++++++++++++++++ jfuse-mac/pom.xml | 1 + .../cryptomator/jfuse/mac/FuseMountImpl.java | 7 ++- .../jfuse/mac/extr/constants$1.java | 14 ++--- .../cryptomator/jfuse/mac/extr/fuse_h.java | 22 +++---- 12 files changed, 175 insertions(+), 24 deletions(-) create mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_loop_config.java create mode 100644 jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_loop_config.java diff --git a/jfuse-linux-aarch64/pom.xml b/jfuse-linux-aarch64/pom.xml index 4690d2f4..f60adc8d 100644 --- a/jfuse-linux-aarch64/pom.xml +++ b/jfuse-linux-aarch64/pom.xml @@ -118,6 +118,7 @@ timespec fuse_conn_info fuse_args + fuse_loop_config FUSE_FILL_DIR_PLUS 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 fcb7d561..897aad77 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 @@ -28,4 +28,7 @@ public MemoryAddress mountPoint() { return fuse_cmdline_opts.mountpoint$get(cmdLineOpts); } + public boolean multithreaded() { + return fuse_cmdline_opts.singlethread$get(cmdLineOpts) == 0; + } } 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 f9c57a6b..562d94b5 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,13 +2,23 @@ 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 java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySession; record FuseMountImpl(MemoryAddress fuse, FuseArgs fuseArgs) implements FuseMount { public int loop() { - // TODO support fuse_loop_mt if args.multiThreaded() - return fuse_h.fuse_loop(fuse); + 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); + return fuse_h.fuse_loop_mt(fuse, loopCfg); + } + } else { + return fuse_h.fuse_loop(fuse); + } } @Override 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.java new file mode 100644 index 00000000..1aeb84c4 --- /dev/null +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_loop_config.java @@ -0,0 +1,59 @@ +// 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.*; +public class fuse_loop_config { + + 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"); + public static MemoryLayout $LAYOUT() { + return fuse_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 fuse_loop_config.clone_fd$VH; + } + public static int clone_fd$get(MemorySegment seg) { + return (int)fuse_loop_config.clone_fd$VH.get(seg); + } + public static void clone_fd$set( MemorySegment seg, int x) { + fuse_loop_config.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())); + } + public static void clone_fd$set(MemorySegment seg, long index, int x) { + fuse_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 fuse_loop_config.max_idle_threads$VH; + } + public static int max_idle_threads$get(MemorySegment seg) { + return (int)fuse_loop_config.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); + } + 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())); + } + 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); + } + 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-linux-amd64/pom.xml b/jfuse-linux-amd64/pom.xml index 744aa986..4634ea65 100644 --- a/jfuse-linux-amd64/pom.xml +++ b/jfuse-linux-amd64/pom.xml @@ -118,6 +118,7 @@ timespec fuse_conn_info fuse_args + fuse_loop_config FUSE_FILL_DIR_PLUS 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 097c92e7..18492d4a 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 @@ -28,4 +28,8 @@ public MemoryAddress mountPoint() { return fuse_cmdline_opts.mountpoint$get(cmdLineOpts); } + public boolean multithreaded() { + return fuse_cmdline_opts.singlethread$get(cmdLineOpts) == 0; + } + } 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 1e558a4a..4e295c5c 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,14 +2,24 @@ 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 java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySession; record FuseMountImpl(MemoryAddress fuse, FuseArgs fuseArgs) implements FuseMount { @Override public int loop() { - // TODO support fuse_loop_mt if args.multiThreaded() - return fuse_h.fuse_loop(fuse); + 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); + return fuse_h.fuse_loop_mt(fuse, loopCfg); + } + } else { + return fuse_h.fuse_loop(fuse); + } } @Override 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.java new file mode 100644 index 00000000..093a4f0d --- /dev/null +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_loop_config.java @@ -0,0 +1,59 @@ +// 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.*; +public class fuse_loop_config { + + 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"); + public static MemoryLayout $LAYOUT() { + return fuse_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 fuse_loop_config.clone_fd$VH; + } + public static int clone_fd$get(MemorySegment seg) { + return (int)fuse_loop_config.clone_fd$VH.get(seg); + } + public static void clone_fd$set( MemorySegment seg, int x) { + fuse_loop_config.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())); + } + public static void clone_fd$set(MemorySegment seg, long index, int x) { + fuse_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 fuse_loop_config.max_idle_threads$VH; + } + public static int max_idle_threads$get(MemorySegment seg) { + return (int)fuse_loop_config.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); + } + 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())); + } + 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); + } + 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-mac/pom.xml b/jfuse-mac/pom.xml index be8f93ac..031239b4 100644 --- a/jfuse-mac/pom.xml +++ b/jfuse-mac/pom.xml @@ -102,6 +102,7 @@ fuse_mount fuse_new fuse_loop + fuse_loop_mt fuse_unmount fuse_destroy diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseMountImpl.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseMountImpl.java index 5d694841..0ec2a6b7 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseMountImpl.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseMountImpl.java @@ -8,8 +8,11 @@ record FuseMountImpl(MemoryAddress fuse, MemoryAddress ch, FuseArgs args) implements FuseMount { public int loop() { - // TODO support fuse_loop_mt if args.multiThreaded() - return fuse_h.fuse_loop(fuse); + if (args.multiThreaded()) { + return fuse_h.fuse_loop_mt(fuse); + } else { + return fuse_h.fuse_loop(fuse); + } } public void unmount() { diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/constants$1.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/constants$1.java index 48ec11f5..27179244 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/constants$1.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/constants$1.java @@ -30,6 +30,13 @@ class constants$1 { "fuse_exit", constants$1.fuse_exit$FUNC ); + static final FunctionDescriptor fuse_loop_mt$FUNC = FunctionDescriptor.of(Constants$root.C_INT$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 FunctionDescriptor fuse_get_context$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT); static final MethodHandle fuse_get_context$MH = RuntimeHelper.downcallHandle( "fuse_get_context", @@ -46,13 +53,6 @@ class constants$1 { "fuse_main_real", constants$1.fuse_main_real$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$1.fuse_get_session$FUNC - ); } diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_h.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_h.java index 3347644c..50b29927 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_h.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_h.java @@ -95,6 +95,17 @@ public static void fuse_exit ( Addressable f) { throw new AssertionError("should not reach here", ex$); } } + public static MethodHandle fuse_loop_mt$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse_loop_mt$MH,"fuse_loop_mt"); + } + public static int fuse_loop_mt ( Addressable f) { + var mh$ = fuse_loop_mt$MH(); + try { + return (int)mh$.invokeExact(f); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } public static MethodHandle fuse_get_context$MH() { return RuntimeHelper.requireNonNull(constants$1.fuse_get_context$MH,"fuse_get_context"); } @@ -117,17 +128,6 @@ public static int fuse_main_real ( int argc, Addressable argv, Addressable op, throw new AssertionError("should not reach here", ex$); } } - public static MethodHandle fuse_get_session$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse_get_session$MH,"fuse_get_session"); - } - public static MemoryAddress fuse_get_session ( Addressable f) { - var mh$ = fuse_get_session$MH(); - try { - return (java.lang.foreign.MemoryAddress)mh$.invokeExact(f); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - } } From 41eac45ece30d00c8beef91cf4dab75da5295f54 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Fri, 2 Sep 2022 18:05:52 +0200 Subject: [PATCH 28/98] added method annotations [ci skip] --- .../org/cryptomator/jfuse/linux/aarch64/FuseMountImpl.java | 2 ++ .../java/org/cryptomator/jfuse/linux/amd64/FuseMountImpl.java | 1 + .../src/main/java/org/cryptomator/jfuse/mac/FuseMountImpl.java | 3 +++ .../java/org/cryptomator/jfuse/win/amd64/FuseMountImpl.java | 3 +++ 4 files changed, 9 insertions(+) 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 562d94b5..f1dbf07b 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 @@ -8,6 +8,8 @@ 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()) { 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 4e295c5c..60e9a2da 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 @@ -8,6 +8,7 @@ import java.lang.foreign.MemorySession; record FuseMountImpl(MemoryAddress fuse, FuseArgs fuseArgs) implements FuseMount { + @Override public int loop() { if (fuseArgs.multithreaded()) { diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseMountImpl.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseMountImpl.java index 0ec2a6b7..135dec06 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseMountImpl.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseMountImpl.java @@ -7,6 +7,7 @@ record FuseMountImpl(MemoryAddress fuse, MemoryAddress ch, FuseArgs args) implements FuseMount { + @Override public int loop() { if (args.multiThreaded()) { return fuse_h.fuse_loop_mt(fuse); @@ -15,11 +16,13 @@ public int loop() { } } + @Override public void unmount() { fuse_h.fuse_exit(fuse); fuse_h.fuse_unmount(args.mountPoint(), ch); } + @Override public void destroy() { fuse_h.fuse_destroy(fuse); } 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 ab38d8ff..52de9983 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 @@ -7,16 +7,19 @@ record FuseMountImpl(MemoryAddress fuse, MemoryAddress ch, FuseArgs args) implements FuseMount { + @Override public int loop() { // TODO support fuse_loop_mt if args.multiThreaded() return fuse_h.fuse_loop(fuse); } + @Override public void unmount() { fuse_h.fuse_exit(fuse); fuse_h.fuse_unmount(args.mountPoint(), ch); } + @Override public void destroy() { fuse_h.fuse_destroy(fuse); } From 8895498ae110e1a77a6995433a894a60469f58ee Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Fri, 2 Sep 2022 18:09:20 +0200 Subject: [PATCH 29/98] fixed javadoc + removed unused exceptions --- jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java | 5 +---- .../main/java/org/cryptomator/jfuse/win/amd64/FuseImpl.java | 3 +-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java index 01d09d6d..c33c2d20 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java @@ -9,7 +9,6 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.CompletionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @@ -54,12 +53,10 @@ public static FuseBuilder builder() { * @param progName The program name used to construct a usage message and to derive a fallback for -ofsname=... * @param mountPoint mount point * @param flags Additional flags. Use flag -help to get a list of available flags - * @return 0 if mounted successfully, or the result of fuse_main_real() in case of errors - * @throws CompletionException wrapping exceptions thrown during init() or fuse_main_real() */ @Blocking @MustBeInvokedByOverriders - public void mount(String progName, Path mountPoint, String... flags) throws CompletionException, TimeoutException { + public void mount(String progName, Path mountPoint, String... flags) { FuseMount lock = new UnmountedFuseMount(); if (!mount.compareAndSet(UNMOUNTED, lock)) { throw new IllegalStateException("Already mounted"); 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 2fafdc42..c2bb34a2 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 @@ -17,7 +17,6 @@ import java.lang.foreign.ValueLayout; import java.nio.file.Path; import java.util.List; -import java.util.concurrent.TimeoutException; import static java.lang.foreign.ValueLayout.JAVA_INT; @@ -33,7 +32,7 @@ public FuseImpl(FuseOperations fuseOperations) { } @Override - public void mount(String progName, Path mountPoint, String... flags) throws TimeoutException { + public void mount(String progName, Path mountPoint, String... flags) { var adjustedMP = mountPoint; if (mountPoint.compareTo(mountPoint.getRoot()) == 0 && mountPoint.isAbsolute()) { //winfsp accepts only drive letters written in drive relative notation From 62d818b28d5fab8cd8e4502beae1c705125cf80d Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Sat, 3 Sep 2022 17:12:53 +0200 Subject: [PATCH 30/98] fixed code smells --- .../main/java/org/cryptomator/jfuse/linux/aarch64/FuseImpl.java | 2 +- .../main/java/org/cryptomator/jfuse/linux/amd64/FuseImpl.java | 2 +- jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java | 2 +- .../src/main/java/org/cryptomator/jfuse/win/amd64/FuseImpl.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) 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 eb94b008..61d4b269 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 @@ -51,7 +51,7 @@ protected FuseMount mount(List args) { private FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { var args = fuse_args.allocate(fuseScope); var argc = cmdLineArgs.size(); - var argv = fuseScope.allocateArray(ValueLayout.ADDRESS, argc + 1); + var argv = fuseScope.allocateArray(ValueLayout.ADDRESS, argc + 1L); for (int i = 0; i < argc; i++) { var cString = fuseScope.allocateUtf8String(cmdLineArgs.get(i)); argv.setAtIndex(ValueLayout.ADDRESS, i, cString); 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 ad5bccf5..33054149 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 @@ -51,7 +51,7 @@ protected FuseMount mount(List args) { private FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { var args = fuse_args.allocate(fuseScope); var argc = cmdLineArgs.size(); - var argv = fuseScope.allocateArray(ValueLayout.ADDRESS, argc + 1); + var argv = fuseScope.allocateArray(ValueLayout.ADDRESS, argc + 1L); for (int i = 0; i < argc; i++) { var cString = fuseScope.allocateUtf8String(cmdLineArgs.get(i)); argv.setAtIndex(ValueLayout.ADDRESS, i, cString); diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java index a6751fbb..695037c4 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java @@ -52,7 +52,7 @@ protected FuseMount mount(List args) { private FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { var args = fuse_args.allocate(fuseScope); var argc = cmdLineArgs.size(); - var argv = fuseScope.allocateArray(ValueLayout.ADDRESS, argc + 1); + var argv = fuseScope.allocateArray(ValueLayout.ADDRESS, argc + 1L); for (int i = 0; i < argc; i++) { var cString = fuseScope.allocateUtf8String(cmdLineArgs.get(i)); argv.setAtIndex(ValueLayout.ADDRESS, i, cString); 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 c2bb34a2..1253d15f 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 @@ -62,7 +62,7 @@ protected FuseMount mount(List args) { private FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { var args = fuse_args.allocate(fuseScope); var argc = cmdLineArgs.size(); - var argv = fuseScope.allocateArray(ValueLayout.ADDRESS, argc + 1); + var argv = fuseScope.allocateArray(ValueLayout.ADDRESS, argc + 1L); for (int i = 0; i < argc; i++) { var cString = fuseScope.allocateUtf8String(cmdLineArgs.get(i)); argv.setAtIndex(ValueLayout.ADDRESS, i, cString); From befa88068b99b9f62994ad4e443ee8ecdae400e5 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Sat, 3 Sep 2022 17:29:09 +0200 Subject: [PATCH 31/98] integration test on windows seems to be a little timing-sensitive --- .../src/test/java/org/cryptomator/jfuse/tests/MirrorIT.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 54f9688a..5fca52c5 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 @@ -44,7 +44,7 @@ public class MirrorIT { private Fuse fuse; @BeforeAll - public void setup(@TempDir Path tmpDir) throws IOException, TimeoutException { + public void setup(@TempDir Path tmpDir) throws IOException, InterruptedException { var builder = Fuse.builder(); orig = tmpDir.resolve("orig"); Files.createDirectories(orig); @@ -62,6 +62,7 @@ public void setup(@TempDir Path tmpDir) throws IOException, TimeoutException { } fuse = builder.build(fs); fuse.mount("mirror-it", mirror, flags.toArray(String[]::new)); + Thread.sleep(100); // give the file system some time to accept the mounted volume } @AfterAll @@ -82,6 +83,7 @@ public void teardown() throws IOException, InterruptedException { if (fuse != null) { Assertions.assertTimeoutPreemptively(Duration.ofSeconds(10), fuse::close, "file system still active"); } + Thread.sleep(100); // give the file system some time before cleaning up the @TempDir } @Nested From a68022c5605dd482984e1a86fb1dc1f3ab0d7006 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Sat, 3 Sep 2022 18:15:29 +0200 Subject: [PATCH 32/98] added tests --- .../jfuse/api/UnmountedFuseMount.java | 3 ++ .../jfuse/api/UnmountedFuseMountTest.java | 25 ++++++++++++++++ .../jfuse/linux/aarch64/FuseArgs.java | 2 +- .../jfuse/linux/aarch64/FuseImpl.java | 3 +- .../jfuse/linux/aarch64/FuseImplTest.java | 28 +++++++++++++++++ .../jfuse/linux/amd64/FuseArgs.java | 4 +-- .../jfuse/linux/amd64/FuseImpl.java | 3 +- .../jfuse/linux/amd64/FuseImplTest.java | 27 +++++++++++++++++ .../org/cryptomator/jfuse/mac/FuseArgs.java | 2 +- .../org/cryptomator/jfuse/mac/FuseImpl.java | 3 +- .../cryptomator/jfuse/mac/FuseImplTest.java | 29 ++++++++++++++++++ .../cryptomator/jfuse/win/amd64/FuseArgs.java | 2 +- .../cryptomator/jfuse/win/amd64/FuseImpl.java | 3 +- .../jfuse/win/amd64/FuseImplTest.java | 30 ++++++++++++++++++- pom.xml | 2 +- 15 files changed, 155 insertions(+), 11 deletions(-) create mode 100644 jfuse-api/src/test/java/org/cryptomator/jfuse/api/UnmountedFuseMountTest.java diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/UnmountedFuseMount.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/UnmountedFuseMount.java index 5baac06f..1c3a4be2 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/UnmountedFuseMount.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/UnmountedFuseMount.java @@ -1,5 +1,8 @@ package org.cryptomator.jfuse.api; +/** + * A dummy implementation that can safely be used for repeated invocations during {@link Fuse#close()}, making it idempotent. + */ class UnmountedFuseMount implements FuseMount { @Override public int loop() { diff --git a/jfuse-api/src/test/java/org/cryptomator/jfuse/api/UnmountedFuseMountTest.java b/jfuse-api/src/test/java/org/cryptomator/jfuse/api/UnmountedFuseMountTest.java new file mode 100644 index 00000000..805c788a --- /dev/null +++ b/jfuse-api/src/test/java/org/cryptomator/jfuse/api/UnmountedFuseMountTest.java @@ -0,0 +1,25 @@ +package org.cryptomator.jfuse.api; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class UnmountedFuseMountTest { + + private final UnmountedFuseMount unmountedMount = new UnmountedFuseMount(); + + @Test + public void testLoop() { + Assertions.assertEquals(0, unmountedMount.loop()); + } + + @Test + public void testUnmount() { + Assertions.assertDoesNotThrow(unmountedMount::unmount); + } + + @Test + public void testDestroy() { + Assertions.assertDoesNotThrow(unmountedMount::destroy); + } + +} \ No newline at end of file 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 897aad77..7ad723b9 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 @@ -7,7 +7,7 @@ import java.lang.foreign.MemorySegment; import java.lang.foreign.ValueLayout; -public record FuseArgs(MemorySegment args, MemorySegment cmdLineOpts) { +record FuseArgs(MemorySegment args, MemorySegment cmdLineOpts) { @Override public String toString() { 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 61d4b269..1c1e035c 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 @@ -48,7 +48,8 @@ protected FuseMount mount(List args) { return new FuseMountImpl(fuse, fuseArgs); } - private FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { + @VisibleForTesting + FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { var args = fuse_args.allocate(fuseScope); var argc = cmdLineArgs.size(); var argv = fuseScope.allocateArray(ValueLayout.ADDRESS, argc + 1L); 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 f60ae4ec..cbb5a7a9 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 @@ -3,6 +3,8 @@ import org.cryptomator.jfuse.api.FuseOperations; import org.cryptomator.jfuse.api.TimeSpec; import org.cryptomator.jfuse.linux.aarch64.extr.fuse_file_info; +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.Assertions; import org.junit.jupiter.api.DisplayName; @@ -13,14 +15,40 @@ import org.mockito.Mockito; import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; import java.lang.foreign.MemorySession; import java.time.Instant; +import java.util.List; public class FuseImplTest { private FuseOperations fuseOps = Mockito.mock(FuseOperations.class); private FuseImpl fuseImpl = new FuseImpl(fuseOps); + @Test + 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 -> { + MemorySegment opts = invocation.getArgument(1); + fuse_cmdline_opts.singlethread$set(opts, 0); + fuse_cmdline_opts.debug$set(opts, 1); + fuse_cmdline_opts.mountpoint$set(opts, scope.allocateUtf8String("/mount/point").address()); + return 0; + }); + + var fuseArgs = fuseImpl.parseArgs(List.of("fusefs", "-foo", "-bar", "/mount/point")); + + Assertions.assertTrue(fuseArgs.multithreaded()); + Assertions.assertTrue(fuseArgs.toString().contains("arg[0] = fusefs")); + Assertions.assertTrue(fuseArgs.toString().contains("arg[1] = -foo")); + Assertions.assertTrue(fuseArgs.toString().contains("arg[2] = -bar")); + Assertions.assertTrue(fuseArgs.toString().contains("singlethreaded = false")); + Assertions.assertTrue(fuseArgs.toString().contains("debug = 1")); + Assertions.assertTrue(fuseArgs.toString().contains("mountPoint = /mount/point")); + } + } + @Nested @DisplayName("utimens") public class Utimens { 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 18492d4a..4c7c5099 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 @@ -7,7 +7,7 @@ import java.lang.foreign.MemorySegment; import java.lang.foreign.ValueLayout; -public record FuseArgs(MemorySegment args, MemorySegment cmdLineOpts) { +record FuseArgs(MemorySegment args, MemorySegment cmdLineOpts) { @Override public String toString() { @@ -20,7 +20,7 @@ public String toString() { } sb.append("mountPoint = ").append(mountPoint().getUtf8String(0)); sb.append("debug = ").append(fuse_cmdline_opts.debug$get(cmdLineOpts)); - sb.append("singlethreaded = ").append(fuse_cmdline_opts.singlethread$get(cmdLineOpts)); + sb.append("singlethreaded = ").append(!multithreaded()); return sb.toString(); } 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 33054149..1a41c44e 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 @@ -48,7 +48,8 @@ protected FuseMount mount(List args) { return new FuseMountImpl(fuse, fuseArgs); } - private FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { + @VisibleForTesting + FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { var args = fuse_args.allocate(fuseScope); var argc = cmdLineArgs.size(); var argv = fuseScope.allocateArray(ValueLayout.ADDRESS, argc + 1L); 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 7b73996d..38965df0 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 @@ -3,6 +3,8 @@ import org.cryptomator.jfuse.api.FuseOperations; import org.cryptomator.jfuse.api.TimeSpec; import org.cryptomator.jfuse.linux.amd64.extr.fuse_file_info; +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.Assertions; import org.junit.jupiter.api.DisplayName; @@ -13,13 +15,38 @@ import org.mockito.Mockito; import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; import java.lang.foreign.MemorySession; import java.time.Instant; +import java.util.List; public class FuseImplTest { private FuseOperations fuseOps = Mockito.mock(FuseOperations.class); private FuseImpl fuseImpl = new FuseImpl(fuseOps); + @Test + 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 -> { + MemorySegment opts = invocation.getArgument(1); + fuse_cmdline_opts.singlethread$set(opts, 0); + fuse_cmdline_opts.debug$set(opts, 1); + fuse_cmdline_opts.mountpoint$set(opts, scope.allocateUtf8String("/mount/point").address()); + return 0; + }); + + var fuseArgs = fuseImpl.parseArgs(List.of("fusefs", "-foo", "-bar", "/mount/point")); + + Assertions.assertTrue(fuseArgs.multithreaded()); + Assertions.assertTrue(fuseArgs.toString().contains("arg[0] = fusefs")); + Assertions.assertTrue(fuseArgs.toString().contains("arg[1] = -foo")); + Assertions.assertTrue(fuseArgs.toString().contains("arg[2] = -bar")); + Assertions.assertTrue(fuseArgs.toString().contains("singlethreaded = false")); + Assertions.assertTrue(fuseArgs.toString().contains("debug = 1")); + Assertions.assertTrue(fuseArgs.toString().contains("mountPoint = /mount/point")); + } + } @Nested @DisplayName("utimens") diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseArgs.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseArgs.java index 1690e3f3..42c92539 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseArgs.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseArgs.java @@ -6,7 +6,7 @@ import java.lang.foreign.MemorySegment; import java.lang.foreign.ValueLayout; -public record FuseArgs(MemorySegment args, MemoryAddress mountPoint, boolean multiThreaded) { +record FuseArgs(MemorySegment args, MemoryAddress mountPoint, boolean multiThreaded) { @Override public String toString() { diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java index 695037c4..37ff0e2d 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java @@ -49,7 +49,8 @@ protected FuseMount mount(List args) { return new FuseMountImpl(fuse, ch, fuseArgs); } - private FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { + @VisibleForTesting + FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { var args = fuse_args.allocate(fuseScope); var argc = cmdLineArgs.size(); var argv = fuseScope.allocateArray(ValueLayout.ADDRESS, argc + 1L); diff --git a/jfuse-mac/src/test/java/org/cryptomator/jfuse/mac/FuseImplTest.java b/jfuse-mac/src/test/java/org/cryptomator/jfuse/mac/FuseImplTest.java index c0d59377..c45b35c6 100644 --- a/jfuse-mac/src/test/java/org/cryptomator/jfuse/mac/FuseImplTest.java +++ b/jfuse-mac/src/test/java/org/cryptomator/jfuse/mac/FuseImplTest.java @@ -2,6 +2,7 @@ import org.cryptomator.jfuse.api.FuseOperations; import org.cryptomator.jfuse.api.TimeSpec; +import org.cryptomator.jfuse.mac.extr.fuse_h; import org.cryptomator.jfuse.mac.extr.timespec; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; @@ -12,13 +13,41 @@ import org.mockito.Mockito; import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; import java.lang.foreign.MemorySession; +import java.lang.foreign.ValueLayout; import java.time.Instant; +import java.util.List; + +import static java.lang.foreign.ValueLayout.JAVA_INT; public class FuseImplTest { private FuseOperations fuseOps = Mockito.mock(FuseOperations.class); private FuseImpl fuseImpl = new FuseImpl(fuseOps); + @Test + public void testParseArgs() { + try (var fuseH = Mockito.mockStatic(fuse_h.class); + var scope = MemorySession.openConfined()) { + fuseH.when(() -> fuse_h.fuse_parse_cmdline(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).then(invocation -> { + MemorySegment mp = invocation.getArgument(1); + MemorySegment mt = invocation.getArgument(2); + MemorySegment fg = invocation.getArgument(3); + mp.set(ValueLayout.ADDRESS, 0L, scope.allocateUtf8String("/mount/point")); + mt.set(JAVA_INT, 0L, 1); + fg.set(JAVA_INT, 0L, 1); + return 0; + }); + + var fuseArgs = fuseImpl.parseArgs(List.of("fusefs", "-foo", "-bar", "/mount/point")); + + Assertions.assertTrue(fuseArgs.multiThreaded()); + Assertions.assertTrue(fuseArgs.toString().contains("arg[0] = fusefs")); + Assertions.assertTrue(fuseArgs.toString().contains("arg[1] = -foo")); + Assertions.assertTrue(fuseArgs.toString().contains("arg[2] = -bar")); + Assertions.assertTrue(fuseArgs.toString().contains("mountPoint = /mount/point")); + } + } @Nested @DisplayName("utimens") diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseArgs.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseArgs.java index 2b26b5e3..1db7e8df 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseArgs.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseArgs.java @@ -6,7 +6,7 @@ import java.lang.foreign.MemorySegment; import java.lang.foreign.ValueLayout; -public record FuseArgs(MemorySegment args, MemoryAddress mountPoint, boolean multiThreaded) { +record FuseArgs(MemorySegment args, MemoryAddress mountPoint, boolean multiThreaded) { @Override public String toString() { 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 1253d15f..f0ac8938 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 @@ -59,7 +59,8 @@ protected FuseMount mount(List args) { return new FuseMountImpl(fuse, ch, fuseArgs); } - private FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { + @VisibleForTesting + FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { var args = fuse_args.allocate(fuseScope); var argc = cmdLineArgs.size(); var argv = fuseScope.allocateArray(ValueLayout.ADDRESS, argc + 1L); 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 d86160e8..4eed3391 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 @@ -1,7 +1,7 @@ package org.cryptomator.jfuse.win.amd64; import org.cryptomator.jfuse.api.FuseOperations; -import org.cryptomator.jfuse.api.TimeSpec; +import org.cryptomator.jfuse.win.amd64.extr.fuse_h; import org.cryptomator.jfuse.win.amd64.extr.fuse_timespec; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; @@ -12,13 +12,41 @@ import org.mockito.Mockito; import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; import java.lang.foreign.MemorySession; +import java.lang.foreign.ValueLayout; import java.time.Instant; +import java.util.List; + +import static java.lang.foreign.ValueLayout.JAVA_INT; public class FuseImplTest { private FuseOperations fuseOps = Mockito.mock(FuseOperations.class); private FuseImpl fuseImpl = new FuseImpl(fuseOps); + @Test + public void testParseArgs() { + try (var fuseH = Mockito.mockStatic(fuse_h.class); + var scope = MemorySession.openConfined()) { + fuseH.when(() -> fuse_h.fuse_parse_cmdline(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).then(invocation -> { + MemorySegment mp = invocation.getArgument(1); + MemorySegment mt = invocation.getArgument(2); + MemorySegment fg = invocation.getArgument(3); + mp.set(ValueLayout.ADDRESS, 0L, scope.allocateUtf8String("/mount/point")); + mt.set(JAVA_INT, 0L, 1); + fg.set(JAVA_INT, 0L, 1); + return 0; + }); + + var fuseArgs = fuseImpl.parseArgs(List.of("fusefs", "-foo", "-bar", "/mount/point")); + + Assertions.assertTrue(fuseArgs.multiThreaded()); + Assertions.assertTrue(fuseArgs.toString().contains("arg[0] = fusefs")); + Assertions.assertTrue(fuseArgs.toString().contains("arg[1] = -foo")); + Assertions.assertTrue(fuseArgs.toString().contains("arg[2] = -bar")); + Assertions.assertTrue(fuseArgs.toString().contains("mountPoint = /mount/point")); + } + } @Nested @DisplayName("utimens") diff --git a/pom.xml b/pom.xml index 83d22cee..21097902 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ org.mockito - mockito-core + mockito-inline 4.7.0 test From 0b7d2964e36bcf43dd344b8fb8a434c7cf8fd700 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 5 Sep 2022 12:48:43 +0200 Subject: [PATCH 33/98] renamed fuse_operations struct, consistent with other implementations for other platforms [ci skip] --- .../cryptomator/jfuse/win/amd64/FuseImpl.java | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 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 f0ac8938..84d2eddb 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 @@ -23,10 +23,10 @@ public final class FuseImpl extends Fuse { private final FuseOperations delegate; - private final MemorySegment struct; + private final MemorySegment fuseOps; public FuseImpl(FuseOperations fuseOperations) { - this.struct = fuse_operations.allocate(fuseScope); + this.fuseOps = fuse_operations.allocate(fuseScope); this.delegate = fuseOperations; fuseOperations.supportedOperations().forEach(this::bind); } @@ -50,7 +50,7 @@ protected FuseMount mount(List args) { // TODO use explicit exception type throw new IllegalArgumentException("fuse_mount failed"); } - var fuse = fuse_h.fuse_new(ch, fuseArgs.args(), struct, struct.byteSize(), MemoryAddress.NULL); + var fuse = fuse_h.fuse_new(ch, fuseArgs.args(), fuseOps, fuseOps.byteSize(), MemoryAddress.NULL); if (MemoryAddress.NULL.equals(fuse)) { fuse_h.fuse_unmount(fuseArgs.mountPoint(), ch); // TODO use explicit exception type @@ -87,28 +87,28 @@ FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { private void bind(FuseOperations.Operation operation) { switch (operation) { - case INIT -> fuse_operations.access$set(struct, fuse_operations.init.allocate(this::init, fuseScope).address()); - case ACCESS -> fuse_operations.access$set(struct, fuse_operations.access.allocate(this::access, fuseScope).address()); - case CHMOD -> fuse_operations.chmod$set(struct, fuse_operations.chmod.allocate(this::chmod, fuseScope).address()); - case CREATE -> fuse_operations.create$set(struct, fuse_operations.create.allocate(this::create, fuseScope).address()); - case DESTROY -> fuse_operations.destroy$set(struct, fuse_operations.destroy.allocate(this::destroy, fuseScope).address()); - case GET_ATTR -> fuse_operations.getattr$set(struct, fuse_operations.getattr.allocate(this::getattr, fuseScope).address()); - case MKDIR -> fuse_operations.mkdir$set(struct, fuse_operations.mkdir.allocate(this::mkdir, fuseScope).address()); - case OPEN -> fuse_operations.open$set(struct, fuse_operations.open.allocate(this::open, fuseScope).address()); - case OPEN_DIR -> fuse_operations.opendir$set(struct, fuse_operations.opendir.allocate(this::opendir, fuseScope).address()); - case READ -> fuse_operations.read$set(struct, fuse_operations.read.allocate(this::read, fuseScope).address()); - case READ_DIR -> fuse_operations.readdir$set(struct, fuse_operations.readdir.allocate(this::readdir, fuseScope).address()); - case READLINK -> fuse_operations.readlink$set(struct, fuse_operations.readlink.allocate(this::readlink, fuseScope).address()); - case RELEASE -> fuse_operations.release$set(struct, fuse_operations.release.allocate(this::release, fuseScope).address()); - case RELEASE_DIR -> fuse_operations.releasedir$set(struct, fuse_operations.releasedir.allocate(this::releasedir, fuseScope).address()); - case RENAME -> fuse_operations.rename$set(struct, fuse_operations.rename.allocate(this::rename, fuseScope).address()); - case RMDIR -> fuse_operations.rmdir$set(struct, fuse_operations.rmdir.allocate(this::rmdir, fuseScope).address()); - case STATFS -> fuse_operations.statfs$set(struct, fuse_operations.statfs.allocate(this::statfs, fuseScope).address()); - case SYMLINK -> fuse_operations.symlink$set(struct, fuse_operations.symlink.allocate(this::symlink, fuseScope).address()); - case TRUNCATE -> fuse_operations.truncate$set(struct, fuse_operations.truncate.allocate(this::truncate, fuseScope).address()); - case UNLINK -> fuse_operations.unlink$set(struct, fuse_operations.unlink.allocate(this::unlink, fuseScope).address()); - case UTIMENS -> fuse_operations.utimens$set(struct, fuse_operations.utimens.allocate(this::utimens, fuseScope).address()); - case WRITE -> fuse_operations.write$set(struct, fuse_operations.write.allocate(this::write, fuseScope).address()); + case INIT -> fuse_operations.access$set(fuseOps, fuse_operations.init.allocate(this::init, fuseScope).address()); + case ACCESS -> fuse_operations.access$set(fuseOps, fuse_operations.access.allocate(this::access, fuseScope).address()); + case CHMOD -> fuse_operations.chmod$set(fuseOps, fuse_operations.chmod.allocate(this::chmod, fuseScope).address()); + case CREATE -> fuse_operations.create$set(fuseOps, fuse_operations.create.allocate(this::create, fuseScope).address()); + case DESTROY -> fuse_operations.destroy$set(fuseOps, fuse_operations.destroy.allocate(this::destroy, fuseScope).address()); + case GET_ATTR -> fuse_operations.getattr$set(fuseOps, fuse_operations.getattr.allocate(this::getattr, fuseScope).address()); + case MKDIR -> fuse_operations.mkdir$set(fuseOps, fuse_operations.mkdir.allocate(this::mkdir, fuseScope).address()); + case OPEN -> fuse_operations.open$set(fuseOps, fuse_operations.open.allocate(this::open, fuseScope).address()); + case OPEN_DIR -> fuse_operations.opendir$set(fuseOps, fuse_operations.opendir.allocate(this::opendir, fuseScope).address()); + case READ -> fuse_operations.read$set(fuseOps, fuse_operations.read.allocate(this::read, fuseScope).address()); + case READ_DIR -> fuse_operations.readdir$set(fuseOps, fuse_operations.readdir.allocate(this::readdir, fuseScope).address()); + case READLINK -> fuse_operations.readlink$set(fuseOps, fuse_operations.readlink.allocate(this::readlink, fuseScope).address()); + case RELEASE -> fuse_operations.release$set(fuseOps, fuse_operations.release.allocate(this::release, fuseScope).address()); + case RELEASE_DIR -> fuse_operations.releasedir$set(fuseOps, fuse_operations.releasedir.allocate(this::releasedir, fuseScope).address()); + case RENAME -> fuse_operations.rename$set(fuseOps, fuse_operations.rename.allocate(this::rename, fuseScope).address()); + case RMDIR -> fuse_operations.rmdir$set(fuseOps, fuse_operations.rmdir.allocate(this::rmdir, fuseScope).address()); + case STATFS -> fuse_operations.statfs$set(fuseOps, fuse_operations.statfs.allocate(this::statfs, fuseScope).address()); + case SYMLINK -> fuse_operations.symlink$set(fuseOps, fuse_operations.symlink.allocate(this::symlink, fuseScope).address()); + case TRUNCATE -> fuse_operations.truncate$set(fuseOps, fuse_operations.truncate.allocate(this::truncate, fuseScope).address()); + case UNLINK -> fuse_operations.unlink$set(fuseOps, fuse_operations.unlink.allocate(this::unlink, fuseScope).address()); + case UTIMENS -> fuse_operations.utimens$set(fuseOps, fuse_operations.utimens.allocate(this::utimens, fuseScope).address()); + case WRITE -> fuse_operations.write$set(fuseOps, fuse_operations.write.allocate(this::write, fuseScope).address()); } } From 7ddffd72151a1d78d1b16e9ac555f79447676bca Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 5 Sep 2022 13:25:18 +0200 Subject: [PATCH 34/98] Added MountFailedException --- .../src/main/java/org/cryptomator/jfuse/api/Fuse.java | 6 ++++-- .../cryptomator/jfuse/api/MountFailedException.java | 9 +++++++++ .../jfuse/examples/HelloWorldFileSystem.java | 4 ++-- .../jfuse/examples/PosixMirrorFileSystem.java | 4 ++-- .../jfuse/examples/WindowsMirrorFileSystem.java | 4 ++-- .../org/cryptomator/jfuse/linux/aarch64/FuseImpl.java | 11 ++++------- .../org/cryptomator/jfuse/linux/amd64/FuseImpl.java | 11 ++++------- .../main/java/org/cryptomator/jfuse/mac/FuseImpl.java | 10 ++++------ .../java/org/cryptomator/jfuse/tests/MirrorIT.java | 4 ++-- .../org/cryptomator/jfuse/win/amd64/FuseImpl.java | 11 +++++------ 10 files changed, 38 insertions(+), 36 deletions(-) create mode 100644 jfuse-api/src/main/java/org/cryptomator/jfuse/api/MountFailedException.java diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java index c33c2d20..864ff50a 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java @@ -53,10 +53,12 @@ public static FuseBuilder builder() { * @param progName The program name used to construct a usage message and to derive a fallback for -ofsname=... * @param mountPoint mount point * @param flags Additional flags. Use flag -help to get a list of available flags + * @throws MountFailedException If mounting failed + * @throws IllegalArgumentException If providing unsupported mount flags */ @Blocking @MustBeInvokedByOverriders - public void mount(String progName, Path mountPoint, String... flags) { + public void mount(String progName, Path mountPoint, String... flags) throws MountFailedException, IllegalArgumentException { FuseMount lock = new UnmountedFuseMount(); if (!mount.compareAndSet(UNMOUNTED, lock)) { throw new IllegalStateException("Already mounted"); @@ -93,7 +95,7 @@ private int fuseLoop() { } @Blocking - protected abstract FuseMount mount(List args); + protected abstract FuseMount mount(List args) throws MountFailedException, IllegalArgumentException; /** * Unmounts (if needed) this fuse file system and frees up system resources. diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/MountFailedException.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/MountFailedException.java new file mode 100644 index 00000000..e1378ffc --- /dev/null +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/MountFailedException.java @@ -0,0 +1,9 @@ +package org.cryptomator.jfuse.api; + +public class MountFailedException extends Exception { + + public MountFailedException(String message) { + super(message); + } + +} diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java index 51807d55..cd47c1b9 100644 --- a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java @@ -6,6 +6,7 @@ import org.cryptomator.jfuse.api.Fuse; import org.cryptomator.jfuse.api.FuseConnInfo; import org.cryptomator.jfuse.api.FuseOperations; +import org.cryptomator.jfuse.api.MountFailedException; import org.cryptomator.jfuse.api.Stat; import org.cryptomator.jfuse.api.Statvfs; import org.slf4j.Logger; @@ -17,7 +18,6 @@ import java.nio.file.Path; import java.util.EnumSet; import java.util.Set; -import java.util.concurrent.CompletionException; import java.util.concurrent.TimeoutException; import java.util.stream.Stream; @@ -46,7 +46,7 @@ public static void main(String[] args) { LOG.info("Mounted to {}.", mountPoint); LOG.info("Enter a anything to unmount..."); System.in.read(); - } catch (TimeoutException | CompletionException e) { + } catch (MountFailedException | TimeoutException e) { LOG.error("Un/Mounting failed. ", e); System.exit(1); } catch (IOException e) { diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/PosixMirrorFileSystem.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/PosixMirrorFileSystem.java index 2bf5a8fa..05da530b 100644 --- a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/PosixMirrorFileSystem.java +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/PosixMirrorFileSystem.java @@ -4,6 +4,7 @@ import org.cryptomator.jfuse.api.FileInfo; import org.cryptomator.jfuse.api.FileModes; import org.cryptomator.jfuse.api.Fuse; +import org.cryptomator.jfuse.api.MountFailedException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,7 +18,6 @@ import java.nio.file.attribute.PosixFileAttributes; import java.nio.file.attribute.PosixFilePermission; import java.util.Set; -import java.util.concurrent.CompletionException; import java.util.concurrent.TimeoutException; public final class PosixMirrorFileSystem extends AbstractMirrorFileSystem { @@ -37,7 +37,7 @@ public static void main(String[] args) { LOG.info("Mounted to {}.", mountPoint); LOG.info("Enter a anything to unmount..."); System.in.read(); - } catch (TimeoutException | CompletionException e) { + } catch (MountFailedException | TimeoutException e) { LOG.error("Un/Mounting failed. ", e); System.exit(1); } catch (IOException e) { diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/WindowsMirrorFileSystem.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/WindowsMirrorFileSystem.java index 5a1249c1..16f52a34 100644 --- a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/WindowsMirrorFileSystem.java +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/WindowsMirrorFileSystem.java @@ -2,6 +2,7 @@ import org.cryptomator.jfuse.api.Errno; import org.cryptomator.jfuse.api.Fuse; +import org.cryptomator.jfuse.api.MountFailedException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,7 +16,6 @@ import java.nio.file.attribute.FileAttribute; import java.nio.file.attribute.PosixFilePermission; import java.util.Set; -import java.util.concurrent.CompletionException; import java.util.concurrent.TimeoutException; public final class WindowsMirrorFileSystem extends AbstractMirrorFileSystem { @@ -35,7 +35,7 @@ public static void main(String[] args) { LOG.info("Mounted to {}.", mountPoint); LOG.info("Enter a anything to unmount..."); System.in.read(); - } catch (TimeoutException | CompletionException e) { + } catch (MountFailedException | TimeoutException e) { LOG.error("Un/Mounting failed. ", e); System.exit(1); } catch (IOException 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 1c1e035c..103034f9 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 @@ -3,6 +3,7 @@ import org.cryptomator.jfuse.api.Fuse; import org.cryptomator.jfuse.api.FuseMount; import org.cryptomator.jfuse.api.FuseOperations; +import org.cryptomator.jfuse.api.MountFailedException; 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; @@ -32,18 +33,14 @@ public FuseImpl(FuseOperations fuseOperations) { } @Override - protected FuseMount mount(List args) { + protected FuseMount mount(List args) throws MountFailedException { var fuseArgs = parseArgs(args); var fuse = fuse_h.fuse_new(fuseArgs.args(), fuseOps, fuseOps.byteSize(), MemoryAddress.NULL); if (MemoryAddress.NULL.equals(fuse)) { - // TODO use explicit exception type - throw new IllegalArgumentException("fuse_new failed"); + throw new MountFailedException("fuse_new failed"); } - //var session = fuse_h.fuse_get_session(fuse); - //var mountPointStr = fuse_cmdline_opts.mountpoint$get(args.opts()); if (fuse_h.fuse_mount(fuse, fuseArgs.mountPoint()) != 0) { - // TODO use explicit exception type - throw new IllegalArgumentException("fuse_mount failed "); + throw new MountFailedException("fuse_mount failed "); } return new FuseMountImpl(fuse, fuseArgs); } 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 1a41c44e..6fe0f743 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 @@ -3,6 +3,7 @@ import org.cryptomator.jfuse.api.Fuse; import org.cryptomator.jfuse.api.FuseMount; import org.cryptomator.jfuse.api.FuseOperations; +import org.cryptomator.jfuse.api.MountFailedException; 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; @@ -32,18 +33,14 @@ public FuseImpl(FuseOperations fuseOperations) { } @Override - protected FuseMount mount(List args) { + protected FuseMount mount(List args) throws MountFailedException { var fuseArgs = parseArgs(args); var fuse = fuse_h.fuse_new(fuseArgs.args(), fuseOps, fuseOps.byteSize(), MemoryAddress.NULL); if (MemoryAddress.NULL.equals(fuse)) { - // TODO use explicit exception type - throw new IllegalArgumentException("fuse_new failed"); + throw new MountFailedException("fuse_new failed"); } - //var session = fuse_h.fuse_get_session(fuse); - //var mountPointStr = fuse_cmdline_opts.mountpoint$get(args.opts()); if (fuse_h.fuse_mount(fuse, fuseArgs.mountPoint()) != 0) { - // TODO use explicit exception type - throw new IllegalArgumentException("fuse_mount failed "); + throw new MountFailedException("fuse_mount failed"); } return new FuseMountImpl(fuse, fuseArgs); } diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java index 37ff0e2d..31c0ca99 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java @@ -3,6 +3,7 @@ import org.cryptomator.jfuse.api.Fuse; import org.cryptomator.jfuse.api.FuseMount; import org.cryptomator.jfuse.api.FuseOperations; +import org.cryptomator.jfuse.api.MountFailedException; import org.cryptomator.jfuse.mac.extr.fuse_args; import org.cryptomator.jfuse.mac.extr.fuse_h; import org.cryptomator.jfuse.mac.extr.fuse_operations; @@ -32,19 +33,16 @@ public FuseImpl(FuseOperations fuseOperations) { } @Override - protected FuseMount mount(List args) { + protected FuseMount mount(List args) throws MountFailedException { var fuseArgs = parseArgs(args); var ch = fuse_h.fuse_mount(fuseArgs.mountPoint(), fuseArgs.args()); if (MemoryAddress.NULL.equals(ch)) { - // TODO any cleanup needed? - // TODO use explicit exception type - throw new IllegalArgumentException("fuse_mount failed"); + throw new MountFailedException("fuse_mount failed"); } var fuse = fuse_h.fuse_new(ch, fuseArgs.args(), fuseOps, fuseOps.byteSize(), MemoryAddress.NULL); if (MemoryAddress.NULL.equals(fuse)) { fuse_h.fuse_unmount(fuseArgs.mountPoint(), ch); - // TODO use explicit exception type - throw new IllegalArgumentException("fuse_new failed"); + throw new MountFailedException("fuse_new failed"); } return new FuseMountImpl(fuse, ch, fuseArgs); } 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 5fca52c5..8f3f459e 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.MountFailedException; import org.cryptomator.jfuse.examples.AbstractMirrorFileSystem; import org.cryptomator.jfuse.examples.PosixMirrorFileSystem; import org.cryptomator.jfuse.examples.WindowsMirrorFileSystem; @@ -30,7 +31,6 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class MirrorIT { @@ -44,7 +44,7 @@ public class MirrorIT { private Fuse fuse; @BeforeAll - public void setup(@TempDir Path tmpDir) throws IOException, InterruptedException { + public void setup(@TempDir Path tmpDir) throws IOException, InterruptedException, MountFailedException { var builder = Fuse.builder(); orig = tmpDir.resolve("orig"); Files.createDirectories(orig); 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 84d2eddb..71fa5ee4 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 @@ -3,6 +3,7 @@ import org.cryptomator.jfuse.api.Fuse; import org.cryptomator.jfuse.api.FuseMount; import org.cryptomator.jfuse.api.FuseOperations; +import org.cryptomator.jfuse.api.MountFailedException; import org.cryptomator.jfuse.win.amd64.extr.fuse_args; import org.cryptomator.jfuse.win.amd64.extr.fuse_h; import org.cryptomator.jfuse.win.amd64.extr.fuse_operations; @@ -32,7 +33,7 @@ public FuseImpl(FuseOperations fuseOperations) { } @Override - public void mount(String progName, Path mountPoint, String... flags) { + public void mount(String progName, Path mountPoint, String... flags) throws MountFailedException { var adjustedMP = mountPoint; if (mountPoint.compareTo(mountPoint.getRoot()) == 0 && mountPoint.isAbsolute()) { //winfsp accepts only drive letters written in drive relative notation @@ -42,19 +43,17 @@ public void mount(String progName, Path mountPoint, String... flags) { } @Override - protected FuseMount mount(List args) { + protected FuseMount mount(List args) throws MountFailedException { var fuseArgs = parseArgs(args); var ch = fuse_h.fuse_mount(fuseArgs.mountPoint(), fuseArgs.args()); if (MemoryAddress.NULL.equals(ch)) { // TODO any cleanup needed? - // TODO use explicit exception type - throw new IllegalArgumentException("fuse_mount failed"); + throw new MountFailedException("fuse_mount failed"); } var fuse = fuse_h.fuse_new(ch, fuseArgs.args(), fuseOps, fuseOps.byteSize(), MemoryAddress.NULL); if (MemoryAddress.NULL.equals(fuse)) { fuse_h.fuse_unmount(fuseArgs.mountPoint(), ch); - // TODO use explicit exception type - throw new IllegalArgumentException("fuse_new failed"); + throw new MountFailedException("fuse_new failed"); } return new FuseMountImpl(fuse, ch, fuseArgs); } From 0972c503e17fae4c6d937c811a0fceaf0d71d52c Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 5 Sep 2022 13:26:02 +0200 Subject: [PATCH 35/98] marked interface as internal [ci skip] --- .../src/main/java/org/cryptomator/jfuse/api/FuseMount.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseMount.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseMount.java index 29cba034..b3213ce8 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseMount.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseMount.java @@ -1,7 +1,9 @@ package org.cryptomator.jfuse.api; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Blocking; +@ApiStatus.Internal public interface FuseMount { /** From a0c574dd214b90449fd6ecd3c8d17f09a283dd0a Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 5 Sep 2022 13:28:04 +0200 Subject: [PATCH 36/98] call `fuse_lib_help` and cancel mounting, when detecting corresponding flags --- jfuse-linux-aarch64/pom.xml | 1 + .../jfuse/linux/aarch64/FuseImpl.java | 4 ++++ .../jfuse/linux/aarch64/extr/constants$0.java | 7 ++++++ .../jfuse/linux/aarch64/extr/fuse_h.java | 11 +++++++++ .../jfuse/linux/aarch64/FuseImplTest.java | 22 ++++++++++++++++++ jfuse-linux-amd64/pom.xml | 1 + .../jfuse/linux/amd64/FuseImpl.java | 4 ++++ .../jfuse/linux/amd64/extr/constants$0.java | 7 ++++++ .../jfuse/linux/amd64/extr/fuse_h.java | 11 +++++++++ .../jfuse/linux/amd64/FuseImplTest.java | 23 +++++++++++++++++++ 10 files changed, 91 insertions(+) diff --git a/jfuse-linux-aarch64/pom.xml b/jfuse-linux-aarch64/pom.xml index f60adc8d..2523b5b1 100644 --- a/jfuse-linux-aarch64/pom.xml +++ b/jfuse-linux-aarch64/pom.xml @@ -98,6 +98,7 @@ fuse_get_context fuse_exit + fuse_lib_help fuse_new fuse_mount fuse_get_session 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 103034f9..3d7227a5 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 @@ -64,6 +64,10 @@ FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { if (parseResult != 0) { throw new IllegalArgumentException("fuse_parse_cmdline failed to parse " + String.join(" ", cmdLineArgs)); } + if (fuse_cmdline_opts.show_help$get(opts) == 1) { + fuse_h.fuse_lib_help(args); + throw new IllegalArgumentException("Flags contained -h or --help. Processing cancelled after printing help"); + } return new FuseArgs(args, opts); } 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 0e68760b..e2b90e3e 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 @@ -19,6 +19,13 @@ class constants$0 { static final MethodHandle fuse_fill_dir_t$MH = RuntimeHelper.downcallHandle( constants$0.fuse_fill_dir_t$FUNC ); + static final FunctionDescriptor fuse_lib_help$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 FunctionDescriptor fuse_new$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, 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 91398d7e..b1fa0b9d 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 @@ -24,6 +24,17 @@ public static int FUSE_READDIR_PLUS() { public static int FUSE_FILL_DIR_PLUS() { return (int)2L; } + public static MethodHandle fuse_lib_help$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_lib_help$MH,"fuse_lib_help"); + } + public static void fuse_lib_help ( Addressable args) { + var mh$ = fuse_lib_help$MH(); + try { + mh$.invokeExact(args); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } public static MethodHandle fuse_new$MH() { return RuntimeHelper.requireNonNull(constants$0.fuse_new$MH,"fuse_new"); } 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 cbb5a7a9..fbe0593e 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 @@ -3,6 +3,7 @@ import org.cryptomator.jfuse.api.FuseOperations; import org.cryptomator.jfuse.api.TimeSpec; 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; @@ -12,6 +13,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.Answers; import org.mockito.Mockito; import java.lang.foreign.MemoryAddress; @@ -25,7 +28,26 @@ public class FuseImplTest { private FuseOperations fuseOps = Mockito.mock(FuseOperations.class); private FuseImpl fuseImpl = new FuseImpl(fuseOps); + @ParameterizedTest(name = "fusefs {0}") + @DisplayName("parseArgs with -h/--help") + @ValueSource(strings = {"--help", "-h"}) + public void testParseArgsHelp(String 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 -> { + MemorySegment opts = invocation.getArgument(1); + fuse_cmdline_opts.show_help$set(opts, 1); + return 0; + }); + fuseH.when(() -> fuse_h.fuse_lib_help(Mockito.any())).thenAnswer(Answers.RETURNS_DEFAULTS); + + Assertions.assertThrows(IllegalArgumentException.class, () -> fuseImpl.parseArgs(List.of("fusefs", arg))); + fuseH.verify(() -> fuse_h.fuse_lib_help(Mockito.any())); + } + } + @Test + @DisplayName("parseArgs") public void testParseArgs() { try (var fuseLowlevelH = Mockito.mockStatic(fuse_lowlevel_h.class); var scope = MemorySession.openConfined()) { diff --git a/jfuse-linux-amd64/pom.xml b/jfuse-linux-amd64/pom.xml index 4634ea65..83daf3d3 100644 --- a/jfuse-linux-amd64/pom.xml +++ b/jfuse-linux-amd64/pom.xml @@ -98,6 +98,7 @@ fuse_get_context fuse_exit + fuse_lib_help fuse_new fuse_mount fuse_get_session 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 6fe0f743..a3d1b051 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 @@ -64,6 +64,10 @@ FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { if (parseResult != 0) { throw new IllegalArgumentException("fuse_parse_cmdline failed to parse " + String.join(" ", cmdLineArgs)); } + if (fuse_cmdline_opts.show_help$get(opts) == 1) { + fuse_h.fuse_lib_help(args); + throw new IllegalArgumentException("Flags contained -h or --help. Processing cancelled after printing help"); + } return new FuseArgs(args, opts); } 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 8f43f3bd..f326ff5c 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 @@ -19,6 +19,13 @@ class constants$0 { static final MethodHandle fuse_fill_dir_t$MH = RuntimeHelper.downcallHandle( constants$0.fuse_fill_dir_t$FUNC ); + static final FunctionDescriptor fuse_lib_help$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 FunctionDescriptor fuse_new$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, 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 485bd2de..5951d6c3 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 @@ -24,6 +24,17 @@ public static int FUSE_READDIR_PLUS() { public static int FUSE_FILL_DIR_PLUS() { return (int)2L; } + public static MethodHandle fuse_lib_help$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_lib_help$MH,"fuse_lib_help"); + } + public static void fuse_lib_help ( Addressable args) { + var mh$ = fuse_lib_help$MH(); + try { + mh$.invokeExact(args); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } public static MethodHandle fuse_new$MH() { return RuntimeHelper.requireNonNull(constants$0.fuse_new$MH,"fuse_new"); } 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 38965df0..145a6248 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 @@ -3,6 +3,7 @@ import org.cryptomator.jfuse.api.FuseOperations; import org.cryptomator.jfuse.api.TimeSpec; 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; @@ -12,6 +13,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.Answers; import org.mockito.Mockito; import java.lang.foreign.MemoryAddress; @@ -24,7 +27,27 @@ public class FuseImplTest { private FuseOperations fuseOps = Mockito.mock(FuseOperations.class); private FuseImpl fuseImpl = new FuseImpl(fuseOps); + + @ParameterizedTest(name = "fusefs {0}") + @DisplayName("parseArgs with -h/--help") + @ValueSource(strings = {"--help", "-h"}) + public void testParseArgsHelp(String 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 -> { + MemorySegment opts = invocation.getArgument(1); + fuse_cmdline_opts.show_help$set(opts, 1); + return 0; + }); + fuseH.when(() -> fuse_h.fuse_lib_help(Mockito.any())).thenAnswer(Answers.RETURNS_DEFAULTS); + + Assertions.assertThrows(IllegalArgumentException.class, () -> fuseImpl.parseArgs(List.of("fusefs", arg))); + fuseH.verify(() -> fuse_h.fuse_lib_help(Mockito.any())); + } + } + @Test + @DisplayName("parseArgs") public void testParseArgs() { try (var fuseLowlevelH = Mockito.mockStatic(fuse_lowlevel_h.class); var scope = MemorySession.openConfined()) { From 3fe1bb626d7cafac2dd9c9cd6dc21681f70c2f1d Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 5 Sep 2022 13:28:33 +0200 Subject: [PATCH 37/98] fixed test --- .../main/java/org/cryptomator/jfuse/linux/aarch64/FuseArgs.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 7ad723b9..9d4014e3 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 @@ -20,7 +20,7 @@ public String toString() { } sb.append("mountPoint = ").append(mountPoint().getUtf8String(0)); sb.append("debug = ").append(fuse_cmdline_opts.debug$get(cmdLineOpts)); - sb.append("singlethreaded = ").append(fuse_cmdline_opts.singlethread$get(cmdLineOpts)); + sb.append("singlethreaded = ").append(!multithreaded()); return sb.toString(); } From a7a4c87f34ba76e46bd808c802d2a0880cd2891b Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 5 Sep 2022 13:29:36 +0200 Subject: [PATCH 38/98] remove unused functions and structs from Linux/Mac implementations --- jfuse-linux-aarch64/pom.xml | 6 +- .../jfuse/linux/aarch64/extr/constants$0.java | 7 - .../jfuse/linux/aarch64/extr/constants$1.java | 23 +--- .../linux/aarch64/extr/fuse_context.java | 129 ------------------ .../jfuse/linux/aarch64/extr/fuse_h.java | 24 +--- jfuse-linux-amd64/pom.xml | 6 +- .../jfuse/linux/amd64/extr/constants$0.java | 7 - .../jfuse/linux/amd64/extr/constants$1.java | 23 +--- .../jfuse/linux/amd64/extr/fuse_context.java | 129 ------------------ .../jfuse/linux/amd64/extr/fuse_h.java | 24 +--- jfuse-mac/pom.xml | 6 +- .../jfuse/mac/extr/constants$1.java | 16 --- .../jfuse/mac/extr/fuse_context.java | 129 ------------------ .../cryptomator/jfuse/mac/extr/fuse_h.java | 22 --- 14 files changed, 19 insertions(+), 532 deletions(-) delete mode 100644 jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_context.java delete mode 100644 jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_context.java delete mode 100644 jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_context.java diff --git a/jfuse-linux-aarch64/pom.xml b/jfuse-linux-aarch64/pom.xml index 2523b5b1..2f79c198 100644 --- a/jfuse-linux-aarch64/pom.xml +++ b/jfuse-linux-aarch64/pom.xml @@ -94,16 +94,13 @@ FUSE_USE_VERSION=35 - fuse_main_real - fuse_get_context - fuse_exit - fuse_lib_help fuse_new fuse_mount fuse_get_session fuse_loop fuse_loop_mt + fuse_exit fuse_unmount fuse_destroy @@ -113,7 +110,6 @@ fuse_operations fuse_file_info - fuse_context stat statvfs timespec 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 e2b90e3e..57a7d35a 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 @@ -51,13 +51,6 @@ class constants$0 { "fuse_unmount", constants$0.fuse_unmount$FUNC ); - static final FunctionDescriptor fuse_destroy$FUNC = FunctionDescriptor.ofVoid( - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle fuse_destroy$MH = RuntimeHelper.downcallHandle( - "fuse_destroy", - constants$0.fuse_destroy$FUNC - ); } 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 a2f43106..6640ad95 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,6 +9,13 @@ import static java.lang.foreign.ValueLayout.*; class constants$1 { + static final FunctionDescriptor fuse_destroy$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_destroy$MH = RuntimeHelper.downcallHandle( + "fuse_destroy", + constants$1.fuse_destroy$FUNC + ); static final FunctionDescriptor fuse_loop$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, Constants$root.C_POINTER$LAYOUT ); @@ -31,22 +38,6 @@ class constants$1 { "fuse_loop_mt", constants$1.fuse_loop_mt$FUNC ); - static final FunctionDescriptor fuse_get_context$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT); - static final MethodHandle fuse_get_context$MH = RuntimeHelper.downcallHandle( - "fuse_get_context", - constants$1.fuse_get_context$FUNC - ); - static final FunctionDescriptor fuse_main_real$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, - Constants$root.C_INT$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_main_real$MH = RuntimeHelper.downcallHandle( - "fuse_main_real", - constants$1.fuse_main_real$FUNC - ); static final FunctionDescriptor fuse_get_session$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT ); diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_context.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_context.java deleted file mode 100644 index a2f1d546..00000000 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/extr/fuse_context.java +++ /dev/null @@ -1,129 +0,0 @@ -// 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.*; -public class fuse_context { - - static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( - Constants$root.C_POINTER$LAYOUT.withName("fuse"), - Constants$root.C_INT$LAYOUT.withName("uid"), - Constants$root.C_INT$LAYOUT.withName("gid"), - Constants$root.C_INT$LAYOUT.withName("pid"), - MemoryLayout.paddingLayout(32), - Constants$root.C_POINTER$LAYOUT.withName("private_data"), - Constants$root.C_INT$LAYOUT.withName("umask"), - MemoryLayout.paddingLayout(32) - ).withName("fuse_context"); - public static MemoryLayout $LAYOUT() { - return fuse_context.$struct$LAYOUT; - } - static final VarHandle fuse$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fuse")); - public static VarHandle fuse$VH() { - return fuse_context.fuse$VH; - } - public static MemoryAddress fuse$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_context.fuse$VH.get(seg); - } - public static void fuse$set( MemorySegment seg, MemoryAddress x) { - fuse_context.fuse$VH.set(seg, x); - } - public static MemoryAddress fuse$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_context.fuse$VH.get(seg.asSlice(index*sizeof())); - } - public static void fuse$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_context.fuse$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle uid$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("uid")); - public static VarHandle uid$VH() { - return fuse_context.uid$VH; - } - public static int uid$get(MemorySegment seg) { - return (int)fuse_context.uid$VH.get(seg); - } - public static void uid$set( MemorySegment seg, int x) { - fuse_context.uid$VH.set(seg, x); - } - public static int uid$get(MemorySegment seg, long index) { - return (int)fuse_context.uid$VH.get(seg.asSlice(index*sizeof())); - } - public static void uid$set(MemorySegment seg, long index, int x) { - fuse_context.uid$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle gid$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("gid")); - public static VarHandle gid$VH() { - return fuse_context.gid$VH; - } - public static int gid$get(MemorySegment seg) { - return (int)fuse_context.gid$VH.get(seg); - } - public static void gid$set( MemorySegment seg, int x) { - fuse_context.gid$VH.set(seg, x); - } - public static int gid$get(MemorySegment seg, long index) { - return (int)fuse_context.gid$VH.get(seg.asSlice(index*sizeof())); - } - public static void gid$set(MemorySegment seg, long index, int x) { - fuse_context.gid$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle pid$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("pid")); - public static VarHandle pid$VH() { - return fuse_context.pid$VH; - } - public static int pid$get(MemorySegment seg) { - return (int)fuse_context.pid$VH.get(seg); - } - public static void pid$set( MemorySegment seg, int x) { - fuse_context.pid$VH.set(seg, x); - } - public static int pid$get(MemorySegment seg, long index) { - return (int)fuse_context.pid$VH.get(seg.asSlice(index*sizeof())); - } - public static void pid$set(MemorySegment seg, long index, int x) { - fuse_context.pid$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle private_data$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("private_data")); - public static VarHandle private_data$VH() { - return fuse_context.private_data$VH; - } - public static MemoryAddress private_data$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_context.private_data$VH.get(seg); - } - public static void private_data$set( MemorySegment seg, MemoryAddress x) { - fuse_context.private_data$VH.set(seg, x); - } - public static MemoryAddress private_data$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_context.private_data$VH.get(seg.asSlice(index*sizeof())); - } - public static void private_data$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_context.private_data$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle umask$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("umask")); - public static VarHandle umask$VH() { - return fuse_context.umask$VH; - } - public static int umask$get(MemorySegment seg) { - return (int)fuse_context.umask$VH.get(seg); - } - public static void umask$set( MemorySegment seg, int x) { - fuse_context.umask$VH.set(seg, x); - } - public static int umask$get(MemorySegment seg, long index) { - return (int)fuse_context.umask$VH.get(seg.asSlice(index*sizeof())); - } - public static void umask$set(MemorySegment seg, long index, int x) { - fuse_context.umask$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-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 b1fa0b9d..c2f61f2d 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 @@ -69,7 +69,7 @@ public static void fuse_unmount ( Addressable f) { } } public static MethodHandle fuse_destroy$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_destroy$MH,"fuse_destroy"); + return RuntimeHelper.requireNonNull(constants$1.fuse_destroy$MH,"fuse_destroy"); } public static void fuse_destroy ( Addressable f) { var mh$ = fuse_destroy$MH(); @@ -112,28 +112,6 @@ public static int fuse_loop_mt ( Addressable f, Addressable config) { throw new AssertionError("should not reach here", ex$); } } - public static MethodHandle fuse_get_context$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse_get_context$MH,"fuse_get_context"); - } - public static MemoryAddress fuse_get_context () { - var mh$ = fuse_get_context$MH(); - try { - return (java.lang.foreign.MemoryAddress)mh$.invokeExact(); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - } - public static MethodHandle fuse_main_real$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse_main_real$MH,"fuse_main_real"); - } - public static int fuse_main_real ( int argc, Addressable argv, Addressable op, long op_size, Addressable private_data) { - var mh$ = fuse_main_real$MH(); - try { - return (int)mh$.invokeExact(argc, argv, op, op_size, private_data); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - } public static MethodHandle fuse_get_session$MH() { return RuntimeHelper.requireNonNull(constants$1.fuse_get_session$MH,"fuse_get_session"); } diff --git a/jfuse-linux-amd64/pom.xml b/jfuse-linux-amd64/pom.xml index 83daf3d3..726db23b 100644 --- a/jfuse-linux-amd64/pom.xml +++ b/jfuse-linux-amd64/pom.xml @@ -94,16 +94,13 @@ FUSE_USE_VERSION=35 - fuse_main_real - fuse_get_context - fuse_exit - fuse_lib_help fuse_new fuse_mount fuse_get_session fuse_loop fuse_loop_mt + fuse_exit fuse_unmount fuse_destroy @@ -113,7 +110,6 @@ fuse_operations fuse_file_info - fuse_context stat statvfs timespec 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 f326ff5c..8ee42214 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 @@ -51,13 +51,6 @@ class constants$0 { "fuse_unmount", constants$0.fuse_unmount$FUNC ); - static final FunctionDescriptor fuse_destroy$FUNC = FunctionDescriptor.ofVoid( - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle fuse_destroy$MH = RuntimeHelper.downcallHandle( - "fuse_destroy", - constants$0.fuse_destroy$FUNC - ); } 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 dfa97a6e..a6d7fef2 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,6 +9,13 @@ import static java.lang.foreign.ValueLayout.*; class constants$1 { + static final FunctionDescriptor fuse_destroy$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_destroy$MH = RuntimeHelper.downcallHandle( + "fuse_destroy", + constants$1.fuse_destroy$FUNC + ); static final FunctionDescriptor fuse_loop$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, Constants$root.C_POINTER$LAYOUT ); @@ -31,22 +38,6 @@ class constants$1 { "fuse_loop_mt", constants$1.fuse_loop_mt$FUNC ); - static final FunctionDescriptor fuse_get_context$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT); - static final MethodHandle fuse_get_context$MH = RuntimeHelper.downcallHandle( - "fuse_get_context", - constants$1.fuse_get_context$FUNC - ); - static final FunctionDescriptor fuse_main_real$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, - Constants$root.C_INT$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_main_real$MH = RuntimeHelper.downcallHandle( - "fuse_main_real", - constants$1.fuse_main_real$FUNC - ); static final FunctionDescriptor fuse_get_session$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT ); diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_context.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_context.java deleted file mode 100644 index 1f25faca..00000000 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/extr/fuse_context.java +++ /dev/null @@ -1,129 +0,0 @@ -// 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.*; -public class fuse_context { - - static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( - Constants$root.C_POINTER$LAYOUT.withName("fuse"), - Constants$root.C_INT$LAYOUT.withName("uid"), - Constants$root.C_INT$LAYOUT.withName("gid"), - Constants$root.C_INT$LAYOUT.withName("pid"), - MemoryLayout.paddingLayout(32), - Constants$root.C_POINTER$LAYOUT.withName("private_data"), - Constants$root.C_INT$LAYOUT.withName("umask"), - MemoryLayout.paddingLayout(32) - ).withName("fuse_context"); - public static MemoryLayout $LAYOUT() { - return fuse_context.$struct$LAYOUT; - } - static final VarHandle fuse$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fuse")); - public static VarHandle fuse$VH() { - return fuse_context.fuse$VH; - } - public static MemoryAddress fuse$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_context.fuse$VH.get(seg); - } - public static void fuse$set( MemorySegment seg, MemoryAddress x) { - fuse_context.fuse$VH.set(seg, x); - } - public static MemoryAddress fuse$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_context.fuse$VH.get(seg.asSlice(index*sizeof())); - } - public static void fuse$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_context.fuse$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle uid$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("uid")); - public static VarHandle uid$VH() { - return fuse_context.uid$VH; - } - public static int uid$get(MemorySegment seg) { - return (int)fuse_context.uid$VH.get(seg); - } - public static void uid$set( MemorySegment seg, int x) { - fuse_context.uid$VH.set(seg, x); - } - public static int uid$get(MemorySegment seg, long index) { - return (int)fuse_context.uid$VH.get(seg.asSlice(index*sizeof())); - } - public static void uid$set(MemorySegment seg, long index, int x) { - fuse_context.uid$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle gid$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("gid")); - public static VarHandle gid$VH() { - return fuse_context.gid$VH; - } - public static int gid$get(MemorySegment seg) { - return (int)fuse_context.gid$VH.get(seg); - } - public static void gid$set( MemorySegment seg, int x) { - fuse_context.gid$VH.set(seg, x); - } - public static int gid$get(MemorySegment seg, long index) { - return (int)fuse_context.gid$VH.get(seg.asSlice(index*sizeof())); - } - public static void gid$set(MemorySegment seg, long index, int x) { - fuse_context.gid$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle pid$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("pid")); - public static VarHandle pid$VH() { - return fuse_context.pid$VH; - } - public static int pid$get(MemorySegment seg) { - return (int)fuse_context.pid$VH.get(seg); - } - public static void pid$set( MemorySegment seg, int x) { - fuse_context.pid$VH.set(seg, x); - } - public static int pid$get(MemorySegment seg, long index) { - return (int)fuse_context.pid$VH.get(seg.asSlice(index*sizeof())); - } - public static void pid$set(MemorySegment seg, long index, int x) { - fuse_context.pid$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle private_data$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("private_data")); - public static VarHandle private_data$VH() { - return fuse_context.private_data$VH; - } - public static MemoryAddress private_data$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_context.private_data$VH.get(seg); - } - public static void private_data$set( MemorySegment seg, MemoryAddress x) { - fuse_context.private_data$VH.set(seg, x); - } - public static MemoryAddress private_data$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_context.private_data$VH.get(seg.asSlice(index*sizeof())); - } - public static void private_data$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_context.private_data$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle umask$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("umask")); - public static VarHandle umask$VH() { - return fuse_context.umask$VH; - } - public static int umask$get(MemorySegment seg) { - return (int)fuse_context.umask$VH.get(seg); - } - public static void umask$set( MemorySegment seg, int x) { - fuse_context.umask$VH.set(seg, x); - } - public static int umask$get(MemorySegment seg, long index) { - return (int)fuse_context.umask$VH.get(seg.asSlice(index*sizeof())); - } - public static void umask$set(MemorySegment seg, long index, int x) { - fuse_context.umask$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-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 5951d6c3..0ad4af01 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 @@ -69,7 +69,7 @@ public static void fuse_unmount ( Addressable f) { } } public static MethodHandle fuse_destroy$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_destroy$MH,"fuse_destroy"); + return RuntimeHelper.requireNonNull(constants$1.fuse_destroy$MH,"fuse_destroy"); } public static void fuse_destroy ( Addressable f) { var mh$ = fuse_destroy$MH(); @@ -112,28 +112,6 @@ public static int fuse_loop_mt ( Addressable f, Addressable config) { throw new AssertionError("should not reach here", ex$); } } - public static MethodHandle fuse_get_context$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse_get_context$MH,"fuse_get_context"); - } - public static MemoryAddress fuse_get_context () { - var mh$ = fuse_get_context$MH(); - try { - return (java.lang.foreign.MemoryAddress)mh$.invokeExact(); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - } - public static MethodHandle fuse_main_real$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse_main_real$MH,"fuse_main_real"); - } - public static int fuse_main_real ( int argc, Addressable argv, Addressable op, long op_size, Addressable private_data) { - var mh$ = fuse_main_real$MH(); - try { - return (int)mh$.invokeExact(argc, argv, op, op_size, private_data); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - } public static MethodHandle fuse_get_session$MH() { return RuntimeHelper.requireNonNull(constants$1.fuse_get_session$MH,"fuse_get_session"); } diff --git a/jfuse-mac/pom.xml b/jfuse-mac/pom.xml index 031239b4..159ee1bd 100644 --- a/jfuse-mac/pom.xml +++ b/jfuse-mac/pom.xml @@ -94,15 +94,12 @@ FUSE_USE_VERSION=29 - fuse_main_real - fuse_get_context - fuse_exit - fuse_parse_cmdline fuse_mount fuse_new fuse_loop fuse_loop_mt + fuse_exit fuse_unmount fuse_destroy @@ -112,7 +109,6 @@ fuse_operations fuse_file_info - fuse_context stat statvfs timespec diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/constants$1.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/constants$1.java index 27179244..f1a3b6fe 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/constants$1.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/constants$1.java @@ -37,22 +37,6 @@ class constants$1 { "fuse_loop_mt", constants$1.fuse_loop_mt$FUNC ); - static final FunctionDescriptor fuse_get_context$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT); - static final MethodHandle fuse_get_context$MH = RuntimeHelper.downcallHandle( - "fuse_get_context", - constants$1.fuse_get_context$FUNC - ); - static final FunctionDescriptor fuse_main_real$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT, - Constants$root.C_INT$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_main_real$MH = RuntimeHelper.downcallHandle( - "fuse_main_real", - constants$1.fuse_main_real$FUNC - ); } diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_context.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_context.java deleted file mode 100644 index 334a3a77..00000000 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_context.java +++ /dev/null @@ -1,129 +0,0 @@ -// Generated by jextract - -package org.cryptomator.jfuse.mac.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 fuse_context { - - static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( - Constants$root.C_POINTER$LAYOUT.withName("fuse"), - Constants$root.C_INT$LAYOUT.withName("uid"), - Constants$root.C_INT$LAYOUT.withName("gid"), - Constants$root.C_INT$LAYOUT.withName("pid"), - MemoryLayout.paddingLayout(32), - Constants$root.C_POINTER$LAYOUT.withName("private_data"), - Constants$root.C_SHORT$LAYOUT.withName("umask"), - MemoryLayout.paddingLayout(48) - ).withName("fuse_context"); - public static MemoryLayout $LAYOUT() { - return fuse_context.$struct$LAYOUT; - } - static final VarHandle fuse$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fuse")); - public static VarHandle fuse$VH() { - return fuse_context.fuse$VH; - } - public static MemoryAddress fuse$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_context.fuse$VH.get(seg); - } - public static void fuse$set( MemorySegment seg, MemoryAddress x) { - fuse_context.fuse$VH.set(seg, x); - } - public static MemoryAddress fuse$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_context.fuse$VH.get(seg.asSlice(index*sizeof())); - } - public static void fuse$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_context.fuse$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle uid$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("uid")); - public static VarHandle uid$VH() { - return fuse_context.uid$VH; - } - public static int uid$get(MemorySegment seg) { - return (int)fuse_context.uid$VH.get(seg); - } - public static void uid$set( MemorySegment seg, int x) { - fuse_context.uid$VH.set(seg, x); - } - public static int uid$get(MemorySegment seg, long index) { - return (int)fuse_context.uid$VH.get(seg.asSlice(index*sizeof())); - } - public static void uid$set(MemorySegment seg, long index, int x) { - fuse_context.uid$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle gid$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("gid")); - public static VarHandle gid$VH() { - return fuse_context.gid$VH; - } - public static int gid$get(MemorySegment seg) { - return (int)fuse_context.gid$VH.get(seg); - } - public static void gid$set( MemorySegment seg, int x) { - fuse_context.gid$VH.set(seg, x); - } - public static int gid$get(MemorySegment seg, long index) { - return (int)fuse_context.gid$VH.get(seg.asSlice(index*sizeof())); - } - public static void gid$set(MemorySegment seg, long index, int x) { - fuse_context.gid$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle pid$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("pid")); - public static VarHandle pid$VH() { - return fuse_context.pid$VH; - } - public static int pid$get(MemorySegment seg) { - return (int)fuse_context.pid$VH.get(seg); - } - public static void pid$set( MemorySegment seg, int x) { - fuse_context.pid$VH.set(seg, x); - } - public static int pid$get(MemorySegment seg, long index) { - return (int)fuse_context.pid$VH.get(seg.asSlice(index*sizeof())); - } - public static void pid$set(MemorySegment seg, long index, int x) { - fuse_context.pid$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle private_data$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("private_data")); - public static VarHandle private_data$VH() { - return fuse_context.private_data$VH; - } - public static MemoryAddress private_data$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_context.private_data$VH.get(seg); - } - public static void private_data$set( MemorySegment seg, MemoryAddress x) { - fuse_context.private_data$VH.set(seg, x); - } - public static MemoryAddress private_data$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_context.private_data$VH.get(seg.asSlice(index*sizeof())); - } - public static void private_data$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_context.private_data$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle umask$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("umask")); - public static VarHandle umask$VH() { - return fuse_context.umask$VH; - } - public static short umask$get(MemorySegment seg) { - return (short)fuse_context.umask$VH.get(seg); - } - public static void umask$set( MemorySegment seg, short x) { - fuse_context.umask$VH.set(seg, x); - } - public static short umask$get(MemorySegment seg, long index) { - return (short)fuse_context.umask$VH.get(seg.asSlice(index*sizeof())); - } - public static void umask$set(MemorySegment seg, long index, short x) { - fuse_context.umask$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-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_h.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_h.java index 50b29927..22cce062 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_h.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/extr/fuse_h.java @@ -106,28 +106,6 @@ public static int fuse_loop_mt ( Addressable f) { throw new AssertionError("should not reach here", ex$); } } - public static MethodHandle fuse_get_context$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse_get_context$MH,"fuse_get_context"); - } - public static MemoryAddress fuse_get_context () { - var mh$ = fuse_get_context$MH(); - try { - return (java.lang.foreign.MemoryAddress)mh$.invokeExact(); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - } - public static MethodHandle fuse_main_real$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse_main_real$MH,"fuse_main_real"); - } - public static int fuse_main_real ( int argc, Addressable argv, Addressable op, long op_size, Addressable user_data) { - var mh$ = fuse_main_real$MH(); - try { - return (int)mh$.invokeExact(argc, argv, op, op_size, user_data); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - } } From 476ba96a977c0767e420b1668abb16a6c001a7bc Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 5 Sep 2022 13:38:17 +0200 Subject: [PATCH 39/98] fix code smells --- .../src/main/java/org/cryptomator/jfuse/api/Fuse.java | 8 ++++---- .../org/cryptomator/jfuse/linux/aarch64/FuseImplTest.java | 3 ++- .../org/cryptomator/jfuse/linux/amd64/FuseImplTest.java | 3 ++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java index 864ff50a..98690140 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/Fuse.java @@ -29,7 +29,6 @@ public abstract class Fuse implements AutoCloseable { protected final MemorySession fuseScope = MemorySession.openShared(); private final AtomicReference mount = new AtomicReference<>(UNMOUNTED); - @BlockingExecutor private final ExecutorService executor; protected Fuse() { @@ -88,6 +87,7 @@ private int fuseLoop() { try { result.set(mount.loop()); } finally { + // TODO remove System.out.println("fuse_loop finished with result " + result.get()); } }); @@ -107,14 +107,14 @@ private int fuseLoop() { @MustBeInvokedByOverriders public void close() throws TimeoutException { try { - var mount = this.mount.getAndSet(UNMOUNTED); - mount.unmount(); + var fuseMount = this.mount.getAndSet(UNMOUNTED); + fuseMount.unmount(); executor.shutdown(); boolean exited = executor.awaitTermination(10, TimeUnit.SECONDS); if (!exited) { throw new TimeoutException("fuse main loop continued runn"); } - mount.destroy(); + fuseMount.destroy(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { 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 fbe0593e..1714db35 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 @@ -32,6 +32,7 @@ public class FuseImplTest { @DisplayName("parseArgs with -h/--help") @ValueSource(strings = {"--help", "-h"}) 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 -> { @@ -41,7 +42,7 @@ public void testParseArgsHelp(String arg) { }); fuseH.when(() -> fuse_h.fuse_lib_help(Mockito.any())).thenAnswer(Answers.RETURNS_DEFAULTS); - Assertions.assertThrows(IllegalArgumentException.class, () -> fuseImpl.parseArgs(List.of("fusefs", arg))); + Assertions.assertThrows(IllegalArgumentException.class, () -> fuseImpl.parseArgs(args)); fuseH.verify(() -> fuse_h.fuse_lib_help(Mockito.any())); } } 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 145a6248..4e98976c 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 @@ -32,6 +32,7 @@ public class FuseImplTest { @DisplayName("parseArgs with -h/--help") @ValueSource(strings = {"--help", "-h"}) 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 -> { @@ -41,7 +42,7 @@ public void testParseArgsHelp(String arg) { }); fuseH.when(() -> fuse_h.fuse_lib_help(Mockito.any())).thenAnswer(Answers.RETURNS_DEFAULTS); - Assertions.assertThrows(IllegalArgumentException.class, () -> fuseImpl.parseArgs(List.of("fusefs", arg))); + Assertions.assertThrows(IllegalArgumentException.class, () -> fuseImpl.parseArgs(args)); fuseH.verify(() -> fuse_h.fuse_lib_help(Mockito.any())); } } From ace6918e1107bd98e09d42276fab2a034250d307 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 5 Sep 2022 14:15:46 +0200 Subject: [PATCH 40/98] added tests --- .../jfuse/linux/aarch64/FuseImpl.java | 2 +- .../jfuse/linux/aarch64/FuseImplTest.java | 49 ++++++++++++++++++ .../jfuse/linux/amd64/FuseImplTest.java | 47 +++++++++++++++++ .../cryptomator/jfuse/mac/FuseImplTest.java | 50 +++++++++++++++++++ .../jfuse/win/amd64/FuseImplTest.java | 49 ++++++++++++++++++ 5 files changed, 196 insertions(+), 1 deletion(-) 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 3d7227a5..7f7d69b8 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 @@ -40,7 +40,7 @@ protected FuseMount mount(List args) throws MountFailedException { throw new MountFailedException("fuse_new failed"); } if (fuse_h.fuse_mount(fuse, fuseArgs.mountPoint()) != 0) { - throw new MountFailedException("fuse_mount failed "); + throw new MountFailedException("fuse_mount failed"); } return new FuseMountImpl(fuse, fuseArgs); } 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 1714db35..e96d92fe 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 @@ -1,13 +1,16 @@ package org.cryptomator.jfuse.linux.aarch64; 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_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; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -15,7 +18,10 @@ 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; @@ -28,6 +34,49 @@ public class FuseImplTest { private FuseOperations fuseOps = Mockito.mock(FuseOperations.class); private FuseImpl fuseImpl = new FuseImpl(fuseOps); + @Nested + @DisplayName("mount()") + public class Mount { + + private List args = List.of("foo", "bar"); + private FuseImpl fuseImplSpy = Mockito.spy(fuseImpl); + private MockedStatic fuseH; + + @BeforeEach + public void setup() { + Mockito.doReturn(Mockito.mock(FuseArgs.class)).when(fuseImplSpy).parseArgs(args); + fuseH = Mockito.mockStatic(fuse_h.class); + } + + @AfterEach + public void teardown() { + fuseH.close(); + } + + @Test + @DisplayName("MountFailedException when fuse_new fails") + public void testFuseNewFails() { + fuseH.when(() -> fuse_h.fuse_new(Mockito.any(), Mockito.any(), Mockito.anyLong(), Mockito.any())).thenReturn(MemoryAddress.NULL); + + var thrown = Assertions.assertThrows(MountFailedException.class, () -> fuseImplSpy.mount(args)); + + fuseH.verify(() -> fuse_h.fuse_mount(Mockito.any(), Mockito.any()), Mockito.never()); + Assertions.assertEquals("fuse_new failed", thrown.getMessage()); + } + + @Test + @DisplayName("MountFailedException when fuse_mount fails") + public void testFuseMountFails() { + fuseH.when(() -> fuse_h.fuse_new(Mockito.any(), Mockito.any(), Mockito.anyLong(), Mockito.any())).thenReturn(MemoryAddress.ofLong(42L)); + fuseH.when(() -> fuse_h.fuse_mount(Mockito.any(), Mockito.any())).thenReturn(1); + + var thrown = Assertions.assertThrows(MountFailedException.class, () -> fuseImplSpy.mount(args)); + + Assertions.assertEquals("fuse_mount failed", thrown.getMessage()); + } + + } + @ParameterizedTest(name = "fusefs {0}") @DisplayName("parseArgs with -h/--help") @ValueSource(strings = {"--help", "-h"}) 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 4e98976c..af4f614f 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 @@ -1,13 +1,16 @@ package org.cryptomator.jfuse.linux.amd64; 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_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; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -15,6 +18,7 @@ import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.ValueSource; import org.mockito.Answers; +import org.mockito.MockedStatic; import org.mockito.Mockito; import java.lang.foreign.MemoryAddress; @@ -28,6 +32,49 @@ public class FuseImplTest { private FuseOperations fuseOps = Mockito.mock(FuseOperations.class); private FuseImpl fuseImpl = new FuseImpl(fuseOps); + @Nested + @DisplayName("mount()") + public class Mount { + + private List args = List.of("foo", "bar"); + private FuseImpl fuseImplSpy = Mockito.spy(fuseImpl); + private MockedStatic fuseH; + + @BeforeEach + public void setup() { + Mockito.doReturn(Mockito.mock(FuseArgs.class)).when(fuseImplSpy).parseArgs(args); + fuseH = Mockito.mockStatic(fuse_h.class); + } + + @AfterEach + public void teardown() { + fuseH.close(); + } + + @Test + @DisplayName("MountFailedException when fuse_new fails") + public void testFuseNewFails() { + fuseH.when(() -> fuse_h.fuse_new(Mockito.any(), Mockito.any(), Mockito.anyLong(), Mockito.any())).thenReturn(MemoryAddress.NULL); + + var thrown = Assertions.assertThrows(MountFailedException.class, () -> fuseImplSpy.mount(args)); + + fuseH.verify(() -> fuse_h.fuse_mount(Mockito.any(), Mockito.any()), Mockito.never()); + Assertions.assertEquals("fuse_new failed", thrown.getMessage()); + } + + @Test + @DisplayName("MountFailedException when fuse_mount fails") + public void testFuseMountFails() { + fuseH.when(() -> fuse_h.fuse_new(Mockito.any(), Mockito.any(), Mockito.anyLong(), Mockito.any())).thenReturn(MemoryAddress.ofLong(42L)); + fuseH.when(() -> fuse_h.fuse_mount(Mockito.any(), Mockito.any())).thenReturn(1); + + var thrown = Assertions.assertThrows(MountFailedException.class, () -> fuseImplSpy.mount(args)); + + Assertions.assertEquals("fuse_mount failed", thrown.getMessage()); + } + + } + @ParameterizedTest(name = "fusefs {0}") @DisplayName("parseArgs with -h/--help") @ValueSource(strings = {"--help", "-h"}) diff --git a/jfuse-mac/src/test/java/org/cryptomator/jfuse/mac/FuseImplTest.java b/jfuse-mac/src/test/java/org/cryptomator/jfuse/mac/FuseImplTest.java index c45b35c6..05d190c8 100644 --- a/jfuse-mac/src/test/java/org/cryptomator/jfuse/mac/FuseImplTest.java +++ b/jfuse-mac/src/test/java/org/cryptomator/jfuse/mac/FuseImplTest.java @@ -1,15 +1,19 @@ package org.cryptomator.jfuse.mac; import org.cryptomator.jfuse.api.FuseOperations; +import org.cryptomator.jfuse.api.MountFailedException; import org.cryptomator.jfuse.api.TimeSpec; import org.cryptomator.jfuse.mac.extr.fuse_h; import org.cryptomator.jfuse.mac.extr.timespec; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; +import org.mockito.MockedStatic; import org.mockito.Mockito; import java.lang.foreign.MemoryAddress; @@ -25,7 +29,53 @@ public class FuseImplTest { private FuseOperations fuseOps = Mockito.mock(FuseOperations.class); private FuseImpl fuseImpl = new FuseImpl(fuseOps); + + @Nested + @DisplayName("mount()") + public class Mount { + + private List args = List.of("foo", "bar"); + private FuseImpl fuseImplSpy = Mockito.spy(fuseImpl); + private MockedStatic fuseH; + + @BeforeEach + public void setup() { + Mockito.doReturn(Mockito.mock(FuseArgs.class)).when(fuseImplSpy).parseArgs(args); + fuseH = Mockito.mockStatic(fuse_h.class); + } + + @AfterEach + public void teardown() { + fuseH.close(); + } + + @Test + @DisplayName("MountFailedException when fuse_new fails") + public void testFuseNewFails() { + fuseH.when(() -> fuse_h.fuse_mount(Mockito.any(), Mockito.any())).thenReturn(MemoryAddress.ofLong(42L)); + fuseH.when(() -> fuse_h.fuse_new(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyLong(), Mockito.any())).thenReturn(MemoryAddress.NULL); + + var thrown = Assertions.assertThrows(MountFailedException.class, () -> fuseImplSpy.mount(args)); + + fuseH.verify(() -> fuse_h.fuse_unmount(Mockito.any(), Mockito.any())); + Assertions.assertEquals("fuse_new failed", thrown.getMessage()); + } + + @Test + @DisplayName("MountFailedException when fuse_mount fails") + public void testFuseMountFails() { + fuseH.when(() -> fuse_h.fuse_mount(Mockito.any(), Mockito.any())).thenReturn(MemoryAddress.NULL); + + var thrown = Assertions.assertThrows(MountFailedException.class, () -> fuseImplSpy.mount(args)); + + fuseH.verify(() -> fuse_h.fuse_new(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyLong(), Mockito.any()), Mockito.never()); + Assertions.assertEquals("fuse_mount failed", thrown.getMessage()); + } + + } + @Test + @DisplayName("parseArgs") public void testParseArgs() { try (var fuseH = Mockito.mockStatic(fuse_h.class); var scope = MemorySession.openConfined()) { 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 4eed3391..f88709b4 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 @@ -1,14 +1,18 @@ package org.cryptomator.jfuse.win.amd64; import org.cryptomator.jfuse.api.FuseOperations; +import org.cryptomator.jfuse.api.MountFailedException; import org.cryptomator.jfuse.win.amd64.extr.fuse_h; import org.cryptomator.jfuse.win.amd64.extr.fuse_timespec; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; +import org.mockito.MockedStatic; import org.mockito.Mockito; import java.lang.foreign.MemoryAddress; @@ -24,7 +28,52 @@ public class FuseImplTest { private FuseOperations fuseOps = Mockito.mock(FuseOperations.class); private FuseImpl fuseImpl = new FuseImpl(fuseOps); + + @Nested + @DisplayName("mount()") + public class Mount { + + private List args = List.of("foo", "bar"); + private FuseImpl fuseImplSpy = Mockito.spy(fuseImpl); + private MockedStatic fuseH; + + @BeforeEach + public void setup() { + Mockito.doReturn(Mockito.mock(FuseArgs.class)).when(fuseImplSpy).parseArgs(args); + fuseH = Mockito.mockStatic(fuse_h.class); + } + + @AfterEach + public void teardown() { + fuseH.close(); + } + + @Test + @DisplayName("MountFailedException when fuse_new fails") + public void testFuseNewFails() { + fuseH.when(() -> fuse_h.fuse_mount(Mockito.any(), Mockito.any())).thenReturn(MemoryAddress.ofLong(42L)); + fuseH.when(() -> fuse_h.fuse_new(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyLong(), Mockito.any())).thenReturn(MemoryAddress.NULL); + + var thrown = Assertions.assertThrows(MountFailedException.class, () -> fuseImplSpy.mount(args)); + + fuseH.verify(() -> fuse_h.fuse_unmount(Mockito.any(), Mockito.any())); + Assertions.assertEquals("fuse_new failed", thrown.getMessage()); + } + + @Test + @DisplayName("MountFailedException when fuse_mount fails") + public void testFuseMountFails() { + fuseH.when(() -> fuse_h.fuse_mount(Mockito.any(), Mockito.any())).thenReturn(MemoryAddress.NULL); + + var thrown = Assertions.assertThrows(MountFailedException.class, () -> fuseImplSpy.mount(args)); + + fuseH.verify(() -> fuse_h.fuse_new(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyLong(), Mockito.any()), Mockito.never()); + Assertions.assertEquals("fuse_mount failed", thrown.getMessage()); + } + } + @Test + @DisplayName("parseArgs") public void testParseArgs() { try (var fuseH = Mockito.mockStatic(fuse_h.class); var scope = MemorySession.openConfined()) { From d8e6bf17f48b1d964aa156b097c00d6621c808ef Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 5 Sep 2022 15:31:25 +0200 Subject: [PATCH 41/98] removed unused functions and structs from Windows implementation --- jfuse-win-amd64/pom.xml | 6 +- .../jfuse/win/amd64/extr/constants$0.java | 10 +- .../jfuse/win/amd64/extr/constants$1.java | 16 --- .../jfuse/win/amd64/extr/fuse_context.java | 129 ------------------ .../jfuse/win/amd64/extr/fuse_h.java | 24 +--- 5 files changed, 7 insertions(+), 178 deletions(-) delete mode 100644 jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_context.java diff --git a/jfuse-win-amd64/pom.xml b/jfuse-win-amd64/pom.xml index 5ea9ed7c..2ee5b840 100644 --- a/jfuse-win-amd64/pom.xml +++ b/jfuse-win-amd64/pom.xml @@ -91,14 +91,11 @@ ${project.parent.basedir}/winfsp/inc/fuse/fuse.h fuse_h - fuse_main_real - fuse_get_context - fuse_exit - fuse_parse_cmdline fuse_mount fuse_new fuse_loop + fuse_exit fuse_unmount fuse_destroy @@ -108,7 +105,6 @@ fuse_operations fuse_file_info - fuse_context fuse_stat fuse_statvfs fuse_timespec diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$0.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$0.java index 9f4d5bad..7d5c3598 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$0.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$0.java @@ -44,16 +44,16 @@ class constants$0 { static final MethodHandle fuse_fill_dir_t$MH = RuntimeHelper.downcallHandle( constants$0.fuse_fill_dir_t$FUNC ); - static final FunctionDescriptor fuse_main_real$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, - Constants$root.C_LONG$LAYOUT, + 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_POINTER$LAYOUT, Constants$root.C_LONG_LONG$LAYOUT, Constants$root.C_POINTER$LAYOUT ); - static final MethodHandle fuse_main_real$MH = RuntimeHelper.downcallHandle( - "fuse_main_real", - constants$0.fuse_main_real$FUNC + static final MethodHandle fuse_new$MH = RuntimeHelper.downcallHandle( + "fuse_new", + constants$0.fuse_new$FUNC ); } 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 779718c2..ad1297db 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 @@ -9,17 +9,6 @@ import static java.lang.foreign.ValueLayout.*; class constants$1 { - 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_POINTER$LAYOUT, - Constants$root.C_LONG_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle fuse_new$MH = RuntimeHelper.downcallHandle( - "fuse_new", - constants$1.fuse_new$FUNC - ); static final FunctionDescriptor fuse_destroy$FUNC = FunctionDescriptor.ofVoid( Constants$root.C_POINTER$LAYOUT ); @@ -41,11 +30,6 @@ class constants$1 { "fuse_exit", constants$1.fuse_exit$FUNC ); - static final FunctionDescriptor fuse_get_context$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT); - static final MethodHandle fuse_get_context$MH = RuntimeHelper.downcallHandle( - "fuse_get_context", - constants$1.fuse_get_context$FUNC - ); } diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_context.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_context.java deleted file mode 100644 index 4ceae473..00000000 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_context.java +++ /dev/null @@ -1,129 +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 fuse_context { - - static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( - Constants$root.C_POINTER$LAYOUT.withName("fuse"), - Constants$root.C_LONG$LAYOUT.withName("uid"), - Constants$root.C_LONG$LAYOUT.withName("gid"), - Constants$root.C_LONG$LAYOUT.withName("pid"), - MemoryLayout.paddingLayout(32), - Constants$root.C_POINTER$LAYOUT.withName("private_data"), - Constants$root.C_LONG$LAYOUT.withName("umask"), - MemoryLayout.paddingLayout(32) - ).withName("fuse_context"); - public static MemoryLayout $LAYOUT() { - return fuse_context.$struct$LAYOUT; - } - static final VarHandle fuse$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fuse")); - public static VarHandle fuse$VH() { - return fuse_context.fuse$VH; - } - public static MemoryAddress fuse$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_context.fuse$VH.get(seg); - } - public static void fuse$set( MemorySegment seg, MemoryAddress x) { - fuse_context.fuse$VH.set(seg, x); - } - public static MemoryAddress fuse$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_context.fuse$VH.get(seg.asSlice(index*sizeof())); - } - public static void fuse$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_context.fuse$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle uid$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("uid")); - public static VarHandle uid$VH() { - return fuse_context.uid$VH; - } - public static int uid$get(MemorySegment seg) { - return (int)fuse_context.uid$VH.get(seg); - } - public static void uid$set( MemorySegment seg, int x) { - fuse_context.uid$VH.set(seg, x); - } - public static int uid$get(MemorySegment seg, long index) { - return (int)fuse_context.uid$VH.get(seg.asSlice(index*sizeof())); - } - public static void uid$set(MemorySegment seg, long index, int x) { - fuse_context.uid$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle gid$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("gid")); - public static VarHandle gid$VH() { - return fuse_context.gid$VH; - } - public static int gid$get(MemorySegment seg) { - return (int)fuse_context.gid$VH.get(seg); - } - public static void gid$set( MemorySegment seg, int x) { - fuse_context.gid$VH.set(seg, x); - } - public static int gid$get(MemorySegment seg, long index) { - return (int)fuse_context.gid$VH.get(seg.asSlice(index*sizeof())); - } - public static void gid$set(MemorySegment seg, long index, int x) { - fuse_context.gid$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle pid$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("pid")); - public static VarHandle pid$VH() { - return fuse_context.pid$VH; - } - public static int pid$get(MemorySegment seg) { - return (int)fuse_context.pid$VH.get(seg); - } - public static void pid$set( MemorySegment seg, int x) { - fuse_context.pid$VH.set(seg, x); - } - public static int pid$get(MemorySegment seg, long index) { - return (int)fuse_context.pid$VH.get(seg.asSlice(index*sizeof())); - } - public static void pid$set(MemorySegment seg, long index, int x) { - fuse_context.pid$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle private_data$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("private_data")); - public static VarHandle private_data$VH() { - return fuse_context.private_data$VH; - } - public static MemoryAddress private_data$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_context.private_data$VH.get(seg); - } - public static void private_data$set( MemorySegment seg, MemoryAddress x) { - fuse_context.private_data$VH.set(seg, x); - } - public static MemoryAddress private_data$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_context.private_data$VH.get(seg.asSlice(index*sizeof())); - } - public static void private_data$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_context.private_data$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle umask$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("umask")); - public static VarHandle umask$VH() { - return fuse_context.umask$VH; - } - public static int umask$get(MemorySegment seg) { - return (int)fuse_context.umask$VH.get(seg); - } - public static void umask$set( MemorySegment seg, int x) { - fuse_context.umask$VH.set(seg, x); - } - public static int umask$get(MemorySegment seg, long index) { - return (int)fuse_context.umask$VH.get(seg.asSlice(index*sizeof())); - } - public static void umask$set(MemorySegment seg, long index, int x) { - fuse_context.umask$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 f8ed78ab..3151da91 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 @@ -51,19 +51,8 @@ public static int fuse_parse_cmdline ( Addressable args, Addressable mountpoint throw new AssertionError("should not reach here", ex$); } } - public static MethodHandle fuse_main_real$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_main_real$MH,"fuse_main_real"); - } - public static int fuse_main_real ( int argc, Addressable argv, Addressable ops, long opsize, Addressable data) { - var mh$ = fuse_main_real$MH(); - try { - return (int)mh$.invokeExact(argc, argv, ops, opsize, data); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - } public static MethodHandle fuse_new$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse_new$MH,"fuse_new"); + return RuntimeHelper.requireNonNull(constants$0.fuse_new$MH,"fuse_new"); } public static MemoryAddress fuse_new ( Addressable ch, Addressable args, Addressable ops, long opsize, Addressable data) { var mh$ = fuse_new$MH(); @@ -106,17 +95,6 @@ public static void fuse_exit ( Addressable f) { throw new AssertionError("should not reach here", ex$); } } - public static MethodHandle fuse_get_context$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse_get_context$MH,"fuse_get_context"); - } - public static MemoryAddress fuse_get_context () { - var mh$ = fuse_get_context$MH(); - try { - return (java.lang.foreign.MemoryAddress)mh$.invokeExact(); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - } } From a2ae33977e68bee4c2a5aac4ebfb825d3f04e272 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 5 Sep 2022 16:35:36 +0200 Subject: [PATCH 42/98] updated README [ci skip] --- README.md | 114 +++++++++++++++++++++++++++--------------------------- 1 file changed, 58 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index e4b0b5b0..2ed115a7 100644 --- a/README.md +++ b/README.md @@ -9,58 +9,60 @@ Zero-Dependency Java bindings for FUSE using [JEP 424](https://openjdk.org/jeps/ This is currently an experimental library requiring JDK 19. As long as the [Foreign Function & Memory API](https://openjdk.org/jeps/424) is incubating, the required JDK will increase. -Currently, it only provides bindings for [libfuse 2.x](https://github.com/libfuse/libfuse/). Once stable, a new branch for libfuse 3.x will be added. +We attempt to support libfuse 3.x on Linux while also remaining compatible with libfuse 2.x on macOS and Windows, leading to some compromises in the API. Windows support for libfuse 3.x is planned. ### Supported `fuse_operations` -Not all `fuse_operations` are supported yet. - -| | Status | -|--------|-------| -| getattr | :white_check_mark: | -| readlink | :white_check_mark: | -| ~getdir~ | use readdir | -| ~mknod~ | use create | -| mkdir | :white_check_mark: | -| unlink | :white_check_mark: | -| rmdir | :white_check_mark: | -| symlink | :white_check_mark: | -| rename | :white_check_mark: | -| link | :x: | -| chmod | :white_check_mark: | -| chown | :x: | -| truncate | :white_check_mark: | -| ~utime~ | use utimens | -| open | :white_check_mark: | -| read | :white_check_mark: | -| write | :white_check_mark: | -| statfs | :white_check_mark: | -| flush | :x: | -| release | :white_check_mark: | -| fsync | :x: | -| setxattr | :x: | -| getxattr | :x: | -| listxattr | :x: | -| removexattr | :x: | -| opendir | :white_check_mark: | -| readdir | :white_check_mark: | -| releasedir | :white_check_mark: | -| fsyncdir | :x: | -| init | :white_check_mark: | -| destroy | :white_check_mark: | -| access | :white_check_mark: | -| create | :white_check_mark: | -| ftruncate | :x: | -| fgetattr | :x: | -| lock | :x: | -| utimens | :white_check_mark: | -| bmap | :x: | -| ioctl | :x: | -| poll | :x: | -| write_buf | :x: | -| read_buf | :x: | -| flock | :x: | -| fallocate | :x: | +Not all [`fuse_operations`](https://libfuse.github.io/doxygen/structfuse__operations.html) are supported yet. + +| | Status | +|-----------------|--------------------| +| getattr | :white_check_mark: | +| fgetattr | :x: | +| readlink | :white_check_mark: | +| ~getdir~ | use readdir | +| ~mknod~ | use create | +| mkdir | :white_check_mark: | +| unlink | :white_check_mark: | +| rmdir | :white_check_mark: | +| symlink | :white_check_mark: | +| rename | :white_check_mark: | +| link | :x: | +| chmod | :white_check_mark: | +| chown | :x: | +| truncate | :white_check_mark: | +| ftruncate | :x: | +| ~utime~ | use utimens | +| open | :white_check_mark: | +| read | :white_check_mark: | +| write | :white_check_mark: | +| statfs | :white_check_mark: | +| flush | :x: | +| release | :white_check_mark: | +| fsync | :x: | +| setxattr | :x: | +| getxattr | :x: | +| listxattr | :x: | +| removexattr | :x: | +| opendir | :white_check_mark: | +| readdir | :white_check_mark: | +| releasedir | :white_check_mark: | +| fsyncdir | :x: | +| init | :white_check_mark: | +| destroy | :white_check_mark: | +| access | :white_check_mark: | +| create | :white_check_mark: | +| lock | :x: | +| utimens | :white_check_mark: | +| bmap | :x: | +| ioctl | :x: | +| poll | :x: | +| write_buf | :x: | +| read_buf | :x: | +| flock | :x: | +| fallocate | :x: | +| copy_file_range | :x: | +| lseek | :x: | ## Usage @@ -70,9 +72,9 @@ Usage examples can be found under [`/jfuse-examples/`](jfuse-examples). You basi var builder = Fuse.builder(); var fs = new MyFileSystem(builder.errno()); try (var fuse = builder.build(fs)) { - int result = fuse.mount("my-awesome-fs", mountPoint); - // thread will now block until unmounted or failed -} + fuse.mount("my-awesome-fs", mountPoint); + // wait as long as the mounted volume is in use +} // closing will force-unmount (previous graceful unmount recommended) ``` During runtime, you will need to add allow native access from platform-specific implementations via `--enable-native-access`, e.g.: @@ -88,10 +90,10 @@ java -p path/to/mods \ Due to slight differences in memory layout, each platform needs its own implementation. Currently, the following operating systems and architectures are supported: -| | Linux | Mac (macFUSE) | Windows (WinFSP) | -|--------|------------------------------------------|-----|---------| -| x86_64 | [jfuse-linux-amd64](jfuse-linux-amd64) | [jfuse-mac](jfuse-mac) | [jfuse-win-amd64](jfuse-win-amd64) | -| arm64 | [jfuse-linux-aarch64](jfuse-linux-aarch64) | [jfuse-mac](jfuse-mac) | | +| | Linux | Mac (macFUSE) | Windows (WinFSP) | +|--------|--------------------------------------------|--------------------------|--------------------------------------| +| x86_64 | [jfuse-linux-amd64](jfuse-linux-amd64) | [jfuse-mac](jfuse-mac) | [jfuse-win-amd64](jfuse-win-amd64) | +| arm64 | [jfuse-linux-aarch64](jfuse-linux-aarch64) | [jfuse-mac](jfuse-mac) | | ## Building From 48196be44a14782de2dd9323a650546e168aa6e2 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 5 Sep 2022 17:14:52 +0200 Subject: [PATCH 43/98] set libfuse2's fgetattr and ftruncate as alias for libfuse3's getattr and truncate with optional fi --- README.md | 4 +- .../cryptomator/jfuse/api/FuseOperations.java | 69 +++++++----------- .../org/cryptomator/jfuse/mac/FuseImpl.java | 30 ++++++-- .../cryptomator/jfuse/mac/FuseImplTest.java | 70 ++++++++++++++++++ .../cryptomator/jfuse/win/amd64/FuseImpl.java | 30 ++++++-- .../jfuse/win/amd64/FuseImplTest.java | 71 +++++++++++++++++++ 6 files changed, 219 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index 2ed115a7..40e5a8c0 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Not all [`fuse_operations`](https://libfuse.github.io/doxygen/structfuse__operat | | Status | |-----------------|--------------------| | getattr | :white_check_mark: | -| fgetattr | :x: | +| ~fgetattr~ | use getattr | | readlink | :white_check_mark: | | ~getdir~ | use readdir | | ~mknod~ | use create | @@ -31,7 +31,7 @@ Not all [`fuse_operations`](https://libfuse.github.io/doxygen/structfuse__operat | chmod | :white_check_mark: | | chown | :x: | | truncate | :white_check_mark: | -| ftruncate | :x: | +| ~ftruncate~ | use truncate | | ~utime~ | use utimens | | open | :white_check_mark: | | read | :white_check_mark: | diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java index 170c4bae..69edf0e3 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java @@ -53,8 +53,18 @@ enum Operation { * Get file attributes. *

* Similar to stat(). The 'st_dev' and 'st_blksize' fields are - * ignored. The 'st_ino' field is ignored except if the 'use_ino' - * mount option is given. + * ignored. The 'st_ino' field is ignored except if the 'use_ino' + * mount option is given. In that case it is passed to userspace, + * but libfuse and the kernel will still assign a different + * inode for internal use (called the "nodeid"). + *

+ * This method doubles as fgetattr in libfuse2 + * + * @param path file path + * @param stat file information + * @param fi will always be null if the file is not currently open, + * but may also be null if the file is open. + * @return 0 on success or negated error code (-errno) */ default int getattr(String path, Stat stat, @Nullable FileInfo fi) { return -errno().enosys(); @@ -153,22 +163,23 @@ default int chown(String path, int uid, int gid) { } /** - * Change the size of a file + * Change the size of a file. + *

+ * Unless FUSE_CAP_HANDLE_KILLPRIV is disabled, this method is + * expected to reset the setuid and setgid bits. + *

+ * This method doubles as ftruncate in libfuse2 + * + * @param path file path + * @param size new size of the file + * @param fi will always be null if the file is not currently open, + * but may also be null if the file is open. + * @return 0 on success or negated error code (-errno) */ default int truncate(String path, long size, @Nullable FileInfo fi) { return -errno().enosys(); } -// /** -// * Change the access and/or modification times of a file -// * -// * @deprecated use {@link #utimens(String, TimeSpec) utimens()} instead. -// */ -// @Deprecated -// default int utime(String path, Pointer utimbufPointer) { -// return -errno().enosys(); -// } - /** * File open operation *

@@ -437,38 +448,6 @@ default int create(String path, int mode, FileInfo fi) { return -errno().enosys(); } - /** - * Change the size of an open file - *

- * This method is called instead of the truncate() method if the - * truncation was invoked from an ftruncate() system call. - *

- * If this method is not implemented or under Linux kernel - * versions earlier than 2.6.15, the truncate() method will be - * called instead. - *

- * Introduced in version 2.5 - */ - default int ftruncate(String path, long size, FileInfo fi) { - return -errno().enosys(); - } - - /** - * Get attributes from an open file - *

- * This method is called instead of the getattr() method if the - * file information is available. - *

- * Currently this is only called after the create() method if that - * is implemented (see above). Later it may be called for - * invocations of fstat() too. - *

- * Introduced in version 2.5 - */ - default int fgetattr(String path, Stat stat, FileInfo fi) { - return -errno().enosys(); - } - // /** // * Perform POSIX file locking operation // *

diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java index 31c0ca99..8ae4aabd 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java @@ -80,7 +80,10 @@ private void bind(FuseOperations.Operation operation) { case CHMOD -> fuse_operations.chmod$set(fuseOps, fuse_operations.chmod.allocate(this::chmod, fuseScope).address()); case CREATE -> fuse_operations.create$set(fuseOps, fuse_operations.create.allocate(this::create, fuseScope).address()); case DESTROY -> fuse_operations.destroy$set(fuseOps, fuse_operations.destroy.allocate(this::destroy, fuseScope).address()); - case GET_ATTR -> fuse_operations.getattr$set(fuseOps, fuse_operations.getattr.allocate(this::getattr, fuseScope).address()); + case GET_ATTR -> { + fuse_operations.getattr$set(fuseOps, fuse_operations.getattr.allocate(this::getattr, fuseScope).address()); + fuse_operations.fgetattr$set(fuseOps, fuse_operations.fgetattr.allocate(this::fgetattr, fuseScope).address()); + } case MKDIR -> fuse_operations.mkdir$set(fuseOps, fuse_operations.mkdir.allocate(this::mkdir, fuseScope).address()); case OPEN -> fuse_operations.open$set(fuseOps, fuse_operations.open.allocate(this::open, fuseScope).address()); case OPEN_DIR -> fuse_operations.opendir$set(fuseOps, fuse_operations.opendir.allocate(this::opendir, fuseScope).address()); @@ -93,7 +96,10 @@ private void bind(FuseOperations.Operation operation) { case RMDIR -> fuse_operations.rmdir$set(fuseOps, fuse_operations.rmdir.allocate(this::rmdir, fuseScope).address()); case STATFS -> fuse_operations.statfs$set(fuseOps, fuse_operations.statfs.allocate(this::statfs, fuseScope).address()); case SYMLINK -> fuse_operations.symlink$set(fuseOps, fuse_operations.symlink.allocate(this::symlink, fuseScope).address()); - case TRUNCATE -> fuse_operations.truncate$set(fuseOps, fuse_operations.truncate.allocate(this::truncate, fuseScope).address()); + case TRUNCATE -> { + fuse_operations.truncate$set(fuseOps, fuse_operations.truncate.allocate(this::truncate, fuseScope).address()); + fuse_operations.ftruncate$set(fuseOps, fuse_operations.ftruncate.allocate(this::ftruncate, fuseScope).address()); + } case UNLINK -> fuse_operations.unlink$set(fuseOps, fuse_operations.unlink.allocate(this::unlink, fuseScope).address()); case UTIMENS -> fuse_operations.utimens$set(fuseOps, fuse_operations.utimens.allocate(this::utimens, fuseScope).address()); case WRITE -> fuse_operations.write$set(fuseOps, fuse_operations.write.allocate(this::write, fuseScope).address()); @@ -125,12 +131,20 @@ private void destroy(MemoryAddress addr) { delegate.destroy(); } - private int getattr(MemoryAddress path, MemoryAddress stat) { + @VisibleForTesting + int getattr(MemoryAddress path, MemoryAddress stat) { try (var scope = MemorySession.openConfined()) { return delegate.getattr(path.getUtf8String(0), new StatImpl(stat, scope), null); } } + @VisibleForTesting + int fgetattr(MemoryAddress path, MemoryAddress stat, MemoryAddress fi) { + try (var scope = MemorySession.openConfined()) { + return delegate.getattr(path.getUtf8String(0), new StatImpl(stat, scope), new FileInfoImpl(fi, scope)); + } + } + private int mkdir(MemoryAddress path, short mode) { return delegate.mkdir(path.getUtf8String(0), mode); } @@ -197,10 +211,18 @@ private int symlink(MemoryAddress linkname, MemoryAddress target) { return delegate.symlink(linkname.getUtf8String(0), target.getUtf8String(0)); } - private int truncate(MemoryAddress path, long size) { + @VisibleForTesting + int truncate(MemoryAddress path, long size) { return delegate.truncate(path.getUtf8String(0), size, null); } + @VisibleForTesting + int ftruncate(MemoryAddress path, long size, MemoryAddress fi) { + try (var scope = MemorySession.openConfined()) { + return delegate.truncate(path.getUtf8String(0), size, new FileInfoImpl(fi, scope)); + } + } + private int unlink(MemoryAddress path) { return delegate.unlink(path.getUtf8String(0)); } diff --git a/jfuse-mac/src/test/java/org/cryptomator/jfuse/mac/FuseImplTest.java b/jfuse-mac/src/test/java/org/cryptomator/jfuse/mac/FuseImplTest.java index 05d190c8..9e4140d4 100644 --- a/jfuse-mac/src/test/java/org/cryptomator/jfuse/mac/FuseImplTest.java +++ b/jfuse-mac/src/test/java/org/cryptomator/jfuse/mac/FuseImplTest.java @@ -3,7 +3,9 @@ import org.cryptomator.jfuse.api.FuseOperations; import org.cryptomator.jfuse.api.MountFailedException; import org.cryptomator.jfuse.api.TimeSpec; +import org.cryptomator.jfuse.mac.extr.fuse_file_info; import org.cryptomator.jfuse.mac.extr.fuse_h; +import org.cryptomator.jfuse.mac.extr.stat; import org.cryptomator.jfuse.mac.extr.timespec; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -142,4 +144,72 @@ public void testUtimens(long sec0, long nsec0, long sec1, long nsec1) { } } + @Nested + @DisplayName("getattr") + public class GetAttr { + + @Test + @DisplayName("getattr") + public void testGetattr() { + try (var scope = MemorySession.openConfined()) { + var path = scope.allocateUtf8String("/foo"); + var attr = stat.allocate(scope); + Mockito.doReturn(42).when(fuseOps).getattr(Mockito.eq("/foo"), Mockito.any(), Mockito.isNull()); + + var result = fuseImpl.getattr(path.address(), attr.address()); + + Assertions.assertEquals(42, result); + } + } + + @Test + @DisplayName("fgetattr") + public void testFgetattr() { + try (var scope = MemorySession.openConfined()) { + var path = scope.allocateUtf8String("/foo"); + var attr = stat.allocate(scope); + var fi = fuse_file_info.allocate(scope); + Mockito.doReturn(42).when(fuseOps).getattr(Mockito.eq("/foo"), Mockito.any(), Mockito.notNull()); + + var result = fuseImpl.fgetattr(path.address(), attr.address(), fi.address()); + + Assertions.assertEquals(42, result); + } + } + + } + + @Nested + @DisplayName("truncate") + public class Truncate { + + @Test + @DisplayName("truncate") + public void testTruncate() { + try (var scope = MemorySession.openConfined()) { + var path = scope.allocateUtf8String("/foo"); + Mockito.doReturn(42).when(fuseOps).truncate(Mockito.eq("/foo"), Mockito.eq(1337L), Mockito.isNull()); + + var result = fuseImpl.truncate(path.address(), 1337L); + + Assertions.assertEquals(42, result); + } + } + + @Test + @DisplayName("ftruncate") + public void testFtruncate() { + try (var scope = MemorySession.openConfined()) { + var path = scope.allocateUtf8String("/foo"); + var fi = fuse_file_info.allocate(scope); + Mockito.doReturn(42).when(fuseOps).truncate(Mockito.eq("/foo"), Mockito.eq(1337L), Mockito.notNull()); + + var result = fuseImpl.ftruncate(path.address(), 1337L, fi.address()); + + Assertions.assertEquals(42, result); + } + } + + } + } \ No newline at end of file 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 71fa5ee4..137715de 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 @@ -91,7 +91,10 @@ private void bind(FuseOperations.Operation operation) { case CHMOD -> fuse_operations.chmod$set(fuseOps, fuse_operations.chmod.allocate(this::chmod, fuseScope).address()); case CREATE -> fuse_operations.create$set(fuseOps, fuse_operations.create.allocate(this::create, fuseScope).address()); case DESTROY -> fuse_operations.destroy$set(fuseOps, fuse_operations.destroy.allocate(this::destroy, fuseScope).address()); - case GET_ATTR -> fuse_operations.getattr$set(fuseOps, fuse_operations.getattr.allocate(this::getattr, fuseScope).address()); + case GET_ATTR -> { + fuse_operations.getattr$set(fuseOps, fuse_operations.getattr.allocate(this::getattr, fuseScope).address()); + fuse_operations.fgetattr$set(fuseOps, fuse_operations.fgetattr.allocate(this::fgetattr, fuseScope).address()); + } case MKDIR -> fuse_operations.mkdir$set(fuseOps, fuse_operations.mkdir.allocate(this::mkdir, fuseScope).address()); case OPEN -> fuse_operations.open$set(fuseOps, fuse_operations.open.allocate(this::open, fuseScope).address()); case OPEN_DIR -> fuse_operations.opendir$set(fuseOps, fuse_operations.opendir.allocate(this::opendir, fuseScope).address()); @@ -104,7 +107,10 @@ private void bind(FuseOperations.Operation operation) { case RMDIR -> fuse_operations.rmdir$set(fuseOps, fuse_operations.rmdir.allocate(this::rmdir, fuseScope).address()); case STATFS -> fuse_operations.statfs$set(fuseOps, fuse_operations.statfs.allocate(this::statfs, fuseScope).address()); case SYMLINK -> fuse_operations.symlink$set(fuseOps, fuse_operations.symlink.allocate(this::symlink, fuseScope).address()); - case TRUNCATE -> fuse_operations.truncate$set(fuseOps, fuse_operations.truncate.allocate(this::truncate, fuseScope).address()); + case TRUNCATE -> { + fuse_operations.truncate$set(fuseOps, fuse_operations.truncate.allocate(this::truncate, fuseScope).address()); + fuse_operations.ftruncate$set(fuseOps, fuse_operations.ftruncate.allocate(this::ftruncate, fuseScope).address()); + } case UNLINK -> fuse_operations.unlink$set(fuseOps, fuse_operations.unlink.allocate(this::unlink, fuseScope).address()); case UTIMENS -> fuse_operations.utimens$set(fuseOps, fuse_operations.utimens.allocate(this::utimens, fuseScope).address()); case WRITE -> fuse_operations.write$set(fuseOps, fuse_operations.write.allocate(this::write, fuseScope).address()); @@ -136,12 +142,20 @@ private void destroy(MemoryAddress addr) { delegate.destroy(); } - private int getattr(MemoryAddress path, MemoryAddress stat) { + @VisibleForTesting + int getattr(MemoryAddress path, MemoryAddress stat) { try (var scope = MemorySession.openConfined()) { return delegate.getattr(path.getUtf8String(0), new StatImpl(stat, scope), null); } } + @VisibleForTesting + int fgetattr(MemoryAddress path, MemoryAddress stat, MemoryAddress fi) { + try (var scope = MemorySession.openConfined()) { + return delegate.getattr(path.getUtf8String(0), new StatImpl(stat, scope), new FileInfoImpl(fi, scope)); + } + } + private int mkdir(MemoryAddress path, int mode) { return delegate.mkdir(path.getUtf8String(0), mode); } @@ -208,10 +222,18 @@ private int symlink(MemoryAddress linkname, MemoryAddress target) { return delegate.symlink(linkname.getUtf8String(0), target.getUtf8String(0)); } - private int truncate(MemoryAddress path, long size) { + @VisibleForTesting + int truncate(MemoryAddress path, long size) { return delegate.truncate(path.getUtf8String(0), size, null); } + @VisibleForTesting + int ftruncate(MemoryAddress path, long size, MemoryAddress fi) { + try (var scope = MemorySession.openConfined()) { + return delegate.truncate(path.getUtf8String(0), size, new FileInfoImpl(fi, scope)); + } + } + private int unlink(MemoryAddress path) { return delegate.unlink(path.getUtf8String(0)); } 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 f88709b4..40bf81b4 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 @@ -2,7 +2,9 @@ import org.cryptomator.jfuse.api.FuseOperations; import org.cryptomator.jfuse.api.MountFailedException; +import org.cryptomator.jfuse.win.amd64.extr.fuse_file_info; import org.cryptomator.jfuse.win.amd64.extr.fuse_h; +import org.cryptomator.jfuse.win.amd64.extr.fuse_stat; import org.cryptomator.jfuse.win.amd64.extr.fuse_timespec; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -140,4 +142,73 @@ public void testUtimens(long sec0, long nsec0, long sec1, long nsec1) { } } + + @Nested + @DisplayName("getattr") + public class GetAttr { + + @Test + @DisplayName("getattr") + public void testGetattr() { + try (var scope = MemorySession.openConfined()) { + var path = scope.allocateUtf8String("/foo"); + var attr = fuse_stat.allocate(scope); + Mockito.doReturn(42).when(fuseOps).getattr(Mockito.eq("/foo"), Mockito.any(), Mockito.isNull()); + + var result = fuseImpl.getattr(path.address(), attr.address()); + + Assertions.assertEquals(42, result); + } + } + + @Test + @DisplayName("fgetattr") + public void testFgetattr() { + try (var scope = MemorySession.openConfined()) { + var path = scope.allocateUtf8String("/foo"); + var attr = fuse_stat.allocate(scope); + var fi = fuse_file_info.allocate(scope); + Mockito.doReturn(42).when(fuseOps).getattr(Mockito.eq("/foo"), Mockito.any(), Mockito.notNull()); + + var result = fuseImpl.fgetattr(path.address(), attr.address(), fi.address()); + + Assertions.assertEquals(42, result); + } + } + + } + + @Nested + @DisplayName("truncate") + public class Truncate { + + @Test + @DisplayName("truncate") + public void testTruncate() { + try (var scope = MemorySession.openConfined()) { + var path = scope.allocateUtf8String("/foo"); + Mockito.doReturn(42).when(fuseOps).truncate(Mockito.eq("/foo"), Mockito.eq(1337L), Mockito.isNull()); + + var result = fuseImpl.truncate(path.address(), 1337L); + + Assertions.assertEquals(42, result); + } + } + + @Test + @DisplayName("ftruncate") + public void testFtruncate() { + try (var scope = MemorySession.openConfined()) { + var path = scope.allocateUtf8String("/foo"); + var fi = fuse_file_info.allocate(scope); + Mockito.doReturn(42).when(fuseOps).truncate(Mockito.eq("/foo"), Mockito.eq(1337L), Mockito.notNull()); + + var result = fuseImpl.ftruncate(path.address(), 1337L, fi.address()); + + Assertions.assertEquals(42, result); + } + } + + } + } \ No newline at end of file From f3376dee2decc13471250d29638ab1005d642d30 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 5 Sep 2022 18:37:13 +0200 Subject: [PATCH 44/98] Javadoc [ci skip] --- .../cryptomator/jfuse/api/FuseOperations.java | 392 ++++++++++++------ 1 file changed, 261 insertions(+), 131 deletions(-) diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java index 69edf0e3..90d23db8 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java @@ -71,43 +71,44 @@ default int getattr(String path, Stat stat, @Nullable FileInfo fi) { } /** - * Read the target of a symbolic link - *

- * The buffer should be filled with a null terminated string. The - * buffer size argument includes the space for the terminating - * null character. If the linkname is too long to fit in the - * buffer, it should be truncated. The return value should be 0 - * for success. + * Read the target of a symbolic link. + * + * @param path file path + * @param buf The buffer should be filled with a null terminated string. + * @param len The buffer size (including the terminating null character). If the linkname is too long to fit in the + * buffer, it should be truncated. + * @return The return value should be 0 */ default int readlink(String path, ByteBuffer buf, long len) { return -errno().enosys(); } -// /** -// * @deprecated use {@link #readdir(String, Pointer, Callback, long, Pointer)} instead -// */ -// @Deprecated -// default int getdir(String path, Pointer fuse_dirhandlePointer, Callback fi2Callback) { -// return -errno().enosys(); -// } - /** - * Create a file node + * Create a file node. *

* This is called for creation of all non-directory, non-symlink * nodes. If the filesystem defines a create() method, then for * regular files that will be called instead. + * + * @param path file path + * @param mode file mode and type of node to create (using bitwise OR) + * @param rdev ignored if mode does not contain S_IFCHR or S_IFBLK + * @return 0 on success or negated error code (-errno) */ default int mknod(String path, short mode, int rdev) { return -errno().enosys(); } /** - * Create a directory + * Create a directory. *

* Note that the mode argument may not have the type specification * bits set, i.e. S_ISDIR(mode) can be false. To obtain the * correct directory type bits use mode|S_IFDIR + * + * @param path file path + * @param mode file mode (using bitwise OR) + * @return 0 on success or negated error code (-errno) */ default int mkdir(String path, int mode) { return -errno().enosys(); @@ -115,6 +116,9 @@ default int mkdir(String path, int mode) { /** * Remove a file + * + * @param path file path + * @return 0 on success or negated error code (-errno) */ default int unlink(String path) { return -errno().enosys(); @@ -122,6 +126,9 @@ default int unlink(String path) { /** * Remove a directory + * + * @param path file path + * @return 0 on success or negated error code (-errno) */ default int rmdir(String path) { return -errno().enosys(); @@ -129,6 +136,10 @@ default int rmdir(String path) { /** * Create a symbolic link + * + * @param linkname file path + * @param target content of the link + * @return 0 on success or negated error code (-errno) */ default int symlink(String linkname, String target) { return -errno().enosys(); @@ -136,13 +147,28 @@ default int symlink(String linkname, String target) { /** * Rename a file + * + * @param oldpath old file path + * @param newpath new file path + * @param flags may be `RENAME_EXCHANGE` or `RENAME_NOREPLACE`. If + * RENAME_NOREPLACE is specified, the filesystem must not + * overwrite *newname* if it exists and return an error + * instead. If `RENAME_EXCHANGE` is specified, the filesystem + * must atomically exchange the two files, i.e. both must + * exist and neither may be deleted. + * @return 0 on success or negated error code (-errno) */ + // TODO create enum for flags default int rename(String oldpath, String newpath, int flags) { return -errno().enosys(); } /** * Create a hard link to a file + * + * @param linkname file path + * @param target content of the link + * @return 0 on success or negated error code (-errno) */ default int link(String linkname, String target) { return -errno().enosys(); @@ -150,6 +176,12 @@ default int link(String linkname, String target) { /** * Change the permission bits of a file + * + * @param path file path + * @param mode file mode (using bitwise OR) + * @param fi will always be null if the file is not currently open, + * but may also be null if the file is open. + * @return 0 on success or negated error code (-errno) */ default int chmod(String path, int mode, @Nullable FileInfo fi) { return -errno().enosys(); @@ -157,8 +189,15 @@ default int chmod(String path, int mode, @Nullable FileInfo fi) { /** * Change the owner and group of a file + * + * @param path file path + * @param uid user id + * @param gid group id + * @param fi will always be null if the file is not currently open, + * but may also be null if the file is open. + * @return 0 on success or negated error code (-errno) */ - default int chown(String path, int uid, int gid) { + default int chown(String path, int uid, int gid, @Nullable FileInfo fi) { return -errno().enosys(); } @@ -181,29 +220,45 @@ default int truncate(String path, long size, @Nullable FileInfo fi) { } /** - * File open operation + * Open a file. *

- * No creation (O_CREAT, O_EXCL) and by default also no - * truncation (O_TRUNC) flags will be passed to open(). If an - * application specifies O_TRUNC, fuse first calls truncate() - * and then open(). Only if 'atomic_o_trunc' has been - * specified and kernel version is 2.6.24 or later, O_TRUNC is - * passed on to open. + * Open flags are available in fi->flags. The following rules apply. + *

    + *
  • Creation (O_CREAT, O_EXCL, O_NOCTTY) flags will be filtered out / handled by the kernel.
  • + *
  • Access modes (O_RDONLY, O_WRONLY, O_RDWR, O_EXEC, O_SEARCH) should be used by the filesystem to check if + * the operation is permitted. If the ``-o default_permissions`` mount option is given, this check is already + * done by the kernel before calling open() and may thus be omitted by the filesystem.
  • + *
  • When writeback caching is enabled, the kernel may send read requests even for files opened with O_WRONLY. + * Thefilesystem should be prepared to handle this.
  • + *
  • When writeback caching is disabled, the filesystem is expected to properly handle the O_APPEND flag and + * ensurethat each write is appending to the end of the file.
  • + *
  • When writeback caching is enabled, the kernel will handle O_APPEND. However, unless all changes to the + * file come through the kernel this will not work reliably. The filesystem should thus either ignore the + * O_APPEND flag (and let the kernel handle it), or return an error (indicating that reliably O_APPEND is + * not available).
  • + *
+ * Filesystem may store an arbitrary file handle (pointer, index, etc) in {@link FileInfo#setFh(long) fi->fh}, + * and use this in other all other file operations (read, write, flush, release, fsync). *

- * Unless the 'default_permissions' mount option is given, - * open should check if the operation is permitted for the - * given flags. Optionally open may also return an arbitrary - * filehandle in the fuse_file_info structure, which will be - * passed to all file operations. + * Filesystem may also implement stateless file I/O and not store anything in {@link FileInfo#setFh(long) fi->fh}. + *

+ * There are also some flags (direct_io, keep_cache) which the filesystem may set in fi, to change the way the file + * is opened. See fuse_file_info structure in for more details. *

- * Changed in version 2.2 + * If this request is answered with an error code of ENOSYS and FUSE_CAP_NO_OPEN_SUPPORT is set in + * `fuse_conn_info.capable`, this is treated as success and future calls to open will also succeed without being + * send to the filesystem process. + * + * @param path file path + * @param fi file info, which may be used to store a file handle + * @return 0 on success or negated error code (-errno) */ default int open(String path, FileInfo fi) { return -errno().enosys(); } /** - * Read data from an open file + * Read data from an open file. *

* Read should return exactly the number of bytes requested except * on EOF or error, otherwise the rest of the data will be @@ -211,80 +266,103 @@ default int open(String path, FileInfo fi) { * 'direct_io' mount option is specified, in which case the return * value of the read system call will reflect the return value of * this operation. - *

- * Changed in version 2.2 - */ - default int read(String path, ByteBuffer buf, long size, long offset, FileInfo fi) { + * + * @param path file path + * @param buf the buffer to read into + * @param count number of bytes to read + * @param offset position in the file to start reading + * @param fi file info + * @return number of bytes read or negated error code (-errno) + */ + default int read(String path, ByteBuffer buf, long count, long offset, FileInfo fi) { return -errno().enosys(); } /** - * Write data to an open file + * Write data to an open file. *

* Write should return exactly the number of bytes requested * except on error. An exception to this is when the 'direct_io' * mount option is specified (see read operation). *

- * Changed in version 2.2 - */ - default int write(String path, ByteBuffer buf, long size, long offset, FileInfo fi) { + * Unless FUSE_CAP_HANDLE_KILLPRIV is disabled, this method is + * expected to reset the setuid and setgid bits. + * + * @param path file path + * @param buf the buffer containing the data to be written + * @param count number of bytes to write + * @param offset position in the file to write to + * @param fi file info + * @return number of bytes written or negated error code (-errno) + */ + default int write(String path, ByteBuffer buf, long count, long offset, FileInfo fi) { return -errno().enosys(); } /** - * Get file system statistics - *

- * The 'f_frsize', 'f_favail', 'f_fsid' and 'f_flag' fields are ignored + * Get file system statistics. *

- * Replaced 'struct statfs' parameter with 'struct statvfs' in - * version 2.5 + * The 'f_favail', 'f_fsid' and 'f_flag' fields are ignored + * + * @param path file path of any file within the file system + * @param statvfs The statistics object to be filled with data + * @return 0 on success or negated error code (-errno) */ default int statfs(String path, Statvfs statvfs) { return -errno().enosys(); } /** - * Possibly flush cached data + * Possibly flush cached data. *

* BIG NOTE: This is not equivalent to fsync(). It's not a * request to sync dirty data. *

- * Flush is called on each close() of a file descriptor. So if a - * filesystem wants to return write errors in close() and the file - * has cached dirty data, this is a good place to write back data - * and return any errors. Since many applications ignore close() - * errors this is not always useful. + * Flush is called on each close() of a file descriptor, as opposed to + * release which is called on the close of the last file descriptor for + * a file. Under Linux, errors returned by flush() will be passed to + * userspace as errors from close(), so flush() is a good place to write + * back any cached dirty data. However, many applications ignore errors + * on close(), and on non-Linux systems, close() may succeed even if flush() + * returns an error. For these reasons, filesystems should not assume + * that errors returned by flush will ever be noticed or even + * delivered. *

* NOTE: The flush() method may be called more than once for each - * open(). This happens if more than one file descriptor refers - * to an opened file due to dup(), dup2() or fork() calls. It is - * not possible to determine if a flush is final, so each flush - * should be treated equally. Multiple write-flush sequences are - * relatively rare, so this shouldn't be a problem. - *

- * Filesystems shouldn't assume that flush will always be called - * after some writes, or that if will be called at all. - *

- * Changed in version 2.2 + * open(). This happens if more than one file descriptor refers to an + * open file handle, e.g. due to dup(), dup2() or fork() calls. It is + * not possible to determine if a flush is final, so each flush should + * be treated equally. Multiple write-flush sequences are relatively + * rare, so this shouldn't be a problem. + *

+ * Filesystems shouldn't assume that flush will be called at any + * particular point. It may be called more times than expected, or not + * at all. + * + * @param path file path + * @param fi file info + * @return 0 on success or negated error code (-errno) */ default int flush(String path, FileInfo fi) { return -errno().enosys(); } /** - * Release an open file + * Release an open file. *

* Release is called when there are no more references to an open * file: all file descriptors are closed and all memory mappings * are unmapped. *

* For every open() call there will be exactly one release() call - * with the same flags and file descriptor. It is possible to + * with the same flags and file handle. It is possible to * have a file opened more than once, in which case only the last * release will mean, that no more reads/writes will happen on the * file. The return value of release is ignored. - *

- * Changed in version 2.2 + * + * @param path file path + * @param fi file info + * @return 0 on success or negated error code (-errno) */ default int release(String path, FileInfo fi) { return 0; @@ -292,11 +370,11 @@ default int release(String path, FileInfo fi) { /** * Synchronize file contents - *

- * If the datasync parameter is non-zero, then only the user data - * should be flushed, not the meta data. - *

- * Changed in version 2.2 + * + * @param path file path + * @param datasync if non-zero, then only the user data should be flushed, not the meta data. + * @param fi file info + * @return 0 on success or negated error code (-errno) */ default int fsync(String path, int datasync, FileInfo fi) { return -errno().enosys(); @@ -304,6 +382,14 @@ default int fsync(String path, int datasync, FileInfo fi) { /** * Set extended attributes + * + * @param path file path + * @param name attribute name + * @param value attribute value + * @param size number of bytes of the value TODO: can this be combined with the value buffer? + * @param flags defaults to zero, which creates or replaces the attribute. For fine-grained atomic control, + * XATTR_CREATE or XATTR_REPLACE may be used. + * @return 0 on success or negated error code (-errno) */ default int setxattr(String path, String name, ByteBuffer value, long size, int flags) { return -errno().enosys(); @@ -311,6 +397,12 @@ default int setxattr(String path, String name, ByteBuffer value, long size, int /** * Get extended attributes + * + * @param path file path + * @param name attribute name + * @param value attribute value + * @param size size of the value buffer TODO: can this be combined with the value buffer? + * @return the non-negative value size or negated error code (-errno) */ default int getxattr(String path, String name, ByteBuffer value, long size) { return -errno().enosys(); @@ -318,6 +410,11 @@ default int getxattr(String path, String name, ByteBuffer value, long size) { /** * List extended attributes + * + * @param path file path + * @param list consecutive list of null-terminated attribute names (as many as fit into the buffer) + * @param size size of the list buffer TODO: can this be combined with the value buffer? + * @return the non-negative list size or negated error code (-errno) */ default int listxattr(String path, ByteBuffer list, long size) { return -errno().enosys(); @@ -325,47 +422,59 @@ default int listxattr(String path, ByteBuffer list, long size) { /** * Remove extended attributes + * + * @param path file path + * @param name attribute name + * @return 0 on success or negated error code (-errno) */ default int removexattr(String path, String name) { return -errno().enosys(); } /** - * Open directory + * Open directory. *

* Unless the 'default_permissions' mount option is given, * this method should check if opendir is permitted for this * directory. Optionally opendir may also return an arbitrary - * filehandle in the fuse_file_info structure, which will be - * passed to readdir, closedir and fsyncdir. - *

- * Introduced in version 2.3 + * {@link FileInfo#setFh(long) filehandle in the fuse_file_info structure}, + * which will be passed to readdir, releasedir and fsyncdir. + * + * @param path directory path + * @param fi file info, which may be used to store a file handle + * @return 0 on success or negated error code (-errno) */ default int opendir(String path, FileInfo fi) { return -errno().enosys(); } /** - * Read directory - *

- * This supersedes the old getdir interface. - * New applications should use this. + * Read directory. *

* The filesystem may choose between two modes of operation: - *

- * 1) The readdir implementation ignores the offset parameter, and - * passes zero to the filler function's offset. The filler - * function will not return '1' (unless an error happens), so the - * whole directory is read in a single readdir operation. This - * works just like the old getdir() method. - *

- * 2) The readdir implementation keeps track of the offsets of the - * directory entries. It uses the offset parameter and always - * passes non-zero offset to the filler function. When the buffer - * is full (or an error happens) the filler function will return - * '1'. - *

- * Introduced in version 2.3 + *

    + *
  1. The readdir implementation ignores the offset parameter, and + * passes zero to the filler function's offset. The filler + * function will not return '1' (unless an error happens), so the + * whole directory is read in a single readdir operation.
  2. + *
  3. The readdir implementation keeps track of the offsets of the + * directory entries. It uses the offset parameter and always + * passes non-zero offset to the filler function. When the buffer + * is full (or an error happens) the filler function will return + * '1'.
  4. + *
+ * When FUSE_READDIR_PLUS is not set, only some parameters of the + * fill function (the fuse_fill_dir_t parameter) are actually used: + * The file type (which is part of stat::st_mode) is used. And if + * fuse_config::use_ino is set, the inode (stat::st_ino) is also + * used. The other fields are ignored when FUSE_READDIR_PLUS is not + * set. + * + * @param path directory path + * @param filler the fill function + * @param offset the offset + * @param fi file info + * @return 0 on success or negated error code (-errno) */ default int readdir(String path, DirFiller filler, long offset, FileInfo fi) { return -errno().enosys(); @@ -373,34 +482,33 @@ default int readdir(String path, DirFiller filler, long offset, FileInfo fi) { /** * Release directory - *

- * Introduced in version 2.3 + * + * @param path directory path. If the directory has been removed after the call to opendir, the + * path parameter will be null + * @param fi file info + * @return 0 on success or negated error code (-errno) */ - default int releasedir(String path, FileInfo fi) { + default int releasedir(@Nullable String path, FileInfo fi) { return 0; } /** * Synchronize directory contents - *

- * If the datasync parameter is non-zero, then only the user data - * should be flushed, not the meta data - *

- * Introduced in version 2.3 + * + * @param path directory path. If the directory has been removed after the call to opendir, the + * path parameter will be null + * @param datasync if non-zero, then only the user data should be flushed, not the meta data + * @param fi file info + * @return 0 on success or negated error code (-errno) */ - default int fsyncdir(String path, int datasync, FileInfo fi) { + default int fsyncdir(@Nullable String path, int datasync, FileInfo fi) { return -errno().enosys(); } /** * Initialize filesystem - *

- * The return value will passed in the private_data field of - * fuse_context to all file operations and as a parameter to the - * destroy() method. - *

- * Introduced in version 2.3 - * Changed in version 2.6 + * + * @param conn FUSE information */ default void init(FuseConnInfo conn) { // TODO: add @Nullable FuseConfig for libfuse3 // no-op @@ -410,30 +518,30 @@ default void init(FuseConnInfo conn) { // TODO: add @Nullable FuseConfig for lib * Clean up filesystem *

* Called on filesystem exit. - *

- * Introduced in version 2.3 */ default void destroy() { // no-op } /** - * Check file access permissions + * Check file access permissions. *

* This will be called for the access() system call. If the * 'default_permissions' mount option is given, this method is not * called. *

* This method is not called under Linux kernel versions 2.4.x - *

- * Introduced in version 2.5 + * + * @param path file path + * @param mask bitwise OR of file access checks + * @return 0 on success or negated error code (-errno) */ default int access(String path, int mask) { return -errno().enosys(); } /** - * Create and open a file + * Create and open a file. *

* If the file does not exist, first create it with the specified * mode, and then open it. @@ -441,8 +549,11 @@ default int access(String path, int mask) { * If this method is not implemented or under Linux kernel * versions earlier than 2.6.15, the mknod() and open() methods * will be called instead. - *

- * Introduced in version 2.5 + * + * @param path file path + * @param mode mode used to create the file if it does not exist yet + * @param fi file info, which may be used to store a file handle + * @return 0 on success or negated error code (-errno) */ default int create(String path, int mode, FileInfo fi) { return -errno().enosys(); @@ -486,14 +597,19 @@ default int create(String path, int mode, FileInfo fi) { /** * Change the access and modification times of a file with - * nanosecond resolution + * nanosecond resolution. *

* This supersedes the old utime() interface. New applications * should use this. *

* See the utimensat(2) man page for details. - *

- * Introduced in version 2.6 + * + * @param path file path + * @param atime last access time + * @param mtime last modified time + * @param fi will always be null if the file is not currently open, + * but may also be null if the file is open. + * @return 0 on success or negated error code (-errno) */ default int utimens(String path, TimeSpec atime, TimeSpec mtime, @Nullable FileInfo fi) { return -errno().enosys(); @@ -521,12 +637,18 @@ default int utimens(String path, TimeSpec atime, TimeSpec mtime, @Nullable FileI * _IOC_READ in area and if both are set in/out area. In all * non-NULL cases, the area is of _IOC_SIZE(cmd) bytes. *

- * If flags has FUSE_IOCTL_DIR then the fuse_file_info refers to a - * directory file handle. - *

- * Introduced in version 2.8 + * Note: the unsigned long request submitted by the application + * is truncated to 32 bits. + * + * @param path file path + * @param cmd the request + * @param arg any arguments + * @param fi file info + * @param flags if containing FUSE_IOCTL_DIR then the fi refers to a directory file handle. + * @param data data (depends on cmd and may be null) + * @return 0 on success or negated error code (-errno) */ - default int ioctl(String path, int cmd, ByteBuffer arg, FileInfo fi, int flags, ByteBuffer data) { + default int ioctl(String path, int cmd, ByteBuffer arg, FileInfo fi, int flags, @Nullable ByteBuffer data) { return -errno().enosys(); } @@ -586,7 +708,7 @@ default int ioctl(String path, int cmd, ByteBuffer arg, FileInfo fi, int flags, // } /** - * Perform BSD file locking operation + * Perform BSD file locking operation. *

* The op argument will be either LOCK_SH, LOCK_EX or LOCK_UN *

@@ -602,22 +724,30 @@ default int ioctl(String path, int cmd, ByteBuffer arg, FileInfo fi, int flags, * Note: if this method is not implemented, the kernel will still * allow file locking to work locally. Hence it is only * interesting for network filesystems and similar. - *

- * Introduced in version 2.9 + * + * @param path file path + * @param fi file info + * @param op one of LOCK_SH, LOCK_EX or LOCK_UN + * @return 0 on success or negated error code (-errno) */ default int flock(String path, FileInfo fi, int op) { return -errno().enosys(); } /** - * Allocates space for an open file + * Allocates space for an open file. *

* This function ensures that required space is allocated for specified * file. If this function returns success then any subsequent write * request to specified range is guaranteed not to fail because of lack * of space on the file system media. - *

- * Introduced in version 2.9.1 + * + * @param path file path + * @param mode the operation to be performed + * @param offset start of the allocated region + * @param length number of bytes to allocate in this file + * @param fi file info + * @return 0 on success or negated error code (-errno) */ default int fallocate(String path, int mode, long offset, long length, FileInfo fi) { return -errno().enosys(); From 467475392bafe7e7a0b23dfb4e68929f5f7bfee0 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Wed, 7 Sep 2022 12:36:48 +0200 Subject: [PATCH 45/98] Remove square brackets to fix javadoc --- .../src/main/java/org/cryptomator/jfuse/api/FuseOperations.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java index 90d23db8..9f4d7e88 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java @@ -243,7 +243,7 @@ default int truncate(String path, long size, @Nullable FileInfo fi) { * Filesystem may also implement stateless file I/O and not store anything in {@link FileInfo#setFh(long) fi->fh}. *

* There are also some flags (direct_io, keep_cache) which the filesystem may set in fi, to change the way the file - * is opened. See fuse_file_info structure in for more details. + * is opened. See fuse_file_info structure in fuse_common.h for more details. *

* If this request is answered with an error code of ENOSYS and FUSE_CAP_NO_OPEN_SUPPORT is set in * `fuse_conn_info.capable`, this is treated as success and future calls to open will also succeed without being From b345bb5c012bc845532644e4325aaae0dfc27ca7 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Thu, 8 Sep 2022 10:35:43 +0200 Subject: [PATCH 46/98] Migrate to fuse3 of winfsp: * use fuse2 libs for fuse_parse_cmd_line(...) * adjust impls to new interface * adjust tests * currently creating jvm crash on real-world test --- jfuse-win-amd64/pom.xml | 35 +- .../jfuse/win/amd64/DirFillerImpl.java | 2 +- .../cryptomator/jfuse/win/amd64/FuseImpl.java | 58 +- .../jfuse/win/amd64/FuseMountImpl.java | 18 +- .../jfuse/win/amd64/extr/constants$0.java | 52 +- .../jfuse/win/amd64/extr/constants$1.java | 23 +- .../jfuse/win/amd64/extr/fuse_conn_info.java | 89 +- .../jfuse/win/amd64/extr/fuse_file_info.java | 60 +- .../jfuse/win/amd64/extr/fuse_fill_dir_t.java | 6 +- .../jfuse/win/amd64/extr/fuse_h.java | 76 +- .../win/amd64/extr/fuse_loop_config.java | 59 ++ .../jfuse/win/amd64/extr/fuse_operations.java | 841 +----------------- .../win/amd64/extr_fuse2/Constants$root.java | 23 + .../win/amd64/extr_fuse2/RuntimeHelper.java | 233 +++++ .../win/amd64/extr_fuse2/constants$0.java | 24 + .../jfuse/win/amd64/extr_fuse2/fuse_2_h.java | 34 + .../jfuse/win/amd64/extr_fuse2/fuse_args.java | 78 ++ .../jfuse/win/amd64/FuseImplTest.java | 49 +- 18 files changed, 787 insertions(+), 973 deletions(-) create mode 100644 jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_loop_config.java create mode 100644 jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/Constants$root.java create mode 100644 jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/RuntimeHelper.java create mode 100644 jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/constants$0.java create mode 100644 jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/fuse_2_h.java create mode 100644 jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/fuse_args.java diff --git a/jfuse-win-amd64/pom.xml b/jfuse-win-amd64/pom.xml index 2ee5b840..b23a08a2 100644 --- a/jfuse-win-amd64/pom.xml +++ b/jfuse-win-amd64/pom.xml @@ -88,13 +88,19 @@ sources - ${project.parent.basedir}/winfsp/inc/fuse/fuse.h + ${project.parent.basedir}/winfsp/inc/fuse3/fuse.h fuse_h + + + FUSE_USE_VERSION=35 + - fuse_parse_cmdline - fuse_mount + fuse_lib_help fuse_new + fuse_mount + fuse_get_session fuse_loop + fuse_loop_mt fuse_exit fuse_unmount fuse_destroy @@ -110,6 +116,29 @@ fuse_timespec fuse_conn_info fuse_args + fuse_loop_config + + + FUSE_FILL_DIR_PLUS + FUSE_READDIR_PLUS + + + + + + jextract-fuse-parse-cmd-line + + sources + + + org.cryptomator.jfuse.win.amd64.extr_fuse2 + ${project.parent.basedir}/winfsp/inc/fuse/fuse_common.h + fuse_2_h + + fuse_parse_cmdline + + + fuse_args diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java index f7520317..a612452e 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java @@ -16,7 +16,7 @@ record DirFillerImpl(MemoryAddress buf, fuse_fill_dir_t callback, MemorySession @Override public int fill(String name, Stat stat, long offset) { var statAddr = stat instanceof StatImpl s ? s.segment().address() : MemoryAddress.NULL; - return callback.apply(buf, scope.allocateUtf8String(name).address(), statAddr, offset); + return callback.apply(buf, scope.allocateUtf8String(name).address(), statAddr, offset, 0); //TODO: readdir plus } } \ No newline at end of file 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 137715de..b63ae354 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 @@ -8,6 +8,7 @@ import org.cryptomator.jfuse.win.amd64.extr.fuse_h; import org.cryptomator.jfuse.win.amd64.extr.fuse_operations; import org.cryptomator.jfuse.win.amd64.extr.fuse_timespec; +import org.cryptomator.jfuse.win.amd64.extr_fuse2.fuse_2_h; import org.jetbrains.annotations.VisibleForTesting; import java.lang.foreign.Addressable; @@ -45,17 +46,14 @@ public void mount(String progName, Path mountPoint, String... flags) throws Moun @Override protected FuseMount mount(List args) throws MountFailedException { var fuseArgs = parseArgs(args); - var ch = fuse_h.fuse_mount(fuseArgs.mountPoint(), fuseArgs.args()); - if (MemoryAddress.NULL.equals(ch)) { - // TODO any cleanup needed? - throw new MountFailedException("fuse_mount failed"); - } - var fuse = fuse_h.fuse_new(ch, fuseArgs.args(), fuseOps, fuseOps.byteSize(), MemoryAddress.NULL); + var fuse = fuse_h.fuse_new(fuseArgs.args(), fuseOps, fuseOps.byteSize(), MemoryAddress.NULL); if (MemoryAddress.NULL.equals(fuse)) { - fuse_h.fuse_unmount(fuseArgs.mountPoint(), ch); throw new MountFailedException("fuse_new failed"); } - return new FuseMountImpl(fuse, ch, fuseArgs); + if (fuse_h.fuse_mount(fuse, fuseArgs.mountPoint()) != 0) { + throw new MountFailedException("fuse_mount failed"); + } + return new FuseMountImpl(fuse, fuseArgs); } @VisibleForTesting @@ -75,7 +73,7 @@ FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { var multithreaded = fuseScope.allocate(JAVA_INT, 1); var foreground = fuseScope.allocate(JAVA_INT, 1); var mountPointPtr = fuseScope.allocate(ValueLayout.ADDRESS); - int parseResult = fuse_h.fuse_parse_cmdline(args, mountPointPtr, multithreaded, foreground); + int parseResult = fuse_2_h.fuse_parse_cmdline(args, mountPointPtr, multithreaded, foreground); if (parseResult != 0) { throw new IllegalArgumentException("fuse_parse_cmdline failed to parse " + String.join(" ", cmdLineArgs)); } @@ -91,10 +89,7 @@ private void bind(FuseOperations.Operation operation) { case CHMOD -> fuse_operations.chmod$set(fuseOps, fuse_operations.chmod.allocate(this::chmod, fuseScope).address()); case CREATE -> fuse_operations.create$set(fuseOps, fuse_operations.create.allocate(this::create, fuseScope).address()); case DESTROY -> fuse_operations.destroy$set(fuseOps, fuse_operations.destroy.allocate(this::destroy, fuseScope).address()); - case GET_ATTR -> { - fuse_operations.getattr$set(fuseOps, fuse_operations.getattr.allocate(this::getattr, fuseScope).address()); - fuse_operations.fgetattr$set(fuseOps, fuse_operations.fgetattr.allocate(this::fgetattr, fuseScope).address()); - } + case GET_ATTR -> fuse_operations.getattr$set(fuseOps, fuse_operations.getattr.allocate(this::getattr, fuseScope).address()); case MKDIR -> fuse_operations.mkdir$set(fuseOps, fuse_operations.mkdir.allocate(this::mkdir, fuseScope).address()); case OPEN -> fuse_operations.open$set(fuseOps, fuse_operations.open.allocate(this::open, fuseScope).address()); case OPEN_DIR -> fuse_operations.opendir$set(fuseOps, fuse_operations.opendir.allocate(this::opendir, fuseScope).address()); @@ -107,17 +102,14 @@ private void bind(FuseOperations.Operation operation) { case RMDIR -> fuse_operations.rmdir$set(fuseOps, fuse_operations.rmdir.allocate(this::rmdir, fuseScope).address()); case STATFS -> fuse_operations.statfs$set(fuseOps, fuse_operations.statfs.allocate(this::statfs, fuseScope).address()); case SYMLINK -> fuse_operations.symlink$set(fuseOps, fuse_operations.symlink.allocate(this::symlink, fuseScope).address()); - case TRUNCATE -> { - fuse_operations.truncate$set(fuseOps, fuse_operations.truncate.allocate(this::truncate, fuseScope).address()); - fuse_operations.ftruncate$set(fuseOps, fuse_operations.ftruncate.allocate(this::ftruncate, fuseScope).address()); - } + case TRUNCATE -> fuse_operations.truncate$set(fuseOps, fuse_operations.truncate.allocate(this::truncate, fuseScope).address()); case UNLINK -> fuse_operations.unlink$set(fuseOps, fuse_operations.unlink.allocate(this::unlink, fuseScope).address()); case UTIMENS -> fuse_operations.utimens$set(fuseOps, fuse_operations.utimens.allocate(this::utimens, fuseScope).address()); case WRITE -> fuse_operations.write$set(fuseOps, fuse_operations.write.allocate(this::write, fuseScope).address()); } } - private Addressable init(MemoryAddress conn) { + private Addressable init(MemoryAddress conn, MemoryAddress fuseConfig) { try (var scope = MemorySession.openConfined()) { delegate.init(new FuseConnInfoImpl(conn, scope)); } @@ -128,8 +120,10 @@ private int access(MemoryAddress path, int mask) { return delegate.access(path.getUtf8String(0), mask); } - private int chmod(MemoryAddress path, int mode) { - return delegate.chmod(path.getUtf8String(0), mode, null); + private int chmod(MemoryAddress path, int mode, MemoryAddress fi) { + try (var scope = MemorySession.openConfined()) { + return delegate.chmod(path.getUtf8String(0), mode, new FileInfoImpl(fi, scope)); + } } private int create(MemoryAddress path, int mode, MemoryAddress fi) { @@ -143,9 +137,9 @@ private void destroy(MemoryAddress addr) { } @VisibleForTesting - int getattr(MemoryAddress path, MemoryAddress stat) { + int getattr(MemoryAddress path, MemoryAddress stat, MemoryAddress fi) { try (var scope = MemorySession.openConfined()) { - return delegate.getattr(path.getUtf8String(0), new StatImpl(stat, scope), null); + return delegate.getattr(path.getUtf8String(0), new StatImpl(stat, scope), new FileInfoImpl(fi, scope)); } } @@ -179,7 +173,7 @@ private int read(MemoryAddress path, MemoryAddress buf, long size, long offset, } } - private int readdir(MemoryAddress path, MemoryAddress buf, MemoryAddress filler, long offset, MemoryAddress fi) { + private int readdir(MemoryAddress path, MemoryAddress buf, MemoryAddress filler, long offset, MemoryAddress fi, int flags) { // TODO: readdir plus try (var scope = MemorySession.openConfined()) { return delegate.readdir(path.getUtf8String(0), new DirFillerImpl(buf, filler, scope), offset, new FileInfoImpl(fi, scope)); } @@ -204,8 +198,8 @@ private int releasedir(MemoryAddress path, MemoryAddress fi) { } } - private int rename(MemoryAddress oldpath, MemoryAddress newpath) { - return delegate.rename(oldpath.getUtf8String(0), newpath.getUtf8String(0), 0); + private int rename(MemoryAddress oldpath, MemoryAddress newpath, int flags) { + return delegate.rename(oldpath.getUtf8String(0), newpath.getUtf8String(0), flags); } private int rmdir(MemoryAddress path) { @@ -223,8 +217,10 @@ private int symlink(MemoryAddress linkname, MemoryAddress target) { } @VisibleForTesting - int truncate(MemoryAddress path, long size) { - return delegate.truncate(path.getUtf8String(0), size, null); + int truncate(MemoryAddress path, long size, MemoryAddress fi) { + try (var scope = MemorySession.openConfined()) { + return delegate.truncate(path.getUtf8String(0), size, new FileInfoImpl(fi, scope)); + } } @VisibleForTesting @@ -239,21 +235,21 @@ private int unlink(MemoryAddress path) { } @VisibleForTesting - int utimens(MemoryAddress path, MemoryAddress times) { + 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 hard-coded UTIME_NOW + fuse_timespec.tv_nsec$set(segment, 0); //TODO: use something like stat_h.UTIME_NOW()) var time = new TimeSpecImpl(segment); - return delegate.utimens(path.getUtf8String(0), time, time, null); + 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), null); + return delegate.utimens(path.getUtf8String(0), new TimeSpecImpl(time0), new TimeSpecImpl(time1), new FileInfoImpl(fi, scope)); } } } 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 52de9983..0374b355 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 @@ -2,21 +2,31 @@ import org.cryptomator.jfuse.api.FuseMount; import org.cryptomator.jfuse.win.amd64.extr.fuse_h; +import org.cryptomator.jfuse.win.amd64.extr.fuse_loop_config; import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySession; -record FuseMountImpl(MemoryAddress fuse, MemoryAddress ch, FuseArgs args) implements FuseMount { +record FuseMountImpl(MemoryAddress fuse, FuseArgs fuseArgs) implements FuseMount { @Override public int loop() { - // TODO support fuse_loop_mt if args.multiThreaded() - return fuse_h.fuse_loop(fuse); + 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); + return fuse_h.fuse_loop_mt(fuse, loopCfg); + } + } else { + return fuse_h.fuse_loop(fuse); + } } @Override public void unmount() { fuse_h.fuse_exit(fuse); - fuse_h.fuse_unmount(args.mountPoint(), ch); + fuse_h.fuse_unmount(fuse); } @Override diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$0.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$0.java index 7d5c3598..739fefd3 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$0.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$0.java @@ -9,43 +9,24 @@ import static java.lang.foreign.ValueLayout.*; class constants$0 { - static final FunctionDescriptor fuse_mount$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle fuse_mount$MH = RuntimeHelper.downcallHandle( - "fuse_mount", - constants$0.fuse_mount$FUNC - ); - static final FunctionDescriptor fuse_unmount$FUNC = FunctionDescriptor.ofVoid( - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle fuse_unmount$MH = RuntimeHelper.downcallHandle( - "fuse_unmount", - constants$0.fuse_unmount$FUNC - ); - static final FunctionDescriptor fuse_parse_cmdline$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$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 FunctionDescriptor fuse_fill_dir_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$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_LONG_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT ); static final MethodHandle fuse_fill_dir_t$MH = RuntimeHelper.downcallHandle( constants$0.fuse_fill_dir_t$FUNC ); + static final FunctionDescriptor fuse_lib_help$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 FunctionDescriptor fuse_new$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_LONG_LONG$LAYOUT, @@ -55,6 +36,21 @@ class constants$0 { "fuse_new", constants$0.fuse_new$FUNC ); + static final FunctionDescriptor fuse_destroy$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_destroy$MH = RuntimeHelper.downcallHandle( + "fuse_destroy", + constants$0.fuse_destroy$FUNC + ); + static final FunctionDescriptor fuse_mount$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle fuse_mount$MH = RuntimeHelper.downcallHandle( + "fuse_mount", + constants$0.fuse_mount$FUNC + ); } 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 ad1297db..77ce4e13 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 @@ -9,12 +9,12 @@ import static java.lang.foreign.ValueLayout.*; class constants$1 { - static final FunctionDescriptor fuse_destroy$FUNC = FunctionDescriptor.ofVoid( + static final FunctionDescriptor fuse_unmount$FUNC = FunctionDescriptor.ofVoid( Constants$root.C_POINTER$LAYOUT ); - static final MethodHandle fuse_destroy$MH = RuntimeHelper.downcallHandle( - "fuse_destroy", - constants$1.fuse_destroy$FUNC + static final MethodHandle fuse_unmount$MH = RuntimeHelper.downcallHandle( + "fuse_unmount", + constants$1.fuse_unmount$FUNC ); static final FunctionDescriptor fuse_loop$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, Constants$root.C_POINTER$LAYOUT @@ -23,6 +23,14 @@ class constants$1 { "fuse_loop", constants$1.fuse_loop$FUNC ); + static final FunctionDescriptor fuse_loop_mt$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$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 FunctionDescriptor fuse_exit$FUNC = FunctionDescriptor.ofVoid( Constants$root.C_POINTER$LAYOUT ); @@ -30,6 +38,13 @@ class constants$1 { "fuse_exit", constants$1.fuse_exit$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$1.fuse_get_session$FUNC + ); } diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_conn_info.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_conn_info.java index 99110f5e..b1a4b77d 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_conn_info.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_conn_info.java @@ -12,12 +12,15 @@ public class fuse_conn_info { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( Constants$root.C_LONG$LAYOUT.withName("proto_major"), Constants$root.C_LONG$LAYOUT.withName("proto_minor"), - Constants$root.C_LONG$LAYOUT.withName("async_read"), Constants$root.C_LONG$LAYOUT.withName("max_write"), + Constants$root.C_LONG$LAYOUT.withName("max_read"), Constants$root.C_LONG$LAYOUT.withName("max_readahead"), Constants$root.C_LONG$LAYOUT.withName("capable"), Constants$root.C_LONG$LAYOUT.withName("want"), - MemoryLayout.sequenceLayout(25, Constants$root.C_LONG$LAYOUT).withName("reserved") + Constants$root.C_LONG$LAYOUT.withName("max_background"), + Constants$root.C_LONG$LAYOUT.withName("congestion_threshold"), + Constants$root.C_LONG$LAYOUT.withName("time_gran"), + MemoryLayout.sequenceLayout(22, Constants$root.C_LONG$LAYOUT).withName("reserved") ).withName("fuse_conn_info"); public static MemoryLayout $LAYOUT() { return fuse_conn_info.$struct$LAYOUT; @@ -54,22 +57,6 @@ public class fuse_conn_info { public static void proto_minor$set(MemorySegment seg, long index, int x) { fuse_conn_info.proto_minor$VH.set(seg.asSlice(index*sizeof()), x); } - static final VarHandle async_read$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("async_read")); - public static VarHandle async_read$VH() { - return fuse_conn_info.async_read$VH; - } - public static int async_read$get(MemorySegment seg) { - return (int)fuse_conn_info.async_read$VH.get(seg); - } - public static void async_read$set( MemorySegment seg, int x) { - fuse_conn_info.async_read$VH.set(seg, x); - } - public static int async_read$get(MemorySegment seg, long index) { - return (int)fuse_conn_info.async_read$VH.get(seg.asSlice(index*sizeof())); - } - public static void async_read$set(MemorySegment seg, long index, int x) { - fuse_conn_info.async_read$VH.set(seg.asSlice(index*sizeof()), x); - } static final VarHandle max_write$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max_write")); public static VarHandle max_write$VH() { return fuse_conn_info.max_write$VH; @@ -86,6 +73,22 @@ public class fuse_conn_info { public static void max_write$set(MemorySegment seg, long index, int x) { fuse_conn_info.max_write$VH.set(seg.asSlice(index*sizeof()), x); } + static final VarHandle max_read$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max_read")); + public static VarHandle max_read$VH() { + return fuse_conn_info.max_read$VH; + } + public static int max_read$get(MemorySegment seg) { + return (int)fuse_conn_info.max_read$VH.get(seg); + } + public static void max_read$set( MemorySegment seg, int x) { + fuse_conn_info.max_read$VH.set(seg, x); + } + public static int max_read$get(MemorySegment seg, long index) { + return (int)fuse_conn_info.max_read$VH.get(seg.asSlice(index*sizeof())); + } + public static void max_read$set(MemorySegment seg, long index, int x) { + fuse_conn_info.max_read$VH.set(seg.asSlice(index*sizeof()), x); + } static final VarHandle max_readahead$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max_readahead")); public static VarHandle max_readahead$VH() { return fuse_conn_info.max_readahead$VH; @@ -134,8 +137,56 @@ public class fuse_conn_info { public static void want$set(MemorySegment seg, long index, int x) { fuse_conn_info.want$VH.set(seg.asSlice(index*sizeof()), x); } + static final VarHandle max_background$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max_background")); + public static VarHandle max_background$VH() { + return fuse_conn_info.max_background$VH; + } + public static int max_background$get(MemorySegment seg) { + return (int)fuse_conn_info.max_background$VH.get(seg); + } + public static void max_background$set( MemorySegment seg, int x) { + fuse_conn_info.max_background$VH.set(seg, x); + } + public static int max_background$get(MemorySegment seg, long index) { + return (int)fuse_conn_info.max_background$VH.get(seg.asSlice(index*sizeof())); + } + public static void max_background$set(MemorySegment seg, long index, int x) { + fuse_conn_info.max_background$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle congestion_threshold$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("congestion_threshold")); + public static VarHandle congestion_threshold$VH() { + return fuse_conn_info.congestion_threshold$VH; + } + public static int congestion_threshold$get(MemorySegment seg) { + return (int)fuse_conn_info.congestion_threshold$VH.get(seg); + } + public static void congestion_threshold$set( MemorySegment seg, int x) { + fuse_conn_info.congestion_threshold$VH.set(seg, x); + } + public static int congestion_threshold$get(MemorySegment seg, long index) { + return (int)fuse_conn_info.congestion_threshold$VH.get(seg.asSlice(index*sizeof())); + } + public static void congestion_threshold$set(MemorySegment seg, long index, int x) { + fuse_conn_info.congestion_threshold$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle time_gran$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("time_gran")); + public static VarHandle time_gran$VH() { + return fuse_conn_info.time_gran$VH; + } + public static int time_gran$get(MemorySegment seg) { + return (int)fuse_conn_info.time_gran$VH.get(seg); + } + public static void time_gran$set( MemorySegment seg, int x) { + fuse_conn_info.time_gran$VH.set(seg, x); + } + public static int time_gran$get(MemorySegment seg, long index) { + return (int)fuse_conn_info.time_gran$VH.get(seg.asSlice(index*sizeof())); + } + public static void time_gran$set(MemorySegment seg, long index, int x) { + fuse_conn_info.time_gran$VH.set(seg.asSlice(index*sizeof()), x); + } public static MemorySegment reserved$slice(MemorySegment seg) { - return seg.asSlice(28, 100); + return seg.asSlice(40, 88); } public static long sizeof() { return $LAYOUT().byteSize(); } public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_file_info.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_file_info.java index 70bc26e6..62f35911 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_file_info.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_file_info.java @@ -11,17 +11,21 @@ public class fuse_file_info { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( Constants$root.C_LONG$LAYOUT.withName("flags"), - Constants$root.C_LONG$LAYOUT.withName("fh_old"), - Constants$root.C_LONG$LAYOUT.withName("writepage"), MemoryLayout.structLayout( + MemoryLayout.paddingLayout(1).withName("writepage"), MemoryLayout.paddingLayout(1).withName("direct_io"), MemoryLayout.paddingLayout(1).withName("keep_cache"), MemoryLayout.paddingLayout(1).withName("flush"), MemoryLayout.paddingLayout(1).withName("nonseekable"), - MemoryLayout.paddingLayout(28).withName("padding") + MemoryLayout.paddingLayout(1).withName("flock_release"), + MemoryLayout.paddingLayout(26), + MemoryLayout.paddingLayout(27).withName("padding"), + MemoryLayout.paddingLayout(37) ), Constants$root.C_LONG_LONG$LAYOUT.withName("fh"), - Constants$root.C_LONG_LONG$LAYOUT.withName("lock_owner") + Constants$root.C_LONG_LONG$LAYOUT.withName("lock_owner"), + Constants$root.C_LONG$LAYOUT.withName("poll_events"), + MemoryLayout.paddingLayout(32) ).withName("fuse_file_info"); public static MemoryLayout $LAYOUT() { return fuse_file_info.$struct$LAYOUT; @@ -42,38 +46,6 @@ public class fuse_file_info { public static void flags$set(MemorySegment seg, long index, int x) { fuse_file_info.flags$VH.set(seg.asSlice(index*sizeof()), x); } - static final VarHandle fh_old$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fh_old")); - public static VarHandle fh_old$VH() { - return fuse_file_info.fh_old$VH; - } - public static int fh_old$get(MemorySegment seg) { - return (int)fuse_file_info.fh_old$VH.get(seg); - } - public static void fh_old$set( MemorySegment seg, int x) { - fuse_file_info.fh_old$VH.set(seg, x); - } - public static int fh_old$get(MemorySegment seg, long index) { - return (int)fuse_file_info.fh_old$VH.get(seg.asSlice(index*sizeof())); - } - public static void fh_old$set(MemorySegment seg, long index, int x) { - fuse_file_info.fh_old$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle writepage$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("writepage")); - public static VarHandle writepage$VH() { - return fuse_file_info.writepage$VH; - } - public static int writepage$get(MemorySegment seg) { - return (int)fuse_file_info.writepage$VH.get(seg); - } - public static void writepage$set( MemorySegment seg, int x) { - fuse_file_info.writepage$VH.set(seg, x); - } - public static int writepage$get(MemorySegment seg, long index) { - return (int)fuse_file_info.writepage$VH.get(seg.asSlice(index*sizeof())); - } - public static void writepage$set(MemorySegment seg, long index, int x) { - fuse_file_info.writepage$VH.set(seg.asSlice(index*sizeof()), x); - } static final VarHandle fh$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fh")); public static VarHandle fh$VH() { return fuse_file_info.fh$VH; @@ -106,6 +78,22 @@ public class fuse_file_info { public static void lock_owner$set(MemorySegment seg, long index, long x) { fuse_file_info.lock_owner$VH.set(seg.asSlice(index*sizeof()), x); } + static final VarHandle poll_events$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("poll_events")); + public static VarHandle poll_events$VH() { + return fuse_file_info.poll_events$VH; + } + public static int poll_events$get(MemorySegment seg) { + return (int)fuse_file_info.poll_events$VH.get(seg); + } + public static void poll_events$set( MemorySegment seg, int x) { + fuse_file_info.poll_events$VH.set(seg, x); + } + public static int poll_events$get(MemorySegment seg, long index) { + return (int)fuse_file_info.poll_events$VH.get(seg.asSlice(index*sizeof())); + } + public static void poll_events$set(MemorySegment seg, long index, int x) { + fuse_file_info.poll_events$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-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_fill_dir_t.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_fill_dir_t.java index 6d4aa71b..aec0f8bd 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_fill_dir_t.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_fill_dir_t.java @@ -9,15 +9,15 @@ import static java.lang.foreign.ValueLayout.*; public interface fuse_fill_dir_t { - int apply(java.lang.foreign.MemoryAddress buf, java.lang.foreign.MemoryAddress name, java.lang.foreign.MemoryAddress stbuf, long off); + int apply(java.lang.foreign.MemoryAddress buf, java.lang.foreign.MemoryAddress name, java.lang.foreign.MemoryAddress stbuf, long off, int flags); static MemorySegment allocate(fuse_fill_dir_t fi, MemorySession session) { return RuntimeHelper.upcallStub(fuse_fill_dir_t.class, fi, constants$0.fuse_fill_dir_t$FUNC, session); } 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) -> { + 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); + 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); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } 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 3151da91..8b9ae8de 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 @@ -18,55 +18,61 @@ 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_mount$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_mount$MH,"fuse_mount"); + public static int FUSE_READDIR_PLUS() { + return (int)1L; } - public static MemoryAddress fuse_mount ( Addressable mountpoint, Addressable args) { - var mh$ = fuse_mount$MH(); + public static int FUSE_FILL_DIR_PLUS() { + return (int)2L; + } + public static MethodHandle fuse_lib_help$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_lib_help$MH,"fuse_lib_help"); + } + public static void fuse_lib_help ( Addressable args) { + var mh$ = fuse_lib_help$MH(); try { - return (java.lang.foreign.MemoryAddress)mh$.invokeExact(mountpoint, args); + mh$.invokeExact(args); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } } - public static MethodHandle fuse_unmount$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_unmount$MH,"fuse_unmount"); + public static MethodHandle fuse_new$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_new$MH,"fuse_new"); } - public static void fuse_unmount ( Addressable mountpoint, Addressable ch) { - var mh$ = fuse_unmount$MH(); + public static MemoryAddress fuse_new ( Addressable args, Addressable ops, long opsize, Addressable data) { + var mh$ = fuse_new$MH(); try { - mh$.invokeExact(mountpoint, ch); + return (java.lang.foreign.MemoryAddress)mh$.invokeExact(args, ops, opsize, data); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } } - public static MethodHandle fuse_parse_cmdline$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_parse_cmdline$MH,"fuse_parse_cmdline"); + public static MethodHandle fuse_destroy$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_destroy$MH,"fuse_destroy"); } - public static int fuse_parse_cmdline ( Addressable args, Addressable mountpoint, Addressable multithreaded, Addressable foreground) { - var mh$ = fuse_parse_cmdline$MH(); + public static void fuse_destroy ( Addressable f) { + var mh$ = fuse_destroy$MH(); try { - return (int)mh$.invokeExact(args, mountpoint, multithreaded, foreground); + mh$.invokeExact(f); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } } - public static MethodHandle fuse_new$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_new$MH,"fuse_new"); + public static MethodHandle fuse_mount$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse_mount$MH,"fuse_mount"); } - public static MemoryAddress fuse_new ( Addressable ch, Addressable args, Addressable ops, long opsize, Addressable data) { - var mh$ = fuse_new$MH(); + public static int fuse_mount ( Addressable f, Addressable mountpoint) { + var mh$ = fuse_mount$MH(); try { - return (java.lang.foreign.MemoryAddress)mh$.invokeExact(ch, args, ops, opsize, data); + return (int)mh$.invokeExact(f, mountpoint); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } } - public static MethodHandle fuse_destroy$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse_destroy$MH,"fuse_destroy"); + public static MethodHandle fuse_unmount$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse_unmount$MH,"fuse_unmount"); } - public static void fuse_destroy ( Addressable f) { - var mh$ = fuse_destroy$MH(); + public static void fuse_unmount ( Addressable f) { + var mh$ = fuse_unmount$MH(); try { mh$.invokeExact(f); } catch (Throwable ex$) { @@ -84,6 +90,17 @@ public static int fuse_loop ( Addressable f) { throw new AssertionError("should not reach here", ex$); } } + public static MethodHandle fuse_loop_mt$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse_loop_mt$MH,"fuse_loop_mt"); + } + public static int fuse_loop_mt ( Addressable f, Addressable config) { + var mh$ = fuse_loop_mt$MH(); + try { + return (int)mh$.invokeExact(f, config); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } public static MethodHandle fuse_exit$MH() { return RuntimeHelper.requireNonNull(constants$1.fuse_exit$MH,"fuse_exit"); } @@ -95,6 +112,17 @@ public static void fuse_exit ( Addressable f) { throw new AssertionError("should not reach here", ex$); } } + public static MethodHandle fuse_get_session$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse_get_session$MH,"fuse_get_session"); + } + public static MemoryAddress fuse_get_session ( Addressable f) { + var mh$ = fuse_get_session$MH(); + try { + return (java.lang.foreign.MemoryAddress)mh$.invokeExact(f); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } } diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_loop_config.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_loop_config.java new file mode 100644 index 00000000..7f4ad1a2 --- /dev/null +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_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 fuse_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("fuse_loop_config"); + public static MemoryLayout $LAYOUT() { + return fuse_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 fuse_loop_config.clone_fd$VH; + } + public static int clone_fd$get(MemorySegment seg) { + return (int)fuse_loop_config.clone_fd$VH.get(seg); + } + public static void clone_fd$set( MemorySegment seg, int x) { + fuse_loop_config.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())); + } + public static void clone_fd$set(MemorySegment seg, long index, int x) { + fuse_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 fuse_loop_config.max_idle_threads$VH; + } + public static int max_idle_threads$get(MemorySegment seg) { + return (int)fuse_loop_config.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); + } + 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())); + } + 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); + } + 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_operations.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_operations.java index 0cad3184..f8c84e6f 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_operations.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_operations.java @@ -11,7 +11,6 @@ public class fuse_operations { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( Constants$root.C_POINTER$LAYOUT.withName("getattr"), - Constants$root.C_POINTER$LAYOUT.withName("getdir"), Constants$root.C_POINTER$LAYOUT.withName("readlink"), Constants$root.C_POINTER$LAYOUT.withName("mknod"), Constants$root.C_POINTER$LAYOUT.withName("mkdir"), @@ -23,7 +22,6 @@ public class fuse_operations { Constants$root.C_POINTER$LAYOUT.withName("chmod"), Constants$root.C_POINTER$LAYOUT.withName("chown"), Constants$root.C_POINTER$LAYOUT.withName("truncate"), - Constants$root.C_POINTER$LAYOUT.withName("utime"), Constants$root.C_POINTER$LAYOUT.withName("open"), Constants$root.C_POINTER$LAYOUT.withName("read"), Constants$root.C_POINTER$LAYOUT.withName("write"), @@ -43,42 +41,21 @@ public class fuse_operations { Constants$root.C_POINTER$LAYOUT.withName("destroy"), Constants$root.C_POINTER$LAYOUT.withName("access"), Constants$root.C_POINTER$LAYOUT.withName("create"), - Constants$root.C_POINTER$LAYOUT.withName("ftruncate"), - Constants$root.C_POINTER$LAYOUT.withName("fgetattr"), Constants$root.C_POINTER$LAYOUT.withName("lock"), Constants$root.C_POINTER$LAYOUT.withName("utimens"), Constants$root.C_POINTER$LAYOUT.withName("bmap"), - MemoryLayout.structLayout( - MemoryLayout.paddingLayout(1).withName("flag_nullpath_ok"), - MemoryLayout.paddingLayout(1).withName("flag_nopath"), - MemoryLayout.paddingLayout(1).withName("flag_utime_omit_ok"), - MemoryLayout.paddingLayout(29).withName("flag_reserved"), - MemoryLayout.paddingLayout(32) - ), Constants$root.C_POINTER$LAYOUT.withName("ioctl"), Constants$root.C_POINTER$LAYOUT.withName("poll"), Constants$root.C_POINTER$LAYOUT.withName("write_buf"), Constants$root.C_POINTER$LAYOUT.withName("read_buf"), Constants$root.C_POINTER$LAYOUT.withName("flock"), - Constants$root.C_POINTER$LAYOUT.withName("fallocate"), - Constants$root.C_POINTER$LAYOUT.withName("getpath"), - Constants$root.C_POINTER$LAYOUT.withName("reserved01"), - Constants$root.C_POINTER$LAYOUT.withName("reserved02"), - Constants$root.C_POINTER$LAYOUT.withName("statfs_x"), - Constants$root.C_POINTER$LAYOUT.withName("setvolname"), - Constants$root.C_POINTER$LAYOUT.withName("exchange"), - Constants$root.C_POINTER$LAYOUT.withName("getxtimes"), - Constants$root.C_POINTER$LAYOUT.withName("setbkuptime"), - Constants$root.C_POINTER$LAYOUT.withName("setchgtime"), - Constants$root.C_POINTER$LAYOUT.withName("setcrtime"), - Constants$root.C_POINTER$LAYOUT.withName("chflags"), - Constants$root.C_POINTER$LAYOUT.withName("setattr_x"), - Constants$root.C_POINTER$LAYOUT.withName("fsetattr_x") + Constants$root.C_POINTER$LAYOUT.withName("fallocate") ).withName("fuse_operations"); public static MemoryLayout $LAYOUT() { return fuse_operations.$struct$LAYOUT; } static final FunctionDescriptor getattr$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT ); @@ -87,15 +64,15 @@ public class fuse_operations { ); public interface getattr { - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2); static MemorySegment allocate(getattr fi, MemorySession session) { return RuntimeHelper.upcallStub(getattr.class, fi, fuse_operations.getattr$FUNC, session); } static getattr ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2) -> { try { - return (int)fuse_operations.getattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + return (int)fuse_operations.getattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -122,51 +99,6 @@ static getattr ofAddress(MemoryAddress addr, MemorySession session) { public static getattr getattr (MemorySegment segment, MemorySession session) { return getattr.ofAddress(getattr$get(segment), session); } - static final FunctionDescriptor getdir$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle getdir$MH = RuntimeHelper.downcallHandle( - fuse_operations.getdir$FUNC - ); - public interface getdir { - - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2); - static MemorySegment allocate(getdir fi, MemorySession session) { - return RuntimeHelper.upcallStub(getdir.class, fi, fuse_operations.getdir$FUNC, session); - } - static getdir ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2) -> { - try { - return (int)fuse_operations.getdir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle getdir$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("getdir")); - public static VarHandle getdir$VH() { - return fuse_operations.getdir$VH; - } - public static MemoryAddress getdir$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.getdir$VH.get(seg); - } - public static void getdir$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.getdir$VH.set(seg, x); - } - public static MemoryAddress getdir$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.getdir$VH.get(seg.asSlice(index*sizeof())); - } - public static void getdir$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.getdir$VH.set(seg.asSlice(index*sizeof()), x); - } - public static getdir getdir (MemorySegment segment, MemorySession session) { - return getdir.ofAddress(getdir$get(segment), session); - } static final FunctionDescriptor readlink$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, @@ -433,22 +365,23 @@ public static symlink symlink (MemorySegment segment, MemorySession session) { } static final FunctionDescriptor rename$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT ); static final MethodHandle rename$MH = RuntimeHelper.downcallHandle( fuse_operations.rename$FUNC ); public interface rename { - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, int _x2); static MemorySegment allocate(rename fi, MemorySession session) { return RuntimeHelper.upcallStub(rename.class, fi, fuse_operations.rename$FUNC, session); } static rename ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, int __x2) -> { try { - return (int)fuse_operations.rename$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + return (int)fuse_operations.rename$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -521,22 +454,23 @@ public static link link (MemorySegment segment, MemorySession session) { } static final FunctionDescriptor chmod$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, Constants$root.C_POINTER$LAYOUT, - Constants$root.C_LONG$LAYOUT + Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT ); static final MethodHandle chmod$MH = RuntimeHelper.downcallHandle( fuse_operations.chmod$FUNC ); public interface chmod { - int apply(java.lang.foreign.MemoryAddress _x0, int _x1); + int apply(java.lang.foreign.MemoryAddress _x0, int _x1, java.lang.foreign.MemoryAddress _x2); static MemorySegment allocate(chmod fi, MemorySession session) { return RuntimeHelper.upcallStub(chmod.class, fi, fuse_operations.chmod$FUNC, session); } static chmod ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, int __x1) -> { + return (java.lang.foreign.MemoryAddress __x0, int __x1, java.lang.foreign.MemoryAddress __x2) -> { try { - return (int)fuse_operations.chmod$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1); + return (int)fuse_operations.chmod$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -566,22 +500,23 @@ public static chmod chmod (MemorySegment segment, MemorySession session) { static final FunctionDescriptor chown$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_LONG$LAYOUT, - Constants$root.C_LONG$LAYOUT + Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT ); static final MethodHandle chown$MH = RuntimeHelper.downcallHandle( fuse_operations.chown$FUNC ); public interface chown { - int apply(java.lang.foreign.MemoryAddress _x0, int _x1, int _x2); + int apply(java.lang.foreign.MemoryAddress _x0, int _x1, int _x2, java.lang.foreign.MemoryAddress _x3); static MemorySegment allocate(chown fi, MemorySession session) { return RuntimeHelper.upcallStub(chown.class, fi, fuse_operations.chown$FUNC, session); } static chown ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, int __x1, int __x2) -> { + return (java.lang.foreign.MemoryAddress __x0, int __x1, int __x2, java.lang.foreign.MemoryAddress __x3) -> { try { - return (int)fuse_operations.chown$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, __x2); + return (int)fuse_operations.chown$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, __x2, (java.lang.foreign.Addressable)__x3); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -610,22 +545,23 @@ public static chown chown (MemorySegment segment, MemorySession session) { } static final FunctionDescriptor truncate$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, Constants$root.C_POINTER$LAYOUT, - Constants$root.C_LONG_LONG$LAYOUT + Constants$root.C_LONG_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT ); static final MethodHandle truncate$MH = RuntimeHelper.downcallHandle( fuse_operations.truncate$FUNC ); public interface truncate { - int apply(java.lang.foreign.MemoryAddress _x0, long _x1); + int apply(java.lang.foreign.MemoryAddress _x0, long _x1, java.lang.foreign.MemoryAddress _x2); static MemorySegment allocate(truncate fi, MemorySession session) { return RuntimeHelper.upcallStub(truncate.class, fi, fuse_operations.truncate$FUNC, session); } static truncate ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, long __x1) -> { + return (java.lang.foreign.MemoryAddress __x0, long __x1, java.lang.foreign.MemoryAddress __x2) -> { try { - return (int)fuse_operations.truncate$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1); + return (int)fuse_operations.truncate$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -652,50 +588,6 @@ static truncate ofAddress(MemoryAddress addr, MemorySession session) { public static truncate truncate (MemorySegment segment, MemorySession session) { return truncate.ofAddress(truncate$get(segment), session); } - static final FunctionDescriptor utime$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle utime$MH = RuntimeHelper.downcallHandle( - fuse_operations.utime$FUNC - ); - public interface utime { - - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); - static MemorySegment allocate(utime fi, MemorySession session) { - return RuntimeHelper.upcallStub(utime.class, fi, fuse_operations.utime$FUNC, session); - } - static utime ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { - try { - return (int)fuse_operations.utime$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle utime$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("utime")); - public static VarHandle utime$VH() { - return fuse_operations.utime$VH; - } - public static MemoryAddress utime$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.utime$VH.get(seg); - } - public static void utime$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.utime$VH.set(seg, x); - } - public static MemoryAddress utime$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.utime$VH.get(seg.asSlice(index*sizeof())); - } - public static void utime$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.utime$VH.set(seg.asSlice(index*sizeof()), x); - } - public static utime utime (MemorySegment segment, MemorySession session) { - return utime.ofAddress(utime$get(segment), session); - } static final FunctionDescriptor open$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT @@ -1242,22 +1134,23 @@ public static opendir opendir (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_LONG_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT ); static final MethodHandle readdir$MH = RuntimeHelper.downcallHandle( fuse_operations.readdir$FUNC ); public interface readdir { - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2, long _x3, java.lang.foreign.MemoryAddress _x4); + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2, long _x3, java.lang.foreign.MemoryAddress _x4, int _x5); static MemorySegment allocate(readdir fi, MemorySession session) { return RuntimeHelper.upcallStub(readdir.class, fi, fuse_operations.readdir$FUNC, session); } static readdir ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2, long __x3, java.lang.foreign.MemoryAddress __x4) -> { + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2, long __x3, java.lang.foreign.MemoryAddress __x4, int __x5) -> { try { - return (int)fuse_operations.readdir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2, __x3, (java.lang.foreign.Addressable)__x4); + return (int)fuse_operations.readdir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2, __x3, (java.lang.foreign.Addressable)__x4, __x5); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1374,6 +1267,7 @@ public static fsyncdir fsyncdir (MemorySegment segment, MemorySession session) { return fsyncdir.ofAddress(fsyncdir$get(segment), session); } static final FunctionDescriptor init$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT ); static final MethodHandle init$MH = RuntimeHelper.downcallHandle( @@ -1381,15 +1275,15 @@ public static fsyncdir fsyncdir (MemorySegment segment, MemorySession session) { ); public interface init { - java.lang.foreign.Addressable apply(java.lang.foreign.MemoryAddress _x0); + java.lang.foreign.Addressable apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); static MemorySegment allocate(init fi, MemorySession session) { return RuntimeHelper.upcallStub(init.class, fi, fuse_operations.init$FUNC, session); } static init ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0) -> { + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { try { - return (java.lang.foreign.Addressable)(java.lang.foreign.MemoryAddress)fuse_operations.init$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0); + return (java.lang.foreign.Addressable)(java.lang.foreign.MemoryAddress)fuse_operations.init$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1548,96 +1442,6 @@ static create ofAddress(MemoryAddress addr, MemorySession session) { public static create create (MemorySegment segment, MemorySession session) { return create.ofAddress(create$get(segment), session); } - static final FunctionDescriptor ftruncate$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_LONG_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle ftruncate$MH = RuntimeHelper.downcallHandle( - fuse_operations.ftruncate$FUNC - ); - public interface ftruncate { - - int apply(java.lang.foreign.MemoryAddress _x0, long _x1, java.lang.foreign.MemoryAddress _x2); - static MemorySegment allocate(ftruncate fi, MemorySession session) { - return RuntimeHelper.upcallStub(ftruncate.class, fi, fuse_operations.ftruncate$FUNC, session); - } - static ftruncate ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, long __x1, java.lang.foreign.MemoryAddress __x2) -> { - try { - return (int)fuse_operations.ftruncate$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle ftruncate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("ftruncate")); - public static VarHandle ftruncate$VH() { - return fuse_operations.ftruncate$VH; - } - public static MemoryAddress ftruncate$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.ftruncate$VH.get(seg); - } - public static void ftruncate$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.ftruncate$VH.set(seg, x); - } - public static MemoryAddress ftruncate$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.ftruncate$VH.get(seg.asSlice(index*sizeof())); - } - public static void ftruncate$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.ftruncate$VH.set(seg.asSlice(index*sizeof()), x); - } - public static ftruncate ftruncate (MemorySegment segment, MemorySession session) { - return ftruncate.ofAddress(ftruncate$get(segment), session); - } - static final FunctionDescriptor fgetattr$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle fgetattr$MH = RuntimeHelper.downcallHandle( - fuse_operations.fgetattr$FUNC - ); - public interface fgetattr { - - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2); - static MemorySegment allocate(fgetattr fi, MemorySession session) { - return RuntimeHelper.upcallStub(fgetattr.class, fi, fuse_operations.fgetattr$FUNC, session); - } - static fgetattr ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2) -> { - try { - return (int)fuse_operations.fgetattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle fgetattr$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fgetattr")); - public static VarHandle fgetattr$VH() { - return fuse_operations.fgetattr$VH; - } - public static MemoryAddress fgetattr$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.fgetattr$VH.get(seg); - } - public static void fgetattr$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.fgetattr$VH.set(seg, x); - } - public static MemoryAddress fgetattr$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.fgetattr$VH.get(seg.asSlice(index*sizeof())); - } - public static void fgetattr$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.fgetattr$VH.set(seg.asSlice(index*sizeof()), x); - } - public static fgetattr fgetattr (MemorySegment segment, MemorySession session) { - return fgetattr.ofAddress(fgetattr$get(segment), session); - } static final FunctionDescriptor lock$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, @@ -1685,6 +1489,7 @@ public static lock lock (MemorySegment segment, MemorySession session) { return lock.ofAddress(lock$get(segment), session); } static final FunctionDescriptor utimens$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT ); @@ -1693,15 +1498,15 @@ public static lock lock (MemorySegment segment, MemorySession session) { ); public interface utimens { - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); + int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2); static MemorySegment allocate(utimens fi, MemorySession session) { return RuntimeHelper.upcallStub(utimens.class, fi, fuse_operations.utimens$FUNC, session); } static utimens ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { + return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2) -> { try { - return (int)fuse_operations.utimens$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + return (int)fuse_operations.utimens$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -2052,576 +1857,6 @@ static fallocate ofAddress(MemoryAddress addr, MemorySession session) { public static fallocate fallocate (MemorySegment segment, MemorySession session) { return fallocate.ofAddress(fallocate$get(segment), session); } - static final FunctionDescriptor getpath$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$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 getpath$MH = RuntimeHelper.downcallHandle( - fuse_operations.getpath$FUNC - ); - public interface getpath { - - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, long _x2, java.lang.foreign.MemoryAddress _x3); - static MemorySegment allocate(getpath fi, MemorySession session) { - return RuntimeHelper.upcallStub(getpath.class, fi, fuse_operations.getpath$FUNC, session); - } - static getpath ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, long __x2, java.lang.foreign.MemoryAddress __x3) -> { - try { - return (int)fuse_operations.getpath$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2, (java.lang.foreign.Addressable)__x3); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle getpath$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("getpath")); - public static VarHandle getpath$VH() { - return fuse_operations.getpath$VH; - } - public static MemoryAddress getpath$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.getpath$VH.get(seg); - } - public static void getpath$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.getpath$VH.set(seg, x); - } - public static MemoryAddress getpath$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.getpath$VH.get(seg.asSlice(index*sizeof())); - } - public static void getpath$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.getpath$VH.set(seg.asSlice(index*sizeof()), x); - } - public static getpath getpath (MemorySegment segment, MemorySession session) { - return getpath.ofAddress(getpath$get(segment), session); - } - static final FunctionDescriptor reserved01$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); - static final MethodHandle reserved01$MH = RuntimeHelper.downcallHandle( - fuse_operations.reserved01$FUNC - ); - public interface reserved01 { - - int apply(); - static MemorySegment allocate(reserved01 fi, MemorySession session) { - return RuntimeHelper.upcallStub(reserved01.class, fi, fuse_operations.reserved01$FUNC, session); - } - static reserved01 ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return () -> { - try { - return (int)fuse_operations.reserved01$MH.invokeExact((Addressable)symbol); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle reserved01$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("reserved01")); - public static VarHandle reserved01$VH() { - return fuse_operations.reserved01$VH; - } - public static MemoryAddress reserved01$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.reserved01$VH.get(seg); - } - public static void reserved01$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.reserved01$VH.set(seg, x); - } - public static MemoryAddress reserved01$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.reserved01$VH.get(seg.asSlice(index*sizeof())); - } - public static void reserved01$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.reserved01$VH.set(seg.asSlice(index*sizeof()), x); - } - public static reserved01 reserved01 (MemorySegment segment, MemorySession session) { - return reserved01.ofAddress(reserved01$get(segment), session); - } - static final FunctionDescriptor reserved02$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); - static final MethodHandle reserved02$MH = RuntimeHelper.downcallHandle( - fuse_operations.reserved02$FUNC - ); - public interface reserved02 { - - int apply(); - static MemorySegment allocate(reserved02 fi, MemorySession session) { - return RuntimeHelper.upcallStub(reserved02.class, fi, fuse_operations.reserved02$FUNC, session); - } - static reserved02 ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return () -> { - try { - return (int)fuse_operations.reserved02$MH.invokeExact((Addressable)symbol); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle reserved02$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("reserved02")); - public static VarHandle reserved02$VH() { - return fuse_operations.reserved02$VH; - } - public static MemoryAddress reserved02$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.reserved02$VH.get(seg); - } - public static void reserved02$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.reserved02$VH.set(seg, x); - } - public static MemoryAddress reserved02$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.reserved02$VH.get(seg.asSlice(index*sizeof())); - } - public static void reserved02$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.reserved02$VH.set(seg.asSlice(index*sizeof()), x); - } - public static reserved02 reserved02 (MemorySegment segment, MemorySession session) { - return reserved02.ofAddress(reserved02$get(segment), session); - } - static final FunctionDescriptor statfs_x$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle statfs_x$MH = RuntimeHelper.downcallHandle( - fuse_operations.statfs_x$FUNC - ); - public interface statfs_x { - - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); - static MemorySegment allocate(statfs_x fi, MemorySession session) { - return RuntimeHelper.upcallStub(statfs_x.class, fi, fuse_operations.statfs_x$FUNC, session); - } - static statfs_x ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { - try { - return (int)fuse_operations.statfs_x$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle statfs_x$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("statfs_x")); - public static VarHandle statfs_x$VH() { - return fuse_operations.statfs_x$VH; - } - public static MemoryAddress statfs_x$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.statfs_x$VH.get(seg); - } - public static void statfs_x$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.statfs_x$VH.set(seg, x); - } - public static MemoryAddress statfs_x$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.statfs_x$VH.get(seg.asSlice(index*sizeof())); - } - public static void statfs_x$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.statfs_x$VH.set(seg.asSlice(index*sizeof()), x); - } - public static statfs_x statfs_x (MemorySegment segment, MemorySession session) { - return statfs_x.ofAddress(statfs_x$get(segment), session); - } - static final FunctionDescriptor setvolname$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle setvolname$MH = RuntimeHelper.downcallHandle( - fuse_operations.setvolname$FUNC - ); - public interface setvolname { - - int apply(java.lang.foreign.MemoryAddress _x0); - static MemorySegment allocate(setvolname fi, MemorySession session) { - return RuntimeHelper.upcallStub(setvolname.class, fi, fuse_operations.setvolname$FUNC, session); - } - static setvolname ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0) -> { - try { - return (int)fuse_operations.setvolname$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle setvolname$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("setvolname")); - public static VarHandle setvolname$VH() { - return fuse_operations.setvolname$VH; - } - public static MemoryAddress setvolname$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.setvolname$VH.get(seg); - } - public static void setvolname$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.setvolname$VH.set(seg, x); - } - public static MemoryAddress setvolname$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.setvolname$VH.get(seg.asSlice(index*sizeof())); - } - public static void setvolname$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.setvolname$VH.set(seg.asSlice(index*sizeof()), x); - } - public static setvolname setvolname (MemorySegment segment, MemorySession session) { - return setvolname.ofAddress(setvolname$get(segment), session); - } - static final FunctionDescriptor exchange$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 exchange$MH = RuntimeHelper.downcallHandle( - fuse_operations.exchange$FUNC - ); - public interface exchange { - - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, int _x2); - static MemorySegment allocate(exchange fi, MemorySession session) { - return RuntimeHelper.upcallStub(exchange.class, fi, fuse_operations.exchange$FUNC, session); - } - static exchange ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, int __x2) -> { - try { - return (int)fuse_operations.exchange$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle exchange$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("exchange")); - public static VarHandle exchange$VH() { - return fuse_operations.exchange$VH; - } - public static MemoryAddress exchange$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.exchange$VH.get(seg); - } - public static void exchange$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.exchange$VH.set(seg, x); - } - public static MemoryAddress exchange$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.exchange$VH.get(seg.asSlice(index*sizeof())); - } - public static void exchange$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.exchange$VH.set(seg.asSlice(index*sizeof()), x); - } - public static exchange exchange (MemorySegment segment, MemorySession session) { - return exchange.ofAddress(exchange$get(segment), session); - } - static final FunctionDescriptor getxtimes$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle getxtimes$MH = RuntimeHelper.downcallHandle( - fuse_operations.getxtimes$FUNC - ); - public interface getxtimes { - - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2); - static MemorySegment allocate(getxtimes fi, MemorySession session) { - return RuntimeHelper.upcallStub(getxtimes.class, fi, fuse_operations.getxtimes$FUNC, session); - } - static getxtimes ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2) -> { - try { - return (int)fuse_operations.getxtimes$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle getxtimes$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("getxtimes")); - public static VarHandle getxtimes$VH() { - return fuse_operations.getxtimes$VH; - } - public static MemoryAddress getxtimes$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.getxtimes$VH.get(seg); - } - public static void getxtimes$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.getxtimes$VH.set(seg, x); - } - public static MemoryAddress getxtimes$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.getxtimes$VH.get(seg.asSlice(index*sizeof())); - } - public static void getxtimes$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.getxtimes$VH.set(seg.asSlice(index*sizeof()), x); - } - public static getxtimes getxtimes (MemorySegment segment, MemorySession session) { - return getxtimes.ofAddress(getxtimes$get(segment), session); - } - static final FunctionDescriptor setbkuptime$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle setbkuptime$MH = RuntimeHelper.downcallHandle( - fuse_operations.setbkuptime$FUNC - ); - public interface setbkuptime { - - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); - static MemorySegment allocate(setbkuptime fi, MemorySession session) { - return RuntimeHelper.upcallStub(setbkuptime.class, fi, fuse_operations.setbkuptime$FUNC, session); - } - static setbkuptime ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { - try { - return (int)fuse_operations.setbkuptime$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle setbkuptime$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("setbkuptime")); - public static VarHandle setbkuptime$VH() { - return fuse_operations.setbkuptime$VH; - } - public static MemoryAddress setbkuptime$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.setbkuptime$VH.get(seg); - } - public static void setbkuptime$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.setbkuptime$VH.set(seg, x); - } - public static MemoryAddress setbkuptime$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.setbkuptime$VH.get(seg.asSlice(index*sizeof())); - } - public static void setbkuptime$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.setbkuptime$VH.set(seg.asSlice(index*sizeof()), x); - } - public static setbkuptime setbkuptime (MemorySegment segment, MemorySession session) { - return setbkuptime.ofAddress(setbkuptime$get(segment), session); - } - static final FunctionDescriptor setchgtime$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle setchgtime$MH = RuntimeHelper.downcallHandle( - fuse_operations.setchgtime$FUNC - ); - public interface setchgtime { - - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); - static MemorySegment allocate(setchgtime fi, MemorySession session) { - return RuntimeHelper.upcallStub(setchgtime.class, fi, fuse_operations.setchgtime$FUNC, session); - } - static setchgtime ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { - try { - return (int)fuse_operations.setchgtime$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle setchgtime$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("setchgtime")); - public static VarHandle setchgtime$VH() { - return fuse_operations.setchgtime$VH; - } - public static MemoryAddress setchgtime$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.setchgtime$VH.get(seg); - } - public static void setchgtime$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.setchgtime$VH.set(seg, x); - } - public static MemoryAddress setchgtime$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.setchgtime$VH.get(seg.asSlice(index*sizeof())); - } - public static void setchgtime$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.setchgtime$VH.set(seg.asSlice(index*sizeof()), x); - } - public static setchgtime setchgtime (MemorySegment segment, MemorySession session) { - return setchgtime.ofAddress(setchgtime$get(segment), session); - } - static final FunctionDescriptor setcrtime$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle setcrtime$MH = RuntimeHelper.downcallHandle( - fuse_operations.setcrtime$FUNC - ); - public interface setcrtime { - - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); - static MemorySegment allocate(setcrtime fi, MemorySession session) { - return RuntimeHelper.upcallStub(setcrtime.class, fi, fuse_operations.setcrtime$FUNC, session); - } - static setcrtime ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { - try { - return (int)fuse_operations.setcrtime$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle setcrtime$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("setcrtime")); - public static VarHandle setcrtime$VH() { - return fuse_operations.setcrtime$VH; - } - public static MemoryAddress setcrtime$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.setcrtime$VH.get(seg); - } - public static void setcrtime$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.setcrtime$VH.set(seg, x); - } - public static MemoryAddress setcrtime$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.setcrtime$VH.get(seg.asSlice(index*sizeof())); - } - public static void setcrtime$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.setcrtime$VH.set(seg.asSlice(index*sizeof()), x); - } - public static setcrtime setcrtime (MemorySegment segment, MemorySession session) { - return setcrtime.ofAddress(setcrtime$get(segment), session); - } - static final FunctionDescriptor chflags$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_LONG$LAYOUT - ); - static final MethodHandle chflags$MH = RuntimeHelper.downcallHandle( - fuse_operations.chflags$FUNC - ); - public interface chflags { - - int apply(java.lang.foreign.MemoryAddress _x0, int _x1); - static MemorySegment allocate(chflags fi, MemorySession session) { - return RuntimeHelper.upcallStub(chflags.class, fi, fuse_operations.chflags$FUNC, session); - } - static chflags ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, int __x1) -> { - try { - return (int)fuse_operations.chflags$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle chflags$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("chflags")); - public static VarHandle chflags$VH() { - return fuse_operations.chflags$VH; - } - public static MemoryAddress chflags$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.chflags$VH.get(seg); - } - public static void chflags$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.chflags$VH.set(seg, x); - } - public static MemoryAddress chflags$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.chflags$VH.get(seg.asSlice(index*sizeof())); - } - public static void chflags$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.chflags$VH.set(seg.asSlice(index*sizeof()), x); - } - public static chflags chflags (MemorySegment segment, MemorySession session) { - return chflags.ofAddress(chflags$get(segment), session); - } - static final FunctionDescriptor setattr_x$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle setattr_x$MH = RuntimeHelper.downcallHandle( - fuse_operations.setattr_x$FUNC - ); - public interface setattr_x { - - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); - static MemorySegment allocate(setattr_x fi, MemorySession session) { - return RuntimeHelper.upcallStub(setattr_x.class, fi, fuse_operations.setattr_x$FUNC, session); - } - static setattr_x ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { - try { - return (int)fuse_operations.setattr_x$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle setattr_x$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("setattr_x")); - public static VarHandle setattr_x$VH() { - return fuse_operations.setattr_x$VH; - } - public static MemoryAddress setattr_x$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.setattr_x$VH.get(seg); - } - public static void setattr_x$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.setattr_x$VH.set(seg, x); - } - public static MemoryAddress setattr_x$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.setattr_x$VH.get(seg.asSlice(index*sizeof())); - } - public static void setattr_x$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.setattr_x$VH.set(seg.asSlice(index*sizeof()), x); - } - public static setattr_x setattr_x (MemorySegment segment, MemorySession session) { - return setattr_x.ofAddress(setattr_x$get(segment), session); - } - static final FunctionDescriptor fsetattr_x$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT, - Constants$root.C_POINTER$LAYOUT - ); - static final MethodHandle fsetattr_x$MH = RuntimeHelper.downcallHandle( - fuse_operations.fsetattr_x$FUNC - ); - public interface fsetattr_x { - - int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2); - static MemorySegment allocate(fsetattr_x fi, MemorySession session) { - return RuntimeHelper.upcallStub(fsetattr_x.class, fi, fuse_operations.fsetattr_x$FUNC, session); - } - static fsetattr_x ofAddress(MemoryAddress addr, MemorySession session) { - MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); - return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2) -> { - try { - return (int)fuse_operations.fsetattr_x$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } - }; - } - } - - static final VarHandle fsetattr_x$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fsetattr_x")); - public static VarHandle fsetattr_x$VH() { - return fuse_operations.fsetattr_x$VH; - } - public static MemoryAddress fsetattr_x$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.fsetattr_x$VH.get(seg); - } - public static void fsetattr_x$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.fsetattr_x$VH.set(seg, x); - } - public static MemoryAddress fsetattr_x$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.fsetattr_x$VH.get(seg.asSlice(index*sizeof())); - } - public static void fsetattr_x$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.fsetattr_x$VH.set(seg.asSlice(index*sizeof()), x); - } - public static fsetattr_x fsetattr_x (MemorySegment segment, MemorySession session) { - return fsetattr_x.ofAddress(fsetattr_x$get(segment), session); - } 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-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/Constants$root.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/Constants$root.java new file mode 100644 index 00000000..347c2999 --- /dev/null +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/Constants$root.java @@ -0,0 +1,23 @@ +// Generated by jextract + +package org.cryptomator.jfuse.win.amd64.extr_fuse2; + +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 OfInt C_LONG$LAYOUT = JAVA_INT.withBitAlignment(32); + 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-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/RuntimeHelper.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/RuntimeHelper.java new file mode 100644 index 00000000..2c48094d --- /dev/null +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/RuntimeHelper.java @@ -0,0 +1,233 @@ +package org.cryptomator.jfuse.win.amd64.extr_fuse2; +// 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-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/constants$0.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/constants$0.java new file mode 100644 index 00000000..c934c5f4 --- /dev/null +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/constants$0.java @@ -0,0 +1,24 @@ +// Generated by jextract + +package org.cryptomator.jfuse.win.amd64.extr_fuse2; + +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$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$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 + ); +} + + diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/fuse_2_h.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/fuse_2_h.java new file mode 100644 index 00000000..1c02ca22 --- /dev/null +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/fuse_2_h.java @@ -0,0 +1,34 @@ +// Generated by jextract + +package org.cryptomator.jfuse.win.amd64.extr_fuse2; + +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 fuse_2_h { + + /* package-private */ fuse_2_h() {} + public static OfByte C_CHAR = Constants$root.C_CHAR$LAYOUT; + public static OfShort C_SHORT = Constants$root.C_SHORT$LAYOUT; + public static OfInt C_INT = Constants$root.C_LONG$LAYOUT; + public static OfInt C_LONG = Constants$root.C_LONG$LAYOUT; + public static OfLong C_LONG_LONG = Constants$root.C_LONG_LONG$LAYOUT; + 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 int fuse_parse_cmdline ( Addressable args, Addressable mountpoint, Addressable multithreaded, Addressable foreground) { + var mh$ = fuse_parse_cmdline$MH(); + try { + return (int)mh$.invokeExact(args, mountpoint, multithreaded, foreground); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } +} + + diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/fuse_args.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/fuse_args.java new file mode 100644 index 00000000..1b208e48 --- /dev/null +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/fuse_args.java @@ -0,0 +1,78 @@ +// Generated by jextract + +package org.cryptomator.jfuse.win.amd64.extr_fuse2; + +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 fuse_args { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("argc"), + MemoryLayout.paddingLayout(32), + Constants$root.C_POINTER$LAYOUT.withName("argv"), + Constants$root.C_LONG$LAYOUT.withName("allocated"), + MemoryLayout.paddingLayout(32) + ).withName("fuse_args"); + public static MemoryLayout $LAYOUT() { + return fuse_args.$struct$LAYOUT; + } + static final VarHandle argc$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("argc")); + public static VarHandle argc$VH() { + return fuse_args.argc$VH; + } + public static int argc$get(MemorySegment seg) { + return (int)fuse_args.argc$VH.get(seg); + } + public static void argc$set( MemorySegment seg, int x) { + fuse_args.argc$VH.set(seg, x); + } + public static int argc$get(MemorySegment seg, long index) { + return (int)fuse_args.argc$VH.get(seg.asSlice(index*sizeof())); + } + public static void argc$set(MemorySegment seg, long index, int x) { + fuse_args.argc$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle argv$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("argv")); + public static VarHandle argv$VH() { + return fuse_args.argv$VH; + } + public static MemoryAddress argv$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)fuse_args.argv$VH.get(seg); + } + public static void argv$set( MemorySegment seg, MemoryAddress x) { + fuse_args.argv$VH.set(seg, x); + } + public static MemoryAddress argv$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)fuse_args.argv$VH.get(seg.asSlice(index*sizeof())); + } + public static void argv$set(MemorySegment seg, long index, MemoryAddress x) { + fuse_args.argv$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle allocated$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("allocated")); + public static VarHandle allocated$VH() { + return fuse_args.allocated$VH; + } + public static int allocated$get(MemorySegment seg) { + return (int)fuse_args.allocated$VH.get(seg); + } + public static void allocated$set( MemorySegment seg, int x) { + fuse_args.allocated$VH.set(seg, x); + } + public static int allocated$get(MemorySegment seg, long index) { + return (int)fuse_args.allocated$VH.get(seg.asSlice(index*sizeof())); + } + public static void allocated$set(MemorySegment seg, long index, int x) { + fuse_args.allocated$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/test/java/org/cryptomator/jfuse/win/amd64/FuseImplTest.java b/jfuse-win-amd64/src/test/java/org/cryptomator/jfuse/win/amd64/FuseImplTest.java index 40bf81b4..66ae6035 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 @@ -1,11 +1,13 @@ package org.cryptomator.jfuse.win.amd64; +import org.cryptomator.jfuse.api.FileInfo; import org.cryptomator.jfuse.api.FuseOperations; import org.cryptomator.jfuse.api.MountFailedException; import org.cryptomator.jfuse.win.amd64.extr.fuse_file_info; import org.cryptomator.jfuse.win.amd64.extr.fuse_h; import org.cryptomator.jfuse.win.amd64.extr.fuse_stat; import org.cryptomator.jfuse.win.amd64.extr.fuse_timespec; +import org.cryptomator.jfuse.win.amd64.extr_fuse2.fuse_2_h; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -14,6 +16,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; +import org.mockito.ArgumentMatcher; import org.mockito.MockedStatic; import org.mockito.Mockito; @@ -53,23 +56,22 @@ public void teardown() { @Test @DisplayName("MountFailedException when fuse_new fails") public void testFuseNewFails() { - fuseH.when(() -> fuse_h.fuse_mount(Mockito.any(), Mockito.any())).thenReturn(MemoryAddress.ofLong(42L)); - fuseH.when(() -> fuse_h.fuse_new(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyLong(), Mockito.any())).thenReturn(MemoryAddress.NULL); + fuseH.when(() -> fuse_h.fuse_new(Mockito.any(), Mockito.any(), Mockito.anyLong(), Mockito.any())).thenReturn(MemoryAddress.NULL); var thrown = Assertions.assertThrows(MountFailedException.class, () -> fuseImplSpy.mount(args)); - fuseH.verify(() -> fuse_h.fuse_unmount(Mockito.any(), Mockito.any())); + fuseH.verify(() -> fuse_h.fuse_mount(Mockito.any(), Mockito.any()), Mockito.never()); Assertions.assertEquals("fuse_new failed", thrown.getMessage()); } @Test @DisplayName("MountFailedException when fuse_mount fails") public void testFuseMountFails() { - fuseH.when(() -> fuse_h.fuse_mount(Mockito.any(), Mockito.any())).thenReturn(MemoryAddress.NULL); + fuseH.when(() -> fuse_h.fuse_new(Mockito.any(), Mockito.any(), Mockito.anyLong(), Mockito.any())).thenReturn(MemoryAddress.ofLong(42L)); + fuseH.when(() -> fuse_h.fuse_mount(Mockito.any(), Mockito.any())).thenReturn(1); var thrown = Assertions.assertThrows(MountFailedException.class, () -> fuseImplSpy.mount(args)); - fuseH.verify(() -> fuse_h.fuse_new(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyLong(), Mockito.any()), Mockito.never()); Assertions.assertEquals("fuse_mount failed", thrown.getMessage()); } } @@ -77,9 +79,9 @@ public void testFuseMountFails() { @Test @DisplayName("parseArgs") public void testParseArgs() { - try (var fuseH = Mockito.mockStatic(fuse_h.class); + try (var fuseH = Mockito.mockStatic(fuse_2_h.class); var scope = MemorySession.openConfined()) { - fuseH.when(() -> fuse_h.fuse_parse_cmdline(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).then(invocation -> { + fuseH.when(() -> fuse_2_h.fuse_parse_cmdline(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).then(invocation -> { MemorySegment mp = invocation.getArgument(1); MemorySegment mt = invocation.getArgument(2); MemorySegment fg = invocation.getArgument(3); @@ -109,9 +111,10 @@ public void testUtimensNow() { try (var scope = MemorySession.openConfined()) { var path = scope.allocateUtf8String("/foo"); var times = MemoryAddress.NULL; - Mockito.doReturn(42).when(fuseOps).utimens(Mockito.eq("/foo"), Mockito.argThat(t -> t.get().getNano() == 0L), Mockito.argThat(t -> t.get().getNano() == 0L), Mockito.isNull()); + var fi = scope.allocate(fuse_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); + var result = fuseImpl.utimens(path.address(), times, fi.address()); Assertions.assertEquals(42, result); } @@ -129,13 +132,14 @@ public void testUtimens(long sec0, long nsec0, long sec1, long nsec1) { try (var scope = MemorySession.openConfined()) { var path = scope.allocateUtf8String("/foo"); var times = fuse_timespec.allocateArray(2, scope); + var fi = scope.allocate(fuse_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.isNull()); + 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()); + var result = fuseImpl.utimens(path.address(), times.address(), fi.address()); Assertions.assertEquals(42, result); } @@ -153,9 +157,10 @@ public void testGetattr() { try (var scope = MemorySession.openConfined()) { var path = scope.allocateUtf8String("/foo"); var attr = fuse_stat.allocate(scope); - Mockito.doReturn(42).when(fuseOps).getattr(Mockito.eq("/foo"), Mockito.any(), Mockito.isNull()); + var fi = scope.allocate(fuse_file_info.$LAYOUT()); + Mockito.doReturn(42).when(fuseOps).getattr(Mockito.eq("/foo"), Mockito.any(), Mockito.argThat(usesSameMemorySegement(fi))); - var result = fuseImpl.getattr(path.address(), attr.address()); + var result = fuseImpl.getattr(path.address(), attr.address(), fi.address()); Assertions.assertEquals(42, result); } @@ -168,7 +173,7 @@ public void testFgetattr() { var path = scope.allocateUtf8String("/foo"); var attr = fuse_stat.allocate(scope); var fi = fuse_file_info.allocate(scope); - Mockito.doReturn(42).when(fuseOps).getattr(Mockito.eq("/foo"), Mockito.any(), Mockito.notNull()); + Mockito.doReturn(42).when(fuseOps).getattr(Mockito.eq("/foo"), Mockito.any(), Mockito.argThat(usesSameMemorySegement(fi))); var result = fuseImpl.fgetattr(path.address(), attr.address(), fi.address()); @@ -187,9 +192,10 @@ public class Truncate { public void testTruncate() { try (var scope = MemorySession.openConfined()) { var path = scope.allocateUtf8String("/foo"); - Mockito.doReturn(42).when(fuseOps).truncate(Mockito.eq("/foo"), Mockito.eq(1337L), Mockito.isNull()); + var fi = scope.allocate(fuse_file_info.$LAYOUT()); + Mockito.doReturn(42).when(fuseOps).truncate(Mockito.eq("/foo"), Mockito.eq(1337L), Mockito.argThat(usesSameMemorySegement(fi))); - var result = fuseImpl.truncate(path.address(), 1337L); + var result = fuseImpl.truncate(path.address(), 1337L, fi.address()); Assertions.assertEquals(42, result); } @@ -201,7 +207,7 @@ public void testFtruncate() { try (var scope = MemorySession.openConfined()) { var path = scope.allocateUtf8String("/foo"); var fi = fuse_file_info.allocate(scope); - Mockito.doReturn(42).when(fuseOps).truncate(Mockito.eq("/foo"), Mockito.eq(1337L), Mockito.notNull()); + Mockito.doReturn(42).when(fuseOps).truncate(Mockito.eq("/foo"), Mockito.eq(1337L), Mockito.argThat(usesSameMemorySegement(fi))); var result = fuseImpl.ftruncate(path.address(), 1337L, fi.address()); @@ -211,4 +217,13 @@ public void testFtruncate() { } + private static ArgumentMatcher usesSameMemorySegement(MemorySegment expected) { + return obj -> { + if (obj instanceof FileInfoImpl fiImpl) { + return fiImpl.segment().address().equals(expected.address()) && fiImpl.segment().byteSize() == expected.byteSize(); + } + return false; + }; + } + } \ No newline at end of file From d8a7514ef329f2677413ca16c2cfbb9e68c1b5c9 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Thu, 8 Sep 2022 11:51:12 +0200 Subject: [PATCH 47/98] fix winfsp to 1.11 --- winfsp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winfsp b/winfsp index ec832b45..5251dcbc 160000 --- a/winfsp +++ b/winfsp @@ -1 +1 @@ -Subproject commit ec832b45ff690ce4c4f9d4c4c66808fdd790ab7f +Subproject commit 5251dcbce93a334cc2b69565eb43de42eeaa2a64 From 273a4ad2cdbcdcbc64be008afacdd80a5e12fbf2 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Thu, 8 Sep 2022 17:27:15 +0200 Subject: [PATCH 48/98] use correct package in FuseArgs imports --- .../src/main/java/org/cryptomator/jfuse/win/amd64/FuseArgs.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseArgs.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseArgs.java index 1db7e8df..46caa472 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseArgs.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseArgs.java @@ -1,6 +1,6 @@ package org.cryptomator.jfuse.win.amd64; -import org.cryptomator.jfuse.win.amd64.extr.fuse_args; +import org.cryptomator.jfuse.win.amd64.extr_fuse2.fuse_args; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemorySegment; From ba18b3d5250f4023d4b2eba64a95be7a02592dfe Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Thu, 8 Sep 2022 17:29:46 +0200 Subject: [PATCH 49/98] Use explicitly fuse3 interface by setting preprocessor var WINFSP_DLL_INTERNAL --- jfuse-win-amd64/pom.xml | 31 +- .../jfuse/win/amd64/DirFillerImpl.java | 6 +- .../jfuse/win/amd64/FileInfoImpl.java | 12 +- .../jfuse/win/amd64/FuseConnInfoImpl.java | 8 +- .../cryptomator/jfuse/win/amd64/FuseImpl.java | 55 +- .../jfuse/win/amd64/FuseMountImpl.java | 18 +- .../jfuse/win/amd64/extr/constants$0.java | 38 +- .../jfuse/win/amd64/extr/constants$1.java | 40 +- ...se_conn_info.java => fuse3_conn_info.java} | 106 +-- ...se_file_info.java => fuse3_file_info.java} | 46 +- ..._fill_dir_t.java => fuse3_fill_dir_t.java} | 10 +- ...oop_config.java => fuse3_loop_config.java} | 26 +- ..._operations.java => fuse3_operations.java} | 646 +++++++++--------- .../jfuse/win/amd64/extr/fuse_args.java | 78 --- .../jfuse/win/amd64/extr/fuse_h.java | 72 +- .../jfuse/win/amd64/FileInfoImplTest.java | 6 +- .../jfuse/win/amd64/FuseImplTest.java | 22 +- 17 files changed, 571 insertions(+), 649 deletions(-) rename jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/{fuse_conn_info.java => fuse3_conn_info.java} (67%) rename jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/{fuse_file_info.java => fuse3_file_info.java} (73%) rename jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/{fuse_fill_dir_t.java => fuse3_fill_dir_t.java} (60%) rename jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/{fuse_loop_config.java => fuse3_loop_config.java} (71%) rename jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/{fuse_operations.java => fuse3_operations.java} (76%) delete mode 100644 jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_args.java diff --git a/jfuse-win-amd64/pom.xml b/jfuse-win-amd64/pom.xml index b23a08a2..4bf70623 100644 --- a/jfuse-win-amd64/pom.xml +++ b/jfuse-win-amd64/pom.xml @@ -91,32 +91,31 @@ ${project.parent.basedir}/winfsp/inc/fuse3/fuse.h fuse_h - + WINFSP_DLL_INTERNAL FUSE_USE_VERSION=35 - fuse_lib_help - fuse_new - fuse_mount - fuse_get_session - fuse_loop - fuse_loop_mt - fuse_exit - fuse_unmount - fuse_destroy + fuse3_lib_help + fuse3_new + fuse3_mount + fuse3_get_session + fuse3_loop + fuse3_loop_mt + fuse3_exit + fuse3_unmount + fuse3_destroy - fuse_fill_dir_t + fuse3_fill_dir_t - fuse_operations - fuse_file_info + fuse3_operations + fuse3_file_info fuse_stat fuse_statvfs fuse_timespec - fuse_conn_info - fuse_args - fuse_loop_config + fuse3_conn_info + fuse3_loop_config FUSE_FILL_DIR_PLUS diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java index a612452e..48490fa4 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java @@ -2,15 +2,15 @@ import org.cryptomator.jfuse.api.DirFiller; import org.cryptomator.jfuse.api.Stat; -import org.cryptomator.jfuse.win.amd64.extr.fuse_fill_dir_t; +import org.cryptomator.jfuse.win.amd64.extr.fuse3_fill_dir_t; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemorySession; -record DirFillerImpl(MemoryAddress buf, fuse_fill_dir_t callback, MemorySession scope) implements DirFiller { +record DirFillerImpl(MemoryAddress buf, fuse3_fill_dir_t callback, MemorySession scope) implements DirFiller { DirFillerImpl(MemoryAddress buf, MemoryAddress callback, MemorySession scope) { - this(buf, fuse_fill_dir_t.ofAddress(callback, scope), scope); + this(buf, fuse3_fill_dir_t.ofAddress(callback, scope), scope); } @Override diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FileInfoImpl.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FileInfoImpl.java index 9768a7ed..b4615ee5 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FileInfoImpl.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FileInfoImpl.java @@ -2,7 +2,7 @@ import org.cryptomator.jfuse.api.FileInfo; import org.cryptomator.jfuse.win.amd64.extr.fcntl_h; -import org.cryptomator.jfuse.win.amd64.extr.fuse_file_info; +import org.cryptomator.jfuse.win.amd64.extr.fuse3_file_info; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemorySegment; @@ -22,22 +22,22 @@ record FileInfoImpl(MemorySegment segment) implements FileInfo { private static final int O_EXCL = fcntl_h.O_EXCL(); public FileInfoImpl(MemoryAddress address, MemorySession scope) { - this(fuse_file_info.ofAddress(address, scope)); + this(fuse3_file_info.ofAddress(address, scope)); } @Override public long getFh() { - return fuse_file_info.fh$get(segment); + return fuse3_file_info.fh$get(segment); } @Override public void setFh(long fh) { - fuse_file_info.fh$set(segment, fh); + fuse3_file_info.fh$set(segment, fh); } @Override public int getFlags() { - return fuse_file_info.flags$get(segment); + return fuse3_file_info.flags$get(segment); } @Override @@ -72,7 +72,7 @@ public Set getOpenFlags() { @Override public long getLockOwner() { - return fuse_file_info.lock_owner$get(segment); + return fuse3_file_info.lock_owner$get(segment); } } diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseConnInfoImpl.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseConnInfoImpl.java index 167c52ec..76acf617 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseConnInfoImpl.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseConnInfoImpl.java @@ -1,7 +1,7 @@ package org.cryptomator.jfuse.win.amd64; import org.cryptomator.jfuse.api.FuseConnInfo; -import org.cryptomator.jfuse.win.amd64.extr.fuse_conn_info; +import org.cryptomator.jfuse.win.amd64.extr.fuse3_conn_info; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemorySegment; @@ -10,16 +10,16 @@ record FuseConnInfoImpl(MemorySegment segment) implements FuseConnInfo { public FuseConnInfoImpl(MemoryAddress address, MemorySession scope) { - this(fuse_conn_info.ofAddress(address, scope)); + this(fuse3_conn_info.ofAddress(address, scope)); } @Override public int protoMajor() { - return fuse_conn_info.proto_major$get(segment); + return fuse3_conn_info.proto_major$get(segment); } @Override public int protoMinor() { - return fuse_conn_info.proto_minor$get(segment); + return fuse3_conn_info.proto_minor$get(segment); } } 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 b63ae354..7cfc9536 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 @@ -4,9 +4,9 @@ import org.cryptomator.jfuse.api.FuseMount; import org.cryptomator.jfuse.api.FuseOperations; import org.cryptomator.jfuse.api.MountFailedException; -import org.cryptomator.jfuse.win.amd64.extr.fuse_args; +import org.cryptomator.jfuse.win.amd64.extr.fuse3_operations; +import org.cryptomator.jfuse.win.amd64.extr_fuse2.fuse_args; import org.cryptomator.jfuse.win.amd64.extr.fuse_h; -import org.cryptomator.jfuse.win.amd64.extr.fuse_operations; import org.cryptomator.jfuse.win.amd64.extr.fuse_timespec; import org.cryptomator.jfuse.win.amd64.extr_fuse2.fuse_2_h; import org.jetbrains.annotations.VisibleForTesting; @@ -28,7 +28,7 @@ public final class FuseImpl extends Fuse { private final MemorySegment fuseOps; public FuseImpl(FuseOperations fuseOperations) { - this.fuseOps = fuse_operations.allocate(fuseScope); + this.fuseOps = fuse3_operations.allocate(fuseScope); this.delegate = fuseOperations; fuseOperations.supportedOperations().forEach(this::bind); } @@ -46,11 +46,11 @@ public void mount(String progName, Path mountPoint, String... flags) throws Moun @Override protected FuseMount mount(List args) throws MountFailedException { var fuseArgs = parseArgs(args); - var fuse = fuse_h.fuse_new(fuseArgs.args(), fuseOps, fuseOps.byteSize(), MemoryAddress.NULL); + var fuse = fuse_h.fuse3_new(fuseArgs.args(), fuseOps, fuseOps.byteSize(), MemoryAddress.NULL); if (MemoryAddress.NULL.equals(fuse)) { throw new MountFailedException("fuse_new failed"); } - if (fuse_h.fuse_mount(fuse, fuseArgs.mountPoint()) != 0) { + if (fuse_h.fuse3_mount(fuse, fuseArgs.mountPoint()) != 0) { throw new MountFailedException("fuse_mount failed"); } return new FuseMountImpl(fuse, fuseArgs); @@ -84,28 +84,29 @@ FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { private void bind(FuseOperations.Operation operation) { switch (operation) { - case INIT -> fuse_operations.access$set(fuseOps, fuse_operations.init.allocate(this::init, fuseScope).address()); - case ACCESS -> fuse_operations.access$set(fuseOps, fuse_operations.access.allocate(this::access, fuseScope).address()); - case CHMOD -> fuse_operations.chmod$set(fuseOps, fuse_operations.chmod.allocate(this::chmod, fuseScope).address()); - case CREATE -> fuse_operations.create$set(fuseOps, fuse_operations.create.allocate(this::create, fuseScope).address()); - case DESTROY -> fuse_operations.destroy$set(fuseOps, fuse_operations.destroy.allocate(this::destroy, fuseScope).address()); - case GET_ATTR -> fuse_operations.getattr$set(fuseOps, fuse_operations.getattr.allocate(this::getattr, fuseScope).address()); - case MKDIR -> fuse_operations.mkdir$set(fuseOps, fuse_operations.mkdir.allocate(this::mkdir, fuseScope).address()); - case OPEN -> fuse_operations.open$set(fuseOps, fuse_operations.open.allocate(this::open, fuseScope).address()); - case OPEN_DIR -> fuse_operations.opendir$set(fuseOps, fuse_operations.opendir.allocate(this::opendir, fuseScope).address()); - case READ -> fuse_operations.read$set(fuseOps, fuse_operations.read.allocate(this::read, fuseScope).address()); - case READ_DIR -> fuse_operations.readdir$set(fuseOps, fuse_operations.readdir.allocate(this::readdir, fuseScope).address()); - case READLINK -> fuse_operations.readlink$set(fuseOps, fuse_operations.readlink.allocate(this::readlink, fuseScope).address()); - case RELEASE -> fuse_operations.release$set(fuseOps, fuse_operations.release.allocate(this::release, fuseScope).address()); - case RELEASE_DIR -> fuse_operations.releasedir$set(fuseOps, fuse_operations.releasedir.allocate(this::releasedir, fuseScope).address()); - case RENAME -> fuse_operations.rename$set(fuseOps, fuse_operations.rename.allocate(this::rename, fuseScope).address()); - case RMDIR -> fuse_operations.rmdir$set(fuseOps, fuse_operations.rmdir.allocate(this::rmdir, fuseScope).address()); - case STATFS -> fuse_operations.statfs$set(fuseOps, fuse_operations.statfs.allocate(this::statfs, fuseScope).address()); - case SYMLINK -> fuse_operations.symlink$set(fuseOps, fuse_operations.symlink.allocate(this::symlink, fuseScope).address()); - case TRUNCATE -> fuse_operations.truncate$set(fuseOps, fuse_operations.truncate.allocate(this::truncate, fuseScope).address()); - case UNLINK -> fuse_operations.unlink$set(fuseOps, fuse_operations.unlink.allocate(this::unlink, fuseScope).address()); - case UTIMENS -> fuse_operations.utimens$set(fuseOps, fuse_operations.utimens.allocate(this::utimens, fuseScope).address()); - case WRITE -> fuse_operations.write$set(fuseOps, fuse_operations.write.allocate(this::write, fuseScope).address()); + case INIT -> fuse3_operations.access$set(fuseOps, fuse3_operations.init.allocate(this::init, fuseScope).address()); + //case ACCESS -> fuse3_operations.access$set(fuseOps, fuse3_operations.access.allocate(this::access, fuseScope).address()); + case ACCESS -> fuse3_operations.access$set(fuseOps, MemoryAddress.NULL); + case CHMOD -> fuse3_operations.chmod$set(fuseOps, fuse3_operations.chmod.allocate(this::chmod, fuseScope).address()); + case CREATE -> fuse3_operations.create$set(fuseOps, fuse3_operations.create.allocate(this::create, fuseScope).address()); + case DESTROY -> fuse3_operations.destroy$set(fuseOps, fuse3_operations.destroy.allocate(this::destroy, fuseScope).address()); + case GET_ATTR -> fuse3_operations.getattr$set(fuseOps, fuse3_operations.getattr.allocate(this::getattr, fuseScope).address()); + case MKDIR -> fuse3_operations.mkdir$set(fuseOps, fuse3_operations.mkdir.allocate(this::mkdir, fuseScope).address()); + case OPEN -> fuse3_operations.open$set(fuseOps, fuse3_operations.open.allocate(this::open, fuseScope).address()); + case OPEN_DIR -> fuse3_operations.opendir$set(fuseOps, fuse3_operations.opendir.allocate(this::opendir, fuseScope).address()); + case READ -> fuse3_operations.read$set(fuseOps, fuse3_operations.read.allocate(this::read, fuseScope).address()); + case READ_DIR -> fuse3_operations.readdir$set(fuseOps, fuse3_operations.readdir.allocate(this::readdir, fuseScope).address()); + case READLINK -> fuse3_operations.readlink$set(fuseOps, fuse3_operations.readlink.allocate(this::readlink, fuseScope).address()); + case RELEASE -> fuse3_operations.release$set(fuseOps, fuse3_operations.release.allocate(this::release, fuseScope).address()); + case RELEASE_DIR -> fuse3_operations.releasedir$set(fuseOps, fuse3_operations.releasedir.allocate(this::releasedir, fuseScope).address()); + case RENAME -> fuse3_operations.rename$set(fuseOps, fuse3_operations.rename.allocate(this::rename, fuseScope).address()); + case RMDIR -> fuse3_operations.rmdir$set(fuseOps, fuse3_operations.rmdir.allocate(this::rmdir, fuseScope).address()); + case STATFS -> fuse3_operations.statfs$set(fuseOps, fuse3_operations.statfs.allocate(this::statfs, fuseScope).address()); + case SYMLINK -> fuse3_operations.symlink$set(fuseOps, fuse3_operations.symlink.allocate(this::symlink, fuseScope).address()); + case TRUNCATE -> fuse3_operations.truncate$set(fuseOps, fuse3_operations.truncate.allocate(this::truncate, fuseScope).address()); + case UNLINK -> fuse3_operations.unlink$set(fuseOps, fuse3_operations.unlink.allocate(this::unlink, fuseScope).address()); + case UTIMENS -> fuse3_operations.utimens$set(fuseOps, fuse3_operations.utimens.allocate(this::utimens, fuseScope).address()); + case WRITE -> fuse3_operations.write$set(fuseOps, fuse3_operations.write.allocate(this::write, fuseScope).address()); } } 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 0374b355..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,8 +1,8 @@ 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 org.cryptomator.jfuse.win.amd64.extr.fuse_loop_config; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemorySession; @@ -13,25 +13,25 @@ record FuseMountImpl(MemoryAddress fuse, FuseArgs fuseArgs) implements FuseMount 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); - return fuse_h.fuse_loop_mt(fuse, loopCfg); + 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.fuse_loop(fuse); + return fuse_h.fuse3_loop(fuse); } } @Override public void unmount() { - fuse_h.fuse_exit(fuse); - fuse_h.fuse_unmount(fuse); + fuse_h.fuse3_exit(fuse); + fuse_h.fuse3_unmount(fuse); } @Override public void destroy() { - fuse_h.fuse_destroy(fuse); + fuse_h.fuse3_destroy(fuse); } } \ No newline at end of file diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$0.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$0.java index 739fefd3..6f64cd87 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$0.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/constants$0.java @@ -9,47 +9,47 @@ import static java.lang.foreign.ValueLayout.*; class constants$0 { - static final FunctionDescriptor fuse_fill_dir_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + static final FunctionDescriptor fuse3_fill_dir_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$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_LONG$LAYOUT ); - static final MethodHandle fuse_fill_dir_t$MH = RuntimeHelper.downcallHandle( - constants$0.fuse_fill_dir_t$FUNC + static final MethodHandle fuse3_fill_dir_t$MH = RuntimeHelper.downcallHandle( + constants$0.fuse3_fill_dir_t$FUNC ); - static final FunctionDescriptor fuse_lib_help$FUNC = FunctionDescriptor.ofVoid( + static final FunctionDescriptor fuse3_lib_help$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 fuse3_lib_help$MH = RuntimeHelper.downcallHandle( + "fuse3_lib_help", + constants$0.fuse3_lib_help$FUNC ); - static final FunctionDescriptor fuse_new$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + static final FunctionDescriptor fuse3_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_new$MH = RuntimeHelper.downcallHandle( - "fuse_new", - constants$0.fuse_new$FUNC + static final MethodHandle fuse3_new$MH = RuntimeHelper.downcallHandle( + "fuse3_new", + constants$0.fuse3_new$FUNC ); - static final FunctionDescriptor fuse_destroy$FUNC = FunctionDescriptor.ofVoid( + static final FunctionDescriptor fuse3_destroy$FUNC = FunctionDescriptor.ofVoid( Constants$root.C_POINTER$LAYOUT ); - static final MethodHandle fuse_destroy$MH = RuntimeHelper.downcallHandle( - "fuse_destroy", - constants$0.fuse_destroy$FUNC + static final MethodHandle fuse3_destroy$MH = RuntimeHelper.downcallHandle( + "fuse3_destroy", + constants$0.fuse3_destroy$FUNC ); - static final FunctionDescriptor fuse_mount$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + static final FunctionDescriptor fuse3_mount$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, Constants$root.C_POINTER$LAYOUT, Constants$root.C_POINTER$LAYOUT ); - static final MethodHandle fuse_mount$MH = RuntimeHelper.downcallHandle( - "fuse_mount", - constants$0.fuse_mount$FUNC + static final MethodHandle fuse3_mount$MH = RuntimeHelper.downcallHandle( + "fuse3_mount", + constants$0.fuse3_mount$FUNC ); } 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 77ce4e13..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 @@ -9,41 +9,41 @@ import static java.lang.foreign.ValueLayout.*; class constants$1 { - static final FunctionDescriptor fuse_unmount$FUNC = FunctionDescriptor.ofVoid( + static final FunctionDescriptor fuse3_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 MethodHandle fuse3_unmount$MH = RuntimeHelper.downcallHandle( + "fuse3_unmount", + constants$1.fuse3_unmount$FUNC ); - static final FunctionDescriptor fuse_loop$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + static final FunctionDescriptor fuse3_loop$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, Constants$root.C_POINTER$LAYOUT ); - static final MethodHandle fuse_loop$MH = RuntimeHelper.downcallHandle( - "fuse_loop", - constants$1.fuse_loop$FUNC + static final MethodHandle fuse3_loop$MH = RuntimeHelper.downcallHandle( + "fuse3_loop", + constants$1.fuse3_loop$FUNC ); - static final FunctionDescriptor fuse_loop_mt$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_POINTER$LAYOUT ); - static final MethodHandle fuse_loop_mt$MH = RuntimeHelper.downcallHandle( - "fuse_loop_mt", - constants$1.fuse_loop_mt$FUNC + static final MethodHandle fuse3_loop_mt$MH = RuntimeHelper.downcallHandle( + "fuse3_loop_mt", + constants$1.fuse3_loop_mt$FUNC ); - static final FunctionDescriptor fuse_exit$FUNC = FunctionDescriptor.ofVoid( + static final FunctionDescriptor fuse3_exit$FUNC = FunctionDescriptor.ofVoid( Constants$root.C_POINTER$LAYOUT ); - static final MethodHandle fuse_exit$MH = RuntimeHelper.downcallHandle( - "fuse_exit", - constants$1.fuse_exit$FUNC + static final MethodHandle fuse3_exit$MH = RuntimeHelper.downcallHandle( + "fuse3_exit", + constants$1.fuse3_exit$FUNC ); - static final FunctionDescriptor fuse_get_session$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + static final FunctionDescriptor fuse3_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$1.fuse_get_session$FUNC + static final MethodHandle fuse3_get_session$MH = RuntimeHelper.downcallHandle( + "fuse3_get_session", + constants$1.fuse3_get_session$FUNC ); } diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_conn_info.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_conn_info.java similarity index 67% rename from jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_conn_info.java rename to jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_conn_info.java index b1a4b77d..f10ddfeb 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_conn_info.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_conn_info.java @@ -7,7 +7,7 @@ import java.nio.ByteOrder; import java.lang.foreign.*; import static java.lang.foreign.ValueLayout.*; -public class fuse_conn_info { +public class fuse3_conn_info { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( Constants$root.C_LONG$LAYOUT.withName("proto_major"), @@ -21,169 +21,169 @@ public class fuse_conn_info { Constants$root.C_LONG$LAYOUT.withName("congestion_threshold"), Constants$root.C_LONG$LAYOUT.withName("time_gran"), MemoryLayout.sequenceLayout(22, Constants$root.C_LONG$LAYOUT).withName("reserved") - ).withName("fuse_conn_info"); + ).withName("fuse3_conn_info"); public static MemoryLayout $LAYOUT() { - return fuse_conn_info.$struct$LAYOUT; + return fuse3_conn_info.$struct$LAYOUT; } static final VarHandle proto_major$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("proto_major")); public static VarHandle proto_major$VH() { - return fuse_conn_info.proto_major$VH; + return fuse3_conn_info.proto_major$VH; } public static int proto_major$get(MemorySegment seg) { - return (int)fuse_conn_info.proto_major$VH.get(seg); + return (int)fuse3_conn_info.proto_major$VH.get(seg); } public static void proto_major$set( MemorySegment seg, int x) { - fuse_conn_info.proto_major$VH.set(seg, x); + fuse3_conn_info.proto_major$VH.set(seg, x); } public static int proto_major$get(MemorySegment seg, long index) { - return (int)fuse_conn_info.proto_major$VH.get(seg.asSlice(index*sizeof())); + return (int)fuse3_conn_info.proto_major$VH.get(seg.asSlice(index*sizeof())); } public static void proto_major$set(MemorySegment seg, long index, int x) { - fuse_conn_info.proto_major$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_conn_info.proto_major$VH.set(seg.asSlice(index*sizeof()), x); } static final VarHandle proto_minor$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("proto_minor")); public static VarHandle proto_minor$VH() { - return fuse_conn_info.proto_minor$VH; + return fuse3_conn_info.proto_minor$VH; } public static int proto_minor$get(MemorySegment seg) { - return (int)fuse_conn_info.proto_minor$VH.get(seg); + return (int)fuse3_conn_info.proto_minor$VH.get(seg); } public static void proto_minor$set( MemorySegment seg, int x) { - fuse_conn_info.proto_minor$VH.set(seg, x); + fuse3_conn_info.proto_minor$VH.set(seg, x); } public static int proto_minor$get(MemorySegment seg, long index) { - return (int)fuse_conn_info.proto_minor$VH.get(seg.asSlice(index*sizeof())); + return (int)fuse3_conn_info.proto_minor$VH.get(seg.asSlice(index*sizeof())); } public static void proto_minor$set(MemorySegment seg, long index, int x) { - fuse_conn_info.proto_minor$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_conn_info.proto_minor$VH.set(seg.asSlice(index*sizeof()), x); } static final VarHandle max_write$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max_write")); public static VarHandle max_write$VH() { - return fuse_conn_info.max_write$VH; + return fuse3_conn_info.max_write$VH; } public static int max_write$get(MemorySegment seg) { - return (int)fuse_conn_info.max_write$VH.get(seg); + return (int)fuse3_conn_info.max_write$VH.get(seg); } public static void max_write$set( MemorySegment seg, int x) { - fuse_conn_info.max_write$VH.set(seg, x); + fuse3_conn_info.max_write$VH.set(seg, x); } public static int max_write$get(MemorySegment seg, long index) { - return (int)fuse_conn_info.max_write$VH.get(seg.asSlice(index*sizeof())); + return (int)fuse3_conn_info.max_write$VH.get(seg.asSlice(index*sizeof())); } public static void max_write$set(MemorySegment seg, long index, int x) { - fuse_conn_info.max_write$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_conn_info.max_write$VH.set(seg.asSlice(index*sizeof()), x); } static final VarHandle max_read$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max_read")); public static VarHandle max_read$VH() { - return fuse_conn_info.max_read$VH; + return fuse3_conn_info.max_read$VH; } public static int max_read$get(MemorySegment seg) { - return (int)fuse_conn_info.max_read$VH.get(seg); + return (int)fuse3_conn_info.max_read$VH.get(seg); } public static void max_read$set( MemorySegment seg, int x) { - fuse_conn_info.max_read$VH.set(seg, x); + fuse3_conn_info.max_read$VH.set(seg, x); } public static int max_read$get(MemorySegment seg, long index) { - return (int)fuse_conn_info.max_read$VH.get(seg.asSlice(index*sizeof())); + return (int)fuse3_conn_info.max_read$VH.get(seg.asSlice(index*sizeof())); } public static void max_read$set(MemorySegment seg, long index, int x) { - fuse_conn_info.max_read$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_conn_info.max_read$VH.set(seg.asSlice(index*sizeof()), x); } static final VarHandle max_readahead$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max_readahead")); public static VarHandle max_readahead$VH() { - return fuse_conn_info.max_readahead$VH; + return fuse3_conn_info.max_readahead$VH; } public static int max_readahead$get(MemorySegment seg) { - return (int)fuse_conn_info.max_readahead$VH.get(seg); + return (int)fuse3_conn_info.max_readahead$VH.get(seg); } public static void max_readahead$set( MemorySegment seg, int x) { - fuse_conn_info.max_readahead$VH.set(seg, x); + fuse3_conn_info.max_readahead$VH.set(seg, x); } public static int max_readahead$get(MemorySegment seg, long index) { - return (int)fuse_conn_info.max_readahead$VH.get(seg.asSlice(index*sizeof())); + return (int)fuse3_conn_info.max_readahead$VH.get(seg.asSlice(index*sizeof())); } public static void max_readahead$set(MemorySegment seg, long index, int x) { - fuse_conn_info.max_readahead$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_conn_info.max_readahead$VH.set(seg.asSlice(index*sizeof()), x); } static final VarHandle capable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("capable")); public static VarHandle capable$VH() { - return fuse_conn_info.capable$VH; + return fuse3_conn_info.capable$VH; } public static int capable$get(MemorySegment seg) { - return (int)fuse_conn_info.capable$VH.get(seg); + return (int)fuse3_conn_info.capable$VH.get(seg); } public static void capable$set( MemorySegment seg, int x) { - fuse_conn_info.capable$VH.set(seg, x); + fuse3_conn_info.capable$VH.set(seg, x); } public static int capable$get(MemorySegment seg, long index) { - return (int)fuse_conn_info.capable$VH.get(seg.asSlice(index*sizeof())); + return (int)fuse3_conn_info.capable$VH.get(seg.asSlice(index*sizeof())); } public static void capable$set(MemorySegment seg, long index, int x) { - fuse_conn_info.capable$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_conn_info.capable$VH.set(seg.asSlice(index*sizeof()), x); } static final VarHandle want$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("want")); public static VarHandle want$VH() { - return fuse_conn_info.want$VH; + return fuse3_conn_info.want$VH; } public static int want$get(MemorySegment seg) { - return (int)fuse_conn_info.want$VH.get(seg); + return (int)fuse3_conn_info.want$VH.get(seg); } public static void want$set( MemorySegment seg, int x) { - fuse_conn_info.want$VH.set(seg, x); + fuse3_conn_info.want$VH.set(seg, x); } public static int want$get(MemorySegment seg, long index) { - return (int)fuse_conn_info.want$VH.get(seg.asSlice(index*sizeof())); + return (int)fuse3_conn_info.want$VH.get(seg.asSlice(index*sizeof())); } public static void want$set(MemorySegment seg, long index, int x) { - fuse_conn_info.want$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_conn_info.want$VH.set(seg.asSlice(index*sizeof()), x); } static final VarHandle max_background$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max_background")); public static VarHandle max_background$VH() { - return fuse_conn_info.max_background$VH; + return fuse3_conn_info.max_background$VH; } public static int max_background$get(MemorySegment seg) { - return (int)fuse_conn_info.max_background$VH.get(seg); + return (int)fuse3_conn_info.max_background$VH.get(seg); } public static void max_background$set( MemorySegment seg, int x) { - fuse_conn_info.max_background$VH.set(seg, x); + fuse3_conn_info.max_background$VH.set(seg, x); } public static int max_background$get(MemorySegment seg, long index) { - return (int)fuse_conn_info.max_background$VH.get(seg.asSlice(index*sizeof())); + return (int)fuse3_conn_info.max_background$VH.get(seg.asSlice(index*sizeof())); } public static void max_background$set(MemorySegment seg, long index, int x) { - fuse_conn_info.max_background$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_conn_info.max_background$VH.set(seg.asSlice(index*sizeof()), x); } static final VarHandle congestion_threshold$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("congestion_threshold")); public static VarHandle congestion_threshold$VH() { - return fuse_conn_info.congestion_threshold$VH; + return fuse3_conn_info.congestion_threshold$VH; } public static int congestion_threshold$get(MemorySegment seg) { - return (int)fuse_conn_info.congestion_threshold$VH.get(seg); + return (int)fuse3_conn_info.congestion_threshold$VH.get(seg); } public static void congestion_threshold$set( MemorySegment seg, int x) { - fuse_conn_info.congestion_threshold$VH.set(seg, x); + fuse3_conn_info.congestion_threshold$VH.set(seg, x); } public static int congestion_threshold$get(MemorySegment seg, long index) { - return (int)fuse_conn_info.congestion_threshold$VH.get(seg.asSlice(index*sizeof())); + return (int)fuse3_conn_info.congestion_threshold$VH.get(seg.asSlice(index*sizeof())); } public static void congestion_threshold$set(MemorySegment seg, long index, int x) { - fuse_conn_info.congestion_threshold$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_conn_info.congestion_threshold$VH.set(seg.asSlice(index*sizeof()), x); } static final VarHandle time_gran$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("time_gran")); public static VarHandle time_gran$VH() { - return fuse_conn_info.time_gran$VH; + return fuse3_conn_info.time_gran$VH; } public static int time_gran$get(MemorySegment seg) { - return (int)fuse_conn_info.time_gran$VH.get(seg); + return (int)fuse3_conn_info.time_gran$VH.get(seg); } public static void time_gran$set( MemorySegment seg, int x) { - fuse_conn_info.time_gran$VH.set(seg, x); + fuse3_conn_info.time_gran$VH.set(seg, x); } public static int time_gran$get(MemorySegment seg, long index) { - return (int)fuse_conn_info.time_gran$VH.get(seg.asSlice(index*sizeof())); + return (int)fuse3_conn_info.time_gran$VH.get(seg.asSlice(index*sizeof())); } public static void time_gran$set(MemorySegment seg, long index, int x) { - fuse_conn_info.time_gran$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_conn_info.time_gran$VH.set(seg.asSlice(index*sizeof()), x); } public static MemorySegment reserved$slice(MemorySegment seg) { return seg.asSlice(40, 88); diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_file_info.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_file_info.java similarity index 73% rename from jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_file_info.java rename to jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_file_info.java index 62f35911..2a86fd2b 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_file_info.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_file_info.java @@ -7,7 +7,7 @@ import java.nio.ByteOrder; import java.lang.foreign.*; import static java.lang.foreign.ValueLayout.*; -public class fuse_file_info { +public class fuse3_file_info { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( Constants$root.C_LONG$LAYOUT.withName("flags"), @@ -26,73 +26,73 @@ public class fuse_file_info { Constants$root.C_LONG_LONG$LAYOUT.withName("lock_owner"), Constants$root.C_LONG$LAYOUT.withName("poll_events"), MemoryLayout.paddingLayout(32) - ).withName("fuse_file_info"); + ).withName("fuse3_file_info"); public static MemoryLayout $LAYOUT() { - return fuse_file_info.$struct$LAYOUT; + return fuse3_file_info.$struct$LAYOUT; } static final VarHandle flags$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("flags")); public static VarHandle flags$VH() { - return fuse_file_info.flags$VH; + return fuse3_file_info.flags$VH; } public static int flags$get(MemorySegment seg) { - return (int)fuse_file_info.flags$VH.get(seg); + return (int)fuse3_file_info.flags$VH.get(seg); } public static void flags$set( MemorySegment seg, int x) { - fuse_file_info.flags$VH.set(seg, x); + fuse3_file_info.flags$VH.set(seg, x); } public static int flags$get(MemorySegment seg, long index) { - return (int)fuse_file_info.flags$VH.get(seg.asSlice(index*sizeof())); + return (int)fuse3_file_info.flags$VH.get(seg.asSlice(index*sizeof())); } public static void flags$set(MemorySegment seg, long index, int x) { - fuse_file_info.flags$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_file_info.flags$VH.set(seg.asSlice(index*sizeof()), x); } static final VarHandle fh$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fh")); public static VarHandle fh$VH() { - return fuse_file_info.fh$VH; + return fuse3_file_info.fh$VH; } public static long fh$get(MemorySegment seg) { - return (long)fuse_file_info.fh$VH.get(seg); + return (long)fuse3_file_info.fh$VH.get(seg); } public static void fh$set( MemorySegment seg, long x) { - fuse_file_info.fh$VH.set(seg, x); + fuse3_file_info.fh$VH.set(seg, x); } public static long fh$get(MemorySegment seg, long index) { - return (long)fuse_file_info.fh$VH.get(seg.asSlice(index*sizeof())); + return (long)fuse3_file_info.fh$VH.get(seg.asSlice(index*sizeof())); } public static void fh$set(MemorySegment seg, long index, long x) { - fuse_file_info.fh$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_file_info.fh$VH.set(seg.asSlice(index*sizeof()), x); } static final VarHandle lock_owner$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("lock_owner")); public static VarHandle lock_owner$VH() { - return fuse_file_info.lock_owner$VH; + return fuse3_file_info.lock_owner$VH; } public static long lock_owner$get(MemorySegment seg) { - return (long)fuse_file_info.lock_owner$VH.get(seg); + return (long)fuse3_file_info.lock_owner$VH.get(seg); } public static void lock_owner$set( MemorySegment seg, long x) { - fuse_file_info.lock_owner$VH.set(seg, x); + fuse3_file_info.lock_owner$VH.set(seg, x); } public static long lock_owner$get(MemorySegment seg, long index) { - return (long)fuse_file_info.lock_owner$VH.get(seg.asSlice(index*sizeof())); + return (long)fuse3_file_info.lock_owner$VH.get(seg.asSlice(index*sizeof())); } public static void lock_owner$set(MemorySegment seg, long index, long x) { - fuse_file_info.lock_owner$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_file_info.lock_owner$VH.set(seg.asSlice(index*sizeof()), x); } static final VarHandle poll_events$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("poll_events")); public static VarHandle poll_events$VH() { - return fuse_file_info.poll_events$VH; + return fuse3_file_info.poll_events$VH; } public static int poll_events$get(MemorySegment seg) { - return (int)fuse_file_info.poll_events$VH.get(seg); + return (int)fuse3_file_info.poll_events$VH.get(seg); } public static void poll_events$set( MemorySegment seg, int x) { - fuse_file_info.poll_events$VH.set(seg, x); + fuse3_file_info.poll_events$VH.set(seg, x); } public static int poll_events$get(MemorySegment seg, long index) { - return (int)fuse_file_info.poll_events$VH.get(seg.asSlice(index*sizeof())); + return (int)fuse3_file_info.poll_events$VH.get(seg.asSlice(index*sizeof())); } public static void poll_events$set(MemorySegment seg, long index, int x) { - fuse_file_info.poll_events$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_file_info.poll_events$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-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_fill_dir_t.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_fill_dir_t.java similarity index 60% rename from jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_fill_dir_t.java rename to jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_fill_dir_t.java index aec0f8bd..45a0540b 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_fill_dir_t.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_fill_dir_t.java @@ -7,17 +7,17 @@ import java.nio.ByteOrder; import java.lang.foreign.*; import static java.lang.foreign.ValueLayout.*; -public interface fuse_fill_dir_t { +public interface fuse3_fill_dir_t { int apply(java.lang.foreign.MemoryAddress buf, java.lang.foreign.MemoryAddress name, java.lang.foreign.MemoryAddress stbuf, long off, int flags); - static MemorySegment allocate(fuse_fill_dir_t fi, MemorySession session) { - return RuntimeHelper.upcallStub(fuse_fill_dir_t.class, fi, constants$0.fuse_fill_dir_t$FUNC, session); + static MemorySegment allocate(fuse3_fill_dir_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(fuse3_fill_dir_t.class, fi, constants$0.fuse3_fill_dir_t$FUNC, session); } - static fuse_fill_dir_t ofAddress(MemoryAddress addr, MemorySession session) { + static fuse3_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$0.fuse3_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-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_loop_config.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_loop_config.java similarity index 71% rename from jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_loop_config.java rename to jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_loop_config.java index 7f4ad1a2..9193a8af 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_loop_config.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_loop_config.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 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("fuse_loop_config"); + ).withName("fuse3_loop_config"); public static MemoryLayout $LAYOUT() { - return fuse_loop_config.$struct$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 fuse_loop_config.clone_fd$VH; + return fuse3_loop_config.clone_fd$VH; } public static int clone_fd$get(MemorySegment seg) { - return (int)fuse_loop_config.clone_fd$VH.get(seg); + return (int)fuse3_loop_config.clone_fd$VH.get(seg); } public static void clone_fd$set( MemorySegment seg, int x) { - fuse_loop_config.clone_fd$VH.set(seg, x); + fuse3_loop_config.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)fuse3_loop_config.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); + 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 fuse_loop_config.max_idle_threads$VH; + return fuse3_loop_config.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)fuse3_loop_config.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); + fuse3_loop_config.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)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) { - fuse_loop_config.max_idle_threads$VH.set(seg.asSlice(index*sizeof()), 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()); } diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_operations.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_operations.java similarity index 76% rename from jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_operations.java rename to jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_operations.java index f8c84e6f..67910ecb 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_operations.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_operations.java @@ -7,7 +7,7 @@ import java.nio.ByteOrder; import java.lang.foreign.*; import static java.lang.foreign.ValueLayout.*; -public class fuse_operations { +public class fuse3_operations { static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( Constants$root.C_POINTER$LAYOUT.withName("getattr"), @@ -50,9 +50,9 @@ public class fuse_operations { Constants$root.C_POINTER$LAYOUT.withName("read_buf"), Constants$root.C_POINTER$LAYOUT.withName("flock"), Constants$root.C_POINTER$LAYOUT.withName("fallocate") - ).withName("fuse_operations"); + ).withName("fuse3_operations"); public static MemoryLayout $LAYOUT() { - return fuse_operations.$struct$LAYOUT; + return fuse3_operations.$struct$LAYOUT; } static final FunctionDescriptor getattr$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, Constants$root.C_POINTER$LAYOUT, @@ -60,19 +60,19 @@ public class fuse_operations { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle getattr$MH = RuntimeHelper.downcallHandle( - fuse_operations.getattr$FUNC + fuse3_operations.getattr$FUNC ); public interface getattr { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2); static MemorySegment allocate(getattr fi, MemorySession session) { - return RuntimeHelper.upcallStub(getattr.class, fi, fuse_operations.getattr$FUNC, session); + return RuntimeHelper.upcallStub(getattr.class, fi, fuse3_operations.getattr$FUNC, session); } static getattr ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2) -> { try { - return (int)fuse_operations.getattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2); + return (int)fuse3_operations.getattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -82,19 +82,19 @@ static getattr ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle getattr$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("getattr")); public static VarHandle getattr$VH() { - return fuse_operations.getattr$VH; + return fuse3_operations.getattr$VH; } public static MemoryAddress getattr$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.getattr$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.getattr$VH.get(seg); } public static void getattr$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.getattr$VH.set(seg, x); + fuse3_operations.getattr$VH.set(seg, x); } public static MemoryAddress getattr$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.getattr$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.getattr$VH.get(seg.asSlice(index*sizeof())); } public static void getattr$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.getattr$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.getattr$VH.set(seg.asSlice(index*sizeof()), x); } public static getattr getattr (MemorySegment segment, MemorySession session) { return getattr.ofAddress(getattr$get(segment), session); @@ -105,19 +105,19 @@ public static getattr getattr (MemorySegment segment, MemorySession session) { Constants$root.C_LONG_LONG$LAYOUT ); static final MethodHandle readlink$MH = RuntimeHelper.downcallHandle( - fuse_operations.readlink$FUNC + fuse3_operations.readlink$FUNC ); public interface readlink { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, long _x2); static MemorySegment allocate(readlink fi, MemorySession session) { - return RuntimeHelper.upcallStub(readlink.class, fi, fuse_operations.readlink$FUNC, session); + return RuntimeHelper.upcallStub(readlink.class, fi, fuse3_operations.readlink$FUNC, session); } static readlink ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, long __x2) -> { try { - return (int)fuse_operations.readlink$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2); + return (int)fuse3_operations.readlink$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -127,19 +127,19 @@ static readlink ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle readlink$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("readlink")); public static VarHandle readlink$VH() { - return fuse_operations.readlink$VH; + return fuse3_operations.readlink$VH; } public static MemoryAddress readlink$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.readlink$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.readlink$VH.get(seg); } public static void readlink$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.readlink$VH.set(seg, x); + fuse3_operations.readlink$VH.set(seg, x); } public static MemoryAddress readlink$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.readlink$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.readlink$VH.get(seg.asSlice(index*sizeof())); } public static void readlink$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.readlink$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.readlink$VH.set(seg.asSlice(index*sizeof()), x); } public static readlink readlink (MemorySegment segment, MemorySession session) { return readlink.ofAddress(readlink$get(segment), session); @@ -150,19 +150,19 @@ public static readlink readlink (MemorySegment segment, MemorySession session) { Constants$root.C_LONG$LAYOUT ); static final MethodHandle mknod$MH = RuntimeHelper.downcallHandle( - fuse_operations.mknod$FUNC + fuse3_operations.mknod$FUNC ); public interface mknod { int apply(java.lang.foreign.MemoryAddress _x0, int _x1, int _x2); static MemorySegment allocate(mknod fi, MemorySession session) { - return RuntimeHelper.upcallStub(mknod.class, fi, fuse_operations.mknod$FUNC, session); + return RuntimeHelper.upcallStub(mknod.class, fi, fuse3_operations.mknod$FUNC, session); } static mknod ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, int __x1, int __x2) -> { try { - return (int)fuse_operations.mknod$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, __x2); + return (int)fuse3_operations.mknod$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, __x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -172,19 +172,19 @@ static mknod ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle mknod$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("mknod")); public static VarHandle mknod$VH() { - return fuse_operations.mknod$VH; + return fuse3_operations.mknod$VH; } public static MemoryAddress mknod$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.mknod$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.mknod$VH.get(seg); } public static void mknod$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.mknod$VH.set(seg, x); + fuse3_operations.mknod$VH.set(seg, x); } public static MemoryAddress mknod$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.mknod$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.mknod$VH.get(seg.asSlice(index*sizeof())); } public static void mknod$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.mknod$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.mknod$VH.set(seg.asSlice(index*sizeof()), x); } public static mknod mknod (MemorySegment segment, MemorySession session) { return mknod.ofAddress(mknod$get(segment), session); @@ -194,19 +194,19 @@ public static mknod mknod (MemorySegment segment, MemorySession session) { Constants$root.C_LONG$LAYOUT ); static final MethodHandle mkdir$MH = RuntimeHelper.downcallHandle( - fuse_operations.mkdir$FUNC + fuse3_operations.mkdir$FUNC ); public interface mkdir { int apply(java.lang.foreign.MemoryAddress _x0, int _x1); static MemorySegment allocate(mkdir fi, MemorySession session) { - return RuntimeHelper.upcallStub(mkdir.class, fi, fuse_operations.mkdir$FUNC, session); + return RuntimeHelper.upcallStub(mkdir.class, fi, fuse3_operations.mkdir$FUNC, session); } static mkdir ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, int __x1) -> { try { - return (int)fuse_operations.mkdir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1); + return (int)fuse3_operations.mkdir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -216,19 +216,19 @@ static mkdir ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle mkdir$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("mkdir")); public static VarHandle mkdir$VH() { - return fuse_operations.mkdir$VH; + return fuse3_operations.mkdir$VH; } public static MemoryAddress mkdir$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.mkdir$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.mkdir$VH.get(seg); } public static void mkdir$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.mkdir$VH.set(seg, x); + fuse3_operations.mkdir$VH.set(seg, x); } public static MemoryAddress mkdir$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.mkdir$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.mkdir$VH.get(seg.asSlice(index*sizeof())); } public static void mkdir$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.mkdir$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.mkdir$VH.set(seg.asSlice(index*sizeof()), x); } public static mkdir mkdir (MemorySegment segment, MemorySession session) { return mkdir.ofAddress(mkdir$get(segment), session); @@ -237,19 +237,19 @@ public static mkdir mkdir (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle unlink$MH = RuntimeHelper.downcallHandle( - fuse_operations.unlink$FUNC + fuse3_operations.unlink$FUNC ); public interface unlink { int apply(java.lang.foreign.MemoryAddress _x0); static MemorySegment allocate(unlink fi, MemorySession session) { - return RuntimeHelper.upcallStub(unlink.class, fi, fuse_operations.unlink$FUNC, session); + return RuntimeHelper.upcallStub(unlink.class, fi, fuse3_operations.unlink$FUNC, session); } static unlink ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0) -> { try { - return (int)fuse_operations.unlink$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0); + return (int)fuse3_operations.unlink$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -259,19 +259,19 @@ static unlink ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle unlink$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("unlink")); public static VarHandle unlink$VH() { - return fuse_operations.unlink$VH; + return fuse3_operations.unlink$VH; } public static MemoryAddress unlink$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.unlink$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.unlink$VH.get(seg); } public static void unlink$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.unlink$VH.set(seg, x); + fuse3_operations.unlink$VH.set(seg, x); } public static MemoryAddress unlink$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.unlink$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.unlink$VH.get(seg.asSlice(index*sizeof())); } public static void unlink$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.unlink$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.unlink$VH.set(seg.asSlice(index*sizeof()), x); } public static unlink unlink (MemorySegment segment, MemorySession session) { return unlink.ofAddress(unlink$get(segment), session); @@ -280,19 +280,19 @@ public static unlink unlink (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle rmdir$MH = RuntimeHelper.downcallHandle( - fuse_operations.rmdir$FUNC + fuse3_operations.rmdir$FUNC ); public interface rmdir { int apply(java.lang.foreign.MemoryAddress _x0); static MemorySegment allocate(rmdir fi, MemorySession session) { - return RuntimeHelper.upcallStub(rmdir.class, fi, fuse_operations.rmdir$FUNC, session); + return RuntimeHelper.upcallStub(rmdir.class, fi, fuse3_operations.rmdir$FUNC, session); } static rmdir ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0) -> { try { - return (int)fuse_operations.rmdir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0); + return (int)fuse3_operations.rmdir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -302,19 +302,19 @@ static rmdir ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle rmdir$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rmdir")); public static VarHandle rmdir$VH() { - return fuse_operations.rmdir$VH; + return fuse3_operations.rmdir$VH; } public static MemoryAddress rmdir$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.rmdir$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.rmdir$VH.get(seg); } public static void rmdir$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.rmdir$VH.set(seg, x); + fuse3_operations.rmdir$VH.set(seg, x); } public static MemoryAddress rmdir$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.rmdir$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.rmdir$VH.get(seg.asSlice(index*sizeof())); } public static void rmdir$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.rmdir$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.rmdir$VH.set(seg.asSlice(index*sizeof()), x); } public static rmdir rmdir (MemorySegment segment, MemorySession session) { return rmdir.ofAddress(rmdir$get(segment), session); @@ -324,19 +324,19 @@ public static rmdir rmdir (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle symlink$MH = RuntimeHelper.downcallHandle( - fuse_operations.symlink$FUNC + fuse3_operations.symlink$FUNC ); public interface symlink { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); static MemorySegment allocate(symlink fi, MemorySession session) { - return RuntimeHelper.upcallStub(symlink.class, fi, fuse_operations.symlink$FUNC, session); + return RuntimeHelper.upcallStub(symlink.class, fi, fuse3_operations.symlink$FUNC, session); } static symlink ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { try { - return (int)fuse_operations.symlink$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + return (int)fuse3_operations.symlink$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -346,19 +346,19 @@ static symlink ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle symlink$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("symlink")); public static VarHandle symlink$VH() { - return fuse_operations.symlink$VH; + return fuse3_operations.symlink$VH; } public static MemoryAddress symlink$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.symlink$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.symlink$VH.get(seg); } public static void symlink$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.symlink$VH.set(seg, x); + fuse3_operations.symlink$VH.set(seg, x); } public static MemoryAddress symlink$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.symlink$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.symlink$VH.get(seg.asSlice(index*sizeof())); } public static void symlink$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.symlink$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.symlink$VH.set(seg.asSlice(index*sizeof()), x); } public static symlink symlink (MemorySegment segment, MemorySession session) { return symlink.ofAddress(symlink$get(segment), session); @@ -369,19 +369,19 @@ public static symlink symlink (MemorySegment segment, MemorySession session) { Constants$root.C_LONG$LAYOUT ); static final MethodHandle rename$MH = RuntimeHelper.downcallHandle( - fuse_operations.rename$FUNC + fuse3_operations.rename$FUNC ); public interface rename { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, int _x2); static MemorySegment allocate(rename fi, MemorySession session) { - return RuntimeHelper.upcallStub(rename.class, fi, fuse_operations.rename$FUNC, session); + return RuntimeHelper.upcallStub(rename.class, fi, fuse3_operations.rename$FUNC, session); } static rename ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, int __x2) -> { try { - return (int)fuse_operations.rename$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2); + return (int)fuse3_operations.rename$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -391,19 +391,19 @@ static rename ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle rename$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rename")); public static VarHandle rename$VH() { - return fuse_operations.rename$VH; + return fuse3_operations.rename$VH; } public static MemoryAddress rename$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.rename$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.rename$VH.get(seg); } public static void rename$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.rename$VH.set(seg, x); + fuse3_operations.rename$VH.set(seg, x); } public static MemoryAddress rename$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.rename$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.rename$VH.get(seg.asSlice(index*sizeof())); } public static void rename$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.rename$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.rename$VH.set(seg.asSlice(index*sizeof()), x); } public static rename rename (MemorySegment segment, MemorySession session) { return rename.ofAddress(rename$get(segment), session); @@ -413,19 +413,19 @@ public static rename rename (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle link$MH = RuntimeHelper.downcallHandle( - fuse_operations.link$FUNC + fuse3_operations.link$FUNC ); public interface link { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); static MemorySegment allocate(link fi, MemorySession session) { - return RuntimeHelper.upcallStub(link.class, fi, fuse_operations.link$FUNC, session); + return RuntimeHelper.upcallStub(link.class, fi, fuse3_operations.link$FUNC, session); } static link ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { try { - return (int)fuse_operations.link$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + return (int)fuse3_operations.link$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -435,19 +435,19 @@ static link ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle link$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("link")); public static VarHandle link$VH() { - return fuse_operations.link$VH; + return fuse3_operations.link$VH; } public static MemoryAddress link$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.link$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.link$VH.get(seg); } public static void link$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.link$VH.set(seg, x); + fuse3_operations.link$VH.set(seg, x); } public static MemoryAddress link$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.link$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.link$VH.get(seg.asSlice(index*sizeof())); } public static void link$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.link$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.link$VH.set(seg.asSlice(index*sizeof()), x); } public static link link (MemorySegment segment, MemorySession session) { return link.ofAddress(link$get(segment), session); @@ -458,19 +458,19 @@ public static link link (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle chmod$MH = RuntimeHelper.downcallHandle( - fuse_operations.chmod$FUNC + fuse3_operations.chmod$FUNC ); public interface chmod { int apply(java.lang.foreign.MemoryAddress _x0, int _x1, java.lang.foreign.MemoryAddress _x2); static MemorySegment allocate(chmod fi, MemorySession session) { - return RuntimeHelper.upcallStub(chmod.class, fi, fuse_operations.chmod$FUNC, session); + return RuntimeHelper.upcallStub(chmod.class, fi, fuse3_operations.chmod$FUNC, session); } static chmod ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, int __x1, java.lang.foreign.MemoryAddress __x2) -> { try { - return (int)fuse_operations.chmod$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); + return (int)fuse3_operations.chmod$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -480,19 +480,19 @@ static chmod ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle chmod$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("chmod")); public static VarHandle chmod$VH() { - return fuse_operations.chmod$VH; + return fuse3_operations.chmod$VH; } public static MemoryAddress chmod$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.chmod$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.chmod$VH.get(seg); } public static void chmod$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.chmod$VH.set(seg, x); + fuse3_operations.chmod$VH.set(seg, x); } public static MemoryAddress chmod$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.chmod$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.chmod$VH.get(seg.asSlice(index*sizeof())); } public static void chmod$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.chmod$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.chmod$VH.set(seg.asSlice(index*sizeof()), x); } public static chmod chmod (MemorySegment segment, MemorySession session) { return chmod.ofAddress(chmod$get(segment), session); @@ -504,19 +504,19 @@ public static chmod chmod (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle chown$MH = RuntimeHelper.downcallHandle( - fuse_operations.chown$FUNC + fuse3_operations.chown$FUNC ); public interface chown { int apply(java.lang.foreign.MemoryAddress _x0, int _x1, int _x2, java.lang.foreign.MemoryAddress _x3); static MemorySegment allocate(chown fi, MemorySession session) { - return RuntimeHelper.upcallStub(chown.class, fi, fuse_operations.chown$FUNC, session); + return RuntimeHelper.upcallStub(chown.class, fi, fuse3_operations.chown$FUNC, session); } static chown ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, int __x1, int __x2, java.lang.foreign.MemoryAddress __x3) -> { try { - return (int)fuse_operations.chown$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, __x2, (java.lang.foreign.Addressable)__x3); + return (int)fuse3_operations.chown$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, __x2, (java.lang.foreign.Addressable)__x3); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -526,19 +526,19 @@ static chown ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle chown$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("chown")); public static VarHandle chown$VH() { - return fuse_operations.chown$VH; + return fuse3_operations.chown$VH; } public static MemoryAddress chown$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.chown$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.chown$VH.get(seg); } public static void chown$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.chown$VH.set(seg, x); + fuse3_operations.chown$VH.set(seg, x); } public static MemoryAddress chown$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.chown$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.chown$VH.get(seg.asSlice(index*sizeof())); } public static void chown$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.chown$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.chown$VH.set(seg.asSlice(index*sizeof()), x); } public static chown chown (MemorySegment segment, MemorySession session) { return chown.ofAddress(chown$get(segment), session); @@ -549,19 +549,19 @@ public static chown chown (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle truncate$MH = RuntimeHelper.downcallHandle( - fuse_operations.truncate$FUNC + fuse3_operations.truncate$FUNC ); public interface truncate { int apply(java.lang.foreign.MemoryAddress _x0, long _x1, java.lang.foreign.MemoryAddress _x2); static MemorySegment allocate(truncate fi, MemorySession session) { - return RuntimeHelper.upcallStub(truncate.class, fi, fuse_operations.truncate$FUNC, session); + return RuntimeHelper.upcallStub(truncate.class, fi, fuse3_operations.truncate$FUNC, session); } static truncate ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, long __x1, java.lang.foreign.MemoryAddress __x2) -> { try { - return (int)fuse_operations.truncate$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); + return (int)fuse3_operations.truncate$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -571,19 +571,19 @@ static truncate ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle truncate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("truncate")); public static VarHandle truncate$VH() { - return fuse_operations.truncate$VH; + return fuse3_operations.truncate$VH; } public static MemoryAddress truncate$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.truncate$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.truncate$VH.get(seg); } public static void truncate$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.truncate$VH.set(seg, x); + fuse3_operations.truncate$VH.set(seg, x); } public static MemoryAddress truncate$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.truncate$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.truncate$VH.get(seg.asSlice(index*sizeof())); } public static void truncate$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.truncate$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.truncate$VH.set(seg.asSlice(index*sizeof()), x); } public static truncate truncate (MemorySegment segment, MemorySession session) { return truncate.ofAddress(truncate$get(segment), session); @@ -593,19 +593,19 @@ public static truncate truncate (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle open$MH = RuntimeHelper.downcallHandle( - fuse_operations.open$FUNC + fuse3_operations.open$FUNC ); public interface open { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); static MemorySegment allocate(open fi, MemorySession session) { - return RuntimeHelper.upcallStub(open.class, fi, fuse_operations.open$FUNC, session); + return RuntimeHelper.upcallStub(open.class, fi, fuse3_operations.open$FUNC, session); } static open ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { try { - return (int)fuse_operations.open$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + return (int)fuse3_operations.open$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -615,19 +615,19 @@ static open ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle open$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("open")); public static VarHandle open$VH() { - return fuse_operations.open$VH; + return fuse3_operations.open$VH; } public static MemoryAddress open$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.open$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.open$VH.get(seg); } public static void open$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.open$VH.set(seg, x); + fuse3_operations.open$VH.set(seg, x); } public static MemoryAddress open$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.open$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.open$VH.get(seg.asSlice(index*sizeof())); } public static void open$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.open$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.open$VH.set(seg.asSlice(index*sizeof()), x); } public static open open (MemorySegment segment, MemorySession session) { return open.ofAddress(open$get(segment), session); @@ -640,19 +640,19 @@ public static open open (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle read$MH = RuntimeHelper.downcallHandle( - fuse_operations.read$FUNC + fuse3_operations.read$FUNC ); public interface read { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, long _x2, long _x3, java.lang.foreign.MemoryAddress _x4); static MemorySegment allocate(read fi, MemorySession session) { - return RuntimeHelper.upcallStub(read.class, fi, fuse_operations.read$FUNC, session); + return RuntimeHelper.upcallStub(read.class, fi, fuse3_operations.read$FUNC, session); } static read ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, long __x2, long __x3, java.lang.foreign.MemoryAddress __x4) -> { try { - return (int)fuse_operations.read$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2, __x3, (java.lang.foreign.Addressable)__x4); + return (int)fuse3_operations.read$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2, __x3, (java.lang.foreign.Addressable)__x4); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -662,19 +662,19 @@ static read ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle read$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("read")); public static VarHandle read$VH() { - return fuse_operations.read$VH; + return fuse3_operations.read$VH; } public static MemoryAddress read$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.read$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.read$VH.get(seg); } public static void read$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.read$VH.set(seg, x); + fuse3_operations.read$VH.set(seg, x); } public static MemoryAddress read$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.read$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.read$VH.get(seg.asSlice(index*sizeof())); } public static void read$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.read$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.read$VH.set(seg.asSlice(index*sizeof()), x); } public static read read (MemorySegment segment, MemorySession session) { return read.ofAddress(read$get(segment), session); @@ -687,19 +687,19 @@ public static read read (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle write$MH = RuntimeHelper.downcallHandle( - fuse_operations.write$FUNC + fuse3_operations.write$FUNC ); public interface write { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, long _x2, long _x3, java.lang.foreign.MemoryAddress _x4); static MemorySegment allocate(write fi, MemorySession session) { - return RuntimeHelper.upcallStub(write.class, fi, fuse_operations.write$FUNC, session); + return RuntimeHelper.upcallStub(write.class, fi, fuse3_operations.write$FUNC, session); } static write ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, long __x2, long __x3, java.lang.foreign.MemoryAddress __x4) -> { try { - return (int)fuse_operations.write$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2, __x3, (java.lang.foreign.Addressable)__x4); + return (int)fuse3_operations.write$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2, __x3, (java.lang.foreign.Addressable)__x4); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -709,19 +709,19 @@ static write ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle write$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("write")); public static VarHandle write$VH() { - return fuse_operations.write$VH; + return fuse3_operations.write$VH; } public static MemoryAddress write$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.write$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.write$VH.get(seg); } public static void write$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.write$VH.set(seg, x); + fuse3_operations.write$VH.set(seg, x); } public static MemoryAddress write$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.write$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.write$VH.get(seg.asSlice(index*sizeof())); } public static void write$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.write$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.write$VH.set(seg.asSlice(index*sizeof()), x); } public static write write (MemorySegment segment, MemorySession session) { return write.ofAddress(write$get(segment), session); @@ -731,19 +731,19 @@ public static write write (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle statfs$MH = RuntimeHelper.downcallHandle( - fuse_operations.statfs$FUNC + fuse3_operations.statfs$FUNC ); public interface statfs { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); static MemorySegment allocate(statfs fi, MemorySession session) { - return RuntimeHelper.upcallStub(statfs.class, fi, fuse_operations.statfs$FUNC, session); + return RuntimeHelper.upcallStub(statfs.class, fi, fuse3_operations.statfs$FUNC, session); } static statfs ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { try { - return (int)fuse_operations.statfs$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + return (int)fuse3_operations.statfs$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -753,19 +753,19 @@ static statfs ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle statfs$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("statfs")); public static VarHandle statfs$VH() { - return fuse_operations.statfs$VH; + return fuse3_operations.statfs$VH; } public static MemoryAddress statfs$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.statfs$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.statfs$VH.get(seg); } public static void statfs$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.statfs$VH.set(seg, x); + fuse3_operations.statfs$VH.set(seg, x); } public static MemoryAddress statfs$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.statfs$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.statfs$VH.get(seg.asSlice(index*sizeof())); } public static void statfs$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.statfs$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.statfs$VH.set(seg.asSlice(index*sizeof()), x); } public static statfs statfs (MemorySegment segment, MemorySession session) { return statfs.ofAddress(statfs$get(segment), session); @@ -775,19 +775,19 @@ public static statfs statfs (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle flush$MH = RuntimeHelper.downcallHandle( - fuse_operations.flush$FUNC + fuse3_operations.flush$FUNC ); public interface flush { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); static MemorySegment allocate(flush fi, MemorySession session) { - return RuntimeHelper.upcallStub(flush.class, fi, fuse_operations.flush$FUNC, session); + return RuntimeHelper.upcallStub(flush.class, fi, fuse3_operations.flush$FUNC, session); } static flush ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { try { - return (int)fuse_operations.flush$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + return (int)fuse3_operations.flush$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -797,19 +797,19 @@ static flush ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle flush$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("flush")); public static VarHandle flush$VH() { - return fuse_operations.flush$VH; + return fuse3_operations.flush$VH; } public static MemoryAddress flush$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.flush$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.flush$VH.get(seg); } public static void flush$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.flush$VH.set(seg, x); + fuse3_operations.flush$VH.set(seg, x); } public static MemoryAddress flush$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.flush$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.flush$VH.get(seg.asSlice(index*sizeof())); } public static void flush$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.flush$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.flush$VH.set(seg.asSlice(index*sizeof()), x); } public static flush flush (MemorySegment segment, MemorySession session) { return flush.ofAddress(flush$get(segment), session); @@ -819,19 +819,19 @@ public static flush flush (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle release$MH = RuntimeHelper.downcallHandle( - fuse_operations.release$FUNC + fuse3_operations.release$FUNC ); public interface release { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); static MemorySegment allocate(release fi, MemorySession session) { - return RuntimeHelper.upcallStub(release.class, fi, fuse_operations.release$FUNC, session); + return RuntimeHelper.upcallStub(release.class, fi, fuse3_operations.release$FUNC, session); } static release ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { try { - return (int)fuse_operations.release$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + return (int)fuse3_operations.release$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -841,19 +841,19 @@ static release ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle release$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("release")); public static VarHandle release$VH() { - return fuse_operations.release$VH; + return fuse3_operations.release$VH; } public static MemoryAddress release$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.release$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.release$VH.get(seg); } public static void release$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.release$VH.set(seg, x); + fuse3_operations.release$VH.set(seg, x); } public static MemoryAddress release$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.release$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.release$VH.get(seg.asSlice(index*sizeof())); } public static void release$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.release$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.release$VH.set(seg.asSlice(index*sizeof()), x); } public static release release (MemorySegment segment, MemorySession session) { return release.ofAddress(release$get(segment), session); @@ -864,19 +864,19 @@ public static release release (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle fsync$MH = RuntimeHelper.downcallHandle( - fuse_operations.fsync$FUNC + fuse3_operations.fsync$FUNC ); public interface fsync { int apply(java.lang.foreign.MemoryAddress _x0, int _x1, java.lang.foreign.MemoryAddress _x2); static MemorySegment allocate(fsync fi, MemorySession session) { - return RuntimeHelper.upcallStub(fsync.class, fi, fuse_operations.fsync$FUNC, session); + return RuntimeHelper.upcallStub(fsync.class, fi, fuse3_operations.fsync$FUNC, session); } static fsync ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, int __x1, java.lang.foreign.MemoryAddress __x2) -> { try { - return (int)fuse_operations.fsync$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); + return (int)fuse3_operations.fsync$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -886,19 +886,19 @@ static fsync ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle fsync$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fsync")); public static VarHandle fsync$VH() { - return fuse_operations.fsync$VH; + return fuse3_operations.fsync$VH; } public static MemoryAddress fsync$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.fsync$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.fsync$VH.get(seg); } public static void fsync$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.fsync$VH.set(seg, x); + fuse3_operations.fsync$VH.set(seg, x); } public static MemoryAddress fsync$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.fsync$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.fsync$VH.get(seg.asSlice(index*sizeof())); } public static void fsync$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.fsync$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.fsync$VH.set(seg.asSlice(index*sizeof()), x); } public static fsync fsync (MemorySegment segment, MemorySession session) { return fsync.ofAddress(fsync$get(segment), session); @@ -911,19 +911,19 @@ public static fsync fsync (MemorySegment segment, MemorySession session) { Constants$root.C_LONG$LAYOUT ); static final MethodHandle setxattr$MH = RuntimeHelper.downcallHandle( - fuse_operations.setxattr$FUNC + fuse3_operations.setxattr$FUNC ); public interface setxattr { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2, long _x3, int _x4); static MemorySegment allocate(setxattr fi, MemorySession session) { - return RuntimeHelper.upcallStub(setxattr.class, fi, fuse_operations.setxattr$FUNC, session); + return RuntimeHelper.upcallStub(setxattr.class, fi, fuse3_operations.setxattr$FUNC, session); } static setxattr ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2, long __x3, int __x4) -> { try { - return (int)fuse_operations.setxattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2, __x3, __x4); + return (int)fuse3_operations.setxattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2, __x3, __x4); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -933,19 +933,19 @@ static setxattr ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle setxattr$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("setxattr")); public static VarHandle setxattr$VH() { - return fuse_operations.setxattr$VH; + return fuse3_operations.setxattr$VH; } public static MemoryAddress setxattr$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.setxattr$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.setxattr$VH.get(seg); } public static void setxattr$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.setxattr$VH.set(seg, x); + fuse3_operations.setxattr$VH.set(seg, x); } public static MemoryAddress setxattr$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.setxattr$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.setxattr$VH.get(seg.asSlice(index*sizeof())); } public static void setxattr$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.setxattr$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.setxattr$VH.set(seg.asSlice(index*sizeof()), x); } public static setxattr setxattr (MemorySegment segment, MemorySession session) { return setxattr.ofAddress(setxattr$get(segment), session); @@ -957,19 +957,19 @@ public static setxattr setxattr (MemorySegment segment, MemorySession session) { Constants$root.C_LONG_LONG$LAYOUT ); static final MethodHandle getxattr$MH = RuntimeHelper.downcallHandle( - fuse_operations.getxattr$FUNC + fuse3_operations.getxattr$FUNC ); public interface getxattr { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2, long _x3); static MemorySegment allocate(getxattr fi, MemorySession session) { - return RuntimeHelper.upcallStub(getxattr.class, fi, fuse_operations.getxattr$FUNC, session); + return RuntimeHelper.upcallStub(getxattr.class, fi, fuse3_operations.getxattr$FUNC, session); } static getxattr ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2, long __x3) -> { try { - return (int)fuse_operations.getxattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2, __x3); + return (int)fuse3_operations.getxattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2, __x3); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -979,19 +979,19 @@ static getxattr ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle getxattr$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("getxattr")); public static VarHandle getxattr$VH() { - return fuse_operations.getxattr$VH; + return fuse3_operations.getxattr$VH; } public static MemoryAddress getxattr$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.getxattr$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.getxattr$VH.get(seg); } public static void getxattr$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.getxattr$VH.set(seg, x); + fuse3_operations.getxattr$VH.set(seg, x); } public static MemoryAddress getxattr$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.getxattr$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.getxattr$VH.get(seg.asSlice(index*sizeof())); } public static void getxattr$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.getxattr$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.getxattr$VH.set(seg.asSlice(index*sizeof()), x); } public static getxattr getxattr (MemorySegment segment, MemorySession session) { return getxattr.ofAddress(getxattr$get(segment), session); @@ -1002,19 +1002,19 @@ public static getxattr getxattr (MemorySegment segment, MemorySession session) { Constants$root.C_LONG_LONG$LAYOUT ); static final MethodHandle listxattr$MH = RuntimeHelper.downcallHandle( - fuse_operations.listxattr$FUNC + fuse3_operations.listxattr$FUNC ); public interface listxattr { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, long _x2); static MemorySegment allocate(listxattr fi, MemorySession session) { - return RuntimeHelper.upcallStub(listxattr.class, fi, fuse_operations.listxattr$FUNC, session); + return RuntimeHelper.upcallStub(listxattr.class, fi, fuse3_operations.listxattr$FUNC, session); } static listxattr ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, long __x2) -> { try { - return (int)fuse_operations.listxattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2); + return (int)fuse3_operations.listxattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1024,19 +1024,19 @@ static listxattr ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle listxattr$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("listxattr")); public static VarHandle listxattr$VH() { - return fuse_operations.listxattr$VH; + return fuse3_operations.listxattr$VH; } public static MemoryAddress listxattr$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.listxattr$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.listxattr$VH.get(seg); } public static void listxattr$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.listxattr$VH.set(seg, x); + fuse3_operations.listxattr$VH.set(seg, x); } public static MemoryAddress listxattr$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.listxattr$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.listxattr$VH.get(seg.asSlice(index*sizeof())); } public static void listxattr$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.listxattr$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.listxattr$VH.set(seg.asSlice(index*sizeof()), x); } public static listxattr listxattr (MemorySegment segment, MemorySession session) { return listxattr.ofAddress(listxattr$get(segment), session); @@ -1046,19 +1046,19 @@ public static listxattr listxattr (MemorySegment segment, MemorySession session) Constants$root.C_POINTER$LAYOUT ); static final MethodHandle removexattr$MH = RuntimeHelper.downcallHandle( - fuse_operations.removexattr$FUNC + fuse3_operations.removexattr$FUNC ); public interface removexattr { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); static MemorySegment allocate(removexattr fi, MemorySession session) { - return RuntimeHelper.upcallStub(removexattr.class, fi, fuse_operations.removexattr$FUNC, session); + return RuntimeHelper.upcallStub(removexattr.class, fi, fuse3_operations.removexattr$FUNC, session); } static removexattr ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { try { - return (int)fuse_operations.removexattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + return (int)fuse3_operations.removexattr$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1068,19 +1068,19 @@ static removexattr ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle removexattr$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("removexattr")); public static VarHandle removexattr$VH() { - return fuse_operations.removexattr$VH; + return fuse3_operations.removexattr$VH; } public static MemoryAddress removexattr$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.removexattr$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.removexattr$VH.get(seg); } public static void removexattr$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.removexattr$VH.set(seg, x); + fuse3_operations.removexattr$VH.set(seg, x); } public static MemoryAddress removexattr$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.removexattr$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.removexattr$VH.get(seg.asSlice(index*sizeof())); } public static void removexattr$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.removexattr$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.removexattr$VH.set(seg.asSlice(index*sizeof()), x); } public static removexattr removexattr (MemorySegment segment, MemorySession session) { return removexattr.ofAddress(removexattr$get(segment), session); @@ -1090,19 +1090,19 @@ public static removexattr removexattr (MemorySegment segment, MemorySession sess Constants$root.C_POINTER$LAYOUT ); static final MethodHandle opendir$MH = RuntimeHelper.downcallHandle( - fuse_operations.opendir$FUNC + fuse3_operations.opendir$FUNC ); public interface opendir { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); static MemorySegment allocate(opendir fi, MemorySession session) { - return RuntimeHelper.upcallStub(opendir.class, fi, fuse_operations.opendir$FUNC, session); + return RuntimeHelper.upcallStub(opendir.class, fi, fuse3_operations.opendir$FUNC, session); } static opendir ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { try { - return (int)fuse_operations.opendir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + return (int)fuse3_operations.opendir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1112,19 +1112,19 @@ static opendir ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle opendir$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("opendir")); public static VarHandle opendir$VH() { - return fuse_operations.opendir$VH; + return fuse3_operations.opendir$VH; } public static MemoryAddress opendir$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.opendir$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.opendir$VH.get(seg); } public static void opendir$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.opendir$VH.set(seg, x); + fuse3_operations.opendir$VH.set(seg, x); } public static MemoryAddress opendir$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.opendir$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.opendir$VH.get(seg.asSlice(index*sizeof())); } public static void opendir$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.opendir$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.opendir$VH.set(seg.asSlice(index*sizeof()), x); } public static opendir opendir (MemorySegment segment, MemorySession session) { return opendir.ofAddress(opendir$get(segment), session); @@ -1138,19 +1138,19 @@ public static opendir opendir (MemorySegment segment, MemorySession session) { Constants$root.C_LONG$LAYOUT ); static final MethodHandle readdir$MH = RuntimeHelper.downcallHandle( - fuse_operations.readdir$FUNC + fuse3_operations.readdir$FUNC ); public interface readdir { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2, long _x3, java.lang.foreign.MemoryAddress _x4, int _x5); static MemorySegment allocate(readdir fi, MemorySession session) { - return RuntimeHelper.upcallStub(readdir.class, fi, fuse_operations.readdir$FUNC, session); + return RuntimeHelper.upcallStub(readdir.class, fi, fuse3_operations.readdir$FUNC, session); } static readdir ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2, long __x3, java.lang.foreign.MemoryAddress __x4, int __x5) -> { try { - return (int)fuse_operations.readdir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2, __x3, (java.lang.foreign.Addressable)__x4, __x5); + return (int)fuse3_operations.readdir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2, __x3, (java.lang.foreign.Addressable)__x4, __x5); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1160,19 +1160,19 @@ static readdir ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle readdir$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("readdir")); public static VarHandle readdir$VH() { - return fuse_operations.readdir$VH; + return fuse3_operations.readdir$VH; } public static MemoryAddress readdir$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.readdir$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.readdir$VH.get(seg); } public static void readdir$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.readdir$VH.set(seg, x); + fuse3_operations.readdir$VH.set(seg, x); } public static MemoryAddress readdir$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.readdir$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.readdir$VH.get(seg.asSlice(index*sizeof())); } public static void readdir$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.readdir$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.readdir$VH.set(seg.asSlice(index*sizeof()), x); } public static readdir readdir (MemorySegment segment, MemorySession session) { return readdir.ofAddress(readdir$get(segment), session); @@ -1182,19 +1182,19 @@ public static readdir readdir (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle releasedir$MH = RuntimeHelper.downcallHandle( - fuse_operations.releasedir$FUNC + fuse3_operations.releasedir$FUNC ); public interface releasedir { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); static MemorySegment allocate(releasedir fi, MemorySession session) { - return RuntimeHelper.upcallStub(releasedir.class, fi, fuse_operations.releasedir$FUNC, session); + return RuntimeHelper.upcallStub(releasedir.class, fi, fuse3_operations.releasedir$FUNC, session); } static releasedir ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { try { - return (int)fuse_operations.releasedir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + return (int)fuse3_operations.releasedir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1204,19 +1204,19 @@ static releasedir ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle releasedir$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("releasedir")); public static VarHandle releasedir$VH() { - return fuse_operations.releasedir$VH; + return fuse3_operations.releasedir$VH; } public static MemoryAddress releasedir$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.releasedir$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.releasedir$VH.get(seg); } public static void releasedir$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.releasedir$VH.set(seg, x); + fuse3_operations.releasedir$VH.set(seg, x); } public static MemoryAddress releasedir$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.releasedir$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.releasedir$VH.get(seg.asSlice(index*sizeof())); } public static void releasedir$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.releasedir$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.releasedir$VH.set(seg.asSlice(index*sizeof()), x); } public static releasedir releasedir (MemorySegment segment, MemorySession session) { return releasedir.ofAddress(releasedir$get(segment), session); @@ -1227,19 +1227,19 @@ public static releasedir releasedir (MemorySegment segment, MemorySession sessio Constants$root.C_POINTER$LAYOUT ); static final MethodHandle fsyncdir$MH = RuntimeHelper.downcallHandle( - fuse_operations.fsyncdir$FUNC + fuse3_operations.fsyncdir$FUNC ); public interface fsyncdir { int apply(java.lang.foreign.MemoryAddress _x0, int _x1, java.lang.foreign.MemoryAddress _x2); static MemorySegment allocate(fsyncdir fi, MemorySession session) { - return RuntimeHelper.upcallStub(fsyncdir.class, fi, fuse_operations.fsyncdir$FUNC, session); + return RuntimeHelper.upcallStub(fsyncdir.class, fi, fuse3_operations.fsyncdir$FUNC, session); } static fsyncdir ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, int __x1, java.lang.foreign.MemoryAddress __x2) -> { try { - return (int)fuse_operations.fsyncdir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); + return (int)fuse3_operations.fsyncdir$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1249,19 +1249,19 @@ static fsyncdir ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle fsyncdir$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fsyncdir")); public static VarHandle fsyncdir$VH() { - return fuse_operations.fsyncdir$VH; + return fuse3_operations.fsyncdir$VH; } public static MemoryAddress fsyncdir$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.fsyncdir$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.fsyncdir$VH.get(seg); } public static void fsyncdir$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.fsyncdir$VH.set(seg, x); + fuse3_operations.fsyncdir$VH.set(seg, x); } public static MemoryAddress fsyncdir$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.fsyncdir$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.fsyncdir$VH.get(seg.asSlice(index*sizeof())); } public static void fsyncdir$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.fsyncdir$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.fsyncdir$VH.set(seg.asSlice(index*sizeof()), x); } public static fsyncdir fsyncdir (MemorySegment segment, MemorySession session) { return fsyncdir.ofAddress(fsyncdir$get(segment), session); @@ -1271,19 +1271,19 @@ public static fsyncdir fsyncdir (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle init$MH = RuntimeHelper.downcallHandle( - fuse_operations.init$FUNC + fuse3_operations.init$FUNC ); public interface init { java.lang.foreign.Addressable apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1); static MemorySegment allocate(init fi, MemorySession session) { - return RuntimeHelper.upcallStub(init.class, fi, fuse_operations.init$FUNC, session); + return RuntimeHelper.upcallStub(init.class, fi, fuse3_operations.init$FUNC, session); } static init ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1) -> { try { - return (java.lang.foreign.Addressable)(java.lang.foreign.MemoryAddress)fuse_operations.init$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); + return (java.lang.foreign.Addressable)(java.lang.foreign.MemoryAddress)fuse3_operations.init$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1293,19 +1293,19 @@ static init ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle init$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("init")); public static VarHandle init$VH() { - return fuse_operations.init$VH; + return fuse3_operations.init$VH; } public static MemoryAddress init$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.init$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.init$VH.get(seg); } public static void init$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.init$VH.set(seg, x); + fuse3_operations.init$VH.set(seg, x); } public static MemoryAddress init$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.init$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.init$VH.get(seg.asSlice(index*sizeof())); } public static void init$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.init$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.init$VH.set(seg.asSlice(index*sizeof()), x); } public static init init (MemorySegment segment, MemorySession session) { return init.ofAddress(init$get(segment), session); @@ -1314,19 +1314,19 @@ public static init init (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle destroy$MH = RuntimeHelper.downcallHandle( - fuse_operations.destroy$FUNC + fuse3_operations.destroy$FUNC ); public interface destroy { void apply(java.lang.foreign.MemoryAddress _x0); static MemorySegment allocate(destroy fi, MemorySession session) { - return RuntimeHelper.upcallStub(destroy.class, fi, fuse_operations.destroy$FUNC, session); + return RuntimeHelper.upcallStub(destroy.class, fi, fuse3_operations.destroy$FUNC, session); } static destroy ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0) -> { try { - fuse_operations.destroy$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0); + fuse3_operations.destroy$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1336,19 +1336,19 @@ static destroy ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle destroy$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("destroy")); public static VarHandle destroy$VH() { - return fuse_operations.destroy$VH; + return fuse3_operations.destroy$VH; } public static MemoryAddress destroy$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.destroy$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.destroy$VH.get(seg); } public static void destroy$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.destroy$VH.set(seg, x); + fuse3_operations.destroy$VH.set(seg, x); } public static MemoryAddress destroy$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.destroy$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.destroy$VH.get(seg.asSlice(index*sizeof())); } public static void destroy$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.destroy$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.destroy$VH.set(seg.asSlice(index*sizeof()), x); } public static destroy destroy (MemorySegment segment, MemorySession session) { return destroy.ofAddress(destroy$get(segment), session); @@ -1358,19 +1358,19 @@ public static destroy destroy (MemorySegment segment, MemorySession session) { Constants$root.C_LONG$LAYOUT ); static final MethodHandle access$MH = RuntimeHelper.downcallHandle( - fuse_operations.access$FUNC + fuse3_operations.access$FUNC ); public interface access { int apply(java.lang.foreign.MemoryAddress _x0, int _x1); static MemorySegment allocate(access fi, MemorySession session) { - return RuntimeHelper.upcallStub(access.class, fi, fuse_operations.access$FUNC, session); + return RuntimeHelper.upcallStub(access.class, fi, fuse3_operations.access$FUNC, session); } static access ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, int __x1) -> { try { - return (int)fuse_operations.access$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1); + return (int)fuse3_operations.access$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1380,19 +1380,19 @@ static access ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle access$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("access")); public static VarHandle access$VH() { - return fuse_operations.access$VH; + return fuse3_operations.access$VH; } public static MemoryAddress access$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.access$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.access$VH.get(seg); } public static void access$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.access$VH.set(seg, x); + fuse3_operations.access$VH.set(seg, x); } public static MemoryAddress access$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.access$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.access$VH.get(seg.asSlice(index*sizeof())); } public static void access$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.access$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.access$VH.set(seg.asSlice(index*sizeof()), x); } public static access access (MemorySegment segment, MemorySession session) { return access.ofAddress(access$get(segment), session); @@ -1403,19 +1403,19 @@ public static access access (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle create$MH = RuntimeHelper.downcallHandle( - fuse_operations.create$FUNC + fuse3_operations.create$FUNC ); public interface create { int apply(java.lang.foreign.MemoryAddress _x0, int _x1, java.lang.foreign.MemoryAddress _x2); static MemorySegment allocate(create fi, MemorySession session) { - return RuntimeHelper.upcallStub(create.class, fi, fuse_operations.create$FUNC, session); + return RuntimeHelper.upcallStub(create.class, fi, fuse3_operations.create$FUNC, session); } static create ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, int __x1, java.lang.foreign.MemoryAddress __x2) -> { try { - return (int)fuse_operations.create$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); + return (int)fuse3_operations.create$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1425,19 +1425,19 @@ static create ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle create$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("create")); public static VarHandle create$VH() { - return fuse_operations.create$VH; + return fuse3_operations.create$VH; } public static MemoryAddress create$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.create$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.create$VH.get(seg); } public static void create$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.create$VH.set(seg, x); + fuse3_operations.create$VH.set(seg, x); } public static MemoryAddress create$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.create$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.create$VH.get(seg.asSlice(index*sizeof())); } public static void create$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.create$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.create$VH.set(seg.asSlice(index*sizeof()), x); } public static create create (MemorySegment segment, MemorySession session) { return create.ofAddress(create$get(segment), session); @@ -1449,19 +1449,19 @@ public static create create (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle lock$MH = RuntimeHelper.downcallHandle( - fuse_operations.lock$FUNC + fuse3_operations.lock$FUNC ); public interface lock { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, int _x2, java.lang.foreign.MemoryAddress _x3); static MemorySegment allocate(lock fi, MemorySession session) { - return RuntimeHelper.upcallStub(lock.class, fi, fuse_operations.lock$FUNC, session); + return RuntimeHelper.upcallStub(lock.class, fi, fuse3_operations.lock$FUNC, session); } static lock ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, int __x2, java.lang.foreign.MemoryAddress __x3) -> { try { - return (int)fuse_operations.lock$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2, (java.lang.foreign.Addressable)__x3); + return (int)fuse3_operations.lock$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2, (java.lang.foreign.Addressable)__x3); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1471,19 +1471,19 @@ static lock ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle lock$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("lock")); public static VarHandle lock$VH() { - return fuse_operations.lock$VH; + return fuse3_operations.lock$VH; } public static MemoryAddress lock$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.lock$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.lock$VH.get(seg); } public static void lock$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.lock$VH.set(seg, x); + fuse3_operations.lock$VH.set(seg, x); } public static MemoryAddress lock$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.lock$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.lock$VH.get(seg.asSlice(index*sizeof())); } public static void lock$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.lock$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.lock$VH.set(seg.asSlice(index*sizeof()), x); } public static lock lock (MemorySegment segment, MemorySession session) { return lock.ofAddress(lock$get(segment), session); @@ -1494,19 +1494,19 @@ public static lock lock (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle utimens$MH = RuntimeHelper.downcallHandle( - fuse_operations.utimens$FUNC + fuse3_operations.utimens$FUNC ); public interface utimens { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2); static MemorySegment allocate(utimens fi, MemorySession session) { - return RuntimeHelper.upcallStub(utimens.class, fi, fuse_operations.utimens$FUNC, session); + return RuntimeHelper.upcallStub(utimens.class, fi, fuse3_operations.utimens$FUNC, session); } static utimens ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2) -> { try { - return (int)fuse_operations.utimens$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2); + return (int)fuse3_operations.utimens$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1516,19 +1516,19 @@ static utimens ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle utimens$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("utimens")); public static VarHandle utimens$VH() { - return fuse_operations.utimens$VH; + return fuse3_operations.utimens$VH; } public static MemoryAddress utimens$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.utimens$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.utimens$VH.get(seg); } public static void utimens$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.utimens$VH.set(seg, x); + fuse3_operations.utimens$VH.set(seg, x); } public static MemoryAddress utimens$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.utimens$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.utimens$VH.get(seg.asSlice(index*sizeof())); } public static void utimens$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.utimens$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.utimens$VH.set(seg.asSlice(index*sizeof()), x); } public static utimens utimens (MemorySegment segment, MemorySession session) { return utimens.ofAddress(utimens$get(segment), session); @@ -1539,19 +1539,19 @@ public static utimens utimens (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle bmap$MH = RuntimeHelper.downcallHandle( - fuse_operations.bmap$FUNC + fuse3_operations.bmap$FUNC ); public interface bmap { int apply(java.lang.foreign.MemoryAddress _x0, long _x1, java.lang.foreign.MemoryAddress _x2); static MemorySegment allocate(bmap fi, MemorySession session) { - return RuntimeHelper.upcallStub(bmap.class, fi, fuse_operations.bmap$FUNC, session); + return RuntimeHelper.upcallStub(bmap.class, fi, fuse3_operations.bmap$FUNC, session); } static bmap ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, long __x1, java.lang.foreign.MemoryAddress __x2) -> { try { - return (int)fuse_operations.bmap$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); + return (int)fuse3_operations.bmap$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1561,19 +1561,19 @@ static bmap ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle bmap$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("bmap")); public static VarHandle bmap$VH() { - return fuse_operations.bmap$VH; + return fuse3_operations.bmap$VH; } public static MemoryAddress bmap$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.bmap$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.bmap$VH.get(seg); } public static void bmap$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.bmap$VH.set(seg, x); + fuse3_operations.bmap$VH.set(seg, x); } public static MemoryAddress bmap$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.bmap$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.bmap$VH.get(seg.asSlice(index*sizeof())); } public static void bmap$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.bmap$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.bmap$VH.set(seg.asSlice(index*sizeof()), x); } public static bmap bmap (MemorySegment segment, MemorySession session) { return bmap.ofAddress(bmap$get(segment), session); @@ -1587,19 +1587,19 @@ public static bmap bmap (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle ioctl$MH = RuntimeHelper.downcallHandle( - fuse_operations.ioctl$FUNC + fuse3_operations.ioctl$FUNC ); public interface ioctl { int apply(java.lang.foreign.MemoryAddress _x0, int _x1, java.lang.foreign.MemoryAddress _x2, java.lang.foreign.MemoryAddress _x3, int _x4, java.lang.foreign.MemoryAddress _x5); static MemorySegment allocate(ioctl fi, MemorySession session) { - return RuntimeHelper.upcallStub(ioctl.class, fi, fuse_operations.ioctl$FUNC, session); + return RuntimeHelper.upcallStub(ioctl.class, fi, fuse3_operations.ioctl$FUNC, session); } static ioctl ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, int __x1, java.lang.foreign.MemoryAddress __x2, java.lang.foreign.MemoryAddress __x3, int __x4, java.lang.foreign.MemoryAddress __x5) -> { try { - return (int)fuse_operations.ioctl$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2, (java.lang.foreign.Addressable)__x3, __x4, (java.lang.foreign.Addressable)__x5); + return (int)fuse3_operations.ioctl$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, (java.lang.foreign.Addressable)__x2, (java.lang.foreign.Addressable)__x3, __x4, (java.lang.foreign.Addressable)__x5); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1609,19 +1609,19 @@ static ioctl ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle ioctl$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("ioctl")); public static VarHandle ioctl$VH() { - return fuse_operations.ioctl$VH; + return fuse3_operations.ioctl$VH; } public static MemoryAddress ioctl$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.ioctl$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.ioctl$VH.get(seg); } public static void ioctl$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.ioctl$VH.set(seg, x); + fuse3_operations.ioctl$VH.set(seg, x); } public static MemoryAddress ioctl$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.ioctl$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.ioctl$VH.get(seg.asSlice(index*sizeof())); } public static void ioctl$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.ioctl$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.ioctl$VH.set(seg.asSlice(index*sizeof()), x); } public static ioctl ioctl (MemorySegment segment, MemorySession session) { return ioctl.ofAddress(ioctl$get(segment), session); @@ -1633,19 +1633,19 @@ public static ioctl ioctl (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle poll$MH = RuntimeHelper.downcallHandle( - fuse_operations.poll$FUNC + fuse3_operations.poll$FUNC ); public interface poll { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, java.lang.foreign.MemoryAddress _x2, java.lang.foreign.MemoryAddress _x3); static MemorySegment allocate(poll fi, MemorySession session) { - return RuntimeHelper.upcallStub(poll.class, fi, fuse_operations.poll$FUNC, session); + return RuntimeHelper.upcallStub(poll.class, fi, fuse3_operations.poll$FUNC, session); } static poll ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, java.lang.foreign.MemoryAddress __x2, java.lang.foreign.MemoryAddress __x3) -> { try { - return (int)fuse_operations.poll$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2, (java.lang.foreign.Addressable)__x3); + return (int)fuse3_operations.poll$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, (java.lang.foreign.Addressable)__x2, (java.lang.foreign.Addressable)__x3); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1655,19 +1655,19 @@ static poll ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle poll$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("poll")); public static VarHandle poll$VH() { - return fuse_operations.poll$VH; + return fuse3_operations.poll$VH; } public static MemoryAddress poll$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.poll$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.poll$VH.get(seg); } public static void poll$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.poll$VH.set(seg, x); + fuse3_operations.poll$VH.set(seg, x); } public static MemoryAddress poll$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.poll$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.poll$VH.get(seg.asSlice(index*sizeof())); } public static void poll$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.poll$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.poll$VH.set(seg.asSlice(index*sizeof()), x); } public static poll poll (MemorySegment segment, MemorySession session) { return poll.ofAddress(poll$get(segment), session); @@ -1679,19 +1679,19 @@ public static poll poll (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle write_buf$MH = RuntimeHelper.downcallHandle( - fuse_operations.write_buf$FUNC + fuse3_operations.write_buf$FUNC ); public interface write_buf { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, long _x2, java.lang.foreign.MemoryAddress _x3); static MemorySegment allocate(write_buf fi, MemorySession session) { - return RuntimeHelper.upcallStub(write_buf.class, fi, fuse_operations.write_buf$FUNC, session); + return RuntimeHelper.upcallStub(write_buf.class, fi, fuse3_operations.write_buf$FUNC, session); } static write_buf ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, long __x2, java.lang.foreign.MemoryAddress __x3) -> { try { - return (int)fuse_operations.write_buf$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2, (java.lang.foreign.Addressable)__x3); + return (int)fuse3_operations.write_buf$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2, (java.lang.foreign.Addressable)__x3); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1701,19 +1701,19 @@ static write_buf ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle write_buf$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("write_buf")); public static VarHandle write_buf$VH() { - return fuse_operations.write_buf$VH; + return fuse3_operations.write_buf$VH; } public static MemoryAddress write_buf$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.write_buf$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.write_buf$VH.get(seg); } public static void write_buf$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.write_buf$VH.set(seg, x); + fuse3_operations.write_buf$VH.set(seg, x); } public static MemoryAddress write_buf$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.write_buf$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.write_buf$VH.get(seg.asSlice(index*sizeof())); } public static void write_buf$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.write_buf$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.write_buf$VH.set(seg.asSlice(index*sizeof()), x); } public static write_buf write_buf (MemorySegment segment, MemorySession session) { return write_buf.ofAddress(write_buf$get(segment), session); @@ -1726,19 +1726,19 @@ public static write_buf write_buf (MemorySegment segment, MemorySession session) Constants$root.C_POINTER$LAYOUT ); static final MethodHandle read_buf$MH = RuntimeHelper.downcallHandle( - fuse_operations.read_buf$FUNC + fuse3_operations.read_buf$FUNC ); public interface read_buf { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, long _x2, long _x3, java.lang.foreign.MemoryAddress _x4); static MemorySegment allocate(read_buf fi, MemorySession session) { - return RuntimeHelper.upcallStub(read_buf.class, fi, fuse_operations.read_buf$FUNC, session); + return RuntimeHelper.upcallStub(read_buf.class, fi, fuse3_operations.read_buf$FUNC, session); } static read_buf ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, long __x2, long __x3, java.lang.foreign.MemoryAddress __x4) -> { try { - return (int)fuse_operations.read_buf$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2, __x3, (java.lang.foreign.Addressable)__x4); + return (int)fuse3_operations.read_buf$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2, __x3, (java.lang.foreign.Addressable)__x4); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1748,19 +1748,19 @@ static read_buf ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle read_buf$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("read_buf")); public static VarHandle read_buf$VH() { - return fuse_operations.read_buf$VH; + return fuse3_operations.read_buf$VH; } public static MemoryAddress read_buf$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.read_buf$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.read_buf$VH.get(seg); } public static void read_buf$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.read_buf$VH.set(seg, x); + fuse3_operations.read_buf$VH.set(seg, x); } public static MemoryAddress read_buf$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.read_buf$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.read_buf$VH.get(seg.asSlice(index*sizeof())); } public static void read_buf$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.read_buf$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.read_buf$VH.set(seg.asSlice(index*sizeof()), x); } public static read_buf read_buf (MemorySegment segment, MemorySession session) { return read_buf.ofAddress(read_buf$get(segment), session); @@ -1771,19 +1771,19 @@ public static read_buf read_buf (MemorySegment segment, MemorySession session) { Constants$root.C_LONG$LAYOUT ); static final MethodHandle flock$MH = RuntimeHelper.downcallHandle( - fuse_operations.flock$FUNC + fuse3_operations.flock$FUNC ); public interface flock { int apply(java.lang.foreign.MemoryAddress _x0, java.lang.foreign.MemoryAddress _x1, int _x2); static MemorySegment allocate(flock fi, MemorySession session) { - return RuntimeHelper.upcallStub(flock.class, fi, fuse_operations.flock$FUNC, session); + return RuntimeHelper.upcallStub(flock.class, fi, fuse3_operations.flock$FUNC, session); } static flock ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, java.lang.foreign.MemoryAddress __x1, int __x2) -> { try { - return (int)fuse_operations.flock$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2); + return (int)fuse3_operations.flock$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, (java.lang.foreign.Addressable)__x1, __x2); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1793,19 +1793,19 @@ static flock ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle flock$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("flock")); public static VarHandle flock$VH() { - return fuse_operations.flock$VH; + return fuse3_operations.flock$VH; } public static MemoryAddress flock$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.flock$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.flock$VH.get(seg); } public static void flock$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.flock$VH.set(seg, x); + fuse3_operations.flock$VH.set(seg, x); } public static MemoryAddress flock$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.flock$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.flock$VH.get(seg.asSlice(index*sizeof())); } public static void flock$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.flock$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.flock$VH.set(seg.asSlice(index*sizeof()), x); } public static flock flock (MemorySegment segment, MemorySession session) { return flock.ofAddress(flock$get(segment), session); @@ -1818,19 +1818,19 @@ public static flock flock (MemorySegment segment, MemorySession session) { Constants$root.C_POINTER$LAYOUT ); static final MethodHandle fallocate$MH = RuntimeHelper.downcallHandle( - fuse_operations.fallocate$FUNC + fuse3_operations.fallocate$FUNC ); public interface fallocate { int apply(java.lang.foreign.MemoryAddress _x0, int _x1, long _x2, long _x3, java.lang.foreign.MemoryAddress _x4); static MemorySegment allocate(fallocate fi, MemorySession session) { - return RuntimeHelper.upcallStub(fallocate.class, fi, fuse_operations.fallocate$FUNC, session); + return RuntimeHelper.upcallStub(fallocate.class, fi, fuse3_operations.fallocate$FUNC, session); } static fallocate ofAddress(MemoryAddress addr, MemorySession session) { MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); return (java.lang.foreign.MemoryAddress __x0, int __x1, long __x2, long __x3, java.lang.foreign.MemoryAddress __x4) -> { try { - return (int)fuse_operations.fallocate$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, __x2, __x3, (java.lang.foreign.Addressable)__x4); + return (int)fuse3_operations.fallocate$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)__x0, __x1, __x2, __x3, (java.lang.foreign.Addressable)__x4); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } @@ -1840,19 +1840,19 @@ static fallocate ofAddress(MemoryAddress addr, MemorySession session) { static final VarHandle fallocate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fallocate")); public static VarHandle fallocate$VH() { - return fuse_operations.fallocate$VH; + return fuse3_operations.fallocate$VH; } public static MemoryAddress fallocate$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_operations.fallocate$VH.get(seg); + return (java.lang.foreign.MemoryAddress)fuse3_operations.fallocate$VH.get(seg); } public static void fallocate$set( MemorySegment seg, MemoryAddress x) { - fuse_operations.fallocate$VH.set(seg, x); + fuse3_operations.fallocate$VH.set(seg, x); } public static MemoryAddress fallocate$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_operations.fallocate$VH.get(seg.asSlice(index*sizeof())); + return (java.lang.foreign.MemoryAddress)fuse3_operations.fallocate$VH.get(seg.asSlice(index*sizeof())); } public static void fallocate$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_operations.fallocate$VH.set(seg.asSlice(index*sizeof()), x); + fuse3_operations.fallocate$VH.set(seg.asSlice(index*sizeof()), x); } public static fallocate fallocate (MemorySegment segment, MemorySession session) { return fallocate.ofAddress(fallocate$get(segment), session); diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_args.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_args.java deleted file mode 100644 index a7103250..00000000 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_args.java +++ /dev/null @@ -1,78 +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 fuse_args { - - static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( - Constants$root.C_LONG$LAYOUT.withName("argc"), - MemoryLayout.paddingLayout(32), - Constants$root.C_POINTER$LAYOUT.withName("argv"), - Constants$root.C_LONG$LAYOUT.withName("allocated"), - MemoryLayout.paddingLayout(32) - ).withName("fuse_args"); - public static MemoryLayout $LAYOUT() { - return fuse_args.$struct$LAYOUT; - } - static final VarHandle argc$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("argc")); - public static VarHandle argc$VH() { - return fuse_args.argc$VH; - } - public static int argc$get(MemorySegment seg) { - return (int)fuse_args.argc$VH.get(seg); - } - public static void argc$set( MemorySegment seg, int x) { - fuse_args.argc$VH.set(seg, x); - } - public static int argc$get(MemorySegment seg, long index) { - return (int)fuse_args.argc$VH.get(seg.asSlice(index*sizeof())); - } - public static void argc$set(MemorySegment seg, long index, int x) { - fuse_args.argc$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle argv$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("argv")); - public static VarHandle argv$VH() { - return fuse_args.argv$VH; - } - public static MemoryAddress argv$get(MemorySegment seg) { - return (java.lang.foreign.MemoryAddress)fuse_args.argv$VH.get(seg); - } - public static void argv$set( MemorySegment seg, MemoryAddress x) { - fuse_args.argv$VH.set(seg, x); - } - public static MemoryAddress argv$get(MemorySegment seg, long index) { - return (java.lang.foreign.MemoryAddress)fuse_args.argv$VH.get(seg.asSlice(index*sizeof())); - } - public static void argv$set(MemorySegment seg, long index, MemoryAddress x) { - fuse_args.argv$VH.set(seg.asSlice(index*sizeof()), x); - } - static final VarHandle allocated$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("allocated")); - public static VarHandle allocated$VH() { - return fuse_args.allocated$VH; - } - public static int allocated$get(MemorySegment seg) { - return (int)fuse_args.allocated$VH.get(seg); - } - public static void allocated$set( MemorySegment seg, int x) { - fuse_args.allocated$VH.set(seg, x); - } - public static int allocated$get(MemorySegment seg, long index) { - return (int)fuse_args.allocated$VH.get(seg.asSlice(index*sizeof())); - } - public static void allocated$set(MemorySegment seg, long index, int x) { - fuse_args.allocated$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 8b9ae8de..acc5b254 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 @@ -24,99 +24,99 @@ public static int FUSE_READDIR_PLUS() { public static int FUSE_FILL_DIR_PLUS() { return (int)2L; } - public static MethodHandle fuse_lib_help$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_lib_help$MH,"fuse_lib_help"); + public static MethodHandle fuse3_lib_help$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse3_lib_help$MH,"fuse3_lib_help"); } - public static void fuse_lib_help ( Addressable args) { - var mh$ = fuse_lib_help$MH(); + public static void fuse3_lib_help ( Addressable args) { + var mh$ = fuse3_lib_help$MH(); try { mh$.invokeExact(args); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } } - public static MethodHandle fuse_new$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_new$MH,"fuse_new"); + public static MethodHandle fuse3_new$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse3_new$MH,"fuse3_new"); } - public static MemoryAddress fuse_new ( Addressable args, Addressable ops, long opsize, Addressable data) { - var mh$ = fuse_new$MH(); + public static MemoryAddress fuse3_new ( Addressable args, Addressable ops, long opsize, Addressable data) { + var mh$ = fuse3_new$MH(); try { return (java.lang.foreign.MemoryAddress)mh$.invokeExact(args, ops, opsize, data); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } } - public static MethodHandle fuse_destroy$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_destroy$MH,"fuse_destroy"); + public static MethodHandle fuse3_destroy$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse3_destroy$MH,"fuse3_destroy"); } - public static void fuse_destroy ( Addressable f) { - var mh$ = fuse_destroy$MH(); + public static void fuse3_destroy ( Addressable f) { + var mh$ = fuse3_destroy$MH(); try { mh$.invokeExact(f); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } } - public static MethodHandle fuse_mount$MH() { - return RuntimeHelper.requireNonNull(constants$0.fuse_mount$MH,"fuse_mount"); + public static MethodHandle fuse3_mount$MH() { + return RuntimeHelper.requireNonNull(constants$0.fuse3_mount$MH,"fuse3_mount"); } - public static int fuse_mount ( Addressable f, Addressable mountpoint) { - var mh$ = fuse_mount$MH(); + public static int fuse3_mount ( Addressable f, Addressable mountpoint) { + var mh$ = fuse3_mount$MH(); try { return (int)mh$.invokeExact(f, mountpoint); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } } - public static MethodHandle fuse_unmount$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse_unmount$MH,"fuse_unmount"); + public static MethodHandle fuse3_unmount$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse3_unmount$MH,"fuse3_unmount"); } - public static void fuse_unmount ( Addressable f) { - var mh$ = fuse_unmount$MH(); + public static void fuse3_unmount ( Addressable f) { + var mh$ = fuse3_unmount$MH(); try { mh$.invokeExact(f); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } } - public static MethodHandle fuse_loop$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse_loop$MH,"fuse_loop"); + public static MethodHandle fuse3_loop$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse3_loop$MH,"fuse3_loop"); } - public static int fuse_loop ( Addressable f) { - var mh$ = fuse_loop$MH(); + public static int fuse3_loop ( Addressable f) { + var mh$ = fuse3_loop$MH(); try { return (int)mh$.invokeExact(f); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } } - public static MethodHandle fuse_loop_mt$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse_loop_mt$MH,"fuse_loop_mt"); + public static MethodHandle fuse3_loop_mt$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse3_loop_mt$MH,"fuse3_loop_mt"); } - public static int fuse_loop_mt ( Addressable f, Addressable config) { - var mh$ = fuse_loop_mt$MH(); + public static int fuse3_loop_mt ( Addressable f, Addressable config) { + var mh$ = fuse3_loop_mt$MH(); try { return (int)mh$.invokeExact(f, config); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } } - public static MethodHandle fuse_exit$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse_exit$MH,"fuse_exit"); + public static MethodHandle fuse3_exit$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse3_exit$MH,"fuse3_exit"); } - public static void fuse_exit ( Addressable f) { - var mh$ = fuse_exit$MH(); + public static void fuse3_exit ( Addressable f) { + var mh$ = fuse3_exit$MH(); try { mh$.invokeExact(f); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } } - public static MethodHandle fuse_get_session$MH() { - return RuntimeHelper.requireNonNull(constants$1.fuse_get_session$MH,"fuse_get_session"); + public static MethodHandle fuse3_get_session$MH() { + return RuntimeHelper.requireNonNull(constants$1.fuse3_get_session$MH,"fuse3_get_session"); } - public static MemoryAddress fuse_get_session ( Addressable f) { - var mh$ = fuse_get_session$MH(); + public static MemoryAddress fuse3_get_session ( Addressable f) { + var mh$ = fuse3_get_session$MH(); try { return (java.lang.foreign.MemoryAddress)mh$.invokeExact(f); } catch (Throwable ex$) { diff --git a/jfuse-win-amd64/src/test/java/org/cryptomator/jfuse/win/amd64/FileInfoImplTest.java b/jfuse-win-amd64/src/test/java/org/cryptomator/jfuse/win/amd64/FileInfoImplTest.java index 63fdbd30..547bc92d 100644 --- a/jfuse-win-amd64/src/test/java/org/cryptomator/jfuse/win/amd64/FileInfoImplTest.java +++ b/jfuse-win-amd64/src/test/java/org/cryptomator/jfuse/win/amd64/FileInfoImplTest.java @@ -1,7 +1,7 @@ package org.cryptomator.jfuse.win.amd64; import org.cryptomator.jfuse.win.amd64.extr.fcntl_h; -import org.cryptomator.jfuse.win.amd64.extr.fuse_file_info; +import org.cryptomator.jfuse.win.amd64.extr.fuse3_file_info; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.params.ParameterizedTest; @@ -21,8 +21,8 @@ public class FileInfoImplTest { @DisplayName("test getOpenFlags()") public void testGetOpenFlags(int flags, Set expectedResult) { try (var scope = MemorySession.openConfined()) { - var fi = new FileInfoImpl(fuse_file_info.allocate(scope)); - fuse_file_info.flags$set(fi.segment(), flags); + var fi = new FileInfoImpl(fuse3_file_info.allocate(scope)); + fuse3_file_info.flags$set(fi.segment(), flags); var result = fi.getOpenFlags(); 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 66ae6035..b2538b0d 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 @@ -3,7 +3,7 @@ import org.cryptomator.jfuse.api.FileInfo; import org.cryptomator.jfuse.api.FuseOperations; import org.cryptomator.jfuse.api.MountFailedException; -import org.cryptomator.jfuse.win.amd64.extr.fuse_file_info; +import org.cryptomator.jfuse.win.amd64.extr.fuse3_file_info; import org.cryptomator.jfuse.win.amd64.extr.fuse_h; import org.cryptomator.jfuse.win.amd64.extr.fuse_stat; import org.cryptomator.jfuse.win.amd64.extr.fuse_timespec; @@ -56,19 +56,19 @@ public void teardown() { @Test @DisplayName("MountFailedException when fuse_new fails") public void testFuseNewFails() { - fuseH.when(() -> fuse_h.fuse_new(Mockito.any(), Mockito.any(), Mockito.anyLong(), Mockito.any())).thenReturn(MemoryAddress.NULL); + fuseH.when(() -> fuse_h.fuse3_new(Mockito.any(), Mockito.any(), Mockito.anyLong(), Mockito.any())).thenReturn(MemoryAddress.NULL); var thrown = Assertions.assertThrows(MountFailedException.class, () -> fuseImplSpy.mount(args)); - fuseH.verify(() -> fuse_h.fuse_mount(Mockito.any(), Mockito.any()), Mockito.never()); + fuseH.verify(() -> fuse_h.fuse3_mount(Mockito.any(), Mockito.any()), Mockito.never()); Assertions.assertEquals("fuse_new failed", thrown.getMessage()); } @Test @DisplayName("MountFailedException when fuse_mount fails") public void testFuseMountFails() { - fuseH.when(() -> fuse_h.fuse_new(Mockito.any(), Mockito.any(), Mockito.anyLong(), Mockito.any())).thenReturn(MemoryAddress.ofLong(42L)); - fuseH.when(() -> fuse_h.fuse_mount(Mockito.any(), Mockito.any())).thenReturn(1); + fuseH.when(() -> fuse_h.fuse3_new(Mockito.any(), Mockito.any(), Mockito.anyLong(), Mockito.any())).thenReturn(MemoryAddress.ofLong(42L)); + fuseH.when(() -> fuse_h.fuse3_mount(Mockito.any(), Mockito.any())).thenReturn(1); var thrown = Assertions.assertThrows(MountFailedException.class, () -> fuseImplSpy.mount(args)); @@ -111,7 +111,7 @@ public void testUtimensNow() { try (var scope = MemorySession.openConfined()) { var path = scope.allocateUtf8String("/foo"); var times = MemoryAddress.NULL; - var fi = scope.allocate(fuse_file_info.$LAYOUT()); + 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()); @@ -132,7 +132,7 @@ public void testUtimens(long sec0, long nsec0, long sec1, long nsec1) { try (var scope = MemorySession.openConfined()) { var path = scope.allocateUtf8String("/foo"); var times = fuse_timespec.allocateArray(2, scope); - var fi = scope.allocate(fuse_file_info.$LAYOUT()); + 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); @@ -157,7 +157,7 @@ public void testGetattr() { try (var scope = MemorySession.openConfined()) { var path = scope.allocateUtf8String("/foo"); var attr = fuse_stat.allocate(scope); - var fi = scope.allocate(fuse_file_info.$LAYOUT()); + var fi = scope.allocate(fuse3_file_info.$LAYOUT()); Mockito.doReturn(42).when(fuseOps).getattr(Mockito.eq("/foo"), Mockito.any(), Mockito.argThat(usesSameMemorySegement(fi))); var result = fuseImpl.getattr(path.address(), attr.address(), fi.address()); @@ -172,7 +172,7 @@ public void testFgetattr() { try (var scope = MemorySession.openConfined()) { var path = scope.allocateUtf8String("/foo"); var attr = fuse_stat.allocate(scope); - var fi = fuse_file_info.allocate(scope); + var fi = fuse3_file_info.allocate(scope); Mockito.doReturn(42).when(fuseOps).getattr(Mockito.eq("/foo"), Mockito.any(), Mockito.argThat(usesSameMemorySegement(fi))); var result = fuseImpl.fgetattr(path.address(), attr.address(), fi.address()); @@ -192,7 +192,7 @@ public class Truncate { public void testTruncate() { try (var scope = MemorySession.openConfined()) { var path = scope.allocateUtf8String("/foo"); - var fi = scope.allocate(fuse_file_info.$LAYOUT()); + var fi = scope.allocate(fuse3_file_info.$LAYOUT()); Mockito.doReturn(42).when(fuseOps).truncate(Mockito.eq("/foo"), Mockito.eq(1337L), Mockito.argThat(usesSameMemorySegement(fi))); var result = fuseImpl.truncate(path.address(), 1337L, fi.address()); @@ -206,7 +206,7 @@ public void testTruncate() { public void testFtruncate() { try (var scope = MemorySession.openConfined()) { var path = scope.allocateUtf8String("/foo"); - var fi = fuse_file_info.allocate(scope); + var fi = fuse3_file_info.allocate(scope); Mockito.doReturn(42).when(fuseOps).truncate(Mockito.eq("/foo"), Mockito.eq(1337L), Mockito.argThat(usesSameMemorySegement(fi))); var result = fuseImpl.ftruncate(path.address(), 1337L, fi.address()); From 90f654b1d40fe78a916c032cba498824fe6323f2 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Thu, 8 Sep 2022 17:32:05 +0200 Subject: [PATCH 50/98] add runconfig for helloWorld fs test --- .../HelloWorldFileSystem__Windows_.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .idea/runConfigurations/HelloWorldFileSystem__Windows_.xml diff --git a/.idea/runConfigurations/HelloWorldFileSystem__Windows_.xml b/.idea/runConfigurations/HelloWorldFileSystem__Windows_.xml new file mode 100644 index 00000000..8489caff --- /dev/null +++ b/.idea/runConfigurations/HelloWorldFileSystem__Windows_.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file From 6eadd4bac7a0f20cb7299e07be33e3be04697ea5 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Thu, 8 Sep 2022 17:41:28 +0200 Subject: [PATCH 51/98] align windows impl to linux impl --- .../main/java/org/cryptomator/jfuse/win/amd64/FuseArgs.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseArgs.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseArgs.java index 46caa472..45b36e6a 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseArgs.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseArgs.java @@ -17,8 +17,8 @@ public String toString() { var cString = argv.getAtIndex(ValueLayout.ADDRESS, i); sb.append("arg[").append(i).append("] = ").append(cString.getUtf8String(0)).append(", "); } - sb.append("mountPoint = ").append(mountPoint.getUtf8String(0)).append(", "); - sb.append("multiThreaded = ").append(multiThreaded); + sb.append("mountPoint = ").append(mountPoint().getUtf8String(0)); + sb.append("singlethreaded = ").append(!multiThreaded); return sb.toString(); } } \ No newline at end of file From c7ea3cd8ea38b30c315b6aea97b0a154f91c4857 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Fri, 9 Sep 2022 16:41:44 +0200 Subject: [PATCH 52/98] Use same version as winfsp fuse3 header --- jfuse-win-amd64/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jfuse-win-amd64/pom.xml b/jfuse-win-amd64/pom.xml index 4bf70623..7850a106 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=35 + FUSE_USE_VERSION=32 fuse3_lib_help @@ -100,7 +100,7 @@ fuse3_mount fuse3_get_session fuse3_loop - fuse3_loop_mt + fuse3_loop_mt_31 fuse3_exit fuse3_unmount fuse3_destroy From 5c2b712953be52a7a8131967c8d1111304a52b6c Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Fri, 9 Sep 2022 16:43:37 +0200 Subject: [PATCH 53/98] due to FUSE_USE_VERSION change use correct fuse_loop_mt function --- .../org/cryptomator/jfuse/win/amd64/FuseMountImpl.java | 9 +-------- .../cryptomator/jfuse/win/amd64/extr/constants$1.java | 10 +++++----- .../org/cryptomator/jfuse/win/amd64/extr/fuse_h.java | 10 +++++----- 3 files changed, 11 insertions(+), 18 deletions(-) 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/fuse_h.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse_h.java index acc5b254..e6eb234f 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 @@ -90,13 +90,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 2ae3e52f33e581397708336f986743dfca589850 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 12 Sep 2022 12:42:00 +0200 Subject: [PATCH 54/98] Apply code suggestions * renamed fuse2 package and maven execution * remove fuse3_loop_config * improve doc --- README.md | 96 +++++++++---------- jfuse-win-amd64/pom.xml | 9 +- .../cryptomator/jfuse/win/amd64/FuseArgs.java | 2 +- .../cryptomator/jfuse/win/amd64/FuseImpl.java | 15 ++- .../fuse2}/Constants$root.java | 2 +- .../fuse2}/RuntimeHelper.java | 2 +- .../fuse2}/constants$0.java | 2 +- .../fuse_2_h.java => extr/fuse2/fuse2_h.java} | 6 +- .../{extr_fuse2 => extr/fuse2}/fuse_args.java | 2 +- .../win/amd64/extr/fuse3_loop_config.java | 59 ------------ .../jfuse/win/amd64/FuseImplTest.java | 6 +- 11 files changed, 70 insertions(+), 131 deletions(-) rename jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/{extr_fuse2 => extr/fuse2}/Constants$root.java (94%) rename jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/{extr_fuse2 => extr/fuse2}/RuntimeHelper.java (99%) rename jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/{extr_fuse2 => extr/fuse2}/constants$0.java (92%) rename jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/{extr_fuse2/fuse_2_h.java => extr/fuse2/fuse2_h.java} (91%) rename jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/{extr_fuse2 => extr/fuse2}/fuse_args.java (98%) delete mode 100644 jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse3_loop_config.java diff --git a/README.md b/README.md index 40e5a8c0..ee43308f 100644 --- a/README.md +++ b/README.md @@ -15,54 +15,54 @@ We attempt to support libfuse 3.x on Linux while also remaining compatible with Not all [`fuse_operations`](https://libfuse.github.io/doxygen/structfuse__operations.html) are supported yet. -| | Status | -|-----------------|--------------------| -| getattr | :white_check_mark: | -| ~fgetattr~ | use getattr | -| readlink | :white_check_mark: | -| ~getdir~ | use readdir | -| ~mknod~ | use create | -| mkdir | :white_check_mark: | -| unlink | :white_check_mark: | -| rmdir | :white_check_mark: | -| symlink | :white_check_mark: | -| rename | :white_check_mark: | -| link | :x: | -| chmod | :white_check_mark: | -| chown | :x: | -| truncate | :white_check_mark: | -| ~ftruncate~ | use truncate | -| ~utime~ | use utimens | -| open | :white_check_mark: | -| read | :white_check_mark: | -| write | :white_check_mark: | -| statfs | :white_check_mark: | -| flush | :x: | -| release | :white_check_mark: | -| fsync | :x: | -| setxattr | :x: | -| getxattr | :x: | -| listxattr | :x: | -| removexattr | :x: | -| opendir | :white_check_mark: | -| readdir | :white_check_mark: | -| releasedir | :white_check_mark: | -| fsyncdir | :x: | -| init | :white_check_mark: | -| destroy | :white_check_mark: | -| access | :white_check_mark: | -| create | :white_check_mark: | -| lock | :x: | -| utimens | :white_check_mark: | -| bmap | :x: | -| ioctl | :x: | -| poll | :x: | -| write_buf | :x: | -| read_buf | :x: | -| flock | :x: | -| fallocate | :x: | -| copy_file_range | :x: | -| lseek | :x: | +| | Status | +|-----------------|-----------------------------------------| +| getattr | :white_check_mark: | +| ~fgetattr~ | use getattr | +| readlink | :white_check_mark: | +| ~getdir~ | use readdir | +| ~mknod~ | use create | +| mkdir | :white_check_mark: | +| unlink | :white_check_mark: | +| rmdir | :white_check_mark: | +| symlink | :white_check_mark: | +| rename | :white_check_mark: | +| link | :x: | +| chmod | :white_check_mark: | +| chown | :x: | +| truncate | :white_check_mark: | +| ~ftruncate~ | use truncate | +| ~utime~ | use utimens | +| open | :white_check_mark: | +| read | :white_check_mark: | +| write | :white_check_mark: | +| statfs | :white_check_mark: | +| flush | :x: | +| release | :white_check_mark: | +| fsync | :x: | +| setxattr | :x: | +| getxattr | :x: | +| listxattr | :x: | +| removexattr | :x: | +| opendir | :white_check_mark: | +| readdir | :white_check_mark: | +| releasedir | :white_check_mark: | +| fsyncdir | :x: | +| init | :white_check_mark: | +| destroy | :white_check_mark: | +| access | :white_check_mark: (ignored on Windows) | +| create | :white_check_mark: | +| lock | :x: | +| utimens | :white_check_mark: | +| bmap | :x: | +| ioctl | :x: | +| poll | :x: | +| write_buf | :x: | +| read_buf | :x: | +| flock | :x: | +| fallocate | :x: | +| copy_file_range | :x: | +| lseek | :x: | ## Usage diff --git a/jfuse-win-amd64/pom.xml b/jfuse-win-amd64/pom.xml index 7850a106..2449d602 100644 --- a/jfuse-win-amd64/pom.xml +++ b/jfuse-win-amd64/pom.xml @@ -115,7 +115,6 @@ fuse_statvfs fuse_timespec fuse3_conn_info - fuse3_loop_config FUSE_FILL_DIR_PLUS @@ -123,16 +122,16 @@ - + - jextract-fuse-parse-cmd-line + jextract-fuse-parse-cmdline sources - org.cryptomator.jfuse.win.amd64.extr_fuse2 + org.cryptomator.jfuse.win.amd64.extr.fuse2 ${project.parent.basedir}/winfsp/inc/fuse/fuse_common.h - fuse_2_h + fuse2_h fuse_parse_cmdline diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseArgs.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseArgs.java index 45b36e6a..0ee5474b 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseArgs.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseArgs.java @@ -1,6 +1,6 @@ package org.cryptomator.jfuse.win.amd64; -import org.cryptomator.jfuse.win.amd64.extr_fuse2.fuse_args; +import org.cryptomator.jfuse.win.amd64.extr.fuse2.fuse_args; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemorySegment; 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 7cfc9536..c3f711bd 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 @@ -4,11 +4,11 @@ import org.cryptomator.jfuse.api.FuseMount; import org.cryptomator.jfuse.api.FuseOperations; import org.cryptomator.jfuse.api.MountFailedException; +import org.cryptomator.jfuse.win.amd64.extr.fuse2.fuse2_h; +import org.cryptomator.jfuse.win.amd64.extr.fuse2.fuse_args; import org.cryptomator.jfuse.win.amd64.extr.fuse3_operations; -import org.cryptomator.jfuse.win.amd64.extr_fuse2.fuse_args; import org.cryptomator.jfuse.win.amd64.extr.fuse_h; import org.cryptomator.jfuse.win.amd64.extr.fuse_timespec; -import org.cryptomator.jfuse.win.amd64.extr_fuse2.fuse_2_h; import org.jetbrains.annotations.VisibleForTesting; import java.lang.foreign.Addressable; @@ -73,7 +73,7 @@ FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { var multithreaded = fuseScope.allocate(JAVA_INT, 1); var foreground = fuseScope.allocate(JAVA_INT, 1); var mountPointPtr = fuseScope.allocate(ValueLayout.ADDRESS); - int parseResult = fuse_2_h.fuse_parse_cmdline(args, mountPointPtr, multithreaded, foreground); + int parseResult = fuse2_h.fuse_parse_cmdline(args, mountPointPtr, multithreaded, foreground); //winfsp pecularity due to unsupportd fuse_lowlevel.h if (parseResult != 0) { throw new IllegalArgumentException("fuse_parse_cmdline failed to parse " + String.join(" ", cmdLineArgs)); } @@ -82,10 +82,13 @@ FuseArgs parseArgs(List cmdLineArgs) throws IllegalArgumentException { return new FuseArgs(args, mountPoint, isMultiThreaded); } + /** + * Sets a fuse callback. For supported callbacks, see winfsp/inc/fuse3/fuse_h + * @param operation The fuse operation enum, indicating which operation to set. + */ private void bind(FuseOperations.Operation operation) { switch (operation) { case INIT -> fuse3_operations.access$set(fuseOps, fuse3_operations.init.allocate(this::init, fuseScope).address()); - //case ACCESS -> fuse3_operations.access$set(fuseOps, fuse3_operations.access.allocate(this::access, fuseScope).address()); case ACCESS -> fuse3_operations.access$set(fuseOps, MemoryAddress.NULL); case CHMOD -> fuse3_operations.chmod$set(fuseOps, fuse3_operations.chmod.allocate(this::chmod, fuseScope).address()); case CREATE -> fuse3_operations.create$set(fuseOps, fuse3_operations.create.allocate(this::create, fuseScope).address()); @@ -117,10 +120,6 @@ private Addressable init(MemoryAddress conn, MemoryAddress fuseConfig) { return MemoryAddress.NULL; } - private int access(MemoryAddress path, int mask) { - return delegate.access(path.getUtf8String(0), mask); - } - private int chmod(MemoryAddress path, int mode, MemoryAddress fi) { try (var scope = MemorySession.openConfined()) { return delegate.chmod(path.getUtf8String(0), mode, new FileInfoImpl(fi, scope)); diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/Constants$root.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse2/Constants$root.java similarity index 94% rename from jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/Constants$root.java rename to jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse2/Constants$root.java index 347c2999..85fa7c32 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/Constants$root.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse2/Constants$root.java @@ -1,6 +1,6 @@ // Generated by jextract -package org.cryptomator.jfuse.win.amd64.extr_fuse2; +package org.cryptomator.jfuse.win.amd64.extr.fuse2; import java.lang.invoke.MethodHandle; import java.lang.invoke.VarHandle; diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/RuntimeHelper.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse2/RuntimeHelper.java similarity index 99% rename from jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/RuntimeHelper.java rename to jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse2/RuntimeHelper.java index 2c48094d..69422f9c 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/RuntimeHelper.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse2/RuntimeHelper.java @@ -1,4 +1,4 @@ -package org.cryptomator.jfuse.win.amd64.extr_fuse2; +package org.cryptomator.jfuse.win.amd64.extr.fuse2; // Generated by jextract import java.lang.foreign.Addressable; diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/constants$0.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse2/constants$0.java similarity index 92% rename from jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/constants$0.java rename to jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse2/constants$0.java index c934c5f4..c13c8dd4 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/constants$0.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse2/constants$0.java @@ -1,6 +1,6 @@ // Generated by jextract -package org.cryptomator.jfuse.win.amd64.extr_fuse2; +package org.cryptomator.jfuse.win.amd64.extr.fuse2; import java.lang.invoke.MethodHandle; import java.lang.invoke.VarHandle; diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/fuse_2_h.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse2/fuse2_h.java similarity index 91% rename from jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/fuse_2_h.java rename to jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse2/fuse2_h.java index 1c02ca22..d06c6cbc 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/fuse_2_h.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse2/fuse2_h.java @@ -1,15 +1,15 @@ // Generated by jextract -package org.cryptomator.jfuse.win.amd64.extr_fuse2; +package org.cryptomator.jfuse.win.amd64.extr.fuse2; 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 fuse_2_h { +public class fuse2_h { - /* package-private */ fuse_2_h() {} + /* package-private */ fuse2_h() {} public static OfByte C_CHAR = Constants$root.C_CHAR$LAYOUT; public static OfShort C_SHORT = Constants$root.C_SHORT$LAYOUT; public static OfInt C_INT = Constants$root.C_LONG$LAYOUT; diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/fuse_args.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse2/fuse_args.java similarity index 98% rename from jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/fuse_args.java rename to jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse2/fuse_args.java index 1b208e48..ab0abb67 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr_fuse2/fuse_args.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/extr/fuse2/fuse_args.java @@ -1,6 +1,6 @@ // Generated by jextract -package org.cryptomator.jfuse.win.amd64.extr_fuse2; +package org.cryptomator.jfuse.win.amd64.extr.fuse2; import java.lang.invoke.MethodHandle; import java.lang.invoke.VarHandle; 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/test/java/org/cryptomator/jfuse/win/amd64/FuseImplTest.java b/jfuse-win-amd64/src/test/java/org/cryptomator/jfuse/win/amd64/FuseImplTest.java index b2538b0d..32608703 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 @@ -3,11 +3,11 @@ import org.cryptomator.jfuse.api.FileInfo; import org.cryptomator.jfuse.api.FuseOperations; import org.cryptomator.jfuse.api.MountFailedException; +import org.cryptomator.jfuse.win.amd64.extr.fuse2.fuse2_h; import org.cryptomator.jfuse.win.amd64.extr.fuse3_file_info; import org.cryptomator.jfuse.win.amd64.extr.fuse_h; import org.cryptomator.jfuse.win.amd64.extr.fuse_stat; import org.cryptomator.jfuse.win.amd64.extr.fuse_timespec; -import org.cryptomator.jfuse.win.amd64.extr_fuse2.fuse_2_h; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -79,9 +79,9 @@ public void testFuseMountFails() { @Test @DisplayName("parseArgs") public void testParseArgs() { - try (var fuseH = Mockito.mockStatic(fuse_2_h.class); + try (var fuseH = Mockito.mockStatic(fuse2_h.class); var scope = MemorySession.openConfined()) { - fuseH.when(() -> fuse_2_h.fuse_parse_cmdline(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).then(invocation -> { + fuseH.when(() -> fuse2_h.fuse_parse_cmdline(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).then(invocation -> { MemorySegment mp = invocation.getArgument(1); MemorySegment mt = invocation.getArgument(2); MemorySegment fg = invocation.getArgument(3); From a0b83c8c2745c89fb3cea2f65e36f169b652534d Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 12 Sep 2022 13:23:32 +0200 Subject: [PATCH 55/98] revert comment reformulation --- .../src/main/java/org/cryptomator/jfuse/win/amd64/FuseImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 c3f711bd..084030be 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 @@ -241,7 +241,7 @@ int utimens(MemoryAddress path, MemoryAddress times, MemoryAddress fi) { // 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); //TODO: use something like stat_h.UTIME_NOW()) + 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 { From 2ad3047503de0acd3d8c796be41651c21a4a96d7 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 12 Sep 2022 14:55:04 +0200 Subject: [PATCH 56/98] block and probe if mount is finished via file existence --- .../org/cryptomator/jfuse/win/amd64/FuseImpl.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) 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 084030be..25a05290 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 @@ -17,8 +17,10 @@ import java.lang.foreign.MemorySegment; import java.lang.foreign.MemorySession; import java.lang.foreign.ValueLayout; +import java.nio.file.Files; import java.nio.file.Path; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; import static java.lang.foreign.ValueLayout.JAVA_INT; @@ -41,8 +43,21 @@ public void mount(String progName, Path mountPoint, String... flags) throws Moun adjustedMP = Path.of(mountPoint.toString().charAt(0) + ":"); } super.mount(progName, adjustedMP, flags); + try { + waitForMountingToComplete(mountPoint); + } catch (InterruptedException e) { + throw new MountFailedException("Interrupted while waiting for mounting to finish"); + } } + private void waitForMountingToComplete(Path mountPoint) throws InterruptedException { + var probe = mountPoint.resolve("."); + while (!Files.exists(probe)) { + Thread.sleep(333); + } + } + + @Override protected FuseMount mount(List args) throws MountFailedException { var fuseArgs = parseArgs(args); From 98bd63faf1ef57e9033300fe3596817501ccf98b Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 12 Sep 2022 15:21:26 +0200 Subject: [PATCH 57/98] fail mirror test if not succeeded after 3minutes --- jfuse-tests/pom.xml | 1 + .../src/test/java/org/cryptomator/jfuse/tests/MirrorIT.java | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/jfuse-tests/pom.xml b/jfuse-tests/pom.xml index cf402cb1..36d4d822 100644 --- a/jfuse-tests/pom.xml +++ b/jfuse-tests/pom.xml @@ -61,6 +61,7 @@ maven-surefire-plugin @{surefire.jacoco.args} -Djava.library.path=@{fuse.lib.path} --enable-native-access=ALL-UNNAMED --enable-preview + 240 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 8f3f459e..12c87d50 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 @@ -62,7 +62,6 @@ public void setup(@TempDir Path tmpDir) throws IOException, InterruptedException } fuse = builder.build(fs); fuse.mount("mirror-it", mirror, flags.toArray(String[]::new)); - Thread.sleep(100); // give the file system some time to accept the mounted volume } @AfterAll From a3eb637cb4bbd6d17512caf755480a55e015652e Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 13 Sep 2022 10:36:59 +0200 Subject: [PATCH 58/98] reformatted [ci skip] --- .idea/codeStyles/Project.xml | 1 + .../org/cryptomator/jfuse/api/FileModes.java | 16 ++++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index dbf56047..311f1cf1 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -1,5 +1,6 @@ +

+ * The kernel wants to prefill the inode cache during readdir. The filesystem may honour this by filling in the + * attributes and setting FUSE_FILL_DIR_FLAGS for the filler function. + * The filesystem may also just ignore this flag completely. + */ + READ_DIR_PLUS; + + /** + * Parses the given {@code flags}. + * + * @param flags The encoded bit set + * @param readDirPlus The constant value of {@code FUSE_READDIR_PLUS} + * @return A set containing all the {@link ReadDirFlags} values encoded in the given bit set + */ + public static Set parse(int flags, int readDirPlus) { + // currently there is only one known flag, hence this rather trivial implementation. + return (flags & readDirPlus) == readDirPlus + ? EnumSet.of(READ_DIR_PLUS) + : Set.of(); + } + } + /** * @return The error codes from errno.h for the current platform. * @see FuseBuilder#errno() @@ -463,20 +490,20 @@ default int opendir(String path, FileInfo fi) { * is full (or an error happens) the filler function will return * '1'. * - * When FUSE_READDIR_PLUS is not set, only some parameters of the - * fill function (the fuse_fill_dir_t parameter) are actually used: - * The file type (which is part of stat::st_mode) is used. And if - * fuse_config::use_ino is set, the inode (stat::st_ino) is also - * used. The other fields are ignored when FUSE_READDIR_PLUS is not - * set. * * @param path directory path * @param filler the fill function * @param offset the offset * @param fi file info + * @param flags When {@link ReadDirFlags#READ_DIR_PLUS READ_DIR_PLUS} is not set, only some parameters of the + * fill function (the {@code filler} parameter) are actually used: + * The file type (which is part of {@link Stat#getMode()}) is used. And if + * fuse_config::use_ino is set, the inode (stat::st_ino) is also + * used. The other fields are ignored when {@code READ_DIR_PLUS} is not + * set. * @return 0 on success or negated error code (-errno) */ - default int readdir(String path, DirFiller filler, long offset, FileInfo fi) { + default int readdir(String path, DirFiller filler, long offset, FileInfo fi, Set flags) { return -errno().enosys(); } 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 2ee0f3df..f11225cc 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 @@ -270,7 +270,7 @@ public int opendir(String path, FileInfo fi) { } @Override - public int readdir(String path, DirFiller filler, long offset, FileInfo fi) { + public int readdir(String path, DirFiller filler, long offset, FileInfo fi, Set flags) { LOG.trace("readdir {}", path); Path node = resolvePath(path); try (var ds = Files.newDirectoryStream(node)) { diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java index cd47c1b9..141dfd6d 100644 --- a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java @@ -144,7 +144,7 @@ public int opendir(String path, FileInfo fi) { } @Override - public int readdir(String path, DirFiller filler, long offset, FileInfo fi) { + public int readdir(String path, DirFiller filler, long offset, FileInfo fi, Set flags) { LOG.debug("readdir() {} {}", path, offset); var entries = Stream.of( // ".", // 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 7f7d69b8..00cf1801 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 @@ -154,9 +154,10 @@ private int read(MemoryAddress path, MemoryAddress buf, long size, long offset, } } - private int readdir(MemoryAddress path, MemoryAddress buf, MemoryAddress filler, long offset, MemoryAddress fi, int flags) { // TODO: readdir plus + private int readdir(MemoryAddress path, MemoryAddress buf, MemoryAddress filler, long offset, MemoryAddress fi, int flags) { try (var scope = MemorySession.openConfined()) { - return delegate.readdir(path.getUtf8String(0), new DirFillerImpl(buf, filler, scope), offset, new FileInfoImpl(fi, scope)); + var parsedFlags = FuseOperations.ReadDirFlags.parse(flags, fuse_h.FUSE_READDIR_PLUS()); + return delegate.readdir(path.getUtf8String(0), new DirFillerImpl(buf, filler, scope), offset, new FileInfoImpl(fi, scope), parsedFlags); } } 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 a3d1b051..68475efa 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 @@ -154,9 +154,10 @@ private int read(MemoryAddress path, MemoryAddress buf, long size, long offset, } } - private int readdir(MemoryAddress path, MemoryAddress buf, MemoryAddress filler, long offset, MemoryAddress fi, int flags) { // TODO: readdir plus + private int readdir(MemoryAddress path, MemoryAddress buf, MemoryAddress filler, long offset, MemoryAddress fi, int flags) { try (var scope = MemorySession.openConfined()) { - return delegate.readdir(path.getUtf8String(0), new DirFillerImpl(buf, filler, scope), offset, new FileInfoImpl(fi, scope)); + var parsedFlags = FuseOperations.ReadDirFlags.parse(flags, fuse_h.FUSE_READDIR_PLUS()); + return delegate.readdir(path.getUtf8String(0), new DirFillerImpl(buf, filler, scope), offset, new FileInfoImpl(fi, scope), parsedFlags); } } diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java index 8ae4aabd..3f241942 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java @@ -18,6 +18,7 @@ import java.lang.foreign.MemorySession; import java.lang.foreign.ValueLayout; import java.util.List; +import java.util.Set; import static java.lang.foreign.ValueLayout.JAVA_INT; @@ -170,7 +171,7 @@ private int read(MemoryAddress path, MemoryAddress buf, long size, long offset, private int readdir(MemoryAddress path, MemoryAddress buf, MemoryAddress filler, long offset, MemoryAddress fi) { try (var scope = MemorySession.openConfined()) { - return delegate.readdir(path.getUtf8String(0), new DirFillerImpl(buf, filler, scope), offset, new FileInfoImpl(fi, scope)); + return delegate.readdir(path.getUtf8String(0), new DirFillerImpl(buf, filler, scope), offset, new FileInfoImpl(fi, scope), Set.of()); } } 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 084030be..86c9afee 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 @@ -173,9 +173,10 @@ private int read(MemoryAddress path, MemoryAddress buf, long size, long offset, } } - private int readdir(MemoryAddress path, MemoryAddress buf, MemoryAddress filler, long offset, MemoryAddress fi, int flags) { // TODO: readdir plus + private int readdir(MemoryAddress path, MemoryAddress buf, MemoryAddress filler, long offset, MemoryAddress fi, int flags) { try (var scope = MemorySession.openConfined()) { - return delegate.readdir(path.getUtf8String(0), new DirFillerImpl(buf, filler, scope), offset, new FileInfoImpl(fi, scope)); + var parsedFlags = FuseOperations.ReadDirFlags.parse(flags, fuse_h.FUSE_READDIR_PLUS()); + return delegate.readdir(path.getUtf8String(0), new DirFillerImpl(buf, filler, scope), offset, new FileInfoImpl(fi, scope), parsedFlags); } } From c34d50a6553474bdd24aba2510f100979fa126fa Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 13 Sep 2022 11:17:25 +0200 Subject: [PATCH 60/98] apply FUSE_FILL_DIR_PLUS when stats are available --- .../org/cryptomator/jfuse/api/DirFiller.java | 61 +++++++++++++++---- .../cryptomator/jfuse/api/FuseOperations.java | 2 +- .../jfuse/linux/aarch64/DirFillerImpl.java | 7 ++- .../jfuse/linux/amd64/DirFillerImpl.java | 7 ++- .../cryptomator/jfuse/mac/DirFillerImpl.java | 3 +- .../jfuse/win/amd64/DirFillerImpl.java | 7 ++- 6 files changed, 67 insertions(+), 20 deletions(-) diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/DirFiller.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/DirFiller.java index e66d9f8d..4bbf39fa 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/DirFiller.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/DirFiller.java @@ -3,37 +3,73 @@ import org.jetbrains.annotations.Nullable; import java.io.IOException; +import java.util.EnumSet; +import java.util.Set; import java.util.stream.Stream; public interface DirFiller { + Set FILL_DIR_PLUS_FLAGS = EnumSet.of(FillDirFlags.FILL_DIR_PLUS); + + enum FillDirFlags { + + /** + * "Plus" mode: all file attributes are valid. + *

+ * The attributes are used by the kernel to prefill the inode cache during a readdir. + *

+ * It is okay to set FILL_DIR_PLUS if {@link FuseOperations.ReadDirFlags#READ_DIR_PLUS READ_DIR_PLUS} is not set + * and vice versa. + */ + FILL_DIR_PLUS; + + /** + * Encodes the given {@code flags} into a bit set. + * + * @param flags The flags + * @param fillDirPlus The constant value of {@code FUSE_FILL_DIR_PLUS} + * @return The bit set containing all the bits set for the given {@code flags} + */ + public static int toMask(Set flags, int fillDirPlus) { + return flags.contains(FILL_DIR_PLUS) + ? fillDirPlus + : 0; + } + } + /** - * Inserts a single item into the directory entry buffer. + * Function to add an entry in a readdir() operation + *

+ * The off parameter can be any non-zero value that enables the filesystem to identify the current point in the + * directory stream. It does not need to be the actual physical position. A value of zero is reserved to indicate + * that seeking in directories is not supported. * - * @param name The file name - * @param stat Currently ignored, future use - * @param offset The offset of the readdir-call plus the number of already filled entries - * @return 0 if readdir should continue to fill in further items, non-zero otherwise (including errors) + * @param name the file name of the directory entry + * @param stat file attributes, can be NULL + * @param offset offset of the next entry or zero + * @param flags fill flags + * @return 1 if buffer is full, zero otherwise * @see official readdir docs * @see readdir explanation from Geoff Kuenning */ - int fill(String name, @Nullable Stat stat, long offset); + int fill(String name, @Nullable Stat stat, long offset, Set flags); /** - * Convenience wrapper for {@link #fill(String, Stat, long)}, ignoring the offset parameter. + * Convenience wrapper for {@link #fill(String, Stat, long, Set)}, ignoring the offset parameter. * * @param name The file name * @param stat Currently ignored, future use. - * @throws IOException If {@link #fill(String, Stat, long) fuse_fill_dir_t} returns 1, which indicates an error. + * @throws IOException If {@link #fill(String, Stat, long, Set) fuse_fill_dir_t} returns 1, which indicates an error. */ default void fill(String name, @Nullable Stat stat) throws IOException { - if (fill(name, stat, 0) != 0) { + var plusMode = stat != null ? FILL_DIR_PLUS_FLAGS : Set.of(); + if (fill(name, stat, 0, plusMode) != 0) { throw new IOException("fuse_fill_dir_t unexpectedly returned 1"); } } /** - * Convenience wrapper for {@link #fill(String, Stat, long)}, using the offset parameter. + * Convenience wrapper for {@link #fill(String, Stat, long, Set)}, using the offset parameter. *

* Important: Note that the complete set of directors entries must contain . and ... * @@ -44,14 +80,15 @@ default void fillChildrenFromOffset(Stream children, long offset) { var iterator = children.iterator(); for (long i = offset; iterator.hasNext(); i++) { var child = iterator.next(); - if (fill(child.name, child.stat, i + 1) != 0) { + var plusMode = child.stat != null ? FILL_DIR_PLUS_FLAGS : Set.of(); + if (fill(child.name, child.stat, i + 1, plusMode) != 0) { return; } } } /** - * Convenience wrapper for {@link #fill(String, Stat, long)}, using the offset parameter. + * Convenience wrapper for {@link #fill(String, Stat, long, Set)}, using the offset parameter. *

* Important: Note that the complete set of directors entries must contain . and ... * diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java index 41f6f8e4..778cb8a2 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java @@ -45,7 +45,7 @@ enum ReadDirFlags { * "Plus" mode. *

* The kernel wants to prefill the inode cache during readdir. The filesystem may honour this by filling in the - * attributes and setting FUSE_FILL_DIR_FLAGS for the filler function. + * attributes and setting {@link DirFiller.FillDirFlags FUSE_FILL_DIR_FLAGS} for the filler function. * The filesystem may also just ignore this flag completely. */ READ_DIR_PLUS; diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/DirFillerImpl.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/DirFillerImpl.java index 3850e0c2..f0af1197 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/DirFillerImpl.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/DirFillerImpl.java @@ -3,9 +3,11 @@ import org.cryptomator.jfuse.api.DirFiller; import org.cryptomator.jfuse.api.Stat; import org.cryptomator.jfuse.linux.aarch64.extr.fuse_fill_dir_t; +import org.cryptomator.jfuse.linux.aarch64.extr.fuse_h; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemorySession; +import java.util.Set; record DirFillerImpl(MemoryAddress buf, fuse_fill_dir_t callback, MemorySession scope) implements DirFiller { @@ -14,9 +16,10 @@ record DirFillerImpl(MemoryAddress buf, fuse_fill_dir_t callback, MemorySession } @Override - public int fill(String name, Stat stat, long offset) { + public int fill(String name, Stat stat, long offset, Set flags) { var statAddr = stat instanceof StatImpl s ? s.segment().address() : MemoryAddress.NULL; - return callback.apply(buf, scope.allocateUtf8String(name).address(), statAddr, offset, 0); // TODO readdir plus + var encodedFlags = FillDirFlags.toMask(flags, fuse_h.FUSE_FILL_DIR_PLUS()); + return callback.apply(buf, scope.allocateUtf8String(name).address(), statAddr, offset, encodedFlags); } } \ No newline at end of file diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/DirFillerImpl.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/DirFillerImpl.java index 6c587644..9d6d468f 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/DirFillerImpl.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/DirFillerImpl.java @@ -3,9 +3,11 @@ import org.cryptomator.jfuse.api.DirFiller; import org.cryptomator.jfuse.api.Stat; import org.cryptomator.jfuse.linux.amd64.extr.fuse_fill_dir_t; +import org.cryptomator.jfuse.linux.amd64.extr.fuse_h; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemorySession; +import java.util.Set; record DirFillerImpl(MemoryAddress buf, fuse_fill_dir_t callback, MemorySession scope) implements DirFiller { @@ -14,9 +16,10 @@ record DirFillerImpl(MemoryAddress buf, fuse_fill_dir_t callback, MemorySession } @Override - public int fill(String name, Stat stat, long offset) { + public int fill(String name, Stat stat, long offset, Set flags) { var statAddr = stat instanceof StatImpl s ? s.segment().address() : MemoryAddress.NULL; - return callback.apply(buf, scope.allocateUtf8String(name).address(), statAddr, offset, 0); // TODO readdir plus + var encodedFlags = FillDirFlags.toMask(flags, fuse_h.FUSE_FILL_DIR_PLUS()); + return callback.apply(buf, scope.allocateUtf8String(name).address(), statAddr, offset, encodedFlags); } } \ No newline at end of file diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/DirFillerImpl.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/DirFillerImpl.java index 77cf64db..8f15f476 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/DirFillerImpl.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/DirFillerImpl.java @@ -6,6 +6,7 @@ import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemorySession; +import java.util.Set; record DirFillerImpl(MemoryAddress buf, fuse_fill_dir_t callback, MemorySession scope) implements DirFiller { @@ -14,7 +15,7 @@ record DirFillerImpl(MemoryAddress buf, fuse_fill_dir_t callback, MemorySession } @Override - public int fill(String name, Stat stat, long offset) { + public int fill(String name, Stat stat, long offset, Set flags) { var statAddr = stat instanceof StatImpl s ? s.segment().address() : MemoryAddress.NULL; return callback.apply(buf, scope.allocateUtf8String(name).address(), statAddr, offset); } diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java index 48490fa4..ac95e966 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java @@ -3,9 +3,11 @@ import org.cryptomator.jfuse.api.DirFiller; import org.cryptomator.jfuse.api.Stat; import org.cryptomator.jfuse.win.amd64.extr.fuse3_fill_dir_t; +import org.cryptomator.jfuse.win.amd64.extr.fuse_h; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemorySession; +import java.util.Set; record DirFillerImpl(MemoryAddress buf, fuse3_fill_dir_t callback, MemorySession scope) implements DirFiller { @@ -14,9 +16,10 @@ record DirFillerImpl(MemoryAddress buf, fuse3_fill_dir_t callback, MemorySession } @Override - public int fill(String name, Stat stat, long offset) { + public int fill(String name, Stat stat, long offset, Set flags) { var statAddr = stat instanceof StatImpl s ? s.segment().address() : MemoryAddress.NULL; - return callback.apply(buf, scope.allocateUtf8String(name).address(), statAddr, offset, 0); //TODO: readdir plus + var encodedFlags = FillDirFlags.toMask(flags, fuse_h.FUSE_FILL_DIR_PLUS()); + return callback.apply(buf, scope.allocateUtf8String(name).address(), statAddr, offset, encodedFlags); } } \ No newline at end of file From 35d89a13d60fc46937a48a44656f6f76b3968e7c Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 13 Sep 2022 15:28:30 +0200 Subject: [PATCH 61/98] add a RandomFileSystem for testing large directory trees --- .../jfuse/examples/RandomFileStructure.java | 80 +++++++++++ .../jfuse/examples/RandomFileSystem.java | 135 ++++++++++++++++++ 2 files changed, 215 insertions(+) create mode 100644 jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileStructure.java create mode 100644 jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileStructure.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileStructure.java new file mode 100644 index 00000000..b397ae30 --- /dev/null +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileStructure.java @@ -0,0 +1,80 @@ +package org.cryptomator.jfuse.examples; + +import java.time.Instant; +import java.util.Base64; +import java.util.Collections; +import java.util.SortedMap; +import java.util.TreeMap; +import java.util.random.RandomGenerator; +import java.util.random.RandomGeneratorFactory; + +/** + * A pseudo-randomized readonly file tree. + */ +public class RandomFileStructure { + + private static final SortedMap NO_CHILDREN = Collections.unmodifiableSortedMap(new TreeMap<>()); + + private final Node root; + + private RandomFileStructure(Node root) { + this.root = root; + } + + public static RandomFileStructure init(long seed, int maxChildren) { + RandomGenerator rng = RandomGeneratorFactory.getDefault().create(seed); + var children = new TreeMap(); + for (int i = 0; i < maxChildren; i++) { + var child = genNode(rng, maxChildren / 2); + children.put(child.name, child); + } + var root = new Node("",true, Instant.EPOCH, 0, children); + return new RandomFileStructure(root); + } + + private static Node genNode(RandomGenerator rng, int maxChildren) { + var bytes = new byte[15]; + rng.nextBytes(bytes); + var name = Base64.getUrlEncoder().encodeToString(bytes); + var isDir = rng.nextInt(10) < 2; // 20% directories + var lastModified = Instant.ofEpochSecond(rng.nextLong(0, 32503676399L)); + if (isDir) { + var children = new TreeMap(); + var nChildren = rng.nextInt(maxChildren); + for (int i = 0; i < nChildren; i++) { + var child = genNode(rng, maxChildren / 2); + children.put(child.name, child); + } + return new Node(name, isDir, lastModified, 0, children); + } else { + var size = isDir ? 0 : rng.nextInt(0, 500_000_000); + return new Node(name, isDir, lastModified, size, NO_CHILDREN); + } + } + + public Node getNode(String absPath) { + assert absPath.indexOf('/') == 0; + var subPath = absPath.substring(1); + return getNode(root, subPath); + } + + private Node getNode(Node base, String relPath) { + int idx = relPath.indexOf('/'); + var current = idx == -1 ? relPath : relPath.substring(0, idx); + var remaining = idx == -1 ? "" : relPath.substring(idx + 1); + if (current.isEmpty()) { + return base; + } else { + var child = base.children.get(current); + if (child == null) { + return null; + } else { + return getNode(child, remaining); + } + } + } + + public record Node (String name, boolean isDir, Instant lastModified, long size, SortedMap children) { + } + +} diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java new file mode 100644 index 00000000..751b6001 --- /dev/null +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java @@ -0,0 +1,135 @@ +package org.cryptomator.jfuse.examples; + +import org.cryptomator.jfuse.api.DirFiller; +import org.cryptomator.jfuse.api.Errno; +import org.cryptomator.jfuse.api.FileInfo; +import org.cryptomator.jfuse.api.Fuse; +import org.cryptomator.jfuse.api.FuseConnInfo; +import org.cryptomator.jfuse.api.FuseOperations; +import org.cryptomator.jfuse.api.MountFailedException; +import org.cryptomator.jfuse.api.Stat; +import org.cryptomator.jfuse.api.Statvfs; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.util.EnumSet; +import java.util.Set; +import java.util.concurrent.TimeoutException; + +@SuppressWarnings("OctalInteger") +public class RandomFileSystem implements FuseOperations { + + private static final int S_IFDIR = 0040000; + private static final int S_IFREG = 0100000; + private static final Logger LOG = LoggerFactory.getLogger(HelloWorldFileSystem.class); + + private final Errno errno; + private final RandomFileStructure rfs; + + + public static void main(String[] args) { + if (args.length != 1) { + LOG.error("Invalid number of arguments. Expected {mountPoint}."); + } + Path mountPoint = Path.of(args[0]); + var builder = Fuse.builder(); + var fuseOps = new RandomFileSystem(builder.errno()); + try (var fuse = builder.build(fuseOps)) { + LOG.info("Mounting at {}...", mountPoint); + fuse.mount("jfuse", mountPoint, "-s"); + LOG.info("Mounted to {}.", mountPoint); + LOG.info("Enter a anything to unmount..."); + System.in.read(); + } catch (MountFailedException | TimeoutException e) { + LOG.error("Un/Mounting failed. ", e); + System.exit(1); + } catch (IOException e) { + LOG.error("Failed to create mirror", e); + System.exit(1); + } + } + + public RandomFileSystem(Errno errno) { + this.errno = errno; + this.rfs = RandomFileStructure.init(42L, 100); + } + + @Override + public Errno errno() { + return errno; + } + + @Override + public Set supportedOperations() { + return EnumSet.of(Operation.GET_ATTR, Operation.OPEN_DIR, Operation.READ_DIR, Operation.RELEASE_DIR, Operation.STATFS); + } + + @Override + public int getattr(String path, Stat stat, FileInfo fi) { + LOG.debug("getattr() {}", path); + var node = rfs.getNode(path); + if (node == null) { + return -errno.enoent(); + } else if (node.isDir()) { + stat.setMode(S_IFDIR | 0755); + stat.setNLink((short) (2 + node.children().size())); + stat.mTime().set(node.lastModified()); + return 0; + } else { + stat.setMode(S_IFREG | 0444); + stat.setNLink((short) 1); + stat.setSize(0); + stat.mTime().set(node.lastModified()); + return 0; + } + } + + @Override + public int opendir(String path, FileInfo fi) { + LOG.debug("opendir() {}", path); + return 0; + } + + @Override + public int readdir(String path, DirFiller filler, long offset, FileInfo fi, Set flags) { + LOG.debug("readdir() {} {}", path, offset); + var node = rfs.getNode(path); + if (node == null) { + return -errno.enoent(); + } else if (!node.isDir()) { + return -errno.enotdir(); + } else { + try { + filler.fill(".", null); + filler.fill("..", null); + for (var name : node.children().keySet()) { + filler.fill(name, null); + } + return 0; + } catch (IOException e) { + return -errno.eio(); + } + } + } + + @Override + public int releasedir(String path, FileInfo fi) { + LOG.debug("releasedir() {}", path); + return 0; + } + + @Override + public int statfs(String path, Statvfs statvfs) { + LOG.debug("statfs() {}", path); + statvfs.setNameMax(255); + statvfs.setBsize(4096); + statvfs.setBlocks(1000); + statvfs.setBfree(500); + statvfs.setBavail(500); + return 0; + } +} From ac16334ef5541eea431c60858b3c10eb91f2ae25 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 13 Sep 2022 16:41:19 +0200 Subject: [PATCH 62/98] adjusted DirFiller API to support FUSE_DIR_FILL_PLUS --- .../org/cryptomator/jfuse/api/DirFiller.java | 57 ++++--------- .../examples/AbstractMirrorFileSystem.java | 79 +++++++++++++------ .../jfuse/examples/HelloWorldFileSystem.java | 28 ++++--- .../jfuse/examples/RandomFileSystem.java | 19 +++-- .../jfuse/linux/aarch64/DirFillerImpl.java | 13 ++- .../jfuse/linux/amd64/DirFillerImpl.java | 13 ++- .../cryptomator/jfuse/mac/DirFillerImpl.java | 13 ++- .../jfuse/win/amd64/DirFillerImpl.java | 13 ++- 8 files changed, 141 insertions(+), 94 deletions(-) diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/DirFiller.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/DirFiller.java index 4bbf39fa..18d50e7b 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/DirFiller.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/DirFiller.java @@ -5,6 +5,7 @@ import java.io.IOException; import java.util.EnumSet; import java.util.Set; +import java.util.function.Consumer; import java.util.stream.Stream; public interface DirFiller { @@ -46,61 +47,37 @@ public static int toMask(Set flags, int fillDirPlus) { * * @param name the file name of the directory entry * @param stat file attributes, can be NULL - * @param offset offset of the next entry or zero + * @param offset offset of the next entry or zero when ignoring the offset parameter * @param flags fill flags - * @return 1 if buffer is full, zero otherwise + * @return 1 if buffer is full or an error occured, zero otherwise * @see official readdir docs * @see readdir explanation from Geoff Kuenning */ - int fill(String name, @Nullable Stat stat, long offset, Set flags); + int fill(String name, Consumer stat, long offset, Set flags); /** - * Convenience wrapper for {@link #fill(String, Stat, long, Set)}, ignoring the offset parameter. + * Convenience wrapper for {@link #fill(String, Consumer, long, Set)}, ignoring the offset parameter. * - * @param name The file name - * @param stat Currently ignored, future use. - * @throws IOException If {@link #fill(String, Stat, long, Set) fuse_fill_dir_t} returns 1, which indicates an error. + * @param name The file name + * @param stat A method to pre-fill the stats of this node + * @param flags fill flags + * @throws IOException If {@link #fill(String, Consumer, long, Set) fuse_fill_dir_t} returns 1, which indicates an error. */ - default void fill(String name, @Nullable Stat stat) throws IOException { - var plusMode = stat != null ? FILL_DIR_PLUS_FLAGS : Set.of(); - if (fill(name, stat, 0, plusMode) != 0) { + default void fill(String name, Consumer stat, Set flags) throws IOException { + if (fill(name, stat, 0, flags) != 0) { throw new IOException("fuse_fill_dir_t unexpectedly returned 1"); } } /** - * Convenience wrapper for {@link #fill(String, Stat, long, Set)}, using the offset parameter. - *

- * Important: Note that the complete set of directors entries must contain . and ... - * - * @param children A stream of directory entries offset by the given offset - * @param offset The offset of the stream (as requested by readdir) - */ - default void fillChildrenFromOffset(Stream children, long offset) { - var iterator = children.iterator(); - for (long i = offset; iterator.hasNext(); i++) { - var child = iterator.next(); - var plusMode = child.stat != null ? FILL_DIR_PLUS_FLAGS : Set.of(); - if (fill(child.name, child.stat, i + 1, plusMode) != 0) { - return; - } - } - } - - /** - * Convenience wrapper for {@link #fill(String, Stat, long, Set)}, using the offset parameter. - *

- * Important: Note that the complete set of directors entries must contain . and ... + * Convenienve wrapper for {@link #fill(String, Consumer, long, Set)}, just filling in the name, ignoring stats. * - * @param childNames A stream of the names of directory entries offset by the given offset - * @param offset The offset of the stream (as requested by readdir) + * @param name The file name + * @throws IOException If {@link #fill(String, Consumer, long, Set) fuse_fill_dir_t} returns 1, which indicates an error. */ - default void fillNamesFromOffset(Stream childNames, long offset) { - var children = childNames.map(name -> new Child(name, null)); - fillChildrenFromOffset(children, offset); - } - - record Child(String name, @Nullable Stat stat) { + default void fill(String name) throws IOException { + fill(name, __ -> { + }, Set.of()); } } 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 f11225cc..8b12046f 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 @@ -20,12 +20,15 @@ import java.nio.file.AccessMode; import java.nio.file.FileAlreadyExistsException; import java.nio.file.FileStore; +import java.nio.file.FileVisitOption; +import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.LinkOption; import java.nio.file.NoSuchFileException; import java.nio.file.NotDirectoryException; import java.nio.file.OpenOption; import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; import java.nio.file.StandardCopyOption; import java.nio.file.StandardOpenOption; import java.nio.file.attribute.BasicFileAttributeView; @@ -174,28 +177,7 @@ public int getattr(String path, Stat stat, FileInfo fi) { Path node = resolvePath(path); try { var attrs = readAttributes(node); - if (attrs instanceof PosixFileAttributes posixAttrs) { - stat.setPermissions(posixAttrs.permissions()); - } else if (attrs instanceof DosFileAttributes dosAttrs) { - int mode = 0444; - mode |= dosAttrs.isReadOnly() ? 0000 : 0200; // add write access for owner - mode |= attrs.isDirectory() ? 0111 : 0000; // add execute access for directories - stat.setMode(mode); - } - stat.setSize(attrs.size()); - stat.setNLink((short) 1); - if (attrs.isDirectory()) { - stat.toggleDir(true); - stat.setNLink((short) (2 + countSubDirs(node))); - } else if (attrs.isSymbolicLink()) { - stat.toggleLnk(true); - } else if (attrs.isRegularFile()){ - stat.toggleReg(true); - } - stat.aTime().set(attrs.lastAccessTime().toInstant()); - stat.mTime().set(attrs.lastModifiedTime().toInstant()); - stat.cTime().set(attrs.lastAccessTime().toInstant()); - stat.birthTime().set(attrs.creationTime().toInstant()); + copyAttrsToStat(attrs, stat); return 0; } catch (NoSuchFileException e) { return -errno.enoent(); @@ -204,6 +186,32 @@ public int getattr(String path, Stat stat, FileInfo fi) { } } + @SuppressWarnings("OctalInteger") + protected void copyAttrsToStat(BasicFileAttributes attrs, Stat stat) { + if (attrs instanceof PosixFileAttributes posixAttrs) { + stat.setPermissions(posixAttrs.permissions()); + } else if (attrs instanceof DosFileAttributes dosAttrs) { + int mode = 0444; + mode |= dosAttrs.isReadOnly() ? 0000 : 0200; // add write access for owner + mode |= attrs.isDirectory() ? 0111 : 0000; // add execute access for directories + stat.setMode(mode); + } + stat.setSize(attrs.size()); + stat.setNLink((short) 1); + if (attrs.isDirectory()) { + stat.toggleDir(true); + stat.setNLink((short) 2); // FIXME subdir count? + } else if (attrs.isSymbolicLink()) { + stat.toggleLnk(true); + } else if (attrs.isRegularFile()){ + stat.toggleReg(true); + } + stat.aTime().set(attrs.lastAccessTime().toInstant()); + stat.mTime().set(attrs.lastModifiedTime().toInstant()); + stat.cTime().set(attrs.lastAccessTime().toInstant()); + stat.birthTime().set(attrs.creationTime().toInstant()); + } + protected abstract BasicFileAttributes readAttributes(Path node) throws IOException; private long countSubDirs(Path dir) throws IOException { @@ -273,10 +281,29 @@ public int opendir(String path, FileInfo fi) { public int readdir(String path, DirFiller filler, long offset, FileInfo fi, Set flags) { LOG.trace("readdir {}", path); Path node = resolvePath(path); - try (var ds = Files.newDirectoryStream(node)) { - var childNames = StreamSupport.stream(ds.spliterator(), false).map(Path::getFileName).map(Path::toString); - var allNames = Stream.concat(Stream.of(".", ".."), childNames); - filler.fillNamesFromOffset(allNames.skip(offset), offset); + + + try { + // The file walker might use cached file attributes, which might be more efficient (not tested though) + Files.walkFileTree(node, EnumSet.noneOf(FileVisitOption.class), 1, new SimpleFileVisitor<>() { + + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + if (node.equals(dir)) { + filler.fill(".", stat -> copyAttrsToStat(attrs, stat), DirFiller.FILL_DIR_PLUS_FLAGS); + filler.fill("..", stat -> {}, Set.of()); + } else { + filler.fill(dir.getFileName().toString(), stat -> copyAttrsToStat(attrs, stat), DirFiller.FILL_DIR_PLUS_FLAGS); + } + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + filler.fill(file.getFileName().toString(), stat -> copyAttrsToStat(attrs, stat), DirFiller.FILL_DIR_PLUS_FLAGS); + return FileVisitResult.CONTINUE; + } + }); return 0; } catch (NotDirectoryException e) { return -errno.enotdir(); diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java index 141dfd6d..dd316584 100644 --- a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java @@ -146,19 +146,21 @@ public int opendir(String path, FileInfo fi) { @Override public int readdir(String path, DirFiller filler, long offset, FileInfo fi, Set flags) { LOG.debug("readdir() {} {}", path, offset); - var entries = Stream.of( // - ".", // - "..", // - HELLO_PATH.substring(1), // - "aaa", // - "bbb", // - "ccc", // - "ddd", // - "xxx", // - "yyy", // - "zzz").skip(offset); - filler.fillNamesFromOffset(entries, offset); - return 0; + try { + filler.fill("."); + filler.fill(".."); + filler.fill(HELLO_PATH.substring(1)); + filler.fill("aaa"); + filler.fill("bbb"); + filler.fill("ccc"); + filler.fill("ddd"); + filler.fill("xxx"); + filler.fill("yyy"); + filler.fill("zzz"); + return 0; + } catch (IOException e) { + return -errno.eio(); + } } @Override diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java index 751b6001..bb3b267f 100644 --- a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java @@ -74,17 +74,22 @@ public int getattr(String path, Stat stat, FileInfo fi) { var node = rfs.getNode(path); if (node == null) { return -errno.enoent(); - } else if (node.isDir()) { + } else { + fillStats(node, stat); + return 0; + } + } + + private void fillStats(RandomFileStructure.Node node, Stat stat){ + if (node.isDir()) { stat.setMode(S_IFDIR | 0755); stat.setNLink((short) (2 + node.children().size())); stat.mTime().set(node.lastModified()); - return 0; } else { stat.setMode(S_IFREG | 0444); stat.setNLink((short) 1); stat.setSize(0); stat.mTime().set(node.lastModified()); - return 0; } } @@ -104,10 +109,10 @@ public int readdir(String path, DirFiller filler, long offset, FileInfo fi, Set< return -errno.enotdir(); } else { try { - filler.fill(".", null); - filler.fill("..", null); - for (var name : node.children().keySet()) { - filler.fill(name, null); + filler.fill(".", stat -> fillStats(node, stat), DirFiller.FILL_DIR_PLUS_FLAGS); + filler.fill(".."); + for (var child : node.children().values()) { + filler.fill(child.name(), stat -> fillStats(child, stat), DirFiller.FILL_DIR_PLUS_FLAGS); } return 0; } catch (IOException e) { diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/DirFillerImpl.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/DirFillerImpl.java index f0af1197..ee120657 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/DirFillerImpl.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/DirFillerImpl.java @@ -4,10 +4,12 @@ import org.cryptomator.jfuse.api.Stat; import org.cryptomator.jfuse.linux.aarch64.extr.fuse_fill_dir_t; import org.cryptomator.jfuse.linux.aarch64.extr.fuse_h; +import org.cryptomator.jfuse.linux.aarch64.extr.stat; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemorySession; import java.util.Set; +import java.util.function.Consumer; record DirFillerImpl(MemoryAddress buf, fuse_fill_dir_t callback, MemorySession scope) implements DirFiller { @@ -16,8 +18,15 @@ record DirFillerImpl(MemoryAddress buf, fuse_fill_dir_t callback, MemorySession } @Override - public int fill(String name, Stat stat, long offset, Set flags) { - var statAddr = stat instanceof StatImpl s ? s.segment().address() : MemoryAddress.NULL; + public int fill(String name, Consumer statFiller, long offset, Set flags) { + MemoryAddress statAddr; + if (statFiller != null) { + var segment = stat.allocate(scope); + statFiller.accept(new StatImpl(segment)); + statAddr = segment.address(); + } else { + statAddr = MemoryAddress.NULL; + } var encodedFlags = FillDirFlags.toMask(flags, fuse_h.FUSE_FILL_DIR_PLUS()); return callback.apply(buf, scope.allocateUtf8String(name).address(), statAddr, offset, encodedFlags); } diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/DirFillerImpl.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/DirFillerImpl.java index 9d6d468f..c10a89f7 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/DirFillerImpl.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/DirFillerImpl.java @@ -4,10 +4,12 @@ import org.cryptomator.jfuse.api.Stat; import org.cryptomator.jfuse.linux.amd64.extr.fuse_fill_dir_t; import org.cryptomator.jfuse.linux.amd64.extr.fuse_h; +import org.cryptomator.jfuse.linux.amd64.extr.stat; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemorySession; import java.util.Set; +import java.util.function.Consumer; record DirFillerImpl(MemoryAddress buf, fuse_fill_dir_t callback, MemorySession scope) implements DirFiller { @@ -16,8 +18,15 @@ record DirFillerImpl(MemoryAddress buf, fuse_fill_dir_t callback, MemorySession } @Override - public int fill(String name, Stat stat, long offset, Set flags) { - var statAddr = stat instanceof StatImpl s ? s.segment().address() : MemoryAddress.NULL; + public int fill(String name, Consumer statFiller, long offset, Set flags) { + MemoryAddress statAddr; + if (statFiller != null) { + var segment = stat.allocate(scope); + statFiller.accept(new StatImpl(segment)); + statAddr = segment.address(); + } else { + statAddr = MemoryAddress.NULL; + } var encodedFlags = FillDirFlags.toMask(flags, fuse_h.FUSE_FILL_DIR_PLUS()); return callback.apply(buf, scope.allocateUtf8String(name).address(), statAddr, offset, encodedFlags); } diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/DirFillerImpl.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/DirFillerImpl.java index 8f15f476..1bf5ac47 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/DirFillerImpl.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/DirFillerImpl.java @@ -3,10 +3,12 @@ import org.cryptomator.jfuse.api.DirFiller; import org.cryptomator.jfuse.api.Stat; import org.cryptomator.jfuse.mac.extr.fuse_fill_dir_t; +import org.cryptomator.jfuse.mac.extr.stat; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemorySession; import java.util.Set; +import java.util.function.Consumer; record DirFillerImpl(MemoryAddress buf, fuse_fill_dir_t callback, MemorySession scope) implements DirFiller { @@ -15,8 +17,15 @@ record DirFillerImpl(MemoryAddress buf, fuse_fill_dir_t callback, MemorySession } @Override - public int fill(String name, Stat stat, long offset, Set flags) { - var statAddr = stat instanceof StatImpl s ? s.segment().address() : MemoryAddress.NULL; + public int fill(String name, Consumer statFiller, long offset, Set flags) { + MemoryAddress statAddr; + if (statFiller != null) { + var segment = stat.allocate(scope); + statFiller.accept(new StatImpl(segment)); + statAddr = segment.address(); + } else { + statAddr = MemoryAddress.NULL; + } return callback.apply(buf, scope.allocateUtf8String(name).address(), statAddr, offset); } diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java index ac95e966..55806c6a 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java @@ -4,10 +4,12 @@ import org.cryptomator.jfuse.api.Stat; import org.cryptomator.jfuse.win.amd64.extr.fuse3_fill_dir_t; import org.cryptomator.jfuse.win.amd64.extr.fuse_h; +import org.cryptomator.jfuse.win.amd64.extr.fuse_stat; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemorySession; import java.util.Set; +import java.util.function.Consumer; record DirFillerImpl(MemoryAddress buf, fuse3_fill_dir_t callback, MemorySession scope) implements DirFiller { @@ -16,8 +18,15 @@ record DirFillerImpl(MemoryAddress buf, fuse3_fill_dir_t callback, MemorySession } @Override - public int fill(String name, Stat stat, long offset, Set flags) { - var statAddr = stat instanceof StatImpl s ? s.segment().address() : MemoryAddress.NULL; + public int fill(String name, Consumer statFiller, long offset, Set flags) { + MemoryAddress statAddr; + if (statFiller != null) { + var segment = fuse_stat.allocate(scope); + statFiller.accept(new StatImpl(segment)); + statAddr = segment.address(); + } else { + statAddr = MemoryAddress.NULL; + } var encodedFlags = FillDirFlags.toMask(flags, fuse_h.FUSE_FILL_DIR_PLUS()); return callback.apply(buf, scope.allocateUtf8String(name).address(), statAddr, offset, encodedFlags); } From 6d42ff6c7b7280160ddf5ecdb8d91eb5e045f2cf Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 13 Sep 2022 17:59:31 +0200 Subject: [PATCH 63/98] READDIR_PLUS only works for non-zero offsets in the dir filler, i.e. we can simplify the DirFiller API in other cases --- .../org/cryptomator/jfuse/api/DirFiller.java | 11 ++----- .../examples/AbstractMirrorFileSystem.java | 32 ++++--------------- .../jfuse/examples/RandomFileStructure.java | 10 +++--- .../jfuse/examples/RandomFileSystem.java | 25 ++++++++------- .../jfuse/tests/BenchmarkTest.java | 17 +++++----- .../cryptomator/jfuse/win/amd64/FuseImpl.java | 2 ++ 6 files changed, 38 insertions(+), 59 deletions(-) diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/DirFiller.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/DirFiller.java index 18d50e7b..24da81f4 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/DirFiller.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/DirFiller.java @@ -1,12 +1,9 @@ package org.cryptomator.jfuse.api; -import org.jetbrains.annotations.Nullable; - import java.io.IOException; import java.util.EnumSet; import java.util.Set; import java.util.function.Consumer; -import java.util.stream.Stream; public interface DirFiller { @@ -60,11 +57,10 @@ public static int toMask(Set flags, int fillDirPlus) { * * @param name The file name * @param stat A method to pre-fill the stats of this node - * @param flags fill flags * @throws IOException If {@link #fill(String, Consumer, long, Set) fuse_fill_dir_t} returns 1, which indicates an error. */ - default void fill(String name, Consumer stat, Set flags) throws IOException { - if (fill(name, stat, 0, flags) != 0) { + default void fill(String name, Consumer stat) throws IOException { + if (fill(name, stat, 0, Set.of()) != 0) { throw new IOException("fuse_fill_dir_t unexpectedly returned 1"); } } @@ -76,8 +72,7 @@ default void fill(String name, Consumer stat, Set flags) thr * @throws IOException If {@link #fill(String, Consumer, long, Set) fuse_fill_dir_t} returns 1, which indicates an error. */ default void fill(String name) throws IOException { - fill(name, __ -> { - }, Set.of()); + fill(name, stat -> {}); } } 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 8b12046f..1a959313 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 @@ -20,15 +20,12 @@ import java.nio.file.AccessMode; import java.nio.file.FileAlreadyExistsException; import java.nio.file.FileStore; -import java.nio.file.FileVisitOption; -import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.LinkOption; import java.nio.file.NoSuchFileException; import java.nio.file.NotDirectoryException; import java.nio.file.OpenOption; import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; import java.nio.file.StandardCopyOption; import java.nio.file.StandardOpenOption; import java.nio.file.attribute.BasicFileAttributeView; @@ -44,7 +41,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicLong; -import java.util.stream.Stream; import java.util.stream.StreamSupport; public abstract sealed class AbstractMirrorFileSystem implements FuseOperations permits PosixMirrorFileSystem, WindowsMirrorFileSystem { @@ -282,28 +278,12 @@ public int readdir(String path, DirFiller filler, long offset, FileInfo fi, Set< LOG.trace("readdir {}", path); Path node = resolvePath(path); - - try { - // The file walker might use cached file attributes, which might be more efficient (not tested though) - Files.walkFileTree(node, EnumSet.noneOf(FileVisitOption.class), 1, new SimpleFileVisitor<>() { - - @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { - if (node.equals(dir)) { - filler.fill(".", stat -> copyAttrsToStat(attrs, stat), DirFiller.FILL_DIR_PLUS_FLAGS); - filler.fill("..", stat -> {}, Set.of()); - } else { - filler.fill(dir.getFileName().toString(), stat -> copyAttrsToStat(attrs, stat), DirFiller.FILL_DIR_PLUS_FLAGS); - } - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - filler.fill(file.getFileName().toString(), stat -> copyAttrsToStat(attrs, stat), DirFiller.FILL_DIR_PLUS_FLAGS); - return FileVisitResult.CONTINUE; - } - }); + try (var ds = Files.newDirectoryStream(node)) { + filler.fill("."); + filler.fill(".."); + for (var child : ds) { + filler.fill(child.getFileName().toString()); + } return 0; } catch (NotDirectoryException e) { return -errno.enotdir(); diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileStructure.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileStructure.java index b397ae30..759efb81 100644 --- a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileStructure.java +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileStructure.java @@ -36,19 +36,19 @@ private static Node genNode(RandomGenerator rng, int maxChildren) { var bytes = new byte[15]; rng.nextBytes(bytes); var name = Base64.getUrlEncoder().encodeToString(bytes); - var isDir = rng.nextInt(10) < 2; // 20% directories + var isDir = rng.nextInt(10) < 1; // 10% directories var lastModified = Instant.ofEpochSecond(rng.nextLong(0, 32503676399L)); if (isDir) { var children = new TreeMap(); var nChildren = rng.nextInt(maxChildren); for (int i = 0; i < nChildren; i++) { - var child = genNode(rng, maxChildren / 2); + var child = genNode(rng, maxChildren / 4); children.put(child.name, child); } - return new Node(name, isDir, lastModified, 0, children); + return new Node(name, true, lastModified, 0, children); } else { - var size = isDir ? 0 : rng.nextInt(0, 500_000_000); - return new Node(name, isDir, lastModified, size, NO_CHILDREN); + var size = rng.nextInt(0, 500_000_000); + return new Node(name, false, lastModified, size, NO_CHILDREN); } } diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java index bb3b267f..ea206518 100644 --- a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java @@ -4,7 +4,6 @@ import org.cryptomator.jfuse.api.Errno; import org.cryptomator.jfuse.api.FileInfo; import org.cryptomator.jfuse.api.Fuse; -import org.cryptomator.jfuse.api.FuseConnInfo; import org.cryptomator.jfuse.api.FuseOperations; import org.cryptomator.jfuse.api.MountFailedException; import org.cryptomator.jfuse.api.Stat; @@ -13,12 +12,11 @@ import org.slf4j.LoggerFactory; import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.util.EnumSet; import java.util.Set; import java.util.concurrent.TimeoutException; +import java.util.stream.Collectors; @SuppressWarnings("OctalInteger") public class RandomFileSystem implements FuseOperations { @@ -101,23 +99,26 @@ public int opendir(String path, FileInfo fi) { @Override public int readdir(String path, DirFiller filler, long offset, FileInfo fi, Set flags) { - LOG.debug("readdir() {} {}", path, offset); + LOG.debug("readdir() {} {} {}", path, offset, flags.stream().map(ReadDirFlags::name).collect(Collectors.joining(", "))); var node = rfs.getNode(path); if (node == null) { return -errno.enoent(); } else if (!node.isDir()) { return -errno.enotdir(); } else { - try { - filler.fill(".", stat -> fillStats(node, stat), DirFiller.FILL_DIR_PLUS_FLAGS); - filler.fill(".."); - for (var child : node.children().values()) { - filler.fill(child.name(), stat -> fillStats(child, stat), DirFiller.FILL_DIR_PLUS_FLAGS); - } + if (offset == 0 && filler.fill(".", stat -> fillStats(node, stat), ++offset, DirFiller.FILL_DIR_PLUS_FLAGS) != 0) + return 0; + if (offset == 1 && filler.fill("..", stat -> {}, ++offset, DirFiller.FILL_DIR_PLUS_FLAGS) != 0) return 0; - } catch (IOException e) { - return -errno.eio(); + assert offset > 1; + var childIter = node.children().values().stream().skip(offset - 2).iterator(); + while (childIter.hasNext()) { + var child = childIter.next(); + if (filler.fill(child.name(), stat -> fillStats(child, stat), ++offset, DirFiller.FILL_DIR_PLUS_FLAGS) != 0) { + return 0; + } } + return 0; } } diff --git a/jfuse-tests/src/test/java/org/cryptomator/jfuse/tests/BenchmarkTest.java b/jfuse-tests/src/test/java/org/cryptomator/jfuse/tests/BenchmarkTest.java index 0c71779c..b4953df4 100644 --- a/jfuse-tests/src/test/java/org/cryptomator/jfuse/tests/BenchmarkTest.java +++ b/jfuse-tests/src/test/java/org/cryptomator/jfuse/tests/BenchmarkTest.java @@ -8,10 +8,7 @@ import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Warmup; -import org.openjdk.jmh.runner.Runner; -import org.openjdk.jmh.runner.RunnerException; -import org.openjdk.jmh.runner.options.Options; -import org.openjdk.jmh.runner.options.OptionsBuilder; +import org.openjdk.jmh.infra.Blackhole; import java.io.IOException; import java.nio.file.Files; @@ -32,8 +29,10 @@ public void runBenchmarks() throws IOException { @Fork(value = 1) @OutputTimeUnit(TimeUnit.MICROSECONDS) @BenchmarkMode(Mode.AverageTime) - public void testListDirJnrMulti() throws IOException { - Files.list(Path.of("/Volumes/bar")).close(); + public void testListDirJnrMulti(Blackhole blackhole) throws IOException { + try (var ds = Files.list(Path.of("/Volumes/bar"))) { + ds.forEach(blackhole::consume); + } } @Benchmark @@ -41,8 +40,10 @@ public void testListDirJnrMulti() throws IOException { @Fork(value = 1) @OutputTimeUnit(TimeUnit.MICROSECONDS) @BenchmarkMode(Mode.AverageTime) - public void testListDirPanamaMulti() throws IOException { - Files.list(Path.of("/Volumes/foo")).close(); + public void testListDirPanamaMulti(Blackhole blackhole) throws IOException { + try (var ds = Files.list(Path.of("/Volumes/foo"))) { + ds.forEach(blackhole::consume); + } } // @Benchmark 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 86c9afee..cd6aa522 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 @@ -143,6 +143,7 @@ int getattr(MemoryAddress path, MemoryAddress stat, MemoryAddress fi) { } } + // TODO remove @VisibleForTesting int fgetattr(MemoryAddress path, MemoryAddress stat, MemoryAddress fi) { try (var scope = MemorySession.openConfined()) { @@ -224,6 +225,7 @@ int truncate(MemoryAddress path, long size, MemoryAddress fi) { } } + // TODO remove @VisibleForTesting int ftruncate(MemoryAddress path, long size, MemoryAddress fi) { try (var scope = MemorySession.openConfined()) { From c80a944071a2c58c042ee6d348d5066bc7555dea Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 13 Sep 2022 18:31:10 +0200 Subject: [PATCH 64/98] create constant number of children --- .../org/cryptomator/jfuse/examples/RandomFileStructure.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileStructure.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileStructure.java index 759efb81..d65898b6 100644 --- a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileStructure.java +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileStructure.java @@ -32,7 +32,7 @@ public static RandomFileStructure init(long seed, int maxChildren) { return new RandomFileStructure(root); } - private static Node genNode(RandomGenerator rng, int maxChildren) { + private static Node genNode(RandomGenerator rng, int nChildren) { var bytes = new byte[15]; rng.nextBytes(bytes); var name = Base64.getUrlEncoder().encodeToString(bytes); @@ -40,9 +40,8 @@ private static Node genNode(RandomGenerator rng, int maxChildren) { var lastModified = Instant.ofEpochSecond(rng.nextLong(0, 32503676399L)); if (isDir) { var children = new TreeMap(); - var nChildren = rng.nextInt(maxChildren); for (int i = 0; i < nChildren; i++) { - var child = genNode(rng, maxChildren / 4); + var child = genNode(rng, nChildren / 4); children.put(child.name, child); } return new Node(name, true, lastModified, 0, children); From 70b586d1966225f78987fd4c26b7f704f36e3a01 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 13 Sep 2022 18:32:26 +0200 Subject: [PATCH 65/98] increased complexity of "ls" benchmark test by recursing on dirs and making sure to also read attributes, not just names --- .../test/java/org/cryptomator/jfuse/tests/BenchmarkTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jfuse-tests/src/test/java/org/cryptomator/jfuse/tests/BenchmarkTest.java b/jfuse-tests/src/test/java/org/cryptomator/jfuse/tests/BenchmarkTest.java index b4953df4..d5e7783c 100644 --- a/jfuse-tests/src/test/java/org/cryptomator/jfuse/tests/BenchmarkTest.java +++ b/jfuse-tests/src/test/java/org/cryptomator/jfuse/tests/BenchmarkTest.java @@ -30,7 +30,7 @@ public void runBenchmarks() throws IOException { @OutputTimeUnit(TimeUnit.MICROSECONDS) @BenchmarkMode(Mode.AverageTime) public void testListDirJnrMulti(Blackhole blackhole) throws IOException { - try (var ds = Files.list(Path.of("/Volumes/bar"))) { + try (var ds = Files.walk(Path.of("/Volumes/bar"), 5)) { ds.forEach(blackhole::consume); } } @@ -41,7 +41,7 @@ public void testListDirJnrMulti(Blackhole blackhole) throws IOException { @OutputTimeUnit(TimeUnit.MICROSECONDS) @BenchmarkMode(Mode.AverageTime) public void testListDirPanamaMulti(Blackhole blackhole) throws IOException { - try (var ds = Files.list(Path.of("/Volumes/foo"))) { + try (var ds = Files.walk(Path.of("/Volumes/foo"), 5)) { ds.forEach(blackhole::consume); } } From 0c217188c1f5e0640c75a7be00230f6d7d0d2668 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Wed, 14 Sep 2022 10:06:42 +0200 Subject: [PATCH 66/98] statFiller is known to be non-null --- .../jfuse/linux/aarch64/DirFillerImpl.java | 12 +++--------- .../cryptomator/jfuse/linux/amd64/DirFillerImpl.java | 12 +++--------- .../cryptomator/jfuse/win/amd64/DirFillerImpl.java | 12 +++--------- 3 files changed, 9 insertions(+), 27 deletions(-) diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/DirFillerImpl.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/DirFillerImpl.java index ee120657..91efa199 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/DirFillerImpl.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/DirFillerImpl.java @@ -19,16 +19,10 @@ record DirFillerImpl(MemoryAddress buf, fuse_fill_dir_t callback, MemorySession @Override public int fill(String name, Consumer statFiller, long offset, Set flags) { - MemoryAddress statAddr; - if (statFiller != null) { - var segment = stat.allocate(scope); - statFiller.accept(new StatImpl(segment)); - statAddr = segment.address(); - } else { - statAddr = MemoryAddress.NULL; - } + var statSegment = stat.allocate(scope); + statFiller.accept(new StatImpl(statSegment)); var encodedFlags = FillDirFlags.toMask(flags, fuse_h.FUSE_FILL_DIR_PLUS()); - return callback.apply(buf, scope.allocateUtf8String(name).address(), statAddr, offset, encodedFlags); + return callback.apply(buf, scope.allocateUtf8String(name).address(), statSegment.address(), offset, encodedFlags); } } \ No newline at end of file diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/DirFillerImpl.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/DirFillerImpl.java index c10a89f7..f0c79fb5 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/DirFillerImpl.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/DirFillerImpl.java @@ -19,16 +19,10 @@ record DirFillerImpl(MemoryAddress buf, fuse_fill_dir_t callback, MemorySession @Override public int fill(String name, Consumer statFiller, long offset, Set flags) { - MemoryAddress statAddr; - if (statFiller != null) { - var segment = stat.allocate(scope); - statFiller.accept(new StatImpl(segment)); - statAddr = segment.address(); - } else { - statAddr = MemoryAddress.NULL; - } + var statSegment = stat.allocate(scope); + statFiller.accept(new StatImpl(statSegment)); var encodedFlags = FillDirFlags.toMask(flags, fuse_h.FUSE_FILL_DIR_PLUS()); - return callback.apply(buf, scope.allocateUtf8String(name).address(), statAddr, offset, encodedFlags); + return callback.apply(buf, scope.allocateUtf8String(name).address(), statSegment.address(), offset, encodedFlags); } } \ No newline at end of file diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java index 55806c6a..8864ac9c 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java @@ -19,16 +19,10 @@ record DirFillerImpl(MemoryAddress buf, fuse3_fill_dir_t callback, MemorySession @Override public int fill(String name, Consumer statFiller, long offset, Set flags) { - MemoryAddress statAddr; - if (statFiller != null) { - var segment = fuse_stat.allocate(scope); - statFiller.accept(new StatImpl(segment)); - statAddr = segment.address(); - } else { - statAddr = MemoryAddress.NULL; - } + var statSegment = fuse_stat.allocate(scope); + statFiller.accept(new StatImpl(statSegment)); var encodedFlags = FillDirFlags.toMask(flags, fuse_h.FUSE_FILL_DIR_PLUS()); - return callback.apply(buf, scope.allocateUtf8String(name).address(), statAddr, offset, encodedFlags); + return callback.apply(buf, scope.allocateUtf8String(name).address(), statSegment.address(), offset, encodedFlags); } } \ No newline at end of file From 55ec92c98b3183ef64971a8dc962c73f64c6e1db Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Wed, 14 Sep 2022 12:45:53 +0200 Subject: [PATCH 67/98] Correct mount-finshed-check: wait for fuse gettAttr()-call for a specific file --- jfuse-tests/pom.xml | 1 - .../cryptomator/jfuse/win/amd64/FuseImpl.java | 26 ++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/jfuse-tests/pom.xml b/jfuse-tests/pom.xml index 36d4d822..cf402cb1 100644 --- a/jfuse-tests/pom.xml +++ b/jfuse-tests/pom.xml @@ -61,7 +61,6 @@ maven-surefire-plugin @{surefire.jacoco.args} -Djava.library.path=@{fuse.lib.path} --enable-native-access=ALL-UNNAMED --enable-preview - 240 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 25a05290..36e8e654 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 @@ -11,6 +11,7 @@ import org.cryptomator.jfuse.win.amd64.extr.fuse_timespec; import org.jetbrains.annotations.VisibleForTesting; +import java.io.IOException; import java.lang.foreign.Addressable; import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemoryLayout; @@ -19,6 +20,8 @@ import java.lang.foreign.ValueLayout; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributeView; +import java.nio.file.attribute.BasicFileAttributes; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; @@ -26,9 +29,14 @@ public final class FuseImpl extends Fuse { + //Used to check, if the mounted fs is actually accessible, see https://github.com/winfsp/winfsp/discussions/440 + private static final String MOUNT_PROBE = "/jfuse_windows_mount"; private final FuseOperations delegate; private final MemorySegment fuseOps; + //TODO: can we use just volatile? + private AtomicBoolean accessProbeSuccess = new AtomicBoolean(false); + public FuseImpl(FuseOperations fuseOperations) { this.fuseOps = fuse3_operations.allocate(fuseScope); this.delegate = fuseOperations; @@ -46,14 +54,22 @@ public void mount(String progName, Path mountPoint, String... flags) throws Moun try { waitForMountingToComplete(mountPoint); } catch (InterruptedException e) { + Thread.currentThread().interrupt(); throw new MountFailedException("Interrupted while waiting for mounting to finish"); } } private void waitForMountingToComplete(Path mountPoint) throws InterruptedException { - var probe = mountPoint.resolve("."); - while (!Files.exists(probe)) { - Thread.sleep(333); + var probe = Files.getFileAttributeView(mountPoint.resolve(MOUNT_PROBE.substring(1)), BasicFileAttributeView.class); + while (!accessProbeSuccess.get()) { + try { + probe.readAttributes(); + Files.readAttributes(mountPoint, BasicFileAttributes.class); + } catch (IOException e) { + //do nothing + } finally { + Thread.sleep(333); + } } } @@ -154,6 +170,10 @@ private void destroy(MemoryAddress addr) { @VisibleForTesting int getattr(MemoryAddress path, MemoryAddress stat, MemoryAddress fi) { try (var scope = MemorySession.openConfined()) { + var pathObj = path.getUtf8String(0); + if(!accessProbeSuccess.get()) { + this.accessProbeSuccess.set(pathObj.equals(MOUNT_PROBE)); + } return delegate.getattr(path.getUtf8String(0), new StatImpl(stat, scope), new FileInfoImpl(fi, scope)); } } From 766eb4a753bfe447a94cd50724cc47fd0e444ba9 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Wed, 14 Sep 2022 13:45:37 +0200 Subject: [PATCH 68/98] adjusted JNR benchmark file system for traversing a randomized dir tree --- ...FileSystem.xml => RandomJnrFileSystem.xml} | 4 +- .../jfuse/tests/BenchmarkTest.java | 4 +- .../jfuse/tests/HelloJnrFileSystem.java | 96 ------------------- .../jfuse/tests/RandomJnrFileSystem.java | 90 +++++++++++++++++ 4 files changed, 94 insertions(+), 100 deletions(-) rename .idea/runConfigurations/{HelloJnrFileSystem.xml => RandomJnrFileSystem.xml} (76%) delete mode 100644 jfuse-tests/src/test/java/org/cryptomator/jfuse/tests/HelloJnrFileSystem.java create mode 100644 jfuse-tests/src/test/java/org/cryptomator/jfuse/tests/RandomJnrFileSystem.java diff --git a/.idea/runConfigurations/HelloJnrFileSystem.xml b/.idea/runConfigurations/RandomJnrFileSystem.xml similarity index 76% rename from .idea/runConfigurations/HelloJnrFileSystem.xml rename to .idea/runConfigurations/RandomJnrFileSystem.xml index 0e5d0cf9..15e82fe9 100644 --- a/.idea/runConfigurations/HelloJnrFileSystem.xml +++ b/.idea/runConfigurations/RandomJnrFileSystem.xml @@ -1,6 +1,6 @@ - -

- * The attributes are used by the kernel to prefill the inode cache during a readdir. - *

- * It is okay to set FILL_DIR_PLUS if {@link FuseOperations.ReadDirFlags#READ_DIR_PLUS READ_DIR_PLUS} is not set - * and vice versa. - */ - FILL_DIR_PLUS; - - /** - * Encodes the given {@code flags} into a bit set. - * - * @param flags The flags - * @param fillDirPlus The constant value of {@code FUSE_FILL_DIR_PLUS} - * @return The bit set containing all the bits set for the given {@code flags} - */ - public static int toMask(Set flags, int fillDirPlus) { - return flags.contains(FILL_DIR_PLUS) - ? fillDirPlus - : 0; - } - } + /** + * "Plus" mode: all file attributes are valid. + *

+ * The attributes are used by the kernel to prefill the inode cache during a readdir. + *

+ * It is okay to set FUSE_FILL_DIR_PLUS if {@link FuseOperations#FUSE_READDIR_PLUS FUSE_READDIR_PLUS} is not set + * and vice versa. + */ + int FUSE_FILL_DIR_PLUS = 1 << 1; /** * Function to add an entry in a readdir() operation @@ -45,31 +27,31 @@ public static int toMask(Set flags, int fillDirPlus) { * @param name the file name of the directory entry * @param stat file attributes, can be NULL * @param offset offset of the next entry or zero when ignoring the offset parameter - * @param flags fill flags + * @param flags fill flags, set to {@link #FUSE_FILL_DIR_PLUS} to cache stats * @return 1 if buffer is full or an error occured, zero otherwise * @see official readdir docs * @see readdir explanation from Geoff Kuenning */ - int fill(String name, Consumer stat, long offset, Set flags); + int fill(String name, Consumer stat, long offset, int flags); /** - * Convenience wrapper for {@link #fill(String, Consumer, long, Set)}, ignoring the offset parameter. + * Convenience wrapper for {@link #fill(String, Consumer, long, int)}, ignoring the offset parameter. * * @param name The file name * @param stat A method to pre-fill the stats of this node - * @throws IOException If {@link #fill(String, Consumer, long, Set) fuse_fill_dir_t} returns 1, which indicates an error. + * @throws IOException If {@link #fill(String, Consumer, long, int) fuse_fill_dir_t} returns 1, which indicates an error. */ default void fill(String name, Consumer stat) throws IOException { - if (fill(name, stat, 0, Set.of()) != 0) { + if (fill(name, stat, 0, 0) != 0) { throw new IOException("fuse_fill_dir_t unexpectedly returned 1"); } } /** - * Convenienve wrapper for {@link #fill(String, Consumer, long, Set)}, just filling in the name, ignoring stats. + * Convenienve wrapper for {@link #fill(String, Consumer, long, int)}, just filling in the name, ignoring stats. * * @param name The file name - * @throws IOException If {@link #fill(String, Consumer, long, Set) fuse_fill_dir_t} returns 1, which indicates an error. + * @throws IOException If {@link #fill(String, Consumer, long, int) fuse_fill_dir_t} returns 1, which indicates an error. */ default void fill(String name) throws IOException { fill(name, stat -> {}); diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java index 778cb8a2..f9bdd260 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java @@ -2,6 +2,7 @@ import org.jetbrains.annotations.Nullable; +import java.io.Serializable; import java.nio.ByteBuffer; import java.util.EnumSet; import java.util.Set; @@ -39,31 +40,15 @@ enum Operation { WRITE } - enum ReadDirFlags { - - /** - * "Plus" mode. - *

- * The kernel wants to prefill the inode cache during readdir. The filesystem may honour this by filling in the - * attributes and setting {@link DirFiller.FillDirFlags FUSE_FILL_DIR_FLAGS} for the filler function. - * The filesystem may also just ignore this flag completely. - */ - READ_DIR_PLUS; - - /** - * Parses the given {@code flags}. - * - * @param flags The encoded bit set - * @param readDirPlus The constant value of {@code FUSE_READDIR_PLUS} - * @return A set containing all the {@link ReadDirFlags} values encoded in the given bit set - */ - public static Set parse(int flags, int readDirPlus) { - // currently there is only one known flag, hence this rather trivial implementation. - return (flags & readDirPlus) == readDirPlus - ? EnumSet.of(READ_DIR_PLUS) - : Set.of(); - } - } + /** + * "Plus" mode. + *

+ * The kernel wants to prefill the inode cache during readdir. The filesystem may honour this by filling in the + * attributes and setting {@link DirFiller#FUSE_FILL_DIR_PLUS FUSE_FILL_DIR_PLUS} for the filler function. + * The filesystem may also just ignore this flag completely. + */ + @SuppressWarnings("PointlessBitwiseExpression") + int FUSE_READDIR_PLUS = 1 << 0; /** * @return The error codes from errno.h for the current platform. @@ -495,7 +480,7 @@ default int opendir(String path, FileInfo fi) { * @param filler the fill function * @param offset the offset * @param fi file info - * @param flags When {@link ReadDirFlags#READ_DIR_PLUS READ_DIR_PLUS} is not set, only some parameters of the + * @param flags When {@link #FUSE_READDIR_PLUS} is not set, only some parameters of the * fill function (the {@code filler} parameter) are actually used: * The file type (which is part of {@link Stat#getMode()}) is used. And if * fuse_config::use_ino is set, the inode (stat::st_ino) is also @@ -503,7 +488,7 @@ default int opendir(String path, FileInfo fi) { * set. * @return 0 on success or negated error code (-errno) */ - default int readdir(String path, DirFiller filler, long offset, FileInfo fi, Set flags) { + default int readdir(String path, DirFiller filler, long offset, FileInfo fi, int flags) { return -errno().enosys(); } 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 1a959313..e81299c6 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 @@ -274,7 +274,7 @@ public int opendir(String path, FileInfo fi) { } @Override - public int readdir(String path, DirFiller filler, long offset, FileInfo fi, Set flags) { + public int readdir(String path, DirFiller filler, long offset, FileInfo fi, int flags) { LOG.trace("readdir {}", path); Path node = resolvePath(path); diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java index dd316584..e9e8effa 100644 --- a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java @@ -144,7 +144,7 @@ public int opendir(String path, FileInfo fi) { } @Override - public int readdir(String path, DirFiller filler, long offset, FileInfo fi, Set flags) { + public int readdir(String path, DirFiller filler, long offset, FileInfo fi, int flags) { LOG.debug("readdir() {} {}", path, offset); try { filler.fill("."); diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java index eae2e5b9..05e7fbc3 100644 --- a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java @@ -82,7 +82,7 @@ public int getattr(String path, Stat stat, FileInfo fi) { private void fillStats(RandomFileStructure.Node node, Stat stat){ if (node.isDir()) { stat.setMode(S_IFDIR | 0755); - stat.setNLink((short) (2 + node.children().size())); + stat.setNLink((short) (2 + node.children().values().stream().filter(RandomFileStructure.Node::isDir).count())); stat.mTime().set(node.lastModified()); } else { stat.setMode(S_IFREG | 0444); @@ -114,23 +114,23 @@ public int opendir(String path, FileInfo fi) { } @Override - public int readdir(String path, DirFiller filler, long offset, FileInfo fi, Set flags) { - LOG.debug("readdir() {} {} {}", path, offset, flags.stream().map(ReadDirFlags::name).collect(Collectors.joining(", "))); + public int readdir(String path, DirFiller filler, long offset, FileInfo fi, int flags) { + LOG.debug("readdir() {} offset={} plus={}", path, offset, (flags & FUSE_READDIR_PLUS) == flags); var node = rfs.getNode(path); if (node == null) { return -errno.enoent(); } else if (!node.isDir()) { return -errno.enotdir(); } else { - if (offset == 0 && filler.fill(".", stat -> fillStats(node, stat), ++offset, DirFiller.FILL_DIR_PLUS_FLAGS) != 0) + if (offset == 0 && filler.fill(".", stat -> fillStats(node, stat), ++offset, DirFiller.FUSE_FILL_DIR_PLUS) != 0) return 0; - if (offset == 1 && filler.fill("..", stat -> {}, ++offset, DirFiller.FILL_DIR_PLUS_FLAGS) != 0) + if (offset == 1 && filler.fill("..", stat -> {}, ++offset, 0) != 0) return 0; assert offset > 1; var childIter = node.children().values().stream().skip(offset - 2).iterator(); while (childIter.hasNext()) { var child = childIter.next(); - if (filler.fill(child.name(), stat -> fillStats(child, stat), ++offset, DirFiller.FILL_DIR_PLUS_FLAGS) != 0) { + if (filler.fill(child.name(), stat -> fillStats(child, stat), ++offset, DirFiller.FUSE_FILL_DIR_PLUS) != 0) { return 0; } } diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/DirFillerImpl.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/DirFillerImpl.java index 91efa199..f1a8a503 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/DirFillerImpl.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/DirFillerImpl.java @@ -18,11 +18,10 @@ record DirFillerImpl(MemoryAddress buf, fuse_fill_dir_t callback, MemorySession } @Override - public int fill(String name, Consumer statFiller, long offset, Set flags) { + public int fill(String name, Consumer statFiller, long offset, int flags) { var statSegment = stat.allocate(scope); statFiller.accept(new StatImpl(statSegment)); - var encodedFlags = FillDirFlags.toMask(flags, fuse_h.FUSE_FILL_DIR_PLUS()); - return callback.apply(buf, scope.allocateUtf8String(name).address(), statSegment.address(), offset, encodedFlags); + return callback.apply(buf, scope.allocateUtf8String(name).address(), statSegment.address(), offset, flags); } } \ No newline at end of file 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 66fe6c63..a1caabaa 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 @@ -156,8 +156,7 @@ private int read(MemoryAddress path, MemoryAddress buf, long size, long offset, private int readdir(MemoryAddress path, MemoryAddress buf, MemoryAddress filler, long offset, MemoryAddress fi, int flags) { try (var scope = MemorySession.openConfined()) { - var parsedFlags = FuseOperations.ReadDirFlags.parse(flags, fuse_h.FUSE_READDIR_PLUS()); - return delegate.readdir(path.getUtf8String(0), new DirFillerImpl(buf, filler, scope), offset, new FileInfoImpl(fi, scope), parsedFlags); + return delegate.readdir(path.getUtf8String(0), new DirFillerImpl(buf, filler, scope), offset, new FileInfoImpl(fi, scope), flags); } } diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/DirFillerImpl.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/DirFillerImpl.java index f0c79fb5..03256697 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/DirFillerImpl.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/DirFillerImpl.java @@ -18,11 +18,10 @@ record DirFillerImpl(MemoryAddress buf, fuse_fill_dir_t callback, MemorySession } @Override - public int fill(String name, Consumer statFiller, long offset, Set flags) { + public int fill(String name, Consumer statFiller, long offset, int flags) { var statSegment = stat.allocate(scope); statFiller.accept(new StatImpl(statSegment)); - var encodedFlags = FillDirFlags.toMask(flags, fuse_h.FUSE_FILL_DIR_PLUS()); - return callback.apply(buf, scope.allocateUtf8String(name).address(), statSegment.address(), offset, encodedFlags); + return callback.apply(buf, scope.allocateUtf8String(name).address(), statSegment.address(), offset, flags); } } \ No newline at end of file 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 8b6f8fab..3fb276ae 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 @@ -156,8 +156,7 @@ private int read(MemoryAddress path, MemoryAddress buf, long size, long offset, private int readdir(MemoryAddress path, MemoryAddress buf, MemoryAddress filler, long offset, MemoryAddress fi, int flags) { try (var scope = MemorySession.openConfined()) { - var parsedFlags = FuseOperations.ReadDirFlags.parse(flags, fuse_h.FUSE_READDIR_PLUS()); - return delegate.readdir(path.getUtf8String(0), new DirFillerImpl(buf, filler, scope), offset, new FileInfoImpl(fi, scope), parsedFlags); + return delegate.readdir(path.getUtf8String(0), new DirFillerImpl(buf, filler, scope), offset, new FileInfoImpl(fi, scope), flags); } } diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/DirFillerImpl.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/DirFillerImpl.java index 1bf5ac47..518234a0 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/DirFillerImpl.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/DirFillerImpl.java @@ -17,7 +17,7 @@ record DirFillerImpl(MemoryAddress buf, fuse_fill_dir_t callback, MemorySession } @Override - public int fill(String name, Consumer statFiller, long offset, Set flags) { + public int fill(String name, Consumer statFiller, long offset, int flags) { MemoryAddress statAddr; if (statFiller != null) { var segment = stat.allocate(scope); diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java index 7e4432ea..39318247 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java @@ -171,7 +171,7 @@ private int read(MemoryAddress path, MemoryAddress buf, long size, long offset, private int readdir(MemoryAddress path, MemoryAddress buf, MemoryAddress filler, long offset, MemoryAddress fi) { try (var scope = MemorySession.openConfined()) { - return delegate.readdir(path.getUtf8String(0), new DirFillerImpl(buf, filler, scope), offset, new FileInfoImpl(fi, scope), Set.of()); + return delegate.readdir(path.getUtf8String(0), new DirFillerImpl(buf, filler, scope), offset, new FileInfoImpl(fi, scope), 0); } } diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java index 8864ac9c..8a1fec8c 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/DirFillerImpl.java @@ -18,11 +18,10 @@ record DirFillerImpl(MemoryAddress buf, fuse3_fill_dir_t callback, MemorySession } @Override - public int fill(String name, Consumer statFiller, long offset, Set flags) { + public int fill(String name, Consumer statFiller, long offset, int flags) { var statSegment = fuse_stat.allocate(scope); statFiller.accept(new StatImpl(statSegment)); - var encodedFlags = FillDirFlags.toMask(flags, fuse_h.FUSE_FILL_DIR_PLUS()); - return callback.apply(buf, scope.allocateUtf8String(name).address(), statSegment.address(), offset, encodedFlags); + return callback.apply(buf, scope.allocateUtf8String(name).address(), statSegment.address(), offset, flags); } } \ No newline at end of file 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 da4c3c77..f2f26e2f 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 @@ -200,8 +200,7 @@ private int read(MemoryAddress path, MemoryAddress buf, long size, long offset, private int readdir(MemoryAddress path, MemoryAddress buf, MemoryAddress filler, long offset, MemoryAddress fi, int flags) { try (var scope = MemorySession.openConfined()) { - var parsedFlags = FuseOperations.ReadDirFlags.parse(flags, fuse_h.FUSE_READDIR_PLUS()); - return delegate.readdir(path.getUtf8String(0), new DirFillerImpl(buf, filler, scope), offset, new FileInfoImpl(fi, scope), parsedFlags); + return delegate.readdir(path.getUtf8String(0), new DirFillerImpl(buf, filler, scope), offset, new FileInfoImpl(fi, scope), flags); } } From f9b5af809fdb713e368f3200fafd9f843855b874 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Fri, 16 Sep 2022 09:22:16 +0200 Subject: [PATCH 84/98] constants no longer needed --- jfuse-linux-aarch64/pom.xml | 4 ---- .../org/cryptomator/jfuse/linux/aarch64/extr/fuse_h.java | 6 ------ jfuse-linux-amd64/pom.xml | 4 ---- .../java/org/cryptomator/jfuse/linux/amd64/extr/fuse_h.java | 6 ------ jfuse-win-amd64/pom.xml | 4 ---- .../java/org/cryptomator/jfuse/win/amd64/extr/fuse_h.java | 6 ------ 6 files changed, 30 deletions(-) diff --git a/jfuse-linux-aarch64/pom.xml b/jfuse-linux-aarch64/pom.xml index 2f79c198..8d7ad2bb 100644 --- a/jfuse-linux-aarch64/pom.xml +++ b/jfuse-linux-aarch64/pom.xml @@ -117,10 +117,6 @@ fuse_args fuse_loop_config - - FUSE_FILL_DIR_PLUS - FUSE_READDIR_PLUS - 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 c2f61f2d..c15911bd 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,12 +18,6 @@ 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 int FUSE_READDIR_PLUS() { - return (int)1L; - } - public static int FUSE_FILL_DIR_PLUS() { - return (int)2L; - } public static MethodHandle fuse_lib_help$MH() { return RuntimeHelper.requireNonNull(constants$0.fuse_lib_help$MH,"fuse_lib_help"); } diff --git a/jfuse-linux-amd64/pom.xml b/jfuse-linux-amd64/pom.xml index 726db23b..a212a140 100644 --- a/jfuse-linux-amd64/pom.xml +++ b/jfuse-linux-amd64/pom.xml @@ -117,10 +117,6 @@ fuse_args fuse_loop_config - - FUSE_FILL_DIR_PLUS - FUSE_READDIR_PLUS - 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 0ad4af01..e188e1d8 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,12 +18,6 @@ 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 int FUSE_READDIR_PLUS() { - return (int)1L; - } - public static int FUSE_FILL_DIR_PLUS() { - return (int)2L; - } public static MethodHandle fuse_lib_help$MH() { return RuntimeHelper.requireNonNull(constants$0.fuse_lib_help$MH,"fuse_lib_help"); } diff --git a/jfuse-win-amd64/pom.xml b/jfuse-win-amd64/pom.xml index 2449d602..80038558 100644 --- a/jfuse-win-amd64/pom.xml +++ b/jfuse-win-amd64/pom.xml @@ -116,10 +116,6 @@ fuse_timespec fuse3_conn_info - - FUSE_FILL_DIR_PLUS - FUSE_READDIR_PLUS - 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 e6eb234f..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 @@ -18,12 +18,6 @@ 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 int FUSE_READDIR_PLUS() { - return (int)1L; - } - public static int FUSE_FILL_DIR_PLUS() { - return (int)2L; - } public static MethodHandle fuse3_lib_help$MH() { return RuntimeHelper.requireNonNull(constants$0.fuse3_lib_help$MH,"fuse3_lib_help"); } From f3e927371ece4072795ff11b5beddb86799a7194 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Fri, 16 Sep 2022 09:35:45 +0200 Subject: [PATCH 85/98] remove unused imports --- .../src/main/java/org/cryptomator/jfuse/api/DirFiller.java | 2 -- .../src/main/java/org/cryptomator/jfuse/api/FuseOperations.java | 2 -- .../org/cryptomator/jfuse/examples/HelloWorldFileSystem.java | 1 - .../java/org/cryptomator/jfuse/examples/RandomFileSystem.java | 1 - jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java | 1 - 5 files changed, 7 deletions(-) diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/DirFiller.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/DirFiller.java index 5613ed47..30294426 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/DirFiller.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/DirFiller.java @@ -1,8 +1,6 @@ package org.cryptomator.jfuse.api; import java.io.IOException; -import java.util.EnumSet; -import java.util.Set; import java.util.function.Consumer; public interface DirFiller { diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java index f9bdd260..c4dcb4dd 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseOperations.java @@ -2,9 +2,7 @@ import org.jetbrains.annotations.Nullable; -import java.io.Serializable; import java.nio.ByteBuffer; -import java.util.EnumSet; import java.util.Set; /** diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java index e9e8effa..d1051499 100644 --- a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java @@ -19,7 +19,6 @@ import java.util.EnumSet; import java.util.Set; import java.util.concurrent.TimeoutException; -import java.util.stream.Stream; @SuppressWarnings("OctalInteger") public class HelloWorldFileSystem implements FuseOperations { diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java index 05e7fbc3..17ab67d1 100644 --- a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java @@ -17,7 +17,6 @@ import java.util.EnumSet; import java.util.Set; import java.util.concurrent.TimeoutException; -import java.util.stream.Collectors; @SuppressWarnings("OctalInteger") public class RandomFileSystem implements FuseOperations { diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java index 39318247..f4655367 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseImpl.java @@ -18,7 +18,6 @@ import java.lang.foreign.MemorySession; import java.lang.foreign.ValueLayout; import java.util.List; -import java.util.Set; import static java.lang.foreign.ValueLayout.JAVA_INT; From a233674091980561adb913c1464facbd147cb31a Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Fri, 16 Sep 2022 11:41:47 +0200 Subject: [PATCH 86/98] explicitly enable native access during tests this fixes a warning indicating that this might become necessary in future JDK versions [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 21097902..6c9a62d4 100644 --- a/pom.xml +++ b/pom.xml @@ -185,7 +185,7 @@ org.apache.maven.plugins maven-surefire-plugin - @{surefire.jacoco.args} --enable-preview + @{surefire.jacoco.args} --enable-preview --enable-native-access=ALL-UNNAMED From a510c15714eb33d2b34f41124a95e8cb7176af8a Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Fri, 16 Sep 2022 12:25:12 +0200 Subject: [PATCH 87/98] improve unit tests for Stat class --- .../org/cryptomator/jfuse/api/StatTest.java | 163 +++++++----------- 1 file changed, 58 insertions(+), 105 deletions(-) diff --git a/jfuse-api/src/test/java/org/cryptomator/jfuse/api/StatTest.java b/jfuse-api/src/test/java/org/cryptomator/jfuse/api/StatTest.java index 836fbf8b..8d1b8617 100644 --- a/jfuse-api/src/test/java/org/cryptomator/jfuse/api/StatTest.java +++ b/jfuse-api/src/test/java/org/cryptomator/jfuse/api/StatTest.java @@ -1,11 +1,16 @@ package org.cryptomator.jfuse.api; import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; import org.mockito.ArgumentMatcher; import org.mockito.Mockito; +import java.util.stream.Stream; + import static org.cryptomator.jfuse.api.Stat.S_IFDIR; import static org.cryptomator.jfuse.api.Stat.S_IFLNK; import static org.cryptomator.jfuse.api.Stat.S_IFREG; @@ -16,122 +21,70 @@ public class StatTest { public Stat stat = Mockito.spy(new StubStatImpl()); - @Nested - public class DirTest { - - @Test - public void testIsDir() { - Mockito.when(stat.getMode()).thenReturn(S_IFDIR | MAGIC); - Assertions.assertTrue(stat.isDir()); - } - - @Test - public void testToggleDir1() { - Mockito.when(stat.getMode()).thenReturn(S_IFDIR | MAGIC); - stat.toggleDir(true); - Mockito.verify(stat).setMode(Mockito.intThat(hasBitsSet(Stat.S_IFDIR))); - } - - @Test - public void testToggleDir2() { - Mockito.when(stat.getMode()).thenReturn(0); - stat.toggleDir(true); - Mockito.verify(stat).setMode(Mockito.intThat(hasBitsSet(Stat.S_IFDIR))); - } - - @Test - public void testToggleDir3() { - Mockito.when(stat.getMode()).thenReturn(S_IFDIR | MAGIC); - stat.toggleDir(false); - Mockito.verify(stat).setMode(Mockito.intThat(hasBitsNotSet(Stat.S_IFDIR))); - } - - @Test - public void testToggleDir4() { - Mockito.when(stat.getMode()).thenReturn(0); - stat.toggleDir(false); - Mockito.verify(stat).setMode(Mockito.intThat(hasBitsNotSet(Stat.S_IFDIR))); - } - + @ParameterizedTest + @MethodSource("provideDataForToggle") + public void testToggleMode(int mode, int mask, boolean toSet) { + Mockito.when(stat.getMode()).thenReturn(mode); + stat.toggleMode(mask, toSet); + Mockito.verify(stat).setMode(Mockito.intThat(toSet ? hasBitsSet(mask) : hasBitsNotSet(mask))); } - @Nested - public class RegTest { - - @Test - public void testIsReg() { - Mockito.when(stat.getMode()).thenReturn(S_IFREG | MAGIC); - Assertions.assertTrue(stat.isReg()); - } - - @Test - public void testToggleReg1() { - Mockito.when(stat.getMode()).thenReturn(S_IFREG | MAGIC); - stat.toggleReg(true); - Mockito.verify(stat).setMode(Mockito.intThat(hasBitsSet(S_IFREG))); - } - - @Test - public void testToggleReg2() { - Mockito.when(stat.getMode()).thenReturn(0); - stat.toggleReg(true); - Mockito.verify(stat).setMode(Mockito.intThat(hasBitsSet(S_IFREG))); - } - - @Test - public void testToggleReg3() { - Mockito.when(stat.getMode()).thenReturn(S_IFREG | MAGIC); - stat.toggleReg(false); - Mockito.verify(stat).setMode(Mockito.intThat(hasBitsNotSet(S_IFREG))); - } - - @Test - public void testToggleReg4() { - Mockito.when(stat.getMode()).thenReturn(0); - stat.toggleReg(false); - Mockito.verify(stat).setMode(Mockito.intThat(hasBitsNotSet(S_IFREG))); - } + public static Stream provideDataForToggle() { + return Stream.of( + Arguments.arguments(S_IFDIR, S_IFDIR, true), // + Arguments.arguments(S_IFDIR, S_IFDIR, false), // + Arguments.arguments(0, S_IFDIR, true), // + Arguments.arguments(0, S_IFDIR, false) + ); + } + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void testHasMode(boolean isPresent) { + Mockito.when(stat.getMode()).thenReturn(isPresent ? MAGIC : ~MAGIC); + boolean result = stat.hasMode(MAGIC); + Assertions.assertEquals(isPresent, result); } - @Nested - public class LnkTest { - @Test - public void testIsLnk() { - Mockito.when(stat.getMode()).thenReturn(S_IFLNK | MAGIC); - Assertions.assertTrue(stat.isLnk()); - } + @Test + public void testIsDir() { + stat.isDir(); + Mockito.verify(stat).hasMode(S_IFDIR); + } - @Test - public void testToggleLnk1() { - Mockito.when(stat.getMode()).thenReturn(S_IFLNK | MAGIC); - stat.toggleLnk(true); - Mockito.verify(stat).setMode(Mockito.intThat(hasBitsSet(S_IFLNK))); - } + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void testToggleDir(boolean isDir) { + stat.toggleDir(isDir); + Mockito.verify(stat).toggleMode(S_IFDIR, isDir); + } - @Test - public void testToggleLnk2() { - Mockito.when(stat.getMode()).thenReturn(0); - stat.toggleLnk(true); - Mockito.verify(stat).setMode(Mockito.intThat(hasBitsSet(S_IFLNK))); - } + @Test + public void testIsReg() { + stat.isReg(); + Mockito.verify(stat).hasMode(S_IFREG); + } - @Test - public void testToggleLnk3() { - Mockito.when(stat.getMode()).thenReturn(S_IFLNK | MAGIC); - stat.toggleLnk(false); - Mockito.verify(stat).setMode(Mockito.intThat(hasBitsNotSet(S_IFLNK))); - } + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void testToggleReg(boolean isReg) { + stat.toggleReg(isReg); + Mockito.verify(stat).toggleMode(S_IFREG, isReg); + } - @Test - public void testToggleLnk4() { - Mockito.when(stat.getMode()).thenReturn(0); - stat.toggleLnk(false); - Mockito.verify(stat).setMode(Mockito.intThat(hasBitsNotSet(S_IFLNK))); - } + @Test + public void testIsLnk() { + stat.isLnk(); + Mockito.verify(stat).hasMode(S_IFLNK); } + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void testToggleLnk(boolean isLnk) { + stat.toggleLnk(isLnk); + Mockito.verify(stat).toggleMode(S_IFLNK, isLnk); + } private static ArgumentMatcher hasBitsSet(int mask) { return toMatch -> (toMatch & mask) == mask; From 322111452c75a49123fd1609e6d14b6d4bfb8b7f Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Fri, 16 Sep 2022 12:36:02 +0200 Subject: [PATCH 88/98] don't redefine constants --- .../cryptomator/jfuse/examples/HelloWorldFileSystem.java | 8 ++++---- .../org/cryptomator/jfuse/examples/RandomFileSystem.java | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java index d1051499..ad07fcb5 100644 --- a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/HelloWorldFileSystem.java @@ -20,11 +20,10 @@ import java.util.Set; import java.util.concurrent.TimeoutException; -@SuppressWarnings("OctalInteger") -public class HelloWorldFileSystem implements FuseOperations { +import static org.cryptomator.jfuse.api.Stat.S_IFDIR; +import static org.cryptomator.jfuse.api.Stat.S_IFREG; - private static final int S_IFDIR = 0040000; - private static final int S_IFREG = 0100000; +public class HelloWorldFileSystem implements FuseOperations { private static final Logger LOG = LoggerFactory.getLogger(HelloWorldFileSystem.class); @@ -74,6 +73,7 @@ public int access(String path, int mask) { return 0; } + @SuppressWarnings("OctalInteger") @Override public int getattr(String path, Stat stat, FileInfo fi) { LOG.debug("getattr() {}", path); diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java index 17ab67d1..e9fa0735 100644 --- a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java @@ -18,11 +18,11 @@ import java.util.Set; import java.util.concurrent.TimeoutException; -@SuppressWarnings("OctalInteger") +import static org.cryptomator.jfuse.api.Stat.S_IFDIR; +import static org.cryptomator.jfuse.api.Stat.S_IFREG; + public class RandomFileSystem implements FuseOperations { - private static final int S_IFDIR = 0040000; - private static final int S_IFREG = 0100000; private static final Logger LOG = LoggerFactory.getLogger(RandomFileSystem.class); private final Errno errno; @@ -78,6 +78,7 @@ public int getattr(String path, Stat stat, FileInfo fi) { } } + @SuppressWarnings("OctalInteger") private void fillStats(RandomFileStructure.Node node, Stat stat){ if (node.isDir()) { stat.setMode(S_IFDIR | 0755); From b9b6504a833438da4ccb65fca08ec698bdcd6611 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Fri, 16 Sep 2022 13:15:23 +0200 Subject: [PATCH 89/98] extend FuseConnInfo class: * union of libfuse 2 and 3 defintion * add readdirplus capability in fuse_conn_info.want by default for linux and windows * document support for libufse2/3 --- .../cryptomator/jfuse/api/FuseConnInfo.java | 138 ++++++++++++++++++ .../jfuse/linux/aarch64/FuseConnInfoImpl.java | 76 ++++++++++ .../jfuse/linux/aarch64/FuseImpl.java | 5 +- .../jfuse/linux/amd64/FuseConnInfoImpl.java | 76 ++++++++++ .../jfuse/linux/amd64/FuseImpl.java | 5 +- .../jfuse/mac/FuseConnInfoImpl.java | 65 +++++++++ .../jfuse/win/amd64/FuseConnInfoImpl.java | 76 ++++++++++ .../cryptomator/jfuse/win/amd64/FuseImpl.java | 5 +- 8 files changed, 443 insertions(+), 3 deletions(-) diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseConnInfo.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseConnInfo.java index af9f1ec3..16a2360f 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseConnInfo.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseConnInfo.java @@ -1,8 +1,146 @@ package org.cryptomator.jfuse.api; +/** + * Fuse connection info struct used in {@link FuseOperations#init(FuseConnInfo)} method. + *

+ * This struct is a union of the libfuse2 and libfuse3 definition. If an accessor method or macro is not supported by used libfuse version, it is documented in the javadoc. + * See also @code{fuse_common.h} of libfuse2 or 3. + */ public interface FuseConnInfo { + int FUSE_CAP_ASYNC_READ = (1 << 0); + int FUSE_CAP_POSIX_LOCKS = (1 << 1); + int FUSE_CAP_ATOMIC_O_TRUNC = (1 << 3); + int FUSE_CAP_EXPORT_SUPPORT = (1 << 4); + /** + * Libfuse2 only + */ + int FUSE_CAP_BIG_WRITES = (1 << 5); + int FUSE_CAP_DONT_MASK = (1 << 6); + int FUSE_CAP_SPLICE_WRITE = (1 << 7); + int FUSE_CAP_SPLICE_MOVE = (1 << 8); + int FUSE_CAP_SPLICE_READ = (1 << 9); + int FUSE_CAP_IOCTL_DIR = (1 << 11); + /** + * Libfuse3 only + */ + int FUSE_CAP_AUTO_INVAL_DATA = (1 << 12); + /** + * Libfuse3 only + */ + int FUSE_CAP_READDIRPLUS = (1 << 13); + /** + * Libfuse3 only + */ + int FUSE_CAP_READDIRPLUS_AUTO = (1 << 14); + /** + * Libfuse3 only + */ + int FUSE_CAP_ASYNC_DIO = (1 << 15); + /** + * Libfuse3 only + */ + int FUSE_CAP_WRITEBACK_CACHE = (1 << 16); + /** + * Libfuse3 only + */ + int FUSE_CAP_NO_OPEN_SUPPORT = (1 << 17); + /** + * Libfuse3 only + */ + int FUSE_CAP_PARALLEL_DIROPS = (1 << 18); + /** + * Libfuse3 only + */ + int FUSE_CAP_POSIX_ACL = (1 << 19); + /** + * Libfuse3 only + */ + int FUSE_CAP_HANDLE_KILLPRIV = (1 << 20); + /** + * Libfuse3 only + */ + int FUSE_CAP_CACHE_SYMLINKS = (1 << 23); + /** + * Libfuse3 only + */ + int FUSE_CAP_NO_OPENDIR_SUPPORT = (1 << 24); + /** + * Libfuse3 only + */ + int FUSE_CAP_EXPLICIT_INVAL_DATA = (1 << 25); + int protoMajor(); int protoMinor(); + + int capable(); + + int want(); + + void setWant(int wanted); + + int maxWrite(); + + void setMaxWrite(int maxWrite); + + /** + * Libfuse3 only + * + * @return maxRead value of fuse_conn_info or 0 if not supported + */ + default int maxRead() { + return 0; + } + + /** + * Libfuse3 only + */ + default void setMaxRead(int maxRead) { + //no-op + } + + int maxReadahead(); + + void setMaxReadahead(int maxReadahead); + + int maxBackground(); + + void setMaxBackground(int maxBackground); + + int congestionThreshold(); + + void setCongestionThreshold(int congestionThreshold); + + /** + * Libfuse3 only + * + * @return time_gran value of fuse_conn_info or 0 if not supported + */ + default int timeGran() { + return 0; + } + + /** + * Libfuse3 only + */ + default void setTimeGran(int timeGran) { + //no-op + } + + /** + * Libfuse2 only + * + * @return async_read value of fuse_conn_info or 0 if not supported + */ + default int asyncRead() { + return 0; + } + + /** + * Libfuse2 only + */ + default void setAsyncRead(int asyncRead) { + //no-op + } } diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseConnInfoImpl.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseConnInfoImpl.java index 30b6b147..70559522 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseConnInfoImpl.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseConnInfoImpl.java @@ -22,4 +22,80 @@ public int protoMajor() { public int protoMinor() { return fuse_conn_info.proto_minor$get(segment); } + + @Override + public int capable() { + return fuse_conn_info.capable$get(segment); + } + + @Override + public void setWant(int wanted) { + fuse_conn_info.want$set(segment, wanted); + + } + + @Override + public int maxWrite() { + return fuse_conn_info.max_write$get(segment); + } + + @Override + public void setMaxWrite(int maxWrite) { + fuse_conn_info.max_write$set(segment, maxWrite); + } + + @Override + public int maxRead() { + return fuse_conn_info.max_read$get(segment); + } + + @Override + public void setMaxRead(int maxRead) { + fuse_conn_info.max_read$set(segment, maxRead); + } + + @Override + public int maxReadahead() { + return fuse_conn_info.max_readahead$get(segment); + } + + @Override + public void setMaxReadahead(int maxReadahead) { + fuse_conn_info.max_readahead$set(segment, maxReadahead); + } + + @Override + public int maxBackground() { + return fuse_conn_info.max_background$get(segment); + } + + @Override + public void setMaxBackground(int maxBackground) { + fuse_conn_info.max_background$set(segment, maxBackground); + } + + @Override + public int congestionThreshold() { + return fuse_conn_info.congestion_threshold$get(segment); + } + + @Override + public void setCongestionThreshold(int congestionThreshold) { + fuse_conn_info.congestion_threshold$set(segment, congestionThreshold); + } + + @Override + public int timeGran() { + return fuse_conn_info.time_gran$get(segment); + } + + @Override + public void setTimeGran(int timeGran) { + fuse_conn_info.time_gran$set(segment, timeGran); + } + + @Override + public int want() { + return fuse_conn_info.want$get(segment); + } } 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 a1caabaa..158ca63d 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 @@ -1,6 +1,7 @@ package org.cryptomator.jfuse.linux.aarch64; import org.cryptomator.jfuse.api.Fuse; +import org.cryptomator.jfuse.api.FuseConnInfo; import org.cryptomator.jfuse.api.FuseMount; import org.cryptomator.jfuse.api.FuseOperations; import org.cryptomator.jfuse.api.MountFailedException; @@ -100,7 +101,9 @@ private void bind(FuseOperations.Operation operation) { private Addressable init(MemoryAddress conn, MemoryAddress fuseConfig) { try (var scope = MemorySession.openConfined()) { - delegate.init(new FuseConnInfoImpl(conn, scope)); + var connInfo = new FuseConnInfoImpl(conn, scope); + connInfo.setWant(connInfo.want() | FuseConnInfo.FUSE_CAP_READDIRPLUS); + delegate.init(connInfo); } return MemoryAddress.NULL; } diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseConnInfoImpl.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseConnInfoImpl.java index 7b4e0233..eb2d9a29 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseConnInfoImpl.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseConnInfoImpl.java @@ -22,4 +22,80 @@ public int protoMajor() { public int protoMinor() { return fuse_conn_info.proto_minor$get(segment); } + + @Override + public int capable() { + return fuse_conn_info.capable$get(segment); + } + + @Override + public void setWant(int wanted) { + fuse_conn_info.want$set(segment, wanted); + + } + + @Override + public int maxWrite() { + return fuse_conn_info.max_write$get(segment); + } + + @Override + public void setMaxWrite(int maxWrite) { + fuse_conn_info.max_write$set(segment, maxWrite); + } + + @Override + public int maxRead() { + return fuse_conn_info.max_read$get(segment); + } + + @Override + public void setMaxRead(int maxRead) { + fuse_conn_info.max_read$set(segment, maxRead); + } + + @Override + public int maxReadahead() { + return fuse_conn_info.max_readahead$get(segment); + } + + @Override + public void setMaxReadahead(int maxReadahead) { + fuse_conn_info.max_readahead$set(segment, maxReadahead); + } + + @Override + public int maxBackground() { + return fuse_conn_info.max_background$get(segment); + } + + @Override + public void setMaxBackground(int maxBackground) { + fuse_conn_info.max_background$set(segment, maxBackground); + } + + @Override + public int congestionThreshold() { + return fuse_conn_info.congestion_threshold$get(segment); + } + + @Override + public void setCongestionThreshold(int congestionThreshold) { + fuse_conn_info.congestion_threshold$set(segment, congestionThreshold); + } + + @Override + public int timeGran() { + return fuse_conn_info.time_gran$get(segment); + } + + @Override + public void setTimeGran(int timeGran) { + fuse_conn_info.time_gran$set(segment, timeGran); + } + + @Override + public int want() { + return fuse_conn_info.want$get(segment); + } } 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 3fb276ae..328a9e8c 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 @@ -1,6 +1,7 @@ package org.cryptomator.jfuse.linux.amd64; import org.cryptomator.jfuse.api.Fuse; +import org.cryptomator.jfuse.api.FuseConnInfo; import org.cryptomator.jfuse.api.FuseMount; import org.cryptomator.jfuse.api.FuseOperations; import org.cryptomator.jfuse.api.MountFailedException; @@ -100,7 +101,9 @@ private void bind(FuseOperations.Operation operation) { private Addressable init(MemoryAddress conn, MemoryAddress fuseConfig) { try (var scope = MemorySession.openConfined()) { - delegate.init(new FuseConnInfoImpl(conn, scope)); + var connInfo = new FuseConnInfoImpl(conn, scope); + connInfo.setWant(connInfo.want() | FuseConnInfo.FUSE_CAP_READDIRPLUS); + delegate.init(connInfo); } return MemoryAddress.NULL; } diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseConnInfoImpl.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseConnInfoImpl.java index 71e3ac20..154599bd 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseConnInfoImpl.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseConnInfoImpl.java @@ -22,4 +22,69 @@ public int protoMajor() { public int protoMinor() { return fuse_conn_info.proto_minor$get(segment); } + @Override + public int capable() { + return fuse_conn_info.capable$get(segment); + } + + @Override + public void setWant(int wanted) { + fuse_conn_info.want$set(segment, wanted); + + } + + @Override + public int maxWrite() { + return fuse_conn_info.max_write$get(segment); + } + + @Override + public void setMaxWrite(int maxWrite) { + fuse_conn_info.max_write$set(segment, maxWrite); + } + + @Override + public int maxReadahead() { + return fuse_conn_info.max_readahead$get(segment); + } + + @Override + public void setMaxReadahead(int maxReadahead) { + fuse_conn_info.max_readahead$set(segment, maxReadahead); + } + + @Override + public int maxBackground() { + return fuse_conn_info.max_background$get(segment); + } + + @Override + public void setMaxBackground(int maxBackground) { + fuse_conn_info.max_background$set(segment, maxBackground); + } + + @Override + public int congestionThreshold() { + return fuse_conn_info.congestion_threshold$get(segment); + } + + @Override + public void setCongestionThreshold(int congestionThreshold) { + fuse_conn_info.congestion_threshold$set(segment, congestionThreshold); + } + + @Override + public int asyncRead() { + return fuse_conn_info.async_read$get(segment); + } + + @Override + public void setAsyncRead(int asyncRead) { + fuse_conn_info.async_read$set(segment, asyncRead); + } + + @Override + public int want() { + return fuse_conn_info.want$get(segment); + } } diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseConnInfoImpl.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseConnInfoImpl.java index 76acf617..d20d3c6f 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseConnInfoImpl.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseConnInfoImpl.java @@ -22,4 +22,80 @@ public int protoMajor() { public int protoMinor() { return fuse3_conn_info.proto_minor$get(segment); } + + @Override + public int capable() { + return fuse3_conn_info.capable$get(segment); + } + + @Override + public void setWant(int wanted) { + fuse3_conn_info.want$set(segment, wanted); + + } + + @Override + public int maxWrite() { + return fuse3_conn_info.max_write$get(segment); + } + + @Override + public void setMaxWrite(int maxWrite) { + fuse3_conn_info.max_write$set(segment, maxWrite); + } + + @Override + public int maxRead() { + return fuse3_conn_info.max_read$get(segment); + } + + @Override + public void setMaxRead(int maxRead) { + fuse3_conn_info.max_read$set(segment, maxRead); + } + + @Override + public int maxReadahead() { + return fuse3_conn_info.max_readahead$get(segment); + } + + @Override + public void setMaxReadahead(int maxReadahead) { + fuse3_conn_info.max_readahead$set(segment, maxReadahead); + } + + @Override + public int maxBackground() { + return fuse3_conn_info.max_background$get(segment); + } + + @Override + public void setMaxBackground(int maxBackground) { + fuse3_conn_info.max_background$set(segment, maxBackground); + } + + @Override + public int congestionThreshold() { + return fuse3_conn_info.congestion_threshold$get(segment); + } + + @Override + public void setCongestionThreshold(int congestionThreshold) { + fuse3_conn_info.congestion_threshold$set(segment, congestionThreshold); + } + + @Override + public int timeGran() { + return fuse3_conn_info.time_gran$get(segment); + } + + @Override + public void setTimeGran(int timeGran) { + fuse3_conn_info.time_gran$set(segment, timeGran); + } + + @Override + public int want() { + return fuse3_conn_info.want$get(segment); + } } 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 f2f26e2f..1c8f4eb3 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 @@ -1,6 +1,7 @@ package org.cryptomator.jfuse.win.amd64; import org.cryptomator.jfuse.api.Fuse; +import org.cryptomator.jfuse.api.FuseConnInfo; import org.cryptomator.jfuse.api.FuseMount; import org.cryptomator.jfuse.api.FuseOperations; import org.cryptomator.jfuse.api.MountFailedException; @@ -143,7 +144,9 @@ private void bind(FuseOperations.Operation operation) { private Addressable init(MemoryAddress conn, MemoryAddress fuseConfig) { try (var scope = MemorySession.openConfined()) { - delegate.init(new FuseConnInfoImpl(conn, scope)); + var connInfo = new FuseConnInfoImpl(conn, scope); + connInfo.setWant(connInfo.want() | FuseConnInfo.FUSE_CAP_READDIRPLUS); + delegate.init(connInfo); } return MemoryAddress.NULL; } From 5cb494bf6496d03eb11599eb491151d276b8c043 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Fri, 16 Sep 2022 13:25:49 +0200 Subject: [PATCH 90/98] cleanup --- README.md | 4 +++- .../java/org/cryptomator/jfuse/examples/RandomFileSystem.java | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ee43308f..8ac882a3 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,9 @@ Zero-Dependency Java bindings for FUSE using [JEP 424](https://openjdk.org/jeps/ This is currently an experimental library requiring JDK 19. As long as the [Foreign Function & Memory API](https://openjdk.org/jeps/424) is incubating, the required JDK will increase. -We attempt to support libfuse 3.x on Linux while also remaining compatible with libfuse 2.x on macOS and Windows, leading to some compromises in the API. Windows support for libfuse 3.x is planned. +We attempt to support libfuse 3.x on Linux and Windows while also remaining compatible with libfuse 2.x on macOS, leading to some compromises in the API. + +For libfuse 3 to ensure that the `readdir` operation runs in readdirplus mode, you have to add `FuseOperations.Operation.INIT` to the set returend by `FuseOperations::supportedOperations` method to the supported operations. An implementation of `init` is not necessary. ### Supported `fuse_operations` diff --git a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java index e9fa0735..6336c43d 100644 --- a/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java +++ b/jfuse-examples/src/main/java/org/cryptomator/jfuse/examples/RandomFileSystem.java @@ -63,7 +63,7 @@ public Errno errno() { @Override public Set supportedOperations() { - return EnumSet.of(Operation.GET_ATTR, Operation.OPEN, Operation.OPEN_DIR, Operation.READ, Operation.READ_DIR, Operation.RELEASE, Operation.RELEASE_DIR, Operation.STATFS); + return EnumSet.of(Operation.GET_ATTR, Operation.OPEN, Operation.OPEN_DIR, Operation.READ, Operation.READ_DIR, Operation.RELEASE, Operation.RELEASE_DIR, Operation.STATFS, Operation.INIT); } @Override From cf3e2bb658bbfbc632ea5e57fd08d20fc6ce4400 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Fri, 16 Sep 2022 14:25:40 +0200 Subject: [PATCH 91/98] added tests for init() --- .../jfuse/linux/aarch64/FuseImpl.java | 3 ++- .../jfuse/linux/aarch64/FuseImplTest.java | 22 +++++++++++++++++++ .../jfuse/linux/amd64/FuseImpl.java | 3 ++- .../jfuse/linux/amd64/FuseImplTest.java | 22 +++++++++++++++++++ .../cryptomator/jfuse/win/amd64/FuseImpl.java | 3 ++- .../jfuse/win/amd64/FuseImplTest.java | 22 +++++++++++++++++++ 6 files changed, 72 insertions(+), 3 deletions(-) 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 158ca63d..b7e084a0 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 @@ -99,7 +99,8 @@ private void bind(FuseOperations.Operation operation) { } } - private Addressable init(MemoryAddress conn, MemoryAddress fuseConfig) { + @VisibleForTesting + Addressable init(MemoryAddress conn, MemoryAddress fuseConfig) { try (var scope = MemorySession.openConfined()) { var connInfo = new FuseConnInfoImpl(conn, scope); connInfo.setWant(connInfo.want() | FuseConnInfo.FUSE_CAP_READDIRPLUS); 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 e96d92fe..393d1569 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 @@ -1,8 +1,10 @@ package org.cryptomator.jfuse.linux.aarch64; +import org.cryptomator.jfuse.api.FuseConnInfo; 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_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; @@ -28,6 +30,7 @@ import java.lang.foreign.MemorySession; import java.time.Instant; import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; public class FuseImplTest { @@ -121,6 +124,25 @@ public void testParseArgs() { } } + @DisplayName("init() sets fuse_conn_info.wants |= FUSE_CAP_READDIRPLUS") + @Test + public void testInit() { + try (var scope = MemorySession.openConfined()) { + var result = new AtomicInteger(); + Mockito.doAnswer(invocation -> { + FuseConnInfo connInfo = invocation.getArgument(0); + result.set(connInfo.want()); + return null; + }).when(fuseOps).init(Mockito.any()); + var connInfo = fuse_conn_info.allocate(scope); + var fuseConfig = MemoryAddress.NULL; // TODO jextract fuse_config + + fuseImpl.init(connInfo.address(), fuseConfig.address()); + + Assertions.assertEquals(FuseConnInfo.FUSE_CAP_READDIRPLUS, result.get() & FuseConnInfo.FUSE_CAP_READDIRPLUS); + } + } + @Nested @DisplayName("utimens") public class Utimens { 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 328a9e8c..55bdb212 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 @@ -99,7 +99,8 @@ private void bind(FuseOperations.Operation operation) { } } - private Addressable init(MemoryAddress conn, MemoryAddress fuseConfig) { + @VisibleForTesting + Addressable init(MemoryAddress conn, MemoryAddress fuseConfig) { try (var scope = MemorySession.openConfined()) { var connInfo = new FuseConnInfoImpl(conn, scope); connInfo.setWant(connInfo.want() | FuseConnInfo.FUSE_CAP_READDIRPLUS); 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 af4f614f..590a5155 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 @@ -1,8 +1,10 @@ package org.cryptomator.jfuse.linux.amd64; +import org.cryptomator.jfuse.api.FuseConnInfo; 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_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; @@ -26,6 +28,7 @@ import java.lang.foreign.MemorySession; import java.time.Instant; import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; public class FuseImplTest { @@ -119,6 +122,25 @@ public void testParseArgs() { } } + @DisplayName("init() sets fuse_conn_info.wants |= FUSE_CAP_READDIRPLUS") + @Test + public void testInit() { + try (var scope = MemorySession.openConfined()) { + var result = new AtomicInteger(); + Mockito.doAnswer(invocation -> { + FuseConnInfo connInfo = invocation.getArgument(0); + result.set(connInfo.want()); + return null; + }).when(fuseOps).init(Mockito.any()); + var connInfo = fuse_conn_info.allocate(scope); + var fuseConfig = MemoryAddress.NULL; // TODO jextract fuse_config + + fuseImpl.init(connInfo.address(), fuseConfig.address()); + + Assertions.assertEquals(FuseConnInfo.FUSE_CAP_READDIRPLUS, result.get() & FuseConnInfo.FUSE_CAP_READDIRPLUS); + } + } + @Nested @DisplayName("utimens") public class Utimens { 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 1c8f4eb3..37ff1703 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 @@ -142,7 +142,8 @@ private void bind(FuseOperations.Operation operation) { } } - private Addressable init(MemoryAddress conn, MemoryAddress fuseConfig) { + @VisibleForTesting + Addressable init(MemoryAddress conn, MemoryAddress fuseConfig) { try (var scope = MemorySession.openConfined()) { var connInfo = new FuseConnInfoImpl(conn, scope); connInfo.setWant(connInfo.want() | FuseConnInfo.FUSE_CAP_READDIRPLUS); 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 5465a0a5..fad54afc 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 @@ -1,10 +1,12 @@ package org.cryptomator.jfuse.win.amd64; import org.cryptomator.jfuse.api.FileInfo; +import org.cryptomator.jfuse.api.FuseConnInfo; import org.cryptomator.jfuse.api.FuseMount; import org.cryptomator.jfuse.api.FuseOperations; import org.cryptomator.jfuse.api.MountFailedException; import org.cryptomator.jfuse.win.amd64.extr.fuse2.fuse2_h; +import org.cryptomator.jfuse.win.amd64.extr.fuse3_conn_info; import org.cryptomator.jfuse.win.amd64.extr.fuse3_file_info; import org.cryptomator.jfuse.win.amd64.extr.fuse_h; import org.cryptomator.jfuse.win.amd64.extr.fuse_stat; @@ -34,6 +36,7 @@ import java.time.Duration; import java.time.Instant; import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; import static java.lang.foreign.ValueLayout.JAVA_INT; @@ -166,6 +169,25 @@ public void testParseArgs() { } } + @DisplayName("init() sets fuse_conn_info.wants |= FUSE_CAP_READDIRPLUS") + @Test + public void testInit() { + try (var scope = MemorySession.openConfined()) { + var result = new AtomicInteger(); + Mockito.doAnswer(invocation -> { + FuseConnInfo connInfo = invocation.getArgument(0); + result.set(connInfo.want()); + return null; + }).when(fuseOps).init(Mockito.any()); + var connInfo = fuse3_conn_info.allocate(scope); + var fuseConfig = MemoryAddress.NULL; // TODO jextract fuse_config + + fuseImpl.init(connInfo.address(), fuseConfig.address()); + + Assertions.assertEquals(FuseConnInfo.FUSE_CAP_READDIRPLUS, result.get() & FuseConnInfo.FUSE_CAP_READDIRPLUS); + } + } + @Nested @DisplayName("utimens") public class Utimens { From 34f2f5b1b6f016f830e767d109799850b81c830c Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Fri, 16 Sep 2022 15:01:37 +0200 Subject: [PATCH 92/98] added unit tests --- .../cryptomator/jfuse/api/FuseConnInfo.java | 1 + .../jfuse/linux/aarch64/FuseConnInfoImpl.java | 10 +-- .../linux/aarch64/FuseConnInfoImplTest.java | 83 +++++++++++++++++++ .../jfuse/linux/amd64/FuseConnInfoImpl.java | 10 +-- .../linux/amd64/FuseConnInfoImplTest.java | 83 +++++++++++++++++++ .../jfuse/mac/FuseConnInfoImpl.java | 9 +- .../jfuse/mac/FuseConnInfoImplTest.java | 81 ++++++++++++++++++ .../jfuse/win/amd64/FuseConnInfoImpl.java | 10 +-- .../jfuse/win/amd64/FuseConnInfoImplTest.java | 83 +++++++++++++++++++ 9 files changed, 350 insertions(+), 20 deletions(-) create mode 100644 jfuse-linux-aarch64/src/test/java/org/cryptomator/jfuse/linux/aarch64/FuseConnInfoImplTest.java create mode 100644 jfuse-linux-amd64/src/test/java/org/cryptomator/jfuse/linux/amd64/FuseConnInfoImplTest.java create mode 100644 jfuse-mac/src/test/java/org/cryptomator/jfuse/mac/FuseConnInfoImplTest.java create mode 100644 jfuse-win-amd64/src/test/java/org/cryptomator/jfuse/win/amd64/FuseConnInfoImplTest.java diff --git a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseConnInfo.java b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseConnInfo.java index 16a2360f..6253c565 100644 --- a/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseConnInfo.java +++ b/jfuse-api/src/main/java/org/cryptomator/jfuse/api/FuseConnInfo.java @@ -8,6 +8,7 @@ */ public interface FuseConnInfo { + @SuppressWarnings("PointlessBitwiseExpression") int FUSE_CAP_ASYNC_READ = (1 << 0); int FUSE_CAP_POSIX_LOCKS = (1 << 1); int FUSE_CAP_ATOMIC_O_TRUNC = (1 << 3); diff --git a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseConnInfoImpl.java b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseConnInfoImpl.java index 70559522..91be8363 100644 --- a/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseConnInfoImpl.java +++ b/jfuse-linux-aarch64/src/main/java/org/cryptomator/jfuse/linux/aarch64/FuseConnInfoImpl.java @@ -28,10 +28,14 @@ public int capable() { return fuse_conn_info.capable$get(segment); } + @Override + public int want() { + return fuse_conn_info.want$get(segment); + } + @Override public void setWant(int wanted) { fuse_conn_info.want$set(segment, wanted); - } @Override @@ -94,8 +98,4 @@ public void setTimeGran(int timeGran) { fuse_conn_info.time_gran$set(segment, timeGran); } - @Override - public int want() { - return fuse_conn_info.want$get(segment); - } } diff --git a/jfuse-linux-aarch64/src/test/java/org/cryptomator/jfuse/linux/aarch64/FuseConnInfoImplTest.java b/jfuse-linux-aarch64/src/test/java/org/cryptomator/jfuse/linux/aarch64/FuseConnInfoImplTest.java new file mode 100644 index 00000000..0789d974 --- /dev/null +++ b/jfuse-linux-aarch64/src/test/java/org/cryptomator/jfuse/linux/aarch64/FuseConnInfoImplTest.java @@ -0,0 +1,83 @@ +package org.cryptomator.jfuse.linux.aarch64; + +import org.cryptomator.jfuse.api.FuseConnInfo; +import org.cryptomator.jfuse.linux.aarch64.extr.fuse_conn_info; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Named; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.stream.Stream; + +public class FuseConnInfoImplTest { + + @DisplayName("test getters") + @ParameterizedTest(name = "{1}") + @MethodSource + public void testGetters(SetInMemorySegment setter, GetInConnInfo getter) { + try (var scope = MemorySession.openConfined()) { + var segment = fuse_conn_info.allocate(scope); + var connInfo = new FuseConnInfoImpl(segment.address(), scope); + + setter.accept(segment, 42); + + Assertions.assertEquals(42, getter.apply(connInfo)); + } + } + + public static Stream testGetters() { + return Stream.of( + Arguments.arguments((SetInMemorySegment) fuse_conn_info::proto_major$set, Named.of("protoMajor()", (GetInConnInfo) FuseConnInfo::protoMajor)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::proto_minor$set, Named.of("protoMinor()", (GetInConnInfo) FuseConnInfo::protoMinor)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::capable$set, Named.of("capable()", (GetInConnInfo) FuseConnInfo::capable)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::max_write$set, Named.of("maxWrite()", (GetInConnInfo) FuseConnInfo::maxWrite)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::max_read$set, Named.of("maxRead()", (GetInConnInfo) FuseConnInfo::maxRead)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::max_readahead$set, Named.of("maxReadahead()", (GetInConnInfo) FuseConnInfo::maxReadahead)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::max_background$set, Named.of("maxBackground()", (GetInConnInfo) FuseConnInfo::maxBackground)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::congestion_threshold$set, Named.of("congestionThreshold()", (GetInConnInfo) FuseConnInfo::congestionThreshold)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::time_gran$set, Named.of("timeGran()", (GetInConnInfo) FuseConnInfo::timeGran)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::want$set, Named.of("want()", (GetInConnInfo) FuseConnInfo::want)) + ); + } + + private interface SetInMemorySegment extends BiConsumer {} + + private interface GetInConnInfo extends Function {} + + @DisplayName("test setters") + @ParameterizedTest(name = "{0}") + @MethodSource + public void testSetters(SetInConnInfo setter, GetInMemorySegment getter) { + try (var scope = MemorySession.openConfined()) { + var segment = fuse_conn_info.allocate(scope); + var connInfo = new FuseConnInfoImpl(segment.address(), scope); + + setter.accept(connInfo, 42); + + Assertions.assertEquals(42, getter.apply(segment)); + } + } + + public static Stream testSetters() { + return Stream.of( + Arguments.arguments(Named.of("setWant()", (SetInConnInfo) FuseConnInfo::setWant), (GetInMemorySegment) fuse_conn_info::want$get), + Arguments.arguments(Named.of("setMaxWrite()", (SetInConnInfo) FuseConnInfo::setMaxWrite), (GetInMemorySegment) fuse_conn_info::max_write$get), + Arguments.arguments(Named.of("setMaxRead()", (SetInConnInfo) FuseConnInfo::setMaxRead), (GetInMemorySegment) fuse_conn_info::max_read$get), + Arguments.arguments(Named.of("setMaxReadahead()", (SetInConnInfo) FuseConnInfo::setMaxReadahead), (GetInMemorySegment) fuse_conn_info::max_readahead$get), + Arguments.arguments(Named.of("setMaxBackground()", (SetInConnInfo) FuseConnInfo::setMaxBackground), (GetInMemorySegment) fuse_conn_info::max_background$get), + Arguments.arguments(Named.of("setCongestionThreshold()", (SetInConnInfo) FuseConnInfo::setCongestionThreshold), (GetInMemorySegment) fuse_conn_info::congestion_threshold$get), + Arguments.arguments(Named.of("setTimeGran()", (SetInConnInfo) FuseConnInfo::setTimeGran), (GetInMemorySegment) fuse_conn_info::time_gran$get) + ); + } + + private interface SetInConnInfo extends BiConsumer {} + + private interface GetInMemorySegment extends Function {} + +} \ No newline at end of file diff --git a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseConnInfoImpl.java b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseConnInfoImpl.java index eb2d9a29..8bc88436 100644 --- a/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseConnInfoImpl.java +++ b/jfuse-linux-amd64/src/main/java/org/cryptomator/jfuse/linux/amd64/FuseConnInfoImpl.java @@ -28,10 +28,14 @@ public int capable() { return fuse_conn_info.capable$get(segment); } + @Override + public int want() { + return fuse_conn_info.want$get(segment); + } + @Override public void setWant(int wanted) { fuse_conn_info.want$set(segment, wanted); - } @Override @@ -94,8 +98,4 @@ public void setTimeGran(int timeGran) { fuse_conn_info.time_gran$set(segment, timeGran); } - @Override - public int want() { - return fuse_conn_info.want$get(segment); - } } diff --git a/jfuse-linux-amd64/src/test/java/org/cryptomator/jfuse/linux/amd64/FuseConnInfoImplTest.java b/jfuse-linux-amd64/src/test/java/org/cryptomator/jfuse/linux/amd64/FuseConnInfoImplTest.java new file mode 100644 index 00000000..7ae3917c --- /dev/null +++ b/jfuse-linux-amd64/src/test/java/org/cryptomator/jfuse/linux/amd64/FuseConnInfoImplTest.java @@ -0,0 +1,83 @@ +package org.cryptomator.jfuse.linux.amd64; + +import org.cryptomator.jfuse.api.FuseConnInfo; +import org.cryptomator.jfuse.linux.amd64.extr.fuse_conn_info; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Named; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.stream.Stream; + +public class FuseConnInfoImplTest { + + @DisplayName("test getters") + @ParameterizedTest(name = "{1}") + @MethodSource + public void testGetters(SetInMemorySegment setter, GetInConnInfo getter) { + try (var scope = MemorySession.openConfined()) { + var segment = fuse_conn_info.allocate(scope); + var connInfo = new FuseConnInfoImpl(segment.address(), scope); + + setter.accept(segment, 42); + + Assertions.assertEquals(42, getter.apply(connInfo)); + } + } + + public static Stream testGetters() { + return Stream.of( + Arguments.arguments((SetInMemorySegment) fuse_conn_info::proto_major$set, Named.of("protoMajor()", (GetInConnInfo) FuseConnInfo::protoMajor)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::proto_minor$set, Named.of("protoMinor()", (GetInConnInfo) FuseConnInfo::protoMinor)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::capable$set, Named.of("capable()", (GetInConnInfo) FuseConnInfo::capable)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::max_write$set, Named.of("maxWrite()", (GetInConnInfo) FuseConnInfo::maxWrite)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::max_read$set, Named.of("maxRead()", (GetInConnInfo) FuseConnInfo::maxRead)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::max_readahead$set, Named.of("maxReadahead()", (GetInConnInfo) FuseConnInfo::maxReadahead)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::max_background$set, Named.of("maxBackground()", (GetInConnInfo) FuseConnInfo::maxBackground)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::congestion_threshold$set, Named.of("congestionThreshold()", (GetInConnInfo) FuseConnInfo::congestionThreshold)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::time_gran$set, Named.of("timeGran()", (GetInConnInfo) FuseConnInfo::timeGran)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::want$set, Named.of("want()", (GetInConnInfo) FuseConnInfo::want)) + ); + } + + private interface SetInMemorySegment extends BiConsumer {} + + private interface GetInConnInfo extends Function {} + + @DisplayName("test setters") + @ParameterizedTest(name = "{0}") + @MethodSource + public void testSetters(SetInConnInfo setter, GetInMemorySegment getter) { + try (var scope = MemorySession.openConfined()) { + var segment = fuse_conn_info.allocate(scope); + var connInfo = new FuseConnInfoImpl(segment.address(), scope); + + setter.accept(connInfo, 42); + + Assertions.assertEquals(42, getter.apply(segment)); + } + } + + public static Stream testSetters() { + return Stream.of( + Arguments.arguments(Named.of("setWant()", (SetInConnInfo) FuseConnInfo::setWant), (GetInMemorySegment) fuse_conn_info::want$get), + Arguments.arguments(Named.of("setMaxWrite()", (SetInConnInfo) FuseConnInfo::setMaxWrite), (GetInMemorySegment) fuse_conn_info::max_write$get), + Arguments.arguments(Named.of("setMaxRead()", (SetInConnInfo) FuseConnInfo::setMaxRead), (GetInMemorySegment) fuse_conn_info::max_read$get), + Arguments.arguments(Named.of("setMaxReadahead()", (SetInConnInfo) FuseConnInfo::setMaxReadahead), (GetInMemorySegment) fuse_conn_info::max_readahead$get), + Arguments.arguments(Named.of("setMaxBackground()", (SetInConnInfo) FuseConnInfo::setMaxBackground), (GetInMemorySegment) fuse_conn_info::max_background$get), + Arguments.arguments(Named.of("setCongestionThreshold()", (SetInConnInfo) FuseConnInfo::setCongestionThreshold), (GetInMemorySegment) fuse_conn_info::congestion_threshold$get), + Arguments.arguments(Named.of("setTimeGran()", (SetInConnInfo) FuseConnInfo::setTimeGran), (GetInMemorySegment) fuse_conn_info::time_gran$get) + ); + } + + private interface SetInConnInfo extends BiConsumer {} + + private interface GetInMemorySegment extends Function {} + +} \ No newline at end of file diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseConnInfoImpl.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseConnInfoImpl.java index 154599bd..fc68702a 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseConnInfoImpl.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/FuseConnInfoImpl.java @@ -27,10 +27,13 @@ public int capable() { return fuse_conn_info.capable$get(segment); } + @Override + public int want() { + return fuse_conn_info.want$get(segment); + } @Override public void setWant(int wanted) { fuse_conn_info.want$set(segment, wanted); - } @Override @@ -83,8 +86,4 @@ public void setAsyncRead(int asyncRead) { fuse_conn_info.async_read$set(segment, asyncRead); } - @Override - public int want() { - return fuse_conn_info.want$get(segment); - } } diff --git a/jfuse-mac/src/test/java/org/cryptomator/jfuse/mac/FuseConnInfoImplTest.java b/jfuse-mac/src/test/java/org/cryptomator/jfuse/mac/FuseConnInfoImplTest.java new file mode 100644 index 00000000..82defd21 --- /dev/null +++ b/jfuse-mac/src/test/java/org/cryptomator/jfuse/mac/FuseConnInfoImplTest.java @@ -0,0 +1,81 @@ +package org.cryptomator.jfuse.mac; + +import org.cryptomator.jfuse.api.FuseConnInfo; +import org.cryptomator.jfuse.mac.extr.fuse_conn_info; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Named; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.stream.Stream; + +public class FuseConnInfoImplTest { + + @DisplayName("test getters") + @ParameterizedTest(name = "{1}") + @MethodSource + public void testGetters(SetInMemorySegment setter, GetInConnInfo getter) { + try (var scope = MemorySession.openConfined()) { + var segment = fuse_conn_info.allocate(scope); + var connInfo = new FuseConnInfoImpl(segment.address(), scope); + + setter.accept(segment, 42); + + Assertions.assertEquals(42, getter.apply(connInfo)); + } + } + + public static Stream testGetters() { + return Stream.of( + Arguments.arguments((SetInMemorySegment) fuse_conn_info::proto_major$set, Named.of("protoMajor()", (GetInConnInfo) FuseConnInfo::protoMajor)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::proto_minor$set, Named.of("protoMinor()", (GetInConnInfo) FuseConnInfo::protoMinor)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::capable$set, Named.of("capable()", (GetInConnInfo) FuseConnInfo::capable)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::max_write$set, Named.of("maxWrite()", (GetInConnInfo) FuseConnInfo::maxWrite)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::max_readahead$set, Named.of("maxReadahead()", (GetInConnInfo) FuseConnInfo::maxReadahead)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::max_background$set, Named.of("maxBackground()", (GetInConnInfo) FuseConnInfo::maxBackground)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::congestion_threshold$set, Named.of("congestionThreshold()", (GetInConnInfo) FuseConnInfo::congestionThreshold)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::async_read$set, Named.of("asyncRead()", (GetInConnInfo) FuseConnInfo::asyncRead)), + Arguments.arguments((SetInMemorySegment) fuse_conn_info::want$set, Named.of("want()", (GetInConnInfo) FuseConnInfo::want)) + ); + } + + private interface SetInMemorySegment extends BiConsumer {} + + private interface GetInConnInfo extends Function {} + + @DisplayName("test setters") + @ParameterizedTest(name = "{0}") + @MethodSource + public void testSetters(SetInConnInfo setter, GetInMemorySegment getter) { + try (var scope = MemorySession.openConfined()) { + var segment = fuse_conn_info.allocate(scope); + var connInfo = new FuseConnInfoImpl(segment.address(), scope); + + setter.accept(connInfo, 42); + + Assertions.assertEquals(42, getter.apply(segment)); + } + } + + public static Stream testSetters() { + return Stream.of( + Arguments.arguments(Named.of("setWant()", (SetInConnInfo) FuseConnInfo::setWant), (GetInMemorySegment) fuse_conn_info::want$get), + Arguments.arguments(Named.of("setMaxWrite()", (SetInConnInfo) FuseConnInfo::setMaxWrite), (GetInMemorySegment) fuse_conn_info::max_write$get), + Arguments.arguments(Named.of("setMaxReadahead()", (SetInConnInfo) FuseConnInfo::setMaxReadahead), (GetInMemorySegment) fuse_conn_info::max_readahead$get), + Arguments.arguments(Named.of("setMaxBackground()", (SetInConnInfo) FuseConnInfo::setMaxBackground), (GetInMemorySegment) fuse_conn_info::max_background$get), + Arguments.arguments(Named.of("setCongestionThreshold()", (SetInConnInfo) FuseConnInfo::setCongestionThreshold), (GetInMemorySegment) fuse_conn_info::congestion_threshold$get), + Arguments.arguments(Named.of("setAsyncRead()", (SetInConnInfo) FuseConnInfo::setAsyncRead), (GetInMemorySegment) fuse_conn_info::async_read$get) + ); + } + + private interface SetInConnInfo extends BiConsumer {} + + private interface GetInMemorySegment extends Function {} + +} \ No newline at end of file diff --git a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseConnInfoImpl.java b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseConnInfoImpl.java index d20d3c6f..5bd40b83 100644 --- a/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseConnInfoImpl.java +++ b/jfuse-win-amd64/src/main/java/org/cryptomator/jfuse/win/amd64/FuseConnInfoImpl.java @@ -28,10 +28,14 @@ public int capable() { return fuse3_conn_info.capable$get(segment); } + @Override + public int want() { + return fuse3_conn_info.want$get(segment); + } + @Override public void setWant(int wanted) { fuse3_conn_info.want$set(segment, wanted); - } @Override @@ -94,8 +98,4 @@ public void setTimeGran(int timeGran) { fuse3_conn_info.time_gran$set(segment, timeGran); } - @Override - public int want() { - return fuse3_conn_info.want$get(segment); - } } diff --git a/jfuse-win-amd64/src/test/java/org/cryptomator/jfuse/win/amd64/FuseConnInfoImplTest.java b/jfuse-win-amd64/src/test/java/org/cryptomator/jfuse/win/amd64/FuseConnInfoImplTest.java new file mode 100644 index 00000000..d37be619 --- /dev/null +++ b/jfuse-win-amd64/src/test/java/org/cryptomator/jfuse/win/amd64/FuseConnInfoImplTest.java @@ -0,0 +1,83 @@ +package org.cryptomator.jfuse.win.amd64; + +import org.cryptomator.jfuse.api.FuseConnInfo; +import org.cryptomator.jfuse.win.amd64.extr.fuse3_conn_info; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Named; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.stream.Stream; + +public class FuseConnInfoImplTest { + + @DisplayName("test getters") + @ParameterizedTest(name = "{1}") + @MethodSource + public void testGetters(SetInMemorySegment setter, GetInConnInfo getter) { + try (var scope = MemorySession.openConfined()) { + var segment = fuse3_conn_info.allocate(scope); + var connInfo = new FuseConnInfoImpl(segment.address(), scope); + + setter.accept(segment, 42); + + Assertions.assertEquals(42, getter.apply(connInfo)); + } + } + + public static Stream testGetters() { + return Stream.of( + Arguments.arguments((SetInMemorySegment) fuse3_conn_info::proto_major$set, Named.of("protoMajor()", (GetInConnInfo) FuseConnInfo::protoMajor)), + Arguments.arguments((SetInMemorySegment) fuse3_conn_info::proto_minor$set, Named.of("protoMinor()", (GetInConnInfo) FuseConnInfo::protoMinor)), + Arguments.arguments((SetInMemorySegment) fuse3_conn_info::capable$set, Named.of("capable()", (GetInConnInfo) FuseConnInfo::capable)), + Arguments.arguments((SetInMemorySegment) fuse3_conn_info::max_write$set, Named.of("maxWrite()", (GetInConnInfo) FuseConnInfo::maxWrite)), + Arguments.arguments((SetInMemorySegment) fuse3_conn_info::max_read$set, Named.of("maxRead()", (GetInConnInfo) FuseConnInfo::maxRead)), + Arguments.arguments((SetInMemorySegment) fuse3_conn_info::max_readahead$set, Named.of("maxReadahead()", (GetInConnInfo) FuseConnInfo::maxReadahead)), + Arguments.arguments((SetInMemorySegment) fuse3_conn_info::max_background$set, Named.of("maxBackground()", (GetInConnInfo) FuseConnInfo::maxBackground)), + Arguments.arguments((SetInMemorySegment) fuse3_conn_info::congestion_threshold$set, Named.of("congestionThreshold()", (GetInConnInfo) FuseConnInfo::congestionThreshold)), + Arguments.arguments((SetInMemorySegment) fuse3_conn_info::time_gran$set, Named.of("timeGran()", (GetInConnInfo) FuseConnInfo::timeGran)), + Arguments.arguments((SetInMemorySegment) fuse3_conn_info::want$set, Named.of("want()", (GetInConnInfo) FuseConnInfo::want)) + ); + } + + private interface SetInMemorySegment extends BiConsumer {} + + private interface GetInConnInfo extends Function {} + + @DisplayName("test setters") + @ParameterizedTest(name = "{0}") + @MethodSource + public void testSetters(SetInConnInfo setter, GetInMemorySegment getter) { + try (var scope = MemorySession.openConfined()) { + var segment = fuse3_conn_info.allocate(scope); + var connInfo = new FuseConnInfoImpl(segment.address(), scope); + + setter.accept(connInfo, 42); + + Assertions.assertEquals(42, getter.apply(segment)); + } + } + + public static Stream testSetters() { + return Stream.of( + Arguments.arguments(Named.of("setWant()", (SetInConnInfo) FuseConnInfo::setWant), (GetInMemorySegment) fuse3_conn_info::want$get), + Arguments.arguments(Named.of("setMaxWrite()", (SetInConnInfo) FuseConnInfo::setMaxWrite), (GetInMemorySegment) fuse3_conn_info::max_write$get), + Arguments.arguments(Named.of("setMaxRead()", (SetInConnInfo) FuseConnInfo::setMaxRead), (GetInMemorySegment) fuse3_conn_info::max_read$get), + Arguments.arguments(Named.of("setMaxReadahead()", (SetInConnInfo) FuseConnInfo::setMaxReadahead), (GetInMemorySegment) fuse3_conn_info::max_readahead$get), + Arguments.arguments(Named.of("setMaxBackground()", (SetInConnInfo) FuseConnInfo::setMaxBackground), (GetInMemorySegment) fuse3_conn_info::max_background$get), + Arguments.arguments(Named.of("setCongestionThreshold()", (SetInConnInfo) FuseConnInfo::setCongestionThreshold), (GetInMemorySegment) fuse3_conn_info::congestion_threshold$get), + Arguments.arguments(Named.of("setTimeGran()", (SetInConnInfo) FuseConnInfo::setTimeGran), (GetInMemorySegment) fuse3_conn_info::time_gran$get) + ); + } + + private interface SetInConnInfo extends BiConsumer {} + + private interface GetInMemorySegment extends Function {} + +} \ No newline at end of file From ba950d58a4500d9b85678d7e7b50722b21243879 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Fri, 16 Sep 2022 15:04:24 +0200 Subject: [PATCH 93/98] forgot one class in 0c217188 --- .../org/cryptomator/jfuse/mac/DirFillerImpl.java | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/DirFillerImpl.java b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/DirFillerImpl.java index 518234a0..62e115d4 100644 --- a/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/DirFillerImpl.java +++ b/jfuse-mac/src/main/java/org/cryptomator/jfuse/mac/DirFillerImpl.java @@ -7,7 +7,6 @@ import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemorySession; -import java.util.Set; import java.util.function.Consumer; record DirFillerImpl(MemoryAddress buf, fuse_fill_dir_t callback, MemorySession scope) implements DirFiller { @@ -18,15 +17,9 @@ record DirFillerImpl(MemoryAddress buf, fuse_fill_dir_t callback, MemorySession @Override public int fill(String name, Consumer statFiller, long offset, int flags) { - MemoryAddress statAddr; - if (statFiller != null) { - var segment = stat.allocate(scope); - statFiller.accept(new StatImpl(segment)); - statAddr = segment.address(); - } else { - statAddr = MemoryAddress.NULL; - } - return callback.apply(buf, scope.allocateUtf8String(name).address(), statAddr, offset); + var statSegment = stat.allocate(scope); + statFiller.accept(new StatImpl(statSegment)); + return callback.apply(buf, scope.allocateUtf8String(name).address(), statSegment.address(), offset); } } \ No newline at end of file From 551f92e6e0e18b532569a92618afb9b53678e0bf Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Fri, 16 Sep 2022 15:19:12 +0200 Subject: [PATCH 94/98] added tests --- .../cryptomator/jfuse/api/DirFillerTest.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 jfuse-api/src/test/java/org/cryptomator/jfuse/api/DirFillerTest.java diff --git a/jfuse-api/src/test/java/org/cryptomator/jfuse/api/DirFillerTest.java b/jfuse-api/src/test/java/org/cryptomator/jfuse/api/DirFillerTest.java new file mode 100644 index 00000000..4e529e93 --- /dev/null +++ b/jfuse-api/src/test/java/org/cryptomator/jfuse/api/DirFillerTest.java @@ -0,0 +1,50 @@ +package org.cryptomator.jfuse.api; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import java.io.IOException; + +public class DirFillerTest { + + @Test + @DisplayName("fill(path, statFiller)") + public void testTwoArgFill() throws IOException { + var filler = Mockito.mock(DirFiller.class); + Mockito.doCallRealMethod().when(filler).fill(Mockito.any(), Mockito.any()); + Mockito.doReturn(0).when(filler).fill(Mockito.any(), Mockito.any(), Mockito.anyLong(), Mockito.anyInt()); + + filler.fill("name", stat -> { + }); + + Mockito.verify(filler).fill(Mockito.any(), Mockito.any(), Mockito.anyLong(), Mockito.anyInt()); + } + + @Test + @DisplayName("fill(path, statFiller) throws IOException") + public void testExceptionalTwoArgFill() throws IOException { + var filler = Mockito.mock(DirFiller.class); + Mockito.doCallRealMethod().when(filler).fill(Mockito.any(), Mockito.any()); + Mockito.doReturn(1).when(filler).fill(Mockito.any(), Mockito.any(), Mockito.anyLong(), Mockito.anyInt()); + + Assertions.assertThrows(IOException.class, () -> { + filler.fill("name", stat -> { + }); + }); + } + + @Test + @DisplayName("fill(path) ") + public void testOneArgFill() throws IOException { + var filler = Mockito.mock(DirFiller.class); + Mockito.doCallRealMethod().when(filler).fill(Mockito.any()); + Mockito.doNothing().when(filler).fill(Mockito.any(), Mockito.any()); + + filler.fill("name"); + + Mockito.verify(filler).fill(Mockito.any(), Mockito.any()); + } + +} \ No newline at end of file From 3e663a6cf66dab761397e802b5ce3997cade79ca Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 19 Sep 2022 13:13:26 +0200 Subject: [PATCH 95/98] fix ServiceLoader not finding jfuse-linux-aarch64 in non-modular world --- .../{ => META-INF}/services/org.cryptomator.jfuse.api.FuseBuilder | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename jfuse-linux-aarch64/src/main/resources/{ => META-INF}/services/org.cryptomator.jfuse.api.FuseBuilder (100%) diff --git a/jfuse-linux-aarch64/src/main/resources/services/org.cryptomator.jfuse.api.FuseBuilder b/jfuse-linux-aarch64/src/main/resources/META-INF/services/org.cryptomator.jfuse.api.FuseBuilder similarity index 100% rename from jfuse-linux-aarch64/src/main/resources/services/org.cryptomator.jfuse.api.FuseBuilder rename to jfuse-linux-aarch64/src/main/resources/META-INF/services/org.cryptomator.jfuse.api.FuseBuilder From c7caa0a4fb6faa8025cae07c320988a01fd386f3 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 19 Sep 2022 13:14:36 +0200 Subject: [PATCH 96/98] added missing `--enable-native-access` to mirror example [ci skip] --- .idea/runConfigurations/PosixMirrorFileSystem.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.idea/runConfigurations/PosixMirrorFileSystem.xml b/.idea/runConfigurations/PosixMirrorFileSystem.xml index 4f943e0f..faa4eb5f 100644 --- a/.idea/runConfigurations/PosixMirrorFileSystem.xml +++ b/.idea/runConfigurations/PosixMirrorFileSystem.xml @@ -3,7 +3,7 @@