From b3f9972a859e95cf836c0044c82fcf312afc566e Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 16 Nov 2005 13:00:24 +0000 Subject: [PATCH] merge FreeBSD stuff --- ChangeLog | 4 ++ Makefile.am | 2 +- configure.in | 22 ++++++- example/fusexmp.c | 63 +++++++++++--------- example/fusexmp_fh.c | 63 +++++++++++--------- kernel/fuse_kernel.h | 7 +++ lib/Makefile.am | 8 ++- lib/fuse.c | 21 ++++++- lib/fuse_lowlevel.c | 2 +- lib/helper.c | 2 +- lib/mount_bsd.c | 133 +++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 264 insertions(+), 63 deletions(-) create mode 100644 lib/mount_bsd.c diff --git a/ChangeLog b/ChangeLog index 46c519a..0c99a0d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2005-11-16 Miklos Szeredi + + * Merge library part of FreeBSD port. Patch by Csaba Henk + 2005-11-11 Miklos Szeredi * Use 64bit type for file handle, so the full range supported by diff --git a/Makefile.am b/Makefile.am index caeaed7..a0da48e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -10,7 +10,7 @@ EXTRA_DIST = \ doc/how-fuse-works \ doc/kernel.txt -pkgconfigdir = $(libdir)/pkgconfig +pkgconfigdir = @pkgconfigdir@ pkgconfig_DATA = fuse.pc $(pkgconfig_DATA): config.status diff --git a/configure.in b/configure.in index 633d436..bdd9502 100644 --- a/configure.in +++ b/configure.in @@ -1,4 +1,5 @@ AC_INIT(fuse, 2.5.0-pre0) +AC_CANONICAL_TARGET AM_INIT_AUTOMAKE AM_CONFIG_HEADER(include/config.h) @@ -13,6 +14,12 @@ if test -z "$mkdir_p"; then AC_SUBST(mkdir_p) fi +case $target_os in + *linux*) arch=linux;; + *bsd*) arch=bsd;; + *) arch=unknown;; +esac + if test "$ac_env_CFLAGS_set" != set; then CFLAGS="-Wall -W -g -O2" fi @@ -29,16 +36,22 @@ AC_ARG_ENABLE(example, AC_ARG_ENABLE(mtab, [ --disable-mtab Disable and ignore usage of /etc/mtab ]) +AC_ARG_WITH(pkgconfigdir, + [ --with-pkgconfigdir=DIR pkgconfig file in DIR @<:@LIBDIR/pkgconfig@:>@], + [pkgconfigdir=$withval], + [pkgconfigdir='${libdir}/pkgconfig']) +AC_SUBST(pkgconfigdir) + subdirs2="include" -if test "$enable_kernel_module" != "no"; then +if test "$arch" = linux -a "$enable_kernel_module" != "no"; then AC_CONFIG_SUBDIRS(kernel) fi if test "$enable_lib" != "no"; then subdirs2="$subdirs2 lib"; fi -if test "$enable_util" != "no"; then +if test "$arch" = linux -a "$enable_util" != "no"; then subdirs2="$subdirs2 util"; fi if test "$enable_example" != "no"; then @@ -47,7 +60,7 @@ fi if test "$enable_mtab" = "no"; then AC_DEFINE(IGNORE_MTAB, 1, [Don't update /etc/mtab]) fi -AC_CHECK_FUNCS([fork setxattr]) +AC_CHECK_FUNCS([fork setxattr fdatasync]) AC_CHECK_MEMBERS([struct stat.st_atim]) if test -z "$MOUNT_FUSE_PATH"; then @@ -61,5 +74,8 @@ AC_SUBST(UDEV_RULES_PATH) AC_SUBST(subdirs2) +AM_CONDITIONAL(LINUX, test "$arch" = linux) +AM_CONDITIONAL(BSD, test "$arch" = bsd) + AC_CONFIG_FILES([fuse.pc Makefile lib/Makefile util/Makefile example/Makefile include/Makefile]) AC_OUTPUT diff --git a/example/fusexmp.c b/example/fusexmp.c index 5a2e9a0..26b2be2 100644 --- a/example/fusexmp.c +++ b/example/fusexmp.c @@ -29,7 +29,7 @@ static int xmp_getattr(const char *path, struct stat *stbuf) int res; res = lstat(path, stbuf); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -40,7 +40,7 @@ static int xmp_access(const char *path, int mask) int res; res = access(path, mask); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -51,7 +51,7 @@ static int xmp_readlink(const char *path, char *buf, size_t size) int res; res = readlink(path, buf, size - 1); - if(res == -1) + if (res == -1) return -errno; buf[res] = '\0'; @@ -69,10 +69,10 @@ static int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler, (void) fi; dp = opendir(path); - if(dp == NULL) + if (dp == NULL) return -errno; - while((de = readdir(dp)) != NULL) { + while ((de = readdir(dp)) != NULL) { struct stat st; memset(&st, 0, sizeof(st)); st.st_ino = de->d_ino; @@ -89,8 +89,17 @@ static int xmp_mknod(const char *path, mode_t mode, dev_t rdev) { int res; - res = mknod(path, mode, rdev); - if(res == -1) + /* 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; @@ -101,7 +110,7 @@ static int xmp_mkdir(const char *path, mode_t mode) int res; res = mkdir(path, mode); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -112,7 +121,7 @@ static int xmp_unlink(const char *path) int res; res = unlink(path); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -123,7 +132,7 @@ static int xmp_rmdir(const char *path) int res; res = rmdir(path); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -134,7 +143,7 @@ static int xmp_symlink(const char *from, const char *to) int res; res = symlink(from, to); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -145,7 +154,7 @@ static int xmp_rename(const char *from, const char *to) int res; res = rename(from, to); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -156,7 +165,7 @@ static int xmp_link(const char *from, const char *to) int res; res = link(from, to); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -167,7 +176,7 @@ static int xmp_chmod(const char *path, mode_t mode) int res; res = chmod(path, mode); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -178,7 +187,7 @@ static int xmp_chown(const char *path, uid_t uid, gid_t gid) int res; res = lchown(path, uid, gid); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -189,7 +198,7 @@ static int xmp_truncate(const char *path, off_t size) int res; res = truncate(path, size); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -200,7 +209,7 @@ static int xmp_utime(const char *path, struct utimbuf *buf) int res; res = utime(path, buf); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -212,7 +221,7 @@ static int xmp_open(const char *path, struct fuse_file_info *fi) int res; res = open(path, fi->flags); - if(res == -1) + if (res == -1) return -errno; close(res); @@ -227,11 +236,11 @@ static int xmp_read(const char *path, char *buf, size_t size, off_t offset, (void) fi; fd = open(path, O_RDONLY); - if(fd == -1) + if (fd == -1) return -errno; res = pread(fd, buf, size, offset); - if(res == -1) + if (res == -1) res = -errno; close(fd); @@ -246,11 +255,11 @@ static int xmp_write(const char *path, const char *buf, size_t size, (void) fi; fd = open(path, O_WRONLY); - if(fd == -1) + if (fd == -1) return -errno; res = pwrite(fd, buf, size, offset); - if(res == -1) + if (res == -1) res = -errno; close(fd); @@ -262,7 +271,7 @@ static int xmp_statfs(const char *path, struct statvfs *stbuf) int res; res = statvfs(path, stbuf); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -296,7 +305,7 @@ 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) + if (res == -1) return -errno; return 0; } @@ -305,7 +314,7 @@ 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) + if (res == -1) return -errno; return res; } @@ -313,7 +322,7 @@ static int xmp_getxattr(const char *path, const char *name, char *value, static int xmp_listxattr(const char *path, char *list, size_t size) { int res = llistxattr(path, list, size); - if(res == -1) + if (res == -1) return -errno; return res; } @@ -321,7 +330,7 @@ static int xmp_listxattr(const char *path, char *list, size_t size) static int xmp_removexattr(const char *path, const char *name) { int res = lremovexattr(path, name); - if(res == -1) + if (res == -1) return -errno; return 0; } diff --git a/example/fusexmp_fh.c b/example/fusexmp_fh.c index 491e691..787f87c 100644 --- a/example/fusexmp_fh.c +++ b/example/fusexmp_fh.c @@ -26,7 +26,7 @@ static int xmp_getattr(const char *path, struct stat *stbuf) int res; res = lstat(path, stbuf); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -40,7 +40,7 @@ static int xmp_fgetattr(const char *path, struct stat *stbuf, (void) path; res = fstat(fi->fh, stbuf); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -51,7 +51,7 @@ static int xmp_access(const char *path, int mask) int res; res = access(path, mask); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -62,7 +62,7 @@ static int xmp_readlink(const char *path, char *buf, size_t size) int res; res = readlink(path, buf, size - 1); - if(res == -1) + if (res == -1) return -errno; buf[res] = '\0'; @@ -97,7 +97,7 @@ static int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler, 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, de->d_off)) + if (filler(buf, de->d_name, &st, telldir(dp))) break; } @@ -116,8 +116,11 @@ static int xmp_mknod(const char *path, mode_t mode, dev_t rdev) { int res; - res = mknod(path, mode, rdev); - if(res == -1) + if (S_ISFIFO(mode)) + res = mkfifo(path, mode); + else + res = mknod(path, mode, rdev); + if (res == -1) return -errno; return 0; @@ -128,7 +131,7 @@ static int xmp_mkdir(const char *path, mode_t mode) int res; res = mkdir(path, mode); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -139,7 +142,7 @@ static int xmp_unlink(const char *path) int res; res = unlink(path); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -150,7 +153,7 @@ static int xmp_rmdir(const char *path) int res; res = rmdir(path); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -161,7 +164,7 @@ static int xmp_symlink(const char *from, const char *to) int res; res = symlink(from, to); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -172,7 +175,7 @@ static int xmp_rename(const char *from, const char *to) int res; res = rename(from, to); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -183,7 +186,7 @@ static int xmp_link(const char *from, const char *to) int res; res = link(from, to); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -194,7 +197,7 @@ static int xmp_chmod(const char *path, mode_t mode) int res; res = chmod(path, mode); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -205,7 +208,7 @@ static int xmp_chown(const char *path, uid_t uid, gid_t gid) int res; res = lchown(path, uid, gid); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -216,7 +219,7 @@ static int xmp_truncate(const char *path, off_t size) int res; res = truncate(path, size); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -230,7 +233,7 @@ static int xmp_ftruncate(const char *path, off_t size, (void) path; res = ftruncate(fi->fh, size); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -241,7 +244,7 @@ static int xmp_utime(const char *path, struct utimbuf *buf) int res; res = utime(path, buf); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -252,7 +255,7 @@ 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) + if (fd == -1) return -errno; fi->fh = fd; @@ -264,7 +267,7 @@ static int xmp_open(const char *path, struct fuse_file_info *fi) int fd; fd = open(path, fi->flags); - if(fd == -1) + if (fd == -1) return -errno; fi->fh = fd; @@ -278,7 +281,7 @@ static int xmp_read(const char *path, char *buf, size_t size, off_t offset, (void) path; res = pread(fi->fh, buf, size, offset); - if(res == -1) + if (res == -1) res = -errno; return res; @@ -291,7 +294,7 @@ static int xmp_write(const char *path, const char *buf, size_t size, (void) path; res = pwrite(fi->fh, buf, size, offset); - if(res == -1) + if (res == -1) res = -errno; return res; @@ -302,7 +305,7 @@ static int xmp_statfs(const char *path, struct statvfs *stbuf) int res; res = statvfs(path, stbuf); - if(res == -1) + if (res == -1) return -errno; return 0; @@ -322,11 +325,15 @@ static int xmp_fsync(const char *path, int isdatasync, 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) + if (res == -1) return -errno; return 0; @@ -338,7 +345,7 @@ 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) + if (res == -1) return -errno; return 0; } @@ -347,7 +354,7 @@ 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) + if (res == -1) return -errno; return res; } @@ -355,7 +362,7 @@ static int xmp_getxattr(const char *path, const char *name, char *value, static int xmp_listxattr(const char *path, char *list, size_t size) { int res = llistxattr(path, list, size); - if(res == -1) + if (res == -1) return -errno; return res; } @@ -363,7 +370,7 @@ static int xmp_listxattr(const char *path, char *list, size_t size) static int xmp_removexattr(const char *path, const char *name) { int res = lremovexattr(path, name); - if(res == -1) + if (res == -1) return -errno; return 0; } diff --git a/kernel/fuse_kernel.h b/kernel/fuse_kernel.h index 48b60fc..492c5cc 100644 --- a/kernel/fuse_kernel.h +++ b/kernel/fuse_kernel.h @@ -36,7 +36,14 @@ /* This file defines the kernel interface of FUSE */ +#ifdef __FreeBSD__ +#include +#define __u64 uint64_t +#define __u32 uint32_t +#define __s32 int32_t +#else #include +#endif /** Version number of this interface */ #define FUSE_KERNEL_VERSION 7 diff --git a/lib/Makefile.am b/lib/Makefile.am index 8d340f9..0bd952e 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -2,6 +2,12 @@ lib_LTLIBRARIES = libfuse.la +if BSD +mount_source = mount_bsd.c +else +mount_source = mount.c +endif + libfuse_la_SOURCES = \ fuse.c \ fuse_i.h \ @@ -12,7 +18,7 @@ libfuse_la_SOURCES = \ fuse_mt.c \ fuse_session.c \ helper.c \ - mount.c + $(mount_source) libfuse_la_LDFLAGS = -lpthread -version-number 2:5:0 \ -Wl,--version-script,fuse_versionscript diff --git a/lib/fuse.c b/lib/fuse.c index 5c5eb0a..8966fab 100644 --- a/lib/fuse.c +++ b/lib/fuse.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -804,7 +805,18 @@ static void fuse_mknod(fuse_req_t req, fuse_ino_t parent, const char *name, fflush(stdout); } err = -ENOSYS; - if (f->op.mknod && f->op.getattr) { + if (S_ISREG(mode) && f->op.create && f->op.getattr) { + struct fuse_file_info fi; + + memset(&fi, 0, sizeof(fi)); + fi.flags = O_CREAT | O_EXCL | O_WRONLY; + err = f->op.create(path, mode, &fi); + if (!err) { + err = lookup_path(f, parent, name, path, &e, &fi); + if (f->op.release) + f->op.release(path, &fi); + } + } else if (f->op.mknod && f->op.getattr) { err = f->op.mknod(path, mode, rdev); if (!err) err = lookup_path(f, parent, name, path, &e, NULL); @@ -1937,6 +1949,13 @@ static int parse_lib_opts(struct fuse *f, const char *opts, char **llopts) else free(xopts); } +#ifdef __FreeBSD__ + /* + * In FreeBSD, we always use these settings as inode numbers are needed to + * make getcwd(3) work. + */ + f->flags |= FUSE_READDIR_INO; +#endif return 0; } diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index f2ac121..31c2789 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -787,7 +787,7 @@ static void fuse_ll_process(void *data, const char *buf, size_t len, req->ch = ch; if (!f->got_init && in->opcode != FUSE_INIT) - fuse_reply_err(req, EPROTO); + fuse_reply_err(req, EIO); else if (f->allow_root && in->uid != f->owner && in->uid != 0 && in->opcode != FUSE_INIT && in->opcode != FUSE_READ && in->opcode != FUSE_WRITE && in->opcode != FUSE_FSYNC && diff --git a/lib/helper.c b/lib/helper.c index d8a522f..79616dc 100644 --- a/lib/helper.c +++ b/lib/helper.c @@ -381,8 +381,8 @@ void fuse_teardown(struct fuse *fuse, int fd, char *mountpoint) else fuse_instance = NULL; - fuse_destroy(fuse); fuse_unmount(mountpoint); + fuse_destroy(fuse); free(mountpoint); } diff --git a/lib/mount_bsd.c b/lib/mount_bsd.c new file mode 100644 index 0000000..0111b14 --- /dev/null +++ b/lib/mount_bsd.c @@ -0,0 +1,133 @@ +/* + FUSE: Filesystem in Userspace + Copyright (C) 2005 Csaba Henk + + This program can be distributed under the terms of the GNU LGPL. + See the file COPYING.LIB. +*/ + +#include "fuse.h" + +#include +#include +#include +#include +#include +#include + +#define FUSERMOUNT_PROG "mount_fusefs" + +void fuse_unmount(const char *mountpoint) +{ + char dev[128]; + char *ssc, *umount_cmd; + FILE *sf; + int rv; + char *seekscript = + "/usr/bin/fstat /dev/fuse* |\n" + "/usr/bin/awk '{if ($3 == %d) print $10}' |\n" + "/usr/bin/sort |\n" + "/usr/bin/uniq |\n" + "/usr/bin/awk '{ i+=1; if(i > 1){ exit (1); }; printf; }; END{if (i==0) exit (1)}'"; + + asprintf(&ssc, seekscript, getpid()); + + errno = 0; + sf = popen(ssc, "r"); + if (! sf) + return; + + fgets(dev, sizeof(dev), sf); + rv = pclose(sf); + if (rv) + return; + + asprintf(&umount_cmd, "/sbin/umount %s", dev); + system(umount_cmd); +} + +int fuse_mount(const char *mountpoint, const char *opts) +{ + const char *mountprog = FUSERMOUNT_PROG; + int fd; + char *fdnam, *dev; + int pid; + + fdnam = getenv("FUSE_DEV_FD"); + + if (fdnam) { + char *ep; + + fd = strtol(fdnam, &ep, 10); + + if (*ep != '\0') { + fprintf(stderr, "invalid value given in FUSE_DEV_FD"); + return -1; + } + + if (fd < 0) + return -1; + + goto mount; + } + + dev = getenv("FUSE_DEV_NAME"); + + if (! dev) + dev = "/dev/fuse"; + + if ((fd = open(dev, O_RDWR)) < 0) { + perror("fuse: failed to open fuse device"); + return -1; + } + +mount: + if (getenv("FUSE_NO_MOUNT") || ! mountpoint) + goto out; + + pid = fork(); + + if (pid == -1) { + perror("fuse: fork() failed"); + close(fd); + return -1; + } + + if (pid == 0) { + pid = fork(); + + if (pid == -1) { + perror("fuse: fork() failed"); + close(fd); + exit(1); + } + + if (pid == 0) { + const char *argv[32]; + int a = 0; + + if (! fdnam) + asprintf(&fdnam, "%d", fd); + + argv[a++] = mountprog; + if (opts) { + argv[a++] = "-o"; + argv[a++] = opts; + } + argv[a++] = fdnam; + argv[a++] = mountpoint; + argv[a++] = NULL; + setenv("MOUNT_FUSEFS_SAFE", "1", 1); + execvp(mountprog, (char **) argv); + perror("fuse: failed to exec mount program"); + exit(1); + } + + exit(0); + } + + waitpid(pid, NULL, 0); + +out: + return fd; +} -- 2.30.2