Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
overheadhunter committed Dec 9, 2019
0 parents commit 1c9a8be
Show file tree
Hide file tree
Showing 18 changed files with 1,345 additions and 0 deletions.
22 changes: 22 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
*.class

# Package Files #
*.jar
*.war
*.ear

# Eclipse Settings Files #
.settings
.project
.classpath

# Maven #
target/
pom.xml.versionsBackup

# IntelliJ Settings Files (https://intellij-support.jetbrains.com/hc/en-us/articles/206544839-How-to-manage-projects-under-Version-Control-Systems) #
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/dictionaries
.idea/**/libraries/
*.iml
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[submodule "libfuse"]
path = libfuse
url = https://github.com/libfuse/libfuse.git
branch = fuse-2_9_bugfix
2 changes: 2 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions .idea/runConfigurations/HelloFileSystem.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 35 additions & 0 deletions bindings/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>fuse-panama</artifactId>
<groupId>de.skymatic</groupId>
<version>0.1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>fuse-panama-bindings</artifactId>

<dependencies>
<dependency>
<groupId>de.skymatic</groupId>
<artifactId>fuse</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${basedir}/../ffi/fuse.jar</systemPath>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.29</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.29</version>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package de.skymatic.fusepanama;

import java.foreign.Scope;
import java.foreign.memory.Callback;
import java.foreign.memory.Pointer;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;

import com.github.libfuse.fuse_common_h;
import com.github.libfuse.fuse_h;
import com.github.libfuse.fuse_lib;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class AbstractFuseFileSystem implements AutoCloseable, FuseOperations {

private static final Logger LOG = LoggerFactory.getLogger(AbstractFuseFileSystem.class);

protected final Scope scope;
protected final fuse_h.fuse_operations fuseOperations;
private final Set<String> notImplementedMethods;
private Pointer<fuse_h.fuse> fuseHandle;

public AbstractFuseFileSystem() {
this.scope = Scope.globalScope().fork();
this.fuseOperations = scope.allocateStruct(fuse_h.fuse_operations.class);
this.notImplementedMethods = Arrays.stream(getClass().getMethods())
.filter(method -> method.getAnnotation(NotImplemented.class) != null)
.map(Method::getName)
.collect(Collectors.toSet());
fuseOperations.getattr$set(allocateIfImplemented("getattr", this::getattr));
fuseOperations.readlink$set(allocateIfImplemented("readlink", this::readlink));
fuseOperations.getdir$set(allocateIfImplemented("getdir", this::getdir));
fuseOperations.mknod$set(allocateIfImplemented("mknod", this::mknod));
fuseOperations.mkdir$set(allocateIfImplemented("mkdir", this::mkdir));
fuseOperations.unlink$set(allocateIfImplemented("unlink", this::unlink));
fuseOperations.rmdir$set(allocateIfImplemented("rmdir", this::rmdir));
fuseOperations.symlink$set(allocateIfImplemented("symlink", this::symlink));
fuseOperations.rename$set(allocateIfImplemented("rename", this::rename));
fuseOperations.link$set(allocateIfImplemented("link", this::link));
fuseOperations.chmod$set(allocateIfImplemented("chmod", this::chmod));
fuseOperations.chown$set(allocateIfImplemented("chown", this::chown));
fuseOperations.truncate$set(allocateIfImplemented("truncate", this::truncate));
fuseOperations.utime$set(allocateIfImplemented("utime", this::utime));
fuseOperations.open$set(allocateIfImplemented("open", this::open));
fuseOperations.read$set(allocateIfImplemented("read", this::read));
fuseOperations.write$set(allocateIfImplemented("write", this::write));
fuseOperations.statfs$set(allocateIfImplemented("statfs", this::statfs));
fuseOperations.flush$set(allocateIfImplemented("flush", this::flush));
fuseOperations.release$set(allocateIfImplemented("release", this::release));
fuseOperations.fsync$set(allocateIfImplemented("fsync", this::fsync));
fuseOperations.setxattr$set(allocateIfImplemented("setxattr", this::setxattr));
fuseOperations.getxattr$set(allocateIfImplemented("getxattr", this::getxattr));
fuseOperations.listxattr$set(allocateIfImplemented("listxattr", this::listxattr));
fuseOperations.removexattr$set(allocateIfImplemented("removexattr", this::removexattr));
fuseOperations.opendir$set(allocateIfImplemented("opendir", this::opendir));
fuseOperations.readdir$set(allocateIfImplemented("readdir", this::readdir));
fuseOperations.releasedir$set(allocateIfImplemented("releasedir", this::releasedir));
fuseOperations.fsyncdir$set(allocateIfImplemented("fsyncdir", this::fsyncdir));
fuseOperations.init$set(allocateIfImplemented("init", this::init));
fuseOperations.destroy$set(allocateIfImplemented("destroy", this::destroy));
fuseOperations.access$set(allocateIfImplemented("access", this::access));
fuseOperations.create$set(allocateIfImplemented("create", this::create));
fuseOperations.ftruncate$set(allocateIfImplemented("ftruncate", this::ftruncate));
fuseOperations.fgetattr$set(allocateIfImplemented("fgetattr", this::fgetattr));
fuseOperations.lock$set(allocateIfImplemented("lock", this::lock));
fuseOperations.utimens$set(allocateIfImplemented("utimens", this::utimens));
fuseOperations.bmap$set(allocateIfImplemented("bmap", this::bmap));
fuseOperations.ioctl$set(allocateIfImplemented("ioctl", this::ioctl));
fuseOperations.poll$set(allocateIfImplemented("poll", this::poll));
fuseOperations.write_buf$set(allocateIfImplemented("writeBuf", this::writeBuf));
fuseOperations.read_buf$set(allocateIfImplemented("readBuf", this::readBuf));
fuseOperations.flock$set(allocateIfImplemented("flock", this::flock));
fuseOperations.fallocate$set(allocateIfImplemented("fallocate", this::fallocate));
}

private <T> Callback<T> allocateIfImplemented(String methodName, T callback) {
if (notImplementedMethods.contains(methodName)) {
return Callback.ofNull();
} else {
return scope.allocateCallback(callback);
}
}

@Override
public Pointer<Void> init(Pointer<fuse_common_h.fuse_conn_info> conn) {
this.fuseHandle = fuse_lib.fuse_get_context().get().fuse$get();
LOG.debug("init()");
return Pointer.ofNull();
}

protected Pointer<fuse_h.fuse> getFuseHandle() {
return fuseHandle;
}

public fuse_h.fuse_operations getFuseOperations() {
return fuseOperations;
}

@Override
public void destroy(Pointer<?> pointer) {
this.fuseHandle = Pointer.ofNull();
LOG.debug("destroy()");
}

@Override
public void close() {
scope.close();
}
}
21 changes: 21 additions & 0 deletions bindings/src/main/java/de/skymatic/fusepanama/Errno.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package de.skymatic.fusepanama;

