summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Siegl <stesie@brokenpipe.de>2006-04-13 22:52:47 +0000
committerStefan Siegl <stesie@brokenpipe.de>2006-04-13 22:52:47 +0000
commit5147e9e1b0e63b00b4fb7a04720da591a5f6c024 (patch)
treeadc11c0bff93d1fe5eb2bccc467ee044886fc1af
parentc2552b393a785f7ba9872215695ff3a22cbdfd5f (diff)
pulled in headers from fuse 2.5.3 and added examples. fuse_ops variable renamed to fuse_ops_compat22 (to make room for 2.5 api functions).
-rw-r--r--configure.ac5
-rw-r--r--example-23/Makefile.am2
-rw-r--r--example-24/Makefile.am2
-rw-r--r--example-25/.cvsignore8
-rw-r--r--example-25/Makefile.am12
-rw-r--r--example-25/fusexmp.c373
-rw-r--r--example-25/fusexmp_fh.c418
-rw-r--r--example-25/hello.c94
-rw-r--r--example-25/hello_ll.c177
-rw-r--r--example-25/null.c88
-rw-r--r--include/fuse.h234
-rw-r--r--include/fuse_common.h117
-rw-r--r--include/fuse_compat.h64
-rw-r--r--include/fuse_opt.h227
-rw-r--r--src/fuse_i.h20
-rw-r--r--src/main.c51
-rw-r--r--src/netfs.c90
-rw-r--r--src/netnode.c7
18 files changed, 1832 insertions, 157 deletions
diff --git a/configure.ac b/configure.ac
index 90a2fa81b..1f1676004 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5,7 +5,7 @@
AC_PREREQ(2.59)
AC_INIT(libfuse, 0.1, hurdextras-hackers@nongnu.org)
-AC_REVISION($Revision: 1.8 $)
+AC_REVISION($Revision: 1.9 $)
AC_CONFIG_SRCDIR(src/main.c)
AM_CONFIG_HEADER(config.h)
@@ -44,5 +44,6 @@ AC_CONFIG_FILES([fuse.pc Makefile]
[example/Makefile
example-22/Makefile
example-23/Makefile
- example-24/Makefile])
+ example-24/Makefile
+ example-25/Makefile])
AC_OUTPUT
diff --git a/example-23/Makefile.am b/example-23/Makefile.am
index 44f1bfe50..849cebd6e 100644
--- a/example-23/Makefile.am
+++ b/example-23/Makefile.am
@@ -8,4 +8,4 @@ null_SOURCES = null.c
hello_SOURCES = hello.c
LDADD = ../src/libfuse.la
-AM_CPPFLAGS = -DFUSE_USE_VERSION=23 -I$(top_srcdir) -I$(top_srcdir)/include
+AM_CPPFLAGS = -DFUSE_USE_VERSION=22 -I$(top_srcdir) -I$(top_srcdir)/include
diff --git a/example-24/Makefile.am b/example-24/Makefile.am
index 8a875b8df..15284f816 100644
--- a/example-24/Makefile.am
+++ b/example-24/Makefile.am
@@ -9,4 +9,4 @@ null_SOURCES = null.c
hello_SOURCES = hello.c
LDADD = ../src/libfuse.la
-AM_CPPFLAGS = -DFUSE_USE_VERSION=23 -I$(top_srcdir) -I$(top_srcdir)/include
+AM_CPPFLAGS = -DFUSE_USE_VERSION=22 -I$(top_srcdir) -I$(top_srcdir)/include
diff --git a/example-25/.cvsignore b/example-25/.cvsignore
new file mode 100644
index 000000000..80eb82bdb
--- /dev/null
+++ b/example-25/.cvsignore
@@ -0,0 +1,8 @@
+Makefile.in
+Makefile
+.deps
+fusexmp
+fusexmp_fh
+null
+hello
+.libs
diff --git a/example-25/Makefile.am b/example-25/Makefile.am
new file mode 100644
index 000000000..0ed939a32
--- /dev/null
+++ b/example-25/Makefile.am
@@ -0,0 +1,12 @@
+## Process this file with automake to produce Makefile.in
+
+noinst_PROGRAMS = fusexmp fusexmp_fh null hello
+# low-level api not supported: hello_ll
+
+fusexmp_SOURCES = fusexmp.c
+fusexmp_fh_SOURCES = fusexmp_fh.c
+null_SOURCES = null.c
+hello_SOURCES = hello.c
+
+LDADD = ../src/libfuse.la
+AM_CPPFLAGS = -DFUSE_USE_VERSION=25 -I$(top_srcdir) -I$(top_srcdir)/include
diff --git a/example-25/fusexmp.c b/example-25/fusexmp.c
new file mode 100644
index 000000000..172dc883f
--- /dev/null
+++ b/example-25/fusexmp.c
@@ -0,0 +1,373 @@
+/*
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu>
+
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
+*/
+
+#include <config.h>
+
+#ifdef linux
+/* For pread()/pwrite() */
+#define _XOPEN_SOURCE 500
+#endif
+
+#include <fuse.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <errno.h>
+#ifdef HAVE_SETXATTR
+#include <sys/xattr.h>
+#endif
+
+static int xmp_getattr(const char *path, struct stat *stbuf)
+{
+ int res;
+
+ res = lstat(path, stbuf);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_access(const char *path, int mask)
+{
+ int res;
+
+ res = access(path, mask);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_readlink(const char *path, char *buf, size_t size)
+{
+ int res;
+
+ res = readlink(path, buf, size - 1);
+ if (res == -1)
+ return -errno;
+
+ buf[res] = '\0';
+ return 0;
+}
+
+
+static int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
+ off_t offset, struct fuse_file_info *fi)
+{
+ DIR *dp;
+ struct dirent *de;
+
+ (void) offset;
+ (void) fi;
+
+ dp = opendir(path);
+ if (dp == NULL)
+ return -errno;
+
+ while ((de = readdir(dp)) != NULL) {
+ struct stat st;
+ memset(&st, 0, sizeof(st));
+ st.st_ino = de->d_ino;
+ st.st_mode = de->d_type << 12;
+ if (filler(buf, de->d_name, &st, 0))
+ break;
+ }
+
+ closedir(dp);
+ return 0;
+}
+
+static int xmp_mknod(const char *path, mode_t mode, dev_t rdev)
+{
+ int res;
+
+ /* On Linux this could just be 'mknod(path, mode, rdev)' but this
+ is more portable */
+ if (S_ISREG(mode)) {
+ res = open(path, O_CREAT | O_EXCL | O_WRONLY, mode);
+ if (res >= 0)
+ res = close(res);
+ } else if (S_ISFIFO(mode))
+ res = mkfifo(path, mode);
+ else
+ res = mknod(path, mode, rdev);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_mkdir(const char *path, mode_t mode)
+{
+ int res;
+
+ res = mkdir(path, mode);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_unlink(const char *path)
+{
+ int res;
+
+ res = unlink(path);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_rmdir(const char *path)
+{
+ int res;
+
+ res = rmdir(path);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_symlink(const char *from, const char *to)
+{
+ int res;
+
+ res = symlink(from, to);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_rename(const char *from, const char *to)
+{
+ int res;
+
+ res = rename(from, to);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_link(const char *from, const char *to)
+{
+ int res;
+
+ res = link(from, to);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_chmod(const char *path, mode_t mode)
+{
+ int res;
+
+ res = chmod(path, mode);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_chown(const char *path, uid_t uid, gid_t gid)
+{
+ int res;
+
+ res = lchown(path, uid, gid);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_truncate(const char *path, off_t size)
+{
+ int res;
+
+ res = truncate(path, size);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_utime(const char *path, struct utimbuf *buf)
+{
+ int res;
+
+ res = utime(path, buf);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+
+static int xmp_open(const char *path, struct fuse_file_info *fi)
+{
+ int res;
+
+ res = open(path, fi->flags);
+ if (res == -1)
+ return -errno;
+
+ close(res);
+ return 0;
+}
+
+static int xmp_read(const char *path, char *buf, size_t size, off_t offset,
+ struct fuse_file_info *fi)
+{
+ int fd;
+ int res;
+
+ (void) fi;
+ fd = open(path, O_RDONLY);
+ if (fd == -1)
+ return -errno;
+
+ res = pread(fd, buf, size, offset);
+ if (res == -1)
+ res = -errno;
+
+ close(fd);
+ return res;
+}
+
+static int xmp_write(const char *path, const char *buf, size_t size,
+ off_t offset, struct fuse_file_info *fi)
+{
+ int fd;
+ int res;
+
+ (void) fi;
+ fd = open(path, O_WRONLY);
+ if (fd == -1)
+ return -errno;
+
+ res = pwrite(fd, buf, size, offset);
+ if (res == -1)
+ res = -errno;
+
+ close(fd);
+ return res;
+}
+
+static int xmp_statfs(const char *path, struct statvfs *stbuf)
+{
+ int res;
+
+ res = statvfs(path, stbuf);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_release(const char *path, struct fuse_file_info *fi)
+{
+ /* Just a stub. This method is optional and can safely be left
+ unimplemented */
+
+ (void) path;
+ (void) fi;
+ return 0;
+}
+
+static int xmp_fsync(const char *path, int isdatasync,
+ struct fuse_file_info *fi)
+{
+ /* Just a stub. This method is optional and can safely be left
+ unimplemented */
+
+ (void) path;
+ (void) isdatasync;
+ (void) fi;
+ return 0;
+}
+
+#ifdef HAVE_SETXATTR
+/* xattr operations are optional and can safely be left unimplemented */
+static int xmp_setxattr(const char *path, const char *name, const char *value,
+ size_t size, int flags)
+{
+ int res = lsetxattr(path, name, value, size, flags);
+ if (res == -1)
+ return -errno;
+ return 0;
+}
+
+static int xmp_getxattr(const char *path, const char *name, char *value,
+ size_t size)
+{
+ int res = lgetxattr(path, name, value, size);
+ if (res == -1)
+ return -errno;
+ return res;
+}
+
+static int xmp_listxattr(const char *path, char *list, size_t size)
+{
+ int res = llistxattr(path, list, size);
+ if (res == -1)
+ return -errno;
+ return res;
+}
+
+static int xmp_removexattr(const char *path, const char *name)
+{
+ int res = lremovexattr(path, name);
+ if (res == -1)
+ return -errno;
+ return 0;
+}
+#endif /* HAVE_SETXATTR */
+
+static struct fuse_operations xmp_oper = {
+ .getattr = xmp_getattr,
+ .access = xmp_access,
+ .readlink = xmp_readlink,
+ .readdir = xmp_readdir,
+ .mknod = xmp_mknod,
+ .mkdir = xmp_mkdir,
+ .symlink = xmp_symlink,
+ .unlink = xmp_unlink,
+ .rmdir = xmp_rmdir,
+ .rename = xmp_rename,
+ .link = xmp_link,
+ .chmod = xmp_chmod,
+ .chown = xmp_chown,
+ .truncate = xmp_truncate,
+ .utime = xmp_utime,
+ .open = xmp_open,
+ .read = xmp_read,
+ .write = xmp_write,
+ .statfs = xmp_statfs,
+ .release = xmp_release,
+ .fsync = xmp_fsync,
+#ifdef HAVE_SETXATTR
+ .setxattr = xmp_setxattr,
+ .getxattr = xmp_getxattr,
+ .listxattr = xmp_listxattr,
+ .removexattr= xmp_removexattr,
+#endif
+};
+
+int main(int argc, char *argv[])
+{
+ umask(0);
+ return fuse_main(argc, argv, &xmp_oper);
+}
diff --git a/example-25/fusexmp_fh.c b/example-25/fusexmp_fh.c
new file mode 100644
index 000000000..3ff6c9dc5
--- /dev/null
+++ b/example-25/fusexmp_fh.c
@@ -0,0 +1,418 @@
+/*
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu>
+
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
+*/
+
+#include <config.h>
+
+#define _GNU_SOURCE
+
+#include <fuse.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <errno.h>
+#ifdef HAVE_SETXATTR
+#include <sys/xattr.h>
+#endif
+
+static int xmp_getattr(const char *path, struct stat *stbuf)
+{
+ int res;
+
+ res = lstat(path, stbuf);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_fgetattr(const char *path, struct stat *stbuf,
+ struct fuse_file_info *fi)
+{
+ int res;
+
+ (void) path;
+
+ res = fstat(fi->fh, stbuf);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_access(const char *path, int mask)
+{
+ int res;
+
+ res = access(path, mask);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_readlink(const char *path, char *buf, size_t size)
+{
+ int res;
+
+ res = readlink(path, buf, size - 1);
+ if (res == -1)
+ return -errno;
+
+ buf[res] = '\0';
+ return 0;
+}
+
+static int xmp_opendir(const char *path, struct fuse_file_info *fi)
+{
+ DIR *dp = opendir(path);
+ if (dp == NULL)
+ return -errno;
+
+ fi->fh = (unsigned long) dp;
+ return 0;
+}
+
+static inline DIR *get_dirp(struct fuse_file_info *fi)
+{
+ return (DIR *) (uintptr_t) fi->fh;
+}
+
+static int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
+ off_t offset, struct fuse_file_info *fi)
+{
+ DIR *dp = get_dirp(fi);
+ struct dirent *de;
+
+ (void) path;
+ seekdir(dp, offset);
+ while ((de = readdir(dp)) != NULL) {
+ struct stat st;
+ memset(&st, 0, sizeof(st));
+ st.st_ino = de->d_ino;
+ st.st_mode = de->d_type << 12;
+ if (filler(buf, de->d_name, &st, telldir(dp)))
+ break;
+ }
+
+ return 0;
+}
+
+static int xmp_releasedir(const char *path, struct fuse_file_info *fi)
+{
+ DIR *dp = get_dirp(fi);
+ (void) path;
+ closedir(dp);
+ return 0;
+}
+
+static int xmp_mknod(const char *path, mode_t mode, dev_t rdev)
+{
+ int res;
+
+ if (S_ISFIFO(mode))
+ res = mkfifo(path, mode);
+ else
+ res = mknod(path, mode, rdev);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_mkdir(const char *path, mode_t mode)
+{
+ int res;
+
+ res = mkdir(path, mode);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_unlink(const char *path)
+{
+ int res;
+
+ res = unlink(path);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_rmdir(const char *path)
+{
+ int res;
+
+ res = rmdir(path);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_symlink(const char *from, const char *to)
+{
+ int res;
+
+ res = symlink(from, to);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_rename(const char *from, const char *to)
+{
+ int res;
+
+ res = rename(from, to);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_link(const char *from, const char *to)
+{
+ int res;
+
+ res = link(from, to);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_chmod(const char *path, mode_t mode)
+{
+ int res;
+
+ res = chmod(path, mode);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_chown(const char *path, uid_t uid, gid_t gid)
+{
+ int res;
+
+ res = lchown(path, uid, gid);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_truncate(const char *path, off_t size)
+{
+ int res;
+
+ res = truncate(path, size);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_ftruncate(const char *path, off_t size,
+ struct fuse_file_info *fi)
+{
+ int res;
+
+ (void) path;
+
+ res = ftruncate(fi->fh, size);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_utime(const char *path, struct utimbuf *buf)
+{
+ int res;
+
+ res = utime(path, buf);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_create(const char *path, mode_t mode, struct fuse_file_info *fi)
+{
+ int fd;
+
+ fd = open(path, fi->flags, mode);
+ if (fd == -1)
+ return -errno;
+
+ fi->fh = fd;
+ return 0;
+}
+
+static int xmp_open(const char *path, struct fuse_file_info *fi)
+{
+ int fd;
+
+ fd = open(path, fi->flags);
+ if (fd == -1)
+ return -errno;
+
+ fi->fh = fd;
+ return 0;
+}
+
+static int xmp_read(const char *path, char *buf, size_t size, off_t offset,
+ struct fuse_file_info *fi)
+{
+ int res;
+
+ (void) path;
+ res = pread(fi->fh, buf, size, offset);
+ if (res == -1)
+ res = -errno;
+
+ return res;
+}
+
+static int xmp_write(const char *path, const char *buf, size_t size,
+ off_t offset, struct fuse_file_info *fi)
+{
+ int res;
+
+ (void) path;
+ res = pwrite(fi->fh, buf, size, offset);
+ if (res == -1)
+ res = -errno;
+
+ return res;
+}
+
+static int xmp_statfs(const char *path, struct statvfs *stbuf)
+{
+ int res;
+
+ res = statvfs(path, stbuf);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+static int xmp_release(const char *path, struct fuse_file_info *fi)
+{
+ (void) path;
+ close(fi->fh);
+
+ return 0;
+}
+
+static int xmp_fsync(const char *path, int isdatasync,
+ struct fuse_file_info *fi)
+{
+ int res;
+ (void) path;
+
+#ifndef HAVE_FDATASYNC
+ (void) isdatasync;
+#else
+ if (isdatasync)
+ res = fdatasync(fi->fh);
+ else
+#endif
+ res = fsync(fi->fh);
+ if (res == -1)
+ return -errno;
+
+ return 0;
+}
+
+#ifdef HAVE_SETXATTR
+/* xattr operations are optional and can safely be left unimplemented */
+static int xmp_setxattr(const char *path, const char *name, const char *value,
+ size_t size, int flags)
+{
+ int res = lsetxattr(path, name, value, size, flags);
+ if (res == -1)
+ return -errno;
+ return 0;
+}
+
+static int xmp_getxattr(const char *path, const char *name, char *value,
+ size_t size)
+{
+ int res = lgetxattr(path, name, value, size);
+ if (res == -1)
+ return -errno;
+ return res;
+}
+
+static int xmp_listxattr(const char *path, char *list, size_t size)
+{
+ int res = llistxattr(path, list, size);
+ if (res == -1)
+ return -errno;
+ return res;
+}
+
+static int xmp_removexattr(const char *path, const char *name)
+{
+ int res = lremovexattr(path, name);
+ if (res == -1)
+ return -errno;
+ return 0;
+}
+#endif /* HAVE_SETXATTR */
+
+static struct fuse_operations xmp_oper = {
+ .getattr = xmp_getattr,
+ .fgetattr = xmp_fgetattr,
+ .access = xmp_access,
+ .readlink = xmp_readlink,
+ .opendir = xmp_opendir,
+ .readdir = xmp_readdir,
+ .releasedir = xmp_releasedir,
+ .mknod = xmp_mknod,
+ .mkdir = xmp_mkdir,
+ .symlink = xmp_symlink,
+ .unlink = xmp_unlink,
+ .rmdir = xmp_rmdir,
+ .rename = xmp_rename,
+ .link = xmp_link,
+ .chmod = xmp_chmod,
+ .chown = xmp_chown,
+ .truncate = xmp_truncate,
+ .ftruncate = xmp_ftruncate,
+ .utime = xmp_utime,
+ .create = xmp_create,
+ .open = xmp_open,
+ .read = xmp_read,
+ .write = xmp_write,
+ .statfs = xmp_statfs,
+ .release = xmp_release,
+ .fsync = xmp_fsync,
+#ifdef HAVE_SETXATTR
+ .setxattr = xmp_setxattr,
+ .getxattr = xmp_getxattr,
+ .listxattr = xmp_listxattr,
+ .removexattr= xmp_removexattr,
+#endif
+};
+
+int main(int argc, char *argv[])
+{
+ umask(0);
+ return fuse_main(argc, argv, &xmp_oper);
+}
diff --git a/example-25/hello.c b/example-25/hello.c
new file mode 100644
index 000000000..8ab718174
--- /dev/null
+++ b/example-25/hello.c
@@ -0,0 +1,94 @@
+/*
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu>
+
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
+*/
+
+#include <fuse.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+
+static const char *hello_str = "Hello World!\n";
+static const char *hello_path = "/hello";
+
+static int hello_getattr(const char *path, struct stat *stbuf)
+{
+ int res = 0;
+
+ memset(stbuf, 0, sizeof(struct stat));
+ if(strcmp(path, "/") == 0) {
+ stbuf->st_mode = S_IFDIR | 0755;
+ stbuf->st_nlink = 2;
+ }
+ else if(strcmp(path, hello_path) == 0) {
+ stbuf->st_mode = S_IFREG | 0444;
+ stbuf->st_nlink = 1;
+ stbuf->st_size = strlen(hello_str);
+ }
+ else
+ res = -ENOENT;
+
+ return res;
+}
+
+static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
+ off_t offset, struct fuse_file_info *fi)
+{
+ (void) offset;
+ (void) fi;
+
+ if(strcmp(path, "/") != 0)
+ return -ENOENT;
+
+ filler(buf, ".", NULL, 0);
+ filler(buf, "..", NULL, 0);
+ filler(buf, hello_path + 1, NULL, 0);
+
+ return 0;
+}
+
+static int hello_open(const char *path, struct fuse_file_info *fi)
+{
+ if(strcmp(path, hello_path) != 0)
+ return -ENOENT;
+
+ if((fi->flags & 3) != O_RDONLY)
+ return -EACCES;
+
+ return 0;
+}
+
+static int hello_read(const char *path, char *buf, size_t size, off_t offset,
+ struct fuse_file_info *fi)
+{
+ size_t len;
+ (void) fi;
+ if(strcmp(path, hello_path) != 0)
+ return -ENOENT;
+
+ len = strlen(hello_str);
+ if (offset < len) {
+ if (offset + size > len)
+ size = len - offset;
+ memcpy(buf, hello_str + offset, size);
+ } else
+ size = 0;
+
+ return size;
+}
+
+static struct fuse_operations hello_oper = {
+ .getattr = hello_getattr,
+ .readdir = hello_readdir,
+ .open = hello_open,
+ .read = hello_read,
+};
+
+int main(int argc, char *argv[])
+{
+ return fuse_main(argc, argv, &hello_oper);
+}
diff --git a/example-25/hello_ll.c b/example-25/hello_ll.c
new file mode 100644
index 000000000..7682f4eaf
--- /dev/null
+++ b/example-25/hello_ll.c
@@ -0,0 +1,177 @@
+/*
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu>
+
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
+*/
+
+#include <fuse_lowlevel.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <assert.h>
+
+static const char *hello_str = "Hello World!\n";
+static const char *hello_name = "hello";
+
+static int hello_stat(fuse_ino_t ino, struct stat *stbuf)
+{
+ stbuf->st_ino = ino;
+ switch (ino) {
+ case 1:
+ stbuf->st_mode = S_IFDIR | 0755;
+ stbuf->st_nlink = 2;
+ break;
+
+ case 2:
+ stbuf->st_mode = S_IFREG | 0444;
+ stbuf->st_nlink = 1;
+ stbuf->st_size = strlen(hello_str);
+ break;
+
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+static void hello_ll_getattr(fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info *fi)
+{
+ struct stat stbuf;
+
+ (void) fi;
+
+ memset(&stbuf, 0, sizeof(stbuf));
+ if (hello_stat(ino, &stbuf) == -1)
+ fuse_reply_err(req, ENOENT);
+ else
+ fuse_reply_attr(req, &stbuf, 1.0);
+}
+
+static void hello_ll_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
+{
+ struct fuse_entry_param e;
+
+ if (parent != 1 || strcmp(name, hello_name) != 0)
+ fuse_reply_err(req, ENOENT);
+ else {
+ memset(&e, 0, sizeof(e));
+ e.ino = 2;
+ e.attr_timeout = 1.0;
+ e.entry_timeout = 1.0;
+ hello_stat(e.ino, &e.attr);
+
+ fuse_reply_entry(req, &e);
+ }
+}
+
+struct dirbuf {
+ char *p;
+ size_t size;
+};
+
+static void dirbuf_add(struct dirbuf *b, const char *name, fuse_ino_t ino)
+{
+ struct stat stbuf;
+ size_t oldsize = b->size;
+ b->size += fuse_dirent_size(strlen(name));
+ b->p = (char *) realloc(b->p, b->size);
+ memset(&stbuf, 0, sizeof(stbuf));
+ stbuf.st_ino = ino;
+ fuse_add_dirent(b->p + oldsize, name, &stbuf, b->size);
+}
+
+#define min(x, y) ((x) < (y) ? (x) : (y))
+
+static int reply_buf_limited(fuse_req_t req, const char *buf, size_t bufsize,
+ off_t off, size_t maxsize)
+{
+ if (off < bufsize)
+ return fuse_reply_buf(req, buf + off, min(bufsize - off, maxsize));
+ else
+ return fuse_reply_buf(req, NULL, 0);
+}
+
+static void hello_ll_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
+ off_t off, struct fuse_file_info *fi)
+{
+ (void) fi;
+
+ if (ino != 1)
+ fuse_reply_err(req, ENOTDIR);
+ else {
+ struct dirbuf b;
+
+ memset(&b, 0, sizeof(b));
+ dirbuf_add(&b, ".", 1);
+ dirbuf_add(&b, "..", 1);
+ dirbuf_add(&b, hello_name, 2);
+ reply_buf_limited(req, b.p, b.size, off, size);
+ free(b.p);
+ }
+}
+
+static void hello_ll_open(fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info *fi)
+{
+ if (ino != 2)
+ fuse_reply_err(req, EISDIR);
+ else if ((fi->flags & 3) != O_RDONLY)
+ fuse_reply_err(req, EACCES);
+ else
+ fuse_reply_open(req, fi);
+}
+
+static void hello_ll_read(fuse_req_t req, fuse_ino_t ino, size_t size,
+ off_t off, struct fuse_file_info *fi)
+{
+ (void) fi;
+
+ assert(ino == 2);
+ reply_buf_limited(req, hello_str, strlen(hello_str), off, size);
+}
+
+static struct fuse_lowlevel_ops hello_ll_oper = {
+ .lookup = hello_ll_lookup,
+ .getattr = hello_ll_getattr,
+ .readdir = hello_ll_readdir,
+ .open = hello_ll_open,
+ .read = hello_ll_read,
+};
+
+int main(int argc, char *argv[])
+{
+ struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
+ char *mountpoint;
+ int err = -1;
+ int fd;
+
+ if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) != -1 &&
+ (fd = fuse_mount(mountpoint, &args)) != -1) {
+ struct fuse_session *se;
+
+ se = fuse_lowlevel_new(&args, &hello_ll_oper, sizeof(hello_ll_oper),
+ NULL);
+ if (se != NULL) {
+ if (fuse_set_signal_handlers(se) != -1) {
+ struct fuse_chan *ch = fuse_kern_chan_new(fd);
+ if (ch != NULL) {
+ fuse_session_add_chan(se, ch);
+ err = fuse_session_loop(se);
+ }
+ fuse_remove_signal_handlers(se);
+ }
+ fuse_session_destroy(se);
+ }
+ close(fd);
+ }
+ fuse_unmount(mountpoint);
+ fuse_opt_free_args(&args);
+
+ return err ? 1 : 0;
+}
diff --git a/example-25/null.c b/example-25/null.c
new file mode 100644
index 000000000..82e7c452d
--- /dev/null
+++ b/example-25/null.c
@@ -0,0 +1,88 @@
+/*
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu>
+
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
+*/
+
+#include <fuse.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <errno.h>
+
+static int null_getattr(const char *path, struct stat *stbuf)
+{
+ if(strcmp(path, "/") != 0)
+ return -ENOENT;
+
+ stbuf->st_mode = S_IFREG | 0644;
+ stbuf->st_nlink = 1;
+ stbuf->st_uid = getuid();
+ stbuf->st_gid = getgid();
+ stbuf->st_size = (1ULL << 32); /* 4G */
+ stbuf->st_blocks = 0;
+ stbuf->st_atime = stbuf->st_mtime = stbuf->st_ctime = time(NULL);
+
+ return 0;
+}
+
+static int null_truncate(const char *path, off_t size)
+{
+ (void) size;
+
+ if(strcmp(path, "/") != 0)
+ return -ENOENT;
+
+ return 0;
+}
+
+static int null_open(const char *path, struct fuse_file_info *fi)
+{
+ (void) fi;
+
+ if(strcmp(path, "/") != 0)
+ return -ENOENT;
+
+ return 0;
+}
+
+static int null_read(const char *path, char *buf, size_t size,
+ off_t offset, struct fuse_file_info *fi)
+{
+ (void) buf;
+ (void) offset;
+ (void) fi;
+
+ if(strcmp(path, "/") != 0)
+ return -ENOENT;
+
+ return size;
+}
+
+static int null_write(const char *path, const char *buf, size_t size,
+ off_t offset, struct fuse_file_info *fi)
+{
+ (void) buf;
+ (void) offset;
+ (void) fi;
+
+ if(strcmp(path, "/") != 0)
+ return -ENOENT;
+
+ return size;
+}
+
+static struct fuse_operations null_oper = {
+ .getattr = null_getattr,
+ .truncate = null_truncate,
+ .open = null_open,
+ .read = null_read,
+ .write = null_write,
+};
+
+int main(int argc, char *argv[])
+{
+ return fuse_main(argc, argv, &null_oper);
+}
diff --git a/include/fuse.h b/include/fuse.h
index fb1c2d6df..eb41c75ec 100644
--- a/include/fuse.h
+++ b/include/fuse.h
@@ -1,6 +1,6 @@
/*
FUSE: Filesystem in Userspace
- Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu>
+ Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu>
This program can be distributed under the terms of the GNU LGPL.
See the file COPYING.LIB.
@@ -12,28 +12,19 @@
/* 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 (this is the
- default), to use the even older 1.X API define it to 11. */
+ header. To use the newest API define it to 25 (recommended for any
+ new application), to use the old API define it to 21 (default) or
+ 22, 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 2
-
-/** Minor version of FUSE library interface */
-#define FUSE_MINOR_VERSION 3
-
-/* 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
+#include "fuse_common.h"
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/statfs.h>
+#include <sys/statvfs.h>
#include <utime.h>
#ifdef __cplusplus
@@ -47,6 +38,9 @@ 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
@@ -56,27 +50,13 @@ struct fuse;
* @return 1 if buffer is full, zero otherwise
*/
typedef int (*fuse_fill_dir_t) (void *buf, const char *name,
- const struct stat *stat, off_t off);
+ 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);
-/** Information about open files */
-struct fuse_file_info {
- /** Open flags. Available in open() and release() */
- int flags;
-
- /** File handle. May be filled in by filesystem in open().
- Available in all other file operations */
- unsigned long fh;
-
- /** In case of a write operation indicates if this was caused by a
- writepage */
- int writepage;
-};
-
/**
* The file system operations:
*
@@ -86,10 +66,10 @@ struct fuse_file_info {
* negated error value (-errno) directly.
*
* All methods are optional, but some are essential for a useful
- * filesystem (e.g. getattr). Flush, release, fsync, opendir,
- * releasedir, fsyncdir, init and destroy are special purpose
- * methods, without which a full featured filesystem can still be
- * implemented.
+ * filesystem (e.g. getattr). Open, flush, release, fsync, opendir,
+ * releasedir, fsyncdir, access, create, ftruncate, fgetattr, init and
+ * destroy are special purpose methods, without which a full featured
+ * filesystem can still be implemented.
*/
struct fuse_operations {
/** Get file attributes.
@@ -152,11 +132,13 @@ struct fuse_operations {
/** File open operation
*
- * No creation, or trunctation flags (O_CREAT, O_EXCL, O_TRUNC)
+ * No creation, or truncation flags (O_CREAT, O_EXCL, O_TRUNC)
* will be passed to open(). Open should check if the operation
* is permitted for the given flags. Optionally open may also
- * return an arbitary filehandle in the fuse_file_info structure,
+ * return an arbitrary filehandle in the fuse_file_info structure,
* which will be passed to all file operations.
+ *
+ * Changed in version 2.2
*/
int (*open) (const char *, struct fuse_file_info *);
@@ -168,6 +150,8 @@ struct fuse_operations {
* 'direct_io' mount option is specified, in which case the return
* value of the read system call will reflect the return value of
* this operation.
+ *
+ * Changed in version 2.2
*/
int (*read) (const char *, char *, size_t, off_t, struct fuse_file_info *);
@@ -176,15 +160,21 @@ struct fuse_operations {
* Write should return exactly the number of bytes requested
* except on error. An exception to this is when the 'direct_io'
* mount option is specified (see read operation).
+ *
+ * Changed in version 2.2
*/
int (*write) (const char *, const char *, size_t, off_t,
struct fuse_file_info *);
+ /** Just a placeholder, don't set */
/** Get file system statistics
*
- * The 'f_type' and 'f_fsid' fields are ignored
+ * The 'f_frsize', 'f_favail', 'f_fsid' and 'f_flag' fields are ignored
+ *
+ * Replaced 'struct statfs' parameter with 'struct statvfs' in
+ * version 2.5
*/
- int (*statfs) (const char *, struct statfs *);
+ int (*statfs) (const char *, struct statvfs *);
/** Possibly flush cached data
*
@@ -203,6 +193,11 @@ struct fuse_operations {
* not possible to determine if a flush is final, so each flush
* should be treated equally. Multiple write-flush sequences are
* relatively rare, so this shouldn't be a problem.
+ *
+ * Filesystems shouldn't assume that flush will always be called
+ * after some writes, or that if will be called at all.
+ *
+ * Changed in version 2.2
*/
int (*flush) (const char *, struct fuse_file_info *);
@@ -217,6 +212,8 @@ struct fuse_operations {
* have a file opened more than once, in which case only the last
* release will mean, that no more reads/writes will happen on the
* file. The return value of release is ignored.
+ *
+ * Changed in version 2.2
*/
int (*release) (const char *, struct fuse_file_info *);
@@ -224,6 +221,8 @@ struct fuse_operations {
*
* If the datasync parameter is non-zero, then only the user data
* should be flushed, not the meta data.
+ *
+ * Changed in version 2.2
*/
int (*fsync) (const char *, int, struct fuse_file_info *);
@@ -239,10 +238,12 @@ struct fuse_operations {
/** Remove extended attributes */
int (*removexattr) (const char *, const char *);
- /** Open direcory
+ /** Open directory
*
* This method should check if the open operation is permitted for
* this directory
+ *
+ * Introduced in version 2.3
*/
int (*opendir) (const char *, struct fuse_file_info *);
@@ -264,17 +265,24 @@ struct fuse_operations {
* passes non-zero offset to the filler function. When the buffer
* is full (or an error happens) the filler function will return
* '1'.
+ *
+ * Introduced in version 2.3
*/
int (*readdir) (const char *, void *, fuse_fill_dir_t, off_t,
struct fuse_file_info *);
- /** Release directory */
+ /** Release directory
+ *
+ * Introduced in version 2.3
+ */
int (*releasedir) (const char *, struct fuse_file_info *);
/** Synchronize directory contents
*
* If the datasync parameter is non-zero, then only the user data
* should be flushed, not the meta data
+ *
+ * Introduced in version 2.3
*/
int (*fsyncdir) (const char *, int, struct fuse_file_info *);
@@ -284,6 +292,8 @@ struct fuse_operations {
* The return value will passed in the private_data field of
* fuse_context to all file operations and as a parameter to the
* destroy() method.
+ *
+ * Introduced in version 2.3
*/
void *(*init) (void);
@@ -291,8 +301,65 @@ struct fuse_operations {
* Clean up filesystem
*
* Called on filesystem exit.
+ *
+ * Introduced in version 2.3
*/
void (*destroy) (void *);
+
+ /**
+ * Check file access permissions
+ *
+ * This will be called for the access() system call. If the
+ * 'default_permissions' mount option is given, this method is not
+ * called.
+ *
+ * This method is not called under Linux kernel versions 2.4.x
+ *
+ * Introduced in version 2.5
+ */
+ int (*access) (const char *, int);
+
+ /**
+ * Create and open a file
+ *
+ * If the file does not exist, first create it with the specified
+ * mode, and then open it.
+ *
+ * If this method is not implemented or under Linux kernel
+ * versions earlier than 2.6.15, the mknod() and open() methods
+ * will be called instead.
+ *
+ * Introduced in version 2.5
+ */
+ int (*create) (const char *, mode_t, struct fuse_file_info *);
+
+ /**
+ * Change the size of an open file
+ *
+ * This method is called instead of the truncate() method if the
+ * truncation was invoked from an ftruncate() system call.
+ *
+ * If this method is not implemented or under Linux kernel
+ * versions earlier than 2.6.15, the truncate() method will be
+ * called instead.
+ *
+ * Introduced in version 2.5
+ */
+ int (*ftruncate) (const char *, off_t, struct fuse_file_info *);
+
+ /**
+ * Get attributes from an open file
+ *
+ * This method is called instead of the getattr() method if the
+ * file information is available.
+ *
+ * Currently this is only called after the create() method if that
+ * is implemented (see above). Later it may be called for
+ * invocations of fstat() too.
+ *
+ * Introduced in version 2.5
+ */
+ int (*fgetattr) (const char *, struct stat *, struct fuse_file_info *);
};
/** Extra context that may be needed by some filesystems
@@ -349,35 +416,16 @@ int fuse_main(int argc, char *argv[], const struct fuse_operations *op);
* More detailed API *
* ----------------------------------------------------------- */
-/*
- * Create a FUSE mountpoint
- *
- * Returns a control file descriptor suitable for passing to
- * fuse_new()
- *
- * @param mountpoint the mount point path
- * @param opts a comma separated list of mount options. Can be NULL.
- * @return the control file descriptor on success, -1 on failure
- */
-int fuse_mount(const char *mountpoint, const char *opts);
-
-/*
- * Umount a FUSE mountpoint
- *
- * @param mountpoint the mount point path
- */
-void fuse_unmount(const char *mountpoint);
-
/**
* Create a new FUSE filesystem.
*
* @param fd the control file descriptor
- * @param opts mount options to be used by the library
+ * @param args argument vector
* @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,
+struct fuse *fuse_new(int fd, struct fuse_args *args,
const struct fuse_operations *op, size_t op_size);
/**
@@ -392,11 +440,11 @@ void fuse_destroy(struct fuse *f);
/**
* FUSE event loop.
*
- * Requests from the kernel are processed, and the apropriate
+ * Requests from the kernel are processed, and the appropriate
* operations are called.
*
* @param f the FUSE handle
- * @return 0 if no error occured, -1 otherwise
+ * @return 0 if no error occurred, -1 otherwise
*/
int fuse_loop(struct fuse *f);
@@ -410,7 +458,7 @@ void fuse_exit(struct fuse *f);
/**
* FUSE event loop with multiple threads
*
- * Requests from the kernel are processed, and the apropriate
+ * Requests from the kernel are processed, and the appropriate
* operations are called. Request are processed in parallel by
* distributing them between multiple threads.
*
@@ -418,7 +466,7 @@ void fuse_exit(struct fuse *f);
* the application.
*
* @param f the FUSE handle
- * @return 0 if no error occured, -1 otherwise
+ * @return 0 if no error occurred, -1 otherwise
*/
int fuse_loop_mt(struct fuse *f);
@@ -434,22 +482,13 @@ int fuse_loop_mt(struct fuse *f);
struct fuse_context *fuse_get_context(void);
/**
- * Invalidate cached data of a file.
- *
- * Useful if the 'kernel_cache' mount option is given, since in that
- * case the cache is not invalidated on file open.
+ * Obsolete, doesn't do anything
*
- * @return 0 on success or -errno on failure
+ * @return -EINVAL
*/
int fuse_invalidate(struct fuse *f, const char *path);
-/**
- * Check whether a mount option should be passed to the kernel or the
- * library
- *
- * @param opt the option to check
- * @return 1 if it is a library option, 0 otherwise
- */
+/* Deprecated, don't use */
int fuse_is_lib_option(const char *opt);
/**
@@ -464,9 +503,6 @@ int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,
* Advanced API for event handling, don't worry about this... *
* ----------------------------------------------------------- */
-/** Structure containing a raw command */
-struct fuse_cmd;
-
/** Function type used to process commands */
typedef void (*fuse_processor_t)(struct fuse *, struct fuse_cmd *, void *);
@@ -490,7 +526,7 @@ 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);
+int fuse_exited(struct fuse *f);
/** Set function which can be used to get the current context */
void fuse_set_getcontext_func(struct fuse_context *(*func)(void));
@@ -499,17 +535,27 @@ void fuse_set_getcontext_func(struct fuse_context *(*func)(void));
* Compatibility stuff *
* ----------------------------------------------------------- */
-#if FUSE_USE_VERSION == 21 || FUSE_USE_VERSION == 11
+#ifndef __FreeBSD__
+
+#if FUSE_USE_VERSION == 22 || FUSE_USE_VERSION == 21 || FUSE_USE_VERSION == 11
# include "fuse_compat.h"
+# undef FUSE_MINOR_VERSION
+# undef fuse_main
+# if FUSE_USE_VERSION == 22
+# define FUSE_MINOR_VERSION 4
+# 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_operations fuse_operations_compat22
+# define fuse_file_info fuse_file_info_compat22
+# define fuse_mount fuse_mount_compat22
+# 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
-# 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
@@ -518,7 +564,10 @@ void fuse_set_getcontext_func(struct fuse_context *(*func)(void));
# define __fuse_teardown fuse_teardown
# define __fuse_exited fuse_exited
# define __fuse_set_getcontext_func fuse_set_getcontext_func
+# define fuse_mount fuse_mount_compat22
# else
+# warning Compatibility with API version 11 is deprecated
+# undef FUSE_MAJOR_VERSION
# define FUSE_MAJOR_VERSION 1
# define FUSE_MINOR_VERSION 1
# define fuse_statfs fuse_statfs_compat1
@@ -528,10 +577,19 @@ void fuse_set_getcontext_func(struct fuse_context *(*func)(void));
# define fuse_mount fuse_mount_compat1
# define FUSE_DEBUG FUSE_DEBUG_COMPAT1
# endif
-#elif FUSE_USE_VERSION < 22
-# error Compatibility with API version other than 21 and 11 not supported
+# endif
+#elif FUSE_USE_VERSION < 25
+# error Compatibility with API version other than 21, 22 and 11 not supported
#endif
+#else /* __FreeBSD__ */
+
+#if FUSE_USE_VERSION < 25
+# error On FreeBSD API version 25 or greater must be used
+#endif
+
+#endif /* __FreeBSD__ */
+
#ifdef __cplusplus
}
#endif
diff --git a/include/fuse_common.h b/include/fuse_common.h
new file mode 100644
index 000000000..0f35ea62b
--- /dev/null
+++ b/include/fuse_common.h
@@ -0,0 +1,117 @@
+/*
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu>
+
+ This program can be distributed under the terms of the GNU LGPL.
+ See the file COPYING.LIB.
+*/
+
+#if !defined(_FUSE_H_) && !defined(_FUSE_LOWLEVEL_H_)
+#error "Never include <fuse_common.h> directly; use <fuse.h> or <fuse_lowlevel.h instead."
+#endif
+
+#ifndef _FUSE_COMMON_H_
+#define _FUSE_COMMON_H_
+
+#include "fuse_opt.h"
+#include <stdint.h>
+
+/** Major version of FUSE library interface */
+#define FUSE_MAJOR_VERSION 2
+
+/** Minor version of FUSE library interface */
+#define FUSE_MINOR_VERSION 5
+
+#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
+
+/**
+ * Information about open files
+ *
+ * Changed in version 2.5
+ */
+struct fuse_file_info {
+ /** Open flags. Available in open() and release() */
+ int flags;
+
+ /** Old file handle, don't use */
+ unsigned long fh_old;
+
+ /** In case of a write operation indicates if this was caused by a
+ writepage */
+ int writepage;
+
+ /** Can be filled in by open, to use direct I/O on this file.
+ Introduced in version 2.4 */
+ unsigned int direct_io : 1;
+
+ /** Can be filled in by open, to indicate, that cached file data
+ need not be invalidated. Introduced in version 2.4 */
+ unsigned int keep_cache : 1;
+
+ /** Padding. Do not use*/
+ unsigned int padding : 30;
+
+ /** File handle. May be filled in by filesystem in open().
+ Available in all other file operations */
+ uint64_t fh;
+};
+
+/**
+ * Create a FUSE mountpoint
+ *
+ * Returns a control file descriptor suitable for passing to
+ * fuse_new()
+ *
+ * @param mountpoint the mount point path
+ * @param args argument vector
+ * @return the control file descriptor on success, -1 on failure
+ */
+int fuse_mount(const char *mountpoint, struct fuse_args *args);
+
+/**
+ * Umount a FUSE mountpoint
+ *
+ * @param mountpoint the mount point path
+ */
+void fuse_unmount(const char *mountpoint);
+
+/**
+ * Parse common options
+ *
+ * The following options are parsed:
+ *
+ * '-f' foreground
+ * '-d' '-odebug' foreground, but keep the debug option
+ * '-s' single threaded
+ * '-h' '--help' help
+ * '-ho' help without header
+ * '-ofsname=..' file system name, if not present, then set to the program
+ * name
+ *
+ * All parameters may be NULL
+ *
+ * @param args argument vector
+ * @param mountpoint the returned mountpoint, should be freed after use
+ * @param multithreaded set to 1 unless the '-s' option is present
+ * @param foreground set to 1 if one of the relevant options is present
+ * @return 0 on success, -1 on failure
+ */
+int fuse_parse_cmdline(struct fuse_args *args, char **mountpoint,
+ int *multithreaded, int *foreground);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FUSE_COMMON_H_ */
diff --git a/include/fuse_compat.h b/include/fuse_compat.h
index af7aecf7d..220ef0752 100644
--- a/include/fuse_compat.h
+++ b/include/fuse_compat.h
@@ -1,6 +1,6 @@
/*
FUSE: Filesystem in Userspace
- Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu>
+ Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu>
This program can be distributed under the terms of the GNU LGPL.
See the file COPYING.LIB.
@@ -9,6 +9,68 @@
/* these definitions provide source compatibility to prior versions.
Do not include this file directly! */
+#include <sys/statfs.h>
+
+struct fuse_file_info_compat22 {
+ int flags;
+ unsigned long fh;
+ int writepage;
+ unsigned int direct_io : 1;
+ unsigned int keep_cache : 1;
+};
+
+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_compat22 *);
+ int (*read) (const char *, char *, size_t, off_t,
+ struct fuse_file_info_compat22 *);
+ int (*write) (const char *, const char *, size_t, off_t,
+ struct fuse_file_info_compat22 *);
+ int (*statfs) (const char *, struct statfs *);
+ int (*flush) (const char *, struct fuse_file_info_compat22 *);
+ int (*release) (const char *, struct fuse_file_info_compat22 *);
+ int (*fsync) (const char *, int, struct fuse_file_info_compat22 *);
+ 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_compat22 *);
+ int (*readdir) (const char *, void *, fuse_fill_dir_t, off_t,
+ struct fuse_file_info_compat22 *);
+ int (*releasedir) (const char *, struct fuse_file_info_compat22 *);
+ int (*fsyncdir) (const char *, int, struct fuse_file_info_compat22 *);
+ 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);
+
+int fuse_mount_compat22(const char *mountpoint, const char *opts);
+
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 *);
diff --git a/include/fuse_opt.h b/include/fuse_opt.h
new file mode 100644
index 000000000..2988902f2
--- /dev/null
+++ b/include/fuse_opt.h
@@ -0,0 +1,227 @@
+/*
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu>
+
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
+*/
+
+#ifndef _FUSE_OPT_H_
+#define _FUSE_OPT_H_
+
+/* This file defines the option parsing interface of FUSE */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Option description
+ *
+ * This structure describes a single option, and and action associated
+ * with it, in case it matches.
+ *
+ * More than one such match may occur, in which case the action for
+ * each match is executed.
+ *
+ * There are three possible actions in case of a match:
+ *
+ * i) An integer (int or unsigned) variable determined by 'offset' is
+ * set to 'value'
+ *
+ * ii) The processing function is called, with 'value' as the key
+ *
+ * iii) An integer (any) or string (char *) variable determined by
+ * 'offset' is set to the value of an option parameter
+ *
+ * 'offset' should normally be either set to
+ *
+ * - 'offsetof(struct foo, member)' actions i) and iii)
+ *
+ * - -1 action ii)
+ *
+ * The 'offsetof()' macro is defined in the <stddef.h> header.
+ *
+ * The template determines which options match, and also have an
+ * effect on the action. Normally the action is either i) or ii), but
+ * if a format is present in the template, then action iii) is
+ * performed.
+ *
+ * The types of templates are:
+ *
+ * 1) "-x", "-foo", "--foo", "--foo-bar", etc. These match only
+ * themselves. Invalid values are "--" and anything beginning
+ * with "-o"
+ *
+ * 2) "foo", "foo-bar", etc. These match "-ofoo", "-ofoo-bar" or
+ * the relevant option in a comma separated option list
+ *
+ * 3) "bar=", "--foo=", etc. These are variations of 1) and 2)
+ * which have a parameter
+ *
+ * 4) "bar=%s", "--foo=%lu", etc. Same matching as above but perform
+ * action iii).
+ *
+ * 5) "-x ", etc. Matches either "-xparam" or "-x param" as
+ * two separate arguments
+ *
+ * 6) "-x %s", etc. Combination of 4) and 5)
+ *
+ * If the format is "%s", memory is allocated for the string unlike
+ * with scanf().
+ */
+struct fuse_opt {
+ /** Matching template and optional parameter formatting */
+ const char *templ;
+
+ /**
+ * Offset of variable within 'data' parameter of fuse_opt_parse()
+ * or -1
+ */
+ unsigned long offset;
+
+ /**
+ * Value to set the variable to, or to be passed as 'key' to the
+ * processing function. Ignored if template has a format
+ */
+ int value;
+};
+
+/**
+ * Key option. In case of a match, the processing function will be
+ * called with the specified key.
+ */
+#define FUSE_OPT_KEY(templ, key) { templ, -1U, key }
+
+/**
+ * Last option. An array of 'struct fuse_opt' must end with a NULL
+ * template value
+ */
+#define FUSE_OPT_END { .templ = NULL }
+
+/**
+ * Argument list
+ */
+struct fuse_args {
+ /** Argument count */
+ int argc;
+
+ /** Argument vector. NULL terminated */
+ char **argv;
+
+ /** Is 'argv' allocated? */
+ int allocated;
+};
+
+/**
+ * Initializer for 'struct fuse_args'
+ */
+#define FUSE_ARGS_INIT(argc, argv) { argc, argv, 0 }
+
+/**
+ * Key value passed to the processing function if an option did not
+ * match any template
+ */
+#define FUSE_OPT_KEY_OPT -1
+
+/**
+ * Key value passed to the processing function for all non-options
+ *
+ * Non-options are the arguments beginning with a charater other than
+ * '-' or all arguments after the special '--' option
+ */
+#define FUSE_OPT_KEY_NONOPT -2
+
+/**
+ * Processing function
+ *
+ * This function is called if
+ * - option did not match any 'struct fuse_opt'
+ * - argument is a non-option
+ * - option did match and offset was set to -1
+ *
+ * The 'arg' parameter will always contain the whole argument or
+ * option including the parameter if exists. A two-argument option
+ * ("-x foo") is always converted to single arguemnt option of the
+ * form "-xfoo" before this function is called.
+ *
+ * Options of the form '-ofoo' are passed to this function without the
+ * '-o' prefix.
+ *
+ * The return value of this function determines whether this argument
+ * is to be inserted into the output argument vector, or discarded.
+ *
+ * @param data is the user data passed to the fuse_opt_parse() function
+ * @param arg is the whole argument or option
+ * @param key determines why the processing function was called
+ * @param outargs the current output argument list
+ * @return -1 on error, 0 if arg is to be discarded, 1 if arg should be kept
+ */
+typedef int (*fuse_opt_proc_t)(void *data, const char *arg, int key,
+ struct fuse_args *outargs);
+
+/**
+ * Option parsing function
+ *
+ * If 'args' was returned from a previous call to fuse_opt_parse() or
+ * it was constructed from
+ *
+ * A NULL 'args' is equivalent to an empty argument vector
+ *
+ * A NULL 'opts' is equivalent to an 'opts' array containing a single
+ * end marker
+ *
+ * A NULL 'proc' is equivalent to a processing function always
+ * returning '1'
+ *
+ * @param args is the input and output argument list
+ * @param data is the user data
+ * @param opts is the option description array
+ * @param proc is the processing function
+ * @return -1 on error, 0 on success
+ */
+int fuse_opt_parse(struct fuse_args *args, void *data,
+ const struct fuse_opt opts[], fuse_opt_proc_t proc);
+
+/**
+ * Add an option to a comma separated option list
+ *
+ * @param opts is a pointer to an option list, may point to a NULL value
+ * @param opt is the option to add
+ * @return -1 on allocation error, 0 on success
+ */
+int fuse_opt_add_opt(char **opts, const char *opt);
+
+/**
+ * Add an argument to a NULL terminated argument vector
+ *
+ * @param args is the structure containing the current argument list
+ * @param arg is the new argument to add
+ * @return -1 on allocation error, 0 on success
+ */
+int fuse_opt_add_arg(struct fuse_args *args, const char *arg);
+
+/**
+ * Free the contents of argument list
+ *
+ * The structure itself is not freed
+ *
+ * @param args is the structure containing the argument list
+ */
+void fuse_opt_free_args(struct fuse_args *args);
+
+
+/**
+ * Check if an option matches
+ *
+ * @param opts is the option description array
+ * @param opt is the option to match
+ * @return 1 if a match is found, 0 if not
+ */
+int fuse_opt_match(const struct fuse_opt opts[], const char *opt);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FUSE_OPT_H_ */
diff --git a/src/fuse_i.h b/src/fuse_i.h
index e6fd4e43e..81d46d405 100644
--- a/src/fuse_i.h
+++ b/src/fuse_i.h
@@ -17,7 +17,7 @@
#ifdef FUSE_USE_VERSION
# include "fuse.h"
#else
-# define FUSE_USE_VERSION 23
+# define FUSE_USE_VERSION 25
# include "fuse.h"
# include "fuse_compat.h"
#endif
@@ -30,13 +30,15 @@
__LINE__)
/* pointer to the fuse_operations structure of this translator process */
-extern const struct fuse_operations *fuse_ops;
-extern const struct fuse_operations_compat2 *fuse_ops_compat;
+extern const struct fuse_operations_compat22 *fuse_ops_compat22;
+extern const struct fuse_operations_compat2 *fuse_ops_compat2;
-#define FUSE_OP_HAVE(a) ((fuse_ops) ? \
- (fuse_ops->a != NULL) : (fuse_ops_compat->a != NULL))
-#define FUSE_OP_CALL(a,b...) ((fuse_ops) ? \
- (fuse_ops->a(b)) : (fuse_ops_compat->a(b)))
+#define FUSE_OP_HAVE(a) ((fuse_ops_compat22) ? \
+ (fuse_ops_compat22->a != NULL) : \
+ (fuse_ops_compat2->a != NULL))
+#define FUSE_OP_CALL(a,b...) ((fuse_ops_compat22) ? \
+ (fuse_ops_compat22->a(b)) : \
+ (fuse_ops_compat2->a(b)))
/*****************************************************************************
*** netnodes (in memory representation of libfuse's files or directories) ***
@@ -53,7 +55,9 @@ struct netnode {
/* information about the opened file
*/
- struct fuse_file_info info;
+ union {
+ struct fuse_file_info_compat22 compat22;
+ } info;
/* pointer to our parent's netnode, if any */
struct netnode *parent;
diff --git a/src/main.c b/src/main.c
index 291c795b1..c2ca44d88 100644
--- a/src/main.c
+++ b/src/main.c
@@ -32,8 +32,8 @@ int netfs_maxsymlinks = 12;
struct _libfuse_params libfuse_params = { 0 };
/* pointer to the fuse_operations structure of this translator process */
-const struct fuse_operations *fuse_ops = NULL;
-const struct fuse_operations_compat2 *fuse_ops_compat = NULL;
+const struct fuse_operations_compat22 *fuse_ops_compat22 = NULL;
+const struct fuse_operations_compat2 *fuse_ops_compat2 = NULL;
/* the port where to write out debug messages to, NULL to omit these */
FILE *debug_port = NULL;
@@ -230,7 +230,7 @@ fuse_main_compat2(int argc, char *argv[],
{
fuse_parse_argv(argc, argv);
- int fd = fuse_mount(NULL, NULL);
+ int fd = fuse_mount_compat22(NULL, NULL);
return (libfuse_params.disable_mt ? fuse_loop : fuse_loop_mt)
(fuse_new_compat2(fd, NULL, op));
}
@@ -240,17 +240,25 @@ fuse_main_compat2(int argc, char *argv[],
/* Main function of FUSE.
* named fuse_main_real, since originial fuse.h defines a macro renaming it */
int
-fuse_main_real(int argc, char *argv[],
- const struct fuse_operations *op, size_t op_size)
+fuse_main_real_compat22(int argc, char *argv[],
+ const struct fuse_operations_compat22 *op,
+ size_t op_size)
{
fuse_parse_argv(argc, argv);
- int fd = fuse_mount(NULL, NULL);
+ int fd = fuse_mount_compat22(NULL, NULL);
return (libfuse_params.disable_mt ? fuse_loop : fuse_loop_mt)
- (fuse_new(fd, NULL, op, op_size));
+ (fuse_new_compat22(fd, NULL, op, op_size));
}
+int
+fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,
+ size_t op_size)
+{
+ assert(0);
+}
+
/* Create a new FUSE filesystem, actually there's nothing for us to do
* on the Hurd.
@@ -267,7 +275,7 @@ fuse_new_compat2(int fd, const char *opts,
if(fuse_parse_opts(opts))
return NULL;
- fuse_ops_compat = op;
+ fuse_ops_compat2 = op;
return (void *) FUSE_MAGIC; /* we don't have a fuse structure, sorry. */
}
@@ -275,12 +283,23 @@ fuse_new_compat2(int fd, const char *opts,
/* Create a new FUSE filesystem, actually there's nothing for us to do
- * on the Hurd.
+ * on the Hurd. Hmm.
*/
struct fuse *
-fuse_new(int fd, const char *opts,
+fuse_new(int fd, struct fuse_args *args,
const struct fuse_operations *op, size_t op_size)
{
+ assert(0);
+}
+
+
+/* Create a new FUSE filesystem, actually there's nothing for us to do
+ * on the Hurd.
+ */
+struct fuse *
+fuse_new_compat22(int fd, const char *opts,
+ const struct fuse_operations_compat22 *op, size_t op_size)
+{
(void) op_size; /* FIXME, see what the real Fuse library does with
* this argument */
@@ -290,18 +309,24 @@ fuse_new(int fd, const char *opts,
if(fuse_parse_opts(opts))
return NULL;
- fuse_ops = op;
+ fuse_ops_compat22 = op;
return (void *) FUSE_MAGIC; /* we don't have a fuse structure, sorry. */
}
-
/* Create a new mountpoint for our fuse filesystem, i.e. do the netfs
* initialization stuff ...
*/
int
-fuse_mount(const char *mountpoint, const char *opts)
+fuse_mount(const char *mountpoint, struct fuse_args *args)
+{
+ assert(0);
+}
+
+
+int
+fuse_mount_compat22(const char *mountpoint, const char *opts)
{
(void) mountpoint; /* we don't care for the specified mountpoint, as
* we need to be set up using settrans ... */
diff --git a/src/netfs.c b/src/netfs.c
index 0fdb5c4a6..dd6ca32e2 100644
--- a/src/netfs.c
+++ b/src/netfs.c
@@ -369,8 +369,8 @@ netfs_check_open_permissions (struct iouser *user, struct node *node,
* into memory. */
if(! err)
{
- node->nn->info.flags = flags;
- if(flags & O_EXEC) node->nn->info.flags |= O_RDONLY;
+ node->nn->info.compat22.flags = flags;
+ if(flags & O_EXEC) node->nn->info.compat22.flags |= O_RDONLY;
}
out:
@@ -510,10 +510,11 @@ netfs_attempt_sync (struct iouser *cred, struct node *node, int wait)
goto out;
}
- if(fuse_ops)
- err = -fuse_ops->fsync(node->nn->path, 0, &node->nn->info);
+ if(fuse_ops_compat22)
+ err = -fuse_ops_compat22->fsync(node->nn->path, 0,
+ &node->nn->info.compat22);
else
- err = -fuse_ops_compat->fsync(node->nn->path, 0);
+ err = -fuse_ops_compat2->fsync(node->nn->path, 0);
if(! err)
node->nn->may_need_sync = 0;
@@ -1009,15 +1010,17 @@ error_t netfs_attempt_write (struct iouser *cred, struct node *node,
goto out;
}
- node->nn->info.writepage = 0; /* cannot distinct on the Hurd :( */
+ node->nn->info.compat22.writepage = 0; /* cannot distinct on the Hurd :( */
- if(fuse_ops && fuse_ops->open)
- if((err = fuse_ops->open(node->nn->path, &node->nn->info)))
+ if(fuse_ops_compat22 && fuse_ops_compat22->open)
+ if((err = fuse_ops_compat22->open(node->nn->path,
+ &node->nn->info.compat22)))
goto out;
- int sz = fuse_ops ?
- (fuse_ops->write(node->nn->path, data, *len, offset, &node->nn->info)) :
- (fuse_ops_compat->write(node->nn->path, data, *len, offset));
+ int sz = fuse_ops_compat22 ?
+ (fuse_ops_compat22->write(node->nn->path, data, *len,
+ offset, &node->nn->info.compat22)) :
+ (fuse_ops_compat2->write(node->nn->path, data, *len, offset));
/* FIXME: open, flush and release handling probably should be changed
* completely, I mean, we probably should do fuse_ops->open in
@@ -1026,11 +1029,12 @@ error_t netfs_attempt_write (struct iouser *cred, struct node *node,
*
* This way we wouldn't be able to report any errors back.
*/
- if(sz >= 0 && fuse_ops && fuse_ops->flush)
- err = fuse_ops->flush(node->nn->path, &node->nn->info);
+ if(sz >= 0 && fuse_ops_compat22 && fuse_ops_compat22->flush)
+ err = fuse_ops_compat22->flush(node->nn->path, &node->nn->info.compat22);
- if(fuse_ops && fuse_ops->open && fuse_ops->release)
- fuse_ops->release(node->nn->path, &node->nn->info);
+ if(fuse_ops_compat22 && fuse_ops_compat22->open
+ && fuse_ops_compat22->release)
+ fuse_ops_compat22->release(node->nn->path, &node->nn->info.compat22);
if(sz < 0)
err = -sz;
@@ -1108,13 +1112,15 @@ error_t netfs_attempt_read (struct iouser *cred, struct node *node,
goto out;
}
- if(fuse_ops && fuse_ops->open)
- if((err = fuse_ops->open(node->nn->path, &node->nn->info)))
+ if(fuse_ops_compat22 && fuse_ops_compat22->open)
+ if((err = fuse_ops_compat22->open(node->nn->path,
+ &node->nn->info.compat22)))
goto out;
- int sz = fuse_ops ?
- (fuse_ops->read(node->nn->path, data, *len, offset, &node->nn->info)) :
- (fuse_ops_compat->read(node->nn->path, data, *len, offset));
+ int sz = fuse_ops_compat22 ?
+ (fuse_ops_compat22->read(node->nn->path, data, *len,
+ offset, &node->nn->info.compat22)) :
+ (fuse_ops_compat2->read(node->nn->path, data, *len, offset));
/* FIXME: open, flush and release handling probably should be changed
* completely, I mean, we probably should do fuse_ops->open in
@@ -1123,11 +1129,12 @@ error_t netfs_attempt_read (struct iouser *cred, struct node *node,
*
* This way we wouldn't be able to report any errors back.
*/
- if(sz >= 0 && fuse_ops && fuse_ops->flush)
- err = fuse_ops->flush(node->nn->path, &node->nn->info);
+ if(sz >= 0 && fuse_ops_compat22 && fuse_ops_compat22->flush)
+ err = fuse_ops_compat22->flush(node->nn->path, &node->nn->info.compat22);
- if(fuse_ops && fuse_ops->open && fuse_ops->release)
- fuse_ops->release(node->nn->path, &node->nn->info);
+ if(fuse_ops_compat22 && fuse_ops_compat22->open
+ && fuse_ops_compat22->release)
+ fuse_ops_compat22->release(node->nn->path, &node->nn->info.compat22);
if(sz < 0)
err = -sz;
@@ -1164,10 +1171,10 @@ fuse_get_inode(const char *name)
{
struct stat stat;
- assert(fuse_ops);
- assert(fuse_ops->getattr);
+ assert(fuse_ops_compat22);
+ assert(fuse_ops_compat22->getattr);
- fuse_ops->getattr(name, &stat);
+ fuse_ops_compat22->getattr(name, &stat);
return stat.st_ino;
}
@@ -1316,10 +1323,11 @@ get_dirents_getdir(struct node *dir, int first_entry, int num_entries,
handle->parent = dir->nn;
handle->hdrpos = (struct dirent*) *data;
- if(fuse_ops)
- fuse_ops->getdir(dir->nn->path, handle, get_dirents_getdir_helper);
+ if(fuse_ops_compat22)
+ fuse_ops_compat22->getdir(dir->nn->path, handle,
+ get_dirents_getdir_helper);
else
- fuse_ops_compat->getdir(dir->nn->path, handle,
+ fuse_ops_compat2->getdir(dir->nn->path, handle,
get_dirents_getdir_helper_compat);
@@ -1449,7 +1457,7 @@ get_dirents_readdir(struct node *dir, int first_entry, int num_entries,
error_t err;
FUNC_PROLOGUE_NODE("get_dirents_readdir", dir);
- if(! (fuse_ops && fuse_ops->readdir))
+ if(! (fuse_ops_compat22 && fuse_ops_compat22->readdir))
FUNC_RETURN(EOPNOTSUPP);
fuse_dirh_t handle;
@@ -1479,20 +1487,22 @@ get_dirents_readdir(struct node *dir, int first_entry, int num_entries,
handle->parent = dir->nn;
handle->hdrpos = (struct dirent*) *data;
- if(fuse_ops->opendir
- && (err = fuse_ops->opendir(dir->nn->path, &dir->nn->info)))
+ if(fuse_ops_compat22->opendir
+ && (err = fuse_ops_compat22->opendir(dir->nn->path,
+ &dir->nn->info.compat22)))
goto out;
- if((err = fuse_ops->readdir(dir->nn->path, handle,
- get_dirents_readdir_helper, first_entry,
- &dir->nn->info)))
+ if((err = fuse_ops_compat22->readdir(dir->nn->path, handle,
+ get_dirents_readdir_helper,
+ first_entry, &dir->nn->info.compat22)))
{
- fuse_ops->releasedir(dir->nn->path, &dir->nn->info);
+ fuse_ops_compat22->releasedir(dir->nn->path, &dir->nn->info.compat22);
goto out;
}
- if(fuse_ops->releasedir
- && (err = fuse_ops->releasedir(dir->nn->path, &dir->nn->info)))
+ if(fuse_ops_compat22->releasedir
+ && (err = fuse_ops_compat22->releasedir(dir->nn->path,
+ &dir->nn->info.compat22)))
goto out;
*data_len -= handle->size; /* subtract number of bytes left in the
@@ -1526,7 +1536,7 @@ netfs_get_dirents (struct iouser *cred, struct node *dir,
goto out;
- if(fuse_ops && fuse_ops->readdir)
+ if(fuse_ops_compat22 && fuse_ops_compat22->readdir)
err = get_dirents_readdir(dir, first_entry, num_entries, data, data_len,
data_entries);
diff --git a/src/netnode.c b/src/netnode.c
index 9727097c1..dc9055262 100644
--- a/src/netnode.c
+++ b/src/netnode.c
@@ -152,9 +152,10 @@ fuse_sync_filesystem(void)
{
if(he->nn->may_need_sync)
{
- err = -(fuse_ops ?
- fuse_ops->fsync(he->nn->path, 0, &he->nn->info) :
- fuse_ops_compat->fsync(he->nn->path, 0));
+ err = -(fuse_ops_compat22 ?
+ fuse_ops_compat22->fsync(he->nn->path, 0,
+ &he->nn->info.compat22) :
+ fuse_ops_compat2->fsync(he->nn->path, 0));
if(err)
goto out;