backward compatibility
authorMiklos Szeredi <miklos@szeredi.hu>
Sat, 4 Dec 2004 00:40:50 +0000 (00:40 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Sat, 4 Dec 2004 00:40:50 +0000 (00:40 +0000)
12 files changed:
ChangeLog
configure.in
include/Makefile.am
include/fuse.h
include/fuse_compat.h [new file with mode: 0644]
kernel/configure.ac
lib/Makefile.am
lib/fuse.c
lib/fuse_i.h
lib/fuse_versionscript [new file with mode: 0644]
lib/helper.c
lib/mount.c

index 5ec4bacfe0cbf4bab01decbc01d6dd44b5e1698e..28bb9ce4c31a57c1755da8ef9d8ea311ebed0139 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2004-12-03  Miklos Szeredi <miklos@szeredi.hu>
+
+       * Add source compatibility to 2.1 and 1.1 APIs.  To select betwen
+       versions simply define FUSE_USE_VERSION to 22, 21 or 11 before
+       including the fuse header
+
+       * Add binary compatibility to 2.1 version of library with symbol
+       versioning
+
 2004-12-01  Miklos Szeredi <miklos@szeredi.hu>
 
        * kernel: clean up writing functions
index 315886da5ebdc0aaf7f803e9ad34c7543bfab747..adc9234a00ba0fb2422d9c9d496b73a0dc24cbb4 100644 (file)
@@ -1,4 +1,4 @@
-AC_INIT(fuse, 3.0-pre0)
+AC_INIT(fuse, 2.2-pre0)
 AM_INIT_AUTOMAKE
 AM_CONFIG_HEADER(include/config.h)
 
@@ -14,7 +14,7 @@ if test -z "$mkdir_p"; then
 fi
 
 CFLAGS="-Wall -W -g -O2"
-CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64 -D_REENTRANT"
+CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64 -D_REENTRANT -DFUSE_USE_VERSION=22"
 
 AC_ARG_ENABLE(kernel-module,
        [  --enable-kernel-module  Compile kernel module ])
index f6f160055bbc957438c698d11572f6a5d032ca18..14ac9d91d1357529e5bf4db35bee8b571cd7ed93 100644 (file)
@@ -1,7 +1,7 @@
 ## Process this file with automake to produce Makefile.in
 
 fuseincludedir=$(includedir)/fuse
-fuseinclude_HEADERS = fuse.h
+fuseinclude_HEADERS = fuse.h fuse_compat.h
 noinst_HEADERS = fuse_kernel.h
 
 # remove fuse.h from old place to avoid collision with new one
index 072ac221633ee6ae31aff55f928d212cb5742df4..3223155b3bf299bfd4b74a1d932447d4a72f457d 100644 (file)
 
 /* This file defines the library interface of FUSE */
 
+/* IMPORTANT: you should define FUSE_USE_VERSION before including this
+   header.  To use the new API define it to 22 (recommended for any
+   new application), to use the old API define it to 21, to use the
+   even older 1.X API define it to 11. */
+
+#ifndef FUSE_USE_VERSION
+#define FUSE_USE_VERSION 21
+#endif
+
 /** Major version of FUSE library interface */
-#define FUSE_MAJOR_VERSION 3
+#define FUSE_MAJOR_VERSION 2
 
 /** Minor version of FUSE library interface */
-#define FUSE_MINOR_VERSION 0
+#define FUSE_MINOR_VERSION 2
 
 /* This interface uses 64 bit off_t */
 #if _FILE_OFFSET_BITS != 64
@@ -174,12 +183,15 @@ struct fuse_context {
  *   - registers the operations
  *   - calls either the single-threaded or the multi-threaded event loop
  *
+ * Note: this is currently implemented as a macro.
+ *
  * @param argc the argument counter passed to the main() function
  * @param argv the argument vector passed to the main() function
  * @param op the file system operation 
  * @return 0 on success, nonzero on failure
  */
-int fuse_main(int argc, char *argv[], const struct fuse_operations *op);
+/* int fuse_main(int argc, char *argv[], const struct fuse_operations *op); */
+#define fuse_main(argc, argv, op) __fuse_main(argc, argv, op, sizeof(*(op)))
 
 /* ----------------------------------------------------------- *
  * More detailed API                                           *
@@ -210,10 +222,11 @@ void fuse_unmount(const char *mountpoint);
  * @param fd the control file descriptor
  * @param opts mount options to be used by the library
  * @param op the operations
+ * @param op_size the size of the fuse_operations structure
  * @return the created FUSE handle
  */
 struct fuse *fuse_new(int fd, const char *opts, 
-                      const struct fuse_operations *op);
+                      const struct fuse_operations *op, size_t op_size);
 
 /**
  * Destroy the FUSE handle. 
@@ -287,6 +300,14 @@ int fuse_invalidate(struct fuse *f, const char *path);
  */
 int fuse_is_lib_option(const char *opt);
 
+/**
+ * The real main function
+ * 
+ * Do not call this directly, use fuse_main()
+ */
+int __fuse_main(int argc, char *argv[], const struct fuse_operations *op,
+                size_t op_size);
+
 /* ----------------------------------------------------------- *
  * Advanced API for event handling, don't worry about this...  *
  * ----------------------------------------------------------- */
@@ -294,7 +315,7 @@ int fuse_is_lib_option(const char *opt);
 struct fuse_cmd;
 typedef void (*fuse_processor_t)(struct fuse *, struct fuse_cmd *, void *);
 struct fuse *__fuse_setup(int argc, char *argv[],
-                          const struct fuse_operations *op,
+                          const struct fuse_operations *op, size_t op_size,
                           char **mountpoint, int *multithreaded, int *fd);
 void __fuse_teardown(struct fuse *fuse, int fd, char *mountpoint);
 struct fuse_cmd *__fuse_read_cmd(struct fuse *f);
@@ -303,6 +324,38 @@ int __fuse_loop_mt(struct fuse *f, fuse_processor_t proc, void *data);
 int __fuse_exited(struct fuse* f);
 void __fuse_set_getcontext_func(struct fuse_context *(*func)(void));
 
+/* ----------------------------------------------------------- *
+ * Compatibility stuff                                         *
+ * ----------------------------------------------------------- */
+
+#if FUSE_USE_VERSION == 21 || FUSE_USE_VERSION == 11
+#  include <fuse_compat.h>
+#  define fuse_dirfil_t _fuse_dirfil_t_compat
+#  undef fuse_main
+#  undef FUSE_MINOR_VERSION
+#  undef FUSE_MAJOR_VERSION
+#  if FUSE_USE_VERSION == 21
+#    define FUSE_MAJOR_VERSION 2
+#    define FUSE_MINOR_VERSION 1
+#    define fuse_operations _fuse_operations_compat2
+#    define fuse_main _fuse_main_compat2
+#    define fuse_new _fuse_new_compat2
+#    define __fuse_setup _fuse_setup_compat2
+#  else
+#    undef FUSE_MAJOR_VERSION
+#    define FUSE_MAJOR_VERSION 1
+#    define FUSE_MINOR_VERSION 1
+#    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_mount _fuse_mount_compat1
+#    define FUSE_DEBUG _FUSE_DEBUG_COMPAT1
+#  endif
+#elif FUSE_USE_VERSION != 22
+#  error API version other than 22, 21 and 11 not supported
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/fuse_compat.h b/include/fuse_compat.h
new file mode 100644 (file)
index 0000000..7ec9a29
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+    FUSE: Filesystem in Userspace
+    Copyright (C) 2001-2004  Miklos Szeredi <miklos@szeredi.hu>
+
+    This program can be distributed under the terms of the GNU LGPL.
+    See the file COPYING.LIB.
+*/
+
+/* these definitions provide source compatibility to prior versions.
+   Do not include this file directly! */
+
+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)
+
+int _fuse_mount_compat1(const char *mountpoint, const char *args[]);
+
+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);
index f078427c2c53d3ba3e7eba5515bd2f22836d5d08..f57a67c97ac09c6d53789145bf92c1e3c319dcb0 100644 (file)
@@ -1,4 +1,4 @@
-AC_INIT(fuse-kernel, 3.0-pre0)
+AC_INIT(fuse-kernel, 2.2-pre0)
 AC_CONFIG_HEADERS([config.h])
 
 AC_PROG_INSTALL
