Code Monkey home page Code Monkey logo

fuse-rs's People

Contributors

abspoel avatar acheronfail avatar asomers avatar bgeron avatar bromind avatar crumblingstatue avatar cuviper avatar dirk avatar ebfe avatar emberian avatar glittershark avatar illicitonion avatar jmmv avatar mic92 avatar micahchalmer avatar navaati avatar oconnor663 avatar tatref avatar toshipp avatar valpackett avatar wfraser avatar wwylele avatar zackmdavis avatar zargony avatar zsiciarz avatar

Stargazers

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

Watchers

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

fuse-rs's Issues

Documentation gaps

I've been tripping over a few things trying to implement a FUSE network filesystem. I thought I'd jot down some questions, and I'd be happy to turn any answers into some documentation PRs.

  1. mount takes an array of options, but in tinkering with options like noatime, subtype=foo, and ro (various options from fuse and mount man pages). I don't see any change reflected in /etc/mtab. Do I simply misunderstand what options can be specified?
  2. Assuming I can get ro vs rw options to work, would the kernel cease to call write, unlink, etc.., or would the filesystem need to explicitly catch such cases and return EROFS?
  3. What is TTL used for on structs like ReplyEntry? Will the kernel actually cache those for that duration and not make repeated calls to FUSE in that duration?
  4. How does one end up with a filesystem with deferred writes? Currently I commit (via HTTP) on release if modified and no remaining readers, which might be fine, but I'd like to tinker with a commit=n type of setting (to optimize for the case where a file is reopened for writing right after it was closed). Given that the kernel doesn't ever seem to trigger fsync for basic open-write-close usage, I presume I'm left to spin up a thread that handles commits if I really want such a feature.
  5. I often wonder which error cases I need to address in different FUSE functions. For example, ENOTDIR is a documented error for mknod if parent isn't a dir, but does FUSE return that before calling mknod (i.e. by checking attr.kind returned by getattr)?

There are probably others, and perhaps some of these are more about FUSE in general, but definitely things that have been tripping me up. There are plenty of other things that I've had to figure out by experimentation, so I might try to summarize some of that up into PR at some point, because by-and-large this library is incredibly approachable for building a FS from scratch with no previous FUSE experience.

Compiling with latest Rust fails

Rust version:

rustc 0.13.0-nightly (770378a31 2014-11-20 23:02:01 +0000)
binary: rustc
commit-hash: 770378a313a573776b16237a46b75bafa49072c1
commit-date: 2014-11-20 23:02:01 +0000
host: x86_64-unknown-linux-gnu
release: 0.13.0-nightly

Last 3 errors (out of 87 very similar ones):

src/request.rs:337:132: 337:141 error: unknown format trait `u`
src/request.rs:337                 debug!("BMAP({:u}) ino {:#018x}, blocksize {:u}, ids {:u}", self.header.unique, self.header.nodeid, arg.blo
cksize, arg.block);

        ^~~~~~~~~
src/session.rs:49:74: 49:77 error: unknown format trait `i`
src/session.rs:49             Err(err) => panic!("Unable to mount filesystem. Error {:i}", err),
                                                                                           ^~~
src/session.rs:80:82: 80:85 error: unknown format trait `i`
src/session.rs:80                 Err(err) => panic!("Lost connection to FUSE device. Error {:i}", err),
                                                                                                   ^~~
error: aborting due to 87 previous errors
Could not compile `fuse`.

[feature request] Add error() to generic reply trait

It would be great if the generic Reply trait had an error function. My use case is that I want to centralize error handling and logging, and so having a way to write a trait-bounded generic function that can call error() on a generic reply object would be super useful.

fuse writeback_cache support

enabling means that filesystem may no longer receive writes in the same order as the application sends them, but the kernel may coalesce small writes into bigger writes. It's not clear if rust-fuse needs to do anything extra to support this, but after passing -owriteback_cache through to the mount options I don't observe any write size changes compared to without.

mount options

I am trying to pass mount options to spawn_mount:

info!("options are {:?}", options);
fuse::spawn_mount(fs, &flags.mount_point, &options)?;

running it gives:

INFO:: options are ["nonempty"]
fuse: mountpoint is not empty
fuse: if you are sure this is safe, use the 'nonempty' mount option

Am I doing anything wrong?

Filesystem API that takes paths instead of inode numbers

In the todo section of the README file, it is mentioned:

An additional more high level API would be nice. It should provide pathnames instead inode numbers ...

This is what I need. I wonder if there has been any progress on this so far? I changed some of the functions such as getattr and readdir in the Filesystem trait to take Path as a parameter. But later, I noticed that the path only contains the current directory name (rather than the full path). lookup already receives the path, but it has the same problem.

Is there any way to receive the full path in Filesystem? I can definitly make a higher level abstraction that keeps track of inodes <-> paths in a dictionary and passes the full path to the functions instead. Is there any easier/more efficient way to get the full path?

Write callbacks

Hi,

Thanks for making and maintaining rust-fuse! The library fills a very important slot in the ecosystem.

I'm currently trying to implement the write support for my file system but there is something that I don't understand. I am working on macOS 10.13.

If I issue an append command:

$ echo "test" >> my_file.txt

where my_file.txt is an existing, non-empty file in my file system, I see that the file will be opened with flags O_WRONLY. I don't see O_APPEND being passed. Is that correct?

The call to open is followed by a call to write with offset 0.

I was expecting either O_APPEND being passed to open and then write being done at offset 0, or O_APPEND isn't passed, and then write is done with offset equal to the current length of the file.

I found some documentation about writeback caches on Linux, where the append mode is handled by the kernel, but no reference to this on macOS.

Do you have any ideas about this issue? It's entirely possible that I'm misunderstanding all the calls.

Thanks!

There should be fusexmp-like example

I typically use fusexmp.c or fusexmp_fh.c as a template for creating new FUSE filesystems.

It allows to mostly avoid dealing with documentation.

Here I see only short hello and even shorter null examples. Although hello can be recrafted to something usable, it would be nice to have exhaustive example showing all possible calls.

In particular, fusexmp-like example is useful for creating simple FUSE wrappers that do leave all files as is, but .... Trying to create that from scratch makes easy to miss problems like missing extended attributes handling.

Merging efforts (MicahChalmer/rust-fuse) into here

@zargony and I each started working independently on a version of almost the same thing, and released it within days of each other. On reddit, we seemed mutually interested in combining our efforts. This issue is basically a message from me to @zargony, who can feel free to close it once he's seen it. Or we can use it as a place to discuss how it would work outside of specific issues in the code.

