fix
diff --git a/ChangeLog b/ChangeLog
index cd1da1d..162916e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,15 @@
2004-02-20 Miklos Szeredi <mszeredi@inf.bme.hu>
+ * removed old way of mounting (fusermount mountpoint program)
+
* more kernel interface changes:
* added nanosecond precision to file times
+ * removed interface version from mount data
+
+ * added /proc/fs/fuse/version which contains MAJOR.MINOR
+
2004-02-19 Miklos Szeredi <mszeredi@inf.bme.hu>
* statfs library API changed to match other methods. Since this
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index 10ef186..834c1be 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -20,11 +20,11 @@
/** Opening this will yield a new control file */
#define FUSE_DEV "/proc/fs/fuse/dev"
+/** The file containing the version in the form MAJOR.MINOR */
+#define FUSE_VERSION_FILE "/proc/fs/fuse/version"
+
/** Data passed to mount */
struct fuse_mount_data {
- /** Must be set to FUSE_KERNEL_VERSION */
- int version;
-
/** The control file descriptor */
int fd;
diff --git a/kernel/dev.c b/kernel/dev.c
index a31615d..43af356 100644
--- a/kernel/dev.c
+++ b/kernel/dev.c
@@ -611,10 +611,17 @@
.release = fuse_dev_release,
};
+static int read_version(char *page, char **start, off_t off, int count,
+ int *eof, void *data)
+{
+ char *s = page;
+ s += sprintf(s, "%i.%i\n", FUSE_KERNEL_VERSION,
+ FUSE_KERNEL_MINOR_VERSION);
+ return s - page;
+}
+
int fuse_dev_init()
{
- int ret;
-
proc_fs_fuse = NULL;
proc_fuse_dev = NULL;
@@ -624,33 +631,31 @@
if(!fuse_req_cachep)
return -ENOMEM;
- ret = -ENOMEM;
proc_fs_fuse = proc_mkdir("fuse", proc_root_fs);
- if(!proc_fs_fuse) {
- printk("fuse: failed to create directory in /proc/fs\n");
- goto err;
+ if(proc_fs_fuse) {
+ struct proc_dir_entry *de;
+
+ proc_fs_fuse->owner = THIS_MODULE;
+ proc_fuse_dev = create_proc_entry("dev", S_IFSOCK | 0666,
+ proc_fs_fuse);
+ if(proc_fuse_dev) {
+ proc_fuse_dev->owner = THIS_MODULE;
+ proc_fuse_dev->proc_fops = &fuse_dev_operations;
+ }
+ de = create_proc_entry("version", S_IFREG | 0444, proc_fs_fuse);
+ if (de) {
+ de->owner = THIS_MODULE;
+ de->read_proc = read_version;
+ }
}
-
- proc_fs_fuse->owner = THIS_MODULE;
- proc_fuse_dev = create_proc_entry("dev", S_IFSOCK | 0666, proc_fs_fuse);
- if(!proc_fuse_dev) {
- printk("fuse: failed to create entry in /proc/fs/fuse\n");
- goto err;
- }
-
- proc_fuse_dev->proc_fops = &fuse_dev_operations;
-
return 0;
-
- err:
- fuse_dev_cleanup();
- return ret;
}
void fuse_dev_cleanup()
{
if(proc_fs_fuse) {
remove_proc_entry("dev", proc_fs_fuse);
+ remove_proc_entry("version", proc_fs_fuse);
remove_proc_entry("fuse", proc_root_fs);
}
diff --git a/kernel/inode.c b/kernel/inode.c
index 08bf3c9..8f82029 100644
--- a/kernel/inode.c
+++ b/kernel/inode.c
@@ -119,11 +119,6 @@
return NULL;
}
- if(d->version != FUSE_KERNEL_VERSION) {
- printk("fuse_read_super: Bad version: %i\n", d->version);
- return NULL;
- }
-
file = fget(d->fd);
ino = NULL;
if(file)
diff --git a/lib/fuse.c b/lib/fuse.c
index 2e6950d..9d0783d 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -1106,6 +1106,9 @@
void fuse_loop(struct fuse *f)
{
+ if(f == NULL)
+ return;
+
while(1) {
struct fuse_cmd *cmd;
@@ -1133,6 +1136,35 @@
return &f->context;
}
+static int check_version(struct fuse *f)
+{
+ int res;
+ FILE *vf = fopen(FUSE_VERSION_FILE, "r");
+ if(vf == NULL) {
+ fprintf(stderr, "fuse: kernel interface too old, need >= %i.%i\n",
+ FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
+ return -1;
+ }
+ res = fscanf(vf, "%i.%i", &f->majorver, &f->minorver);
+ fclose(vf);
+ if(res != 2) {
+ fprintf(stderr, "fuse: error reading %s\n", FUSE_VERSION_FILE);
+ return -1;
+ }
+ if(f->majorver != FUSE_KERNEL_VERSION) {
+ fprintf(stderr, "fuse: bad kernel interface major version: needs %i\n",
+ FUSE_KERNEL_VERSION);
+ return -1;
+ }
+ if(f->minorver < FUSE_KERNEL_MINOR_VERSION) {
+ fprintf(stderr, "fuse: kernel interface too old: need >= %i.%i",
+ FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
+ return -1;
+ }
+
+ return 0;
+}
+
struct fuse *fuse_new(int fd, int flags, const struct fuse_operations *op)
{
struct fuse *f;
@@ -1140,6 +1172,11 @@
f = (struct fuse *) calloc(1, sizeof(struct fuse));
+ if(check_version(f) == -1) {
+ free(f);
+ return NULL;
+ }
+
f->flags = flags;
f->fd = fd;
f->ctr = 0;
diff --git a/lib/fuse_i.h b/lib/fuse_i.h
index 4eaa5ba..ce81604 100644
--- a/lib/fuse_i.h
+++ b/lib/fuse_i.h
@@ -41,6 +41,8 @@
struct fuse_context context;
pthread_key_t context_key;
volatile int exited;
+ int majorver;
+ int minorver;
};
struct fuse_dirhandle {
diff --git a/lib/fuse_mt.c b/lib/fuse_mt.c
index f1a2e5c..40da6ed 100644
--- a/lib/fuse_mt.c
+++ b/lib/fuse_mt.c
@@ -114,5 +114,8 @@
void fuse_loop_mt(struct fuse *f)
{
+ if(f == NULL)
+ return;
+
__fuse_loop_mt(f, (fuse_processor_t) __fuse_process_cmd, NULL);
}
diff --git a/lib/helper.c b/lib/helper.c
index d417d90..7cbb9eb 100644
--- a/lib/helper.c
+++ b/lib/helper.c
@@ -15,9 +15,6 @@
#include <limits.h>
#include <signal.h>
-#define FUSE_MOUNTED_ENV "_FUSE_MOUNTED"
-#define FUSE_UMOUNT_CMD_ENV "_FUSE_UNMOUNT_CMD"
-
static struct fuse *fuse;
static void usage(char *progname)
@@ -73,21 +70,14 @@
void fuse_main(int argc, char *argv[], const struct fuse_operations *op)
{
- int argctr = 1;
+ int argctr = 2;
int flags;
int multithreaded;
- char *isreexec = getenv(FUSE_MOUNTED_ENV);
int fuse_fd;
char *fuse_mountpoint = NULL;
char umount_cmd[1024] = "";
char **fusermount_args = NULL;
- if(!isreexec) {
- if(argc < 2 || argv[1][0] == '-')
- usage(argv[0]);
- argctr ++;
- }
-
flags = 0;
multithreaded = 1;
for(; argctr < argc && !fusermount_args; argctr ++) {
@@ -106,10 +96,7 @@
break;
case '-':
- if(!isreexec)
- fusermount_args = &argv[argctr+1];
- else
- invalid_option(argv, argctr);
+ fusermount_args = &argv[argctr+1];
break;
default:
@@ -119,30 +106,16 @@
invalid_option(argv, argctr);
}
- if(!isreexec) {
- fuse_mountpoint = strdup(argv[1]);
- fuse_fd = fuse_mount(fuse_mountpoint, (const char **) fusermount_args);
- if(fuse_fd == -1)
- exit(1);
- } else {
- char *tmpstr;
-
- /* Old (obsolescent) way of doing the mount:
-
- fusermount [options] mountpoint [program [args ...]]
-
- fusermount execs this program and passes the control file
- descriptor dup()-ed to stdin */
- fuse_fd = 0;
-
- tmpstr = getenv(FUSE_UMOUNT_CMD_ENV);
- if(tmpstr != NULL)
- strncpy(umount_cmd, tmpstr, sizeof(umount_cmd) - 1);
- }
+ fuse_mountpoint = strdup(argv[1]);
+ fuse_fd = fuse_mount(fuse_mountpoint, (const char **) fusermount_args);
+ if(fuse_fd == -1)
+ exit(1);
set_signal_handlers();
fuse = fuse_new(fuse_fd, flags, op);
+ if(fuse == NULL)
+ exit(1);
if(multithreaded)
fuse_loop_mt(fuse);
diff --git a/util/fusermount.c b/util/fusermount.c
index ee4c005..6d27372 100644
--- a/util/fusermount.c
+++ b/util/fusermount.c
@@ -37,9 +37,6 @@
#define FUSE_DEV "/proc/fs/fuse/dev"
-#define FUSE_MOUNTED_ENV "_FUSE_MOUNTED"
-#define FUSE_UMOUNT_CMD_ENV "_FUSE_UNMOUNT_CMD"
-#define FUSE_KERNEL_VERSION_ENV "_FUSE_KERNEL_VERSION"
#define FUSE_COMMFD_ENV "_FUSE_COMMFD"
const char *progname;
@@ -303,7 +300,6 @@
return -1;
}
- data.version = FUSE_KERNEL_VERSION;
data.fd = fd;
data.rootmode = rootmode;
data.uid = getuid();
@@ -476,7 +472,7 @@
static void usage()
{
fprintf(stderr,
- "%s: [options] mountpoint [program [args ...]]\n"
+ "%s: [options] mountpoint\n"
"Options:\n"
" -h print help\n"
" -u unmount\n"
@@ -498,15 +494,11 @@
char *origmnt;
char *mnt;
int unmount = 0;
- char **userprog;
- int numargs;
- char mypath[PATH_MAX];
- char *unmount_cmd;
char *commfd;
const char *fsname = NULL;
- char verstr[128];
int flags = 0;
int quiet = 0;
+ int cfd;
progname = argv[0];
@@ -599,60 +591,19 @@
}
commfd = getenv(FUSE_COMMFD_ENV);
-
- if(a == argc && commfd == NULL) {
- fprintf(stderr, "%s: Missing program argument\n", progname);
+ if(commfd == NULL) {
+ fprintf(stderr, "%s: old style mounting not supported\n", progname);
exit(1);
}
-
- userprog = argv + a;
- numargs = argc - a;
-
+
fd = mount_fuse(mnt, flags, fsname);
if(fd == -1)
exit(1);
- if(commfd != NULL) {
- int cfd = atoi(commfd);
- res = send_fd(cfd, fd);
- if(res == -1)
- exit(1);
- exit(0);
- }
+ cfd = atoi(commfd);
+ res = send_fd(cfd, fd);
+ if(res == -1)
+ exit(1);
- /* Dup the file descriptor to stdin */
- if(fd != 0) {
- dup2(fd, 0);
- close(fd);
- }
-
- /* Strangely this doesn't work after dropping permissions... */
- res = readlink("/proc/self/exe", mypath, sizeof(mypath) - 1);
- if(res == -1) {
- fprintf(stderr, "%s: failed to determine self path: %s\n",
- progname, strerror(errno));
- strcpy(mypath, "fusermount");
- fprintf(stderr, "using %s as the default\n", mypath);
- }
- else
- mypath[res] = '\0';
-
- /* Drop setuid/setgid permissions */
- setuid(getuid());
- setgid(getgid());
-
- unmount_cmd = (char *) malloc(strlen(mypath) + strlen(mnt) + 64);
- sprintf(unmount_cmd, "%s -u -q %s", mypath, mnt);
- setenv(FUSE_UMOUNT_CMD_ENV, unmount_cmd, 1);
- sprintf(verstr, "%i", FUSE_KERNEL_VERSION);
- setenv(FUSE_KERNEL_VERSION_ENV, verstr, 1);
- setenv(FUSE_MOUNTED_ENV, "", 1);
-
- execvp(userprog[0], userprog);
- fprintf(stderr, "%s: failed to exec %s: %s\n", progname, userprog[0],
- strerror(errno));
-
- close(0);
- system(unmount_cmd);
- return 1;
+ return 0;
}