+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
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) {
}
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;
# 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
* 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
size_t op_size, char **mountpoint,
int *multithreaded, int *fd);
+void fuse_unmount_compat22(const char *mountpoint);
+
#ifndef __FreeBSD__
#include <sys/statfs.h>
fuse_set_getcontext_func;
fuse_setup_compat2;
fuse_teardown;
- fuse_unmount;
};
FUSE_2.4 {
fuse_opt_insert_arg;
fuse_setup;
fuse_setup_compat25;
+ fuse_unmount;
+ fuse_unmount_compat22;
local:
*;
err_destroy:
fuse_destroy(fuse);
err_unmount:
- fuse_unmount(*mountpoint);
+ fuse_unmount(*mountpoint, *fd);
err_free:
free(*mountpoint);
return NULL;
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);
}
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;
}
__asm__(".symver fuse_mount_compat22,fuse_mount@FUSE_2.2");
+__asm__(".symver fuse_unmount_compat22,fuse_unmount@FUSE_2.2");
#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"
return 1;
}
-void fuse_unmount(const char *mountpoint)
+void fuse_unmount_compat22(const char *mountpoint)
{
char dev[128];
char *ssc, *umount_cmd;
(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;
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;
free(mo.kernel_opts);
return res;
}
+
+__asm__(".symver fuse_unmount_compat22,fuse_unmount@FUSE_2.2");