Looking at both repos, I think yours is the better basis for future efforts. Also, in the last few months I had more spare time to work on stuff like this than I will in the next few months. So I'm fine to have you own the repo for now, and will submit issues and pull requests to you for future ideas--some that were already there in my other version, some new altogether.

I'll put in issues for bigger changes to get feedback on the general idea before or while implementing. Or if the change is small, I'll just do it and submit a pull request right away.

Listxattr reply

The method signature of listxattr gives me a ReplyXattr for a reply. But it does not state how one should encode a list of attribute names into a &[u8] to be able to use ReplyXattr::data(). Is there any documentation on this?

Unable to compile. Can't find size_t

This is likely a goof on my end but I'm having trouble getting rust-fuse to compile. It's failing at ffi-sys:

   Compiling libffi-sys v0.4.6
error: failed to run custom build command for `libffi-sys v0.4.6`
process didn't exit successfully: `/home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-40d92df5f46790ce/build-script-build` (exit code: 101)
--- stdout
libtoolize: putting auxiliary files in '.'.
libtoolize: copying file './ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'm4'.
libtoolize: copying file 'm4/libtool.m4'
libtoolize: copying file 'm4/ltoptions.m4'
libtoolize: copying file 'm4/ltsugar.m4'
libtoolize: copying file 'm4/ltversion.m4'
libtoolize: copying file 'm4/lt~obsolete.m4'
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking target system type... x86_64-pc-linux-gnu
continue configure in default builddir "./x86_64-unknown-linux-gnu"
....exec /bin/bash .././configure "--srcdir=.." "--enable-builddir=x86_64-unknown-linux-gnu" "linux
gnu"
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking target system type... x86_64-pc-linux-gnu
checking for gsed... sed
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking whether gcc understands -c and -o together... yes
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
checking for g++... no
checking for c++... c++
checking whether we are using the GNU C++ compiler... yes
checking whether c++ accepts -g... yes
checking dependency style of c++... gcc3
checking dependency style of gcc... gcc3
checking how to print strings... printf
checking for a sed that does not truncate output... /bin/sed
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for fgrep... /bin/grep -F
checking for ld used by gcc... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 1572864
checking how to convert x86_64-pc-linux-gnu file names to x86_64-pc-linux-gnu format... func_convert_file_noop
checking how to convert x86_64-pc-linux-gnu file names to toolchain format... func_convert_file_noop
checking for /usr/bin/ld option to reload object files... -r
checking for objdump... objdump
checking how to recognize dependent libraries... pass_all
checking for dlltool... no
checking how to associate runtime and link libraries... printf %s\n
checking for ar... ar
checking for archiver @FILE support... @
checking for strip... strip
checking for ranlib... ranlib
checking command to parse /usr/bin/nm -B output from gcc object... ok
checking for sysroot... no
checking for a working dd... /bin/dd
checking how to truncate binary pipes... /bin/dd bs=4096 count=1
checking for mt... mt
checking if mt is a manifest tool... no
checking how to run the C preprocessor... gcc -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for dlfcn.h... yes
checking for objdir... .libs
checking if gcc supports -fno-rtti -fno-exceptions... no
checking for gcc option to produce PIC... -fPIC -DPIC
checking if gcc PIC flag -fPIC -DPIC works... yes
checking if gcc static flag -static works... yes
checking if gcc supports -c -o file.o... yes
checking if gcc supports -c -o file.o... (cached) yes
checking whether the gcc linker (/usr/bin/ld -m elf_x86_64) supports shared libraries... yes
checking whether -lc should be explicitly linked in... no
checking dynamic linker characteristics... GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... yes
checking how to run the C++ preprocessor... c++ -E
checking for ld used by c++... /usr/bin/ld -m elf_x86_64
checking if the linker (/usr/bin/ld -m elf_x86_64) is GNU ld... yes
checking whether the c++ linker (/usr/bin/ld -m elf_x86_64) supports shared libraries... yes
checking for c++ option to produce PIC... -fPIC -DPIC
checking if c++ PIC flag -fPIC -DPIC works... yes
checking if c++ static flag -static works... yes
checking if c++ supports -c -o file.o... yes
checking if c++ supports -c -o file.o... (cached) yes
checking whether the c++ linker (/usr/bin/ld -m elf_x86_64) supports shared libraries... yes
checking dynamic linker characteristics... (cached) GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking size of size_t... 8
checking for C compiler vendor... gnu
checking whether C compiler accepts -fstrict-aliasing... yes
checking whether C compiler accepts -ffast-math... yes
checking for gcc architecture flag... 
checking for x86 cpuid 0 output... d:68747541:444d4163:69746e65
checking for x86 cpuid 1 output... 600f20:6080800:3e98320b:178bfbff
checking whether C compiler accepts -march=amdfam10... yes
checking for gcc architecture flag... -march=amdfam10
checking whether C compiler accepts -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=amdfam10... yes
checking CFLAGS for maximum warnings... -Wall
checking whether to enable maintainer-specific portions of Makefiles... no
checking sys/mman.h usability... yes
checking sys/mman.h presence... yes
checking for sys/mman.h... yes
checking for mmap... yes
checking for mkostemp... yes
checking for sys/mman.h... (cached) yes
checking for mmap... (cached) yes
checking whether read-only mmap of a plain file works... yes
checking whether mmap from /dev/zero works... yes
checking for MAP_ANON(YMOUS)... yes
checking whether mmap with MAP_ANON(YMOUS) works... yes
checking for ANSI C header files... (cached) yes
checking for memcpy... yes
checking for size_t... yes
checking for working alloca.h... yes
checking for alloca... yes
checking size of double... 8
checking size of long double... 16
checking whether byte ordering is bigendian... no
checking assembler .cfi pseudo-op support... yes
checking assembler supports pc related relocs... yes
checking assembler .ascii pseudo-op support... yes
checking assembler .string pseudo-op support... yes
checking for _ prefix in compiled symbols... no
checking toolchain supports unwind section type... yes
checking whether .eh_frame section should be read-only... yes
checking for __attribute__((visibility("hidden")))... yes
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating include/Makefile
config.status: creating include/ffi.h
config.status: creating Makefile
config.status: creating testsuite/Makefile
config.status: creating man/Makefile
config.status: creating libffi.pc
config.status: creating fficonfig.h
config.status: fficonfig.h is unchanged
config.status: linking ../src/x86/ffitarget.h to include/ffitarget.h
config.status: executing buildir commands
config.status: create top_srcdir/Makefile guessed from local Makefile
config.status: build in x86_64-unknown-linux-gnu (HOST=x86_64-unknown-linux-gnu)
config.status: executing depfiles commands
config.status: executing libtool commands
config.status: executing include commands
config.status: executing src commands
MAKE x86_64-unknown-linux-gnu : 1 * install
make[1]: Entering directory '/home/chris/.multirust/toolchains/stable/cargo/registry/src/github.com-1ecc6299db9ec823/libffi-sys-0.4.6/libffi/x86_64-unknown-linux-gnu'
Making install in include
make[2]: Entering directory '/home/chris/.multirust/toolchains/stable/cargo/registry/src/github.com-1ecc6299db9ec823/libffi-sys-0.4.6/libffi/x86_64-unknown-linux-gnu/include'
make[3]: Entering directory '/home/chris/.multirust/toolchains/stable/cargo/registry/src/github.com-1ecc6299db9ec823/libffi-sys-0.4.6/libffi/x86_64-unknown-linux-gnu/include'
make[3]: Nothing to be done for 'install-exec-am'.
 /bin/mkdir -p '/home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/lib/libffi-3.2.1/include'
 /usr/bin/install -c -m 644 ffi.h ffitarget.h '/home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/lib/libffi-3.2.1/include'
