aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCsaba Henk <csaba.henk@creo.hu>2006-03-01 09:40:35 +0000
committerCsaba Henk <csaba.henk@creo.hu>2006-03-01 09:40:35 +0000
commitee588c01dca3991807aea456a66246ff8ad0c332 (patch)
tree495e5e37dc07b9049df2650a5866eaf80d7d145d
parentaa8258e9fb887d45c0a5754f158015e035ce37bc (diff)
downloadlibfuse-ee588c01dca3991807aea456a66246ff8ad0c332.tar.gz
pass device file descriptor to fuse_unmount
-rw-r--r--ChangeLog7
-rw-r--r--example/hello_ll.c7
-rw-r--r--include/fuse.h1
-rw-r--r--include/fuse_common.h3
-rw-r--r--include/fuse_compat.h2
-rw-r--r--lib/fuse_versionscript3
-rw-r--r--lib/helper.c6
-rw-r--r--lib/mount.c10
-rw-r--r--lib/mount_bsd.c39
9 files changed, 67 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 43a0e7d..c08d4c9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2006-03-01 Csaba Henk <csaba.henk@creo.hu>
+
+ * libfuse: pass device file descriptor to fuse_unmount(), rewrite
+ FreeBSD implementation so that it uses libc (sysctl backed) instead
+ of an embdedded script (kmem backed). Adjust the control flow of
+ hello_ll so that device doesn't get closed before unmount attempt.
+
2006-02-25 Miklos Szeredi <miklos@szeredi.hu>
* Lowlevel lib: return all-zero statvfs data if filesystem doesn't
diff --git a/example/hello_ll.c b/example/hello_ll.c
index 2213285..531d1c9 100644
--- a/example/hello_ll.c
+++ b/example/hello_ll.c
@@ -151,7 +151,7 @@ int main(int argc, char *argv[])
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
char *mountpoint;
int err = -1;
- int fd;
+ int fd = -1;
if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) != -1 &&
(fd = fuse_mount(mountpoint, &args)) != -1) {
@@ -168,11 +168,14 @@ int main(int argc, char *argv[])
}
fuse_remove_signal_handlers(se);
}
+ fuse_unmount(mountpoint, fd);
fuse_session_destroy(se);
+ goto out;
}
close(fd);
}
- fuse_unmount(mountpoint);
+ fuse_unmount(mountpoint, fd);
+out:
fuse_opt_free_args(&args);
return err ? 1 : 0;
diff --git a/include/fuse.h b/include/fuse.h
index b6ecaef..6c0bb72 100644
--- a/include/fuse.h
+++ b/include/fuse.h
@@ -562,6 +562,7 @@ void fuse_set_getcontext_func(struct fuse_context *(*func)(void));
# define fuse_operations fuse_operations_compat22
# define fuse_file_info fuse_file_info_compat22
# define fuse_mount fuse_mount_compat22
+# define fuse_unmount fuse_unmount_compat22
# else
# define fuse_dirfil_t fuse_dirfil_t_compat
# define __fuse_read_cmd fuse_read_cmd
diff --git a/include/fuse_common.h b/include/fuse_common.h
index 191b6f9..f05d237 100644
--- a/include/fuse_common.h
+++ b/include/fuse_common.h
@@ -91,8 +91,9 @@ int fuse_mount(const char *mountpoint, struct fuse_args *args);
* Umount a FUSE mountpoint
*
* @param mountpoint the mount point path
+ * @param the control file descriptor
*/
-void fuse_unmount(const char *mountpoint);
+void fuse_unmount(const char *mountpoint, int fd);
/**
* Parse common options
diff --git a/include/fuse_compat.h b/include/fuse_compat.h
index 97f7b12..ef7ff67 100644
--- a/include/fuse_compat.h
+++ b/include/fuse_compat.h
@@ -62,6 +62,8 @@ struct fuse *fuse_setup_compat25(int argc, char *argv[],
size_t op_size, char **mountpoint,
int *multithreaded, int *fd);
+void fuse_unmount_compat22(const char *mountpoint);
+
#ifndef __FreeBSD__
#include <sys/statfs.h>
diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript
index b6e6e18..02ac176 100644
--- a/lib/fuse_versionscript
+++ b/lib/fuse_versionscript
@@ -20,7 +20,6 @@ FUSE_2.2 {
fuse_set_getcontext_func;
fuse_setup_compat2;
fuse_teardown;
- fuse_unmount;
};
FUSE_2.4 {
@@ -95,6 +94,8 @@ FUSE_2.6 {
fuse_opt_insert_arg;
fuse_setup;
fuse_setup_compat25;
+ fuse_unmount;
+ fuse_unmount_compat22;
local:
*;
diff --git a/lib/helper.c b/lib/helper.c
index f937366..a5935de 100644
--- a/lib/helper.c
+++ b/lib/helper.c
@@ -225,7 +225,7 @@ static struct fuse *fuse_setup_common(int argc, char *argv[],
err_destroy:
fuse_destroy(fuse);
err_unmount:
- fuse_unmount(*mountpoint);
+ fuse_unmount(*mountpoint, *fd);
err_free:
free(*mountpoint);
return NULL;
@@ -242,10 +242,8 @@ struct fuse *fuse_setup(int argc, char *argv[],
void fuse_teardown(struct fuse *fuse, int fd, char *mountpoint)
{
- (void) fd;
-
fuse_remove_signal_handlers(fuse_get_session(fuse));
- fuse_unmount(mountpoint);
+ fuse_unmount(mountpoint, fd);
fuse_destroy(fuse);
free(mountpoint);
}
diff --git a/lib/mount.c b/lib/mount.c
index 0a14df3..a1875f0 100644
--- a/lib/mount.c
+++ b/lib/mount.c
@@ -166,11 +166,18 @@ static int receive_fd(int fd)
return *(int*)CMSG_DATA(cmsg);
}
-void fuse_unmount(const char *mountpoint)
+void fuse_unmount_compat22(const char *mountpoint)
+{
+ fuse_unmount(mountpoint, -1);
+}
+
+void fuse_unmount(const char *mountpoint, int fd)
{
const char *mountprog = FUSERMOUNT_PROG;
int pid;
+ (void) fd;
+
if (!mountpoint)
return;
@@ -293,3 +300,4 @@ int fuse_mount_compat1(const char *mountpoint, const char *args[])
}
__asm__(".symver fuse_mount_compat22,fuse_mount@FUSE_2.2");
+__asm__(".symver fuse_unmount_compat22,fuse_unmount@FUSE_2.2");
diff --git a/lib/mount_bsd.c b/lib/mount_bsd.c
index cb1b2b9..c5661d2 100644
--- a/lib/mount_bsd.c
+++ b/lib/mount_bsd.c
@@ -9,14 +9,16 @@
#include "fuse.h"
#include "fuse_opt.h"
+#include <sys/stat.h>
+#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stddef.h>
#include <fcntl.h>
#include <errno.h>
-#include <sys/wait.h>
#include <string.h>
+#include <paths.h>
#define FUSERMOUNT_PROG "mount_fusefs"
#define FUSE_DEV_TRUNK "/dev/fuse"
@@ -154,7 +156,7 @@ static int fuse_mount_opt_proc(void *data, const char *arg, int key,
return 1;
}
-void fuse_unmount(const char *mountpoint)
+void fuse_unmount_compat22(const char *mountpoint)
{
char dev[128];
char *ssc, *umount_cmd;
@@ -171,6 +173,14 @@ void fuse_unmount(const char *mountpoint)
(void) mountpoint;
+ /*
+ * If we don't know the fd, we have to resort to the scripted solution --
+ * iterating over the fd-s is unpractical, as we don't know how many of
+ * open files we have. (This could be looked up in procfs -- however,
+ * that's optional on FBSD; or read out from the kmem -- however, that's
+ * bound to privileges (in fact, that's what happens when we call the
+ * setgid kmem fstat(1) utility).
+ */
asprintf(&ssc, seekscript, getpid());
errno = 0;
@@ -187,6 +197,29 @@ void fuse_unmount(const char *mountpoint)
system(umount_cmd);
}
+void fuse_unmount(const char *mountpoint, int fd)
+{
+ char *ep, *umount_cmd, dev[128];
+ struct stat sbuf;
+
+ (void)mountpoint;
+
+ if (fstat(fd, &sbuf) == -1)
+ return;
+
+ devname_r(sbuf.st_rdev, S_IFCHR, dev, 128);
+
+ if (strncmp(dev, "fuse", 4))
+ return;
+
+ strtol(dev + 4, &ep, 10);
+ if (*ep != '\0')
+ return;
+
+ asprintf(&umount_cmd, "/sbin/umount " _PATH_DEV "%s", dev);
+ system(umount_cmd);
+}
+
static int fuse_mount_core(const char *mountpoint, const char *opts)
{
const char *mountprog = FUSERMOUNT_PROG;
@@ -299,3 +332,5 @@ int fuse_mount(const char *mountpoint, struct fuse_args *args)
free(mo.kernel_opts);
return res;
}
+
+__asm__(".symver fuse_unmount_compat22,fuse_unmount@FUSE_2.2");