aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--ChangeLog67
-rw-r--r--configure.ac5
-rw-r--r--doc/.gitignore1
-rw-r--r--example/cusexmp.c2
-rw-r--r--example/fioc.c2
-rw-r--r--example/fsel.c2
-rw-r--r--example/fusexmp.c2
-rw-r--r--example/fusexmp_fh.c7
-rw-r--r--example/hello.c2
-rw-r--r--example/hello_ll.c2
-rw-r--r--example/null.c2
-rw-r--r--include/Makefile.am5
-rw-r--r--include/fuse.h182
-rw-r--r--include/fuse_common.h86
-rw-r--r--include/fuse_common_compat.h26
-rw-r--r--include/fuse_compat.h201
-rw-r--r--include/fuse_kernel.h46
-rw-r--r--include/fuse_lowlevel.h83
-rw-r--r--include/fuse_lowlevel_compat.h155
-rw-r--r--include/fuse_opt.h5
-rw-r--r--include/old/fuse.h9
-rw-r--r--lib/Makefile.am4
-rw-r--r--lib/cuse_lowlevel.c3
-rw-r--r--lib/fuse.c462
-rw-r--r--lib/fuse_i.h31
-rw-r--r--lib/fuse_lowlevel.c286
-rw-r--r--lib/fuse_misc.h11
-rw-r--r--lib/fuse_mt.c100
-rw-r--r--lib/fuse_opt.c14
-rw-r--r--lib/fuse_session.c40
-rw-r--r--lib/fuse_versionscript73
-rw-r--r--lib/helper.c178
-rw-r--r--lib/modules/iconv.c3
-rw-r--r--lib/modules/subdir.c3
-rw-r--r--lib/mount.c28
-rw-r--r--lib/mount_bsd.c2
-rw-r--r--test/stracedecode.c1
38 files changed, 451 insertions, 1682 deletions
diff --git a/.gitignore b/.gitignore
index 65a37c7..6a5e5e4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,5 +32,5 @@ config.*
/INSTALL
/fuse.pc
/.pc
-/patches
+/patches*
/m4
diff --git a/ChangeLog b/ChangeLog
index 3afa404..a543264 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,67 @@
cancelling that same worker. This caused a segmenation
fault. Reported and tested by Anatol Pomozov
+2013-02-20 Miklos Szeredi <miklos@szeredi.hu>
+
+ * libfuse: change the type of fuse_ino_t from 'unsigned long' to
+ 'uint64_t'
+
+ * libfuse: use O_CLOEXEC flag when opening /dev/fuse device.
+ Patch by Richard W.M. Jones
+
+ * libfuse: don't force -D_FILE_OFFSET_BITS=64 in pkgconfig file.
+ Patch by Richard W.M. Jones
+
+2013-02-19 Miklos Szeredi <miklos@szeredi.hu>
+
+ * fuse_daemonize(): chdir to "/" even if not running in the
+ background for consistency. Reported by Vladimir Rutsky
+
+2013-02-18 Miklos Szeredi <miklos@szeredi.hu>
+
+ * fuse_opt_parse(): when storing a newly allocated string for
+ format "%s", free the previous value stored at that location.
+ Reported by Marco Schuster
+
+2013-02-07 Miklos Szeredi <miklos@szeredi.hu>
+
+ * libfuse: add readdirplus support in fuse_lowlevel_ops. Patch by
+ Feng Shuo
+
+ * libfuse: add poll_events to fuse_file_info. Patch by Enke Chen
+
+ * libfuse: fix fs cleanup. Reported by Eric Wong
+
+ * libfuse: pass security context options to kernel. Patch by
+ Dalvik Khertel
+
+ * libfuse: remove deprecated features:
+ - fuse_is_lib_option()
+ - fuse_invalidate()
+ - fuse_set_getcontext_func()
+ - fuse_loop_mt_proc()
+ - fuse_read_cmd()
+ - fuse_process_cmd()
+ - fuse_setup()
+ - fuse_teardown()
+ - fuse_exited()
+ - fuse_lowlevel_is_lib_option()
+ - fuse_operations.getdir()
+ - fuse_operations.utime()
+ - fuse_operations.utime_omit_ok
+
+2013-02-06 Miklos Szeredi <miklos@szeredi.hu>
+
+ * libfuse: set close-on-exec flag on pipe file descriptors. Patch
+ by Eric Wong
+
+ * libfuse: add missing INIT flags
+
+2013-02-05 Miklos Szeredi <miklos@szeredi.hu>
+
+ * libfuse: fix fuse_get_context() in non fuse threads. Reported
+ by Michael Berlin
+
2013-02-04 Miklos Szeredi <miklos@szeredi.hu>
* libfuse: fix crash in unlock_path(). Patch by Ratna Manoj
@@ -48,6 +109,12 @@
2012-07-19 Miklos Szeredi <miklos@szeredi.hu>
+ * Start of 3.0 series. This is going to be a new major version of
+ the library breaking backward compatibility on the binary level as
+ well as the source level.
+
+2012-07-19 Miklos Szeredi <miklos@szeredi.hu>
+
* Released 2.9.1
2012-07-19 Miklos Szeredi <miklos@szeredi.hu>
diff --git a/configure.ac b/configure.ac
index 0737bad..7bf6553 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,4 @@
-AC_INIT(fuse, 2.9.2)
-
+AC_INIT(fuse, 3.0.0-pre0)
AC_PREREQ(2.59d)
AC_CONFIG_MACRO_DIR([m4])
AC_CANONICAL_TARGET
@@ -53,7 +52,7 @@ if test "$enable_mtab" = "no"; then
AC_DEFINE(IGNORE_MTAB, 1, [Don't update /etc/mtab])
fi
-AC_CHECK_FUNCS([fork setxattr fdatasync splice vmsplice utimensat])
+AC_CHECK_FUNCS([fork setxattr fdatasync splice vmsplice utimensat pipe2])
AC_CHECK_FUNCS([posix_fallocate])
AC_CHECK_MEMBERS([struct stat.st_atim])
AC_CHECK_MEMBERS([struct stat.st_atimespec])
diff --git a/doc/.gitignore b/doc/.gitignore
new file mode 100644
index 0000000..1936cc1
--- /dev/null
+++ b/doc/.gitignore
@@ -0,0 +1 @@
+html
diff --git a/example/cusexmp.c b/example/cusexmp.c
index 01fcdf7..b69f97c 100644
--- a/example/cusexmp.c
+++ b/example/cusexmp.c
@@ -9,7 +9,7 @@
gcc -Wall cusexmp.c `pkg-config fuse --cflags --libs` -o cusexmp
*/
-#define FUSE_USE_VERSION 29
+#define FUSE_USE_VERSION 30
#include <cuse_lowlevel.h>
#include <fuse_opt.h>
diff --git a/example/fioc.c b/example/fioc.c
index bee40b9..849bd5d 100644
--- a/example/fioc.c
+++ b/example/fioc.c
@@ -9,7 +9,7 @@
gcc -Wall fioc.c `pkg-config fuse --cflags --libs` -o fioc
*/
-#define FUSE_USE_VERSION 26
+#define FUSE_USE_VERSION 30
#include <fuse.h>
#include <stdlib.h>
diff --git a/example/fsel.c b/example/fsel.c
index 9cf0221..bddc1aa 100644
--- a/example/fsel.c
+++ b/example/fsel.c
@@ -9,7 +9,7 @@
gcc -Wall fsel.c `pkg-config fuse --cflags --libs` -o fsel
*/
-#define FUSE_USE_VERSION 29
+#define FUSE_USE_VERSION 30
#include <fuse.h>
#include <unistd.h>
diff --git a/example/fusexmp.c b/example/fusexmp.c
index dca8a46..42a8134 100644
--- a/example/fusexmp.c
+++ b/example/fusexmp.c
@@ -9,7 +9,7 @@
gcc -Wall fusexmp.c `pkg-config fuse --cflags --libs` -o fusexmp
*/
-#define FUSE_USE_VERSION 26
+#define FUSE_USE_VERSION 30
#ifdef HAVE_CONFIG_H
#include <config.h>
diff --git a/example/fusexmp_fh.c b/example/fusexmp_fh.c
index 1ba9dbc..eea6b9b 100644
--- a/example/fusexmp_fh.c
+++ b/example/fusexmp_fh.c
@@ -9,7 +9,7 @@
gcc -Wall fusexmp_fh.c `pkg-config fuse --cflags --libs` -lulockmgr -o fusexmp_fh
*/
-#define FUSE_USE_VERSION 26
+#define FUSE_USE_VERSION 30
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -553,11 +553,6 @@ static struct fuse_operations xmp_oper = {
#endif
.lock = xmp_lock,
.flock = xmp_flock,
-
- .flag_nullpath_ok = 1,
-#if HAVE_UTIMENSAT
- .flag_utime_omit_ok = 1,
-#endif
};
int main(int argc, char *argv[])
diff --git a/example/hello.c b/example/hello.c
index bcb6b4c..b31fbe5 100644
--- a/example/hello.c
+++ b/example/hello.c
@@ -8,7 +8,7 @@
gcc -Wall hello.c `pkg-config fuse --cflags --libs` -o hello
*/
-#define FUSE_USE_VERSION 26
+#define FUSE_USE_VERSION 30
#include <fuse.h>
#include <stdio.h>
diff --git a/example/hello_ll.c b/example/hello_ll.c
index 1405441..baf41bc 100644
--- a/example/hello_ll.c
+++ b/example/hello_ll.c
@@ -8,7 +8,7 @@
gcc -Wall hello_ll.c `pkg-config fuse --cflags --libs` -o hello_ll
*/
-#define FUSE_USE_VERSION 26
+#define FUSE_USE_VERSION 30
#include <fuse_lowlevel.h>
#include <stdio.h>
diff --git a/example/null.c b/example/null.c
index b72cf4d..4e2bb8f 100644
--- a/example/null.c
+++ b/example/null.c
@@ -8,7 +8,7 @@
gcc -Wall null.c `pkg-config fuse --cflags --libs` -o null
*/
-#define FUSE_USE_VERSION 26
+#define FUSE_USE_VERSION 30
#include <fuse.h>
#include <string.h>
diff --git a/include/Makefile.am b/include/Makefile.am
index 663e164..df02a59 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -4,14 +4,11 @@ fuseincludedir=$(includedir)/fuse
fuseinclude_HEADERS = \
fuse.h \
- fuse_compat.h \
fuse_common.h \
- fuse_common_compat.h \
fuse_lowlevel.h \
- fuse_lowlevel_compat.h \
fuse_opt.h \
cuse_lowlevel.h
-include_HEADERS = old/fuse.h ulockmgr.h
+include_HEADERS = ulockmgr.h
noinst_HEADERS = fuse_kernel.h
diff --git a/include/fuse.h b/include/fuse.h
index c657e67..793862e 100644
--- a/include/fuse.h
+++ b/include/fuse.h
@@ -13,21 +13,13 @@
*
* This file defines the library interface of FUSE
*
- * IMPORTANT: you should define FUSE_USE_VERSION before including this
- * header. To use the newest API define it to 26 (recommended for any
- * new application), to use the old API define it to 21 (default) 22
- * or 25, to use the even older 1.X API define it to 11.
+ * IMPORTANT: you should define FUSE_USE_VERSION before including this header.
*/
-#ifndef FUSE_USE_VERSION
-#define FUSE_USE_VERSION 21
-#endif
-
#include "fuse_common.h"
#include <fcntl.h>
#include <time.h>
-#include <utime.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
@@ -44,9 +36,6 @@ extern "C" {
/** Handle for a FUSE filesystem */
struct fuse;
-/** Structure containing a raw command */
-struct fuse_cmd;
-
/** Function to add an entry in a readdir() operation
*
* @param buf the buffer passed to the readdir() operation
@@ -58,11 +47,6 @@ struct fuse_cmd;
typedef int (*fuse_fill_dir_t) (void *buf, const char *name,
const struct stat *stbuf, off_t off);
-/* Used by deprecated getdir() method */
-typedef struct fuse_dirhandle *fuse_dirh_t;
-typedef int (*fuse_dirfil_t) (fuse_dirh_t h, const char *name, int type,
- ino_t ino);
-
/**
* The file system operations:
*
@@ -86,6 +70,24 @@ typedef int (*fuse_dirfil_t) (fuse_dirh_t h, const char *name, int type,
* is also a snapshot of the relevant wiki pages in the doc/ folder.
*/
struct fuse_operations {
+ /**
+ * Flag indicating that the path need not be calculated for
+ * the following operations:
+ *
+ * read, write, flush, release, fsync, readdir, releasedir,
+ * fsyncdir, ftruncate, fgetattr, lock, ioctl and poll
+ *
+ * If this flag is set then the path will not be calculaged even if the
+ * file wasn't unlinked. However the path can still be non-NULL if it
+ * needs to be calculated for some other reason.
+ */
+ unsigned int flag_nopath:1;
+
+ /**
+ * Reserved flags, don't set
+ */
+ unsigned int flag_reserved:31;
+
/** Get file attributes.
*
* Similar to stat(). The 'st_dev' and 'st_blksize' fields are
@@ -104,9 +106,6 @@ struct fuse_operations {
*/
int (*readlink) (const char *, char *, size_t);
- /* Deprecated, use readdir() instead */
- int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t);
-
/** Create a file node
*
* This is called for creation of all non-directory, non-symlink
@@ -147,12 +146,6 @@ struct fuse_operations {
/** Change the size of a file */
int (*truncate) (const char *, off_t);
- /** Change the access and/or modification times of a file
- *
- * Deprecated, use utimens() instead.
- */
- int (*utime) (const char *, struct utimbuf *);
-
/** File open operation
*
* No creation (O_CREAT, O_EXCL) and by default also no
@@ -282,16 +275,12 @@ struct fuse_operations {
/** Read directory
*
- * This supersedes the old getdir() interface. New applications
- * should use this.
- *
* 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.
+ * whole directory is read in a single readdir operation.
*
* 2) The readdir implementation keeps track of the offsets of the
* directory entries. It uses the offset parameter and always
@@ -454,43 +443,6 @@ struct fuse_operations {
int (*bmap) (const char *, size_t blocksize, uint64_t *idx);
/**
- * Flag indicating that the filesystem can accept a NULL path
- * as the first argument for the following operations:
- *
- * read, write, flush, release, fsync, readdir, releasedir,
- * fsyncdir, ftruncate, fgetattr, lock, ioctl and poll
- *
- * If this flag is set these operations continue to work on
- * unlinked files even if "-ohard_remove" option was specified.
- */
- unsigned int flag_nullpath_ok:1;
-
- /**
- * Flag indicating that the path need not be calculated for
- * the following operations:
- *
- * read, write, flush, release, fsync, readdir, releasedir,
- * fsyncdir, ftruncate, fgetattr, lock, ioctl and poll
- *
- * Closely related to flag_nullpath_ok, but if this flag is
- * set then the path will not be calculaged even if the file
- * wasn't unlinked. However the path can still be non-NULL if
- * it needs to be calculated for some other reason.
- */
- unsigned int flag_nopath:1;
-
- /**
- * Flag indicating that the filesystem accepts special
- * UTIME_NOW and UTIME_OMIT values in its utimens operation.
- */
- unsigned int flag_utime_omit_ok:1;
-
- /**
- * Reserved flags, don't set
- */
- unsigned int flag_reserved:29;
-
- /**
* Ioctl
*
* flags will have FUSE_IOCTL_COMPAT set for 32bit ioctls in
@@ -746,16 +698,6 @@ int fuse_getgroups(int size, gid_t list[]);
int fuse_interrupted(void);
/**
- * Obsolete, doesn't do anything
- *
- * @return -EINVAL
- */
-int fuse_invalidate(struct fuse *f, const char *path);
-
-/* Deprecated, don't use */
-int fuse_is_lib_option(const char *opt);
-
-/**
* The real main function
*
* Do not call this directly, use fuse_main()
@@ -964,93 +906,9 @@ void fuse_register_module(struct fuse_module *mod);
fuse_register_module(&mod); \
}
-
-/* ----------------------------------------------------------- *
- * Advanced API for event handling, don't worry about this... *
- * ----------------------------------------------------------- */
-
-/* NOTE: the following functions are deprecated, and will be removed
- from the 3.0 API. Use the lowlevel session functions instead */
-
-/** Function type used to process commands */
-typedef void (*fuse_processor_t)(struct fuse *, struct fuse_cmd *, void *);
-
-/** This is the part of fuse_main() before the event loop */
-struct fuse *fuse_setup(int argc, char *argv[],
- const struct fuse_operations *op, size_t op_size,
- char **mountpoint, int *multithreaded,
- void *user_data);
-
-/** This is the part of fuse_main() after the event loop */
-void fuse_teardown(struct fuse *fuse, char *mountpoint);
-
-/** Read a single command. If none are read, return NULL */
-struct fuse_cmd *fuse_read_cmd(struct fuse *f);
-
-/** Process a single command */
-void fuse_process_cmd(struct fuse *f, struct fuse_cmd *cmd);
-
-/** Multi threaded event loop, which calls the custom command
- processor function */
-int fuse_loop_mt_proc(struct fuse *f, fuse_processor_t proc, void *data);
-
-/** Return the exited flag, which indicates if fuse_exit() has been
- called */
-int fuse_exited(struct fuse *f);
-
-/** This function is obsolete and implemented as a no-op */
-void fuse_set_getcontext_func(struct fuse_context *(*func)(void));
-
/** Get session from fuse object */
struct fuse_session *fuse_get_session(struct fuse *f);
-/* ----------------------------------------------------------- *
- * Compatibility stuff *
- * ----------------------------------------------------------- */
-
-#if FUSE_USE_VERSION < 26
-# include "fuse_compat.h"
-# undef fuse_main
-# if FUSE_USE_VERSION == 25
-# define fuse_main(argc, argv, op) \
- fuse_main_real_compat25(argc, argv, op, sizeof(*(op)))
-# define fuse_new fuse_new_compat25
-# define fuse_setup fuse_setup_compat25
-# define fuse_teardown fuse_teardown_compat22
-# define fuse_operations fuse_operations_compat25
-# elif FUSE_USE_VERSION == 22
-# define fuse_main(argc, argv, op) \
- fuse_main_real_compat22(argc, argv, op, sizeof(*(op)))
-# define fuse_new fuse_new_compat22
-# define fuse_setup fuse_setup_compat22
-# define fuse_teardown fuse_teardown_compat22
-# define fuse_operations fuse_operations_compat22
-# define fuse_file_info fuse_file_info_compat
-# elif FUSE_USE_VERSION == 24
-# error Compatibility with high-level API version 24 not supported
-# else
-# define fuse_dirfil_t fuse_dirfil_t_compat
-# define __fuse_read_cmd fuse_read_cmd
-# define __fuse_process_cmd fuse_process_cmd
-# define __fuse_loop_mt fuse_loop_mt_proc
-# if FUSE_USE_VERSION == 21
-# define fuse_operations fuse_operations_compat2
-# define fuse_main fuse_main_compat2
-# define fuse_new fuse_new_compat2
-# define __fuse_setup fuse_setup_compat2
-# define __fuse_teardown fuse_teardown_compat22
-# define __fuse_exited fuse_exited
-# define __fuse_set_getcontext_func fuse_set_getcontext_func
-# else
-# define fuse_statfs fuse_statfs_compat1
-# define fuse_operations fuse_operations_compat1
-# define fuse_main fuse_main_compat1
-# define fuse_new fuse_new_compat1
-# define FUSE_DEBUG FUSE_DEBUG_COMPAT1
-# endif
-# endif
-#endif
-
#ifdef __cplusplus
}
#endif
diff --git a/include/fuse_common.h b/include/fuse_common.h
index a4d980d..af16203 100644
--- a/include/fuse_common.h
+++ b/include/fuse_common.h
@@ -1,5 +1,4 @@
-/*
- FUSE: Filesystem in Userspace
+/* FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
This program can be distributed under the terms of the GNU LGPLv2.
@@ -20,19 +19,14 @@
#include <sys/types.h>
/** Major version of FUSE library interface */
-#define FUSE_MAJOR_VERSION 2
+#define FUSE_MAJOR_VERSION 3
/** Minor version of FUSE library interface */
-#define FUSE_MINOR_VERSION 9
+#define FUSE_MINOR_VERSION 0
#define FUSE_MAKE_VERSION(maj, min) ((maj) * 10 + (min))
#define FUSE_VERSION FUSE_MAKE_VERSION(FUSE_MAJOR_VERSION, FUSE_MINOR_VERSION)
-/* This interface uses 64 bit off_t */
-#if _FILE_OFFSET_BITS != 64
-#error Please add -D_FILE_OFFSET_BITS=64 to your compile flags!
-#endif
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -85,6 +79,11 @@ struct fuse_file_info {
/** Lock owner id. Available in locking operations and flush */
uint64_t lock_owner;
+
+ /** Requested poll events. Available in ->poll. Only set on kernels
+ which support it. If unsupported, this field is set to zero.
+ Introduced in version 3.0 */
+ uint32_t poll_events;
};
/**
@@ -101,17 +100,20 @@ struct fuse_file_info {
* FUSE_CAP_SPLICE_READ: ability to use splice() to read from the fuse device
* FUSE_CAP_IOCTL_DIR: ioctl support on directories
*/
-#define FUSE_CAP_ASYNC_READ (1 << 0)
-#define FUSE_CAP_POSIX_LOCKS (1 << 1)
-#define FUSE_CAP_ATOMIC_O_TRUNC (1 << 3)
-#define FUSE_CAP_EXPORT_SUPPORT (1 << 4)
-#define FUSE_CAP_BIG_WRITES (1 << 5)
-#define FUSE_CAP_DONT_MASK (1 << 6)
-#define FUSE_CAP_SPLICE_WRITE (1 << 7)
-#define FUSE_CAP_SPLICE_MOVE (1 << 8)
-#define FUSE_CAP_SPLICE_READ (1 << 9)
-#define FUSE_CAP_FLOCK_LOCKS (1 << 10)
-#define FUSE_CAP_IOCTL_DIR (1 << 11)
+#define FUSE_CAP_ASYNC_READ (1 << 0)
+#define FUSE_CAP_POSIX_LOCKS (1 << 1)
+#define FUSE_CAP_ATOMIC_O_TRUNC (1 << 3)
+#define FUSE_CAP_EXPORT_SUPPORT (1 << 4)
+#define FUSE_CAP_BIG_WRITES (1 << 5)
+#define FUSE_CAP_DONT_MASK (1 << 6)
+#define FUSE_CAP_SPLICE_WRITE (1 << 7)
+#define FUSE_CAP_SPLICE_MOVE (1 << 8)
+#define FUSE_CAP_SPLICE_READ (1 << 9)
+#define FUSE_CAP_FLOCK_LOCKS (1 << 10)
+#define FUSE_CAP_IOCTL_DIR (1 << 11)
+#define FUSE_CAP_AUTO_INVAL_DATA (1 << 12)
+#define FUSE_CAP_READDIRPLUS (1 << 13)
+#define FUSE_CAP_READDIRPLUS_AUTO (1 << 14)
/**
* Ioctl flags
@@ -468,38 +470,26 @@ void fuse_remove_signal_handlers(struct fuse_session *se);
* Compatibility stuff *
* ----------------------------------------------------------- */
-#if FUSE_USE_VERSION < 26
-# ifdef __FreeBSD__
-# if FUSE_USE_VERSION < 25
-# error On FreeBSD API version 25 or greater must be used
-# endif
-# endif
-# include "fuse_common_compat.h"
-# undef FUSE_MINOR_VERSION
-# undef fuse_main
-# define fuse_unmount fuse_unmount_compat22
-# if FUSE_USE_VERSION == 25
-# define FUSE_MINOR_VERSION 5
-# define fuse_mount fuse_mount_compat25
-# elif FUSE_USE_VERSION == 24 || FUSE_USE_VERSION == 22
-# define FUSE_MINOR_VERSION 4
-# define fuse_mount fuse_mount_compat22
-# elif FUSE_USE_VERSION == 21
-# define FUSE_MINOR_VERSION 1
-# define fuse_mount fuse_mount_compat22
-# elif FUSE_USE_VERSION == 11
-# warning Compatibility with API version 11 is deprecated
-# undef FUSE_MAJOR_VERSION
-# define FUSE_MAJOR_VERSION 1
-# define FUSE_MINOR_VERSION 1
-# define fuse_mount fuse_mount_compat1
-# else
-# error Compatibility with API version other than 21, 22, 24, 25 and 11 not supported
-# endif
+#if !defined(FUSE_USE_VERSION) || FUSE_USE_VERSION < 30
+# error only API version 30 or greater is supported
#endif
#ifdef __cplusplus
}
#endif
+
+/*
+ * This interface uses 64 bit off_t.
+ *
+ * On 32bit systems please add -D_FILE_OFFSET_BITS=64 to your compile flags!
+ */
+
+#if defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 6) && !defined __cplusplus
+_Static_assert(sizeof(off_t) == 8, "fuse: off_t must be 64bit");
+#else
+struct _fuse_off_t_must_be_64bit_dummy_struct \
+ { unsigned _fuse_off_t_must_be_64bit:((sizeof(off_t) == 8) ? 1 : -1); };
+#endif
+
#endif /* _FUSE_COMMON_H_ */
diff --git a/include/fuse_common_compat.h b/include/fuse_common_compat.h
deleted file mode 100644
index 34440ff..0000000
--- a/include/fuse_common_compat.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
-
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
-*/
-
-/* these definitions provide source compatibility to prior versions.
- Do not include this file directly! */
-
-struct fuse_file_info_compat {
- int flags;
- unsigned long fh;
- int writepage;
- unsigned int direct_io : 1;
- unsigned int keep_cache : 1;
-};
-
-int fuse_mount_compat25(const char *mountpoint, struct fuse_args *args);
-
-int fuse_mount_compat22(const char *mountpoint, const char *opts);
-
-int fuse_mount_compat1(const char *mountpoint, const char *args[]);
-
-void fuse_unmount_compat22(const char *mountpoint);
diff --git a/include/fuse_compat.h b/include/fuse_compat.h
deleted file mode 100644
index e7497a9..0000000
--- a/include/fuse_compat.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
-
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
-*/
-
-/* these definitions provide source compatibility to prior versions.
- Do not include this file directly! */
-
-struct fuse_operations_compat25 {
- int (*getattr) (const char *, struct stat *);
- int (*readlink) (const char *, char *, size_t);
- int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t);
- int (*mknod) (const char *, mode_t, dev_t);
- int (*mkdir) (const char *, mode_t);
- int (*unlink) (const char *);
- int (*rmdir) (const char *);
- int (*symlink) (const char *, const char *);
- int (*rename) (const char *, const char *);
- int (*link) (const char *, const char *);
- int (*chmod) (const char *, mode_t);
- int (*chown) (const char *, uid_t, gid_t);
- int (*truncate) (const char *, off_t);
- int (*utime) (const char *, struct utimbuf *);
- int (*open) (const char *, struct fuse_file_info *);
- int (*read) (const char *, char *, size_t, off_t,
- struct fuse_file_info *);
- int (*write) (const char *, const char *, size_t, off_t,
- struct fuse_file_info *);
- int (*statfs) (const char *, struct statvfs *);
- int (*flush) (const char *, struct fuse_file_info *);
- int (*release) (const char *, struct fuse_file_info *);
- int (*fsync) (const char *, int, struct fuse_file_info *);
- int (*setxattr) (const char *, const char *, const char *, size_t, int);
- int (*getxattr) (const char *, const char *, char *, size_t);
- int (*listxattr) (const char *, char *, size_t);
- int (*removexattr) (const char *, const char *);
- int (*opendir) (const char *, struct fuse_file_info *);
- int (*readdir) (const char *, void *, fuse_fill_dir_t, off_t,
- struct fuse_file_info *);
- int (*releasedir) (const char *, struct fuse_file_info *);
- int (*fsyncdir) (const char *, int, struct fuse_file_info *);
- void *(*init) (void);
- void (*destroy) (void *);
- int (*access) (const char *, int);
- int (*create) (const char *, mode_t, struct fuse_file_info *);
- int (*ftruncate) (const char *, off_t, struct fuse_file_info *);
- int (*fgetattr) (const char *, struct stat *, struct fuse_file_info *);
-};
-
-struct fuse *fuse_new_compat25(int fd, struct fuse_args *args,
- const struct fuse_operations_compat25 *op,
- size_t op_size);
-
-int fuse_main_real_compat25(int argc, char *argv[],
- const struct fuse_operations_compat25 *op,
- size_t op_size);
-
-struct fuse *fuse_setup_compat25(int argc, char *argv[],
- const struct fuse_operations_compat25 *op,
- size_t op_size, char **mountpoint,
- int *multithreaded, int *fd);
-
-void fuse_teardown_compat22(struct fuse *fuse, int fd, char *mountpoint);
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-#include <sys/statfs.h>
-
-struct fuse_operations_compat22 {
- int (*getattr) (const char *, struct stat *);
- int (*readlink) (const char *, char *, size_t);
- int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t);
- int (*mknod) (const char *, mode_t, dev_t);
- int (*mkdir) (const char *, mode_t);
- int (*unlink) (const char *);
- int (*rmdir) (const char *);
- int (*symlink) (const char *, const char *);
- int (*rename) (const char *, const char *);
- int (*link) (const char *, const char *);
- int (*chmod) (const char *, mode_t);
- int (*chown) (const char *, uid_t, gid_t);
- int (*truncate) (const char *, off_t);
- int (*utime) (const char *, struct utimbuf *);
- int (*open) (const char *, struct fuse_file_info_compat *);
- int (*read) (const char *, char *, size_t, off_t,
- struct fuse_file_info_compat *);
- int (*write) (const char *, const char *, size_t, off_t,
- struct fuse_file_info_compat *);
- int (*statfs) (const char *, struct statfs *);
- int (*flush) (const char *, struct fuse_file_info_compat *);
- int (*release) (const char *, struct fuse_file_info_compat *);
- int (*fsync) (const char *, int, struct fuse_file_info_compat *);
- int (*setxattr) (const char *, const char *, const char *, size_t, int);
- int (*getxattr) (const char *, const char *, char *, size_t);
- int (*listxattr) (const char *, char *, size_t);
- int (*removexattr) (const char *, const char *);
- int (*opendir) (const char *, struct fuse_file_info_compat *);
- int (*readdir) (const char *, void *, fuse_fill_dir_t, off_t,
- struct fuse_file_info_compat *);
- int (*releasedir) (const char *, struct fuse_file_info_compat *);
- int (*fsyncdir) (const char *, int, struct fuse_file_info_compat *);
- void *(*init) (void);
- void (*destroy) (void *);
-};
-
-struct fuse *fuse_new_compat22(int fd, const char *opts,
- const struct fuse_operations_compat22 *op,
- size_t op_size);
-
-struct fuse *fuse_setup_compat22(int argc, char *argv[],
- const struct fuse_operations_compat22 *op,
- size_t op_size, char **mountpoint,
- int *multithreaded, int *fd);
-
-int fuse_main_real_compat22(int argc, char *argv[],
- const struct fuse_operations_compat22 *op,
- size_t op_size);
-
-typedef int (*fuse_dirfil_t_compat) (fuse_dirh_t h, const char *name, int type);
-struct fuse_operations_compat2 {
- int (*getattr) (const char *, struct stat *);
- int (*readlink) (const char *, char *, size_t);
- int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t_compat);
- int (*mknod) (const char *, mode_t, dev_t);
- int (*mkdir) (const char *, mode_t);
- int (*unlink) (const char *);
- int (*rmdir) (const char *);
- int (*symlink) (const char *, const char *);
- int (*rename) (const char *, const char *);
- int (*link) (const char *, const char *);
- int (*chmod) (const char *, mode_t);
- int (*chown) (const char *, uid_t, gid_t);
- int (*truncate) (const char *, off_t);
- int (*utime) (const char *, struct utimbuf *);
- int (*open) (const char *, int);
- int (*read) (const char *, char *, size_t, off_t);
- int (*write) (const char *, const char *, size_t, off_t);
- int (*statfs) (const char *, struct statfs *);
- int (*flush) (const char *);
- int (*release) (const char *, int);
- int (*fsync) (const char *, int);
- int (*setxattr) (const char *, const char *, const char *,
- size_t, int);
- int (*getxattr) (const char *, const char *, char *, size_t);
- int (*listxattr) (const char *, char *, size_t);
- int (*removexattr) (const char *, const char *);
-};
-
-int fuse_main_compat2(int argc, char *argv[],
- const struct fuse_operations_compat2 *op);
-
-struct fuse *fuse_new_compat2(int fd, const char *opts,
- const struct fuse_operations_compat2 *op);
-
-struct fuse *fuse_setup_compat2(int argc, char *argv[],
- const struct fuse_operations_compat2 *op,
- char **mountpoint, int *multithreaded, int *fd);
-
-struct fuse_statfs_compat1 {
- long block_size;
- long blocks;
- long blocks_free;
- long files;
- long files_free;
- long namelen;
-};
-
-struct fuse_operations_compat1 {
- int (*getattr) (const char *, struct stat *);
- int (*readlink) (const char *, char *, size_t);
- int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t_compat);
- int (*mknod) (const char *, mode_t, dev_t);
- int (*mkdir) (const char *, mode_t);
- int (*unlink) (const char *);
- int (*rmdir) (const char *);
- int (*symlink) (const char *, const char *);
- int (*rename) (const char *, const char *);
- int (*link) (const char *, const char *);
- int (*chmod) (const char *, mode_t);
- int (*chown) (const char *, uid_t, gid_t);
- int (*truncate) (const char *, off_t);
- int (*utime) (const char *, struct utimbuf *);
- int (*open) (const char *, int);
- int (*read) (const char *, char *, size_t, off_t);
- int (*write) (const char *, const char *, size_t, off_t);
- int (*statfs) (struct fuse_statfs_compat1 *);
- int (*release) (const char *, int);
- int (*fsync) (const char *, int);
-};
-
-#define FUSE_DEBUG_COMPAT1 (1 << 1)
-
-struct fuse *fuse_new_compat1(int fd, int flags,
- const struct fuse_operations_compat1 *op);
-
-void fuse_main_compat1(int argc, char *argv[],
- const struct fuse_operations_compat1 *op);
-
-#endif /* __FreeBSD__ || __NetBSD__ */
diff --git a/include/fuse_kernel.h b/include/fuse_kernel.h
index c632b58..4c43b44 100644
--- a/include/fuse_kernel.h
+++ b/include/fuse_kernel.h
@@ -83,17 +83,28 @@
*
* 7.19
* - add FUSE_FALLOCATE
+ *
+ * 7.20
+ * - add FUSE_AUTO_INVAL_DATA
+ *
+ * 7.21
+ * - add FUSE_READDIRPLUS
+ * - send the requested events in POLL request
*/
#ifndef _LINUX_FUSE_H
#define _LINUX_FUSE_H
-#include <sys/types.h>
+#ifdef __linux__
+#include <linux/types.h>
+#else
+#include <stdint.h>
#define __u64 uint64_t
#define __s64 int64_t
#define __u32 uint32_t
#define __s32 int32_t
#define __u16 uint16_t
+#endif
/*
* Version negotiation:
@@ -119,7 +130,7 @@
#define FUSE_KERNEL_VERSION 7
/** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 19
+#define FUSE_KERNEL_MINOR_VERSION 21
/** The node ID of the root inode */
#define FUSE_ROOT_ID 1
@@ -194,10 +205,21 @@ struct fuse_file_lock {
/**
* INIT request/reply flags
*
+ * FUSE_ASYNC_READ: asynchronous read requests
* FUSE_POSIX_LOCKS: remote locking for POSIX file locks
+ * FUSE_FILE_OPS: kernel sends file handle for fstat, etc... (not yet supported)
+ * FUSE_ATOMIC_O_TRUNC: handles the O_TRUNC open flag in the filesystem
* FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".."
+ * FUSE_BIG_WRITES: filesystem can handle write size larger than 4kB
* FUSE_DONT_MASK: don't apply umask to file mode on create operations
+ * FUSE_SPLICE_WRITE: kernel supports splice write on the device
+ * FUSE_SPLICE_MOVE: kernel supports splice move on the device
+ * FUSE_SPLICE_READ: kernel supports splice read on the device
* FUSE_FLOCK_LOCKS: remote locking for BSD style file locks
+ * FUSE_HAS_IOCTL_DIR: kernel supports ioctl on directories
+ * FUSE_AUTO_INVAL_DATA: automatically invalidate cached pages
+ * FUSE_DO_READDIRPLUS: do READDIRPLUS (READDIR+LOOKUP in one)
+ * FUSE_READDIRPLUS_AUTO: adaptive readdirplus
*/
#define FUSE_ASYNC_READ (1 << 0)
#define FUSE_POSIX_LOCKS (1 << 1)
@@ -206,7 +228,14 @@ struct fuse_file_lock {
#define FUSE_EXPORT_SUPPORT (1 << 4)
#define FUSE_BIG_WRITES (1 << 5)
#define FUSE_DONT_MASK (1 << 6)
+#define FUSE_SPLICE_WRITE (1 << 7)
+#define FUSE_SPLICE_MOVE (1 << 8)
+#define FUSE_SPLICE_READ (1 << 9)
#define FUSE_FLOCK_LOCKS (1 << 10)
+#define FUSE_HAS_IOCTL_DIR (1 << 11)
+#define FUSE_AUTO_INVAL_DATA (1 << 12)
+#define FUSE_DO_READDIRPLUS (1 << 13)
+#define FUSE_READDIRPLUS_AUTO (1 << 14)
/**
* CUSE INIT request/reply flags
@@ -313,6 +342,7 @@ enum fuse_opcode {
FUSE_NOTIFY_REPLY = 41,
FUSE_BATCH_FORGET = 42,
FUSE_FALLOCATE = 43,
+ FUSE_READDIRPLUS = 44,
/* CUSE specific operations */
CUSE_INIT = 4096,
@@ -594,7 +624,7 @@ struct fuse_poll_in {
__u64 fh;
__u64 kh;
__u32 flags;
- __u32 padding;
+ __u32 events;
};
struct fuse_poll_out {
@@ -644,6 +674,16 @@ struct fuse_dirent {
#define FUSE_DIRENT_SIZE(d) \
FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen)
+struct fuse_direntplus {
+ struct fuse_entry_out entry_out;
+ struct fuse_dirent dirent;
+};
+
+#define FUSE_NAME_OFFSET_DIRENTPLUS \
+ offsetof(struct fuse_direntplus, dirent.name)
+#define FUSE_DIRENTPLUS_SIZE(d) \
+ FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET_DIRENTPLUS + (d)->dirent.namelen)
+
struct fuse_notify_inval_inode_out {
__u64 ino;
__s64 off;
diff --git a/include/fuse_lowlevel.h b/include/fuse_lowlevel.h
index 2036717..0a1d5f5 100644
--- a/include/fuse_lowlevel.h
+++ b/include/fuse_lowlevel.h
@@ -44,7 +44,7 @@ extern "C" {
#define FUSE_ROOT_ID 1
/** Inode number type */
-typedef unsigned long fuse_ino_t;
+typedef uint64_t fuse_ino_t;
/** Request pointer type */
typedef struct fuse_req *fuse_req_t;
@@ -122,7 +122,7 @@ struct fuse_ctx {
};
struct fuse_forget_data {
- uint64_t ino;
+ fuse_ino_t ino;
uint64_t nlookup;
};
@@ -1016,6 +1016,32 @@ struct fuse_lowlevel_ops {
*/
void (*fallocate) (fuse_req_t req, fuse_ino_t ino, int mode,
off_t offset, off_t length, struct fuse_file_info *fi);
+
+ /**
+ * Read directory with attributes
+ *
+ * Send a buffer filled using fuse_add_direntry_plus(), with size not
+ * exceeding the requested size. Send an empty buffer on end of
+ * stream.
+ *
+ * fi->fh will contain the value set by the opendir method, or
+ * will be undefined if the opendir method didn't set any value.
+ *
+ * Introduced in version 3.0
+ *
+ * Valid replies:
+ * fuse_reply_buf
+ * fuse_reply_data
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number
+ * @param size maximum number of bytes to send
+ * @param off offset to continue reading the directory stream
+ * @param fi file information
+ */
+ void (*readdirplus) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
+ struct fuse_file_info *fi);
};
/**
@@ -1252,6 +1278,34 @@ size_t fuse_add_direntry(fuse_req_t req, char *buf, size_t bufsize,
off_t off);
/**
+ * Add a directory entry to the buffer with the attributes
+ *
+ * Buffer needs to be large enough to hold the entry. If it's not,
+ * then the entry is not filled in but the size of the entry is still
+ * returned. The caller can check this by comparing the bufsize
+ * parameter with the returned entry size. If the entry size is
+ * larger than the buffer size, the operation failed.
+ *
+ * From the 'stbuf' argument the st_ino field and bits 12-15 of the
+ * st_mode field are used. The other fields are ignored.
+ *
+ * Note: offsets do not necessarily represent physical offsets, and
+ * could be any marker, that enables the implementation to find a
+ * specific point in the directory stream.
+ *
+ * @param req request handle
+ * @param buf the point where the new entry will be added to the buffer
+ * @param bufsize remaining size of the buffer
+ * @param name the name of the entry
+ * @param e the directory entry
+ * @param off the offset of the next entry
+ * @return the space needed for the entry
+ */
+size_t fuse_add_direntry_plus(fuse_req_t req, char *buf, size_t bufsize,
+ const char *name,
+ const struct fuse_entry_param *e, off_t off);
+
+/**
* Reply to ask for data fetch and output buffer preparation. ioctl
* will be retried with the specified input data fetched and output
* buffer prepared.
@@ -1491,9 +1545,6 @@ int fuse_req_interrupted(fuse_req_t req);
* Filesystem setup *
* ----------------------------------------------------------- */
-/* Deprecated, don't use */
-int fuse_lowlevel_is_lib_option(const char *opt);
-
/**
* Create a low level session
*
@@ -1808,28 +1859,6 @@ int fuse_chan_send(struct fuse_chan *ch, const struct iovec iov[],
*/
void fuse_chan_destroy(struct fuse_chan *ch);
-/* ----------------------------------------------------------- *
- * Compatibility stuff *
- * ----------------------------------------------------------- */
-
-#if FUSE_USE_VERSION < 26
-# include "fuse_lowlevel_compat.h"
-# define fuse_chan_ops fuse_chan_ops_compat24
-# define fuse_chan_new fuse_chan_new_compat24
-# if FUSE_USE_VERSION == 25
-# define fuse_lowlevel_ops fuse_lowlevel_ops_compat25
-# define fuse_lowlevel_new fuse_lowlevel_new_compat25
-# elif FUSE_USE_VERSION == 24
-# define fuse_lowlevel_ops fuse_lowlevel_ops_compat
-# define fuse_lowlevel_new fuse_lowlevel_new_compat
-# define fuse_file_info fuse_file_info_compat
-# define fuse_reply_statfs fuse_reply_statfs_compat
-# define fuse_reply_open fuse_reply_open_compat
-# else
-# error Compatibility with low-level API version < 24 not supported
-# endif
-#endif
-
#ifdef __cplusplus
}
#endif
diff --git a/include/fuse_lowlevel_compat.h b/include/fuse_lowlevel_compat.h
deleted file mode 100644
index 8de220b..0000000
--- a/include/fuse_lowlevel_compat.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
-
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
-*/
-
-/* these definitions provide source compatibility to prior versions.
- Do not include this file directly! */
-
-struct fuse_lowlevel_ops_compat25 {
- void (*init) (void *userdata);
- void (*destroy) (void *userdata);
- void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
- void (*forget) (fuse_req_t req, fuse_ino_t ino, unsigned long nlookup);
- void (*getattr) (fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi);
- void (*setattr) (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
- int to_set, struct fuse_file_info *fi);
- void (*readlink) (fuse_req_t req, fuse_ino_t ino);
- void (*mknod) (fuse_req_t req, fuse_ino_t parent, const char *name,
- mode_t mode, dev_t rdev);
- void (*mkdir) (fuse_req_t req, fuse_ino_t parent, const char *name,
- mode_t mode);
- void (*unlink) (fuse_req_t req, fuse_ino_t parent, const char *name);
- void (*rmdir) (fuse_req_t req, fuse_ino_t parent, const char *name);
- void (*symlink) (fuse_req_t req, const char *link, fuse_ino_t parent,
- const char *name);
- void (*rename) (fuse_req_t req, fuse_ino_t parent, const char *name,
- fuse_ino_t newparent, const char *newname);
- void (*link) (fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
- const char *newname);
- void (*open) (fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi);
- void (*read) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
- struct fuse_file_info *fi);
- void (*write) (fuse_req_t req, fuse_ino_t ino, const char *buf,
- size_t size, off_t off, struct fuse_file_info *fi);
- void (*flush) (fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi);
- void (*release) (fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi);
- void (*fsync) (fuse_req_t req, fuse_ino_t ino, int datasync,
- struct fuse_file_info *fi);
- void (*opendir) (fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi);
- void (*readdir) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
- struct fuse_file_info *fi);
- void (*releasedir) (fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi);
- void (*fsyncdir) (fuse_req_t req, fuse_ino_t ino, int datasync,
- struct fuse_file_info *fi);
- void (*statfs) (fuse_req_t req);
- void (*setxattr) (fuse_req_t req, fuse_ino_t ino, const char *name,
- const char *value, size_t size, int flags);
- void (*getxattr) (fuse_req_t req, fuse_ino_t ino, const char *name,
- size_t size);
- void (*listxattr) (fuse_req_t req, fuse_ino_t ino, size_t size);
- void (*removexattr) (fuse_req_t req, fuse_ino_t ino, const char *name);
- void (*access) (fuse_req_t req, fuse_ino_t ino, int mask);
- void (*create) (fuse_req_t req, fuse_ino_t parent, const char *name,
- mode_t mode, struct fuse_file_info *fi);
-};
-
-struct fuse_session *fuse_lowlevel_new_compat25(struct fuse_args *args,
- const struct fuse_lowlevel_ops_compat25 *op,
- size_t op_size, void *userdata);
-
-size_t fuse_dirent_size(size_t namelen);
-
-char *fuse_add_dirent(char *buf, const char *name, const struct stat *stbuf,
- off_t off);
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-
-#include <sys/statfs.h>
-
-struct fuse_lowlevel_ops_compat {
- void (*init) (void *userdata);
- void (*destroy) (void *userdata);
- void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
- void (*forget) (fuse_req_t req, fuse_ino_t ino, unsigned long nlookup);
- void (*getattr) (fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info_compat *fi);
- void (*setattr) (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
- int to_set, struct fuse_file_info_compat *fi);
- void (*readlink) (fuse_req_t req, fuse_ino_t ino);
- void (*mknod) (fuse_req_t req, fuse_ino_t parent, const char *name,
- mode_t mode, dev_t rdev);
- void (*mkdir) (fuse_req_t req, fuse_ino_t parent, const char *name,
- mode_t mode);
- void (*unlink) (fuse_req_t req, fuse_ino_t parent, const char *name);
- void (*rmdir) (fuse_req_t req, fuse_ino_t parent, const char *name);
- void (*symlink) (fuse_req_t req, const char *link, fuse_ino_t parent,
- const char *name);
- void (*rename) (fuse_req_t req, fuse_ino_t parent, const char *name,
- fuse_ino_t newparent, const char *newname);
- void (*link) (fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
- const char *newname);
- void (*open) (fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info_compat *fi);
- void (*read) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
- struct fuse_file_info_compat *fi);
- void (*write) (fuse_req_t req, fuse_ino_t ino, const char *buf,
- size_t size, off_t off, struct fuse_file_info_compat *fi);
- void (*flush) (fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info_compat *fi);
- void (*release) (fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info_compat *fi);
- void (*fsync) (fuse_req_t req, fuse_ino_t ino, int datasync,
- struct fuse_file_info_compat *fi);
- void (*opendir) (fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info_compat *fi);
- void (*readdir) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
- struct fuse_file_info_compat *fi);
- void (*releasedir) (fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info_compat *fi);
- void (*fsyncdir) (fuse_req_t req, fuse_ino_t ino, int datasync,
- struct fuse_file_info_compat *fi);
- void (*statfs) (fuse_req_t req);
- void (*setxattr) (fuse_req_t req, fuse_ino_t ino, const char *name,
- const char *value, size_t size, int flags);
- void (*getxattr) (fuse_req_t req, fuse_ino_t ino, const char *name,
- size_t size);
- void (*listxattr) (fuse_req_t req, fuse_ino_t ino, size_t size);
- void (*removexattr) (fuse_req_t req, fuse_ino_t ino, const char *name);
- void (*access) (fuse_req_t req, fuse_ino_t ino, int mask);
- void (*create) (fuse_req_t req, fuse_ino_t parent, const char *name,
- mode_t mode, struct fuse_file_info_compat *fi);
-};
-
-int fuse_reply_statfs_compat(fuse_req_t req, const struct statfs *stbuf);
-
-int fuse_reply_open_compat(fuse_req_t req,
- const struct fuse_file_info_compat *fi);
-
-struct fuse_session *fuse_lowlevel_new_compat(const char *opts,
- const struct fuse_lowlevel_ops_compat *op,
- size_t op_size, void *userdata);
-
-#endif /* __FreeBSD__ || __NetBSD__ */
-
-struct fuse_chan_ops_compat24 {
- int (*receive)(struct fuse_chan *ch, char *buf, size_t size);
- int (*send)(struct fuse_chan *ch, const struct iovec iov[],
- size_t count);
- void (*destroy)(struct fuse_chan *ch);
-};
-
-struct fuse_chan *fuse_chan_new_compat24(struct fuse_chan_ops_compat24 *op,
- int fd, size_t bufsize, void *data);
-
-int fuse_chan_receive(struct fuse_chan *ch, char *buf, size_t size);
-struct fuse_chan *fuse_kern_chan_new(int fd);
diff --git a/include/fuse_opt.h b/include/fuse_opt.h
index add0a30..20653b1 100644
--- a/include/fuse_opt.h
+++ b/include/fuse_opt.h
@@ -70,8 +70,9 @@ extern "C" {
*
* 6) "-x %s", etc. Combination of 4) and 5)
*
- * If the format is "%s", memory is allocated for the string unlike
- * with scanf().
+ * If the format is "%s", memory is allocated for the string unlike with
+ * scanf(). The previous value (if non-NULL) stored at the this location is
+ * freed.
*/
struct fuse_opt {
/** Matching template and optional parameter formatting */
diff --git a/include/old/fuse.h b/include/old/fuse.h
deleted file mode 100644
index 3db0945..0000000
--- a/include/old/fuse.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- This header is for compatibility with older software using FUSE.
-
- Please use 'pkg-config --cflags fuse' to set include path. The
- correct usage is still '#include <fuse.h>', not '#include
- <fuse/fuse.h>'.
-*/
-
-#include "fuse/fuse.h"
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 3ec2401..8ec234a 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -1,7 +1,7 @@
## Process this file with automake to produce Makefile.in
AM_CPPFLAGS = -I$(top_srcdir)/include -DFUSERMOUNT_DIR=\"$(bindir)\" \
- -D_FILE_OFFSET_BITS=64 -D_REENTRANT -DFUSE_USE_VERSION=26
+ -D_FILE_OFFSET_BITS=64 -D_REENTRANT -DFUSE_USE_VERSION=30
lib_LTLIBRARIES = libfuse.la libulockmgr.la
@@ -36,7 +36,7 @@ libfuse_la_SOURCES = \
$(iconv_source) \
$(mount_source)
-libfuse_la_LDFLAGS = -pthread @libfuse_libs@ -version-number 2:9:2 \
+libfuse_la_LDFLAGS = -pthread @libfuse_libs@ -version-number 3:0:0 \
-Wl,--version-script,$(srcdir)/fuse_versionscript
if NETBSD
diff --git a/lib/cuse_lowlevel.c b/lib/cuse_lowlevel.c
index 402cf4b..c51a78e 100644
--- a/lib/cuse_lowlevel.c
+++ b/lib/cuse_lowlevel.c
@@ -11,7 +11,6 @@
#include "fuse_kernel.h"
#include "fuse_i.h"
#include "fuse_opt.h"
-#include "fuse_misc.h"
#include <stdio.h>
#include <string.h>
@@ -170,7 +169,7 @@ struct fuse_session *cuse_lowlevel_new(struct fuse_args *args,
lop.ioctl = clop->ioctl ? cuse_fll_ioctl : NULL;
lop.poll = clop->poll ? cuse_fll_poll : NULL;
- se = fuse_lowlevel_new_common(args, &lop, sizeof(lop), userdata);
+ se = fuse_lowlevel_new(args, &lop, sizeof(lop), userdata);
if (!se) {
free(cd);
return NULL;
diff --git a/lib/fuse.c b/lib/fuse.c
index 067d0dc..e2d48d3 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -15,8 +15,6 @@
#include "fuse_lowlevel.h"
#include "fuse_opt.h"
#include "fuse_misc.h"
-#include "fuse_common_compat.h"
-#include "fuse_compat.h"
#include "fuse_kernel.h"
#include <stdio.h>
@@ -82,7 +80,6 @@ struct fuse_fs {
struct fuse_operations op;
struct fuse_module *m;
void *user_data;
- int compat;
int debug;
};
@@ -145,8 +142,6 @@ struct fuse {
struct fuse_config conf;
int intr_installed;
struct fuse_fs *fs;
- int nullpath_ok;
- int utime_omit_ok;
struct lock_queue_element *lockq;
int pagesize;
struct list_head partial_slabs;
@@ -207,12 +202,6 @@ struct fuse_dh {
fuse_ino_t nodeid;
};
-/* old dir handle */
-struct fuse_dirhandle {
- fuse_fill_dir_t filler;
- void *buf;
-};
-
struct fuse_context_i {
struct fuse_context ctx;
fuse_req_t req;
@@ -1103,10 +1092,13 @@ static void debug_path(struct fuse *f, const char *msg, fuse_ino_t nodeid,
if (wr)
wnode = lookup_node(f, nodeid, name);
- if (wnode)
- fprintf(stderr, "%s %li (w)\n", msg, wnode->nodeid);
- else
- fprintf(stderr, "%s %li\n", msg, nodeid);
+ if (wnode) {
+ fprintf(stderr, "%s %llu (w)\n",
+ msg, (unsigned long long) wnode->nodeid);
+ } else {
+ fprintf(stderr, "%s %llu\n",
+ msg, (unsigned long long) nodeid);
+ }
}
}
@@ -1181,7 +1173,7 @@ static int get_path_nullok(struct fuse *f, fuse_ino_t nodeid, char **path)
*path = NULL;
} else {
err = get_path_common(f, nodeid, NULL, path, NULL);
- if (err == -ENOENT && f->nullpath_ok)
+ if (err == -ENOENT)
err = 0;
}
@@ -1463,129 +1455,6 @@ static inline void fuse_prepare_interrupt(struct fuse *f, fuse_req_t req,
fuse_do_prepare_interrupt(req, d);
}
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-
-static int fuse_compat_open(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
-{
- int err;
- if (!fs->compat || fs->compat >= 25)
- err = fs->op.open(path, fi);
- else if (fs->compat == 22) {
- struct fuse_file_info_compat tmp;
- memcpy(&tmp, fi, sizeof(tmp));
- err = ((struct fuse_operations_compat22 *) &fs->op)->open(path,
- &tmp);
- memcpy(fi, &tmp, sizeof(tmp));
- fi->fh = tmp.fh;
- } else
- err = ((struct fuse_operations_compat2 *) &fs->op)
- ->open(path, fi->flags);
- return err;
-}
-
-static int fuse_compat_release(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
-{
- if (!fs->compat || fs->compat >= 22)
- return fs->op.release(path, fi);
- else
- return ((struct fuse_operations_compat2 *) &fs->op)
- ->release(path, fi->flags);
-}
-
-static int fuse_compat_opendir(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
-{
- if (!fs->compat || fs->compat >= 25)
- return fs->op.opendir(path, fi);
- else {
- int err;
- struct fuse_file_info_compat tmp;
- memcpy(&tmp, fi, sizeof(tmp));
- err = ((struct fuse_operations_compat22 *) &fs->op)
- ->opendir(path, &tmp);
- memcpy(fi, &tmp, sizeof(tmp));
- fi->fh = tmp.fh;
- return err;
- }
-}
-
-static void convert_statfs_compat(struct fuse_statfs_compat1 *compatbuf,
- struct statvfs *stbuf)
-{
- stbuf->f_bsize = compatbuf->block_size;
- stbuf->f_blocks = compatbuf->blocks;
- stbuf->f_bfree = compatbuf->blocks_free;
- stbuf->f_bavail = compatbuf->blocks_free;
- stbuf->f_files = compatbuf->files;
- stbuf->f_ffree = compatbuf->files_free;
- stbuf->f_namemax = compatbuf->namelen;
-}
-
-static void convert_statfs_old(struct statfs *oldbuf, struct statvfs *stbuf)
-{
- stbuf->f_bsize = oldbuf->f_bsize;
- stbuf->f_blocks = oldbuf->f_blocks;
- stbuf->f_bfree = oldbuf->f_bfree;
- stbuf->f_bavail = oldbuf->f_bavail;
- stbuf->f_files = oldbuf->f_files;
- stbuf->f_ffree = oldbuf->f_ffree;
- stbuf->f_namemax = oldbuf->f_namelen;
-}
-
-static int fuse_compat_statfs(struct fuse_fs *fs, const char *path,
- struct statvfs *buf)
-{
- int err;
-
- if (!fs->compat || fs->compat >= 25) {
- err = fs->op.statfs(fs->compat == 25 ? "/" : path, buf);
- } else if (fs->compat > 11) {
- struct statfs oldbuf;
- err = ((struct fuse_operations_compat22 *) &fs->op)
- ->statfs("/", &oldbuf);
- if (!err)
- convert_statfs_old(&oldbuf, buf);
- } else {
- struct fuse_statfs_compat1 compatbuf;
- memset(&compatbuf, 0, sizeof(struct fuse_statfs_compat1));
- err = ((struct fuse_operations_compat1 *) &fs->op)
- ->statfs(&compatbuf);
- if (!err)
- convert_statfs_compat(&compatbuf, buf);
- }
- return err;
-}
-
-#else /* __FreeBSD__ || __NetBSD__ */
-
-static inline int fuse_compat_open(struct fuse_fs *fs, char *path,
- struct fuse_file_info *fi)
-{
- return fs->op.open(path, fi);
-}
-
-static inline int fuse_compat_release(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
-{
- return fs->op.release(path, fi);
-}
-
-static inline int fuse_compat_opendir(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
-{
- return fs->op.opendir(path, fi);
-}
-
-static inline int fuse_compat_statfs(struct fuse_fs *fs, const char *path,
- struct statvfs *buf)
-{
- return fs->op.statfs(fs->compat == 25 ? "/" : path, buf);
-}
-
-#endif /* __FreeBSD__ || __NetBSD__ */
-
int fuse_fs_getattr(struct fuse_fs *fs, const char *path, struct stat *buf)
{
fuse_get_context()->private_data = fs->user_data;
@@ -1695,7 +1564,7 @@ int fuse_fs_release(struct fuse_fs *fs, const char *path,
fi->flush ? "+flush" : "",
(unsigned long long) fi->fh, fi->flags);
- return fuse_compat_release(fs, path, fi);
+ return fs->op.release(path, fi);
} else {
return 0;
}
@@ -1712,10 +1581,10 @@ int fuse_fs_opendir(struct fuse_fs *fs, const char *path,
fprintf(stderr, "opendir flags: 0x%x %s\n", fi->flags,
path);
- err = fuse_compat_opendir(fs, path, fi);
+ err = fs->op.opendir(path, fi);
if (fs->debug && !err)
- fprintf(stderr, " opendir[%lli] flags: 0x%x %s\n",
+ fprintf(stderr, " opendir[%llu] flags: 0x%x %s\n",
(unsigned long long) fi->fh, fi->flags, path);
return err;
@@ -1735,10 +1604,10 @@ int fuse_fs_open(struct fuse_fs *fs, const char *path,
fprintf(stderr, "open flags: 0x%x %s\n", fi->flags,
path);
- err = fuse_compat_open(fs, path, fi);
+ err = fs->op.open(path, fi);
if (fs->debug && !err)
- fprintf(stderr, " open[%lli] flags: 0x%x %s\n",
+ fprintf(stderr, " open[%llu] flags: 0x%x %s\n",
(unsigned long long) fi->fh, fi->flags, path);
return err;
@@ -1957,7 +1826,7 @@ int fuse_fs_statfs(struct fuse_fs *fs, const char *path, struct statvfs *buf)
if (fs->debug)
fprintf(stderr, "statfs %s\n", path);
- return fuse_compat_statfs(fs, path, buf);
+ return fs->op.statfs(path, buf);
} else {
buf->f_namemax = 255;
buf->f_bsize = 512;
@@ -1980,20 +1849,6 @@ int fuse_fs_releasedir(struct fuse_fs *fs, const char *path,
}
}
-static int fill_dir_old(struct fuse_dirhandle *dh, const char *name, int type,
- ino_t ino)
-{
- int res;
- struct stat stbuf;
-
- memset(&stbuf, 0, sizeof(stbuf));
- stbuf.st_mode = type << 12;
- stbuf.st_ino = ino;
-
- res = dh->filler(dh->buf, name, &stbuf, 0);
- return res ? -ENOMEM : 0;
-}
-
int fuse_fs_readdir(struct fuse_fs *fs, const char *path, void *buf,
fuse_fill_dir_t filler, off_t off,
struct fuse_file_info *fi)
@@ -2006,16 +1861,6 @@ int fuse_fs_readdir(struct fuse_fs *fs, const char *path, void *buf,
(unsigned long long) off);
return fs->op.readdir(path, buf, filler, off, fi);
- } else if (fs->op.getdir) {
- struct fuse_dirhandle dh;
-
- if (fs->debug)
- fprintf(stderr, "getdir[%llu]\n",
- (unsigned long long) fi->fh);
-
- dh.filler = filler;
- dh.buf = buf;
- return fs->op.getdir(path, &dh, fill_dir_old);
} else {
return -ENOSYS;
}
@@ -2153,16 +1998,6 @@ int fuse_fs_utimens(struct fuse_fs *fs, const char *path,
tv[1].tv_sec, tv[1].tv_nsec);
return fs->op.utimens(path, tv);
- } else if(fs->op.utime) {
- struct utimbuf buf;
-
- if (fs->debug)
- fprintf(stderr, "utime %s %li %li\n", path,
- tv[0].tv_sec, tv[1].tv_sec);
-
- buf.actime = tv[0].tv_sec;
- buf.modtime = tv[1].tv_sec;
- return fs->op.utime(path, &buf);
} else {
return -ENOSYS;
}
@@ -2323,8 +2158,9 @@ int fuse_fs_poll(struct fuse_fs *fs, const char *path,
int res;
if (fs->debug)
- fprintf(stderr, "poll[%llu] ph: %p\n",
- (unsigned long long) fi->fh, ph);
+ fprintf(stderr, "poll[%llu] ph: %p, events 0x%x\n",
+ (unsigned long long) fi->fh, ph,
+ fi->poll_events);
res = fs->op.poll(path, fi, ph, reventsp);
@@ -2486,8 +2322,8 @@ static int lookup_path(struct fuse *f, fuse_ino_t nodeid,
}
set_stat(f, e->ino, &e->attr);
if (f->conf.debug)
- fprintf(stderr, " NODEID: %lu\n",
- (unsigned long) e->ino);
+ fprintf(stderr, " NODEID: %llu\n",
+ (unsigned long long) e->ino);
}
}
return res;
@@ -2495,9 +2331,12 @@ static int lookup_path(struct fuse *f, fuse_ino_t nodeid,
static struct fuse_context_i *fuse_get_context_internal(void)
{
- struct fuse_context_i *c;
+ return (struct fuse_context_i *) pthread_getspecific(fuse_context_key);
+}
- c = (struct fuse_context_i *) pthread_getspecific(fuse_context_key);
+static struct fuse_context_i *fuse_create_context(struct fuse *f)
+{
+ struct fuse_context_i *c = fuse_get_context_internal();
if (c == NULL) {
c = (struct fuse_context_i *)
calloc(1, sizeof(struct fuse_context_i));
@@ -2510,7 +2349,11 @@ static struct fuse_context_i *fuse_get_context_internal(void)
abort();
}
pthread_setspecific(fuse_context_key, c);
+ } else {
+ memset(c, 0, sizeof(*c));
}
+ c->ctx.fuse = f;
+
return c;
}
@@ -2550,10 +2393,9 @@ static void fuse_delete_context_key(void)
static struct fuse *req_fuse_prepare(fuse_req_t req)
{
- struct fuse_context_i *c = fuse_get_context_internal();
+ struct fuse_context_i *c = fuse_create_context(req_fuse(req));
const struct fuse_ctx *ctx = fuse_req_ctx(req);
c->req = req;
- c->ctx.fuse = req_fuse(req);
c->ctx.uid = ctx->uid;
c->ctx.gid = ctx->gid;
c->ctx.pid = ctx->pid;
@@ -2597,10 +2439,8 @@ void fuse_fs_init(struct fuse_fs *fs, struct fuse_conn_info *conn)
static void fuse_lib_init(void *data, struct fuse_conn_info *conn)
{
struct fuse *f = (struct fuse *) data;
- struct fuse_context_i *c = fuse_get_context_internal();
- memset(c, 0, sizeof(*c));
- c->ctx.fuse = f;
+ fuse_create_context(f);
conn->want |= FUSE_CAP_EXPORT_SUPPORT;
fuse_fs_init(f->fs, conn);
}
@@ -2618,10 +2458,8 @@ void fuse_fs_destroy(struct fuse_fs *fs)
static void fuse_lib_destroy(void *data)
{
struct fuse *f = (struct fuse *) data;
- struct fuse_context_i *c = fuse_get_context_internal();
- memset(c, 0, sizeof(*c));
- c->ctx.fuse = f;
+ fuse_create_context(f);
fuse_fs_destroy(f->fs);
f->fs = NULL;
}
@@ -2795,7 +2633,7 @@ static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
attr->st_size);
}
#ifdef HAVE_UTIMENSAT
- if (!err && f->utime_omit_ok &&
+ if (!err &&
(valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))) {
struct timespec tv[2];
@@ -3078,14 +2916,8 @@ static void fuse_do_release(struct fuse *f, fuse_ino_t ino, const char *path,
{
struct node *node;
int unlink_hidden = 0;
- const char *compatpath;
-
- if (path != NULL || f->nullpath_ok || f->conf.nopath)
- compatpath = path;
- else
- compatpath = "-";
- fuse_fs_release(f->fs, compatpath, fi);
+ fuse_fs_release(f->fs, path, fi);
pthread_mutex_lock(&f->lock);
node = get_node(f, ino);
@@ -3516,16 +3348,11 @@ static void fuse_lib_releasedir(fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info fi;
struct fuse_dh *dh = get_dirhandle(llfi, &fi);
char *path;
- const char *compatpath;
get_path_nullok(f, ino, &path);
- if (path != NULL || f->nullpath_ok || f->conf.nopath)
- compatpath = path;
- else
- compatpath = "-";
fuse_prepare_interrupt(f, req, &d);
- fuse_fs_releasedir(f->fs, compatpath, &fi);
+ fuse_fs_releasedir(f->fs, path, &fi);
fuse_finish_interrupt(f, req, &d);
free_path(f, ino, path);
@@ -4183,63 +4010,11 @@ int fuse_notify_poll(struct fuse_pollhandle *ph)
return fuse_lowlevel_notify_poll(ph);
}
-static void free_cmd(struct fuse_cmd *cmd)
-{
- free(cmd->buf);
- free(cmd);
-}
-
-void fuse_process_cmd(struct fuse *f, struct fuse_cmd *cmd)
-{
- fuse_session_process(f->se, cmd->buf, cmd->buflen, cmd->ch);
- free_cmd(cmd);
-}
-
-int fuse_exited(struct fuse *f)
-{
- return fuse_session_exited(f->se);
-}
-
struct fuse_session *fuse_get_session(struct fuse *f)
{
return f->se;
}
-static struct fuse_cmd *fuse_alloc_cmd(size_t bufsize)
-{
- struct fuse_cmd *cmd = (struct fuse_cmd *) malloc(sizeof(*cmd));
- if (cmd == NULL) {
- fprintf(stderr, "fuse: failed to allocate cmd\n");
- return NULL;
- }
- cmd->buf = (char *) malloc(bufsize);
- if (cmd->buf == NULL) {
- fprintf(stderr, "fuse: failed to allocate read buffer\n");
- free(cmd);
- return NULL;
- }
- return cmd;
-}
-
-struct fuse_cmd *fuse_read_cmd(struct fuse *f)
-{
- struct fuse_chan *ch = fuse_session_next_chan(f->se, NULL);
- size_t bufsize = fuse_chan_bufsize(ch);
- struct fuse_cmd *cmd = fuse_alloc_cmd(bufsize);
- if (cmd != NULL) {
- int res = fuse_chan_recv(&ch, cmd->buf, bufsize);
- if (res <= 0) {
- free_cmd(cmd);
- if (res < 0 && res != -EINTR && res != -EAGAIN)
- fuse_exit(f);
- return NULL;
- }
- cmd->buflen = res;
- cmd->ch = ch;
- }
- return cmd;
-}
-
static int fuse_session_loop_remember(struct fuse *f)
{
struct fuse_session *se = f->se;
@@ -4313,13 +4088,6 @@ int fuse_loop(struct fuse *f)
return fuse_session_loop(f->se);
}
-int fuse_invalidate(struct fuse *f, const char *path)
-{
- (void) f;
- (void) path;
- return -EINVAL;
-}
-
void fuse_exit(struct fuse *f)
{
fuse_session_exit(f->se);
@@ -4327,36 +4095,31 @@ void fuse_exit(struct fuse *f)
struct fuse_context *fuse_get_context(void)
{
- return &fuse_get_context_internal()->ctx;
-}
+ struct fuse_context_i *c = fuse_get_context_internal();
-/*
- * The size of fuse_context got extended, so need to be careful about
- * incompatibility (i.e. a new binary cannot work with an old
- * library).
- */
-struct fuse_context *fuse_get_context_compat22(void);
-struct fuse_context *fuse_get_context_compat22(void)
-{
- return &fuse_get_context_internal()->ctx;
+ if (c)
+ return &c->ctx;
+ else
+ return NULL;
}
-FUSE_SYMVER(".symver fuse_get_context_compat22,fuse_get_context@FUSE_2.2");
int fuse_getgroups(int size, gid_t list[])
{
- fuse_req_t req = fuse_get_context_internal()->req;
- return fuse_req_getgroups(req, size, list);
+ struct fuse_context_i *c = fuse_get_context_internal();
+ if (!c)
+ return -EINVAL;
+
+ return fuse_req_getgroups(c->req, size, list);
}
int fuse_interrupted(void)
{
- return fuse_req_interrupted(fuse_get_context_internal()->req);
-}
+ struct fuse_context_i *c = fuse_get_context_internal();
-void fuse_set_getcontext_func(struct fuse_context *(*func)(void))
-{
- (void) func;
- /* no-op */
+ if (c)
+ return fuse_req_interrupted(c->req);
+ else
+ return 0;
}
enum {
@@ -4458,12 +4221,6 @@ static int fuse_lib_opt_proc(void *data, const char *arg, int key,
return 1;
}
-int fuse_is_lib_option(const char *opt)
-{
- return fuse_lowlevel_is_lib_option(opt) ||
- fuse_opt_match(fuse_lib_opts, opt);
-}
-
static int fuse_init_intr_signal(int signum, int *installed)
{
struct sigaction old_sa;
@@ -4516,9 +4273,7 @@ static int fuse_push_module(struct fuse *f, const char *module,
}
newfs->m = m;
f->fs = newfs;
- f->nullpath_ok = newfs->op.flag_nullpath_ok && f->nullpath_ok;
f->conf.nopath = newfs->op.flag_nopath && f->conf.nopath;
- f->utime_omit_ok = newfs->op.flag_utime_omit_ok && f->utime_omit_ok;
return 0;
}
@@ -4588,9 +4343,9 @@ void fuse_stop_cleanup_thread(struct fuse *f)
}
}
-struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args,
- const struct fuse_operations *op,
- size_t op_size, void *user_data, int compat)
+struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args,
+ const struct fuse_operations *op,
+ size_t op_size, void *user_data)
{
struct fuse *f;
struct node *root;
@@ -4610,11 +4365,8 @@ struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args,
if (!fs)
goto out_free;
- fs->compat = compat;
f->fs = fs;
- f->nullpath_ok = fs->op.flag_nullpath_ok;
f->conf.nopath = fs->op.flag_nopath;
- f->utime_omit_ok = fs->op.flag_utime_omit_ok;
/* Oh f**k, this is ugly! */
if (!fs->op.lock) {
@@ -4662,12 +4414,7 @@ struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args,
f->conf.readdir_ino = 1;
#endif
- if (compat && compat <= 25) {
- if (fuse_sync_compat_args(args) == -1)
- goto out_free_fs;
- }
-
- f->se = fuse_lowlevel_new_common(args, &llop, sizeof(llop), f);
+ f->se = fuse_lowlevel_new(args, &llop, sizeof(llop), f);
if (f->se == NULL) {
if (f->conf.help)
fuse_lib_help_modules();
@@ -4677,9 +4424,7 @@ struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args,
fuse_session_add_chan(f->se, ch);
if (f->conf.debug) {
- fprintf(stderr, "nullpath_ok: %i\n", f->nullpath_ok);
fprintf(stderr, "nopath: %i\n", f->conf.nopath);
- fprintf(stderr, "utime_omit_ok: %i\n", f->utime_omit_ok);
}
/* Trace topmost layer by default */
@@ -4728,10 +4473,9 @@ out_free_name_table:
out_free_session:
fuse_session_destroy(f->se);
out_free_fs:
- /* Horrible compatibility hack to stop the destructor from being
- called on the filesystem without init being called first */
- fs->op.destroy = NULL;
- fuse_fs_destroy(f->fs);
+ if (f->fs->m)
+ fuse_put_module(f->fs->m);
+ free(f->fs);
free(f->conf.modules);
out_free:
free(f);
@@ -4741,13 +4485,6 @@ out:
return NULL;
}
-struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args,
- const struct fuse_operations *op, size_t op_size,
- void *user_data)
-{
- return fuse_new_common(ch, args, op, op_size, user_data, 0);
-}
-
void fuse_destroy(struct fuse *f)
{
size_t i;
@@ -4756,10 +4493,7 @@ void fuse_destroy(struct fuse *f)
fuse_restore_intr_signal(f->conf.intr_signal);
if (f->fs) {
- struct fuse_context_i *c = fuse_get_context_internal();
-
- memset(c, 0, sizeof(*c));
- c->ctx.fuse = f;
+ fuse_create_context(f);
for (i = 0; i < f->id_table.size; i++) {
struct node *node;
@@ -4798,19 +4532,6 @@ void fuse_destroy(struct fuse *f)
fuse_delete_context_key();
}
-static struct fuse *fuse_new_common_compat25(int fd, struct fuse_args *args,
- const struct fuse_operations *op,
- size_t op_size, int compat)
-{
- struct fuse *f = NULL;
- struct fuse_chan *ch = fuse_kern_chan_new(fd);
-
- if (ch)
- f = fuse_new_common(ch, args, op, op_size, NULL, compat);
-
- return f;
-}
-
/* called with fuse_context_lock held or during initialization (before
main() has been called) */
void fuse_register_module(struct fuse_module *mod)
@@ -4822,72 +4543,3 @@ void fuse_register_module(struct fuse_module *mod)
mod->next = fuse_modules;
fuse_modules = mod;
}
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-
-static struct fuse *fuse_new_common_compat(int fd, const char *opts,
- const struct fuse_operations *op,
- size_t op_size, int compat)
-{
- struct fuse *f;
- struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
-
- if (fuse_opt_add_arg(&args, "") == -1)
- return NULL;
- if (opts &&
- (fuse_opt_add_arg(&args, "-o") == -1 ||
- fuse_opt_add_arg(&args, opts) == -1)) {
- fuse_opt_free_args(&args);
- return NULL;
- }
- f = fuse_new_common_compat25(fd, &args, op, op_size, compat);
- fuse_opt_free_args(&args);
-
- return f;
-}
-
-struct fuse *fuse_new_compat22(int fd, const char *opts,
- const struct fuse_operations_compat22 *op,
- size_t op_size)
-{
- return fuse_new_common_compat(fd, opts, (struct fuse_operations *) op,
- op_size, 22);
-}
-
-struct fuse *fuse_new_compat2(int fd, const char *opts,
- const struct fuse_operations_compat2 *op)
-{
- return fuse_new_common_compat(fd, opts, (struct fuse_operations *) op,
- sizeof(struct fuse_operations_compat2),
- 21);
-}
-
-struct fuse *fuse_new_compat1(int fd, int flags,
- const struct fuse_operations_compat1 *op)
-{
- const char *opts = NULL;
- if (flags & FUSE_DEBUG_COMPAT1)
- opts = "debug";
- return fuse_new_common_compat(fd, opts, (struct fuse_operations *) op,
- sizeof(struct fuse_operations_compat1),
- 11);
-}
-
-FUSE_SYMVER(".symver fuse_exited,__fuse_exited@");
-FUSE_SYMVER(".symver fuse_process_cmd,__fuse_process_cmd@");
-FUSE_SYMVER(".symver fuse_read_cmd,__fuse_read_cmd@");
-FUSE_SYMVER(".symver fuse_set_getcontext_func,__fuse_set_getcontext_func@");
-FUSE_SYMVER(".symver fuse_new_compat2,fuse_new@");
-FUSE_SYMVER(".symver fuse_new_compat22,fuse_new@FUSE_2.2");
-
-#endif /* __FreeBSD__ || __NetBSD__ */
-
-struct fuse *fuse_new_compat25(int fd, struct fuse_args *args,
- const struct fuse_operations_compat25 *op,
- size_t op_size)
-{
- return fuse_new_common_compat25(fd, args, (struct fuse_operations *) op,
- op_size, 25);
-}
-
-FUSE_SYMVER(".symver fuse_new_compat25,fuse_new@FUSE_2.5");
diff --git a/lib/fuse_i.h b/lib/fuse_i.h
index 78f1467..ffcf062 100644
--- a/lib/fuse_i.h
+++ b/lib/fuse_i.h
@@ -71,6 +71,10 @@ struct fuse_ll {
int no_splice_write;
int no_splice_move;
int no_splice_read;
+ int auto_inval_data;
+ int no_auto_inval_data;
+ int no_readdirplus;
+ int no_readdirplus_auto;
struct fuse_lowlevel_ops op;
int got_init;
struct cuse_data *cuse_data;
@@ -87,25 +91,8 @@ struct fuse_ll {
struct fuse_notify_req notify_list;
};
-struct fuse_cmd {
- char *buf;
- size_t buflen;
- struct fuse_chan *ch;
-};
-
-struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args,
- const struct fuse_operations *op,
- size_t op_size, void *user_data, int compat);
-
-int fuse_sync_compat_args(struct fuse_args *args);
-
struct fuse_chan *fuse_kern_chan_new(int fd);
-struct fuse_session *fuse_lowlevel_new_common(struct fuse_args *args,
- const struct fuse_lowlevel_ops *op,
- size_t op_size, void *userdata);
-
-void fuse_kern_unmount_compat22(const char *mountpoint);
void fuse_kern_unmount(const char *mountpoint, int fd);
int fuse_kern_mount(const char *mountpoint, struct fuse_args *args);
@@ -113,16 +100,6 @@ int fuse_send_reply_iov_nofree(fuse_req_t req, int error, struct iovec *iov,
int count);
void fuse_free_req(fuse_req_t req);
-
-struct fuse *fuse_setup_common(int argc, char *argv[],
- const struct fuse_operations *op,
- size_t op_size,
- char **mountpoint,
- int *multithreaded,
- int *fd,
- void *user_data,
- int compat);
-
void cuse_lowlevel_init(fuse_req_t req, fuse_ino_t nodeide, const void *inarg);
int fuse_start_thread(pthread_t *thread_id, void *(*func)(void *), void *arg);
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
index 01efc6a..45cd5f3 100644
--- a/lib/fuse_lowlevel.c
+++ b/lib/fuse_lowlevel.c
@@ -13,8 +13,6 @@
#include "fuse_kernel.h"
#include "fuse_opt.h"
#include "fuse_misc.h"
-#include "fuse_common_compat.h"
-#include "fuse_lowlevel_compat.h"
#include <stdio.h>
#include <stdlib.h>
@@ -241,13 +239,13 @@ int fuse_reply_iov(fuse_req_t req, const struct iovec *iov, int count)
return res;
}
-size_t fuse_dirent_size(size_t namelen)
+static size_t fuse_dirent_size(size_t namelen)
{
return FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + namelen);
}
-char *fuse_add_dirent(char *buf, const char *name, const struct stat *stbuf,
- off_t off)
+static char *fuse_add_dirent(char *buf, const char *name,
+ const struct stat *stbuf, off_t off)
{
unsigned namelen = strlen(name);
unsigned entlen = FUSE_NAME_OFFSET + namelen;
@@ -341,6 +339,25 @@ static void fill_entry(struct fuse_entry_out *arg,
convert_stat(&e->attr, &arg->attr);
}
+size_t fuse_add_direntry_plus(fuse_req_t req, char *buf, size_t bufsize,
+ const char *name,
+ const struct fuse_entry_param *e, off_t off)
+{
+ struct fuse_entry_out *argp;
+ size_t entsize;
+
+ (void) req;
+ entsize = FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET_DIRENTPLUS +
+ fuse_dirent_size(strlen(name)));
+ if (entsize <= bufsize && buf){
+ argp = (struct fuse_entry_out *)buf;
+ memset(argp, 0, sizeof(*argp));
+ fill_entry(argp, e);
+ fuse_add_dirent(buf + sizeof(*argp), name, &(e->attr), off);
+ }
+ return entsize;
+}
+
static void fill_open(struct fuse_open_out *arg,
const struct fuse_file_info *f)
{
@@ -485,6 +502,31 @@ static void fuse_ll_pipe_free(struct fuse_ll_pipe *llp)
}
#ifdef HAVE_SPLICE
+#if !defined(HAVE_PIPE2) || !defined(O_CLOEXEC)
+static int fuse_pipe(int fds[2])
+{
+ int rv = pipe(fds);
+
+ if (rv == -1)
+ return rv;
+
+ if (fcntl(fds[0], F_SETFL, O_NONBLOCK) == -1 ||
+ fcntl(fds[1], F_SETFL, O_NONBLOCK) == -1 ||
+ fcntl(fds[0], F_SETFD, FD_CLOEXEC) == -1 ||
+ fcntl(fds[1], F_SETFD, FD_CLOEXEC) == -1) {
+ close(fds[0]);
+ close(fds[1]);
+ rv = -1;
+ }
+ return rv;
+}
+#else
+static int fuse_pipe(int fds[2])
+{
+ return pipe2(fds, O_CLOEXEC | O_NONBLOCK);
+}
+#endif
+
static struct fuse_ll_pipe *fuse_ll_get_pipe(struct fuse_ll *f)
{
struct fuse_ll_pipe *llp = pthread_getspecific(f->pipe_key);
@@ -495,20 +537,12 @@ static struct fuse_ll_pipe *fuse_ll_get_pipe(struct fuse_ll *f)
if (llp == NULL)
return NULL;
- res = pipe(llp->pipe);
+ res = fuse_pipe(llp->pipe);
if (res == -1) {
free(llp);
return NULL;
}
- if (fcntl(llp->pipe[0], F_SETFL, O_NONBLOCK) == -1 ||
- fcntl(llp->pipe[1], F_SETFL, O_NONBLOCK) == -1) {
- close(llp->pipe[0]);
- close(llp->pipe[1]);
- free(llp);
- return NULL;
- }
-
/*
*the default size is 16 pages on linux
*/
@@ -1391,6 +1425,21 @@ static void do_readdir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
fuse_reply_err(req, ENOSYS);
}
+static void do_readdirplus(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
+{
+ struct fuse_read_in *arg = (struct fuse_read_in *) inarg;
+ struct fuse_file_info fi;
+
+ memset(&fi, 0, sizeof(fi));
+ fi.fh = arg->fh;
+ fi.fh_old = fi.fh;
+
+ if (req->f->op.readdirplus)
+ req->f->op.readdirplus(req, nodeid, arg->size, arg->offset, &fi);
+ else
+ fuse_reply_err(req, ENOSYS);
+}
+
static void do_releasedir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
struct fuse_release_in *arg = (struct fuse_release_in *) inarg;
@@ -1697,6 +1746,7 @@ static void do_poll(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
memset(&fi, 0, sizeof(fi));
fi.fh = arg->fh;
fi.fh_old = fi.fh;
+ fi.poll_events = arg->events;
if (req->f->op.poll) {
struct fuse_pollhandle *ph = NULL;
@@ -1789,6 +1839,12 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
f->conn.capable |= FUSE_CAP_DONT_MASK;
if (arg->flags & FUSE_FLOCK_LOCKS)
f->conn.capable |= FUSE_CAP_FLOCK_LOCKS;
+ if (arg->flags & FUSE_AUTO_INVAL_DATA)
+ f->conn.capable |= FUSE_CAP_AUTO_INVAL_DATA;
+ if (arg->flags & FUSE_DO_READDIRPLUS)
+ f->conn.capable |= FUSE_CAP_READDIRPLUS;
+ if (arg->flags & FUSE_READDIRPLUS_AUTO)
+ f->conn.capable |= FUSE_CAP_READDIRPLUS_AUTO;
} else {
f->conn.async_read = 0;
f->conn.max_readahead = 0;
@@ -1819,6 +1875,13 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
f->conn.want |= FUSE_CAP_FLOCK_LOCKS;
if (f->big_writes)
f->conn.want |= FUSE_CAP_BIG_WRITES;
+ if (f->auto_inval_data)
+ f->conn.want |= FUSE_CAP_AUTO_INVAL_DATA;
+ if (f->op.readdirplus && !f->no_readdirplus) {
+ f->conn.want |= FUSE_CAP_READDIRPLUS;
+ if (!f->no_readdirplus_auto)
+ f->conn.want |= FUSE_CAP_READDIRPLUS_AUTO;
+ }
if (bufsize < FUSE_MIN_READ_BUFFER) {
fprintf(stderr, "fuse: warning: buffer size too small: %zu\n",
@@ -1840,7 +1903,12 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
f->conn.want &= ~FUSE_CAP_SPLICE_WRITE;
if (f->no_splice_move)
f->conn.want &= ~FUSE_CAP_SPLICE_MOVE;
-
+ if (f->no_auto_inval_data)
+ f->conn.want &= ~FUSE_CAP_AUTO_INVAL_DATA;
+ if (f->no_readdirplus)
+ f->conn.want &= ~FUSE_CAP_READDIRPLUS;
+ if (f->no_readdirplus_auto)
+ f->conn.want &= ~FUSE_CAP_READDIRPLUS_AUTO;
if (f->conn.async_read || (f->conn.want & FUSE_CAP_ASYNC_READ))
outarg.flags |= FUSE_ASYNC_READ;
if (f->conn.want & FUSE_CAP_POSIX_LOCKS)
@@ -1855,6 +1923,12 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
outarg.flags |= FUSE_DONT_MASK;
if (f->conn.want & FUSE_CAP_FLOCK_LOCKS)
outarg.flags |= FUSE_FLOCK_LOCKS;
+ if (f->conn.want & FUSE_CAP_AUTO_INVAL_DATA)
+ outarg.flags |= FUSE_AUTO_INVAL_DATA;
+ if (f->conn.want & FUSE_CAP_READDIRPLUS)
+ outarg.flags |= FUSE_DO_READDIRPLUS;
+ if (f->conn.want & FUSE_CAP_READDIRPLUS_AUTO)
+ outarg.flags |= FUSE_READDIRPLUS_AUTO;
outarg.max_readahead = f->conn.max_readahead;
outarg.max_write = f->conn.max_write;
if (f->conn.proto_minor >= 13) {
@@ -2202,21 +2276,6 @@ const struct fuse_ctx *fuse_req_ctx(fuse_req_t req)
return &req->ctx;
}
-/*
- * The size of fuse_ctx got extended, so need to be careful about
- * incompatibility (i.e. a new binary cannot work with an old
- * library).
- */
-const struct fuse_ctx *fuse_req_ctx_compat24(fuse_req_t req);
-const struct fuse_ctx *fuse_req_ctx_compat24(fuse_req_t req)
-{
- return fuse_req_ctx(req);
-}
-#ifndef __NetBSD__
-FUSE_SYMVER(".symver fuse_req_ctx_compat24,fuse_req_ctx@FUSE_2.4");
-#endif
-
-
void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func,
void *data)
{
@@ -2286,6 +2345,7 @@ static struct {
[FUSE_DESTROY] = { do_destroy, "DESTROY" },
[FUSE_NOTIFY_REPLY] = { (void *) 1, "NOTIFY_REPLY" },
[FUSE_BATCH_FORGET] = { do_batch_forget, "BATCH_FORGET" },
+ [FUSE_READDIRPLUS] = { do_readdirplus, "READDIRPLUS"},
[CUSE_INIT] = { cuse_lowlevel_init, "CUSE_INIT" },
};
@@ -2351,10 +2411,10 @@ static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf,
if (f->debug) {
fprintf(stderr,
- "unique: %llu, opcode: %s (%i), nodeid: %lu, insize: %zu, pid: %u\n",
+ "unique: %llu, opcode: %s (%i), nodeid: %llu, insize: %zu, pid: %u\n",
(unsigned long long) in->unique,
opname((enum fuse_opcode) in->opcode), in->opcode,
- (unsigned long) in->nodeid, buf->size, in->pid);
+ (unsigned long long) in->nodeid, buf->size, in->pid);
}
req = fuse_ll_alloc_req(f);
@@ -2394,7 +2454,8 @@ static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf,
in->opcode != FUSE_WRITE && in->opcode != FUSE_FSYNC &&
in->opcode != FUSE_RELEASE && in->opcode != FUSE_READDIR &&
in->opcode != FUSE_FSYNCDIR && in->opcode != FUSE_RELEASEDIR &&
- in->opcode != FUSE_NOTIFY_REPLY)
+ in->opcode != FUSE_NOTIFY_REPLY &&
+ in->opcode != FUSE_READDIRPLUS)
goto reply_err;
err = ENOSYS;
@@ -2491,6 +2552,13 @@ static const struct fuse_opt fuse_ll_opts[] = {
{ "no_splice_move", offsetof(struct fuse_ll, no_splice_move), 1},
{ "splice_read", offsetof(struct fuse_ll, splice_read), 1},
{ "no_splice_read", offsetof(struct fuse_ll, no_splice_read), 1},
+ { "auto_inval_data", offsetof(struct fuse_ll, auto_inval_data), 1},
+ { "no_auto_inval_data", offsetof(struct fuse_ll, no_auto_inval_data), 1},
+ { "readdirplus=no", offsetof(struct fuse_ll, no_readdirplus), 1},
+ { "readdirplus=yes", offsetof(struct fuse_ll, no_readdirplus), 0},
+ { "readdirplus=yes", offsetof(struct fuse_ll, no_readdirplus_auto), 1},
+ { "readdirplus=auto", offsetof(struct fuse_ll, no_readdirplus), 0},
+ { "readdirplus=auto", offsetof(struct fuse_ll, no_readdirplus_auto), 0},
FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_DISCARD),
FUSE_OPT_KEY("-h", KEY_HELP),
FUSE_OPT_KEY("--help", KEY_HELP),
@@ -2522,6 +2590,8 @@ static void fuse_ll_help(void)
" -o [no_]splice_write use splice to write to the fuse device\n"
" -o [no_]splice_move move data while splicing to the fuse device\n"
" -o [no_]splice_read use splice to read from the fuse device\n"
+" -o [no_]auto_inval_data use automatic kernel cache invalidation logic\n"
+" -o readdirplus=S control readdirplus use (yes|no|auto)\n"
);
}
@@ -2546,11 +2616,6 @@ static int fuse_ll_opt_proc(void *data, const char *arg, int key,
return -1;
}
-int fuse_lowlevel_is_lib_option(const char *opt)
-{
- return fuse_opt_match(fuse_ll_opts, opt);
-}
-
static void fuse_ll_destroy(void *data)
{
struct fuse_ll *f = (struct fuse_ll *) data;
@@ -2690,14 +2755,9 @@ static int fuse_ll_receive_buf(struct fuse_session *se, struct fuse_buf *buf,
#endif
-/*
- * always call fuse_lowlevel_new_common() internally, to work around a
- * misfeature in the FreeBSD runtime linker, which links the old
- * version of a symbol to internal references.
- */
-struct fuse_session *fuse_lowlevel_new_common(struct fuse_args *args,
- const struct fuse_lowlevel_ops *op,
- size_t op_size, void *userdata)
+struct fuse_session *fuse_lowlevel_new(struct fuse_args *args,
+ const struct fuse_lowlevel_ops *op,
+ size_t op_size, void *userdata)
{
int err;
struct fuse_ll *f;
@@ -2763,14 +2823,6 @@ out:
return NULL;
}
-
-struct fuse_session *fuse_lowlevel_new(struct fuse_args *args,
- const struct fuse_lowlevel_ops *op,
- size_t op_size, void *userdata)
-{
- return fuse_lowlevel_new_common(args, op, op_size, userdata);
-}
-
#ifdef linux
int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[])
{
@@ -2839,129 +2891,3 @@ int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[])
return -ENOSYS;
}
#endif
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-
-static void fill_open_compat(struct fuse_open_out *arg,
- const struct fuse_file_info_compat *f)
-{
- arg->fh = f->fh;
- if (f->direct_io)
- arg->open_flags |= FOPEN_DIRECT_IO;
- if (f->keep_cache)
- arg->open_flags |= FOPEN_KEEP_CACHE;
-}
-
-static void convert_statfs_compat(const struct statfs *compatbuf,
- struct statvfs *buf)
-{
- buf->f_bsize = compatbuf->f_bsize;
- buf->f_blocks = compatbuf->f_blocks;
- buf->f_bfree = compatbuf->f_bfree;
- buf->f_bavail = compatbuf->f_bavail;
- buf->f_files = compatbuf->f_files;
- buf->f_ffree = compatbuf->f_ffree;
- buf->f_namemax = compatbuf->f_namelen;
-}
-
-int fuse_reply_open_compat(fuse_req_t req,
- const struct fuse_file_info_compat *f)
-{
- struct fuse_open_out arg;
-
- memset(&arg, 0, sizeof(arg));
- fill_open_compat(&arg, f);
- return send_reply_ok(req, &arg, sizeof(arg));
-}
-
-int fuse_reply_statfs_compat(fuse_req_t req, const struct statfs *stbuf)
-{
- struct statvfs newbuf;
-
- memset(&newbuf, 0, sizeof(newbuf));
- convert_statfs_compat(stbuf, &newbuf);
-
- return fuse_reply_statfs(req, &newbuf);
-}
-
-struct fuse_session *fuse_lowlevel_new_compat(const char *opts,
- const struct fuse_lowlevel_ops_compat *op,
- size_t op_size, void *userdata)
-{
- struct fuse_session *se;
- struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
-
- if (opts &&
- (fuse_opt_add_arg(&args, "") == -1 ||
- fuse_opt_add_arg(&args, "-o") == -1 ||
- fuse_opt_add_arg(&args, opts) == -1)) {
- fuse_opt_free_args(&args);
- return NULL;
- }
- se = fuse_lowlevel_new(&args, (const struct fuse_lowlevel_ops *) op,
- op_size, userdata);
- fuse_opt_free_args(&args);
-
- return se;
-}
-
-struct fuse_ll_compat_conf {
- unsigned max_read;
- int set_max_read;
-};
-
-static const struct fuse_opt fuse_ll_opts_compat[] = {
- { "max_read=", offsetof(struct fuse_ll_compat_conf, set_max_read), 1 },
- { "max_read=%u", offsetof(struct fuse_ll_compat_conf, max_read), 0 },
- FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_KEEP),
- FUSE_OPT_END
-};
-
-int fuse_sync_compat_args(struct fuse_args *args)
-{
- struct fuse_ll_compat_conf conf;
-
- memset(&conf, 0, sizeof(conf));
- if (fuse_opt_parse(args, &conf, fuse_ll_opts_compat, NULL) == -1)
- return -1;
-
- if (fuse_opt_insert_arg(args, 1, "-osync_read"))
- return -1;
-
- if (conf.set_max_read) {
- char tmpbuf[64];
-
- sprintf(tmpbuf, "-omax_readahead=%u", conf.max_read);
- if (fuse_opt_insert_arg(args, 1, tmpbuf) == -1)
- return -1;
- }
- return 0;
-}
-
-FUSE_SYMVER(".symver fuse_reply_statfs_compat,fuse_reply_statfs@FUSE_2.4");
-FUSE_SYMVER(".symver fuse_reply_open_compat,fuse_reply_open@FUSE_2.4");
-FUSE_SYMVER(".symver fuse_lowlevel_new_compat,fuse_lowlevel_new@FUSE_2.4");
-
-#else /* __FreeBSD__ || __NetBSD__ */
-
-int fuse_sync_compat_args(struct fuse_args *args)
-{
- (void) args;
- return 0;
-}
-
-#endif /* __FreeBSD__ || __NetBSD__ */
-
-struct fuse_session *fuse_lowlevel_new_compat25(struct fuse_args *args,
- const struct fuse_lowlevel_ops_compat25 *op,
- size_t op_size, void *userdata)
-{
- if (fuse_sync_compat_args(args) == -1)
- return NULL;
-
- return fuse_lowlevel_new_common(args,
- (const struct fuse_lowlevel_ops *) op,
- op_size, userdata);
-}
-
-FUSE_SYMVER(".symver fuse_lowlevel_new_compat25,fuse_lowlevel_new@FUSE_2.5");
diff --git a/lib/fuse_misc.h b/lib/fuse_misc.h
index eedf0e0..f102ba3 100644
--- a/lib/fuse_misc.h
+++ b/lib/fuse_misc.h
@@ -9,17 +9,6 @@
#include "config.h"
#include <pthread.h>
-/*
- Versioned symbols cannot be used in some cases because it
- - confuse the dynamic linker in uClibc
- - not supported on MacOSX (in MachO binary format)
-*/
-#if (!defined(__UCLIBC__) && !defined(__APPLE__))
-#define FUSE_SYMVER(x) __asm__(x)
-#else
-#define FUSE_SYMVER(x)
-#endif
-
#ifndef USE_UCLIBC
#define fuse_mutex_init(mut) pthread_mutex_init(mut, NULL)
#else
diff --git a/lib/fuse_mt.c b/lib/fuse_mt.c
index f6dbe71..ee38b28 100644
--- a/lib/fuse_mt.c
+++ b/lib/fuse_mt.c
@@ -6,105 +6,9 @@
See the file COPYING.LIB.
*/
-#include "fuse_i.h"
-#include "fuse_misc.h"
+#include "fuse.h"
#include "fuse_lowlevel.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <pthread.h>
-#include <assert.h>
-
-struct procdata {
- struct fuse *f;
- struct fuse_chan *prevch;
- struct fuse_session *prevse;
- fuse_processor_t proc;
- void *data;
-};
-
-static void mt_session_proc(void *data, const char *buf, size_t len,
- struct fuse_chan *ch)
-{
- struct procdata *pd = (struct procdata *) data;
- struct fuse_cmd *cmd = *(struct fuse_cmd **) buf;
-
- (void) len;
- (void) ch;
- pd->proc(pd->f, cmd, pd->data);
-}
-
-static void mt_session_exit(void *data, int val)
-{
- struct procdata *pd = (struct procdata *) data;
- if (val)
- fuse_session_exit(pd->prevse);
- else
- fuse_session_reset(pd->prevse);
-}
-
-static int mt_session_exited(void *data)
-{
- struct procdata *pd = (struct procdata *) data;
- return fuse_session_exited(pd->prevse);
-}
-
-static int mt_chan_receive(struct fuse_chan **chp, char *buf, size_t size)
-{
- struct fuse_cmd *cmd;
- struct procdata *pd = (struct procdata *) fuse_chan_data(*chp);
-
- assert(size >= sizeof(cmd));
-
- cmd = fuse_read_cmd(pd->f);
- if (cmd == NULL)
- return 0;
-
- *(struct fuse_cmd **) buf = cmd;
-
- return sizeof(cmd);
-}
-
-int fuse_loop_mt_proc(struct fuse *f, fuse_processor_t proc, void *data)
-{
- int res;
- struct procdata pd;
- struct fuse_session *prevse = fuse_get_session(f);
- struct fuse_session *se;
- struct fuse_chan *prevch = fuse_session_next_chan(prevse, NULL);
- struct fuse_chan *ch;
- struct fuse_session_ops sop = {
- .exit = mt_session_exit,
- .exited = mt_session_exited,
- .process = mt_session_proc,
- };
- struct fuse_chan_ops cop = {
- .receive = mt_chan_receive,
- };
-
- pd.f = f;
- pd.prevch = prevch;
- pd.prevse = prevse;
- pd.proc = proc;
- pd.data = data;
-
- se = fuse_session_new(&sop, &pd);
- if (se == NULL)
- return -1;
-
- ch = fuse_chan_new(&cop, fuse_chan_fd(prevch),
- sizeof(struct fuse_cmd *), &pd);
- if (ch == NULL) {
- fuse_session_destroy(se);
- return -1;
- }
- fuse_session_add_chan(se, ch);
- res = fuse_session_loop_mt(se);
- fuse_session_destroy(se);
- return res;
-}
-
int fuse_loop_mt(struct fuse *f)
{
if (f == NULL)
@@ -118,5 +22,3 @@ int fuse_loop_mt(struct fuse *f)
fuse_stop_cleanup_thread(f);
return res;
}
-
-FUSE_SYMVER(".symver fuse_loop_mt_proc,__fuse_loop_mt@");
diff --git a/lib/fuse_opt.c b/lib/fuse_opt.c
index a2118ce..15f9e21 100644
--- a/lib/fuse_opt.c
+++ b/lib/fuse_opt.c
@@ -92,13 +92,6 @@ int fuse_opt_insert_arg(struct fuse_args *args, int pos, const char *arg)
return fuse_opt_insert_arg_common(args, pos, arg);
}
-int fuse_opt_insert_arg_compat(struct fuse_args *args, int pos,
- const char *arg);
-int fuse_opt_insert_arg_compat(struct fuse_args *args, int pos, const char *arg)
-{
- return fuse_opt_insert_arg_common(args, pos, arg);
-}
-
static int next_arg(struct fuse_opt_context *ctx, const char *opt)
{
if (ctx->argctr + 1 >= ctx->argc) {
@@ -211,11 +204,13 @@ static int process_opt_param(void *var, const char *format, const char *param,
{
assert(format[0] == '%');
if (format[1] == 's') {
+ char **s = var;
char *copy = strdup(param);
if (!copy)
return alloc_failed();
- *(char **) var = copy;
+ free(*s);
+ *s = copy;
} else {
if (sscanf(param, format, var) != 1) {
fprintf(stderr, "fuse: invalid parameter in option `%s'\n", arg);
@@ -421,6 +416,3 @@ int fuse_opt_parse(struct fuse_args *args, void *data,
fuse_opt_free_args(&ctx.outargs);
return res;
}
-
-/* This symbol version was mistakenly added to the version script */
-FUSE_SYMVER(".symver fuse_opt_insert_arg_compat,fuse_opt_insert_arg@FUSE_2.5");
diff --git a/lib/fuse_session.c b/lib/fuse_session.c
index c55f250..ccd11c3 100644
--- a/lib/fuse_session.c
+++ b/lib/fuse_session.c
@@ -8,8 +8,6 @@
#include "fuse_i.h"
#include "fuse_misc.h"
-#include "fuse_common_compat.h"
-#include "fuse_lowlevel_compat.h"
#include <stdio.h>
#include <stdlib.h>
@@ -27,8 +25,6 @@ struct fuse_chan {
size_t bufsize;
void *data;
-
- int compat;
};
struct fuse_session *fuse_session_new(struct fuse_session_ops *op, void *data)
@@ -144,9 +140,8 @@ void *fuse_session_data(struct fuse_session *se)
return se->data;
}
-static struct fuse_chan *fuse_chan_new_common(struct fuse_chan_ops *op, int fd,
- size_t bufsize, void *data,
- int compat)
+struct fuse_chan *fuse_chan_new(struct fuse_chan_ops *op, int fd,
+ size_t bufsize, void *data)
{
struct fuse_chan *ch = (struct fuse_chan *) malloc(sizeof(*ch));
if (ch == NULL) {
@@ -159,24 +154,10 @@ static struct fuse_chan *fuse_chan_new_common(struct fuse_chan_ops *op, int fd,
ch->fd = fd;
ch->bufsize = bufsize;
ch->data = data;
- ch->compat = compat;
return ch;
}
-struct fuse_chan *fuse_chan_new(struct fuse_chan_ops *op, int fd,
- size_t bufsize, void *data)
-{
- return fuse_chan_new_common(op, fd, bufsize, data, 0);
-}
-
-struct fuse_chan *fuse_chan_new_compat24(struct fuse_chan_ops_compat24 *op,
- int fd, size_t bufsize, void *data)
-{
- return fuse_chan_new_common((struct fuse_chan_ops *) op, fd, bufsize,
- data, 24);
-}
-
int fuse_chan_fd(struct fuse_chan *ch)
{
return ch->fd;
@@ -200,19 +181,8 @@ struct fuse_session *fuse_chan_session(struct fuse_chan *ch)
int fuse_chan_recv(struct fuse_chan **chp, char *buf, size_t size)
{
struct fuse_chan *ch = *chp;
- if (ch->compat)
- return ((struct fuse_chan_ops_compat24 *) &ch->op)
- ->receive(ch, buf, size);
- else
- return ch->op.receive(chp, buf, size);
-}
-int fuse_chan_receive(struct fuse_chan *ch, char *buf, size_t size)
-{
- int res;
-
- res = fuse_chan_recv(&ch, buf, size);
- return res >= 0 ? res : (res != -EINTR && res != -EAGAIN) ? -1 : 0;
+ return ch->op.receive(chp, buf, size);
}
int fuse_chan_send(struct fuse_chan *ch, const struct iovec iov[], size_t count)
@@ -227,7 +197,3 @@ void fuse_chan_destroy(struct fuse_chan *ch)
ch->op.destroy(ch);
free(ch);
}
-
-#ifndef __FreeBSD__
-FUSE_SYMVER(".symver fuse_chan_new_compat24,fuse_chan_new@FUSE_2.4");
-#endif
diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript
index 8d91887..cfff5de 100644
--- a/lib/fuse_versionscript
+++ b/lib/fuse_versionscript
@@ -1,38 +1,15 @@
-FUSE_2.2 {
+FUSE_3.0 {
global:
fuse_destroy;
fuse_exit;
- fuse_exited;
- fuse_invalidate;
- fuse_is_lib_option;
fuse_loop;
fuse_loop_mt;
- fuse_loop_mt_proc;
- fuse_main;
- fuse_main_compat1;
- fuse_main_compat2;
- fuse_mount_compat1;
- fuse_new_compat1;
- fuse_new_compat2;
- fuse_process_cmd;
- fuse_read_cmd;
- fuse_set_getcontext_func;
- fuse_setup_compat2;
-};
-
-FUSE_2.4 {
- global:
- fuse_add_dirent;
fuse_chan_bufsize;
fuse_chan_data;
fuse_chan_destroy;
fuse_chan_fd;
- fuse_chan_receive;
fuse_chan_send;
fuse_chan_session;
- fuse_dirent_size;
- fuse_kern_chan_new;
- fuse_lowlevel_is_lib_option;
fuse_reply_attr;
fuse_reply_buf;
fuse_reply_entry;
@@ -52,14 +29,6 @@ FUSE_2.4 {
fuse_session_next_chan;
fuse_session_process;
fuse_session_reset;
-} FUSE_2.2;
-
-FUSE_2.5 {
- global:
- fuse_lowlevel_new_compat;
- fuse_main_real_compat22;
- fuse_mount_compat22;
- fuse_new_compat22;
fuse_opt_parse;
fuse_opt_add_opt;
fuse_opt_add_arg;
@@ -69,45 +38,25 @@ FUSE_2.5 {
fuse_remove_signal_handlers;
fuse_reply_create;
fuse_reply_open;
- fuse_reply_open_compat;
fuse_reply_statfs;
- fuse_reply_statfs_compat;
- fuse_setup_compat22;
fuse_set_signal_handlers;
-} FUSE_2.4;
-
-FUSE_2.6 {
- global:
fuse_add_direntry;
+ fuse_add_direntry_plus;
fuse_chan_new;
- fuse_chan_new_compat24;
fuse_chan_recv;
fuse_daemonize;
fuse_get_session;
fuse_interrupted;
fuse_lowlevel_new;
- fuse_lowlevel_new_compat25;
fuse_main_real;
- fuse_main_real_compat25;
fuse_mount;
- fuse_mount_compat25;
fuse_new;
- fuse_new_compat25;
fuse_opt_insert_arg;
fuse_reply_lock;
fuse_req_interrupt_func;
fuse_req_interrupted;
fuse_session_remove_chan;
- fuse_setup;
- fuse_setup_compat25;
- fuse_teardown;
- fuse_teardown_compat22;
fuse_unmount;
- fuse_unmount_compat22;
-} FUSE_2.5;
-
-FUSE_2.7 {
- global:
fuse_fs_access;
fuse_fs_bmap;
fuse_fs_chmod;
@@ -148,15 +97,7 @@ FUSE_2.7 {
fuse_register_module;
fuse_reply_iov;
fuse_version;
-} FUSE_2.6;
-
-FUSE_2.7.5 {
- global:
fuse_reply_bmap;
-} FUSE_2.7;
-
-FUSE_2.8 {
- global:
cuse_lowlevel_new;
cuse_lowlevel_main;
cuse_lowlevel_setup;
@@ -178,10 +119,6 @@ FUSE_2.8 {
fuse_req_ctx;
fuse_req_getgroups;
fuse_session_data;
-} FUSE_2.7.5;
-
-FUSE_2.9 {
- global:
fuse_buf_copy;
fuse_buf_size;
fuse_fs_read_buf;
@@ -196,12 +133,8 @@ FUSE_2.9 {
fuse_clean_cache;
fuse_lowlevel_notify_delete;
fuse_fs_flock;
-} FUSE_2.8;
-
-FUSE_2.9.1 {
- global:
fuse_fs_fallocate;
local:
*;
-} FUSE_2.9;
+};
diff --git a/lib/helper.c b/lib/helper.c
index ace19dd..8ee66df 100644
--- a/lib/helper.c
+++ b/lib/helper.c
@@ -11,7 +11,6 @@
#include "fuse_misc.h"
#include "fuse_opt.h"
#include "fuse_lowlevel.h"
-#include "fuse_common_compat.h"
#include <stdio.h>
#include <stdlib.h>
@@ -211,12 +210,13 @@ int fuse_daemonize(int foreground)
if (nullfd > 2)
close(nullfd);
}
+ } else {
+ (void) chdir("/");
}
return 0;
}
-static struct fuse_chan *fuse_mount_common(const char *mountpoint,
- struct fuse_args *args)
+struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args)
{
struct fuse_chan *ch;
int fd;
@@ -231,7 +231,7 @@ static struct fuse_chan *fuse_mount_common(const char *mountpoint,
close(fd);
} while (fd >= 0 && fd <= 2);
- fd = fuse_mount_compat25(mountpoint, args);
+ fd = fuse_kern_mount(mountpoint, args);
if (fd == -1)
return NULL;
@@ -242,12 +242,7 @@ static struct fuse_chan *fuse_mount_common(const char *mountpoint,
return ch;
}
-struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args)
-{
- return fuse_mount_common(mountpoint, args);
-}
-
-static void fuse_unmount_common(const char *mountpoint, struct fuse_chan *ch)
+void fuse_unmount(const char *mountpoint, struct fuse_chan *ch)
{
int fd = ch ? fuse_chan_fd(ch) : -1;
fuse_kern_unmount(mountpoint, fd);
@@ -255,19 +250,9 @@ static void fuse_unmount_common(const char *mountpoint, struct fuse_chan *ch)
fuse_chan_destroy(ch);
}
-void fuse_unmount(const char *mountpoint, struct fuse_chan *ch)
-{
- fuse_unmount_common(mountpoint, ch);
-}
-
-struct fuse *fuse_setup_common(int argc, char *argv[],
- const struct fuse_operations *op,
- size_t op_size,
- char **mountpoint,
- int *multithreaded,
- int *fd,
- void *user_data,
- int compat)
+static struct fuse *fuse_setup(int argc, char *argv[],
+ const struct fuse_operations *op, size_t op_size,
+ char **mountpoint, int *multithreaded, void *user_data)
{
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
struct fuse_chan *ch;
@@ -279,13 +264,13 @@ struct fuse *fuse_setup_common(int argc, char *argv[],
if (res == -1)
return NULL;
- ch = fuse_mount_common(*mountpoint, &args);
+ ch = fuse_mount(*mountpoint, &args);
if (!ch) {
fuse_opt_free_args(&args);
goto err_free;
}
- fuse = fuse_new_common(ch, &args, op, op_size, user_data, compat);
+ fuse = fuse_new(ch, &args, op, op_size, user_data);
fuse_opt_free_args(&args);
if (fuse == NULL)
goto err_unmount;
@@ -298,13 +283,10 @@ struct fuse *fuse_setup_common(int argc, char *argv[],
if (res == -1)
goto err_unmount;
- if (fd)
- *fd = fuse_chan_fd(ch);
-
return fuse;
err_unmount:
- fuse_unmount_common(*mountpoint, ch);
+ fuse_unmount(*mountpoint, ch);
if (fuse)
fuse_destroy(fuse);
err_free:
@@ -312,40 +294,26 @@ err_free:
return NULL;
}
-struct fuse *fuse_setup(int argc, char *argv[],
- const struct fuse_operations *op, size_t op_size,
- char **mountpoint, int *multithreaded, void *user_data)
-{
- return fuse_setup_common(argc, argv, op, op_size, mountpoint,
- multithreaded, NULL, user_data, 0);
-}
-
-static void fuse_teardown_common(struct fuse *fuse, char *mountpoint)
+static void fuse_teardown(struct fuse *fuse, char *mountpoint)
{
struct fuse_session *se = fuse_get_session(fuse);
struct fuse_chan *ch = fuse_session_next_chan(se, NULL);
fuse_remove_signal_handlers(se);
- fuse_unmount_common(mountpoint, ch);
+ fuse_unmount(mountpoint, ch);
fuse_destroy(fuse);
free(mountpoint);
}
-void fuse_teardown(struct fuse *fuse, char *mountpoint)
-{
- fuse_teardown_common(fuse, mountpoint);
-}
-
-static int fuse_main_common(int argc, char *argv[],
- const struct fuse_operations *op, size_t op_size,
- void *user_data, int compat)
+int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,
+ size_t op_size, void *user_data)
{
struct fuse *fuse;
char *mountpoint;
int multithreaded;
int res;
- fuse = fuse_setup_common(argc, argv, op, op_size, &mountpoint,
- &multithreaded, NULL, user_data, compat);
+ fuse = fuse_setup(argc, argv, op, op_size, &mountpoint,
+ &multithreaded, user_data);
if (fuse == NULL)
return 1;
@@ -354,125 +322,15 @@ static int fuse_main_common(int argc, char *argv[],
else
res = fuse_loop(fuse);
- fuse_teardown_common(fuse, mountpoint);
+ fuse_teardown(fuse, mountpoint);
if (res == -1)
return 1;
return 0;
}
-int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,
- size_t op_size, void *user_data)
-{
- return fuse_main_common(argc, argv, op, op_size, user_data, 0);
-}
-
-#undef fuse_main
-int fuse_main(void);
-int fuse_main(void)
-{
- fprintf(stderr, "fuse_main(): This function does not exist\n");
- return -1;
-}
-
int fuse_version(void)
{
return FUSE_VERSION;
}
-#include "fuse_compat.h"
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-
-struct fuse *fuse_setup_compat22(int argc, char *argv[],
- const struct fuse_operations_compat22 *op,
- size_t op_size, char **mountpoint,
- int *multithreaded, int *fd)
-{
- return fuse_setup_common(argc, argv, (struct fuse_operations *) op,
- op_size, mountpoint, multithreaded, fd, NULL,
- 22);
-}
-
-struct fuse *fuse_setup_compat2(int argc, char *argv[],
- const struct fuse_operations_compat2 *op,
- char **mountpoint, int *multithreaded,
- int *fd)
-{
- return fuse_setup_common(argc, argv, (struct fuse_operations *) op,
- sizeof(struct fuse_operations_compat2),
- mountpoint, multithreaded, fd, NULL, 21);
-}
-
-int fuse_main_real_compat22(int argc, char *argv[],
- const struct fuse_operations_compat22 *op,
- size_t op_size)
-{
- return fuse_main_common(argc, argv, (struct fuse_operations *) op,
- op_size, NULL, 22);
-}
-
-void fuse_main_compat1(int argc, char *argv[],
- const struct fuse_operations_compat1 *op)
-{
- fuse_main_common(argc, argv, (struct fuse_operations *) op,
- sizeof(struct fuse_operations_compat1), NULL, 11);
-}
-
-int fuse_main_compat2(int argc, char *argv[],
- const struct fuse_operations_compat2 *op)
-{
- return fuse_main_common(argc, argv, (struct fuse_operations *) op,
- sizeof(struct fuse_operations_compat2), NULL,
- 21);
-}
-
-int fuse_mount_compat1(const char *mountpoint, const char *args[])
-{
- /* just ignore mount args for now */
- (void) args;
- return fuse_mount_compat22(mountpoint, NULL);
-}
-
-FUSE_SYMVER(".symver fuse_setup_compat2,__fuse_setup@");
-FUSE_SYMVER(".symver fuse_setup_compat22,fuse_setup@FUSE_2.2");
-FUSE_SYMVER(".symver fuse_teardown,__fuse_teardown@");
-FUSE_SYMVER(".symver fuse_main_compat2,fuse_main@");
-FUSE_SYMVER(".symver fuse_main_real_compat22,fuse_main_real@FUSE_2.2");
-
-#endif /* __FreeBSD__ || __NetBSD__ */
-
-
-struct fuse *fuse_setup_compat25(int argc, char *argv[],
- const struct fuse_operations_compat25 *op,
- size_t op_size, char **mountpoint,
- int *multithreaded, int *fd)
-{
- return fuse_setup_common(argc, argv, (struct fuse_operations *) op,
- op_size, mountpoint, multithreaded, fd, NULL,
- 25);
-}
-
-int fuse_main_real_compat25(int argc, char *argv[],
- const struct fuse_operations_compat25 *op,
- size_t op_size)
-{
- return fuse_main_common(argc, argv, (struct fuse_operations *) op,
- op_size, NULL, 25);
-}
-
-void fuse_teardown_compat22(struct fuse *fuse, int fd, char *mountpoint)
-{
- (void) fd;
- fuse_teardown_common(fuse, mountpoint);
-}
-
-int fuse_mount_compat25(const char *mountpoint, struct fuse_args *args)
-{
- return fuse_kern_mount(mountpoint, args);
-}
-
-FUSE_SYMVER(".symver fuse_setup_compat25,fuse_setup@FUSE_2.5");
-FUSE_SYMVER(".symver fuse_teardown_compat22,fuse_teardown@FUSE_2.2");
-FUSE_SYMVER(".symver fuse_main_real_compat25,fuse_main_real@FUSE_2.5");
-FUSE_SYMVER(".symver fuse_mount_compat25,fuse_mount@FUSE_2.5");
diff --git a/lib/modules/iconv.c b/lib/modules/iconv.c
index 89b22e4..bc3694e 100644
--- a/lib/modules/iconv.c
+++ b/lib/modules/iconv.c
@@ -6,7 +6,7 @@
See the file COPYING.LIB
*/
-#define FUSE_USE_VERSION 26
+#define FUSE_USE_VERSION 30
#include <fuse.h>
#include <stdio.h>
@@ -631,7 +631,6 @@ static const struct fuse_operations iconv_oper = {
.flock = iconv_flock,
.bmap = iconv_bmap,
- .flag_nullpath_ok = 1,
.flag_nopath = 1,
};
diff --git a/lib/modules/subdir.c b/lib/modules/subdir.c
index 76a53fa..52b91e1 100644
--- a/lib/modules/subdir.c
+++ b/lib/modules/subdir.c
@@ -6,7 +6,7 @@
See the file COPYING.LIB
*/
-#define FUSE_USE_VERSION 26
+#define FUSE_USE_VERSION 30
#include <fuse.h>
#include <stdio.h>
@@ -614,7 +614,6 @@ static const struct fuse_operations subdir_oper = {
.flock = subdir_flock,
.bmap = subdir_bmap,
- .flag_nullpath_ok = 1,
.flag_nopath = 1,
};
diff --git a/lib/mount.c b/lib/mount.c
index 6a9da9e..4f74841 100644
--- a/lib/mount.c
+++ b/lib/mount.c
@@ -10,7 +10,6 @@
#include "fuse_i.h"
#include "fuse_misc.h"
#include "fuse_opt.h"
-#include "fuse_common_compat.h"
#include "mount_util.h"
#include <stdio.h>
@@ -98,6 +97,10 @@ static const struct fuse_opt fuse_mount_opts[] = {
FUSE_OPT_KEY("large_read", KEY_KERN_OPT),
FUSE_OPT_KEY("blksize=", KEY_KERN_OPT),
FUSE_OPT_KEY("default_permissions", KEY_KERN_OPT),
+ FUSE_OPT_KEY("context=", KEY_KERN_OPT),
+ FUSE_OPT_KEY("fscontext=", KEY_KERN_OPT),
+ FUSE_OPT_KEY("defcontext=", KEY_KERN_OPT),
+ FUSE_OPT_KEY("rootcontext=", KEY_KERN_OPT),
FUSE_OPT_KEY("max_read=", KEY_KERN_OPT),
FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_KEEP),
FUSE_OPT_KEY("user=", KEY_MTAB_OPT),
@@ -333,11 +336,6 @@ void fuse_kern_unmount(const char *mountpoint, int fd)
waitpid(pid, NULL, 0);
}
-void fuse_unmount_compat22(const char *mountpoint)
-{
- fuse_kern_unmount(mountpoint, -1);
-}
-
static int fuse_mount_fusermount(const char *mountpoint, struct mount_opts *mo,
const char *opts, int quiet)
{
@@ -408,14 +406,9 @@ static int fuse_mount_fusermount(const char *mountpoint, struct mount_opts *mo,
return rv;
}
-int fuse_mount_compat22(const char *mountpoint, const char *opts)
-{
- struct mount_opts mo;
- memset(&mo, 0, sizeof(mo));
- mo.flags = MS_NOSUID | MS_NODEV;
-
- return fuse_mount_fusermount(mountpoint, &mo, opts, 0);
-}
+#ifndef O_CLOEXEC
+#define O_CLOEXEC 0
+#endif
static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
const char *mnt_opts)
@@ -453,7 +446,7 @@ static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
return -2;
}
- fd = open(devname, O_RDWR);
+ fd = open(devname, O_RDWR | O_CLOEXEC);
if (fd == -1) {
if (errno == ENODEV || errno == ENOENT)
fprintf(stderr, "fuse: device not found, try 'modprobe fuse' first\n");
@@ -462,6 +455,8 @@ static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
devname, strerror(errno));
return -1;
}
+ if (!O_CLOEXEC)
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
snprintf(tmp, sizeof(tmp), "fd=%i,rootmode=%o,user_id=%i,group_id=%i",
fd, stbuf.st_mode & S_IFMT, getuid(), getgid());
@@ -631,6 +626,3 @@ out:
free(mo.mtab_opts);
return res;
}
-
-FUSE_SYMVER(".symver fuse_mount_compat22,fuse_mount@FUSE_2.2");
-FUSE_SYMVER(".symver fuse_unmount_compat22,fuse_unmount@FUSE_2.2");
diff --git a/lib/mount_bsd.c b/lib/mount_bsd.c
index 62443ac..9ee74fb 100644
--- a/lib/mount_bsd.c
+++ b/lib/mount_bsd.c
@@ -384,5 +384,3 @@ out:
free(mo.kernel_opts);
return res;
}
-
-FUSE_SYMVER(".symver fuse_unmount_compat22,fuse_unmount@FUSE_2.2");
diff --git a/test/stracedecode.c b/test/stracedecode.c
index 27b883c..940438a 100644
--- a/test/stracedecode.c
+++ b/test/stracedecode.c
@@ -41,6 +41,7 @@ static struct {
[FUSE_INTERRUPT] = { "INTERRUPT" },
[FUSE_BMAP] = { "BMAP" },
[FUSE_DESTROY] = { "DESTROY" },
+ [FUSE_READDIRPLUS] = { "READDIRPLUS" },
};
#define FUSE_MAXOP (sizeof(fuse_ll_ops) / sizeof(fuse_ll_ops[0]))