make[3]: Leaving directory '/home/chris/.multirust/toolchains/stable/cargo/registry/src/github.com-1ecc6299db9ec823/libffi-sys-0.4.6/libffi/x86_64-unknown-linux-gnu/include'
make[2]: Leaving directory '/home/chris/.multirust/toolchains/stable/cargo/registry/src/github.com-1ecc6299db9ec823/libffi-sys-0.4.6/libffi/x86_64-unknown-linux-gnu/include'
Making install in testsuite
make[2]: Entering directory '/home/chris/.multirust/toolchains/stable/cargo/registry/src/github.com-1ecc6299db9ec823/libffi-sys-0.4.6/libffi/x86_64-unknown-linux-gnu/testsuite'
make[3]: Entering directory '/home/chris/.multirust/toolchains/stable/cargo/registry/src/github.com-1ecc6299db9ec823/libffi-sys-0.4.6/libffi/x86_64-unknown-linux-gnu/testsuite'
make[3]: Nothing to be done for 'install-exec-am'.
make[3]: Nothing to be done for 'install-data-am'.
make[3]: Leaving directory '/home/chris/.multirust/toolchains/stable/cargo/registry/src/github.com-1ecc6299db9ec823/libffi-sys-0.4.6/libffi/x86_64-unknown-linux-gnu/testsuite'
make[2]: Leaving directory '/home/chris/.multirust/toolchains/stable/cargo/registry/src/github.com-1ecc6299db9ec823/libffi-sys-0.4.6/libffi/x86_64-unknown-linux-gnu/testsuite'
Making install in man
make[2]: Entering directory '/home/chris/.multirust/toolchains/stable/cargo/registry/src/github.com-1ecc6299db9ec823/libffi-sys-0.4.6/libffi/x86_64-unknown-linux-gnu/man'
make[3]: Entering directory '/home/chris/.multirust/toolchains/stable/cargo/registry/src/github.com-1ecc6299db9ec823/libffi-sys-0.4.6/libffi/x86_64-unknown-linux-gnu/man'
make[3]: Nothing to be done for 'install-exec-am'.
 /bin/mkdir -p '/home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/share/man/man3'
 /usr/bin/install -c -m 644 ../../man/ffi.3 ../../man/ffi_call.3 ../../man/ffi_prep_cif.3 ../../man/ffi_prep_cif_var.3 '/home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/share/man/man3'