index e370ef4eb58055bf9ac117f08eeb1b497c9d8422..c9a2cd4dda91fb12cce6e17d568b9d76d250b1c9 100644 (file)
@@ -9,4 +9,5 @@ libfuse_la_SOURCES =    \
        mount.c         \
        fuse_i.h
 
-libfuse_la_LDFLAGS = -lpthread -version-number 3:0:0
+libfuse_la_LDFLAGS = -lpthread -version-number 2:2:0 \
+       -Wl,--version-script,fuse_versionscript
index 100b50f6528e394429bf2327c0d8981e3faed191..afc8c74ba97cd9b7f7ae77e859706a8707f32e9e 100644 (file)
@@ -17,6 +17,7 @@
 #include <errno.h>
 #include <sys/param.h>
 
+#define FUSE_KERNEL_MINOR_VERSION_NEED 1
 #define FUSE_VERSION_FILE_OLD "/proc/fs/fuse/version"
 #define FUSE_VERSION_FILE_NEW "/sys/fs/fuse/version"
 #define FUSE_DEV_OLD "/proc/fs/fuse/dev"
@@ -1067,8 +1068,12 @@ static void do_open(struct fuse *f, struct fuse_in_header *in,
     path = get_path(f, in->nodeid);
     if (path != NULL) {
         res = -ENOSYS;
-        if (f->op.open)
-            res = f->op.open(path, &fi);
+        if (f->op.open.curr) {
+            if (!f->compat)
+                res = f->op.open.curr(path, &fi);
+            else
+                res = f->op.open.compat2(path, fi.flags);
+        }
     }
     if (res == 0) {
         int res2;
@@ -1087,8 +1092,12 @@ static void do_open(struct fuse *f, struct fuse_in_header *in,
         res2 = __send_reply(f, in, res, &outarg, sizeof(outarg), 1);
         if(res2 == -ENOENT) {
             /* The open syscall was interrupted, so it must be cancelled */
-            if(f->op.release)
-                f->op.release(path, &fi);
+            if(f->op.release.curr) {
+                if (!f->compat)
+                    f->op.release.curr(path, &fi);
+                else
+                    f->op.release.compat2(path, fi.flags);
+            }
         } else
             get_node(f, in->nodeid)->open_count ++;
         pthread_mutex_unlock(&f->lock);
@@ -1146,8 +1155,12 @@ static void do_release(struct fuse *f, struct fuse_in_header *in,
             printf("RELEASE[%lu]\n", arg->fh);
             fflush(stdout);
         }
-        if (f->op.release)
-            f->op.release(path, &fi);
+        if (f->op.release.curr) {
+            if (!f->compat)
+                f->op.release.curr(path, &fi);
+            else
+                f->op.release.compat2(path, fi.flags);
+        }
 
         if(node->is_hidden && node->open_count == 0)
             /* can now clean up this hidden file */
@@ -1252,6 +1265,18 @@ static int default_statfs(struct statfs *buf)
     return 0;
 }
 
+static void convert_statfs_compat(struct _fuse_statfs_compat1 *compatbuf,
+                                  struct statfs *statfs)
+{
+    statfs->f_bsize   = compatbuf->block_size;
+    statfs->f_blocks  = compatbuf->blocks;
+    statfs->f_bfree   = compatbuf->blocks_free;
+    statfs->f_bavail  = compatbuf->blocks_free;
+    statfs->f_files   = compatbuf->files;
+    statfs->f_ffree   = compatbuf->files_free;
+    statfs->f_namelen = compatbuf->namelen;
+}
+
 static void convert_statfs(struct statfs *statfs, struct fuse_kstatfs *kstatfs)
 {
     kstatfs->bsize     = statfs->f_bsize;
@@ -1270,8 +1295,17 @@ static void do_statfs(struct fuse *f, struct fuse_in_header *in)
     struct statfs buf;
 
     memset(&buf, 0, sizeof(struct statfs));
-    if (f->op.statfs)
-        res = f->op.statfs("/", &buf);
+    if (f->op.statfs.curr) {
+        if (!f->compat || f->compat > 11)
+            res = f->op.statfs.curr("/", &buf);
+        else {
+            struct _fuse_statfs_compat1 compatbuf;
+            memset(&compatbuf, 0, sizeof(struct _fuse_statfs_compat1));
+            res = f->op.statfs.compat1(&compatbuf);
+            if (res == 0)
+                convert_statfs_compat(&compatbuf, &buf);
+        }
+    }
     else
         res = default_statfs(&buf);
 
@@ -1773,7 +1807,7 @@ static int check_version(struct fuse *f)
                 FUSE_KERNEL_VERSION);
         return -1;
     }
-    if (f->minorver < FUSE_KERNEL_MINOR_VERSION) {
+    if (f->minorver < FUSE_KERNEL_MINOR_VERSION_NEED) {
         fprintf(stderr, "fuse: kernel interface too old: need >= %i.%i\n",
                 FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
         return -1;
@@ -1818,11 +1852,18 @@ static int parse_lib_opts(struct fuse *f, const char *opts)
     return 0;
 }
 
-struct fuse *fuse_new(int fd, const char *opts, const struct fuse_operations *op)
+struct fuse *fuse_new_common(int fd, const char *opts,
+                             const struct fuse_operations *op,
+                             size_t op_size, int compat)
 {
     struct fuse *f;
     struct node *root;
 
+    if (sizeof(struct fuse_operations_i) < op_size) {
+        fprintf(stderr, "fuse: warning: library too old, some operations may not not work\n");
+        op_size = sizeof(struct fuse_operations_i);
+    }
+
     f = (struct fuse *) calloc(1, sizeof(struct fuse));
     if (f == NULL)
         goto out;
@@ -1862,7 +1903,8 @@ struct fuse *fuse_new(int fd, const char *opts, const struct fuse_operations *op
 #endif
     f->numworker = 0;
     f->numavail = 0;
-    f->op = *op;
+    memcpy(&f->op, op, op_size);
+    f->compat = compat;
     f->exited = 0;
 
     root = (struct node *) calloc(1, sizeof(struct node));
@@ -1895,6 +1937,29 @@ struct fuse *fuse_new(int fd, const char *opts, const struct fuse_operations *op
     return NULL;
 }
 
+struct fuse *fuse_new(int fd, const char *opts,
+                      const struct fuse_operations *op, size_t op_size)
+{
+    return fuse_new_common(fd, opts, op, op_size, 0);
+}
+
+struct fuse *_fuse_new_compat2(int fd, const char *opts,
+                              const struct _fuse_operations_compat2 *op)
+{
+    return fuse_new_common(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)
+{
+    char *opts = NULL;
+    if (flags & _FUSE_DEBUG_COMPAT1)
+        opts = "debug";
+    return fuse_new_common(fd, opts, (struct fuse_operations *) op,
+                           sizeof(struct _fuse_operations_compat1), 11);
+}
+
 void fuse_destroy(struct fuse *f)
 {
     size_t i;
@@ -1923,3 +1988,5 @@ void fuse_destroy(struct fuse *f)
     pthread_mutex_destroy(&f->lock);
     free(f);
 }
+
+__asm__(".symver _fuse_new_compat2,fuse_new@");
index b9ea90354d1171ed9154ce55a6b67d4ac96c03da..f88dda15f383947cd221c409ef01f170f181da6e 100644 (file)
@@ -7,6 +7,7 @@
 */
 
 #include "fuse.h"
+#include "fuse_compat.h"
 #include <stdio.h>
 #include <pthread.h>
 
@@ -40,10 +41,50 @@ struct node {
     int is_hidden;
 };
 
+struct fuse_operations_i {
+    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 *);
+    union {
+        int (*curr)    (const char *, struct fuse_file_info *);
+        int (*compat2) (const char *, int);
+    } open;
+    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 *);
+    union {
+        int (*curr)    (const char *, struct statfs *);
+        int (*compat1) (struct _fuse_statfs_compat1 *);
+    } statfs;
+    int (*flush)       (const char *, struct fuse_file_info *);
+    union {
+        int (*curr)    (const char *, struct fuse_file_info *);
+        int (*compat2) (const char *, int);
+    } release;
+    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 *);
+};
+
 struct fuse {
     int flags;
     int fd;
-    struct fuse_operations op;
+    struct fuse_operations_i op;
+    int compat;
     struct node **name_table;
     size_t name_table_size;
     struct node **id_table;
@@ -69,3 +110,7 @@ struct fuse_cmd {
     char *buf;
     size_t buflen;
 };
+
+struct fuse *fuse_new_common(int fd, const char *opts,
+                             const struct fuse_operations *op,
+                             size_t op_size, int compat);
diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript
new file mode 100644 (file)
index 0000000..175cf32
--- /dev/null
@@ -0,0 +1,29 @@
+FUSE_2.2 {
+       global:
+               __fuse_exited;
+               __fuse_loop_mt;
+               __fuse_main;
+               __fuse_process_cmd;
+               __fuse_read_cmd;
+               __fuse_set_getcontext_func;
+               __fuse_setup;
+               __fuse_teardown;
+               _fuse_setup_compat2;
+               _fuse_main_compat1;
+               _fuse_main_compat2;
+               _fuse_mount_compat1;
+               _fuse_new_compat1;
+               _fuse_new_compat2;
+               fuse_destroy;
+               fuse_exit;
+               fuse_get_context;
+               fuse_invalidate;
+               fuse_is_lib_option;
+               fuse_loop;
+               fuse_loop_mt;
+               fuse_mount;
+               fuse_new;
+               fuse_unmount;
+       local:
+                *;
+};
index b4d437fd6abaf0997ee7c43ea4e9c50f309950f5..50d43c1b2fa0a494773c0b86584f90d3d339e771 100644 (file)
@@ -6,7 +6,7 @@
     See the file COPYING.LIB.
 */
 
-#include "fuse.h"
+#include "fuse_i.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -249,16 +249,20 @@ static int fuse_parse_cmdline(int argc, const char *argv[], char **kernel_opts,
 }
                               
 
-struct fuse *__fuse_setup(int argc, char *argv[],
-                          const struct fuse_operations *op,
-                          char **mountpoint, int *multithreaded, int *fd)
+static struct fuse *fuse_setup_common(int argc, char *argv[],
+                                      const struct fuse_operations *op,
+                                      size_t op_size,
+                                      char **mountpoint,
+                                      int *multithreaded,
+                                      int *fd,
+                                      int compat)
 {
     struct fuse *fuse;
     int background;
     char *kernel_opts;
     char *lib_opts;
     int res;
-    
+
     if (fuse_instance != NULL) {
         fprintf(stderr, "fuse: __fuse_setup() called twice\n");
         return NULL;
@@ -274,7 +278,7 @@ struct fuse *__fuse_setup(int argc, char *argv[],
     if (*fd == -1)
         goto err_free;
 
-    fuse = fuse_new(*fd, lib_opts, op);
+    fuse = fuse_new_common(*fd, lib_opts, op, op_size, compat);
     if (fuse == NULL)
         goto err_unmount;
 
@@ -306,6 +310,25 @@ struct fuse *__fuse_setup(int argc, char *argv[],
     return NULL;
 }
 
+struct fuse *__fuse_setup(int argc, char *argv[],
+                          const struct fuse_operations *op,
+                          size_t op_size, char **mountpoint,
+                          int *multithreaded, int *fd)
+{
+    return fuse_setup_common(argc, argv, op, op_size, mountpoint,
+                             multithreaded, fd, 0);
+}
+
+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, 21);
+}
+
 void __fuse_teardown(struct fuse *fuse, int fd, char *mountpoint)
 {
     if (fuse_instance != fuse)
@@ -319,8 +342,9 @@ void __fuse_teardown(struct fuse *fuse, int fd, char *mountpoint)
     free(mountpoint);
 }
 
-
-int fuse_main(int argc, char *argv[], const struct fuse_operations *op)
+static int fuse_main_common(int argc, char *argv[],
+                            const struct fuse_operations *op, size_t op_size,
+                            int compat)
 {
     struct fuse *fuse;
     char *mountpoint;
@@ -328,7 +352,8 @@ int fuse_main(int argc, char *argv[], const struct fuse_operations *op)
     int res;
     int fd;
 
-    fuse = __fuse_setup(argc, argv, op, &mountpoint, &multithreaded, &fd);
+    fuse = fuse_setup_common(argc, argv, op, op_size, &mountpoint,
+                             &multithreaded, &fd, compat);
     if (fuse == NULL)
         return 1;
     
@@ -344,3 +369,25 @@ int fuse_main(int argc, char *argv[], const struct fuse_operations *op)
     return 0;
 }
 
+int __fuse_main(int argc, char *argv[],const struct fuse_operations *op,
+                 size_t op_size)
+{
+    return fuse_main_common(argc, argv, op, op_size, 0);
+}
+
+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), 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), 21);
+}
+
+__asm__(".symver _fuse_setup_compat2,__fuse_setup@");
+__asm__(".symver _fuse_main_compat2,fuse_main@");
index a84dbee47f158bfb3aa3d21483da01343e3ee977..fd29020eb64ca10a30bfabecf04b55e003f72d0b 100644 (file)
@@ -7,6 +7,7 @@
 */
 
 #include "fuse.h"
+#include "fuse_compat.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -124,3 +125,10 @@ int fuse_mount(const char *mountpoint, const char *opts)
 
     return rv;
 }
+
+int _fuse_mount_compat1(const char *mountpoint, const char *args[])
+{
+    /* just ignore mount args for now */
+    (void) args;
+    return fuse_mount(mountpoint, NULL);
+}