/**
* Error codes extracted from
* <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/asm-generic/errno.h">errno.h (linux)</a>
* and <a href="https://github.com/apple/darwin-xnu/blob/master/bsd/sys/errno.h">errno.h (darwin)</a>
*/
public interface Errno {

boolean IS_MAC = System.getProperty("os.name").toLowerCase().contains("mac");

/**
* No such file or directory
*/
int ENOENT = 2;

/**
* Invalid system call number
*/
int ENOSYS = IS_MAC ? 78 : 38;
}
42 changes: 42 additions & 0 deletions bindings/src/main/java/de/skymatic/fusepanama/Fuse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package de.skymatic.fusepanama;

import java.foreign.Scope;
import java.foreign.memory.Pointer;
import java.util.concurrent.ThreadLocalRandom;

import com.github.libfuse.fuse_lib;
import com.github.libfuse.fuse_opt_h;
import com.github.libfuse.fuse_opt_lib;

public class Fuse {

/**
* Mounts the given file system at the given mount point.
* <p>
* This method blocks until unmounted.
*/
public static void mount(AbstractFuseFileSystem fs, String mountPoint, boolean debug) {
try (Scope scope = Scope.globalScope().fork()) {
var fuse_args = scope.allocateStruct(fuse_opt_h.fuse_args.class);
fuse_args.argc$set(0);
fuse_args.argv$set(Pointer.ofNull());
fuse_args.allocated$set(0);
fuse_opt_lib.fuse_opt_add_arg(fuse_args.ptr(), scope.allocateCString("fusefs-" + ThreadLocalRandom.current().nextInt()));
fuse_opt_lib.fuse_opt_add_arg(fuse_args.ptr(), scope.allocateCString("-f"));
if (debug) {
fuse_opt_lib.fuse_opt_add_arg(fuse_args.ptr(), scope.allocateCString("-d"));
}
fuse_opt_lib.fuse_opt_add_arg(fuse_args.ptr(), scope.allocateCString(mountPoint));

int result = fuse_lib.fuse_main_real(fuse_args.argc$get(), fuse_args.argv$get(), fs.fuseOperations.ptr(), FuseOperations.SIZEOF_FUSE_OPERATIONS, Pointer.ofNull());

fuse_opt_lib.fuse_opt_free_args(fuse_args.ptr());

if (result != 0) {
throw new RuntimeException("mount failed with return code " + result);
}
}
}


}
Loading

0 comments on commit 1c9a8be

Please sign in to comment.