cleanups
authorMiklos Szeredi <miklos@szeredi.hu>
Tue, 6 Nov 2001 15:07:17 +0000 (15:07 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Tue, 6 Nov 2001 15:07:17 +0000 (15:07 +0000)
14 files changed:
.cvsignore
Makefile
fusepro.c [deleted file]
fusexmp.c [new file with mode: 0644]
include/fuse.h
include/linux/fuse.h
kernel/fuse_i.h
kernel/inode.c
kernel/util.c
lib/Makefile
lib/fuse.c
lib/fuse_i.h
lib/mount.c
usermux.c

index 5743e9b205f3ff72fdd5ff23bc45d08d3b654e05..d6dac71133122da36213b4f9b38741b405b94e3a 100644 (file)
@@ -1,2 +1,2 @@
-fusepro
+fusexmp
 avfsd
index 97d19d48b508e1cde3e9c520cb7accacc7b2ebb0..92d91ad9a76ff84f0f479bdfa7896931c124a185 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,14 +1,12 @@
 CC = gcc
 CFLAGS = -Wall -g `glib-config --cflags`
-LDFLAGS = `glib-config --libs` -ldl -L ../avfs/libneon/
+LDFLAGS = `glib-config --libs` -ldl -L ../avfs/libneon/ -L lib
 #LIBXML = -lxml
 LIBXML = -lxmltok -lxmlparse
-LDLIBS = -lneon $(LIBXML) -lpthread
+LDLIBS = -lneon $(LIBXML) -lfuse -lpthread
 CPPFLAGS = -Iinclude -I ../avfs/include
 
-
-
-all: kernel/fuse.o fusepro avfsd
+all: kernel/fuse.o fusexmp avfsd
 
 kernel/fuse.o: FORCE
        make -C kernel fuse.o
@@ -16,15 +14,21 @@ kernel/fuse.o: FORCE
 lib/libfuse.a: FORCE
        make -C lib libfuse.a
 
-fusepro: fusepro.o lib/libfuse.a
+lib/libfuse.so: FORCE
+       make -C lib libfuse.so
+
+fusexmp: fusexmp.o lib/libfuse.so
+       gcc $(CFLAGS) $(LDFLAGS) -o fusexmp fusexmp.o $(LDLIBS)
 
-avfsd: usermux.o avfsd.o ../avfs/lib/avfs.o lib/libfuse.a 
+avfsd_objs = usermux.o avfsd.o ../avfs/lib/avfs.o
+avfsd: $(avfsd_objs) lib/libfuse.so
+       gcc $(CFLAGS) $(LDFLAGS) -o avfsd $(avfsd_objs) $(LDLIBS)
 
 clean:
        make -C kernel clean
        make -C lib clean
        rm -f *.o
-       rm -f fusepro avfsd
+       rm -f fusexmp avfsd
        rm -f *~
 
 FORCE:
diff --git a/fusepro.c b/fusepro.c
deleted file mode 100644 (file)
index ce32000..0000000
--- a/fusepro.c
+++ /dev/null
@@ -1,314 +0,0 @@
-#ifdef linux
-/* For pread()/pwrite() */
-#define _XOPEN_SOURCE 500
-#endif
-
-#include <fuse.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <errno.h>
-#include <signal.h>
-#include <utime.h>
-#include <fcntl.h>
-
-static struct fuse *pro_fuse;
-
-static int pro_getattr(struct fuse_cred *cred, const char *path,
-                       struct stat *stbuf)
-{
-    int res;
-
-    res = lstat(path, stbuf);
-    if(res == -1)
-        return -errno;
-
-    return 0;
-}
-
-static int pro_readlink(struct fuse_cred *cred, 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 pro_getdir(struct fuse_cred *cred, const char *path, fuse_dirh_t h,
-                      fuse_dirfil_t filler)
-{
-    DIR *dp;
-    struct dirent *de;
-    int res;
-
-    dp = opendir(path);
-    if(dp == NULL)
-        return -errno;
-
-    while((de = readdir(dp)) != NULL) {
-        res = filler(h, de->d_name, de->d_type);
-        if(res != 0)
-            break;
-    }
-
-    closedir(dp);
-    return res;
-}
-
-static int pro_mknod(struct fuse_cred *cred, const char *path, mode_t mode,
-                     dev_t rdev)
-{
-    int res;
-
-    res = mknod(path, mode, rdev);
-    if(res == -1)
-        return -errno;
-
-    return 0;
-}
-
-static int pro_mkdir(struct fuse_cred *cred, const char *path, mode_t mode)
-{
-    int res;
-
-    res = mkdir(path, mode);
-    if(res == -1)
-        return -errno;
-
-    return 0;
-}
-
-static int pro_unlink(struct fuse_cred *cred, const char *path)
-{
-    int res;
-
-    res = unlink(path);
-    if(res == -1)
-        return -errno;
-
-    return 0;
-}
-
-static int pro_rmdir(struct fuse_cred *cred, const char *path)
-{
-    int res;
-
-    res = rmdir(path);
-    if(res == -1)
-        return -errno;
-
-    return 0;
-}
-
-static int pro_symlink(struct fuse_cred *cred, const char *from,
-                       const char *to)
-{
-    int res;
-
-    res = symlink(from, to);
-    if(res == -1)
-        return -errno;
-
-    return 0;
-}
-
-static int pro_rename(struct fuse_cred *cred, const char *from, const char *to)
-{
-    int res;
-
-    res = rename(from, to);
-    if(res == -1)
-        return -errno;
-
-    return 0;
-}
-
-static int pro_link(struct fuse_cred *cred, const char *from, const char *to)
-{
-    int res;
-
-    res = link(from, to);
-    if(res == -1)
-        return -errno;
-
-    return 0;
-}
-
-static int pro_chmod(struct fuse_cred *cred, const char *path, mode_t mode)
-{
-    int res;
-
-    res = chmod(path, mode);
-    if(res == -1)
-        return -errno;
-    
-    return 0;
-}
-
-static int pro_chown(struct fuse_cred *cred, 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 pro_truncate(struct fuse_cred *cred, const char *path, off_t size)
-{
-    int res;
-    
-    res = truncate(path, size);
-    if(res == -1)
-        return -errno;
-
-    return 0;
-}
-
-static int pro_utime(struct fuse_cred *cred, const char *path,
-                     struct utimbuf *buf)
-{
-    int res;
-    
-    res = utime(path, buf);
-    if(res == -1)
-        return -errno;
-
-    return 0;
-}
-
-
-static int pro_open(struct fuse_cred *cred, const char *path, int flags)
-{
-    int res;
-
-    res = open(path, flags);
-    if(res == -1) 
-        return -errno;
-
-    close(res);
-    return 0;
-}
-
-static int pro_read(struct fuse_cred *cred, const char *path, char *buf,
-                    size_t size, off_t offset)
-{
-    int fd;
-    int res;
-
-    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 pro_write(struct fuse_cred *cred, const char *path, const char *buf,
-                     size_t size, off_t offset)
-{
-    int fd;
-    int res;
-
-    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 void exit_handler()
-{
-    exit(0);
-}
-
-static void set_signal_handlers()
-{
-    struct sigaction sa;
-
-    sa.sa_handler = exit_handler;
-    sigemptyset(&(sa.sa_mask));
-    sa.sa_flags = 0;
-
-    if (sigaction(SIGHUP, &sa, NULL) == -1 || 
-       sigaction(SIGINT, &sa, NULL) == -1 || 
-       sigaction(SIGTERM, &sa, NULL) == -1) {
-       
-       perror("Cannot set exit signal handlers");
-        exit(1);
-    }
-
-    sa.sa_handler = SIG_IGN;
-    
-    if(sigaction(SIGPIPE, &sa, NULL) == -1) {
-       perror("Cannot set ignored signals");
-        exit(1);
-    }
-}
-
-static void cleanup()
-{
-    fuse_unmount(pro_fuse);
-    fuse_destroy(pro_fuse);
-}
-
-static struct fuse_operations pro_oper = {
-    getattr:   pro_getattr,
-    readlink:  pro_readlink,
-    getdir:     pro_getdir,
-    mknod:     pro_mknod,
-    mkdir:     pro_mkdir,
-    symlink:   pro_symlink,
-    unlink:    pro_unlink,
-    rmdir:     pro_rmdir,
-    rename:     pro_rename,
-    link:      pro_link,
-    chmod:     pro_chmod,
-    chown:     pro_chown,
-    truncate:  pro_truncate,
-    utime:     pro_utime,
-    open:      pro_open,
-    read:      pro_read,
-    write:     pro_write,
-};
-
-int main(int argc, char *argv[])
-{
-    int res;
-    if(argc != 2) {
-        fprintf(stderr, "usage: %s mount_dir\n", argv[0]);
-        exit(1);
-    }
-
-    set_signal_handlers();
-    atexit(cleanup);
-
-    pro_fuse = fuse_new(0);
-    res = fuse_mount(pro_fuse, argv[1]);
-    if(res == -1)
-        exit(1);
-        
-    fuse_set_operations(pro_fuse, &pro_oper);
-    fuse_loop(pro_fuse);
-
-    return 0;
-}
diff --git a/fusexmp.c b/fusexmp.c
new file mode 100644 (file)
index 0000000..b00039d
--- /dev/null
+++ b/fusexmp.c
@@ -0,0 +1,410 @@
+#ifdef linux
+/* For pread()/pwrite() */
+#define _XOPEN_SOURCE 500
+#endif
+
+/* For setgroups() */
+#define _BSD_SOURCE
+
+#include <fuse.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <errno.h>
+#include <signal.h>
+#include <utime.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <sys/fsuid.h>
+
+static struct fuse *xmp_fuse;
+
+static int set_creds(struct fuse_cred *cred)
+{
+    int res;
+
+    res = setfsuid(cred->uid);
+    if(res == -1)
+        return -errno;
+
+    res = setfsgid(cred->gid);
+    if(res == -1)
+        return -errno;
+
+    return 0;
+}
+
+static void restore_creds()
+{
+    setfsuid(getuid());
+    setfsgid(getgid());
+}
+
+static int xmp_getattr(struct fuse_cred *cred, const char *path,
+                       struct stat *stbuf)
+{
+    int res;
+
+    res = set_creds(cred);
+    if(res)
+        return res;
+    res = lstat(path, stbuf);
+    restore_creds();
+    if(res == -1)
+        return -errno;
+
+    return 0;
+}
+
+static int xmp_readlink(struct fuse_cred *cred, const char *path, char *buf,
+                        size_t size)
+{
+    int res;
+
+    res = set_creds(cred);
+    if(res)
+        return res;
+    res = readlink(path, buf, size - 1);
+    restore_creds();
+    if(res == -1)
+        return -errno;
+
+    buf[res] = '\0';
+    return 0;
+}
+
+
+static int xmp_getdir(struct fuse_cred *cred, const char *path, fuse_dirh_t h,
+                      fuse_dirfil_t filler)
+{
+    DIR *dp;
+    struct dirent *de;
+    int res;
+
+    res = set_creds(cred);
+    if(res)
+        return res;
+    dp = opendir(path);
+    restore_creds();
+    if(dp == NULL)
+        return -errno;
+
+    while((de = readdir(dp)) != NULL) {
+        res = filler(h, de->d_name, de->d_type);
+        if(res != 0)
+            break;
+    }
+
+    closedir(dp);
+    return res;
+}
+
+static int xmp_mknod(struct fuse_cred *cred, const char *path, mode_t mode,
+                     dev_t rdev)
+{
+    int res;
+
+    res = set_creds(cred);
+    if(res)
+        return res;
+    res = mknod(path, mode, rdev);
+    restore_creds();
+    if(res == -1)
+        return -errno;
+
+    return 0;
+}
+
+static int xmp_mkdir(struct fuse_cred *cred, const char *path, mode_t mode)
+{
+    int res;
+
+    res = set_creds(cred);
+    if(res)
+        return res;
+    res = mkdir(path, mode);
+    restore_creds();
+    if(res == -1)
+        return -errno;
+
+    return 0;
+}
+
+static int xmp_unlink(struct fuse_cred *cred, const char *path)
+{
+    int res;
+
+    res = set_creds(cred);
+    if(res)
+        return res;
+    res = unlink(path);
+    restore_creds();
+    if(res == -1)
+        return -errno;
+
+    return 0;
+}
+
+static int xmp_rmdir(struct fuse_cred *cred, const char *path)
+{
+    int res;
+
+    res = set_creds(cred);
+    if(res)
+        return res;
+    res = rmdir(path);
+    restore_creds();
+    if(res == -1)
+        return -errno;
+
+    return 0;
+}
+
+static int xmp_symlink(struct fuse_cred *cred, const char *from,
+                       const char *to)
+{
+    int res;
+
+    res = set_creds(cred);
+    if(res)
+        return res;
+    res = symlink(from, to);
+    restore_creds();
+    if(res == -1)
+        return -errno;
+
+    return 0;
+}
+
+static int xmp_rename(struct fuse_cred *cred, const char *from, const char *to)
+{
+    int res;
+
+    res = set_creds(cred);
+    if(res)
+        return res;
+    res = rename(from, to);
+    restore_creds();
+    if(res == -1)
+        return -errno;
+
+    return 0;
+}
+
+static int xmp_link(struct fuse_cred *cred, const char *from, const char *to)
+{
+    int res;
+
+    res = set_creds(cred);
+    if(res)
+        return res;
+    res = link(from, to);
+    restore_creds();
+    if(res == -1)
+        return -errno;
+
+    return 0;
+}
+
+static int xmp_chmod(struct fuse_cred *cred, const char *path, mode_t mode)
+{
+    int res;
+
+    res = set_creds(cred);
+    if(res)
+        return res;
+    res = chmod(path, mode);
+    restore_creds();
+    if(res == -1)
+        return -errno;
+    
+    return 0;
+}
+
+static int xmp_chown(struct fuse_cred *cred, const char *path, uid_t uid,
+                     gid_t gid)
+{
+    int res;
+
+    res = set_creds(cred);
+    if(res)
+        return res;
+    res = lchown(path, uid, gid);
+    restore_creds();
+    if(res == -1)
+        return -errno;
+
+    return 0;
+}
+
+static int xmp_truncate(struct fuse_cred *cred, const char *path, off_t size)
+{
+    int res;
+    
+    res = set_creds(cred);
+    if(res)
+        return res;
+    res = truncate(path, size);
+    restore_creds();
+    if(res == -1)
+        return -errno;
+
+    return 0;
+}
+
+static int xmp_utime(struct fuse_cred *cred, const char *path,
+                     struct utimbuf *buf)
+{
+    int res;
+    
+    res = set_creds(cred);
+    if(res)
+        return res;
+    res = utime(path, buf);
+    restore_creds();
+    if(res == -1)
+        return -errno;
+
+    return 0;
+}
+
+
+static int xmp_open(struct fuse_cred *cred, const char *path, int flags)
+{
+    int res;
+
+    res = set_creds(cred);
+    if(res)
+        return res;
+    res = open(path, flags);
+    restore_creds();
+    if(res == -1) 
+        return -errno;
+
+    close(res);
+    return 0;
+}
+
+static int xmp_read(struct fuse_cred *cred, const char *path, char *buf,
+                    size_t size, off_t offset)
+{
+    int fd;
+    int res;
+
+    res = set_creds(cred);
+    if(res)
+        return res;
+    fd = open(path, O_RDONLY);
+    restore_creds();
+    if(fd == -1)
+        return -errno;
+
+    res = pread(fd, buf, size, offset);
+    if(res == -1)
+        res = -errno;
+    
+    close(fd);
+    return res;
+}
+
+static int xmp_write(struct fuse_cred *cred, const char *path, const char *buf,
+                     size_t size, off_t offset)
+{
+    int fd;
+    int res;
+
+    res = set_creds(cred);
+    if(res)
+        return res;
+    fd = open(path, O_WRONLY);
+    restore_creds();
+    if(fd == -1)
+        return -errno;
+
+    res = pwrite(fd, buf, size, offset);
+    if(res == -1)
+        res = -errno;
+    
+    close(fd);
+    return res;
+}
+
+static void exit_handler()
+{
+    exit(0);
+}
+
+static void set_signal_handlers()
+{
+    struct sigaction sa;
+
+    sa.sa_handler = exit_handler;
+    sigemptyset(&(sa.sa_mask));
+    sa.sa_flags = 0;
+
+    if (sigaction(SIGHUP, &sa, NULL) == -1 || 
+       sigaction(SIGINT, &sa, NULL) == -1 || 
+       sigaction(SIGTERM, &sa, NULL) == -1) {
+       
+       perror("Cannot set exit signal handlers");
+        exit(1);
+    }
+
+    sa.sa_handler = SIG_IGN;
+    
+    if(sigaction(SIGPIPE, &sa, NULL) == -1) {
+       perror("Cannot set ignored signals");
+        exit(1);
+    }
+}
+
+static void cleanup()
+{
+    fuse_unmount(xmp_fuse);
+    fuse_destroy(xmp_fuse);
+}
+
+static struct fuse_operations xmp_oper = {
+    getattr:   xmp_getattr,
+    readlink:  xmp_readlink,
+    getdir:     xmp_getdir,
+    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,
+};
+
+int main(int argc, char *argv[])
+{
+    int res;
+    if(argc != 2) {
+        fprintf(stderr, "usage: %s mount_dir\n", argv[0]);
+        exit(1);
+    }
+
+    set_signal_handlers();
+    atexit(cleanup);
+    setgroups(0, NULL);
+
+    xmp_fuse = fuse_new(0,0);
+    res = fuse_mount(xmp_fuse, argv[1]);
+    if(res == -1)
+        exit(1);
+        
+    fuse_set_operations(xmp_fuse, &xmp_oper);
+
+    fuse_loop(xmp_fuse);
+
+    return 0;
+}
index 4edb0c7c3b63cbed80a128d77c532943e1820c1a..4cddaaf13168d024033ee5c33bd922f43cd5f6bb 100644 (file)
 #include <sys/stat.h>
 #include <utime.h>
 
+/** Handle for a FUSE filesystem */
 struct fuse;
+
+/** Handle for a getdir() operation */
 typedef struct fuse_dirhandle *fuse_dirh_t;
 
+/** Function to add an entry in a getdir() operation */
 typedef int (*fuse_dirfil_t) (fuse_dirh_t, const char *, int type);
 
+/** Credentials for an operation, these are determined by the fsuid
+    and fsgid of the calling process */
 struct fuse_cred {
     uid_t uid;
     gid_t gid;
+    /* FIXME: supplementary groups should also be included */
 };
 
+/**
+ * The file system operations:
+ *
+ * Most of these should work very similarly to the well known UNIX
+ * file system operations.  Exceptions are:
+ * 
+ *  - All operations get a fuse_cred structure by which the filesystem
+ *  implementation can check, whether the operation is permitted or
+ *  not.
+ * 
+ *  - All operations should return the negated error value (-errno) on
+ *  error.
+ * 
+ *  - readlink() should fill the buffer with a null terminated string.
+ *  The buffer size argument includes the space for the terminating
+ *  null character.  If the linkname is too long to fit in the buffer,
+ *  it should be truncated.  The return value should be 0 for success.
+ *
+ *  - getdir() is the opendir(), readdir(), ..., closedir() sequence
+ *  in one call. For each directory entry the filldir parameter should
+ *  be called. 
+ *
+ *  - There is no create() operation, mknod() will be called for
+ *  creation of all non directory, non symlink nodes.
+ *
+ *  - open() should not return a filehandle, but 0 on success.  No
+ *  creation, or trunctation flags (O_CREAT, O_EXCL, O_TRUNC) will be
+ *  passed to open().  Open should only check if the operation is
+ *  permitted for the given flags.
+ * 
+ *  - read(), write() are not passed a filehandle, but rather a
+ *  pathname.  The offset of the read and write is passed as the last
+ *  argument, like the pread() and pwrite() system calls.  */
 struct fuse_operations {
     int (*getattr)  (struct fuse_cred *, const char *, struct stat *);
     int (*readlink) (struct fuse_cred *, const char *, char *, size_t);
@@ -42,16 +82,64 @@ struct fuse_operations {
     int (*write)    (struct fuse_cred *, const char *, const char *, size_t, off_t);
 };
 
+/* FUSE flags: */
 #define FUSE_MULTITHREAD (1 << 0)
 
-struct fuse *fuse_new(int flags);
+/**
+ * Create a new FUSE filesystem. The filesystem is not yet mounted
+ *
+ * @param flags any combination of the FUSE flags defined above, or 0
+ * @param root the file type of the root node. 0 is the default (directory).
+ * @return the created FUSE handle
+ */
+struct fuse *fuse_new(int flags, mode_t root);
 
-int fuse_mount(struct fuse *f, const char *dir);
+/**
+ * Connect to the kernel and mount the filesystem.
+ * 
+ * @param f the FUSE handle
+ * @param mnt the mount point
+ * @return 0 on success -1 on failure
+ */
+int fuse_mount(struct fuse *f, const char *mnt);
 
+/**
+ * Set the filesystem operations. 
+ * 
+ * Operations which are initialised to NULL will return ENOSYS to the
+ * calling process.  This function can be called anytime after
+ * fuse_new() and before fuse_loop().
+ * 
+ * @param f the FUSE handle
+ * @param op the operations
+ */
 void fuse_set_operations(struct fuse *f, const struct fuse_operations *op);
 
+/**
+ * FUSE event loop.
+ *
+ * Requests from the kernel are processed, and the apropriate
+ * operations are called. 
+ *
+ * @param f the FUSE handle
+ */
 void fuse_loop(struct fuse *f);
 
+/**
+ * Disconnect from the kernel and unmount the filesystem
+ *
+ * @param f the FUSE handle
+ */
 int fuse_unmount(struct fuse *f);
 
+/**
+ * Destroy the filesystem. 
+ *
+ * The filesystem is not unmounted (call fuse_unmount() for that).
+ * After a fork() system call it is possible to call fuse_destroy() in
+ * one process, and leave the other process to service the filesystem
+ * requests.
+ *
+ * @param f the FUSE handle
+ */
 void fuse_destroy(struct fuse *f);
index a6e74dfbaf9f73d1a7295ff1f1abaa867c96523a..22897d42894d6655963eaeecec7d557049b9ad1b 100644 (file)
@@ -9,11 +9,12 @@
 /* This file defines the kernel interface of FUSE */
 
 
-#define FUSE_MOUNT_VERSION 1
+#define FUSE_KERNEL_VERSION 1
 
 struct fuse_mount_data {
        int version;
        int fd;
+       unsigned int rootmode;
 };
 
 #define FUSE_ROOT_INO 1
index b738bed07b8f702aee5eabdfe9ca4ab858f45ef2..b3f3a9cd77d2314e4eaa531df6cfcae254843a84 100644 (file)
@@ -12,8 +12,6 @@
 #include <linux/spinlock.h>
 #include <linux/rwsem.h>
 
-#define FUSE_VERSION "0.1"
-
 #define MAX_CLEARED 256
 
 /**
index 77e8469dfb68c5e6b0e1b3bfa1487fc7897dd584..5fb4a667ee06af9ead9d57bfa0823ab1c51677d1 100644 (file)
@@ -66,8 +66,8 @@ static struct fuse_conn *get_conn(struct fuse_mount_data *d)
                return NULL;
        }
 
-       if(d->version != FUSE_MOUNT_VERSION) {
-               printk("fuse_read_super: Bad mount version: %i\n", d->version);
+       if(d->version != FUSE_KERNEL_VERSION) {
+               printk("fuse_read_super: Bad version: %i\n", d->version);
                return NULL;
        }
 
@@ -89,12 +89,12 @@ static struct fuse_conn *get_conn(struct fuse_mount_data *d)
 
 }
 
-static struct inode *get_root_inode(struct super_block *sb)
+static struct inode *get_root_inode(struct super_block *sb, unsigned int mode)
 {
        struct fuse_attr attr;
        memset(&attr, 0, sizeof(attr));
 
-       attr.mode = S_IFDIR;
+       attr.mode = mode;
        return fuse_iget(sb, 1, &attr, 0);
 }
 
@@ -103,20 +103,21 @@ static struct super_block *fuse_read_super(struct super_block *sb,
 {      
        struct fuse_conn *fc;
        struct inode *root;
+       struct fuse_mount_data *d = data;
 
         sb->s_blocksize = 1024;
         sb->s_blocksize_bits = 10;
         sb->s_magic = FUSE_SUPER_MAGIC;
         sb->s_op = &fuse_super_operations;
 
-       root = get_root_inode(sb);
+       root = get_root_inode(sb, d->rootmode);
        if(root == NULL) {
                printk("fuse_read_super: failed to get root inode\n");
                return NULL;
        }
 
        spin_lock(&fuse_lock);
-       fc = get_conn(data);
+       fc = get_conn(d);
        if(fc == NULL)
                goto err;
 
index 57b1a90665bda064ef3d762ebb027d2a4408626e..9b7bec173d7ef17663dbcd93b1e1e18c8df8ef75 100644 (file)
@@ -12,8 +12,6 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 
-#define FUSE_VERSION "0.1"
-
 spinlock_t fuse_lock = SPIN_LOCK_UNLOCKED;
 
 /* Must be called with the fuse lock held */
@@ -28,7 +26,7 @@ int init_module(void)
 {
        int res;
 
-       printk(KERN_DEBUG "fuse init (version %s)\n", FUSE_VERSION);
+       printk(KERN_DEBUG "fuse init (version %i)\n", FUSE_KERNEL_VERSION);
 
        res = fuse_fs_init();
        if(res)
index e72a39d4439b6c3c7193ff1693492bf3e964994e..88b087a3cae6383b1b7e3b61d156675b974c1f3e 100644 (file)
@@ -1,16 +1,18 @@
 CC = gcc
-CFLAGS = -Wall -W -g `glib-config --cflags`
+CFLAGS = -Wall -W -g `glib-config --cflags` -fPIC
 LDFLAGS = `glib-config --libs`
 CPPFLAGS = -I../include
 
-
-all: libfuse.a
+all: libfuse.a libfuse.so
 
 libfuse_objs = mount.o fuse.o
 
 libfuse.a: $(libfuse_objs)
        ar cr libfuse.a $(libfuse_objs)
 
+libfuse.so: $(libfuse_objs)
+       gcc -shared -o libfuse.so $(libfuse_objs)
+
 clean:
        rm -f *.o *.a
        rm -f *~
index 137b5ef5ea1af812f1c229713c0da022602ae974..b12c58d2334fb25d90e2d4efbbcaf783176c5a9c 100644 (file)
@@ -407,6 +407,7 @@ static void do_readlink(struct fuse *f, struct fuse_in_header *in)
             res = f->op.readlink(&cred, path, link, sizeof(link));
         g_free(path);
     }
+    link[PATH_MAX] = '\0';
     send_reply(f, in, res, link, !res ? strlen(link) : 0);
 }
 
@@ -756,6 +757,17 @@ static void *do_command(void *data)
     return NULL;
 }
 
+/* This hack makes it possible to link FUSE with or without the
+   pthread library */
+__attribute__((weak))
+int pthread_create(pthread_t *thrid           __attribute__((unused)), 
+                   const pthread_attr_t *attr __attribute__((unused)), 
+                   void *(*func)(void *)      __attribute__((unused)),
+                   void *arg                  __attribute__((unused)))
+{
+    return ENOSYS;
+}
+
 void fuse_loop(struct fuse *f)
 {
     int res;
@@ -787,24 +799,35 @@ void fuse_loop(struct fuse *f)
         
         if(f->flags & FUSE_MULTITHREAD) {
             res = pthread_create(&thrid, &attr, do_command, cmd);
-            if(res != 0) {
-                fprintf(stderr, "Error creating thread: %s\n", 
-                        strerror(errno));
-                exit(1);
-            }
+            if(res == 0)
+                continue;
+            
+            fprintf(stderr, "Error creating thread: %s\n", strerror(res));
+            fprintf(stderr, "Will run in single thread mode\n");
+            f->flags &= ~FUSE_MULTITHREAD;
         }
-        else
-            do_command(cmd);
+
+        do_command(cmd);
     }
 }
 
-struct fuse *fuse_new(int flags)
+struct fuse *fuse_new(int flags, mode_t root)
 {
     struct fuse *f = g_new0(struct fuse, 1);
 
+    if(!root)
+        root = S_IFDIR;
+
+    if(!S_ISDIR(root) && !S_ISREG(root)) {
+        fprintf(stderr, "Invalid mode for root: 0%o\n", root);
+        root = S_IFDIR;
+    }
+    root &= S_IFMT;
+
     f->flags = flags;
+    f->rootmode = root;
     f->fd = -1;
-    f->dir = NULL;
+    f->mnt = NULL;
     f->nametab = g_hash_table_new((GHashFunc) name_hash,
                                   (GCompareFunc) name_compare);
     pthread_mutex_init(&f->lock, NULL);
index c28e2e899d2db89440652c834a222135550329db..6f363d8123a1e492f8a74bfcabfdc385368dc796 100644 (file)
@@ -25,7 +25,8 @@ struct node {
 
 struct fuse {
     int flags;
-    char *dir;
+    char *mnt;
+    mode_t rootmode;
     int fd;
     struct fuse_operations op;
     GHashTable *nametab;
index 48d9d45423f3d6eea38c7ecf07249cdc264e1d0d..98d9e591fd65c7a15cda2ca2c751e50198a79037 100644 (file)
 #include <sys/mount.h>
 #include <mntent.h>
 
-static int do_mount(const char *dev, const char *dir, const char *type, int fd)
+static int do_mount(const char *dev, const char *dir, const char *type,
+                    mode_t rootmode, int fd)
 {
     int res;
     struct fuse_mount_data data;
     
-    data.version = FUSE_MOUNT_VERSION;
+    data.version = FUSE_KERNEL_VERSION;
     data.fd = fd;
+    data.rootmode = rootmode;
 
     res = mount(dev, dir, type, MS_MGC_VAL | MS_NOSUID | MS_NODEV, &data);
     if(res == -1) {
@@ -100,7 +102,7 @@ int fuse_mount(struct fuse *f, const char *dir)
     const char *dev = FUSE_DEV;
     const char *type = "fuse";
 
-    if(f->dir != NULL)
+    if(f->mnt != NULL)
         return 0;
 
     f->fd = open(dev, O_RDWR);
@@ -109,12 +111,12 @@ int fuse_mount(struct fuse *f, const char *dir)
         return -1;
     }
     
-    res = do_mount(dev, dir, type, f->fd);
+    res = do_mount(dev, dir, type, f->rootmode, f->fd);
     if(res == -1)
         return -1;
 
     add_mntent(dev, dir, type);
-    f->dir = g_strdup(dir);
+    f->mnt = g_strdup(dir);
     
     return 0;
 }
@@ -123,20 +125,20 @@ int fuse_unmount(struct fuse *f)
 {
     int res;
 
-    if(f->dir == NULL)
+    if(f->mnt == NULL)
         return 0;
 
     close(f->fd);
     f->fd = -1;
 
-    res = umount(f->dir);
+    res = umount(f->mnt);
     if(res == -1)
         perror("umount failed");
     else
-        remove_mntent(f->dir);
+        remove_mntent(f->mnt);
 
-    g_free(f->dir);
-    f->dir = NULL;
+    g_free(f->mnt);
+    f->mnt = NULL;
 
     return res;
 }
index 4caacb98fa8278a747a7ca1c427b9ad621bbfc90..f2f11f3dc43d4b122b6309863f95b43c145a4eb0 100644 (file)
--- a/usermux.c
+++ b/usermux.c
@@ -50,7 +50,7 @@ static void start_avfs(uid_t uid)
     if(pw == NULL)
         return;
 
-    user_fuse = fuse_new(0);
+    user_fuse = fuse_new(FUSE_MULTITHREAD, 0);
     
     userdir = g_strdup_printf("%s/%010u", MOUNTDIR, uid);
     mkdir(userdir, 0755);
@@ -240,7 +240,7 @@ int main(int argc, char *argv[])
     set_signal_handlers();
     atexit(cleanup);
 
-    um_fuse = fuse_new(0);
+    um_fuse = fuse_new(FUSE_MULTITHREAD, 0);
     res = fuse_mount(um_fuse, um_dir);
     if(res == -1)
         exit(1);