make[3]: Leaving directory '/home/chris/.multirust/toolchains/stable/cargo/registry/src/github.com-1ecc6299db9ec823/libffi-sys-0.4.6/libffi/x86_64-unknown-linux-gnu/man'
make[2]: Leaving directory '/home/chris/.multirust/toolchains/stable/cargo/registry/src/github.com-1ecc6299db9ec823/libffi-sys-0.4.6/libffi/x86_64-unknown-linux-gnu/man'
make[2]: Entering directory '/home/chris/.multirust/toolchains/stable/cargo/registry/src/github.com-1ecc6299db9ec823/libffi-sys-0.4.6/libffi/x86_64-unknown-linux-gnu'
depbase=`echo src/prep_cif.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
/bin/bash ./libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I..  -I. -I../include -Iinclude -I../src   -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=amdfam10  -Wall -fexceptions -MT src/prep_cif.lo -MD -MP -MF $depbase.Tpo -c -o src/prep_cif.lo ../src/prep_cif.c &&\
mv -f $depbase.Tpo $depbase.Plo
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=amdfam10 -Wall -fexceptions -MT src/prep_cif.lo -MD -MP -MF src/.deps/prep_cif.Tpo -c ../src/prep_cif.c  -fPIC -DPIC -o src/.libs/prep_cif.o
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=amdfam10 -Wall -fexceptions -MT src/prep_cif.lo -MD -MP -MF src/.deps/prep_cif.Tpo -c ../src/prep_cif.c -o src/prep_cif.o >/dev/null 2>&1
depbase=`echo src/types.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
/bin/bash ./libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I..  -I. -I../include -Iinclude -I../src   -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=amdfam10  -Wall -fexceptions -MT src/types.lo -MD -MP -MF $depbase.Tpo -c -o src/types.lo ../src/types.c &&\
mv -f $depbase.Tpo $depbase.Plo
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=amdfam10 -Wall -fexceptions -MT src/types.lo -MD -MP -MF src/.deps/types.Tpo -c ../src/types.c  -fPIC -DPIC -o src/.libs/types.o
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=amdfam10 -Wall -fexceptions -MT src/types.lo -MD -MP -MF src/.deps/types.Tpo -c ../src/types.c -o src/types.o >/dev/null 2>&1
depbase=`echo src/raw_api.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
/bin/bash ./libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I..  -I. -I../include -Iinclude -I../src   -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=amdfam10  -Wall -fexceptions -MT src/raw_api.lo -MD -MP -MF $depbase.Tpo -c -o src/raw_api.lo ../src/raw_api.c &&\
mv -f $depbase.Tpo $depbase.Plo
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=amdfam10 -Wall -fexceptions -MT src/raw_api.lo -MD -MP -MF src/.deps/raw_api.Tpo -c ../src/raw_api.c  -fPIC -DPIC -o src/.libs/raw_api.o
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=amdfam10 -Wall -fexceptions -MT src/raw_api.lo -MD -MP -MF src/.deps/raw_api.Tpo -c ../src/raw_api.c -o src/raw_api.o >/dev/null 2>&1
depbase=`echo src/java_raw_api.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
/bin/bash ./libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I..  -I. -I../include -Iinclude -I../src   -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=amdfam10  -Wall -fexceptions -MT src/java_raw_api.lo -MD -MP -MF $depbase.Tpo -c -o src/java_raw_api.lo ../src/java_raw_api.c &&\
mv -f $depbase.Tpo $depbase.Plo
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=amdfam10 -Wall -fexceptions -MT src/java_raw_api.lo -MD -MP -MF src/.deps/java_raw_api.Tpo -c ../src/java_raw_api.c  -fPIC -DPIC -o src/.libs/java_raw_api.o
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=amdfam10 -Wall -fexceptions -MT src/java_raw_api.lo -MD -MP -MF src/.deps/java_raw_api.Tpo -c ../src/java_raw_api.c -o src/java_raw_api.o >/dev/null 2>&1
depbase=`echo src/closures.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
/bin/bash ./libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I..  -I. -I../include -Iinclude -I../src   -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=amdfam10  -Wall -fexceptions -MT src/closures.lo -MD -MP -MF $depbase.Tpo -c -o src/closures.lo ../src/closures.c &&\
mv -f $depbase.Tpo $depbase.Plo
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=amdfam10 -Wall -fexceptions -MT src/closures.lo -MD -MP -MF src/.deps/closures.Tpo -c ../src/closures.c  -fPIC -DPIC -o src/.libs/closures.o
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=amdfam10 -Wall -fexceptions -MT src/closures.lo -MD -MP -MF src/.deps/closures.Tpo -c ../src/closures.c -o src/closures.o >/dev/null 2>&1
depbase=`echo src/x86/ffi64.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
/bin/bash ./libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I..  -I. -I../include -Iinclude -I../src   -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=amdfam10  -Wall -fexceptions -MT src/x86/ffi64.lo -MD -MP -MF $depbase.Tpo -c -o src/x86/ffi64.lo ../src/x86/ffi64.c &&\
mv -f $depbase.Tpo $depbase.Plo
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=amdfam10 -Wall -fexceptions -MT src/x86/ffi64.lo -MD -MP -MF src/x86/.deps/ffi64.Tpo -c ../src/x86/ffi64.c  -fPIC -DPIC -o src/x86/.libs/ffi64.o
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=amdfam10 -Wall -fexceptions -MT src/x86/ffi64.lo -MD -MP -MF src/x86/.deps/ffi64.Tpo -c ../src/x86/ffi64.c -o src/x86/ffi64.o >/dev/null 2>&1
depbase=`echo src/x86/unix64.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
/bin/bash ./libtool    --mode=compile gcc -DHAVE_CONFIG_H -I. -I..  -I. -I../include -Iinclude -I../src  -I. -I../include -Iinclude -I../src  -MT src/x86/unix64.lo -MD -MP -MF $depbase.Tpo -c -o src/x86/unix64.lo ../src/x86/unix64.S &&\
mv -f $depbase.Tpo $depbase.Plo
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -I. -I../include -Iinclude -I../src -MT src/x86/unix64.lo -MD -MP -MF src/x86/.deps/unix64.Tpo -c ../src/x86/unix64.S  -fPIC -DPIC -o src/x86/.libs/unix64.o
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -I. -I../include -Iinclude -I../src -MT src/x86/unix64.lo -MD -MP -MF src/x86/.deps/unix64.Tpo -c ../src/x86/unix64.S -o src/x86/unix64.o >/dev/null 2>&1
/bin/bash ./libtool  --tag=CC   --mode=link gcc  -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=amdfam10  -Wall -fexceptions   -o libffi_convenience.la  src/prep_cif.lo src/types.lo src/raw_api.lo src/java_raw_api.lo src/closures.lo                                src/x86/ffi64.lo src/x86/unix64.lo src/x86/ffi.lo src/x86/sysv.lo          
libtool: link: rm -fr  .libs/libffi_convenience.a .libs/libffi_convenience.la
libtool: link: ar cru .libs/libffi_convenience.a src/.libs/prep_cif.o src/.libs/types.o src/.libs/raw_api.o src/.libs/java_raw_api.o src/.libs/closures.o src/x86/.libs/ffi64.o src/x86/.libs/unix64.o src/x86/.libs/ffi.o src/x86/.libs/sysv.o 
libtool: link: ranlib .libs/libffi_convenience.a
libtool: link: ( cd ".libs" && rm -f "libffi_convenience.la" && ln -s "../libffi_convenience.la" "libffi_convenience.la" )
/bin/bash ./libtool  --tag=CC   --mode=link gcc  -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=amdfam10  -Wall -fexceptions -no-undefined -version-info `grep -v '^#' ../libtool-version`    -o libffi.la -rpath /home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/lib/../lib src/prep_cif.lo src/types.lo src/raw_api.lo src/java_raw_api.lo src/closures.lo                                src/x86/ffi64.lo src/x86/unix64.lo src/x86/ffi.lo src/x86/sysv.lo          
libtool: link: rm -fr  .libs/libffi.a .libs/libffi.la .libs/libffi.lai .libs/libffi.so .libs/libffi.so.6 .libs/libffi.so.6.0.4
libtool: link: gcc -shared  -fPIC -DPIC  src/.libs/prep_cif.o src/.libs/types.o src/.libs/raw_api.o src/.libs/java_raw_api.o src/.libs/closures.o src/x86/.libs/ffi64.o src/x86/.libs/unix64.o src/x86/.libs/ffi.o src/x86/.libs/sysv.o    -O3 -march=amdfam10   -Wl,-soname -Wl,libffi.so.6 -o .libs/libffi.so.6.0.4
libtool: link: (cd ".libs" && rm -f "libffi.so.6" && ln -s "libffi.so.6.0.4" "libffi.so.6")
libtool: link: (cd ".libs" && rm -f "libffi.so" && ln -s "libffi.so.6.0.4" "libffi.so")
libtool: link: ar cru .libs/libffi.a  src/prep_cif.o src/types.o src/raw_api.o src/java_raw_api.o src/closures.o src/x86/ffi64.o src/x86/unix64.o src/x86/ffi.o src/x86/sysv.o
libtool: link: ranlib .libs/libffi.a
libtool: link: ( cd ".libs" && rm -f "libffi.la" && ln -s "../libffi.la" "libffi.la" )
make[3]: Entering directory '/home/chris/.multirust/toolchains/stable/cargo/registry/src/github.com-1ecc6299db9ec823/libffi-sys-0.4.6/libffi/x86_64-unknown-linux-gnu'
 /bin/mkdir -p '/home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/lib/../lib'
 /bin/bash ./libtool   --mode=install /usr/bin/install -c   libffi.la '/home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/lib/../lib'
libtool: install: /usr/bin/install -c .libs/libffi.so.6.0.4 /home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/lib/../lib/libffi.so.6.0.4
libtool: install: (cd /home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/lib/../lib && { ln -s -f libffi.so.6.0.4 libffi.so.6 || { rm -f libffi.so.6 && ln -s libffi.so.6.0.4 libffi.so.6; }; })
libtool: install: (cd /home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/lib/../lib && { ln -s -f libffi.so.6.0.4 libffi.so || { rm -f libffi.so && ln -s libffi.so.6.0.4 libffi.so; }; })
libtool: install: /usr/bin/install -c .libs/libffi.lai /home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/lib/../lib/libffi.la
libtool: install: /usr/bin/install -c .libs/libffi.a /home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/lib/../lib/libffi.a
libtool: install: chmod 644 /home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/lib/../lib/libffi.a
libtool: install: ranlib /home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/lib/../lib/libffi.a
libtool: finish: PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/lib/jvm/java-8-oracle/bin:/usr/lib/jvm/java-8-oracle/db/bin:/usr/lib/jvm/java-8-oracle/jre/bin:/home/chris/.rvm/bin:/home/chris/.rvm/bin:/home/chris/.multirust/toolchains/beta/cargo/bin:/home/chris/.multirust/toolchains/stable/bin:/sbin" ldconfig -n /home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/lib/../lib
----------------------------------------------------------------------
Libraries have been installed in:
   /home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/lib/../lib

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the '-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the 'LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the 'LD_RUN_PATH' environment variable
     during linking
   - use the '-Wl,-rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to '/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
 /bin/mkdir -p '/home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/share/info'
 /usr/bin/install -c -m 644 ../doc/libffi.info '/home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/share/info'
 install-info --info-dir='/home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/share/info' '/home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/share/info/libffi.info'
 /bin/mkdir -p '/home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/lib/pkgconfig'
 /usr/bin/install -c -m 644 libffi.pc '/home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/lib/pkgconfig'
make[3]: Leaving directory '/home/chris/.multirust/toolchains/stable/cargo/registry/src/github.com-1ecc6299db9ec823/libffi-sys-0.4.6/libffi/x86_64-unknown-linux-gnu'
make[2]: Leaving directory '/home/chris/.multirust/toolchains/stable/cargo/registry/src/github.com-1ecc6299db9ec823/libffi-sys-0.4.6/libffi/x86_64-unknown-linux-gnu'
make[1]: Leaving directory '/home/chris/.multirust/toolchains/stable/cargo/registry/src/github.com-1ecc6299db9ec823/libffi-sys-0.4.6/libffi/x86_64-unknown-linux-gnu'

--- stderr
autoreconf: Entering directory `.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal --force -I m4
autoreconf: configure.ac: tracing
autoreconf: running: libtoolize --copy --force
autoreconf: running: /usr/bin/autoconf --force
autoreconf: running: /usr/bin/autoheader --force
autoreconf: running: automake --add-missing --copy --force-missing
configure.ac:31: installing './compile'
configure.ac:19: installing './missing'
Makefile.am: installing './depcomp'
autoreconf: Leaving directory `.'
configure: WARNING: unrecognized options: --disable-docs
configure: WARNING: unrecognized options: --disable-docs
configure: WARNING: unrecognized options: --disable-docs
../src/closures.c: In function ‘dlmmap_locked’:
../src/closures.c:488:7: warning: ignoring return value of ‘ftruncate’, declared with attribute warn_unused_result [-Wunused-result]
       ftruncate (execfd, offset);
       ^
../src/closures.c:500:7: warning: ignoring return value of ‘ftruncate’, declared with attribute warn_unused_result [-Wunused-result]
       ftruncate (execfd, offset);
       ^
ar: `u' modifier ignored since `D' is the default (see `U')
ar: `u' modifier ignored since `D' is the default (see `U')
/home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/lib/libffi-3.2.1/include/ffi.h:114:3: error: unknown type name 'size_t'
/home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/lib/libffi-3.2.1/include/ffi.h:292:1: error: unknown type name 'size_t'
/home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/lib/libffi-3.2.1/include/ffi.h:305:1: error: unknown type name 'size_t'
/home/chris/repos/glusterfs-fuse/target/debug/build/libffi-sys-c180ae0cc8ed998b/out/libffi-root/lib/libffi-3.2.1/include/ffi.h:333:26: error: unknown type name 'size_t'
thread 'main' panicked at '
        **********
        Bindgen generation failed. Please file a bug report.
        **********
    : ()', /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libcore/result.rs:837
note: Run with `RUST_BACKTRACE=1` for a backtrace.

This works fine on a fresh ubuntu 16.04 laptop so it's probably something silly that I misconfigured. Any help is greatly appreciated!

Allow, but not require, filesystem options running concurrently

In reply to your comment on reddit in which you explained why you don't spawn a new task for each operation:

First I planned to dispatch every operation into separate tasks, but then I realized that this might not be always desirable. One idea of Rust is to prevent waiting/locking at all by grouping access to one resource in a single task. Most of the filesystem operations deal with metadata that manage inodes. They could easily be done in a single task since they'd require exclusive access to these metadata anyway. Operations that deal with actual data (read/write) are candidates to be parallelized, I think. However I don't have any benchmarks on this idea yet.

The metadata, as well as the underlying data, may live across a network somewhere, which means any operation might be both slow and parallelizeable. So I think all of operations should be able to run concurrently, not just read and write. But your point about internal inode mappings still stands, so I agree that it shouldn't force a new task for every operation.

So here's another idea. For simplicity, let me pick readlink as the example--the signature would change from this:

fn readlink (&mut self, _ino: u64) -> Result<~str, c_int>

to this:

fn readlink (&mut self, _ino: u64,
             handle: ReplyHandle<Result<~str, c_int>>)

(I'm not sure I like the name "ReplyHandle" but am at a loss for a better one.) You could implement it synchronously like this:

impl FileSystem for SingleTaskFS {
    fn readlink(&mut self, ino: u64,
                handle: ReplyHandle<Result<~str, c_int>>) {
        let s:~str = (/*get the result here...*/);
        handle.reply(Ok(s));
    }
}

or asynchronously like this:

impl FileSystem for MultiTaskFS {
    fn readlink(&mut self, ino: u64,
                handle: ReplyHandle<Result<~str, c_int>>) {
        do task().spawn_with(handle) |handle| {
            let s:~str = (/*get the result here...*/);
            handle.reply(Ok(s));
        }
    }
}

The reply method of the handle would take by-value self, and the handle would be sendable but not copyable. So the compiler would ensure that the operation could not reply multiple times, and that only correctly typed replies could be sent for each operation. It could not enforce at compile time that the code for the operation always explicitly provides a reply, but the handle could implement Drop so as to automatically provide an error back to FUSE if it falls out of scope when no reply was provided.

This pattern could also allow data to be passed out of read without copying the data--the handle passed to read could take an enum with many forms, including a borrowed slice, another file descriptor, or even (unsafely) an iovec.

I plan to try this out myself, but I'm leaving this issue here in advance, in case you had any thoughts on the general idea before I've fleshed out all the specifics.

Is x86_64-unknown-linux-musl unsupported for reason or just because of platform detection is lacky?

$ cargo test --target=x86_64-unknown-linux-musl
Build failed, waiting for other jobs to finish...
failed to run custom build command for `fuse v0.2.7`
Process didn't exit successfully: `/home/vi/code/outoforderfs/target/debug/build/fuse-5faebf645a751bfb/build-script-build` (exit code: 101)
--- stderr
thread '<main>' panicked at 'Unsupported target platform', /home/vi/.multirust/toolchains/nightly/cargo/registry/src/github.com-48ad6e4054423464/fuse-0.2.7/build.rs:15
note: Run with `RUST_BACKTRACE=1` for a backtrace.
build.rs>  else if target.ends_with("-unknown-linux-gnu") || target.ends_with("-unknown-freebsd")

getattr does not receive fh

In the c libfuse, getattr calls receive fh if there is some (see fuse_lowlevel.c:1087, static void do_getattr). In rust-fuse, only setattr receives _fh: Option<u64>.

Make API more idiomatic

Basically: Look at the methods for the fuse-mt::FilesystemMT trait. Note how those methods have actual return values, rather than having the C-like "do something with some variable passed in as an argument and then return void" API that this crate currently has.

I think changing this crate's API to be more like fuse-mt's would be an improvement.

ReadDirAll

Hi,

why is it not possible to return just all files/folders when a readdir() request comes in?

It seems that many files are missing if I just return everything I know.

regards,
Dom

Package fuse was not found in the pkg-config search path

I'm trying to build a FUSE project on Linux and I get this error:

   Compiling fuse v0.2.8
failed to run custom build command for `fuse v0.2.8`
Process didn't exit successfully: `/home/aidan/hashtag-fs/target/debug/build/fuse-eb6a62fe8373dd63/build-script-build` (exit code: 101)
--- stderr
thread '<main>' panicked at 'called `Result::unwrap()` on an `Err` value: Failure { command: "\"pkg-config\" \"--libs\" \"--cflags\" \"fuse\"", output: Output { status: ExitStatus(ExitStatus(256)), stdout: "", stderr: "Package fuse was not found in the pkg-config search path.\nPerhaps you should add the directory containing `fuse.pc\'\nto the PKG_CONFIG_PATH environment variable\nNo package \'fuse\' found\n" } }', src/libcore/result.rs:688

It looks like it's because the library isn't being downloaded normally, which is weird because it's on crates.io. What's going on?

Add details about dependencies (install instructions) to README

I am trying to build this from the repo on Ubuntu 15.04 and having some trouble, I was hoping that you could point me in the right direction. I have fuse installed fuse is already the newest version. but there seems to be something in the build script that is triggering a build failure. I tracked it down to the fact that the program below has the output that it does. But I have fuse installed, so I'm not sure where to go from here.

$ pkg-config --libs --cflags libfuse
Package libfuse was not found in the pkg-config search path.
Perhaps you should add the directory containing `libfuse.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libfuse' found

For now, I commented out the build script in Cargo.toml and it builds just fine. I'm not sure how to proceed from here but just wanted to let you know that I ran into this problem on my machine.

Missing support for ARM

After adding || target.ends_with("-unknown-linux-gnueabi") || target.ends_with("-unknown-linux-gnueabihf") to build.rs, I get

   Compiling fuse v0.2.7 (file:///root/.cargo/registry/src/github.com-1ecc6299db9ec823/fuse-0.2.7)
src/argument.rs:36:41: 36:61 error: mismatched types [E0308]
src/argument.rs:36     let s = unsafe { CStr::from_ptr(ptr as *const c_char) };
                               ^~~~~~~~~~~~~~~~~~~~
src/argument.rs:36:41: 36:61 help: run `rustc --explain E0308` to see a detailed explanation
src/channel.rs:48:27: 48:40 error: mismatched types [E0308]
src/channel.rs:48     if libc::realpath(path.as_ptr(), resolved.as_mut_ptr()).is_null() {
                        ^~~~~~~~~~~~~
src/channel.rs:48:27: 48:40 help: run `rustc --explain E0308` to see a detailed explanation
src/channel.rs:52:44: 52:61 error: mismatched types [E0308]
src/channel.rs:52         let cresolved = CStr::from_ptr(resolved.as_ptr());
                                 ^~~~~~~~~~~~~~~~~
src/channel.rs:52:44: 52:61 help: run `rustc --explain E0308` to see a detailed explanation
src/channel.rs:63:67: 63:74 error: the trait bound `std::vec::Vec<*const i8>: std::iter::FromIterator<*const u8>` is not satisfied [E0277]
src/channel.rs:63     let argptrs: Vec<*const i8> = args.iter().map(|s| s.as_ptr()).collect();
                                            ^~~~~~~
src/channel.rs:63:67: 63:74 help: run `rustc --explain E0277` to see a detailed explanation
src/channel.rs:63:67: 63:74 note: a collection of type `std::vec::Vec<*const i8>` cannot be built from an iterator over elements of type `*const u8`
src/channel.rs:82:55: 82:67 error: mismatched types [E0308]
src/channel.rs:82         let fd = unsafe { fuse_mount_compat25(mnt.as_ptr(), args) };
                                    ^~~~~~~~~~~~
src/channel.rs:82:55: 82:67 help: run `rustc --explain E0308` to see a detailed explanation
src/channel.rs:177:40: 177:52 error: mismatched types [E0308]
src/channel.rs:177     let rc = unsafe { libc::umount(mnt.as_ptr()) };
                              ^~~~~~~~~~~~
src/channel.rs:177:40: 177:52 help: run `rustc --explain E0308` to see a detailed explanation
src/channel.rs:181:44: 181:56 error: mismatched types [E0308]
src/channel.rs:181         unsafe { fuse_unmount_compat22(mnt.as_ptr()); }
                                  ^~~~~~~~~~~~
src/channel.rs:181:44: 181:56 help: run `rustc --explain E0308` to see a detailed explanation
error: aborting due to 7 previous errors
error: Could not compile `fuse`.

ReplyDirectory offsets are i64 not u64

https://github.com/libfuse/libfuse/blob/da29b950bc9d204a93706985255a299f1dfea561/include/fuse_kernel.h#L709 suggests that the underlying fuse_dirent offsets are unsigned.

https://github.com/zargony/rust-fuse/blob/60bd7766d56dc7793b3c9ce4936432a148d4094c/src/reply.rs#L548 accepts signed values.

Is there a reason for this discrepancy? If so, could it be documented? If not, could we consider making the Rust API use unsigned values for consistency? I don't believe the sign is currently significant, but I ended up delving into the code to check in case it had some meaning, which could be avoided in the future :)

BackgroundSession does not stop filesystem thread on OS X

If you create a BackgroundSession object and destroy it, the background task running the real session won't actually terminate right away on OS X. It seems that the libc::read call is not interrupted by the call to fuse_unmount_compat22, so it won't kill the background task until something else tries to use the filesystem. Unmounting it externally (by running "umount" in another shell) does not appear to have this problem--it interrupts the read call right away. The problem also doesn't seem to happen on Linux.

It would be nice if serde support was added

I'm trying to use serde to make it easier to serialize a file metadata struct to disk. It would be nice if the FileType enum implemented Serialize/Deserialize. This can probably be done behind a feature flag so that not everyone needs to drag in serde even if they're not using it.

use of proc() { } causes compilation to fail

As of rustc version “rustc 0.13.0-nightly (42deaa5e4 2014-12-16 17:51:23 +0000)”
the library fails to compile. The cause appears to be the removal of proc():

$ cargo build
   Compiling fuse v0.2.0 (file:///home/phg/src/rust-dev/rust-fuse-git)
src/reply.rs:27:34: 27:38 error: obsolete syntax: the `proc` type
src/reply.rs:27     fn new (unique: u64, sender: proc(&[&[u8]]):Send) -> Self;
                                                 ^~~~
note: use unboxed closures instead

How do I build the example?

cargo build produce empty target/debug/examples/ directory.

Manual compilation also fails:

$  rustc    -L target/debug  examples/hello.rs  
examples/hello.rs:3:1: 3:19 error: found possibly newer version of crate `log` which `fuse` depends on
examples/hello.rs:3 extern crate fuse;
                    ^~~~~~~~~~~~~~~~~~
examples/hello.rs:3:1: 3:19 note: perhaps this crate needs to be recompiled?
examples/hello.rs:3 extern crate fuse;
                    ^~~~~~~~~~~~~~~~~~
examples/hello.rs:3:19: 3:19 note: crate `log` path #1: /home/vi/home/rust/prefix/lib/rustlib/i686-unknown-linux-gnu/lib/liblog-4e7c5e5c.rlib
examples/hello.rs:3:19: 3:19 note: crate `log` path #2: /home/vi/home/rust/prefix/lib/rustlib/i686-unknown-linux-gnu/lib/liblog-4e7c5e5c.so
examples/hello.rs:3:19: 3:19 note: crate `fuse` path #1: /home/vi/home/rust/rust-fuse/target/debug/libfuse-c61beed3b50079b8.rlib
error: aborting due to previous error

I think there should also be a fusexmp or bindfs-like example. This is both useful as a reference of Rust's filesytem features and as a basis for new FUSE programs.

Release tagging

Greetings, there is a project, which presents a higher-level abstraction over rust-fuse: fuse-mt.

The author currently special-cases the socket type (used for UNIX sockets), because the feature is present in your repository, but not correctly tagged and therefore not present in the crates.io version.

Here is the link to the issue over there: fuse-mt issue 18

Any way to solve this? Tag and release a new version?

Expose file-descriptor and read-one-request/write-one-reply functions for use in event loops

Right now, rust-fuse expects either mount or spawn_mount to be called, and these run an event loop, doing blocking reads to the FUSE fd and then dispatching the events read from it to user-implemented callbacks.

In most filesystems of some complexity, IPC, disk IO, or network IO will be performed in response to FUSE events, and it would be nice to be able to perform these asynchronously, e.g. with MIO. But because rust-fuse runs the eventloop itself and hides the FUSE fd, it isn't possible to implement MIO's Evented trait for fuse::Channel (which isn't even exposed in the crate's public API). Asnychronous operation enables higher throughput, so it's desirable to overlap not just multiple requests to the filesystem, but also those requests with IO operations to other OS resources, and it shouldn't be necessary to spawn multiple threads to do so.

If rust-fuse provided a way to get the fd so it can be added to an epoll-based event-loop, as well functions to read a request from the FUSE fd and write a reply to it, this integration would be easy to implement.

Implementing notify functions

First of all great work with the library :)

I was wondering if there would be any interest in implementing the notification functions of fuse. These functions allow the filesystem to notify the kernel driver of events which have occurred - mainly associated with changes to inodes/files/directories to allow the kernel to update its caches.

These functions can be found at https://github.com/libfuse/libfuse/blob/56fde4ba9ee0268ece42512a00782b2064537b15/include/fuse_lowlevel.h#L1497 in libfuse

Thanks :)

Cleanup on terminate or prior to mount

The file system is not unmounted when the application is terminated. E.g. ctrl+c in the hello example. Attempting to run the application again (on OSX) errors out with:

mount_osxfusefs: mount point /private/tmp/test is itself on a OSXFUSE volume

I wanted to use the unmount function prior to calling mount, but it's private. Hoping this would do the necessary cleanup to attempt unmounting orphaned file systems, and let the application happily continue running.

Read is single threaded

First read hangs for 6 seconds and second read is not executed until first read is complete.


    fn read(&mut self, _req: &Request, ino: u64, _: u64,
            offset: u64, size: u32, reply: ReplyData) {
        println!("read ino {}; ofs {}; sz {}", ino, offset, size);
        self.counter += 1;
        if self.counter % 2 == 1 {
            sleep(Duration::new(6, 0))
        }

fuse_attr needs blksize

Current rust-fuse doesn't have blksize field in fuse_attr struct.

Is this a bug?

struct fuse_attr {
        __u64   ino;
        __u64   size;
        __u64   blocks;
        __u64   atime;
        __u64   mtime;
        __u64   ctime;
        __u32   atimensec;
        __u32   mtimensec;
        __u32   ctimensec;
        __u32   mode;
        __u32   nlink;
        __u32   uid;
        __u32   gid;
        __u32   rdev;
        __u32   blksize;
        __u32   padding;
};

BUG: maxos: fuse_getxattr_in.position is not used

In macosx, fuse_getxattr_in has a member "position" but it isn't used. I think getxattr method in Filesystem trait should add a parameter "position" in the same way as setxattr.

static void do_getxattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
        struct fuse_getxattr_in *arg = (struct fuse_getxattr_in *) inarg;

        if (req->f->op.getxattr)
#ifdef __APPLE__
                req->f->op.getxattr(req, nodeid, PARAM(arg), arg->size, arg->position);
#else
                req->f->op.getxattr(req, nodeid, PARAM(arg), arg->size);
#endif

Cargo Build - FUSE Error

Hi,

I'm trying to use an app and run the cargo build, it will give me error on the FUSE, do you mind help me with this.

I already asked the DEV, but we couldn't find the problem from his side, so I was wondering if you can give us some insight and we fix this issue.

I tried both RUST 1.19 and 1.21 nightly and same result.
I have macOS 10.12.6 also

Danials-iMac:plexdrive-rust danial$ RUST_BACKTRACE=1 cargo build
   Compiling fuse v0.3.0
   Compiling chrono v0.4.0
   Compiling chrono v0.2.25
   Compiling hyper v0.10.12
   Compiling openssl v0.9.16
   Compiling ring v0.11.0
error: failed to run custom build command for `fuse v0.3.0`
process didn't exit successfully: `/Users/danial/Downloads/plexdrive-rust/target/debug/build/fuse-9b6f07c4aca6099a/build-script-build` (exit code: 101)
--- stderr
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Command { command: "\"pkg-config\" \"--libs\" \"--cflags\" \"fuse\"", cause: Error { repr: Os { code: 2, message: "No such file or directory" } } }', src/libcore/result.rs:860
stack backtrace:
   0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
   1: std::panicking::default_hook::{{closure}}
   2: std::panicking::default_hook
   3: std::panicking::rust_panic_with_hook
   4: std::panicking::begin_panic
   5: std::panicking::begin_panic_fmt
   6: rust_begin_unwind
   7: core::panicking::panic_fmt
   8: core::result::unwrap_failed
   9: <core::result::Result<T, E>>::unwrap
  10: build_script_build::main
  11: __rust_maybe_catch_panic
  12: std::rt::lang_start
  13: main

Build failed, waiting for other jobs to finish...
error: build failed

Tokio version

Would anybody be interested in cooperating on a Tokio version of rust-fuse? I feel like this could be a huge improvement when using other tokio (or futures) based services in the filesystem implementation.

It does require a bit of refactoring. An interesting option would be to allow both single threaded use and running the service on a CpuPool.

I've been playing around with this for a bit, but am currently running into some interesting issues with setting the socket to non-blocking io.

Linux umount() is only permitted for root

After commits ef283a7 and e9560fd, Linux builds are no longer using the FUSE unmount library call, only the umount syscall. However, this only works for root, and other users get EPERM.

The FUSE library handles this failure by running fusermount, which is setuid-root, just like it does for mounting in the first place.

Thus non-root users can't use drop or variable scopes to unmount a session from spawn_mount anymore.

Filesystem is not fully up and running when spawn_mount returns

Consider this snippet from #8:

    let _session = fuse::spawn_mount(HelloFS, &mountpoint, []);

    // TODO: Without this, the test fails--the filesystem is not fully set up by the time the next
    // line tries to use it.  What guarantee should we make (if any) about this?  Should it be fully
    // ready before spawn_mount returns?
    std::io::timer::sleep(100);

    let hello_contents = File::open(&mountpoint.join("hello.txt")).read_to_end();
    assert_eq!(hello_contents, hello_world.as_bytes().into_owned());

without the sleep call, the test fails.

Even waiting for init to be called on the filesystem does not suffice. I tried using that to sync (the init call would send on a channel, with the test code receiving on the corresponding port in place of the sleep) and it still did not work without the additional sleep call.

I'm not even sure what guarantee should be in place--my instinct is to say that the FS should be usable when spawn_mount returns though.

read op can't reply with fuse_reply_iov

rust-fuse forces the read op implementation to use ReplyData type as the reply object which is equivalent to fuse_reply_data or fuse_reply_buf because it returns a single buffer.

But, returning by scatter-gather is better for performance. If I understand correctly, that's because read op allows the user to reply with fuse_reply_iov.

This isn't a bug but I think rust-fuse has a reason to rethink its design.

        /**
         * Read data
         *
         * Read should send exactly the number of bytes requested except
         * on EOF or error, otherwise the rest of the data will be
         * substituted with zeroes.  An exception to this is when the file
         * has been opened in 'direct_io' mode, in which case the return
         * value of the read system call will reflect the return value of
         * this operation.
         *
         * fi->fh will contain the value set by the open method, or will
         * be undefined if the open method didn't set any value.
         *
         * Valid replies:
         *   fuse_reply_buf
         *   fuse_reply_iov
         *   fuse_reply_data
         *   fuse_reply_err
         *
         * @param req request handle
         * @param ino the inode number
         * @param size number of bytes to read
         * @param off offset to read from
         * @param fi file information
         */
        void (*read) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
                      struct fuse_file_info *fi);

Recommend Projects

  • React photo React

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

  • Vue.js photo Vue.js

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

  • Typescript photo Typescript

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

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

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

  • web

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

  • server

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

  • Machine learning

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

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

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

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.