aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Miklos Szeredi <miklos@szeredi.hu>2007-12-12 14:25:40 +0000
committerGravatar Miklos Szeredi <miklos@szeredi.hu>2007-12-12 14:25:40 +0000
commitcdb8b79bad5fea81b74931a9027f1d5ca344af8e (patch)
tree11ab550f265dc3eb546b7c26f3745e6d139b1fcc
parent918f0ad95b73e506d20488cb8ddd35d1a2524c7c (diff)
change indenting
-rw-r--r--example/fusexmp.c412
-rw-r--r--example/fusexmp_fh.c468
-rw-r--r--example/hello.c106
-rw-r--r--example/hello_ll.c231
-rw-r--r--example/null.c90
-rw-r--r--include/fuse.h875
-rw-r--r--include/fuse_common.h160
-rw-r--r--include/fuse_common_compat.h19
-rw-r--r--include/fuse_compat.h300
-rw-r--r--include/fuse_lowlevel.h1561
-rw-r--r--include/fuse_lowlevel_compat.h223
-rw-r--r--include/fuse_opt.h56
-rw-r--r--include/ulockmgr.h10
-rw-r--r--lib/fuse.c4987
-rw-r--r--lib/fuse_i.h22
-rw-r--r--lib/fuse_kern_chan.c118
-rw-r--r--lib/fuse_loop.c48
-rw-r--r--lib/fuse_loop_mt.c347
-rw-r--r--lib/fuse_lowlevel.c1791
-rw-r--r--lib/fuse_misc.h18
-rw-r--r--lib/fuse_mt.c136
-rw-r--r--lib/fuse_opt.c528
-rw-r--r--lib/fuse_session.c185
-rw-r--r--lib/fuse_signals.c78
-rw-r--r--lib/helper.c568
-rw-r--r--lib/modules/iconv.c1021
-rw-r--r--lib/modules/subdir.c913
-rw-r--r--lib/mount.c966
-rw-r--r--lib/mount_bsd.c560
-rw-r--r--lib/mount_util.c397
-rw-r--r--lib/mount_util.h12
-rw-r--r--lib/ulockmgr.c702
-rw-r--r--test/stracedecode.c348
-rw-r--r--test/test.c2318
-rw-r--r--util/fusermount.c1533
-rw-r--r--util/mount.fuse.c353
-rw-r--r--util/ulockmgr_server.c671
37 files changed, 11656 insertions, 11475 deletions
diff --git a/example/fusexmp.c b/example/fusexmp.c
index 8df474c..083bbea 100644
--- a/example/fusexmp.c
+++ b/example/fusexmp.c
@@ -1,11 +1,11 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU GPL.
- See the file COPYING.
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
- gcc -Wall `pkg-config fuse --cflags --libs` fusexmp.c -o fusexmp
+ gcc -Wall `pkg-config fuse --cflags --libs` fusexmp.c -o fusexmp
*/
#define FUSE_USE_VERSION 26
@@ -33,353 +33,353 @@
static int xmp_getattr(const char *path, struct stat *stbuf)
{
- int res;
+ int res;
- res = lstat(path, stbuf);
- if (res == -1)
- return -errno;
+ res = lstat(path, stbuf);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_access(const char *path, int mask)
{
- int res;
+ int res;
- res = access(path, mask);
- if (res == -1)
- return -errno;
+ res = access(path, mask);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_readlink(const char *path, char *buf, size_t size)
{
- int res;
+ int res;
- res = readlink(path, buf, size - 1);
- if (res == -1)
- return -errno;
+ res = readlink(path, buf, size - 1);
+ if (res == -1)
+ return -errno;
- buf[res] = '\0';
- return 0;
+ buf[res] = '\0';
+ return 0;
}
static int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
- off_t offset, struct fuse_file_info *fi)
+ off_t offset, struct fuse_file_info *fi)
{
- DIR *dp;
- struct dirent *de;
-
- (void) offset;
- (void) fi;
-
- dp = opendir(path);
- if (dp == NULL)
- return -errno;
-
- while ((de = readdir(dp)) != NULL) {
- struct stat st;
- 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, 0))
- break;
- }
-
- closedir(dp);
- return 0;
+ DIR *dp;
+ struct dirent *de;
+
+ (void) offset;
+ (void) fi;
+
+ dp = opendir(path);
+ if (dp == NULL)
+ return -errno;
+
+ while ((de = readdir(dp)) != NULL) {
+ struct stat st;
+ 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, 0))
+ break;
+ }
+
+ closedir(dp);
+ return 0;
}
static int xmp_mknod(const char *path, mode_t mode, dev_t rdev)
{
- int res;
-
- /* 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;
+ int res;
+
+ /* 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;
}
static int xmp_mkdir(const char *path, mode_t mode)
{
- int res;
+ int res;
- res = mkdir(path, mode);
- if (res == -1)
- return -errno;
+ res = mkdir(path, mode);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_unlink(const char *path)
{
- int res;
+ int res;
- res = unlink(path);
- if (res == -1)
- return -errno;
+ res = unlink(path);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_rmdir(const char *path)
{
- int res;
+ int res;
- res = rmdir(path);
- if (res == -1)
- return -errno;
+ res = rmdir(path);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_symlink(const char *from, const char *to)
{
- int res;
+ int res;
- res = symlink(from, to);
- if (res == -1)
- return -errno;
+ res = symlink(from, to);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_rename(const char *from, const char *to)
{
- int res;
+ int res;
- res = rename(from, to);
- if (res == -1)
- return -errno;
+ res = rename(from, to);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_link(const char *from, const char *to)
{
- int res;
+ int res;
- res = link(from, to);
- if (res == -1)
- return -errno;
+ res = link(from, to);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_chmod(const char *path, mode_t mode)
{
- int res;
+ int res;
- res = chmod(path, mode);
- if (res == -1)
- return -errno;
+ res = chmod(path, mode);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_chown(const char *path, uid_t uid, gid_t gid)
{
- int res;
+ int res;
- res = lchown(path, uid, gid);
- if (res == -1)
- return -errno;
+ res = lchown(path, uid, gid);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_truncate(const char *path, off_t size)
{
- int res;
+ int res;
- res = truncate(path, size);
- if (res == -1)
- return -errno;
+ res = truncate(path, size);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_utimens(const char *path, const struct timespec ts[2])
{
- int res;
- struct timeval tv[2];
+ int res;
+ struct timeval tv[2];
- tv[0].tv_sec = ts[0].tv_sec;
- tv[0].tv_usec = ts[0].tv_nsec / 1000;
- tv[1].tv_sec = ts[1].tv_sec;
- tv[1].tv_usec = ts[1].tv_nsec / 1000;
+ tv[0].tv_sec = ts[0].tv_sec;
+ tv[0].tv_usec = ts[0].tv_nsec / 1000;
+ tv[1].tv_sec = ts[1].tv_sec;
+ tv[1].tv_usec = ts[1].tv_nsec / 1000;
- res = utimes(path, tv);
- if (res == -1)
- return -errno;
+ res = utimes(path, tv);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_open(const char *path, struct fuse_file_info *fi)
{
- int res;
+ int res;
- res = open(path, fi->flags);
- if (res == -1)
- return -errno;
+ res = open(path, fi->flags);
+ if (res == -1)
+ return -errno;
- close(res);
- return 0;
+ close(res);
+ return 0;
}
static int xmp_read(const char *path, char *buf, size_t size, off_t offset,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- int fd;
- int res;
+ int fd;
+ int res;
- (void) fi;
- fd = open(path, O_RDONLY);
- if (fd == -1)
- return -errno;
+ (void) fi;
+ fd = open(path, O_RDONLY);
+ if (fd == -1)
+ return -errno;
- res = pread(fd, buf, size, offset);
- if (res == -1)
- res = -errno;
+ res = pread(fd, buf, size, offset);
+ if (res == -1)
+ res = -errno;
- close(fd);
- return res;
+ close(fd);
+ return res;
}
static int xmp_write(const char *path, const char *buf, size_t size,
- off_t offset, struct fuse_file_info *fi)
+ off_t offset, struct fuse_file_info *fi)
{
- int fd;
- int res;
+ int fd;
+ int res;
- (void) fi;
- fd = open(path, O_WRONLY);
- if (fd == -1)
- return -errno;
+ (void) fi;
+ fd = open(path, O_WRONLY);
+ if (fd == -1)
+ return -errno;
- res = pwrite(fd, buf, size, offset);
- if (res == -1)
- res = -errno;
+ res = pwrite(fd, buf, size, offset);
+ if (res == -1)
+ res = -errno;
- close(fd);
- return res;
+ close(fd);
+ return res;
}
static int xmp_statfs(const char *path, struct statvfs *stbuf)
{
- int res;
+ int res;
- res = statvfs(path, stbuf);
- if (res == -1)
- return -errno;
+ res = statvfs(path, stbuf);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_release(const char *path, struct fuse_file_info *fi)
{
- /* Just a stub. This method is optional and can safely be left
- unimplemented */
+ /* Just a stub. This method is optional and can safely be left
+ unimplemented */
- (void) path;
- (void) fi;
- return 0;
+ (void) path;
+ (void) fi;
+ return 0;
}
static int xmp_fsync(const char *path, int isdatasync,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- /* Just a stub. This method is optional and can safely be left
- unimplemented */
+ /* Just a stub. This method is optional and can safely be left
+ unimplemented */
- (void) path;
- (void) isdatasync;
- (void) fi;
- return 0;
+ (void) path;
+ (void) isdatasync;
+ (void) fi;
+ return 0;
}
#ifdef HAVE_SETXATTR
/* xattr operations are optional and can safely be left unimplemented */
static int xmp_setxattr(const char *path, const char *name, const char *value,
- size_t size, int flags)
+ size_t size, int flags)
{
- int res = lsetxattr(path, name, value, size, flags);
- if (res == -1)
- return -errno;
- return 0;
+ int res = lsetxattr(path, name, value, size, flags);
+ if (res == -1)
+ return -errno;
+ return 0;
}
static int xmp_getxattr(const char *path, const char *name, char *value,
- size_t size)
+ size_t size)
{
- int res = lgetxattr(path, name, value, size);
- if (res == -1)
- return -errno;
- return res;
+ int res = lgetxattr(path, name, value, size);
+ if (res == -1)
+ return -errno;
+ return res;
}
static int xmp_listxattr(const char *path, char *list, size_t size)
{
- int res = llistxattr(path, list, size);
- if (res == -1)
- return -errno;
- return res;
+ int res = llistxattr(path, list, size);
+ if (res == -1)
+ return -errno;
+ return res;
}
static int xmp_removexattr(const char *path, const char *name)
{
- int res = lremovexattr(path, name);
- if (res == -1)
- return -errno;
- return 0;
+ int res = lremovexattr(path, name);
+ if (res == -1)
+ return -errno;
+ return 0;
}
#endif /* HAVE_SETXATTR */
static struct fuse_operations xmp_oper = {
- .getattr = xmp_getattr,
- .access = xmp_access,
- .readlink = xmp_readlink,
- .readdir = xmp_readdir,
- .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,
- .utimens = xmp_utimens,
- .open = xmp_open,
- .read = xmp_read,
- .write = xmp_write,
- .statfs = xmp_statfs,
- .release = xmp_release,
- .fsync = xmp_fsync,
+ .getattr = xmp_getattr,
+ .access = xmp_access,
+ .readlink = xmp_readlink,
+ .readdir = xmp_readdir,
+ .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,
+ .utimens = xmp_utimens,
+ .open = xmp_open,
+ .read = xmp_read,
+ .write = xmp_write,
+ .statfs = xmp_statfs,
+ .release = xmp_release,
+ .fsync = xmp_fsync,
#ifdef HAVE_SETXATTR
- .setxattr = xmp_setxattr,
- .getxattr = xmp_getxattr,
- .listxattr = xmp_listxattr,
- .removexattr= xmp_removexattr,
+ .setxattr = xmp_setxattr,
+ .getxattr = xmp_getxattr,
+ .listxattr = xmp_listxattr,
+ .removexattr = xmp_removexattr,
#endif
};
int main(int argc, char *argv[])
{
- umask(0);
- return fuse_main(argc, argv, &xmp_oper, NULL);
+ umask(0);
+ return fuse_main(argc, argv, &xmp_oper, NULL);
}
diff --git a/example/fusexmp_fh.c b/example/fusexmp_fh.c
index 6565cf9..616c263 100644
--- a/example/fusexmp_fh.c
+++ b/example/fusexmp_fh.c
@@ -1,11 +1,11 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU GPL.
- See the file COPYING.
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
- gcc -Wall `pkg-config fuse --cflags --libs` -lulockmgr fusexmp_fh.c -o fusexmp_fh
+ gcc -Wall `pkg-config fuse --cflags --libs` -lulockmgr fusexmp_fh.c -o fusexmp_fh
*/
#define FUSE_USE_VERSION 26
@@ -31,430 +31,430 @@
static int xmp_getattr(const char *path, struct stat *stbuf)
{
- int res;
+ int res;
- res = lstat(path, stbuf);
- if (res == -1)
- return -errno;
+ res = lstat(path, stbuf);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_fgetattr(const char *path, struct stat *stbuf,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- int res;
+ int res;
- (void) path;
+ (void) path;
- res = fstat(fi->fh, stbuf);
- if (res == -1)
- return -errno;
+ res = fstat(fi->fh, stbuf);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_access(const char *path, int mask)
{
- int res;
+ int res;
- res = access(path, mask);
- if (res == -1)
- return -errno;
+ res = access(path, mask);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_readlink(const char *path, char *buf, size_t size)
{
- int res;
+ int res;
- res = readlink(path, buf, size - 1);
- if (res == -1)
- return -errno;
+ res = readlink(path, buf, size - 1);
+ if (res == -1)
+ return -errno;
- buf[res] = '\0';
- return 0;
+ buf[res] = '\0';
+ return 0;
}
static int xmp_opendir(const char *path, struct fuse_file_info *fi)
{
- DIR *dp = opendir(path);
- if (dp == NULL)
- return -errno;
+ DIR *dp = opendir(path);
+ if (dp == NULL)
+ return -errno;
- fi->fh = (unsigned long) dp;
- return 0;
+ fi->fh = (unsigned long) dp;
+ return 0;
}
static inline DIR *get_dirp(struct fuse_file_info *fi)
{
- return (DIR *) (uintptr_t) fi->fh;
+ return (DIR *) (uintptr_t) fi->fh;
}
static int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
- off_t offset, struct fuse_file_info *fi)
+ off_t offset, struct fuse_file_info *fi)
{
- DIR *dp = get_dirp(fi);
- struct dirent *de;
+ DIR *dp = get_dirp(fi);
+ struct dirent *de;
- (void) path;
- seekdir(dp, offset);
- while ((de = readdir(dp)) != NULL) {
- struct stat st;
- 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, telldir(dp)))
- break;
- }
+ (void) path;
+ seekdir(dp, offset);
+ while ((de = readdir(dp)) != NULL) {
+ struct stat st;
+ 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, telldir(dp)))
+ break;
+ }
- return 0;
+ return 0;
}
static int xmp_releasedir(const char *path, struct fuse_file_info *fi)
{
- DIR *dp = get_dirp(fi);
- (void) path;
- closedir(dp);
- return 0;
+ DIR *dp = get_dirp(fi);
+ (void) path;
+ closedir(dp);
+ return 0;
}
static int xmp_mknod(const char *path, mode_t mode, dev_t rdev)
{
- int res;
+ int res;
- if (S_ISFIFO(mode))
- res = mkfifo(path, mode);
- else
- res = mknod(path, mode, rdev);
- if (res == -1)
- return -errno;
+ if (S_ISFIFO(mode))
+ res = mkfifo(path, mode);
+ else
+ res = mknod(path, mode, rdev);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_mkdir(const char *path, mode_t mode)
{
- int res;
+ int res;
- res = mkdir(path, mode);
- if (res == -1)
- return -errno;
+ res = mkdir(path, mode);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_unlink(const char *path)
{
- int res;
+ int res;
- res = unlink(path);
- if (res == -1)
- return -errno;
+ res = unlink(path);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_rmdir(const char *path)
{
- int res;
+ int res;
- res = rmdir(path);
- if (res == -1)
- return -errno;
+ res = rmdir(path);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_symlink(const char *from, const char *to)
{
- int res;
+ int res;
- res = symlink(from, to);
- if (res == -1)
- return -errno;
+ res = symlink(from, to);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_rename(const char *from, const char *to)
{
- int res;
+ int res;
- res = rename(from, to);
- if (res == -1)
- return -errno;
+ res = rename(from, to);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_link(const char *from, const char *to)
{
- int res;
+ int res;
- res = link(from, to);
- if (res == -1)
- return -errno;
+ res = link(from, to);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_chmod(const char *path, mode_t mode)
{
- int res;
+ int res;
- res = chmod(path, mode);
- if (res == -1)
- return -errno;
+ res = chmod(path, mode);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_chown(const char *path, uid_t uid, gid_t gid)
{
- int res;
+ int res;
- res = lchown(path, uid, gid);
- if (res == -1)
- return -errno;
+ res = lchown(path, uid, gid);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_truncate(const char *path, off_t size)
{
- int res;
+ int res;
- res = truncate(path, size);
- if (res == -1)
- return -errno;
+ res = truncate(path, size);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_ftruncate(const char *path, off_t size,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- int res;
+ int res;
- (void) path;
+ (void) path;
- res = ftruncate(fi->fh, size);
- if (res == -1)
- return -errno;
+ res = ftruncate(fi->fh, size);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_utimens(const char *path, const struct timespec ts[2])
{
- int res;
- struct timeval tv[2];
+ int res;
+ struct timeval tv[2];
- tv[0].tv_sec = ts[0].tv_sec;
- tv[0].tv_usec = ts[0].tv_nsec / 1000;
- tv[1].tv_sec = ts[1].tv_sec;
- tv[1].tv_usec = ts[1].tv_nsec / 1000;
+ tv[0].tv_sec = ts[0].tv_sec;
+ tv[0].tv_usec = ts[0].tv_nsec / 1000;
+ tv[1].tv_sec = ts[1].tv_sec;
+ tv[1].tv_usec = ts[1].tv_nsec / 1000;
- res = utimes(path, tv);
- if (res == -1)
- return -errno;
+ res = utimes(path, tv);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_create(const char *path, mode_t mode, struct fuse_file_info *fi)
{
- int fd;
+ int fd;
- fd = open(path, fi->flags, mode);
- if (fd == -1)
- return -errno;
+ fd = open(path, fi->flags, mode);
+ if (fd == -1)
+ return -errno;
- fi->fh = fd;
- return 0;
+ fi->fh = fd;
+ return 0;
}
static int xmp_open(const char *path, struct fuse_file_info *fi)
{
- int fd;
+ int fd;
- fd = open(path, fi->flags);
- if (fd == -1)
- return -errno;
+ fd = open(path, fi->flags);
+ if (fd == -1)
+ return -errno;
- fi->fh = fd;
- return 0;
+ fi->fh = fd;
+ return 0;
}
static int xmp_read(const char *path, char *buf, size_t size, off_t offset,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- int res;
+ int res;
- (void) path;
- res = pread(fi->fh, buf, size, offset);
- if (res == -1)
- res = -errno;
+ (void) path;
+ res = pread(fi->fh, buf, size, offset);
+ if (res == -1)
+ res = -errno;
- return res;
+ return res;
}
static int xmp_write(const char *path, const char *buf, size_t size,
- off_t offset, struct fuse_file_info *fi)
+ off_t offset, struct fuse_file_info *fi)
{
- int res;
+ int res;
- (void) path;
- res = pwrite(fi->fh, buf, size, offset);
- if (res == -1)
- res = -errno;
+ (void) path;
+ res = pwrite(fi->fh, buf, size, offset);
+ if (res == -1)
+ res = -errno;
- return res;
+ return res;
}
static int xmp_statfs(const char *path, struct statvfs *stbuf)
{
- int res;
+ int res;
- res = statvfs(path, stbuf);
- if (res == -1)
- return -errno;
+ res = statvfs(path, stbuf);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_flush(const char *path, struct fuse_file_info *fi)
{
- int res;
+ int res;
- (void) path;
- /* This is called from every close on an open file, so call the
- close on the underlying filesystem. But since flush may be
- called multiple times for an open file, this must not really
- close the file. This is important if used on a network
- filesystem like NFS which flush the data/metadata on close() */
- res = close(dup(fi->fh));
- if (res == -1)
- return -errno;
+ (void) path;
+ /* This is called from every close on an open file, so call the
+ close on the underlying filesystem. But since flush may be
+ called multiple times for an open file, this must not really
+ close the file. This is important if used on a network
+ filesystem like NFS which flush the data/metadata on close() */
+ res = close(dup(fi->fh));
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
static int xmp_release(const char *path, struct fuse_file_info *fi)
{
- (void) path;
- close(fi->fh);
+ (void) path;
+ close(fi->fh);
- return 0;
+ return 0;
}
static int xmp_fsync(const char *path, int isdatasync,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- int res;
- (void) path;
+ int res;
+ (void) path;
#ifndef HAVE_FDATASYNC
- (void) isdatasync;
+ (void) isdatasync;
#else
- if (isdatasync)
- res = fdatasync(fi->fh);
- else
+ if (isdatasync)
+ res = fdatasync(fi->fh);
+ else
#endif
- res = fsync(fi->fh);
- if (res == -1)
- return -errno;
+ res = fsync(fi->fh);
+ if (res == -1)
+ return -errno;
- return 0;
+ return 0;
}
#ifdef HAVE_SETXATTR
/* xattr operations are optional and can safely be left unimplemented */
static int xmp_setxattr(const char *path, const char *name, const char *value,
- size_t size, int flags)
+ size_t size, int flags)
{
- int res = lsetxattr(path, name, value, size, flags);
- if (res == -1)
- return -errno;
- return 0;
+ int res = lsetxattr(path, name, value, size, flags);
+ if (res == -1)
+ return -errno;
+ return 0;
}
static int xmp_getxattr(const char *path, const char *name, char *value,
- size_t size)
+ size_t size)
{
- int res = lgetxattr(path, name, value, size);
- if (res == -1)
- return -errno;
- return res;
+ int res = lgetxattr(path, name, value, size);
+ if (res == -1)
+ return -errno;
+ return res;
}
static int xmp_listxattr(const char *path, char *list, size_t size)
{
- int res = llistxattr(path, list, size);
- if (res == -1)
- return -errno;
- return res;
+ int res = llistxattr(path, list, size);
+ if (res == -1)
+ return -errno;
+ return res;
}
static int xmp_removexattr(const char *path, const char *name)
{
- int res = lremovexattr(path, name);
- if (res == -1)
- return -errno;
- return 0;
+ int res = lremovexattr(path, name);
+ if (res == -1)
+ return -errno;
+ return 0;
}
#endif /* HAVE_SETXATTR */
static int xmp_lock(const char *path, struct fuse_file_info *fi, int cmd,
- struct flock *lock)
+ struct flock *lock)
{
- (void) path;
+ (void) path;
- return ulockmgr_op(fi->fh, cmd, lock, &fi->lock_owner,
- sizeof(fi->lock_owner));
+ return ulockmgr_op(fi->fh, cmd, lock, &fi->lock_owner,
+ sizeof(fi->lock_owner));
}
static struct fuse_operations xmp_oper = {
- .getattr = xmp_getattr,
- .fgetattr = xmp_fgetattr,
- .access = xmp_access,
- .readlink = xmp_readlink,
- .opendir = xmp_opendir,
- .readdir = xmp_readdir,
- .releasedir = xmp_releasedir,
- .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,
- .ftruncate = xmp_ftruncate,
- .utimens = xmp_utimens,
- .create = xmp_create,
- .open = xmp_open,
- .read = xmp_read,
- .write = xmp_write,
- .statfs = xmp_statfs,
- .flush = xmp_flush,
- .release = xmp_release,
- .fsync = xmp_fsync,
+ .getattr = xmp_getattr,
+ .fgetattr = xmp_fgetattr,
+ .access = xmp_access,
+ .readlink = xmp_readlink,
+ .opendir = xmp_opendir,
+ .readdir = xmp_readdir,
+ .releasedir = xmp_releasedir,
+ .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,
+ .ftruncate = xmp_ftruncate,
+ .utimens = xmp_utimens,
+ .create = xmp_create,
+ .open = xmp_open,
+ .read = xmp_read,
+ .write = xmp_write,
+ .statfs = xmp_statfs,
+ .flush = xmp_flush,
+ .release = xmp_release,
+ .fsync = xmp_fsync,
#ifdef HAVE_SETXATTR
- .setxattr = xmp_setxattr,
- .getxattr = xmp_getxattr,
- .listxattr = xmp_listxattr,
- .removexattr= xmp_removexattr,
+ .setxattr = xmp_setxattr,
+ .getxattr = xmp_getxattr,
+ .listxattr = xmp_listxattr,
+ .removexattr = xmp_removexattr,
#endif
- .lock = xmp_lock,
+ .lock = xmp_lock,
};
int main(int argc, char *argv[])
{
- umask(0);
- return fuse_main(argc, argv, &xmp_oper, NULL);
+ umask(0);
+ return fuse_main(argc, argv, &xmp_oper, NULL);
}
diff --git a/example/hello.c b/example/hello.c
index 463e286..bcde80a 100644
--- a/example/hello.c
+++ b/example/hello.c
@@ -1,11 +1,11 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU GPL.
- See the file COPYING.
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
- gcc -Wall `pkg-config fuse --cflags --libs` hello.c -o hello
+ gcc -Wall `pkg-config fuse --cflags --libs` hello.c -o hello
*/
#define FUSE_USE_VERSION 26
@@ -21,76 +21,76 @@ static const char *hello_path = "/hello";
static int hello_getattr(const char *path, struct stat *stbuf)
{
- int res = 0;
-
- memset(stbuf, 0, sizeof(struct stat));
- if (strcmp(path, "/") == 0) {
- stbuf->st_mode = S_IFDIR | 0755;
- stbuf->st_nlink = 2;
- } else if (strcmp(path, hello_path) == 0) {
- stbuf->st_mode = S_IFREG | 0444;
- stbuf->st_nlink = 1;
- stbuf->st_size = strlen(hello_str);
- } else
- res = -ENOENT;
-
- return res;
+ int res = 0;
+
+ memset(stbuf, 0, sizeof(struct stat));
+ if (strcmp(path, "/") == 0) {
+ stbuf->st_mode = S_IFDIR | 0755;
+ stbuf->st_nlink = 2;
+ } else if (strcmp(path, hello_path) == 0) {
+ stbuf->st_mode = S_IFREG | 0444;
+ stbuf->st_nlink = 1;
+ stbuf->st_size = strlen(hello_str);
+ } else
+ res = -ENOENT;
+
+ return res;
}
static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
- off_t offset, struct fuse_file_info *fi)
+ off_t offset, struct fuse_file_info *fi)
{
- (void) offset;
- (void) fi;
+ (void) offset;
+ (void) fi;
- if (strcmp(path, "/") != 0)
- return -ENOENT;
+ if (strcmp(path, "/") != 0)
+ return -ENOENT;
- filler(buf, ".", NULL, 0);
- filler(buf, "..", NULL, 0);
- filler(buf, hello_path + 1, NULL, 0);
+ filler(buf, ".", NULL, 0);
+ filler(buf, "..", NULL, 0);
+ filler(buf, hello_path + 1, NULL, 0);
- return 0;
+ return 0;
}
static int hello_open(const char *path, struct fuse_file_info *fi)
{
- if (strcmp(path, hello_path) != 0)
- return -ENOENT;
+ if (strcmp(path, hello_path) != 0)
+ return -ENOENT;
- if ((fi->flags & 3) != O_RDONLY)
- return -EACCES;
+ if ((fi->flags & 3) != O_RDONLY)
+ return -EACCES;
- return 0;
+ return 0;
}
static int hello_read(const char *path, char *buf, size_t size, off_t offset,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- size_t len;
- (void) fi;
- if(strcmp(path, hello_path) != 0)
- return -ENOENT;
-
- len = strlen(hello_str);
- if (offset < len) {
- if (offset + size > len)
- size = len - offset;
- memcpy(buf, hello_str + offset, size);
- } else
- size = 0;
-
- return size;
+ size_t len;
+ (void) fi;
+ if(strcmp(path, hello_path) != 0)
+ return -ENOENT;
+
+ len = strlen(hello_str);
+ if (offset < len) {
+ if (offset + size > len)
+ size = len - offset;
+ memcpy(buf, hello_str + offset, size);
+ } else
+ size = 0;
+
+ return size;
}
static struct fuse_operations hello_oper = {
- .getattr = hello_getattr,
- .readdir = hello_readdir,
- .open = hello_open,
- .read = hello_read,
+ .getattr = hello_getattr,
+ .readdir = hello_readdir,
+ .open = hello_open,
+ .read = hello_read,
};
int main(int argc, char *argv[])
{
- return fuse_main(argc, argv, &hello_oper, NULL);
+ return fuse_main(argc, argv, &hello_oper, NULL);
}
diff --git a/example/hello_ll.c b/example/hello_ll.c
index 6ab6172..1d3a1a8 100644
--- a/example/hello_ll.c
+++ b/example/hello_ll.c
@@ -1,11 +1,11 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU GPL.
- See the file COPYING.
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
- gcc -Wall `pkg-config fuse --cflags --libs` hello_ll.c -o hello_ll
+ gcc -Wall `pkg-config fuse --cflags --libs` hello_ll.c -o hello_ll
*/
#define FUSE_USE_VERSION 26
@@ -24,157 +24,158 @@ static const char *hello_name = "hello";
static int hello_stat(fuse_ino_t ino, struct stat *stbuf)
{
- stbuf->st_ino = ino;
- switch (ino) {
- case 1:
- stbuf->st_mode = S_IFDIR | 0755;
- stbuf->st_nlink = 2;
- break;
-
- case 2:
- stbuf->st_mode = S_IFREG | 0444;
- stbuf->st_nlink = 1;
- stbuf->st_size = strlen(hello_str);
- break;
-
- default:
- return -1;
- }
- return 0;
+ stbuf->st_ino = ino;
+ switch (ino) {
+ case 1:
+ stbuf->st_mode = S_IFDIR | 0755;
+ stbuf->st_nlink = 2;
+ break;
+
+ case 2:
+ stbuf->st_mode = S_IFREG | 0444;
+ stbuf->st_nlink = 1;
+ stbuf->st_size = strlen(hello_str);
+ break;
+
+ default:
+ return -1;
+ }
+ return 0;
}
static void hello_ll_getattr(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct stat stbuf;
+ struct stat stbuf;
- (void) fi;
+ (void) fi;
- memset(&stbuf, 0, sizeof(stbuf));
- if (hello_stat(ino, &stbuf) == -1)
- fuse_reply_err(req, ENOENT);
- else
- fuse_reply_attr(req, &stbuf, 1.0);
+ memset(&stbuf, 0, sizeof(stbuf));
+ if (hello_stat(ino, &stbuf) == -1)
+ fuse_reply_err(req, ENOENT);
+ else
+ fuse_reply_attr(req, &stbuf, 1.0);
}
static void hello_ll_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
{
- struct fuse_entry_param e;
-
- if (parent != 1 || strcmp(name, hello_name) != 0)
- fuse_reply_err(req, ENOENT);
- else {
- memset(&e, 0, sizeof(e));
- e.ino = 2;
- e.attr_timeout = 1.0;
- e.entry_timeout = 1.0;
- hello_stat(e.ino, &e.attr);
-
- fuse_reply_entry(req, &e);
- }
+ struct fuse_entry_param e;
+
+ if (parent != 1 || strcmp(name, hello_name) != 0)
+ fuse_reply_err(req, ENOENT);
+ else {
+ memset(&e, 0, sizeof(e));
+ e.ino = 2;
+ e.attr_timeout = 1.0;
+ e.entry_timeout = 1.0;
+ hello_stat(e.ino, &e.attr);
+
+ fuse_reply_entry(req, &e);
+ }
}
struct dirbuf {
- char *p;
- size_t size;
+ char *p;
+ size_t size;
};
static void dirbuf_add(fuse_req_t req, struct dirbuf *b, const char *name,
- fuse_ino_t ino)
+ fuse_ino_t ino)
{
- struct stat stbuf;
- size_t oldsize = b->size;
- b->size += fuse_add_direntry(req, NULL, 0, name, NULL, 0);
- b->p = (char *) realloc(b->p, b->size);
- memset(&stbuf, 0, sizeof(stbuf));
- stbuf.st_ino = ino;
- fuse_add_direntry(req, b->p + oldsize, b->size - oldsize, name, &stbuf,
- b->size);
+ struct stat stbuf;
+ size_t oldsize = b->size;
+ b->size += fuse_add_direntry(req, NULL, 0, name, NULL, 0);
+ b->p = (char *) realloc(b->p, b->size);
+ memset(&stbuf, 0, sizeof(stbuf));
+ stbuf.st_ino = ino;
+ fuse_add_direntry(req, b->p + oldsize, b->size - oldsize, name, &stbuf,
+ b->size);
}
#define min(x, y) ((x) < (y) ? (x) : (y))
static int reply_buf_limited(fuse_req_t req, const char *buf, size_t bufsize,
- off_t off, size_t maxsize)
+ off_t off, size_t maxsize)
{
- if (off < bufsize)
- return fuse_reply_buf(req, buf + off, min(bufsize - off, maxsize));
- else
- return fuse_reply_buf(req, NULL, 0);
+ if (off < bufsize)
+ return fuse_reply_buf(req, buf + off,
+ min(bufsize - off, maxsize));
+ else
+ return fuse_reply_buf(req, NULL, 0);
}
static void hello_ll_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
- off_t off, struct fuse_file_info *fi)
+ off_t off, struct fuse_file_info *fi)
{
- (void) fi;
-
- if (ino != 1)
- fuse_reply_err(req, ENOTDIR);
- else {
- struct dirbuf b;
-
- memset(&b, 0, sizeof(b));
- dirbuf_add(req, &b, ".", 1);
- dirbuf_add(req, &b, "..", 1);
- dirbuf_add(req, &b, hello_name, 2);
- reply_buf_limited(req, b.p, b.size, off, size);
- free(b.p);
- }
+ (void) fi;
+
+ if (ino != 1)
+ fuse_reply_err(req, ENOTDIR);
+ else {
+ struct dirbuf b;
+
+ memset(&b, 0, sizeof(b));
+ dirbuf_add(req, &b, ".", 1);
+ dirbuf_add(req, &b, "..", 1);
+ dirbuf_add(req, &b, hello_name, 2);
+ reply_buf_limited(req, b.p, b.size, off, size);
+ free(b.p);
+ }
}
static void hello_ll_open(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- if (ino != 2)
- fuse_reply_err(req, EISDIR);
- else if ((fi->flags & 3) != O_RDONLY)
- fuse_reply_err(req, EACCES);
- else
- fuse_reply_open(req, fi);
+ if (ino != 2)
+ fuse_reply_err(req, EISDIR);
+ else if ((fi->flags & 3) != O_RDONLY)
+ fuse_reply_err(req, EACCES);
+ else
+ fuse_reply_open(req, fi);
}
static void hello_ll_read(fuse_req_t req, fuse_ino_t ino, size_t size,
- off_t off, struct fuse_file_info *fi)
+ off_t off, struct fuse_file_info *fi)
{
- (void) fi;
+ (void) fi;
- assert(ino == 2);
- reply_buf_limited(req, hello_str, strlen(hello_str), off, size);
+ assert(ino == 2);
+ reply_buf_limited(req, hello_str, strlen(hello_str), off, size);
}
static struct fuse_lowlevel_ops hello_ll_oper = {
- .lookup = hello_ll_lookup,
- .getattr = hello_ll_getattr,
- .readdir = hello_ll_readdir,
- .open = hello_ll_open,
- .read = hello_ll_read,
+ .lookup = hello_ll_lookup,
+ .getattr = hello_ll_getattr,
+ .readdir = hello_ll_readdir,
+ .open = hello_ll_open,
+ .read = hello_ll_read,
};
int main(int argc, char *argv[])
{
- struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
- struct fuse_chan *ch;
- char *mountpoint;
- int err = -1;
-
- if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) != -1 &&
- (ch = fuse_mount(mountpoint, &args)) != NULL) {
- struct fuse_session *se;
-
- se = fuse_lowlevel_new(&args, &hello_ll_oper, sizeof(hello_ll_oper),
- NULL);
- if (se != NULL) {
- if (fuse_set_signal_handlers(se) != -1) {
- fuse_session_add_chan(se, ch);
- err = fuse_session_loop(se);
- fuse_remove_signal_handlers(se);
- fuse_session_remove_chan(ch);
- }
- fuse_session_destroy(se);
- }
- fuse_unmount(mountpoint, ch);
- }
- fuse_opt_free_args(&args);
-
- return err ? 1 : 0;
+ struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
+ struct fuse_chan *ch;
+ char *mountpoint;
+ int err = -1;
+
+ if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) != -1 &&
+ (ch = fuse_mount(mountpoint, &args)) != NULL) {
+ struct fuse_session *se;
+
+ se = fuse_lowlevel_new(&args, &hello_ll_oper,
+ sizeof(hello_ll_oper), NULL);
+ if (se != NULL) {
+ if (fuse_set_signal_handlers(se) != -1) {
+ fuse_session_add_chan(se, ch);
+ err = fuse_session_loop(se);
+ fuse_remove_signal_handlers(se);
+ fuse_session_remove_chan(ch);
+ }
+ fuse_session_destroy(se);
+ }
+ fuse_unmount(mountpoint, ch);
+ }
+ fuse_opt_free_args(&args);
+
+ return err ? 1 : 0;
}
diff --git a/example/null.c b/example/null.c
index 0793de6..a98226e 100644
--- a/example/null.c
+++ b/example/null.c
@@ -1,11 +1,11 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU GPL.
- See the file COPYING.
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
- gcc -Wall `pkg-config fuse --cflags --libs` null.c -o null
+ gcc -Wall `pkg-config fuse --cflags --libs` null.c -o null
*/
#define FUSE_USE_VERSION 26
@@ -18,75 +18,75 @@
static int null_getattr(const char *path, struct stat *stbuf)
{
- if(strcmp(path, "/") != 0)
- return -ENOENT;
-
- stbuf->st_mode = S_IFREG | 0644;
- stbuf->st_nlink = 1;
- stbuf->st_uid = getuid();
- stbuf->st_gid = getgid();
- stbuf->st_size = (1ULL << 32); /* 4G */
- stbuf->st_blocks = 0;
- stbuf->st_atime = stbuf->st_mtime = stbuf->st_ctime = time(NULL);
-
- return 0;
+ if(strcmp(path, "/") != 0)
+ return -ENOENT;
+
+ stbuf->st_mode = S_IFREG | 0644;
+ stbuf->st_nlink = 1;
+ stbuf->st_uid = getuid();
+ stbuf->st_gid = getgid();
+ stbuf->st_size = (1ULL << 32); /* 4G */
+ stbuf->st_blocks = 0;
+ stbuf->st_atime = stbuf->st_mtime = stbuf->st_ctime = time(NULL);
+
+ return 0;
}
static int null_truncate(const char *path, off_t size)
{
- (void) size;
+ (void) size;
- if(strcmp(path, "/") != 0)
- return -ENOENT;
+ if(strcmp(path, "/") != 0)
+ return -ENOENT;
- return 0;
+ return 0;
}
static int null_open(const char *path, struct fuse_file_info *fi)
{
- (void) fi;
+ (void) fi;
- if(strcmp(path, "/") != 0)
- return -ENOENT;
+ if(strcmp(path, "/") != 0)
+ return -ENOENT;
- return 0;
+ return 0;
}
static int null_read(const char *path, char *buf, size_t size,
- off_t offset, struct fuse_file_info *fi)
+ off_t offset, struct fuse_file_info *fi)
{
- (void) buf;
- (void) offset;
- (void) fi;
+ (void) buf;
+ (void) offset;
+ (void) fi;
- if(strcmp(path, "/") != 0)
- return -ENOENT;
+ if(strcmp(path, "/") != 0)
+ return -ENOENT;
- return size;
+ return size;
}
static int null_write(const char *path, const char *buf, size_t size,
- off_t offset, struct fuse_file_info *fi)
+ off_t offset, struct fuse_file_info *fi)
{
- (void) buf;
- (void) offset;
- (void) fi;
+ (void) buf;
+ (void) offset;
+ (void) fi;
- if(strcmp(path, "/") != 0)
- return -ENOENT;
+ if(strcmp(path, "/") != 0)
+ return -ENOENT;
- return size;
+ return size;
}
static struct fuse_operations null_oper = {
- .getattr = null_getattr,
- .truncate = null_truncate,
- .open = null_open,
- .read = null_read,
- .write = null_write,
+ .getattr = null_getattr,
+ .truncate = null_truncate,
+ .open = null_open,
+ .read = null_read,
+ .write = null_write,
};
int main(int argc, char *argv[])
{
- return fuse_main(argc, argv, &null_oper, NULL);
+ return fuse_main(argc, argv, &null_oper, NULL);
}
diff --git a/include/fuse.h b/include/fuse.h
index 683ab1a..b7708c7 100644
--- a/include/fuse.h
+++ b/include/fuse.h
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB.
*/
#ifndef _FUSE_H_
@@ -37,7 +37,7 @@ extern "C" {
#endif
/* ----------------------------------------------------------- *
- * Basic FUSE API *
+ * Basic FUSE API *
* ----------------------------------------------------------- */
/** Handle for a FUSE filesystem */
@@ -55,12 +55,12 @@ struct fuse_cmd;
* @return 1 if buffer is full, zero otherwise
*/
typedef int (*fuse_fill_dir_t) (void *buf, const char *name,
- const struct stat *stbuf, off_t off);
+ const struct stat *stbuf, off_t off);
/* Used by deprecated getdir() method */
typedef struct fuse_dirhandle *fuse_dirh_t;
typedef int (*fuse_dirfil_t) (fuse_dirh_t h, const char *name, int type,
- ino_t ino);
+ ino_t ino);
/**
* The file system operations:
@@ -77,351 +77,352 @@ typedef int (*fuse_dirfil_t) (fuse_dirh_t h, const char *name, int type,
* featured filesystem can still be implemented.
*/
struct fuse_operations {
- /** Get file attributes.
- *
- * Similar to stat(). The 'st_dev' and 'st_blksize' fields are
- * ignored. The 'st_ino' field is ignored except if the 'use_ino'
- * mount option is given.
- */
- int (*getattr) (const char *, struct stat *);
-
- /** Read the target of a symbolic link
- *
- * The buffer should be filled 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.
- */
- int (*readlink) (const char *, char *, size_t);
-
- /* Deprecated, use readdir() instead */
- int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t);
-
- /** Create a file node
- *
- * This is called for creation of all non-directory, non-symlink
- * nodes. If the filesystem defines a create() method, then for
- * regular files that will be called instead.
- */
- int (*mknod) (const char *, mode_t, dev_t);
-
- /** Create a directory */
- int (*mkdir) (const char *, mode_t);
-
- /** Remove a file */
- int (*unlink) (const char *);
-
- /** Remove a directory */
- int (*rmdir) (const char *);
-
- /** Create a symbolic link */
- int (*symlink) (const char *, const char *);
-
- /** Rename a file */
- int (*rename) (const char *, const char *);
-
- /** Create a hard link to a file */
- int (*link) (const char *, const char *);
-
- /** Change the permission bits of a file */
- int (*chmod) (const char *, mode_t);
-
- /** Change the owner and group of a file */
- int (*chown) (const char *, uid_t, gid_t);
-
- /** Change the size of a file */
- int (*truncate) (const char *, off_t);
-
- /** Change the access and/or modification times of a file
- *
- * Deprecated, use utimens() instead.
- */
- int (*utime) (const char *, struct utimbuf *);
-
- /** File open operation
- *
- * No creation, or truncation flags (O_CREAT, O_EXCL, O_TRUNC)
- * will be passed to open(). Open should check if the operation
- * is permitted for the given flags. Optionally open may also
- * return an arbitrary filehandle in the fuse_file_info structure,
- * which will be passed to all file operations.
- *
- * Changed in version 2.2
- */
- int (*open) (const char *, struct fuse_file_info *);
-
- /** Read data from an open file
- *
- * Read should return exactly the number of bytes requested except
- * on EOF or error, otherwise the rest of the data will be
- * substituted with zeroes. An exception to this is when the
- * 'direct_io' mount option is specified, in which case the return
- * value of the read system call will reflect the return value of
- * this operation.
- *
- * Changed in version 2.2
- */
- int (*read) (const char *, char *, size_t, off_t, struct fuse_file_info *);
-
- /** Write data to an open file
- *
- * Write should return exactly the number of bytes requested
- * except on error. An exception to this is when the 'direct_io'
- * mount option is specified (see read operation).
- *
- * Changed in version 2.2
- */
- int (*write) (const char *, const char *, size_t, off_t,
- struct fuse_file_info *);
-
- /** Get file system statistics
- *
- * The 'f_frsize', 'f_favail', 'f_fsid' and 'f_flag' fields are ignored
- *
- * Replaced 'struct statfs' parameter with 'struct statvfs' in
- * version 2.5
- */
- int (*statfs) (const char *, struct statvfs *);
-
- /** Possibly flush cached data
- *
- * BIG NOTE: This is not equivalent to fsync(). It's not a
- * request to sync dirty data.
- *
- * Flush is called on each close() of a file descriptor. So if a
- * filesystem wants to return write errors in close() and the file
- * has cached dirty data, this is a good place to write back data
- * and return any errors. Since many applications ignore close()
- * errors this is not always useful.
- *
- * NOTE: The flush() method may be called more than once for each
- * open(). This happens if more than one file descriptor refers
- * to an opened file due to dup(), dup2() or fork() calls. It is
- * not possible to determine if a flush is final, so each flush
- * should be treated equally. Multiple write-flush sequences are
- * relatively rare, so this shouldn't be a problem.
- *
- * Filesystems shouldn't assume that flush will always be called
- * after some writes, or that if will be called at all.
- *
- * Changed in version 2.2
- */
- int (*flush) (const char *, struct fuse_file_info *);
-
- /** Release an open file
- *
- * Release is called when there are no more references to an open
- * file: all file descriptors are closed and all memory mappings
- * are unmapped.
- *
- * For every open() call there will be exactly one release() call
- * with the same flags and file descriptor. It is possible to
- * have a file opened more than once, in which case only the last
- * release will mean, that no more reads/writes will happen on the
- * file. The return value of release is ignored.
- *
- * Changed in version 2.2
- */
- int (*release) (const char *, struct fuse_file_info *);
-
- /** Synchronize file contents
- *
- * If the datasync parameter is non-zero, then only the user data
- * should be flushed, not the meta data.
- *
- * Changed in version 2.2
- */
- int (*fsync) (const char *, int, struct fuse_file_info *);
-
- /** Set extended attributes */
- int (*setxattr) (const char *, const char *, const char *, size_t, int);
-
- /** Get extended attributes */
- int (*getxattr) (const char *, const char *, char *, size_t);
-
- /** List extended attributes */
- int (*listxattr) (const char *, char *, size_t);
-
- /** Remove extended attributes */
- int (*removexattr) (const char *, const char *);
-
- /** Open directory
- *
- * This method should check if the open operation is permitted for
- * this directory
- *
- * Introduced in version 2.3
- */
- int (*opendir) (const char *, struct fuse_file_info *);
-
- /** Read directory
- *
- * This supersedes the old getdir() interface. New applications
- * should use this.
- *
- * The filesystem may choose between two modes of operation:
- *
- * 1) The readdir implementation ignores the offset parameter, and
- * passes zero to the filler function's offset. The filler
- * function will not return '1' (unless an error happens), so the
- * whole directory is read in a single readdir operation. This
- * works just like the old getdir() method.
- *
- * 2) The readdir implementation keeps track of the offsets of the
- * directory entries. It uses the offset parameter and always
- * passes non-zero offset to the filler function. When the buffer
- * is full (or an error happens) the filler function will return
- * '1'.
- *
- * Introduced in version 2.3
- */
- int (*readdir) (const char *, void *, fuse_fill_dir_t, off_t,
- struct fuse_file_info *);
-
- /** Release directory
- *
- * Introduced in version 2.3
- */
- int (*releasedir) (const char *, struct fuse_file_info *);
-
- /** Synchronize directory contents
- *
- * If the datasync parameter is non-zero, then only the user data
- * should be flushed, not the meta data
- *
- * Introduced in version 2.3
- */
- int (*fsyncdir) (const char *, int, struct fuse_file_info *);
-
- /**
- * Initialize filesystem
- *
- * The return value will passed in the private_data field of
- * fuse_context to all file operations and as a parameter to the
- * destroy() method.
- *
- * Introduced in version 2.3
- * Changed in version 2.6
- */
- void *(*init) (struct fuse_conn_info *conn);
-
- /**
- * Clean up filesystem
- *
- * Called on filesystem exit.
- *
- * Introduced in version 2.3
- */
- void (*destroy) (void *);
-
- /**
- * Check file access permissions
- *
- * This will be called for the access() system call. If the
- * 'default_permissions' mount option is given, this method is not
- * called.
- *
- * This method is not called under Linux kernel versions 2.4.x
- *
- * Introduced in version 2.5
- */
- int (*access) (const char *, int);
-
- /**
- * Create and open a file
- *
- * If the file does not exist, first create it with the specified
- * mode, and then open it.
- *
- * If this method is not implemented or under Linux kernel
- * versions earlier than 2.6.15, the mknod() and open() methods
- * will be called instead.
- *
- * Introduced in version 2.5
- */
- int (*create) (const char *, mode_t, struct fuse_file_info *);
-
- /**
- * Change the size of an open file
- *
- * This method is called instead of the truncate() method if the
- * truncation was invoked from an ftruncate() system call.
- *
- * If this method is not implemented or under Linux kernel
- * versions earlier than 2.6.15, the truncate() method will be
- * called instead.
- *
- * Introduced in version 2.5
- */
- int (*ftruncate) (const char *, off_t, struct fuse_file_info *);
-
- /**
- * Get attributes from an open file
- *
- * This method is called instead of the getattr() method if the
- * file information is available.
- *
- * Currently this is only called after the create() method if that
- * is implemented (see above). Later it may be called for
- * invocations of fstat() too.
- *
- * Introduced in version 2.5
- */
- int (*fgetattr) (const char *, struct stat *, struct fuse_file_info *);
-
- /**
- * Perform POSIX file locking operation
- *
- * The cmd argument will be either F_GETLK, F_SETLK or F_SETLKW.
- *
- * For the meaning of fields in 'struct flock' see the man page
- * for fcntl(2). The l_whence field will always be set to
- * SEEK_SET.
- *
- * For checking lock ownership, the 'fuse_file_info->owner'
- * argument must be used.
- *
- * For F_GETLK operation, the library will first check currently
- * held locks, and if a conflicting lock is found it will return
- * information without calling this method. This ensures, that
- * for local locks the l_pid field is correctly filled in. The
- * results may not be accurate in case of race conditions and in
- * the presence of hard links, but it's unlikly that an
- * application would rely on accurate GETLK results in these
- * cases. If a conflicting lock is not found, this method will be
- * called, and the filesystem may fill out l_pid by a meaningful
- * value, or it may leave this field zero.
- *
- * For F_SETLK and F_SETLKW the l_pid field will be set to the pid
- * of the process performing the locking operation.
- *
- * Note: if this method is not implemented, the kernel will still
- * allow file locking to work locally. Hence it is only
- * interesting for network filesystems and similar.
- *
- * Introduced in version 2.6
- */
- int (*lock) (const char *, struct fuse_file_info *, int cmd,
- struct flock *);
-
- /**
- * Change the access and modification times of a file with
- * nanosecond resolution
- *
- * Introduced in version 2.6
- */
- int (*utimens) (const char *, const struct timespec tv[2]);
-
- /**
- * Map block index within file to block index within device
- *
- * Note: This makes sense only for block device backed filesystems
- * mounted with the 'blkdev' option
- *
- * Introduced in version 2.6
- */
- int (*bmap) (const char *, size_t blocksize, uint64_t *idx);
+ /** Get file attributes.
+ *
+ * Similar to stat(). The 'st_dev' and 'st_blksize' fields are
+ * ignored. The 'st_ino' field is ignored except if the 'use_ino'
+ * mount option is given.
+ */
+ int (*getattr) (const char *, struct stat *);
+
+ /** Read the target of a symbolic link
+ *
+ * The buffer should be filled 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.
+ */
+ int (*readlink) (const char *, char *, size_t);
+
+ /* Deprecated, use readdir() instead */
+ int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t);
+
+ /** Create a file node
+ *
+ * This is called for creation of all non-directory, non-symlink
+ * nodes. If the filesystem defines a create() method, then for
+ * regular files that will be called instead.
+ */
+ int (*mknod) (const char *, mode_t, dev_t);
+
+ /** Create a directory */
+ int (*mkdir) (const char *, mode_t);
+
+ /** Remove a file */
+ int (*unlink) (const char *);
+
+ /** Remove a directory */
+ int (*rmdir) (const char *);
+
+ /** Create a symbolic link */
+ int (*symlink) (const char *, const char *);
+
+ /** Rename a file */
+ int (*rename) (const char *, const char *);
+
+ /** Create a hard link to a file */
+ int (*link) (const char *, const char *);
+
+ /** Change the permission bits of a file */
+ int (*chmod) (const char *, mode_t);
+
+ /** Change the owner and group of a file */
+ int (*chown) (const char *, uid_t, gid_t);
+
+ /** Change the size of a file */
+ int (*truncate) (const char *, off_t);
+
+ /** Change the access and/or modification times of a file
+ *
+ * Deprecated, use utimens() instead.
+ */
+ int (*utime) (const char *, struct utimbuf *);
+
+ /** File open operation
+ *
+ * No creation, or truncation flags (O_CREAT, O_EXCL, O_TRUNC)
+ * will be passed to open(). Open should check if the operation
+ * is permitted for the given flags. Optionally open may also
+ * return an arbitrary filehandle in the fuse_file_info structure,
+ * which will be passed to all file operations.
+ *
+ * Changed in version 2.2
+ */
+ int (*open) (const char *, struct fuse_file_info *);
+
+ /** Read data from an open file
+ *
+ * Read should return exactly the number of bytes requested except
+ * on EOF or error, otherwise the rest of the data will be
+ * substituted with zeroes. An exception to this is when the
+ * 'direct_io' mount option is specified, in which case the return
+ * value of the read system call will reflect the return value of
+ * this operation.
+ *
+ * Changed in version 2.2
+ */
+ int (*read) (const char *, char *, size_t, off_t,
+ struct fuse_file_info *);
+
+ /** Write data to an open file
+ *
+ * Write should return exactly the number of bytes requested
+ * except on error. An exception to this is when the 'direct_io'
+ * mount option is specified (see read operation).
+ *
+ * Changed in version 2.2
+ */
+ int (*write) (const char *, const char *, size_t, off_t,
+ struct fuse_file_info *);
+
+ /** Get file system statistics
+ *
+ * The 'f_frsize', 'f_favail', 'f_fsid' and 'f_flag' fields are ignored
+ *
+ * Replaced 'struct statfs' parameter with 'struct statvfs' in
+ * version 2.5
+ */
+ int (*statfs) (const char *, struct statvfs *);
+
+ /** Possibly flush cached data
+ *
+ * BIG NOTE: This is not equivalent to fsync(). It's not a
+ * request to sync dirty data.
+ *
+ * Flush is called on each close() of a file descriptor. So if a
+ * filesystem wants to return write errors in close() and the file
+ * has cached dirty data, this is a good place to write back data
+ * and return any errors. Since many applications ignore close()
+ * errors this is not always useful.
+ *
+ * NOTE: The flush() method may be called more than once for each
+ * open(). This happens if more than one file descriptor refers
+ * to an opened file due to dup(), dup2() or fork() calls. It is
+ * not possible to determine if a flush is final, so each flush
+ * should be treated equally. Multiple write-flush sequences are
+ * relatively rare, so this shouldn't be a problem.
+ *
+ * Filesystems shouldn't assume that flush will always be called
+ * after some writes, or that if will be called at all.
+ *
+ * Changed in version 2.2
+ */
+ int (*flush) (const char *, struct fuse_file_info *);
+
+ /** Release an open file
+ *
+ * Release is called when there are no more references to an open
+ * file: all file descriptors are closed and all memory mappings
+ * are unmapped.
+ *
+ * For every open() call there will be exactly one release() call
+ * with the same flags and file descriptor. It is possible to
+ * have a file opened more than once, in which case only the last
+ * release will mean, that no more reads/writes will happen on the
+ * file. The return value of release is ignored.
+ *
+ * Changed in version 2.2
+ */
+ int (*release) (const char *, struct fuse_file_info *);
+
+ /** Synchronize file contents
+ *
+ * If the datasync parameter is non-zero, then only the user data
+ * should be flushed, not the meta data.
+ *
+ * Changed in version 2.2
+ */
+ int (*fsync) (const char *, int, struct fuse_file_info *);
+
+ /** Set extended attributes */
+ int (*setxattr) (const char *, const char *, const char *, size_t, int);
+
+ /** Get extended attributes */
+ int (*getxattr) (const char *, const char *, char *, size_t);
+
+ /** List extended attributes */
+ int (*listxattr) (const char *, char *, size_t);
+
+ /** Remove extended attributes */
+ int (*removexattr) (const char *, const char *);
+
+ /** Open directory
+ *
+ * This method should check if the open operation is permitted for
+ * this directory
+ *
+ * Introduced in version 2.3
+ */
+ int (*opendir) (const char *, struct fuse_file_info *);
+
+ /** Read directory
+ *
+ * This supersedes the old getdir() interface. New applications
+ * should use this.
+ *
+ * The filesystem may choose between two modes of operation:
+ *
+ * 1) The readdir implementation ignores the offset parameter, and
+ * passes zero to the filler function's offset. The filler
+ * function will not return '1' (unless an error happens), so the
+ * whole directory is read in a single readdir operation. This
+ * works just like the old getdir() method.
+ *
+ * 2) The readdir implementation keeps track of the offsets of the
+ * directory entries. It uses the offset parameter and always
+ * passes non-zero offset to the filler function. When the buffer
+ * is full (or an error happens) the filler function will return
+ * '1'.
+ *
+ * Introduced in version 2.3
+ */
+ int (*readdir) (const char *, void *, fuse_fill_dir_t, off_t,
+ struct fuse_file_info *);
+
+ /** Release directory
+ *
+ * Introduced in version 2.3
+ */
+ int (*releasedir) (const char *, struct fuse_file_info *);
+
+ /** Synchronize directory contents
+ *
+ * If the datasync parameter is non-zero, then only the user data
+ * should be flushed, not the meta data
+ *
+ * Introduced in version 2.3
+ */
+ int (*fsyncdir) (const char *, int, struct fuse_file_info *);
+
+ /**
+ * Initialize filesystem
+ *
+ * The return value will passed in the private_data field of
+ * fuse_context to all file operations and as a parameter to the
+ * destroy() method.
+ *
+ * Introduced in version 2.3
+ * Changed in version 2.6
+ */
+ void *(*init) (struct fuse_conn_info *conn);
+
+ /**
+ * Clean up filesystem
+ *
+ * Called on filesystem exit.
+ *
+ * Introduced in version 2.3
+ */
+ void (*destroy) (void *);
+
+ /**
+ * Check file access permissions
+ *
+ * This will be called for the access() system call. If the
+ * 'default_permissions' mount option is given, this method is not
+ * called.
+ *
+ * This method is not called under Linux kernel versions 2.4.x
+ *
+ * Introduced in version 2.5
+ */
+ int (*access) (const char *, int);
+
+ /**
+ * Create and open a file
+ *
+ * If the file does not exist, first create it with the specified
+ * mode, and then open it.
+ *
+ * If this method is not implemented or under Linux kernel
+ * versions earlier than 2.6.15, the mknod() and open() methods
+ * will be called instead.
+ *
+ * Introduced in version 2.5
+ */
+ int (*create) (const char *, mode_t, struct fuse_file_info *);
+
+ /**
+ * Change the size of an open file
+ *
+ * This method is called instead of the truncate() method if the
+ * truncation was invoked from an ftruncate() system call.
+ *
+ * If this method is not implemented or under Linux kernel
+ * versions earlier than 2.6.15, the truncate() method will be
+ * called instead.
+ *
+ * Introduced in version 2.5
+ */
+ int (*ftruncate) (const char *, off_t, struct fuse_file_info *);
+
+ /**
+ * Get attributes from an open file
+ *
+ * This method is called instead of the getattr() method if the
+ * file information is available.
+ *
+ * Currently this is only called after the create() method if that
+ * is implemented (see above). Later it may be called for
+ * invocations of fstat() too.
+ *
+ * Introduced in version 2.5
+ */
+ int (*fgetattr) (const char *, struct stat *, struct fuse_file_info *);
+
+ /**
+ * Perform POSIX file locking operation
+ *
+ * The cmd argument will be either F_GETLK, F_SETLK or F_SETLKW.
+ *
+ * For the meaning of fields in 'struct flock' see the man page
+ * for fcntl(2). The l_whence field will always be set to
+ * SEEK_SET.
+ *
+ * For checking lock ownership, the 'fuse_file_info->owner'
+ * argument must be used.
+ *
+ * For F_GETLK operation, the library will first check currently
+ * held locks, and if a conflicting lock is found it will return
+ * information without calling this method. This ensures, that
+ * for local locks the l_pid field is correctly filled in. The
+ * results may not be accurate in case of race conditions and in
+ * the presence of hard links, but it's unlikly that an
+ * application would rely on accurate GETLK results in these
+ * cases. If a conflicting lock is not found, this method will be
+ * called, and the filesystem may fill out l_pid by a meaningful
+ * value, or it may leave this field zero.
+ *
+ * For F_SETLK and F_SETLKW the l_pid field will be set to the pid
+ * of the process performing the locking operation.
+ *
+ * Note: if this method is not implemented, the kernel will still
+ * allow file locking to work locally. Hence it is only
+ * interesting for network filesystems and similar.
+ *
+ * Introduced in version 2.6
+ */
+ int (*lock) (const char *, struct fuse_file_info *, int cmd,
+ struct flock *);
+
+ /**
+ * Change the access and modification times of a file with
+ * nanosecond resolution
+ *
+ * Introduced in version 2.6
+ */
+ int (*utimens) (const char *, const struct timespec tv[2]);
+
+ /**
+ * Map block index within file to block index within device
+ *
+ * Note: This makes sense only for block device backed filesystems
+ * mounted with the 'blkdev' option
+ *
+ * Introduced in version 2.6
+ */
+ int (*bmap) (const char *, size_t blocksize, uint64_t *idx);
};
/** Extra context that may be needed by some filesystems
@@ -430,20 +431,20 @@ struct fuse_operations {
* operation.
*/
struct fuse_context {
- /** Pointer to the fuse object */
- struct fuse *fuse;
+ /** Pointer to the fuse object */
+ struct fuse *fuse;
- /** User ID of the calling process */
- uid_t uid;
+ /** User ID of the calling process */
+ uid_t uid;
- /** Group ID of the calling process */
- gid_t gid;
+ /** Group ID of the calling process */
+ gid_t gid;
- /** Thread ID of the calling process */
- pid_t pid;
+ /** Thread ID of the calling process */
+ pid_t pid;
- /** Private filesystem data */
- void *private_data;
+ /** Private filesystem data */
+ void *private_data;
};
/**
@@ -470,14 +471,14 @@ struct fuse_context {
* @return 0 on success, nonzero on failure
*/
/*
-int fuse_main(int argc, char *argv[], const struct fuse_operations *op,
- void *user_data);
+ int fuse_main(int argc, char *argv[], const struct fuse_operations *op,
+ void *user_data);
*/
-#define fuse_main(argc, argv, op, user_data) \
- fuse_main_real(argc, argv, op, sizeof(*(op)), user_data)
+#define fuse_main(argc, argv, op, user_data) \
+ fuse_main_real(argc, argv, op, sizeof(*(op)), user_data)
/* ----------------------------------------------------------- *
- * More detailed API *
+ * More detailed API *
* ----------------------------------------------------------- */
/**
@@ -491,15 +492,15 @@ int fuse_main(int argc, char *argv[], const struct fuse_operations *op,
* @return the created FUSE handle
*/
struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args,
- const struct fuse_operations *op, size_t op_size,
- void *user_data);
+ const struct fuse_operations *op, size_t op_size,
+ void *user_data);
/**
* Destroy the FUSE handle.
*
* The communication channel attached to the handle is also destroyed.
*
- * NOTE: This function does not unmount the filesystem. If this is
+ * NOTE: This function does not unmount the filesystem. If this is
* needed, call fuse_unmount() before calling this function.
*
* @param f the FUSE handle
@@ -573,7 +574,7 @@ int fuse_is_lib_option(const char *opt);
* Do not call this directly, use fuse_main()
*/
int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,
- size_t op_size, void *user_data);
+ size_t op_size, void *user_data);
/*
* Stacking API
@@ -597,63 +598,63 @@ struct fuse_fs;
int fuse_fs_getattr(struct fuse_fs *fs, const char *path, struct stat *buf);
int fuse_fs_fgetattr(struct fuse_fs *fs, const char *path, struct stat *buf,
- struct fuse_file_info *fi);
+ struct fuse_file_info *fi);
int fuse_fs_rename(struct fuse_fs *fs, const char *oldpath,
- const char *newpath);
+ const char *newpath);
int fuse_fs_unlink(struct fuse_fs *fs, const char *path);
int fuse_fs_rmdir(struct fuse_fs *fs, const char *path);
int fuse_fs_symlink(struct fuse_fs *fs, const char *linkname,
- const char *path);
+ const char *path);
int fuse_fs_link(struct fuse_fs *fs, const char *oldpath, const char *newpath);
-int fuse_fs_release(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi);
+int fuse_fs_release(struct fuse_fs *fs, const char *path,
+ struct fuse_file_info *fi);
int fuse_fs_open(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi);
+ struct fuse_file_info *fi);
int fuse_fs_read(struct fuse_fs *fs, const char *path, char *buf, size_t size,
- off_t off, struct fuse_file_info *fi);
+ off_t off, struct fuse_file_info *fi);
int fuse_fs_write(struct fuse_fs *fs, const char *path, const char *buf,
- size_t size, off_t off, struct fuse_file_info *fi);
+ size_t size, off_t off, struct fuse_file_info *fi);
int fuse_fs_fsync(struct fuse_fs *fs, const char *path, int datasync,
- struct fuse_file_info *fi);
+ struct fuse_file_info *fi);
int fuse_fs_flush(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi);
+ struct fuse_file_info *fi);
int fuse_fs_statfs(struct fuse_fs *fs, const char *path, struct statvfs *buf);
int fuse_fs_opendir(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi);
+ struct fuse_file_info *fi);
int fuse_fs_readdir(struct fuse_fs *fs, const char *path, void *buf,
- fuse_fill_dir_t filler, off_t off,
- struct fuse_file_info *fi);
+ fuse_fill_dir_t filler, off_t off,
+ struct fuse_file_info *fi);
int fuse_fs_fsyncdir(struct fuse_fs *fs, const char *path, int datasync,
- struct fuse_file_info *fi);
+ struct fuse_file_info *fi);
int fuse_fs_releasedir(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi);
+ struct fuse_file_info *fi);
int fuse_fs_create(struct fuse_fs *fs, const char *path, mode_t mode,
- struct fuse_file_info *fi);
+ struct fuse_file_info *fi);
int fuse_fs_lock(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi, int cmd, struct flock *lock);
+ struct fuse_file_info *fi, int cmd, struct flock *lock);
int fuse_fs_chmod(struct fuse_fs *fs, const char *path, mode_t mode);
int fuse_fs_chown(struct fuse_fs *fs, const char *path, uid_t uid, gid_t gid);
int fuse_fs_truncate(struct fuse_fs *fs, const char *path, off_t size);
int fuse_fs_ftruncate(struct fuse_fs *fs, const char *path, off_t size,
- struct fuse_file_info *fi);
+ struct fuse_file_info *fi);
int fuse_fs_utimens(struct fuse_fs *fs, const char *path,
- const struct timespec tv[2]);
+ const struct timespec tv[2]);
int fuse_fs_access(struct fuse_fs *fs, const char *path, int mask);
int fuse_fs_readlink(struct fuse_fs *fs, const char *path, char *buf,
- size_t len);
+ size_t len);
int fuse_fs_mknod(struct fuse_fs *fs, const char *path, mode_t mode,
- dev_t rdev);
+ dev_t rdev);
int fuse_fs_mkdir(struct fuse_fs *fs, const char *path, mode_t mode);
int fuse_fs_setxattr(struct fuse_fs *fs, const char *path, const char *name,
- const char *value, size_t size, int flags);
+ const char *value, size_t size, int flags);
int fuse_fs_getxattr(struct fuse_fs *fs, const char *path, const char *name,
- char *value, size_t size);
+ char *value, size_t size);
int fuse_fs_listxattr(struct fuse_fs *fs, const char *path, char *list,
- size_t size);
+ size_t size);
int fuse_fs_removexattr(struct fuse_fs *fs, const char *path,
- const char *name);
+ const char *name);
int fuse_fs_bmap(struct fuse_fs *fs, const char *path, size_t blocksize,
- uint64_t *idx);
+ uint64_t *idx);
void fuse_fs_init(struct fuse_fs *fs, struct fuse_conn_info *conn);
void fuse_fs_destroy(struct fuse_fs *fs);
@@ -669,7 +670,7 @@ void fuse_fs_destroy(struct fuse_fs *fs);
* @return a new filesystem object
*/
struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size,
- void *user_data);
+ void *user_data);
/**
* Filesystem module
@@ -682,30 +683,31 @@ struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size,
* function.
*/
struct fuse_module {
- /**
- * Name of filesystem
- */
- const char *name;
-
- /**
- * Factory for creating filesystem objects
- *
- * The function may use and remove options from 'args' that belong
- * to this module.
- *
- * For now the 'fs' vector always contains exactly one filesystem.
- * This is the filesystem which will be below the newly created
- * filesystem in the stack.
- *
- * @param args the command line arguments
- * @param fs NULL terminated filesystem object vector
- * @return the new filesystem object
- */
- struct fuse_fs *(*factory)(struct fuse_args *args, struct fuse_fs *fs[]);
-
- struct fuse_module *next;
- struct fusemod_so *so;
- int ctr;
+ /**
+ * Name of filesystem
+ */
+ const char *name;
+
+ /**
+ * Factory for creating filesystem objects
+ *
+ * The function may use and remove options from 'args' that belong
+ * to this module.
+ *
+ * For now the 'fs' vector always contains exactly one filesystem.
+ * This is the filesystem which will be below the newly created
+ * filesystem in the stack.
+ *
+ * @param args the command line arguments
+ * @param fs NULL terminated filesystem object vector
+ * @return the new filesystem object
+ */
+ struct fuse_fs *(*factory)(struct fuse_args *args,
+ struct fuse_fs *fs[]);
+
+ struct fuse_module *next;
+ struct fusemod_so *so;
+ int ctr;
};
/**
@@ -722,12 +724,13 @@ void fuse_register_module(struct fuse_module *mod);
* For the parameters, see description of the fields in 'struct
* fuse_module'
*/
-#define FUSE_REGISTER_MODULE(name_, factory_) \
-static __attribute__((constructor)) void name_ ## _register(void) \
-{ \
- static struct fuse_module mod = { #name_, factory_, NULL, NULL, 0 }; \
- fuse_register_module(&mod); \
-}
+#define FUSE_REGISTER_MODULE(name_, factory_) \
+ static __attribute__((constructor)) void name_ ## _register(void) \
+ { \
+ static struct fuse_module mod = \
+ { #name_, factory_, NULL, NULL, 0 }; \
+ fuse_register_module(&mod); \
+ }
/* ----------------------------------------------------------- *
@@ -742,9 +745,9 @@ typedef void (*fuse_processor_t)(struct fuse *, struct fuse_cmd *, void *);
/** This is the part of fuse_main() before the event loop */
struct fuse *fuse_setup(int argc, char *argv[],
- const struct fuse_operations *op, size_t op_size,
- char **mountpoint, int *multithreaded,
- void *user_data);
+ const struct fuse_operations *op, size_t op_size,
+ char **mountpoint, int *multithreaded,
+ void *user_data);
/** This is the part of fuse_main() after the event loop */
void fuse_teardown(struct fuse *fuse, char *mountpoint);
@@ -770,22 +773,22 @@ void fuse_set_getcontext_func(struct fuse_context *(*func)(void));
struct fuse_session *fuse_get_session(struct fuse *f);
/* ----------------------------------------------------------- *
- * Compatibility stuff *
+ * Compatibility stuff *
* ----------------------------------------------------------- */
#if FUSE_USE_VERSION < 26
# include "fuse_compat.h"
# undef fuse_main
# if FUSE_USE_VERSION == 25
-# define fuse_main(argc, argv, op) \
- fuse_main_real_compat25(argc, argv, op, sizeof(*(op)))
+# define fuse_main(argc, argv, op) \
+ fuse_main_real_compat25(argc, argv, op, sizeof(*(op)))
# define fuse_new fuse_new_compat25
# define fuse_setup fuse_setup_compat25
# define fuse_teardown fuse_teardown_compat22
# define fuse_operations fuse_operations_compat25
# elif FUSE_USE_VERSION == 22
-# define fuse_main(argc, argv, op) \
- fuse_main_real_compat22(argc, argv, op, sizeof(*(op)))
+# define fuse_main(argc, argv, op) \
+ fuse_main_real_compat22(argc, argv, op, sizeof(*(op)))
# define fuse_new fuse_new_compat22
# define fuse_setup fuse_setup_compat22
# define fuse_teardown fuse_teardown_compat22
diff --git a/include/fuse_common.h b/include/fuse_common.h
index 1a97512..9747e45 100644
--- a/include/fuse_common.h
+++ b/include/fuse_common.h
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB.
*/
/** @file */
@@ -42,38 +42,38 @@ extern "C" {
* Changed in version 2.5
*/
struct fuse_file_info {
- /** Open flags. Available in open() and release() */
- int flags;
+ /** Open flags. Available in open() and release() */
+ int flags;
- /** Old file handle, don't use */
- unsigned long fh_old;
+ /** Old file handle, don't use */
+ unsigned long fh_old;
- /** In case of a write operation indicates if this was caused by a
- writepage */
- int writepage;
+ /** In case of a write operation indicates if this was caused by a
+ writepage */
+ int writepage;
- /** Can be filled in by open, to use direct I/O on this file.
- Introduced in version 2.4 */
- unsigned int direct_io : 1;
+ /** Can be filled in by open, to use direct I/O on this file.
+ Introduced in version 2.4 */
+ unsigned int direct_io : 1;
- /** Can be filled in by open, to indicate, that cached file data
- need not be invalidated. Introduced in version 2.4 */
- unsigned int keep_cache : 1;
+ /** Can be filled in by open, to indicate, that cached file data
+ need not be invalidated. Introduced in version 2.4 */
+ unsigned int keep_cache : 1;
- /** Indicates a flush operation. Set in flush operation, also
- maybe set in highlevel lock operation and lowlevel release
- operation. Introduced in version 2.6 */
- unsigned int flush : 1;
+ /** Indicates a flush operation. Set in flush operation, also
+ maybe set in highlevel lock operation and lowlevel release
+ operation. Introduced in version 2.6 */
+ unsigned int flush : 1;
- /** Padding. Do not use*/
- unsigned int padding : 29;
+ /** Padding. Do not use*/
+ unsigned int padding : 29;
- /** File handle. May be filled in by filesystem in open().
- Available in all other file operations */
- uint64_t fh;
+ /** File handle. May be filled in by filesystem in open().
+ Available in all other file operations */
+ uint64_t fh;
- /** Lock owner id. Available in locking operations and flush */
- uint64_t lock_owner;
+ /** Lock owner id. Available in locking operations and flush */
+ uint64_t lock_owner;
};
/**
@@ -84,35 +84,35 @@ struct fuse_file_info {
* value must usually be smaller than the indicated value.
*/
struct fuse_conn_info {
- /**
- * Major version of the protocol (read-only)
- */
- unsigned proto_major;
-
- /**
- * Minor version of the protocol (read-only)
- */
- unsigned proto_minor;
-
- /**
- * Is asynchronous read supported (read-write)
- */
- unsigned async_read;
-
- /**
- * Maximum size of the write buffer
- */
- unsigned max_write;
-
- /**
- * Maximum readahead
- */
- unsigned max_readahead;
-
- /**
- * For future use.
- */
- unsigned reserved[27];
+ /**
+ * Major version of the protocol (read-only)
+ */
+ unsigned proto_major;
+
+ /**
+ * Minor version of the protocol (read-only)
+ */
+ unsigned proto_minor;
+
+ /**
+ * Is asynchronous read supported (read-write)
+ */
+ unsigned async_read;
+
+ /**
+ * Maximum size of the write buffer
+ */
+ unsigned max_write;
+
+ /**
+ * Maximum readahead
+ */
+ unsigned max_readahead;
+
+ /**
+ * For future use.
+ */
+ unsigned reserved[27];
};
struct fuse_session;
@@ -143,13 +143,13 @@ void fuse_unmount(const char *mountpoint, struct fuse_chan *ch);
*
* The following options are parsed:
*
- * '-f' foreground
+ * '-f' foreground
* '-d' '-odebug' foreground, but keep the debug option
- * '-s' single threaded
+ * '-s' single threaded
* '-h' '--help' help
- * '-ho' help without header
+ * '-ho' help without header
* '-ofsname=..' file system name, if not present, then set to the program
- * name
+ * name
*
* All parameters may be NULL
*
@@ -160,7 +160,7 @@ void fuse_unmount(const char *mountpoint, struct fuse_chan *ch);
* @return 0 on success, -1 on failure
*/
int fuse_parse_cmdline(struct fuse_args *args, char **mountpoint,
- int *multithreaded, int *foreground);
+ int *multithreaded, int *foreground);
/**
* Go into the background
@@ -178,13 +178,13 @@ int fuse_daemonize(int foreground);
int fuse_version(void);
/* ----------------------------------------------------------- *
- * Signal handling *
+ * Signal handling *
* ----------------------------------------------------------- */
/**
* Exit session on HUP, TERM and INT signals and ignore PIPE signal
*
- * Stores session in a global variable. May only be called once per
+ * Stores session in a global variable. May only be called once per
* process until fuse_remove_signal_handlers() is called.
*
* @param se the session to exit
@@ -203,36 +203,36 @@ int fuse_set_signal_handlers(struct fuse_session *se);
void fuse_remove_signal_handlers(struct fuse_session *se);
/* ----------------------------------------------------------- *
- * Compatibility stuff *
+ * Compatibility stuff *
* ----------------------------------------------------------- */
#if FUSE_USE_VERSION < 26
# ifdef __FreeBSD__
-# if FUSE_USE_VERSION < 25
-# error On FreeBSD API version 25 or greater must be used
-# endif
+# if FUSE_USE_VERSION < 25
+# error On FreeBSD API version 25 or greater must be used
+# endif
# endif
# include "fuse_common_compat.h"
# undef FUSE_MINOR_VERSION
# undef fuse_main
# define fuse_unmount fuse_unmount_compat22
# if FUSE_USE_VERSION == 25
-# define FUSE_MINOR_VERSION 5
-# define fuse_mount fuse_mount_compat25
+# define FUSE_MINOR_VERSION 5
+# define fuse_mount fuse_mount_compat25
# elif FUSE_USE_VERSION == 24 || FUSE_USE_VERSION == 22
-# define FUSE_MINOR_VERSION 4
-# define fuse_mount fuse_mount_compat22
+# define FUSE_MINOR_VERSION 4
+# define fuse_mount fuse_mount_compat22
# elif FUSE_USE_VERSION == 21
-# define FUSE_MINOR_VERSION 1
-# define fuse_mount fuse_mount_compat22
+# define FUSE_MINOR_VERSION 1
+# define fuse_mount fuse_mount_compat22
# elif FUSE_USE_VERSION == 11
-# warning Compatibility with API version 11 is deprecated
-# undef FUSE_MAJOR_VERSION
-# define FUSE_MAJOR_VERSION 1
-# define FUSE_MINOR_VERSION 1
-# define fuse_mount fuse_mount_compat1
+# warning Compatibility with API version 11 is deprecated
+# undef FUSE_MAJOR_VERSION
+# define FUSE_MAJOR_VERSION 1
+# define FUSE_MINOR_VERSION 1
+# define fuse_mount fuse_mount_compat1
# else
-# error Compatibility with API version other than 21, 22, 24, 25 and 11 not supported
+# error Compatibility with API version other than 21, 22, 24, 25 and 11 not supported
# endif
#endif
diff --git a/include/fuse_common_compat.h b/include/fuse_common_compat.h
index 0383ed7..34440ff 100644
--- a/include/fuse_common_compat.h
+++ b/include/fuse_common_compat.h
@@ -1,20 +1,20 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB.
*/
/* these definitions provide source compatibility to prior versions.
Do not include this file directly! */
struct fuse_file_info_compat {
- int flags;
- unsigned long fh;
- int writepage;
- unsigned int direct_io : 1;
- unsigned int keep_cache : 1;
+ int flags;
+ unsigned long fh;
+ int writepage;
+ unsigned int direct_io : 1;
+ unsigned int keep_cache : 1;
};
int fuse_mount_compat25(const char *mountpoint, struct fuse_args *args);
@@ -24,4 +24,3 @@ int fuse_mount_compat22(const char *mountpoint, const char *opts);
int fuse_mount_compat1(const char *mountpoint, const char *args[]);
void fuse_unmount_compat22(const char *mountpoint);
-
diff --git a/include/fuse_compat.h b/include/fuse_compat.h
index 59df3d3..225276f 100644
--- a/include/fuse_compat.h
+++ b/include/fuse_compat.h
@@ -1,66 +1,67 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB.
*/
/* these definitions provide source compatibility to prior versions.
Do not include this file directly! */
struct fuse_operations_compat25 {
- int (*getattr) (const char *, struct stat *);
- int (*readlink) (const char *, char *, size_t);
- int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t);
- int (*mknod) (const char *, mode_t, dev_t);
- int (*mkdir) (const char *, mode_t);
- int (*unlink) (const char *);
- int (*rmdir) (const char *);
- int (*symlink) (const char *, const char *);
- int (*rename) (const char *, const char *);
- int (*link) (const char *, const char *);
- int (*chmod) (const char *, mode_t);
- int (*chown) (const char *, uid_t, gid_t);
- int (*truncate) (const char *, off_t);
- int (*utime) (const char *, struct utimbuf *);
- int (*open) (const char *, struct fuse_file_info *);
- int (*read) (const char *, char *, size_t, off_t, struct fuse_file_info *);
- int (*write) (const char *, const char *, size_t, off_t,
- struct fuse_file_info *);
- int (*statfs) (const char *, struct statvfs *);
- int (*flush) (const char *, struct fuse_file_info *);
- int (*release) (const char *, struct fuse_file_info *);
- int (*fsync) (const char *, int, struct fuse_file_info *);
- int (*setxattr) (const char *, const char *, const char *, size_t, int);
- int (*getxattr) (const char *, const char *, char *, size_t);
- int (*listxattr) (const char *, char *, size_t);
- int (*removexattr) (const char *, const char *);
- int (*opendir) (const char *, struct fuse_file_info *);
- int (*readdir) (const char *, void *, fuse_fill_dir_t, off_t,
- struct fuse_file_info *);
- int (*releasedir) (const char *, struct fuse_file_info *);
- int (*fsyncdir) (const char *, int, struct fuse_file_info *);
- void *(*init) (void);
- void (*destroy) (void *);
- int (*access) (const char *, int);
- int (*create) (const char *, mode_t, struct fuse_file_info *);
- int (*ftruncate) (const char *, off_t, struct fuse_file_info *);
- int (*fgetattr) (const char *, struct stat *, struct fuse_file_info *);
+ int (*getattr) (const char *, struct stat *);
+ int (*readlink) (const char *, char *, size_t);
+ int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t);
+ int (*mknod) (const char *, mode_t, dev_t);
+ int (*mkdir) (const char *, mode_t);
+ int (*unlink) (const char *);
+ int (*rmdir) (const char *);
+ int (*symlink) (const char *, const char *);
+ int (*rename) (const char *, const char *);
+ int (*link) (const char *, const char *);
+ int (*chmod) (const char *, mode_t);
+ int (*chown) (const char *, uid_t, gid_t);
+ int (*truncate) (const char *, off_t);
+ int (*utime) (const char *, struct utimbuf *);
+ int (*open) (const char *, struct fuse_file_info *);
+ int (*read) (const char *, char *, size_t, off_t,
+ struct fuse_file_info *);
+ int (*write) (const char *, const char *, size_t, off_t,
+ struct fuse_file_info *);
+ int (*statfs) (const char *, struct statvfs *);
+ int (*flush) (const char *, struct fuse_file_info *);
+ int (*release) (const char *, struct fuse_file_info *);
+ int (*fsync) (const char *, int, struct fuse_file_info *);
+ int (*setxattr) (const char *, const char *, const char *, size_t, int);
+ int (*getxattr) (const char *, const char *, char *, size_t);
+ int (*listxattr) (const char *, char *, size_t);
+ int (*removexattr) (const char *, const char *);
+ int (*opendir) (const char *, struct fuse_file_info *);
+ int (*readdir) (const char *, void *, fuse_fill_dir_t, off_t,
+ struct fuse_file_info *);
+ int (*releasedir) (const char *, struct fuse_file_info *);
+ int (*fsyncdir) (const char *, int, struct fuse_file_info *);
+ void *(*init) (void);
+ void (*destroy) (void *);
+ int (*access) (const char *, int);
+ int (*create) (const char *, mode_t, struct fuse_file_info *);
+ int (*ftruncate) (const char *, off_t, struct fuse_file_info *);
+ int (*fgetattr) (const char *, struct stat *, struct fuse_file_info *);
};
struct fuse *fuse_new_compat25(int fd, struct fuse_args *args,
- const struct fuse_operations_compat25 *op,
- size_t op_size);
+ const struct fuse_operations_compat25 *op,
+ size_t op_size);
int fuse_main_real_compat25(int argc, char *argv[],
- const struct fuse_operations_compat25 *op,
- size_t op_size);
+ const struct fuse_operations_compat25 *op,
+ size_t op_size);
struct fuse *fuse_setup_compat25(int argc, char *argv[],
- const struct fuse_operations_compat25 *op,
- size_t op_size, char **mountpoint,
- int *multithreaded, int *fd);
+ const struct fuse_operations_compat25 *op,
+ size_t op_size, char **mountpoint,
+ int *multithreaded, int *fd);
void fuse_teardown_compat22(struct fuse *fuse, int fd, char *mountpoint);
@@ -68,126 +69,133 @@ void fuse_teardown_compat22(struct fuse *fuse, int fd, char *mountpoint);
#include <sys/statfs.h>
struct fuse_operations_compat22 {
- int (*getattr) (const char *, struct stat *);
- int (*readlink) (const char *, char *, size_t);
- int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t);
- int (*mknod) (const char *, mode_t, dev_t);
- int (*mkdir) (const char *, mode_t);
- int (*unlink) (const char *);
- int (*rmdir) (const char *);
- int (*symlink) (const char *, const char *);
- int (*rename) (const char *, const char *);
- int (*link) (const char *, const char *);
- int (*chmod) (const char *, mode_t);
- int (*chown) (const char *, uid_t, gid_t);
- int (*truncate) (const char *, off_t);
- int (*utime) (const char *, struct utimbuf *);
- int (*open) (const char *, struct fuse_file_info_compat *);
- int (*read) (const char *, char *, size_t, off_t,
- struct fuse_file_info_compat *);
- int (*write) (const char *, const char *, size_t, off_t,
- struct fuse_file_info_compat *);
- int (*statfs) (const char *, struct statfs *);
- int (*flush) (const char *, struct fuse_file_info_compat *);
- int (*release) (const char *, struct fuse_file_info_compat *);
- int (*fsync) (const char *, int, struct fuse_file_info_compat *);
- int (*setxattr) (const char *, const char *, const char *, size_t, int);
- int (*getxattr) (const char *, const char *, char *, size_t);
- int (*listxattr) (const char *, char *, size_t);
- int (*removexattr) (const char *, const char *);
- int (*opendir) (const char *, struct fuse_file_info_compat *);
- int (*readdir) (const char *, void *, fuse_fill_dir_t, off_t,
- struct fuse_file_info_compat *);
- int (*releasedir) (const char *, struct fuse_file_info_compat *);
- int (*fsyncdir) (const char *, int, struct fuse_file_info_compat *);
- void *(*init) (void);
- void (*destroy) (void *);
+ int (*getattr) (const char *, struct stat *);
+ int (*readlink) (const char *, char *, size_t);
+ int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t);
+ int (*mknod) (const char *, mode_t, dev_t);
+ int (*mkdir) (const char *, mode_t);
+ int (*unlink) (const char *);
+ int (*rmdir) (const char *);
+ int (*symlink) (const char *, const char *);
+ int (*rename) (const char *, const char *);
+ int (*link) (const char *, const char *);
+ int (*chmod) (const char *, mode_t);
+ int (*chown) (const char *, uid_t, gid_t);
+ int (*truncate) (const char *, off_t);
+ int (*utime) (const char *, struct utimbuf *);
+ int (*open) (const char *, struct fuse_file_info_compat *);
+ int (*read) (const char *, char *, size_t, off_t,
+ struct fuse_file_info_compat *);
+ int (*write) (const char *, const char *, size_t, off_t,
+ struct fuse_file_info_compat *);
+ int (*statfs) (const char *, struct statfs *);
+ int (*flush) (const char *, struct fuse_file_info_compat *);
+ int (*release) (const char *, struct fuse_file_info_compat *);
+ int (*fsync) (const char *, int, struct fuse_file_info_compat *);
+ int (*setxattr) (const char *, const char *, const char *, size_t, int);
+ int (*getxattr) (const char *, const char *, char *, size_t);
+ int (*listxattr) (const char *, char *, size_t);
+ int (*removexattr) (const char *, const char *);
+ int (*opendir) (const char *, struct fuse_file_info_compat *);
+ int (*readdir) (const char *, void *, fuse_fill_dir_t, off_t,
+ struct fuse_file_info_compat *);
+ int (*releasedir) (const char *, struct fuse_file_info_compat *);
+ int (*fsyncdir) (const char *, int, struct fuse_file_info_compat *);
+ void *(*init) (void);
+ void (*destroy) (void *);
};
struct fuse *fuse_new_compat22(int fd, const char *opts,
- const struct fuse_operations_compat22 *op,
- size_t op_size);
+ const struct fuse_operations_compat22 *op,
+ size_t op_size);
struct fuse *fuse_setup_compat22(int argc, char *argv[],
- const struct fuse_operations_compat22 *op,
- size_t op_size, char **mountpoint,
- int *multithreaded, int *fd);
+ const struct fuse_operations_compat22 *op,
+ size_t op_size, char **mountpoint,
+ int *multithreaded, int *fd);
int fuse_main_real_compat22(int argc, char *argv[],
- const struct fuse_operations_compat22 *op,
- size_t op_size);
+ const struct fuse_operations_compat22 *op,
+ size_t op_size);
typedef int (*fuse_dirfil_t_compat) (fuse_dirh_t h, const char *name, int type);
struct fuse_operations_compat2 {
- int (*getattr) (const char *, struct stat *);
- int (*readlink) (const char *, char *, size_t);
- int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t_compat);
- int (*mknod) (const char *, mode_t, dev_t);
- int (*mkdir) (const char *, mode_t);
- int (*unlink) (const char *);
- int (*rmdir) (const char *);
- int (*symlink) (const char *, const char *);
- int (*rename) (const char *, const char *);
- int (*link) (const char *, const char *);
- int (*chmod) (const char *, mode_t);
- int (*chown) (const char *, uid_t, gid_t);
- int (*truncate) (const char *, off_t);
- int (*utime) (const char *, struct utimbuf *);
- int (*open) (const char *, int);
- int (*read) (const char *, char *, size_t, off_t);
- int (*write) (const char *, const char *, size_t, off_t);
- int (*statfs) (const char *, struct statfs *);
- int (*flush) (const char *);
- int (*release) (const char *, int);
- int (*fsync) (const char *, int);
- int (*setxattr) (const char *, const char *, const char *, size_t, int);
- int (*getxattr) (const char *, const char *, char *, size_t);
- int (*listxattr) (const char *, char *, size_t);
- int (*removexattr) (const char *, const char *);
+ int (*getattr) (const char *, struct stat *);
+ int (*readlink) (const char *, char *, size_t);
+ int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t_compat);
+ int (*mknod) (const char *, mode_t, dev_t);
+ int (*mkdir) (const char *, mode_t);
+ int (*unlink) (const char *);
+ int (*rmdir) (const char *);
+ int (*symlink) (const char *, const char *);
+ int (*rename) (const char *, const char *);
+ int (*link) (const char *, const char *);
+ int (*chmod) (const char *, mode_t);
+ int (*chown) (const char *, uid_t, gid_t);
+ int (*truncate) (const char *, off_t);
+ int (*utime) (const char *, struct utimbuf *);
+ int (*open) (const char *, int);
+ int (*read) (const char *, char *, size_t, off_t);
+ int (*write) (const char *, const char *, size_t, off_t);
+ int (*statfs) (const char *, struct statfs *);
+ int (*flush) (const char *);
+ int (*release) (const char *, int);
+ int (*fsync) (const char *, int);
+ int (*setxattr) (const char *, const char *, const char *,
+ size_t, int);
+ int (*getxattr) (const char *, const char *, char *, size_t);
+ int (*listxattr) (const char *, char *, size_t);
+ int (*removexattr) (const char *, const char *);
};
-int fuse_main_compat2(int argc, char *argv[], const struct fuse_operations_compat2 *op);
+int fuse_main_compat2(int argc, char *argv[],
+ const struct fuse_operations_compat2 *op);
-struct fuse *fuse_new_compat2(int fd, const char *opts, const struct fuse_operations_compat2 *op);
+struct fuse *fuse_new_compat2(int fd, const char *opts,
+ const struct fuse_operations_compat2 *op);
-struct fuse *fuse_setup_compat2(int argc, char *argv[], const struct fuse_operations_compat2 *op, char **mountpoint, int *multithreaded, int *fd);
+struct fuse *fuse_setup_compat2(int argc, char *argv[],
+ const struct fuse_operations_compat2 *op,
+ char **mountpoint, int *multithreaded, int *fd);
struct fuse_statfs_compat1 {
- long block_size;
- long blocks;
- long blocks_free;
- long files;
- long files_free;
- long namelen;
+ long block_size;
+ long blocks;
+ long blocks_free;
+ long files;
+ long files_free;
+ long namelen;
};
struct fuse_operations_compat1 {
- int (*getattr) (const char *, struct stat *);
- int (*readlink) (const char *, char *, size_t);
- int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t_compat);
- int (*mknod) (const char *, mode_t, dev_t);
- int (*mkdir) (const char *, mode_t);
- int (*unlink) (const char *);
- int (*rmdir) (const char *);
- int (*symlink) (const char *, const char *);
- int (*rename) (const char *, const char *);
- int (*link) (const char *, const char *);
- int (*chmod) (const char *, mode_t);
- int (*chown) (const char *, uid_t, gid_t);
- int (*truncate) (const char *, off_t);
- int (*utime) (const char *, struct utimbuf *);
- int (*open) (const char *, int);
- int (*read) (const char *, char *, size_t, off_t);
- int (*write) (const char *, const char *, size_t, off_t);
- int (*statfs) (struct fuse_statfs_compat1 *);
- int (*release) (const char *, int);
- int (*fsync) (const char *, int);
+ int (*getattr) (const char *, struct stat *);
+ int (*readlink) (const char *, char *, size_t);
+ int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t_compat);
+ int (*mknod) (const char *, mode_t, dev_t);
+ int (*mkdir) (const char *, mode_t);
+ int (*unlink) (const char *);
+ int (*rmdir) (const char *);
+ int (*symlink) (const char *, const char *);
+ int (*rename) (const char *, const char *);
+ int (*link) (const char *, const char *);
+ int (*chmod) (const char *, mode_t);
+ int (*chown) (const char *, uid_t, gid_t);
+ int (*truncate) (const char *, off_t);
+ int (*utime) (const char *, struct utimbuf *);
+ int (*open) (const char *, int);
+ int (*read) (const char *, char *, size_t, off_t);
+ int (*write) (const char *, const char *, size_t, off_t);
+ int (*statfs) (struct fuse_statfs_compat1 *);
+ int (*release) (const char *, int);
+ int (*fsync) (const char *, int);
};
-#define FUSE_DEBUG_COMPAT1 (1 << 1)
+#define FUSE_DEBUG_COMPAT1 (1 << 1)
-struct fuse *fuse_new_compat1(int fd, int flags, const struct fuse_operations_compat1 *op);
+struct fuse *fuse_new_compat1(int fd, int flags,
+ const struct fuse_operations_compat1 *op);
-void fuse_main_compat1(int argc, char *argv[], const struct fuse_operations_compat1 *op);
+void fuse_main_compat1(int argc, char *argv[],
+ const struct fuse_operations_compat1 *op);
#endif /* __FreeBSD__ */
diff --git a/include/fuse_lowlevel.h b/include/fuse_lowlevel.h
index 96c7340..9330548 100644
--- a/include/fuse_lowlevel.h
+++ b/include/fuse_lowlevel.h
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB.
*/
#ifndef _FUSE_LOWLEVEL_H_
@@ -37,7 +37,7 @@ extern "C" {
#endif
/* ----------------------------------------------------------- *
- * Miscellaneous definitions *
+ * Miscellaneous definitions *
* ----------------------------------------------------------- */
/** The node ID of the root inode */
@@ -66,43 +66,49 @@ struct fuse_chan;
/** Directory entry parameters supplied to fuse_reply_entry() */
struct fuse_entry_param {
- /** Unique inode number
- *
- * In lookup, zero means negative entry (from version 2.5)
- * Returning ENOENT also means negative entry, but by setting zero
- * ino the kernel may cache negative entries for entry_timeout
- * seconds.
- */
- fuse_ino_t ino;
-
- /** Generation number for this entry. The ino/generation pair
- should be unique for the filesystem's lifetime. It must be
- non-zero, otherwise FUSE will treat it as an error. */
- unsigned long generation;
-
- /** Inode attributes. Even if attr_timeout == 0, attr must be
- correct. For example, for open(), FUSE uses attr.st_size from
- lookup() to determine how many bytes to request. If this
- value is not correct, incorrect data will be returned. */
- struct stat attr;
-
- /** Validity timeout (in seconds) for the attributes */
- double attr_timeout;
-
- /** Validity timeout (in seconds) for the name */
- double entry_timeout;
+ /** Unique inode number
+ *
+ * In lookup, zero means negative entry (from version 2.5)
+ * Returning ENOENT also means negative entry, but by setting zero
+ * ino the kernel may cache negative entries for entry_timeout
+ * seconds.
+ */
+ fuse_ino_t ino;
+
+ /** Generation number for this entry.
+ *
+ * The ino/generation pair should be unique for the filesystem's
+ * lifetime. It must be non-zero, otherwise FUSE will treat it as an
+ * error.
+ */
+ unsigned long generation;
+
+ /** Inode attributes.
+ *
+ * Even if attr_timeout == 0, attr must be correct. For example,
+ * for open(), FUSE uses attr.st_size from lookup() to determine
+ * how many bytes to request. If this value is not correct,
+ * incorrect data will be returned.
+ */
+ struct stat attr;
+
+ /** Validity timeout (in seconds) for the attributes */
+ double attr_timeout;
+
+ /** Validity timeout (in seconds) for the name */
+ double entry_timeout;
};
/** Additional context associated with requests */
struct fuse_ctx {
- /** User ID of the calling process */
- uid_t uid;
+ /** User ID of the calling process */
+ uid_t uid;
- /** Group ID of the calling process */
- gid_t gid;
+ /** Group ID of the calling process */
+ gid_t gid;
- /** Thread ID of the calling process */
- pid_t pid;
+ /** Thread ID of the calling process */
+ pid_t pid;
};
/* 'to_set' flags in setattr */
@@ -114,7 +120,7 @@ struct fuse_ctx {
#define FUSE_SET_ATTR_MTIME (1 << 5)
/* ----------------------------------------------------------- *
- * Request methods and replies *
+ * Request methods and replies *
* ----------------------------------------------------------- */
/**
@@ -139,662 +145,668 @@ struct fuse_ctx {
* this file will not be called.
*/
struct fuse_lowlevel_ops {
- /**
- * Initialize filesystem
- *
- * Called before any other filesystem method
- *
- * There's no reply to this function
- *
- * @param userdata the user data passed to fuse_lowlevel_new()
- */
- void (*init) (void *userdata, struct fuse_conn_info *conn);
-
- /**
- * Clean up filesystem
- *
- * Called on filesystem exit
- *
- * There's no reply to this function
- *
- * @param userdata the user data passed to fuse_lowlevel_new()
- */
- void (*destroy) (void *userdata);
-
- /**
- * Look up a directory entry by name and get its attributes.
- *
- * Valid replies:
- * fuse_reply_entry
- * fuse_reply_err
- *
- * @param req request handle
- * @param parent inode number of the parent directory
- * @param name the name to look up
- */
- void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
-
- /**
- * Forget about an inode
- *
- * The nlookup parameter indicates the number of lookups
- * previously performed on this inode.
- *
- * If the filesystem implements inode lifetimes, it is recommended
- * that inodes acquire a single reference on each lookup, and lose
- * nlookup references on each forget.
- *
- * The filesystem may ignore forget calls, if the inodes don't
- * need to have a limited lifetime.
- *
- * On unmount it is not guaranteed, that all referenced inodes
- * will receive a forget message.
- *
- * Valid replies:
- * fuse_reply_none
- *
- * @param req request handle
- * @param ino the inode number
- * @param nlookup the number of lookups to forget
- */
- void (*forget) (fuse_req_t req, fuse_ino_t ino, unsigned long nlookup);
-
- /**
- * Get file attributes
- *
- * Valid replies:
- * fuse_reply_attr
- * fuse_reply_err
- *
- * @param req request handle
- * @param ino the inode number
- * @param fi for future use, currently always NULL
- */
- void (*getattr) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
-
- /**
- * Set file attributes
- *
- * In the 'attr' argument only members indicated by the 'to_set'
- * bitmask contain valid values. Other members contain undefined
- * values.
- *
- * If the setattr was invoked from the ftruncate() system call
- * under Linux kernel versions 2.6.15 or later, the fi->fh will
- * contain the value set by the open method or will be undefined
- * if the open method didn't set any value. Otherwise (not
- * ftruncate call, or kernel version earlier than 2.6.15) the fi
- * parameter will be NULL.
- *
- * Valid replies:
- * fuse_reply_attr
- * fuse_reply_err
- *
- * @param req request handle
- * @param ino the inode number
- * @param attr the attributes
- * @param to_set bit mask of attributes which should be set
- * @param fi file information, or NULL
- *
- * Changed in version 2.5:
- * file information filled in for ftruncate
- */
- void (*setattr) (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
- int to_set, struct fuse_file_info *fi);
-
- /**
- * Read symbolic link
- *
- * Valid replies:
- * fuse_reply_readlink
- * fuse_reply_err
- *
- * @param req request handle
- * @param ino the inode number
- */
- void (*readlink) (fuse_req_t req, fuse_ino_t ino);
-
- /**
- * Create file node
- *
- * Create a regular file, character device, block device, fifo or
- * socket node.
- *
- * Valid replies:
- * fuse_reply_entry
- * fuse_reply_err
- *
- * @param req request handle
- * @param parent inode number of the parent directory
- * @param name to create
- * @param mode file type and mode with which to create the new file
- * @param rdev the device number (only valid if created file is a device)
- */
- void (*mknod) (fuse_req_t req, fuse_ino_t parent, const char *name,
- mode_t mode, dev_t rdev);
-
- /**
- * Create a directory
- *
- * Valid replies:
- * fuse_reply_entry
- * fuse_reply_err
- *
- * @param req request handle
- * @param parent inode number of the parent directory
- * @param name to create
- * @param mode with which to create the new file
- */
- void (*mkdir) (fuse_req_t req, fuse_ino_t parent, const char *name,
- mode_t mode);
-
- /**
- * Remove a file
- *
- * Valid replies:
- * fuse_reply_err
- *
- * @param req request handle
- * @param parent inode number of the parent directory
- * @param name to remove
- */
- void (*unlink) (fuse_req_t req, fuse_ino_t parent, const char *name);
-
- /**
- * Remove a directory
- *
- * Valid replies:
- * fuse_reply_err
- *
- * @param req request handle
- * @param parent inode number of the parent directory
- * @param name to remove
- */
- void (*rmdir) (fuse_req_t req, fuse_ino_t parent, const char *name);
-
- /**
- * Create a symbolic link
- *
- * Valid replies:
- * fuse_reply_entry
- * fuse_reply_err
- *
- * @param req request handle
- * @param link the contents of the symbolic link
- * @param parent inode number of the parent directory
- * @param name to create
- */
- void (*symlink) (fuse_req_t req, const char *link, fuse_ino_t parent,
- const char *name);
-
- /** Rename a file
- *
- * Valid replies:
- * fuse_reply_err
- *
- * @param req request handle
- * @param parent inode number of the old parent directory
- * @param name old name
- * @param newparent inode number of the new parent directory
- * @param newname new name
- */
- void (*rename) (fuse_req_t req, fuse_ino_t parent, const char *name,
- fuse_ino_t newparent, const char *newname);
-
- /**
- * Create a hard link
- *
- * Valid replies:
- * fuse_reply_entry
- * fuse_reply_err
- *
- * @param req request handle
- * @param ino the old inode number
- * @param newparent inode number of the new parent directory
- * @param newname new name to create
- */
- void (*link) (fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
- const char *newname);
-
- /**
- * Open a file
- *
- * Open flags (with the exception of O_CREAT, O_EXCL, O_NOCTTY and
- * O_TRUNC) are available in fi->flags.
- *
- * Filesystem may store an arbitrary file handle (pointer, index,
- * etc) in fi->fh, and use this in other all other file operations
- * (read, write, flush, release, fsync).
- *
- * Filesystem may also implement stateless file I/O and not store
- * anything in fi->fh.
- *
- * There are also some flags (direct_io, keep_cache) which the
- * filesystem may set in fi, to change the way the file is opened.
- * See fuse_file_info structure in <fuse_common.h> for more details.
- *
- * Valid replies:
- * fuse_reply_open
- * fuse_reply_err
- *
- * @param req request handle
- * @param ino the inode number
- * @param fi file information
- */
- void (*open) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
-
- /**
- * Read data
- *
- * Read should send exactly the number of bytes requested except
- * on EOF or error, otherwise the rest of the data will be
- * substituted with zeroes. An exception to this is when the file
- * has been opened in 'direct_io' mode, in which case the return
- * value of the read system call will reflect the return value of
- * this operation.
- *
- * fi->fh will contain the value set by the open method, or will
- * be undefined if the open method didn't set any value.
- *
- * Valid replies:
- * fuse_reply_buf
- * fuse_reply_err
- *
- * @param req request handle
- * @param ino the inode number
- * @param size number of bytes to read
- * @param off offset to read from
- * @param fi file information
- */
- void (*read) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
- struct fuse_file_info *fi);
-
- /**
- * Write data
- *
- * Write should return exactly the number of bytes requested
- * except on error. An exception to this is when the file has
- * been opened in 'direct_io' mode, in which case the return value
- * of the write system call will reflect the return value of this
- * operation.
- *
- * fi->fh will contain the value set by the open method, or will
- * be undefined if the open method didn't set any value.
- *
- * Valid replies:
- * fuse_reply_write
- * fuse_reply_err
- *
- * @param req request handle
- * @param ino the inode number
- * @param buf data to write
- * @param size number of bytes to write
- * @param off offset to write to
- * @param fi file information
- */
- void (*write) (fuse_req_t req, fuse_ino_t ino, const char *buf,
- size_t size, off_t off, struct fuse_file_info *fi);
-
- /**
- * Flush method
- *
- * This is called on each close() of the opened file.
- *
- * Since file descriptors can be duplicated (dup, dup2, fork), for
- * one open call there may be many flush calls.
- *
- * Filesystems shouldn't assume that flush will always be called
- * after some writes, or that if will be called at all.
- *
- * fi->fh will contain the value set by the open method, or will
- * be undefined if the open method didn't set any value.
- *
- * NOTE: the name of the method is misleading, since (unlike
- * fsync) the filesystem is not forced to flush pending writes.
- * One reason to flush data, is if the filesystem wants to return
- * write errors.
- *
- * If the filesystem supports file locking operations (setlk,
- * getlk) it should remove all locks belonging to 'fi->owner'.
- *
- * Valid replies:
- * fuse_reply_err
- *
- * @param req request handle
- * @param ino the inode number
- * @param fi file information
- */
- void (*flush) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
-
- /**
- * Release an open file
- *
- * Release is called when there are no more references to an open
- * file: all file descriptors are closed and all memory mappings
- * are unmapped.
- *
- * For every open call there will be exactly one release call.
- *
- * The filesystem may reply with an error, but error values are
- * not returned to close() or munmap() which triggered the
- * release.
- *
- * fi->fh will contain the value set by the open method, or will
- * be undefined if the open method didn't set any value.
- * fi->flags will contain the same flags as for open.
- *
- * Valid replies:
- * fuse_reply_err
- *
- * @param req request handle
- * @param ino the inode number
- * @param fi file information
- */
- void (*release) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
-
- /**
- * Synchronize file contents
- *
- * If the datasync parameter is non-zero, then only the user data
- * should be flushed, not the meta data.
- *
- * Valid replies:
- * fuse_reply_err
- *
- * @param req request handle
- * @param ino the inode number
- * @param datasync flag indicating if only data should be flushed
- * @param fi file information
- */
- void (*fsync) (fuse_req_t req, fuse_ino_t ino, int datasync,
- struct fuse_file_info *fi);
-
- /**
- * Open a directory
- *
- * Filesystem may store an arbitrary file handle (pointer, index,
- * etc) in fi->fh, and use this in other all other directory
- * stream operations (readdir, releasedir, fsyncdir).
- *
- * Filesystem may also implement stateless directory I/O and not
- * store anything in fi->fh, though that makes it impossible to
- * implement standard conforming directory stream operations in
- * case the contents of the directory can change between opendir
- * and releasedir.
- *
- * Valid replies:
- * fuse_reply_open
- * fuse_reply_err
- *
- * @param req request handle
- * @param ino the inode number
- * @param fi file information
- */
- void (*opendir) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
-
- /**
- * Read directory
- *
- * Send a buffer filled using fuse_add_direntry(), with size not
- * exceeding the requested size. Send an empty buffer on end of
- * stream.
- *
- * fi->fh will contain the value set by the opendir method, or
- * will be undefined if the opendir method didn't set any value.
- *
- * Valid replies:
- * fuse_reply_buf
- * fuse_reply_err
- *
- * @param req request handle
- * @param ino the inode number
- * @param size maximum number of bytes to send
- * @param off offset to continue reading the directory stream
- * @param fi file information
- */
- void (*readdir) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
- struct fuse_file_info *fi);
-
- /**
- * Release an open directory
- *
- * For every opendir call there will be exactly one releasedir
- * call.
- *
- * fi->fh will contain the value set by the opendir method, or
- * will be undefined if the opendir method didn't set any value.
- *
- * Valid replies:
- * fuse_reply_err
- *
- * @param req request handle
- * @param ino the inode number
- * @param fi file information
- */
- void (*releasedir) (fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi);
-
- /**
- * Synchronize directory contents
- *
- * If the datasync parameter is non-zero, then only the directory
- * contents should be flushed, not the meta data.
- *
- * fi->fh will contain the value set by the opendir method, or
- * will be undefined if the opendir method didn't set any value.
- *
- * Valid replies:
- * fuse_reply_err
- *
- * @param req request handle
- * @param ino the inode number
- * @param datasync flag indicating if only data should be flushed
- * @param fi file information
- */
- void (*fsyncdir) (fuse_req_t req, fuse_ino_t ino, int datasync,
- struct fuse_file_info *fi);
-
- /**
- * Get file system statistics
- *
- * Valid replies:
- * fuse_reply_statfs
- * fuse_reply_err
- *
- * @param req request handle
- * @param ino the inode number, zero means "undefined"
- */
- void (*statfs) (fuse_req_t req, fuse_ino_t ino);
-
- /**
- * Set an extended attribute
- *
- * Valid replies:
- * fuse_reply_err
- */
- void (*setxattr) (fuse_req_t req, fuse_ino_t ino, const char *name,
- const char *value, size_t size, int flags);
-
- /**
- * Get an extended attribute
- *
- * If size is zero, the size of the value should be sent with
- * fuse_reply_xattr.
- *
- * If the size is non-zero, and the value fits in the buffer, the
- * value should be sent with fuse_reply_buf.
- *
- * If the size is too small for the value, the ERANGE error should
- * be sent.
- *
- * Valid replies:
- * fuse_reply_buf
- * fuse_reply_xattr
- * fuse_reply_err
- *
- * @param req request handle
- * @param ino the inode number
- * @param name of the extended attribute
- * @param size maximum size of the value to send
- */
- void (*getxattr) (fuse_req_t req, fuse_ino_t ino, const char *name,
- size_t size);
-
- /**
- * List extended attribute names
- *
- * If size is zero, the total size of the attribute list should be
- * sent with fuse_reply_xattr.
- *
- * If the size is non-zero, and the null character separated
- * attribute list fits in the buffer, the list should be sent with
- * fuse_reply_buf.
- *
- * If the size is too small for the list, the ERANGE error should
- * be sent.
- *
- * Valid replies:
- * fuse_reply_buf
- * fuse_reply_xattr
- * fuse_reply_err
- *
- * @param req request handle
- * @param ino the inode number
- * @param size maximum size of the list to send
- */
- void (*listxattr) (fuse_req_t req, fuse_ino_t ino, size_t size);
-
- /**
- * Remove an extended attribute
- *
- * Valid replies:
- * fuse_reply_err
- *
- * @param req request handle
- * @param ino the inode number
- * @param name of the extended attribute
- */
- void (*removexattr) (fuse_req_t req, fuse_ino_t ino, const char *name);
-
- /**
- * Check file access permissions
- *
- * This will be called for the access() system call. If the
- * 'default_permissions' mount option is given, this method is not
- * called.
- *
- * This method is not called under Linux kernel versions 2.4.x
- *
- * Introduced in version 2.5
- *
- * Valid replies:
- * fuse_reply_err
- *
- * @param req request handle
- * @param ino the inode number
- * @param mask requested access mode
- */
- void (*access) (fuse_req_t req, fuse_ino_t ino, int mask);
-
- /**
- * Create and open a file
- *
- * If the file does not exist, first create it with the specified
- * mode, and then open it.
- *
- * Open flags (with the exception of O_NOCTTY) are available in
- * fi->flags.
- *
- * Filesystem may store an arbitrary file handle (pointer, index,
- * etc) in fi->fh, and use this in other all other file operations
- * (read, write, flush, release, fsync).
- *
- * There are also some flags (direct_io, keep_cache) which the
- * filesystem may set in fi, to change the way the file is opened.
- * See fuse_file_info structure in <fuse_common.h> for more details.
- *
- * If this method is not implemented or under Linux kernel
- * versions earlier than 2.6.15, the mknod() and open() methods
- * will be called instead.
- *
- * Introduced in version 2.5
- *
- * Valid replies:
- * fuse_reply_create
- * fuse_reply_err
- *
- * @param req request handle
- * @param parent inode number of the parent directory
- * @param name to create
- * @param mode file type and mode with which to create the new file
- * @param fi file information
- */
- void (*create) (fuse_req_t req, fuse_ino_t parent, const char *name,
- mode_t mode, struct fuse_file_info *fi);
-
- /**
- * Test for a POSIX file lock
- *
- * Introduced in version 2.6
- *
- * Valid replies:
- * fuse_reply_lock
- * fuse_reply_err
- *
- * @param req request handle
- * @param ino the inode number
- * @param fi file information
- * @param lock the region/type to test
- */
- void (*getlk) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi,
- struct flock *lock);
-
- /**
- * Acquire, modify or release a POSIX file lock
- *
- * For POSIX threads (NPTL) there's a 1-1 relation between pid and
- * owner, but otherwise this is not always the case. For checking
- * lock ownership, 'fi->owner' must be used. The l_pid field in
- * 'struct flock' should only be used to fill in this field in
- * getlk().
- *
- * Note: if the locking methods are not implemented, the kernel
- * will still allow file locking to work locally. Hence these are
- * only interesting for network filesystems and similar.
- *
- * Introduced in version 2.6
- *
- * Valid replies:
- * fuse_reply_err
- *
- * @param req request handle
- * @param ino the inode number
- * @param fi file information
- * @param lock the region/type to test
- * @param sleep locking operation may sleep
- */
- void (*setlk) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi,
- struct flock *lock, int sleep);
-
- /**
- * Map block index within file to block index within device
- *
- * Note: This makes sense only for block device backed filesystems
- * mounted with the 'blkdev' option
- *
- * Introduced in version 2.6
- *
- * Valid replies:
- * fuse_reply_bmap
- * fuse_reply_err
- *
- * @param req request handle
- * @param ino the inode number
- * @param blocksize unit of block index
- * @param idx block index within file
- */
- void (*bmap) (fuse_req_t req, fuse_ino_t ino, size_t blocksize,
- uint64_t idx);
+ /**
+ * Initialize filesystem
+ *
+ * Called before any other filesystem method
+ *
+ * There's no reply to this function
+ *
+ * @param userdata the user data passed to fuse_lowlevel_new()
+ */
+ void (*init) (void *userdata, struct fuse_conn_info *conn);
+
+ /**
+ * Clean up filesystem
+ *
+ * Called on filesystem exit
+ *
+ * There's no reply to this function
+ *
+ * @param userdata the user data passed to fuse_lowlevel_new()
+ */
+ void (*destroy) (void *userdata);
+
+ /**
+ * Look up a directory entry by name and get its attributes.
+ *
+ * Valid replies:
+ * fuse_reply_entry
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param parent inode number of the parent directory
+ * @param name the name to look up
+ */
+ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
+
+ /**
+ * Forget about an inode
+ *
+ * The nlookup parameter indicates the number of lookups
+ * previously performed on this inode.
+ *
+ * If the filesystem implements inode lifetimes, it is recommended
+ * that inodes acquire a single reference on each lookup, and lose
+ * nlookup references on each forget.
+ *
+ * The filesystem may ignore forget calls, if the inodes don't
+ * need to have a limited lifetime.
+ *
+ * On unmount it is not guaranteed, that all referenced inodes
+ * will receive a forget message.
+ *
+ * Valid replies:
+ * fuse_reply_none
+ *
+ * @param req request handle
+ * @param ino the inode number
+ * @param nlookup the number of lookups to forget
+ */
+ void (*forget) (fuse_req_t req, fuse_ino_t ino, unsigned long nlookup);
+
+ /**
+ * Get file attributes
+ *
+ * Valid replies:
+ * fuse_reply_attr
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number
+ * @param fi for future use, currently always NULL
+ */
+ void (*getattr) (fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info *fi);
+
+ /**
+ * Set file attributes
+ *
+ * In the 'attr' argument only members indicated by the 'to_set'
+ * bitmask contain valid values. Other members contain undefined
+ * values.
+ *
+ * If the setattr was invoked from the ftruncate() system call
+ * under Linux kernel versions 2.6.15 or later, the fi->fh will
+ * contain the value set by the open method or will be undefined
+ * if the open method didn't set any value. Otherwise (not
+ * ftruncate call, or kernel version earlier than 2.6.15) the fi
+ * parameter will be NULL.
+ *
+ * Valid replies:
+ * fuse_reply_attr
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number
+ * @param attr the attributes
+ * @param to_set bit mask of attributes which should be set
+ * @param fi file information, or NULL
+ *
+ * Changed in version 2.5:
+ * file information filled in for ftruncate
+ */
+ void (*setattr) (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
+ int to_set, struct fuse_file_info *fi);
+
+ /**
+ * Read symbolic link
+ *
+ * Valid replies:
+ * fuse_reply_readlink
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number
+ */
+ void (*readlink) (fuse_req_t req, fuse_ino_t ino);
+
+ /**
+ * Create file node
+ *
+ * Create a regular file, character device, block device, fifo or
+ * socket node.
+ *
+ * Valid replies:
+ * fuse_reply_entry
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param parent inode number of the parent directory
+ * @param name to create
+ * @param mode file type and mode with which to create the new file
+ * @param rdev the device number (only valid if created file is a device)
+ */
+ void (*mknod) (fuse_req_t req, fuse_ino_t parent, const char *name,
+ mode_t mode, dev_t rdev);
+
+ /**
+ * Create a directory
+ *
+ * Valid replies:
+ * fuse_reply_entry
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param parent inode number of the parent directory
+ * @param name to create
+ * @param mode with which to create the new file
+ */
+ void (*mkdir) (fuse_req_t req, fuse_ino_t parent, const char *name,
+ mode_t mode);
+
+ /**
+ * Remove a file
+ *
+ * Valid replies:
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param parent inode number of the parent directory
+ * @param name to remove
+ */
+ void (*unlink) (fuse_req_t req, fuse_ino_t parent, const char *name);
+
+ /**
+ * Remove a directory
+ *
+ * Valid replies:
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param parent inode number of the parent directory
+ * @param name to remove
+ */
+ void (*rmdir) (fuse_req_t req, fuse_ino_t parent, const char *name);
+
+ /**
+ * Create a symbolic link
+ *
+ * Valid replies:
+ * fuse_reply_entry
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param link the contents of the symbolic link
+ * @param parent inode number of the parent directory
+ * @param name to create
+ */
+ void (*symlink) (fuse_req_t req, const char *link, fuse_ino_t parent,
+ const char *name);
+
+ /** Rename a file
+ *
+ * Valid replies:
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param parent inode number of the old parent directory
+ * @param name old name
+ * @param newparent inode number of the new parent directory
+ * @param newname new name
+ */
+ void (*rename) (fuse_req_t req, fuse_ino_t parent, const char *name,
+ fuse_ino_t newparent, const char *newname);
+
+ /**
+ * Create a hard link
+ *
+ * Valid replies:
+ * fuse_reply_entry
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the old inode number
+ * @param newparent inode number of the new parent directory
+ * @param newname new name to create
+ */
+ void (*link) (fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
+ const char *newname);
+
+ /**
+ * Open a file
+ *
+ * Open flags (with the exception of O_CREAT, O_EXCL, O_NOCTTY and
+ * O_TRUNC) are available in fi->flags.
+ *
+ * Filesystem may store an arbitrary file handle (pointer, index,
+ * etc) in fi->fh, and use this in other all other file operations
+ * (read, write, flush, release, fsync).
+ *
+ * Filesystem may also implement stateless file I/O and not store
+ * anything in fi->fh.
+ *
+ * There are also some flags (direct_io, keep_cache) which the
+ * filesystem may set in fi, to change the way the file is opened.
+ * See fuse_file_info structure in <fuse_common.h> for more details.
+ *
+ * Valid replies:
+ * fuse_reply_open
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number
+ * @param fi file information
+ */
+ void (*open) (fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info *fi);
+
+ /**
+ * Read data
+ *
+ * Read should send exactly the number of bytes requested except
+ * on EOF or error, otherwise the rest of the data will be
+ * substituted with zeroes. An exception to this is when the file
+ * has been opened in 'direct_io' mode, in which case the return
+ * value of the read system call will reflect the return value of
+ * this operation.
+ *
+ * fi->fh will contain the value set by the open method, or will
+ * be undefined if the open method didn't set any value.
+ *
+ * Valid replies:
+ * fuse_reply_buf
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number
+ * @param size number of bytes to read
+ * @param off offset to read from
+ * @param fi file information
+ */
+ void (*read) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
+ struct fuse_file_info *fi);
+
+ /**
+ * Write data
+ *
+ * Write should return exactly the number of bytes requested
+ * except on error. An exception to this is when the file has
+ * been opened in 'direct_io' mode, in which case the return value
+ * of the write system call will reflect the return value of this
+ * operation.
+ *
+ * fi->fh will contain the value set by the open method, or will
+ * be undefined if the open method didn't set any value.
+ *
+ * Valid replies:
+ * fuse_reply_write
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number
+ * @param buf data to write
+ * @param size number of bytes to write
+ * @param off offset to write to
+ * @param fi file information
+ */
+ void (*write) (fuse_req_t req, fuse_ino_t ino, const char *buf,
+ size_t size, off_t off, struct fuse_file_info *fi);
+
+ /**
+ * Flush method
+ *
+ * This is called on each close() of the opened file.
+ *
+ * Since file descriptors can be duplicated (dup, dup2, fork), for
+ * one open call there may be many flush calls.
+ *
+ * Filesystems shouldn't assume that flush will always be called
+ * after some writes, or that if will be called at all.
+ *
+ * fi->fh will contain the value set by the open method, or will
+ * be undefined if the open method didn't set any value.
+ *
+ * NOTE: the name of the method is misleading, since (unlike
+ * fsync) the filesystem is not forced to flush pending writes.
+ * One reason to flush data, is if the filesystem wants to return
+ * write errors.
+ *
+ * If the filesystem supports file locking operations (setlk,
+ * getlk) it should remove all locks belonging to 'fi->owner'.
+ *
+ * Valid replies:
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number
+ * @param fi file information
+ */
+ void (*flush) (fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info *fi);
+
+ /**
+ * Release an open file
+ *
+ * Release is called when there are no more references to an open
+ * file: all file descriptors are closed and all memory mappings
+ * are unmapped.
+ *
+ * For every open call there will be exactly one release call.
+ *
+ * The filesystem may reply with an error, but error values are
+ * not returned to close() or munmap() which triggered the
+ * release.
+ *
+ * fi->fh will contain the value set by the open method, or will
+ * be undefined if the open method didn't set any value.
+ * fi->flags will contain the same flags as for open.
+ *
+ * Valid replies:
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number
+ * @param fi file information
+ */
+ void (*release) (fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info *fi);
+
+ /**
+ * Synchronize file contents
+ *
+ * If the datasync parameter is non-zero, then only the user data
+ * should be flushed, not the meta data.
+ *
+ * Valid replies:
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number
+ * @param datasync flag indicating if only data should be flushed
+ * @param fi file information
+ */
+ void (*fsync) (fuse_req_t req, fuse_ino_t ino, int datasync,
+ struct fuse_file_info *fi);
+
+ /**
+ * Open a directory
+ *
+ * Filesystem may store an arbitrary file handle (pointer, index,
+ * etc) in fi->fh, and use this in other all other directory
+ * stream operations (readdir, releasedir, fsyncdir).
+ *
+ * Filesystem may also implement stateless directory I/O and not
+ * store anything in fi->fh, though that makes it impossible to
+ * implement standard conforming directory stream operations in
+ * case the contents of the directory can change between opendir
+ * and releasedir.
+ *
+ * Valid replies:
+ * fuse_reply_open
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number
+ * @param fi file information
+ */
+ void (*opendir) (fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info *fi);
+
+ /**
+ * Read directory
+ *
+ * Send a buffer filled using fuse_add_direntry(), with size not
+ * exceeding the requested size. Send an empty buffer on end of
+ * stream.
+ *
+ * fi->fh will contain the value set by the opendir method, or
+ * will be undefined if the opendir method didn't set any value.
+ *
+ * Valid replies:
+ * fuse_reply_buf
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number
+ * @param size maximum number of bytes to send
+ * @param off offset to continue reading the directory stream
+ * @param fi file information
+ */
+ void (*readdir) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
+ struct fuse_file_info *fi);
+
+ /**
+ * Release an open directory
+ *
+ * For every opendir call there will be exactly one releasedir
+ * call.
+ *
+ * fi->fh will contain the value set by the opendir method, or
+ * will be undefined if the opendir method didn't set any value.
+ *
+ * Valid replies:
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number
+ * @param fi file information
+ */
+ void (*releasedir) (fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info *fi);
+
+ /**
+ * Synchronize directory contents
+ *
+ * If the datasync parameter is non-zero, then only the directory
+ * contents should be flushed, not the meta data.
+ *
+ * fi->fh will contain the value set by the opendir method, or
+ * will be undefined if the opendir method didn't set any value.
+ *
+ * Valid replies:
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number
+ * @param datasync flag indicating if only data should be flushed
+ * @param fi file information
+ */
+ void (*fsyncdir) (fuse_req_t req, fuse_ino_t ino, int datasync,
+ struct fuse_file_info *fi);
+
+ /**
+ * Get file system statistics
+ *
+ * Valid replies:
+ * fuse_reply_statfs
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number, zero means "undefined"
+ */
+ void (*statfs) (fuse_req_t req, fuse_ino_t ino);
+
+ /**
+ * Set an extended attribute
+ *
+ * Valid replies:
+ * fuse_reply_err
+ */
+ void (*setxattr) (fuse_req_t req, fuse_ino_t ino, const char *name,
+ const char *value, size_t size, int flags);
+
+ /**
+ * Get an extended attribute
+ *
+ * If size is zero, the size of the value should be sent with
+ * fuse_reply_xattr.
+ *
+ * If the size is non-zero, and the value fits in the buffer, the
+ * value should be sent with fuse_reply_buf.
+ *
+ * If the size is too small for the value, the ERANGE error should
+ * be sent.
+ *
+ * Valid replies:
+ * fuse_reply_buf
+ * fuse_reply_xattr
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number
+ * @param name of the extended attribute
+ * @param size maximum size of the value to send
+ */
+ void (*getxattr) (fuse_req_t req, fuse_ino_t ino, const char *name,
+ size_t size);
+
+ /**
+ * List extended attribute names
+ *
+ * If size is zero, the total size of the attribute list should be
+ * sent with fuse_reply_xattr.
+ *
+ * If the size is non-zero, and the null character separated
+ * attribute list fits in the buffer, the list should be sent with
+ * fuse_reply_buf.
+ *
+ * If the size is too small for the list, the ERANGE error should
+ * be sent.
+ *
+ * Valid replies:
+ * fuse_reply_buf
+ * fuse_reply_xattr
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number
+ * @param size maximum size of the list to send
+ */
+ void (*listxattr) (fuse_req_t req, fuse_ino_t ino, size_t size);
+
+ /**
+ * Remove an extended attribute
+ *
+ * Valid replies:
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number
+ * @param name of the extended attribute
+ */
+ void (*removexattr) (fuse_req_t req, fuse_ino_t ino, const char *name);
+
+ /**
+ * Check file access permissions
+ *
+ * This will be called for the access() system call. If the
+ * 'default_permissions' mount option is given, this method is not
+ * called.
+ *
+ * This method is not called under Linux kernel versions 2.4.x
+ *
+ * Introduced in version 2.5
+ *
+ * Valid replies:
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number
+ * @param mask requested access mode
+ */
+ void (*access) (fuse_req_t req, fuse_ino_t ino, int mask);
+
+ /**
+ * Create and open a file
+ *
+ * If the file does not exist, first create it with the specified
+ * mode, and then open it.
+ *
+ * Open flags (with the exception of O_NOCTTY) are available in
+ * fi->flags.
+ *
+ * Filesystem may store an arbitrary file handle (pointer, index,
+ * etc) in fi->fh, and use this in other all other file operations
+ * (read, write, flush, release, fsync).
+ *
+ * There are also some flags (direct_io, keep_cache) which the
+ * filesystem may set in fi, to change the way the file is opened.
+ * See fuse_file_info structure in <fuse_common.h> for more details.
+ *
+ * If this method is not implemented or under Linux kernel
+ * versions earlier than 2.6.15, the mknod() and open() methods
+ * will be called instead.
+ *
+ * Introduced in version 2.5
+ *
+ * Valid replies:
+ * fuse_reply_create
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param parent inode number of the parent directory
+ * @param name to create
+ * @param mode file type and mode with which to create the new file
+ * @param fi file information
+ */
+ void (*create) (fuse_req_t req, fuse_ino_t parent, const char *name,
+ mode_t mode, struct fuse_file_info *fi);
+
+ /**
+ * Test for a POSIX file lock
+ *
+ * Introduced in version 2.6
+ *
+ * Valid replies:
+ * fuse_reply_lock
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number
+ * @param fi file information
+ * @param lock the region/type to test
+ */
+ void (*getlk) (fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info *fi, struct flock *lock);
+
+ /**
+ * Acquire, modify or release a POSIX file lock
+ *
+ * For POSIX threads (NPTL) there's a 1-1 relation between pid and
+ * owner, but otherwise this is not always the case. For checking
+ * lock ownership, 'fi->owner' must be used. The l_pid field in
+ * 'struct flock' should only be used to fill in this field in
+ * getlk().
+ *
+ * Note: if the locking methods are not implemented, the kernel
+ * will still allow file locking to work locally. Hence these are
+ * only interesting for network filesystems and similar.
+ *
+ * Introduced in version 2.6
+ *
+ * Valid replies:
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number
+ * @param fi file information
+ * @param lock the region/type to test
+ * @param sleep locking operation may sleep
+ */
+ void (*setlk) (fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info *fi,
+ struct flock *lock, int sleep);
+
+ /**
+ * Map block index within file to block index within device
+ *
+ * Note: This makes sense only for block device backed filesystems
+ * mounted with the 'blkdev' option
+ *
+ * Introduced in version 2.6
+ *
+ * Valid replies:
+ * fuse_reply_bmap
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number
+ * @param blocksize unit of block index
+ * @param idx block index within file
+ */
+ void (*bmap) (fuse_req_t req, fuse_ino_t ino, size_t blocksize,
+ uint64_t idx);
};
/**
@@ -849,7 +861,7 @@ int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e);
* @return zero for success, -errno for failure to send reply
*/
int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e,
- const struct fuse_file_info *fi);
+ const struct fuse_file_info *fi);
/**
* Reply with attributes
@@ -859,11 +871,11 @@ int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e,
*
* @param req request handle
* @param the attributes
- * @param attr_timeout validity timeout (in seconds) for the attributes
+ * @param attr_timeout validity timeout (in seconds) for the attributes
* @return zero for success, -errno for failure to send reply
*/
int fuse_reply_attr(fuse_req_t req, const struct stat *attr,
- double attr_timeout);
+ double attr_timeout);
/**
* Reply with the contents of a symbolic link
@@ -973,13 +985,13 @@ int fuse_reply_lock(fuse_req_t req, struct flock *lock);
* bmap
*
* @param req request handle
- * @param idx block index within device
+ * @param idx block index within device
* @return zero for success, -errno for failure to send reply
*/
int fuse_reply_bmap(fuse_req_t req, uint64_t idx);
/* ----------------------------------------------------------- *
- * Filling a buffer in readdir *
+ * Filling a buffer in readdir *
* ----------------------------------------------------------- */
/**
@@ -1007,11 +1019,11 @@ int fuse_reply_bmap(fuse_req_t req, uint64_t idx);
* @return the space needed for the entry
*/
size_t fuse_add_direntry(fuse_req_t req, char *buf, size_t bufsize,
- const char *name, const struct stat *stbuf,
- off_t off);
+ const char *name, const struct stat *stbuf,
+ off_t off);
/* ----------------------------------------------------------- *
- * Utility functions *
+ * Utility functions *
* ----------------------------------------------------------- */
/**
@@ -1053,7 +1065,7 @@ typedef void (*fuse_interrupt_func_t)(fuse_req_t req, void *data);
* @parm data user data passed to the callback function
*/
void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func,
- void *data);
+ void *data);
/**
* Check if a request has already been interrupted
@@ -1064,7 +1076,7 @@ void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func,
int fuse_req_interrupted(fuse_req_t req);
/* ----------------------------------------------------------- *
- * Filesystem setup *
+ * Filesystem setup *
* ----------------------------------------------------------- */
/* Deprecated, don't use */
@@ -1080,11 +1092,11 @@ int fuse_lowlevel_is_lib_option(const char *opt);
* @return the created session object, or NULL on failure
*/
struct fuse_session *fuse_lowlevel_new(struct fuse_args *args,
- const struct fuse_lowlevel_ops *op,
- size_t op_size, void *userdata);
+ const struct fuse_lowlevel_ops *op,
+ size_t op_size, void *userdata);
/* ----------------------------------------------------------- *
- * Session interface *
+ * Session interface *
* ----------------------------------------------------------- */
/**
@@ -1093,39 +1105,39 @@ struct fuse_session *fuse_lowlevel_new(struct fuse_args *args,
* This is used in session creation
*/
struct fuse_session_ops {
- /**
- * Hook to process a request (mandatory)
- *
- * @param data user data passed to fuse_session_new()
- * @param buf buffer containing the raw request
- * @param len request length
- * @param ch channel on which the request was received
- */
- void (*process) (void *data, const char *buf, size_t len,
- struct fuse_chan *ch);
-
- /**
- * Hook for session exit and reset (optional)
- *
- * @param data user data passed to fuse_session_new()
- * @param val exited status (1 - exited, 0 - not exited)
- */
- void (*exit) (void *data, int val);
-
- /**
- * Hook for querying the current exited status (optional)
- *
- * @param data user data passed to fuse_session_new()
- * @return 1 if exited, 0 if not exited
- */
- int (*exited) (void *data);
-
- /**
- * Hook for cleaning up the channel on destroy (optional)
- *
- * @param data user data passed to fuse_session_new()
- */
- void (*destroy) (void *data);
+ /**
+ * Hook to process a request (mandatory)
+ *
+ * @param data user data passed to fuse_session_new()
+ * @param buf buffer containing the raw request
+ * @param len request length
+ * @param ch channel on which the request was received
+ */
+ void (*process) (void *data, const char *buf, size_t len,
+ struct fuse_chan *ch);
+
+ /**
+ * Hook for session exit and reset (optional)
+ *
+ * @param data user data passed to fuse_session_new()
+ * @param val exited status (1 - exited, 0 - not exited)
+ */
+ void (*exit) (void *data, int val);
+
+ /**
+ * Hook for querying the current exited status (optional)
+ *
+ * @param data user data passed to fuse_session_new()
+ * @return 1 if exited, 0 if not exited
+ */
+ int (*exited) (void *data);
+
+ /**
+ * Hook for cleaning up the channel on destroy (optional)
+ *
+ * @param data user data passed to fuse_session_new()
+ */
+ void (*destroy) (void *data);
};
/**
@@ -1171,7 +1183,7 @@ void fuse_session_remove_chan(struct fuse_chan *ch);
* @return the next channel, or NULL if no more channels exist
*/
struct fuse_chan *fuse_session_next_chan(struct fuse_session *se,
- struct fuse_chan *ch);
+ struct fuse_chan *ch);
/**
* Process a raw request
@@ -1182,7 +1194,7 @@ struct fuse_chan *fuse_session_next_chan(struct fuse_session *se,
* @param ch channel on which the request was received
*/
void fuse_session_process(struct fuse_session *se, const char *buf, size_t len,
- struct fuse_chan *ch);
+ struct fuse_chan *ch);
/**
* Destroy a session
@@ -1230,7 +1242,7 @@ int fuse_session_loop(struct fuse_session *se);
int fuse_session_loop_mt(struct fuse_session *se);
/* ----------------------------------------------------------- *
- * Channel interface *
+ * Channel interface *
* ----------------------------------------------------------- */
/**
@@ -1239,35 +1251,36 @@ int fuse_session_loop_mt(struct fuse_session *se);
* This is used in channel creation
*/
struct fuse_chan_ops {
- /**
- * Hook for receiving a raw request
- *
- * @param ch pointer to the channel
- * @param buf the buffer to store the request in
- * @param size the size of the buffer
- * @return the actual size of the raw request, or -1 on error
- */
- int (*receive)(struct fuse_chan **chp, char *buf, size_t size);
-
- /**
- * Hook for sending a raw reply
- *
- * A return value of -ENOENT means, that the request was
- * interrupted, and the reply was discarded
- *
- * @param ch the channel
- * @param iov vector of blocks
- * @param count the number of blocks in vector
- * @return zero on success, -errno on failure
- */
- int (*send)(struct fuse_chan *ch, const struct iovec iov[], size_t count);
-
- /**
- * Destroy the channel
- *
- * @param ch the channel
- */
- void (*destroy)(struct fuse_chan *ch);
+ /**
+ * Hook for receiving a raw request
+ *
+ * @param ch pointer to the channel
+ * @param buf the buffer to store the request in
+ * @param size the size of the buffer
+ * @return the actual size of the raw request, or -1 on error
+ */
+ int (*receive)(struct fuse_chan **chp, char *buf, size_t size);
+
+ /**
+ * Hook for sending a raw reply
+ *
+ * A return value of -ENOENT means, that the request was
+ * interrupted, and the reply was discarded
+ *
+ * @param ch the channel
+ * @param iov vector of blocks
+ * @param count the number of blocks in vector
+ * @return zero on success, -errno on failure
+ */
+ int (*send)(struct fuse_chan *ch, const struct iovec iov[],
+ size_t count);
+
+ /**
+ * Destroy the channel
+ *
+ * @param ch the channel
+ */
+ void (*destroy)(struct fuse_chan *ch);
};
/**
@@ -1280,7 +1293,7 @@ struct fuse_chan_ops {
* @return the new channel object, or NULL on failure
*/
struct fuse_chan *fuse_chan_new(struct fuse_chan_ops *op, int fd,
- size_t bufsize, void *data);
+ size_t bufsize, void *data);
/**
* Query the file descriptor of the channel
@@ -1338,7 +1351,7 @@ int fuse_chan_recv(struct fuse_chan **ch, char *buf, size_t size);
* @return zero on success, -errno on failure
*/
int fuse_chan_send(struct fuse_chan *ch, const struct iovec iov[],
- size_t count);
+ size_t count);
/**
* Destroy a channel
@@ -1348,7 +1361,7 @@ int fuse_chan_send(struct fuse_chan *ch, const struct iovec iov[],
void fuse_chan_destroy(struct fuse_chan *ch);
/* ----------------------------------------------------------- *
- * Compatibility stuff *
+ * Compatibility stuff *
* ----------------------------------------------------------- */
#if FUSE_USE_VERSION < 26
diff --git a/include/fuse_lowlevel_compat.h b/include/fuse_lowlevel_compat.h
index d9313b8..aba45e6 100644
--- a/include/fuse_lowlevel_compat.h
+++ b/include/fuse_lowlevel_compat.h
@@ -1,144 +1,155 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB.
*/
/* these definitions provide source compatibility to prior versions.
Do not include this file directly! */
struct fuse_lowlevel_ops_compat25 {
- void (*init) (void *userdata);
- void (*destroy) (void *userdata);
- void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
- void (*forget) (fuse_req_t req, fuse_ino_t ino, unsigned long nlookup);
- void (*getattr) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
- void (*setattr) (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
- int to_set, struct fuse_file_info *fi);
- void (*readlink) (fuse_req_t req, fuse_ino_t ino);
- void (*mknod) (fuse_req_t req, fuse_ino_t parent, const char *name,
- mode_t mode, dev_t rdev);
- void (*mkdir) (fuse_req_t req, fuse_ino_t parent, const char *name,
- mode_t mode);
- void (*unlink) (fuse_req_t req, fuse_ino_t parent, const char *name);
- void (*rmdir) (fuse_req_t req, fuse_ino_t parent, const char *name);
- void (*symlink) (fuse_req_t req, const char *link, fuse_ino_t parent,
- const char *name);
- void (*rename) (fuse_req_t req, fuse_ino_t parent, const char *name,
- fuse_ino_t newparent, const char *newname);
- void (*link) (fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
- const char *newname);
- void (*open) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
- void (*read) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
- struct fuse_file_info *fi);
- void (*write) (fuse_req_t req, fuse_ino_t ino, const char *buf,
- size_t size, off_t off, struct fuse_file_info *fi);
- void (*flush) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
- void (*release) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
- void (*fsync) (fuse_req_t req, fuse_ino_t ino, int datasync,
- struct fuse_file_info *fi);
- void (*opendir) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
- void (*readdir) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
- struct fuse_file_info *fi);
- void (*releasedir) (fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi);
- void (*fsyncdir) (fuse_req_t req, fuse_ino_t ino, int datasync,
- struct fuse_file_info *fi);
- void (*statfs) (fuse_req_t req);
- void (*setxattr) (fuse_req_t req, fuse_ino_t ino, const char *name,
- const char *value, size_t size, int flags);
- void (*getxattr) (fuse_req_t req, fuse_ino_t ino, const char *name,
- size_t size);
- void (*listxattr) (fuse_req_t req, fuse_ino_t ino, size_t size);
- void (*removexattr) (fuse_req_t req, fuse_ino_t ino, const char *name);
- void (*access) (fuse_req_t req, fuse_ino_t ino, int mask);
- void (*create) (fuse_req_t req, fuse_ino_t parent, const char *name,
- mode_t mode, struct fuse_file_info *fi);
+ void (*init) (void *userdata);
+ void (*destroy) (void *userdata);
+ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
+ void (*forget) (fuse_req_t req, fuse_ino_t ino, unsigned long nlookup);
+ void (*getattr) (fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info *fi);
+ void (*setattr) (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
+ int to_set, struct fuse_file_info *fi);
+ void (*readlink) (fuse_req_t req, fuse_ino_t ino);
+ void (*mknod) (fuse_req_t req, fuse_ino_t parent, const char *name,
+ mode_t mode, dev_t rdev);
+ void (*mkdir) (fuse_req_t req, fuse_ino_t parent, const char *name,
+ mode_t mode);
+ void (*unlink) (fuse_req_t req, fuse_ino_t parent, const char *name);
+ void (*rmdir) (fuse_req_t req, fuse_ino_t parent, const char *name);
+ void (*symlink) (fuse_req_t req, const char *link, fuse_ino_t parent,
+ const char *name);
+ void (*rename) (fuse_req_t req, fuse_ino_t parent, const char *name,
+ fuse_ino_t newparent, const char *newname);
+ void (*link) (fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
+ const char *newname);
+ void (*open) (fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info *fi);
+ void (*read) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
+ struct fuse_file_info *fi);
+ void (*write) (fuse_req_t req, fuse_ino_t ino, const char *buf,
+ size_t size, off_t off, struct fuse_file_info *fi);
+ void (*flush) (fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info *fi);
+ void (*release) (fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info *fi);
+ void (*fsync) (fuse_req_t req, fuse_ino_t ino, int datasync,
+ struct fuse_file_info *fi);
+ void (*opendir) (fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info *fi);
+ void (*readdir) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
+ struct fuse_file_info *fi);
+ void (*releasedir) (fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info *fi);
+ void (*fsyncdir) (fuse_req_t req, fuse_ino_t ino, int datasync,
+ struct fuse_file_info *fi);
+ void (*statfs) (fuse_req_t req);
+ void (*setxattr) (fuse_req_t req, fuse_ino_t ino, const char *name,
+ const char *value, size_t size, int flags);
+ void (*getxattr) (fuse_req_t req, fuse_ino_t ino, const char *name,
+ size_t size);
+ void (*listxattr) (fuse_req_t req, fuse_ino_t ino, size_t size);
+ void (*removexattr) (fuse_req_t req, fuse_ino_t ino, const char *name);
+ void (*access) (fuse_req_t req, fuse_ino_t ino, int mask);
+ void (*create) (fuse_req_t req, fuse_ino_t parent, const char *name,
+ mode_t mode, struct fuse_file_info *fi);
};
struct fuse_session *fuse_lowlevel_new_compat25(struct fuse_args *args,
- const struct fuse_lowlevel_ops_compat25 *op,
- size_t op_size, void *userdata);
+ const struct fuse_lowlevel_ops_compat25 *op,
+ size_t op_size, void *userdata);
size_t fuse_dirent_size(size_t namelen);
char *fuse_add_dirent(char *buf, const char *name, const struct stat *stbuf,
- off_t off);
+ off_t off);
#ifndef __FreeBSD__
#include <sys/statfs.h>
struct fuse_lowlevel_ops_compat {
- void (*init) (void *userdata);
- void (*destroy) (void *userdata);
- void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
- void (*forget) (fuse_req_t req, fuse_ino_t ino, unsigned long nlookup);
- void (*getattr) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info_compat *fi);
- void (*setattr) (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
- int to_set, struct fuse_file_info_compat *fi);
- void (*readlink) (fuse_req_t req, fuse_ino_t ino);
- void (*mknod) (fuse_req_t req, fuse_ino_t parent, const char *name,
- mode_t mode, dev_t rdev);
- void (*mkdir) (fuse_req_t req, fuse_ino_t parent, const char *name,
- mode_t mode);
- void (*unlink) (fuse_req_t req, fuse_ino_t parent, const char *name);
- void (*rmdir) (fuse_req_t req, fuse_ino_t parent, const char *name);
- void (*symlink) (fuse_req_t req, const char *link, fuse_ino_t parent,
- const char *name);
- void (*rename) (fuse_req_t req, fuse_ino_t parent, const char *name,
- fuse_ino_t newparent, const char *newname);
- void (*link) (fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
- const char *newname);
- void (*open) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info_compat *fi);
- void (*read) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
- struct fuse_file_info_compat *fi);
- void (*write) (fuse_req_t req, fuse_ino_t ino, const char *buf,
- size_t size, off_t off, struct fuse_file_info_compat *fi);
- void (*flush) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info_compat *fi);
- void (*release) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info_compat *fi);
- void (*fsync) (fuse_req_t req, fuse_ino_t ino, int datasync,
- struct fuse_file_info_compat *fi);
- void (*opendir) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info_compat *fi);
- void (*readdir) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
- struct fuse_file_info_compat *fi);
- void (*releasedir) (fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info_compat *fi);
- void (*fsyncdir) (fuse_req_t req, fuse_ino_t ino, int datasync,
- struct fuse_file_info_compat *fi);
- void (*statfs) (fuse_req_t req);
- void (*setxattr) (fuse_req_t req, fuse_ino_t ino, const char *name,
- const char *value, size_t size, int flags);
- void (*getxattr) (fuse_req_t req, fuse_ino_t ino, const char *name,
- size_t size);
- void (*listxattr) (fuse_req_t req, fuse_ino_t ino, size_t size);
- void (*removexattr) (fuse_req_t req, fuse_ino_t ino, const char *name);
- void (*access) (fuse_req_t req, fuse_ino_t ino, int mask);
- void (*create) (fuse_req_t req, fuse_ino_t parent, const char *name,
- mode_t mode, struct fuse_file_info_compat *fi);
+ void (*init) (void *userdata);
+ void (*destroy) (void *userdata);
+ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
+ void (*forget) (fuse_req_t req, fuse_ino_t ino, unsigned long nlookup);
+ void (*getattr) (fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info_compat *fi);
+ void (*setattr) (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
+ int to_set, struct fuse_file_info_compat *fi);
+ void (*readlink) (fuse_req_t req, fuse_ino_t ino);
+ void (*mknod) (fuse_req_t req, fuse_ino_t parent, const char *name,
+ mode_t mode, dev_t rdev);
+ void (*mkdir) (fuse_req_t req, fuse_ino_t parent, const char *name,
+ mode_t mode);
+ void (*unlink) (fuse_req_t req, fuse_ino_t parent, const char *name);
+ void (*rmdir) (fuse_req_t req, fuse_ino_t parent, const char *name);
+ void (*symlink) (fuse_req_t req, const char *link, fuse_ino_t parent,
+ const char *name);
+ void (*rename) (fuse_req_t req, fuse_ino_t parent, const char *name,
+ fuse_ino_t newparent, const char *newname);
+ void (*link) (fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
+ const char *newname);
+ void (*open) (fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info_compat *fi);
+ void (*read) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
+ struct fuse_file_info_compat *fi);
+ void (*write) (fuse_req_t req, fuse_ino_t ino, const char *buf,
+ size_t size, off_t off, struct fuse_file_info_compat *fi);
+ void (*flush) (fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info_compat *fi);
+ void (*release) (fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info_compat *fi);
+ void (*fsync) (fuse_req_t req, fuse_ino_t ino, int datasync,
+ struct fuse_file_info_compat *fi);
+ void (*opendir) (fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info_compat *fi);
+ void (*readdir) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
+ struct fuse_file_info_compat *fi);
+ void (*releasedir) (fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info_compat *fi);
+ void (*fsyncdir) (fuse_req_t req, fuse_ino_t ino, int datasync,
+ struct fuse_file_info_compat *fi);
+ void (*statfs) (fuse_req_t req);
+ void (*setxattr) (fuse_req_t req, fuse_ino_t ino, const char *name,
+ const char *value, size_t size, int flags);
+ void (*getxattr) (fuse_req_t req, fuse_ino_t ino, const char *name,
+ size_t size);
+ void (*listxattr) (fuse_req_t req, fuse_ino_t ino, size_t size);
+ void (*removexattr) (fuse_req_t req, fuse_ino_t ino, const char *name);
+ void (*access) (fuse_req_t req, fuse_ino_t ino, int mask);
+ void (*create) (fuse_req_t req, fuse_ino_t parent, const char *name,
+ mode_t mode, struct fuse_file_info_compat *fi);
};
int fuse_reply_statfs_compat(fuse_req_t req, const struct statfs *stbuf);
int fuse_reply_open_compat(fuse_req_t req,
- const struct fuse_file_info_compat *fi);
+ const struct fuse_file_info_compat *fi);
struct fuse_session *fuse_lowlevel_new_compat(const char *opts,
- const struct fuse_lowlevel_ops_compat *op,
- size_t op_size, void *userdata);
+ const struct fuse_lowlevel_ops_compat *op,
+ size_t op_size, void *userdata);
#endif /* __FreeBSD__ */
struct fuse_chan_ops_compat24 {
- int (*receive)(struct fuse_chan *ch, char *buf, size_t size);
- int (*send)(struct fuse_chan *ch, const struct iovec iov[], size_t count);
- void (*destroy)(struct fuse_chan *ch);
+ int (*receive)(struct fuse_chan *ch, char *buf, size_t size);
+ int (*send)(struct fuse_chan *ch, const struct iovec iov[],
+ size_t count);
+ void (*destroy)(struct fuse_chan *ch);
};
struct fuse_chan *fuse_chan_new_compat24(struct fuse_chan_ops_compat24 *op,
- int fd, size_t bufsize, void *data);
+ int fd, size_t bufsize, void *data);
int fuse_chan_receive(struct fuse_chan *ch, char *buf, size_t size);
struct fuse_chan *fuse_kern_chan_new(int fd);
diff --git a/include/fuse_opt.h b/include/fuse_opt.h
index 6123d0b..7ae08af 100644
--- a/include/fuse_opt.h
+++ b/include/fuse_opt.h
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB.
*/
#ifndef _FUSE_OPT_H_
@@ -41,7 +41,7 @@ extern "C" {
*
* - 'offsetof(struct foo, member)' actions i) and iii)
*
- * - -1 action ii)
+ * - -1 action ii)
*
* The 'offsetof()' macro is defined in the <stddef.h> header.
*
@@ -52,7 +52,7 @@ extern "C" {
*
* The types of templates are:
*
- * 1) "-x", "-foo", "--foo", "--foo-bar", etc. These match only
+ * 1) "-x", "-foo", "--foo", "--foo-bar", etc. These match only
* themselves. Invalid values are "--" and anything beginning
* with "-o"
*
@@ -74,30 +74,30 @@ extern "C" {
* with scanf().
*/
struct fuse_opt {
- /** Matching template and optional parameter formatting */
- const char *templ;
+ /** Matching template and optional parameter formatting */
+ const char *templ;
- /**
- * Offset of variable within 'data' parameter of fuse_opt_parse()
- * or -1
- */
- unsigned long offset;
+ /**
+ * Offset of variable within 'data' parameter of fuse_opt_parse()
+ * or -1
+ */
+ unsigned long offset;
- /**
- * Value to set the variable to, or to be passed as 'key' to the
- * processing function. Ignored if template has a format
- */
- int value;
+ /**
+ * Value to set the variable to, or to be passed as 'key' to the
+ * processing function. Ignored if template has a format
+ */
+ int value;
};
/**
- * Key option. In case of a match, the processing function will be
+ * Key option. In case of a match, the processing function will be
* called with the specified key.
*/
#define FUSE_OPT_KEY(templ, key) { templ, -1U, key }
/**
- * Last option. An array of 'struct fuse_opt' must end with a NULL
+ * Last option. An array of 'struct fuse_opt' must end with a NULL
* template value
*/
#define FUSE_OPT_END { .templ = NULL }
@@ -106,14 +106,14 @@ struct fuse_opt {
* Argument list
*/
struct fuse_args {
- /** Argument count */
- int argc;
+ /** Argument count */
+ int argc;
- /** Argument vector. NULL terminated */
- char **argv;
+ /** Argument vector. NULL terminated */
+ char **argv;
- /** Is 'argv' allocated? */
- int allocated;
+ /** Is 'argv' allocated? */
+ int allocated;
};
/**
@@ -177,7 +177,7 @@ struct fuse_args {
* @return -1 on error, 0 if arg is to be discarded, 1 if arg should be kept
*/
typedef int (*fuse_opt_proc_t)(void *data, const char *arg, int key,
- struct fuse_args *outargs);
+ struct fuse_args *outargs);
/**
* Option parsing function
@@ -200,7 +200,7 @@ typedef int (*fuse_opt_proc_t)(void *data, const char *arg, int key,
* @return -1 on error, 0 on success
*/
int fuse_opt_parse(struct fuse_args *args, void *data,
- const struct fuse_opt opts[], fuse_opt_proc_t proc);
+ const struct fuse_opt opts[], fuse_opt_proc_t proc);
/**
* Add an option to a comma separated option list
diff --git a/include/ulockmgr.h b/include/ulockmgr.h
index 61bc36b..ad55579 100644
--- a/include/ulockmgr.h
+++ b/include/ulockmgr.h
@@ -1,9 +1,9 @@
/*
- libulockmgr: Userspace Lock Manager Library
- Copyright (C) 2006 Miklos Szeredi <miklos@szeredi.hu>
+ libulockmgr: Userspace Lock Manager Library
+ Copyright (C) 2006 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB.
*/
#include <stdint.h>
@@ -21,4 +21,4 @@
* @return 0 on success -errno on error
*/
int ulockmgr_op(int fd, int cmd, struct flock *lock, const void *owner,
- size_t owner_len);
+ size_t owner_len);
diff --git a/lib/fuse.c b/lib/fuse.c
index d22e200..7bcbe76 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
@@ -40,109 +40,109 @@
#define OFFSET_MAX 0x7fffffffffffffffLL
struct fuse_config {
- unsigned int uid;
- unsigned int gid;
- unsigned int umask;
- double entry_timeout;
- double negative_timeout;
- double attr_timeout;
- double ac_attr_timeout;
- int ac_attr_timeout_set;
- int debug;
- int hard_remove;
- int use_ino;
- int readdir_ino;
- int set_mode;
- int set_uid;
- int set_gid;
- int direct_io;
- int kernel_cache;
- int auto_cache;
- int intr;
- int intr_signal;
- int help;
- char *modules;
+ unsigned int uid;
+ unsigned int gid;
+ unsigned int umask;
+ double entry_timeout;
+ double negative_timeout;
+ double attr_timeout;
+ double ac_attr_timeout;
+ int ac_attr_timeout_set;
+ int debug;
+ int hard_remove;
+ int use_ino;
+ int readdir_ino;
+ int set_mode;
+ int set_uid;
+ int set_gid;
+ int direct_io;
+ int kernel_cache;
+ int auto_cache;
+ int intr;
+ int intr_signal;
+ int help;
+ char *modules;
};
struct fuse_fs {
- struct fuse_operations op;
- struct fuse_module *m;
- void *user_data;
- int compat;
+ struct fuse_operations op;
+ struct fuse_module *m;
+ void *user_data;
+ int compat;
};
struct fusemod_so {
- void *handle;
- int ctr;
+ void *handle;
+ int ctr;
};
struct fuse {
- struct fuse_session *se;
- struct node **name_table;
- size_t name_table_size;
- struct node **id_table;
- size_t id_table_size;
- fuse_ino_t ctr;
- unsigned int generation;
- unsigned int hidectr;
- pthread_mutex_t lock;
- pthread_rwlock_t tree_lock;
- struct fuse_config conf;
- int intr_installed;
- struct fuse_fs *fs;
+ struct fuse_session *se;
+ struct node **name_table;
+ size_t name_table_size;
+ struct node **id_table;
+ size_t id_table_size;
+ fuse_ino_t ctr;
+ unsigned int generation;
+ unsigned int hidectr;
+ pthread_mutex_t lock;
+ pthread_rwlock_t tree_lock;
+ struct fuse_config conf;
+ int intr_installed;
+ struct fuse_fs *fs;
};
struct lock {
- int type;
- off_t start;
- off_t end;
- pid_t pid;
- uint64_t owner;
- struct lock *next;
+ int type;
+ off_t start;
+ off_t end;
+ pid_t pid;
+ uint64_t owner;
+ struct lock *next;
};
struct node {
- struct node *name_next;
- struct node *id_next;
- fuse_ino_t nodeid;
- unsigned int generation;
- int refctr;
- struct node *parent;
- char *name;
- uint64_t nlookup;
- int open_count;
- int is_hidden;
- struct timespec stat_updated;
- struct timespec mtime;
- off_t size;
- int cache_valid;
- struct lock *locks;
+ struct node *name_next;
+ struct node *id_next;
+ fuse_ino_t nodeid;
+ unsigned int generation;
+ int refctr;
+ struct node *parent;
+ char *name;
+ uint64_t nlookup;
+ int open_count;
+ int is_hidden;
+ struct timespec stat_updated;
+ struct timespec mtime;
+ off_t size;
+ int cache_valid;
+ struct lock *locks;
};
struct fuse_dh {
- pthread_mutex_t lock;
- struct fuse *fuse;
- fuse_req_t req;
- char *contents;
- int allocated;
- unsigned len;
- unsigned size;
- unsigned needlen;
- int filled;
- uint64_t fh;
- int error;
- fuse_ino_t nodeid;
+ pthread_mutex_t lock;
+ struct fuse *fuse;
+ fuse_req_t req;
+ char *contents;
+ int allocated;
+ unsigned len;
+ unsigned size;
+ unsigned needlen;
+ int filled;
+ uint64_t fh;
+ int error;
+ fuse_ino_t nodeid;
};
/* old dir handle */
struct fuse_dirhandle {
- fuse_fill_dir_t filler;
- void *buf;
+ fuse_fill_dir_t filler;
+ void *buf;
};
struct fuse_context_i {
- struct fuse_context ctx;
- fuse_req_t req;
+ struct fuse_context ctx;
+ fuse_req_t req;
};
static pthread_key_t fuse_context_key;
@@ -153,1017 +153,1025 @@ static struct fuse_module *fuse_modules;
static int fuse_load_so_name(const char *soname)
{
- struct fusemod_so *so;
-
- so = calloc(1, sizeof(struct fusemod_so));
- if (!so) {
- fprintf(stderr, "fuse: memory allocation failed\n");
- return -1;
- }
-
- fuse_current_so = so;
- so->handle = dlopen(soname, RTLD_NOW);
- fuse_current_so = NULL;
- if (!so->handle) {
- fprintf(stderr, "fuse: %s\n", dlerror());
- goto err;
- }
- if (!so->ctr) {
- fprintf(stderr, "fuse: %s did not register any modules", soname);
- goto err;
- }
- return 0;
-
- err:
- if (so->handle)
- dlclose(so->handle);
- free(so);
- return -1;
+ struct fusemod_so *so;
+
+ so = calloc(1, sizeof(struct fusemod_so));
+ if (!so) {
+ fprintf(stderr, "fuse: memory allocation failed\n");
+ return -1;
+ }
+
+ fuse_current_so = so;
+ so->handle = dlopen(soname, RTLD_NOW);
+ fuse_current_so = NULL;
+ if (!so->handle) {
+ fprintf(stderr, "fuse: %s\n", dlerror());
+ goto err;
+ }
+ if (!so->ctr) {
+ fprintf(stderr, "fuse: %s did not register any modules",
+ soname);
+ goto err;
+ }
+ return 0;
+
+err:
+ if (so->handle)
+ dlclose(so->handle);
+ free(so);
+ return -1;
}
static int fuse_load_so_module(const char *module)
{
- int res;
- char *soname = malloc(strlen(module) + 64);
- if (!soname) {
- fprintf(stderr, "fuse: memory allocation failed\n");
- return -1;
- }
- sprintf(soname, "libfusemod_%s.so", module);
- res = fuse_load_so_name(soname);
- free(soname);
- return res;
+ int res;
+ char *soname = malloc(strlen(module) + 64);
+ if (!soname) {
+ fprintf(stderr, "fuse: memory allocation failed\n");
+ return -1;
+ }
+ sprintf(soname, "libfusemod_%s.so", module);
+ res = fuse_load_so_name(soname);
+ free(soname);
+ return res;
}
static struct fuse_module *fuse_find_module(const char *module)
{
- struct fuse_module *m;
- for (m = fuse_modules; m; m = m->next) {
- if (strcmp(module, m->name) == 0) {
- m->ctr++;
- break;
- }
- }
- return m;
+ struct fuse_module *m;
+ for (m = fuse_modules; m; m = m->next) {
+ if (strcmp(module, m->name) == 0) {
+ m->ctr++;
+ break;
+ }
+ }
+ return m;
}
static struct fuse_module *fuse_get_module(const char *module)
{
- struct fuse_module *m;
+ struct fuse_module *m;
- pthread_mutex_lock(&fuse_context_lock);
- m = fuse_find_module(module);
- if (!m) {
- int err = fuse_load_so_module(module);
- if (!err)
- m = fuse_find_module(module);
- }
- pthread_mutex_unlock(&fuse_context_lock);
- return m;
+ pthread_mutex_lock(&fuse_context_lock);
+ m = fuse_find_module(module);
+ if (!m) {
+ int err = fuse_load_so_module(module);
+ if (!err)
+ m = fuse_find_module(module);
+ }
+ pthread_mutex_unlock(&fuse_context_lock);
+ return m;
}
static void fuse_put_module(struct fuse_module *m)
{
- pthread_mutex_lock(&fuse_context_lock);
- assert(m->ctr > 0);
- m->ctr--;
- if (!m->ctr && m->so) {
- struct fusemod_so *so = m->so;
- assert(so->ctr > 0);
- so->ctr--;
- if (!so->ctr) {
- struct fuse_module **mp;
- for (mp = &fuse_modules; *mp;) {
- if ((*mp)->so == so)
- *mp = (*mp)->next;
- else
- mp = &(*mp)->next;
- }
- dlclose(so->handle);
- free(so);
- }
- }
- pthread_mutex_unlock(&fuse_context_lock);
+ pthread_mutex_lock(&fuse_context_lock);
+ assert(m->ctr > 0);
+ m->ctr--;
+ if (!m->ctr && m->so) {
+ struct fusemod_so *so = m->so;
+ assert(so->ctr > 0);
+ so->ctr--;
+ if (!so->ctr) {
+ struct fuse_module **mp;
+ for (mp = &fuse_modules; *mp;) {
+ if ((*mp)->so == so)
+ *mp = (*mp)->next;
+ else
+ mp = &(*mp)->next;
+ }
+ dlclose(so->handle);
+ free(so);
+ }
+ }
+ pthread_mutex_unlock(&fuse_context_lock);
}
static struct node *get_node_nocheck(struct fuse *f, fuse_ino_t nodeid)
{
- size_t hash = nodeid % f->id_table_size;
- struct node *node;
+ size_t hash = nodeid % f->id_table_size;
+ struct node *node;
- for (node = f->id_table[hash]; node != NULL; node = node->id_next)
- if (node->nodeid == nodeid)
- return node;
+ for (node = f->id_table[hash]; node != NULL; node = node->id_next)
+ if (node->nodeid == nodeid)
+ return node;
- return NULL;
+ return NULL;
}
static struct node *get_node(struct fuse *f, fuse_ino_t nodeid)
{
- struct node *node = get_node_nocheck(f, nodeid);
- if (!node) {
- fprintf(stderr, "fuse internal error: node %llu not found\n",
- (unsigned long long) nodeid);
- abort();
- }
- return node;
+ struct node *node = get_node_nocheck(f, nodeid);
+ if (!node) {
+ fprintf(stderr, "fuse internal error: node %llu not found\n",
+ (unsigned long long) nodeid);
+ abort();
+ }
+ return node;
}
static void free_node(struct node *node)
{
- free(node->name);
- free(node);
+ free(node->name);
+ free(node);
}
static void unhash_id(struct fuse *f, struct node *node)
{
- size_t hash = node->nodeid % f->id_table_size;
- struct node **nodep = &f->id_table[hash];
+ size_t hash = node->nodeid % f->id_table_size;
+ struct node **nodep = &f->id_table[hash];
- for (; *nodep != NULL; nodep = &(*nodep)->id_next)
- if (*nodep == node) {
- *nodep = node->id_next;
- return;
- }
+ for (; *nodep != NULL; nodep = &(*nodep)->id_next)
+ if (*nodep == node) {
+ *nodep = node->id_next;
+ return;
+ }
}
static void hash_id(struct fuse *f, struct node *node)
{
- size_t hash = node->nodeid % f->id_table_size;
- node->id_next = f->id_table[hash];
- f->id_table[hash] = node;
+ size_t hash = node->nodeid % f->id_table_size;
+ node->id_next = f->id_table[hash];
+ f->id_table[hash] = node;
}
static unsigned int name_hash(struct fuse *f, fuse_ino_t parent,
- const char *name)
+ const char *name)
{
- unsigned int hash = *name;
+ unsigned int hash = *name;
- if (hash)
- for (name += 1; *name != '\0'; name++)
- hash = (hash << 5) - hash + *name;
+ if (hash)
+ for (name += 1; *name != '\0'; name++)
+ hash = (hash << 5) - hash + *name;
- return (hash + parent) % f->name_table_size;
+ return (hash + parent) % f->name_table_size;
}
static void unref_node(struct fuse *f, struct node *node);
static void unhash_name(struct fuse *f, struct node *node)
{
- if (node->name) {
- size_t hash = name_hash(f, node->parent->nodeid, node->name);
- struct node **nodep = &f->name_table[hash];
-
- for (; *nodep != NULL; nodep = &(*nodep)->name_next)
- if (*nodep == node) {
- *nodep = node->name_next;
- node->name_next = NULL;
- unref_node(f, node->parent);
- free(node->name);
- node->name = NULL;
- node->parent = NULL;
- return;
- }
- fprintf(stderr, "fuse internal error: unable to unhash node: %llu\n",
- (unsigned long long) node->nodeid);
- abort();
- }
+ if (node->name) {
+ size_t hash = name_hash(f, node->parent->nodeid, node->name);
+ struct node **nodep = &f->name_table[hash];
+
+ for (; *nodep != NULL; nodep = &(*nodep)->name_next)
+ if (*nodep == node) {
+ *nodep = node->name_next;
+ node->name_next = NULL;
+ unref_node(f, node->parent);
+ free(node->name);
+ node->name = NULL;
+ node->parent = NULL;
+ return;
+ }
+ fprintf(stderr,
+ "fuse internal error: unable to unhash node: %llu\n",
+ (unsigned long long) node->nodeid);
+ abort();
+ }
}
static int hash_name(struct fuse *f, struct node *node, fuse_ino_t parentid,
- const char *name)
+ const char *name)
{
- size_t hash = name_hash(f, parentid, name);
- struct node *parent = get_node(f, parentid);
- node->name = strdup(name);
- if (node->name == NULL)
- return -1;
+ size_t hash = name_hash(f, parentid, name);
+ struct node *parent = get_node(f, parentid);
+ node->name = strdup(name);
+ if (node->name == NULL)
+ return -1;
- parent->refctr ++;
- node->parent = parent;
- node->name_next = f->name_table[hash];
- f->name_table[hash] = node;
- return 0;
+ parent->refctr ++;
+ node->parent = parent;
+ node->name_next = f->name_table[hash];
+ f->name_table[hash] = node;
+ return 0;
}
static void delete_node(struct fuse *f, struct node *node)
{
- if (f->conf.debug)
- fprintf(stderr, "delete: %llu\n", (unsigned long long) node->nodeid);
+ if (f->conf.debug)
+ fprintf(stderr, "delete: %llu\n",
+ (unsigned long long) node->nodeid);
- assert(!node->name);
- unhash_id(f, node);
- free_node(node);
+ assert(!node->name);
+ unhash_id(f, node);
+ free_node(node);
}
static void unref_node(struct fuse *f, struct node *node)
{
- assert(node->refctr > 0);
- node->refctr --;
- if (!node->refctr)
- delete_node(f, node);
+ assert(node->refctr > 0);
+ node->refctr --;
+ if (!node->refctr)
+ delete_node(f, node);
}
static fuse_ino_t next_id(struct fuse *f)
{
- do {
- f->ctr = (f->ctr + 1) & 0xffffffff;
- if (!f->ctr)
- f->generation ++;
- } while (f->ctr == 0 || f->ctr == FUSE_UNKNOWN_INO ||
- get_node_nocheck(f, f->ctr) != NULL);
- return f->ctr;
+ do {
+ f->ctr = (f->ctr + 1) & 0xffffffff;
+ if (!f->ctr)
+ f->generation ++;
+ } while (f->ctr == 0 || f->ctr == FUSE_UNKNOWN_INO ||
+ get_node_nocheck(f, f->ctr) != NULL);
+ return f->ctr;
}
static struct node *lookup_node(struct fuse *f, fuse_ino_t parent,
- const char *name)
+ const char *name)
{
- size_t hash = name_hash(f, parent, name);
- struct node *node;
+ size_t hash = name_hash(f, parent, name);
+ struct node *node;
- for (node = f->name_table[hash]; node != NULL; node = node->name_next)
- if (node->parent->nodeid == parent && strcmp(node->name, name) == 0)
- return node;
+ for (node = f->name_table[hash]; node != NULL; node = node->name_next)
+ if (node->parent->nodeid == parent &&
+ strcmp(node->name, name) == 0)
+ return node;
- return NULL;
+ return NULL;
}
static struct node *find_node(struct fuse *f, fuse_ino_t parent,
- const char *name)
-{
- struct node *node;
-
- pthread_mutex_lock(&f->lock);
- node = lookup_node(f, parent, name);
- if (node == NULL) {
- node = (struct node *) calloc(1, sizeof(struct node));
- if (node == NULL)
- goto out_err;
-
- node->refctr = 1;
- node->nodeid = next_id(f);
- node->open_count = 0;
- node->is_hidden = 0;
- node->generation = f->generation;
- if (hash_name(f, node, parent, name) == -1) {
- free(node);
- node = NULL;
- goto out_err;
- }
- hash_id(f, node);
- }
- node->nlookup ++;
- out_err:
- pthread_mutex_unlock(&f->lock);
- return node;
+ const char *name)
+{
+ struct node *node;
+
+ pthread_mutex_lock(&f->lock);
+ node = lookup_node(f, parent, name);
+ if (node == NULL) {
+ node = (struct node *) calloc(1, sizeof(struct node));
+ if (node == NULL)
+ goto out_err;
+
+ node->refctr = 1;
+ node->nodeid = next_id(f);
+ node->open_count = 0;
+ node->is_hidden = 0;
+ node->generation = f->generation;
+ if (hash_name(f, node, parent, name) == -1) {
+ free(node);
+ node = NULL;
+ goto out_err;
+ }
+ hash_id(f, node);
+ }
+ node->nlookup ++;
+out_err:
+ pthread_mutex_unlock(&f->lock);
+ return node;
}
static char *add_name(char *buf, char *s, const char *name)
{
- size_t len = strlen(name);
- s -= len;
- if (s <= buf) {
- fprintf(stderr, "fuse: path too long: ...%s\n", s + len);
- return NULL;
- }
- strncpy(s, name, len);
- s--;
- *s = '/';
+ size_t len = strlen(name);
+ s -= len;
+ if (s <= buf) {
+ fprintf(stderr, "fuse: path too long: ...%s\n", s + len);
+ return NULL;
+ }
+ strncpy(s, name, len);
+ s--;
+ *s = '/';
- return s;
+ return s;
}
static char *get_path_name(struct fuse *f, fuse_ino_t nodeid, const char *name)
{
- char buf[FUSE_MAX_PATH];
- char *s = buf + FUSE_MAX_PATH - 1;
- struct node *node;
+ char buf[FUSE_MAX_PATH];
+ char *s = buf + FUSE_MAX_PATH - 1;
+ struct node *node;
- *s = '\0';
+ *s = '\0';
- if (name != NULL) {
- s = add_name(buf, s, name);
- if (s == NULL)
- return NULL;
- }
+ if (name != NULL) {
+ s = add_name(buf, s, name);
+ if (s == NULL)
+ return NULL;
+ }
- pthread_mutex_lock(&f->lock);
- for (node = get_node(f, nodeid); node && node->nodeid != FUSE_ROOT_ID;
- node = node->parent) {
- if (node->name == NULL) {
- s = NULL;
- break;
- }
+ pthread_mutex_lock(&f->lock);
+ for (node = get_node(f, nodeid); node && node->nodeid != FUSE_ROOT_ID;
+ node = node->parent) {
+ if (node->name == NULL) {
+ s = NULL;
+ break;
+ }
- s = add_name(buf, s, node->name);
- if (s == NULL)
- break;
- }
- pthread_mutex_unlock(&f->lock);
+ s = add_name(buf, s, node->name);
+ if (s == NULL)
+ break;
+ }
+ pthread_mutex_unlock(&f->lock);
- if (node == NULL || s == NULL)
- return NULL;
- else if (*s == '\0')
- return strdup("/");
- else
- return strdup(s);
+ if (node == NULL || s == NULL)
+ return NULL;
+ else if (*s == '\0')
+ return strdup("/");
+ else
+ return strdup(s);
}
static char *get_path(struct fuse *f, fuse_ino_t nodeid)
{
- return get_path_name(f, nodeid, NULL);
+ return get_path_name(f, nodeid, NULL);
}
static void forget_node(struct fuse *f, fuse_ino_t nodeid, uint64_t nlookup)
{
- struct node *node;
- if (nodeid == FUSE_ROOT_ID)
- return;
- pthread_mutex_lock(&f->lock);
- node = get_node(f, nodeid);
- assert(node->nlookup >= nlookup);
- node->nlookup -= nlookup;
- if (!node->nlookup) {
- unhash_name(f, node);
- unref_node(f, node);
- }
- pthread_mutex_unlock(&f->lock);
+ struct node *node;
+ if (nodeid == FUSE_ROOT_ID)
+ return;
+ pthread_mutex_lock(&f->lock);
+ node = get_node(f, nodeid);
+ assert(node->nlookup >= nlookup);
+ node->nlookup -= nlookup;
+ if (!node->nlookup) {
+ unhash_name(f, node);
+ unref_node(f, node);
+ }
+ pthread_mutex_unlock(&f->lock);
}
static void remove_node(struct fuse *f, fuse_ino_t dir, const char *name)
{
- struct node *node;
+ struct node *node;
- pthread_mutex_lock(&f->lock);
- node = lookup_node(f, dir, name);
- if (node != NULL)
- unhash_name(f, node);
- pthread_mutex_unlock(&f->lock);
+ pthread_mutex_lock(&f->lock);
+ node = lookup_node(f, dir, name);
+ if (node != NULL)
+ unhash_name(f, node);
+ pthread_mutex_unlock(&f->lock);
}
static int rename_node(struct fuse *f, fuse_ino_t olddir, const char *oldname,
- fuse_ino_t newdir, const char *newname, int hide)
-{
- struct node *node;
- struct node *newnode;
- int err = 0;
-
- pthread_mutex_lock(&f->lock);
- node = lookup_node(f, olddir, oldname);
- newnode = lookup_node(f, newdir, newname);
- if (node == NULL)
- goto out;
-
- if (newnode != NULL) {
- if (hide) {
- fprintf(stderr, "fuse: hidden file got created during hiding\n");
- err = -EBUSY;
- goto out;
- }
- unhash_name(f, newnode);
- }
-
- unhash_name(f, node);
- if (hash_name(f, node, newdir, newname) == -1) {
- err = -ENOMEM;
- goto out;
- }
-
- if (hide)
- node->is_hidden = 1;
+ fuse_ino_t newdir, const char *newname, int hide)
+{
+ struct node *node;
+ struct node *newnode;
+ int err = 0;
+
+ pthread_mutex_lock(&f->lock);
+ node = lookup_node(f, olddir, oldname);
+ newnode = lookup_node(f, newdir, newname);
+ if (node == NULL)
+ goto out;
+
+ if (newnode != NULL) {
+ if (hide) {
+ fprintf(stderr, "fuse: hidden file got created during hiding\n");
+ err = -EBUSY;
+ goto out;
+ }
+ unhash_name(f, newnode);
+ }
+
+ unhash_name(f, node);
+ if (hash_name(f, node, newdir, newname) == -1) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ if (hide)
+ node->is_hidden = 1;
- out:
- pthread_mutex_unlock(&f->lock);
- return err;
+out:
+ pthread_mutex_unlock(&f->lock);
+ return err;
}
static void set_stat(struct fuse *f, fuse_ino_t nodeid, struct stat *stbuf)
{
- if (!f->conf.use_ino)
- stbuf->st_ino = nodeid;
- if (f->conf.set_mode)
- stbuf->st_mode = (stbuf->st_mode & S_IFMT) | (0777 & ~f->conf.umask);
- if (f->conf.set_uid)
- stbuf->st_uid = f->conf.uid;
- if (f->conf.set_gid)
- stbuf->st_gid = f->conf.gid;
+ if (!f->conf.use_ino)
+ stbuf->st_ino = nodeid;
+ if (f->conf.set_mode)
+ stbuf->st_mode = (stbuf->st_mode & S_IFMT) |
+ (0777 & ~f->conf.umask);
+ if (f->conf.set_uid)
+ stbuf->st_uid = f->conf.uid;
+ if (f->conf.set_gid)
+ stbuf->st_gid = f->conf.gid;
}
static struct fuse *req_fuse(fuse_req_t req)
{
- return (struct fuse *) fuse_req_userdata(req);
+ return (struct fuse *) fuse_req_userdata(req);
}
static void fuse_intr_sighandler(int sig)
{
- (void) sig;
- /* Nothing to do */
+ (void) sig;
+ /* Nothing to do */
}
struct fuse_intr_data {
- pthread_t id;
- pthread_cond_t cond;
- int finished;
+ pthread_t id;
+ pthread_cond_t cond;
+ int finished;
};
static void fuse_interrupt(fuse_req_t req, void *d_)
{
- struct fuse_intr_data *d = d_;
- struct fuse *f = req_fuse(req);
+ struct fuse_intr_data *d = d_;
+ struct fuse *f = req_fuse(req);
- if (d->id == pthread_self())
- return;
+ if (d->id == pthread_self())
+ return;
- pthread_mutex_lock(&f->lock);
- while (!d->finished) {
- struct timeval now;
- struct timespec timeout;
+ pthread_mutex_lock(&f->lock);
+ while (!d->finished) {
+ struct timeval now;
+ struct timespec timeout;
- pthread_kill(d->id, f->conf.intr_signal);
- gettimeofday(&now, NULL);
- timeout.tv_sec = now.tv_sec + 1;
- timeout.tv_nsec = now.tv_usec * 1000;
- pthread_cond_timedwait(&d->cond, &f->lock, &timeout);
- }
- pthread_mutex_unlock(&f->lock);
+ pthread_kill(d->id, f->conf.intr_signal);
+ gettimeofday(&now, NULL);
+ timeout.tv_sec = now.tv_sec + 1;
+ timeout.tv_nsec = now.tv_usec * 1000;
+ pthread_cond_timedwait(&d->cond, &f->lock, &timeout);
+ }
+ pthread_mutex_unlock(&f->lock);
}
static void fuse_do_finish_interrupt(struct fuse *f, fuse_req_t req,
- struct fuse_intr_data *d)
+ struct fuse_intr_data *d)
{
- pthread_mutex_lock(&f->lock);
- d->finished = 1;
- pthread_cond_broadcast(&d->cond);
- pthread_mutex_unlock(&f->lock);
- fuse_req_interrupt_func(req, NULL, NULL);
- pthread_cond_destroy(&d->cond);
+ pthread_mutex_lock(&f->lock);
+ d->finished = 1;
+ pthread_cond_broadcast(&d->cond);
+ pthread_mutex_unlock(&f->lock);
+ fuse_req_interrupt_func(req, NULL, NULL);
+ pthread_cond_destroy(&d->cond);
}
static void fuse_do_prepare_interrupt(fuse_req_t req, struct fuse_intr_data *d)
{
- d->id = pthread_self();
- pthread_cond_init(&d->cond, NULL);
- d->finished = 0;
- fuse_req_interrupt_func(req, fuse_interrupt, d);
+ d->id = pthread_self();
+ pthread_cond_init(&d->cond, NULL);
+ d->finished = 0;
+ fuse_req_interrupt_func(req, fuse_interrupt, d);
}
static inline void fuse_finish_interrupt(struct fuse *f, fuse_req_t req,
- struct fuse_intr_data *d)
+ struct fuse_intr_data *d)
{
- if (f->conf.intr)
- fuse_do_finish_interrupt(f, req, d);
+ if (f->conf.intr)
+ fuse_do_finish_interrupt(f, req, d);
}
static inline void fuse_prepare_interrupt(struct fuse *f, fuse_req_t req,
- struct fuse_intr_data *d)
+ struct fuse_intr_data *d)
{
- if (f->conf.intr)
- fuse_do_prepare_interrupt(req, d);
+ if (f->conf.intr)
+ fuse_do_prepare_interrupt(req, d);
}
#ifndef __FreeBSD__
static int fuse_compat_open(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
-{
- int err;
- if (!fs->compat || fs->compat >= 25)
- err = fs->op.open(path, fi);
- else if (fs->compat == 22) {
- struct fuse_file_info_compat tmp;
- memcpy(&tmp, fi, sizeof(tmp));
- err = ((struct fuse_operations_compat22 *) &fs->op)->open(path, &tmp);
- memcpy(fi, &tmp, sizeof(tmp));
- fi->fh = tmp.fh;
- } else
- err = ((struct fuse_operations_compat2 *) &fs->op)
- ->open(path, fi->flags);
- return err;
+ struct fuse_file_info *fi)
+{
+ int err;
+ if (!fs->compat || fs->compat >= 25)
+ err = fs->op.open(path, fi);
+ else if (fs->compat == 22) {
+ struct fuse_file_info_compat tmp;
+ memcpy(&tmp, fi, sizeof(tmp));
+ err = ((struct fuse_operations_compat22 *) &fs->op)->open(path,
+ &tmp);
+ memcpy(fi, &tmp, sizeof(tmp));
+ fi->fh = tmp.fh;
+ } else
+ err = ((struct fuse_operations_compat2 *) &fs->op)
+ ->open(path, fi->flags);
+ return err;
}
static int fuse_compat_release(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- if (!fs->compat || fs->compat >= 22)
- return fs->op.release(path, fi);
- else
- return ((struct fuse_operations_compat2 *) &fs->op)
- ->release(path, fi->flags);
+ if (!fs->compat || fs->compat >= 22)
+ return fs->op.release(path, fi);
+ else
+ return ((struct fuse_operations_compat2 *) &fs->op)
+ ->release(path, fi->flags);
}
static int fuse_compat_opendir(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
-{
- if (!fs->compat || fs->compat >= 25)
- return fs->op.opendir(path, fi);
- else {
- int err;
- struct fuse_file_info_compat tmp;
- memcpy(&tmp, fi, sizeof(tmp));
- err = ((struct fuse_operations_compat22 *) &fs->op)
- ->opendir(path, &tmp);
- memcpy(fi, &tmp, sizeof(tmp));
- fi->fh = tmp.fh;
- return err;
- }
+ struct fuse_file_info *fi)
+{
+ if (!fs->compat || fs->compat >= 25)
+ return fs->op.opendir(path, fi);
+ else {
+ int err;
+ struct fuse_file_info_compat tmp;
+ memcpy(&tmp, fi, sizeof(tmp));
+ err = ((struct fuse_operations_compat22 *) &fs->op)
+ ->opendir(path, &tmp);
+ memcpy(fi, &tmp, sizeof(tmp));
+ fi->fh = tmp.fh;
+ return err;
+ }
}
static void convert_statfs_compat(struct fuse_statfs_compat1 *compatbuf,
- struct statvfs *stbuf)
+ struct statvfs *stbuf)
{
- stbuf->f_bsize = compatbuf->block_size;
- stbuf->f_blocks = compatbuf->blocks;
- stbuf->f_bfree = compatbuf->blocks_free;
- stbuf->f_bavail = compatbuf->blocks_free;
- stbuf->f_files = compatbuf->files;
- stbuf->f_ffree = compatbuf->files_free;
- stbuf->f_namemax = compatbuf->namelen;
+ stbuf->f_bsize = compatbuf->block_size;
+ stbuf->f_blocks = compatbuf->blocks;
+ stbuf->f_bfree = compatbuf->blocks_free;
+ stbuf->f_bavail = compatbuf->blocks_free;
+ stbuf->f_files = compatbuf->files;
+ stbuf->f_ffree = compatbuf->files_free;
+ stbuf->f_namemax = compatbuf->namelen;
}
static void convert_statfs_old(struct statfs *oldbuf, struct statvfs *stbuf)
{
- stbuf->f_bsize = oldbuf->f_bsize;
- stbuf->f_blocks = oldbuf->f_blocks;
- stbuf->f_bfree = oldbuf->f_bfree;
- stbuf->f_bavail = oldbuf->f_bavail;
- stbuf->f_files = oldbuf->f_files;
- stbuf->f_ffree = oldbuf->f_ffree;
- stbuf->f_namemax = oldbuf->f_namelen;
+ stbuf->f_bsize = oldbuf->f_bsize;
+ stbuf->f_blocks = oldbuf->f_blocks;
+ stbuf->f_bfree = oldbuf->f_bfree;
+ stbuf->f_bavail = oldbuf->f_bavail;
+ stbuf->f_files = oldbuf->f_files;
+ stbuf->f_ffree = oldbuf->f_ffree;
+ stbuf->f_namemax = oldbuf->f_namelen;
}
static int fuse_compat_statfs(struct fuse_fs *fs, const char *path,
- struct statvfs *buf)
-{
- int err;
-
- if (!fs->compat || fs->compat >= 25) {
- err = fs->op.statfs(fs->compat == 25 ? "/" : path, buf);
- } else if (fs->compat > 11) {
- struct statfs oldbuf;
- err = ((struct fuse_operations_compat22 *) &fs->op)
- ->statfs("/", &oldbuf);
- if (!err)
- convert_statfs_old(&oldbuf, buf);
- } else {
- struct fuse_statfs_compat1 compatbuf;
- memset(&compatbuf, 0, sizeof(struct fuse_statfs_compat1));
- err = ((struct fuse_operations_compat1 *) &fs->op)->statfs(&compatbuf);
- if (!err)
- convert_statfs_compat(&compatbuf, buf);
- }
- return err;
+ struct statvfs *buf)
+{
+ int err;
+
+ if (!fs->compat || fs->compat >= 25) {
+ err = fs->op.statfs(fs->compat == 25 ? "/" : path, buf);
+ } else if (fs->compat > 11) {
+ struct statfs oldbuf;
+ err = ((struct fuse_operations_compat22 *) &fs->op)
+ ->statfs("/", &oldbuf);
+ if (!err)
+ convert_statfs_old(&oldbuf, buf);
+ } else {
+ struct fuse_statfs_compat1 compatbuf;
+ memset(&compatbuf, 0, sizeof(struct fuse_statfs_compat1));
+ err = ((struct fuse_operations_compat1 *) &fs->op)
+ ->statfs(&compatbuf);
+ if (!err)
+ convert_statfs_compat(&compatbuf, buf);
+ }
+ return err;
}
#else /* __FreeBSD__ */
static inline int fuse_compat_open(struct fuse_fs *fs, char *path,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- return fs->op.open(path, fi);
+ return fs->op.open(path, fi);
}
static inline int fuse_compat_release(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- return fs->op.release(path, fi);
+ return fs->op.release(path, fi);
}
static inline int fuse_compat_opendir(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- return fs->op.opendir(path, fi);
+ return fs->op.opendir(path, fi);
}
static inline int fuse_compat_statfs(struct fuse_fs *fs, const char *path,
- struct statvfs *buf)
+ struct statvfs *buf)
{
- return fs->op.statfs(fs->compat == 25 ? "/" : path, buf);
+ return fs->op.statfs(fs->compat == 25 ? "/" : path, buf);
}
#endif /* __FreeBSD__ */
int fuse_fs_getattr(struct fuse_fs *fs, const char *path, struct stat *buf)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.getattr)
- return fs->op.getattr(path, buf);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.getattr)
+ return fs->op.getattr(path, buf);
+ else
+ return -ENOSYS;
}
int fuse_fs_fgetattr(struct fuse_fs *fs, const char *path, struct stat *buf,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.fgetattr)
- return fs->op.fgetattr(path, buf, fi);
- else if (fs->op.getattr)
- return fs->op.getattr(path, buf);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.fgetattr)
+ return fs->op.fgetattr(path, buf, fi);
+ else if (fs->op.getattr)
+ return fs->op.getattr(path, buf);
+ else
+ return -ENOSYS;
}
int fuse_fs_rename(struct fuse_fs *fs, const char *oldpath,
- const char *newpath)
+ const char *newpath)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.rename)
- return fs->op.rename(oldpath, newpath);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.rename)
+ return fs->op.rename(oldpath, newpath);
+ else
+ return -ENOSYS;
}
int fuse_fs_unlink(struct fuse_fs *fs, const char *path)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.unlink)
- return fs->op.unlink(path);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.unlink)
+ return fs->op.unlink(path);
+ else
+ return -ENOSYS;
}
int fuse_fs_rmdir(struct fuse_fs *fs, const char *path)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.rmdir)
- return fs->op.rmdir(path);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.rmdir)
+ return fs->op.rmdir(path);
+ else
+ return -ENOSYS;
}
int fuse_fs_symlink(struct fuse_fs *fs, const char *linkname, const char *path)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.symlink)
- return fs->op.symlink(linkname, path);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.symlink)
+ return fs->op.symlink(linkname, path);
+ else
+ return -ENOSYS;
}
int fuse_fs_link(struct fuse_fs *fs, const char *oldpath, const char *newpath)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.link)
- return fs->op.link(oldpath, newpath);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.link)
+ return fs->op.link(oldpath, newpath);
+ else
+ return -ENOSYS;
}
-int fuse_fs_release(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
+int fuse_fs_release(struct fuse_fs *fs, const char *path,
+ struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.release)
- return fuse_compat_release(fs, path, fi);
- else
- return 0;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.release)
+ return fuse_compat_release(fs, path, fi);
+ else
+ return 0;
}
int fuse_fs_opendir(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.opendir)
- return fuse_compat_opendir(fs, path, fi);
- else
- return 0;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.opendir)
+ return fuse_compat_opendir(fs, path, fi);
+ else
+ return 0;
}
int fuse_fs_open(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.open)
- return fuse_compat_open(fs, path, fi);
- else
- return 0;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.open)
+ return fuse_compat_open(fs, path, fi);
+ else
+ return 0;
}
int fuse_fs_read(struct fuse_fs *fs, const char *path, char *buf, size_t size,
- off_t off, struct fuse_file_info *fi)
+ off_t off, struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.read)
- return fs->op.read(path, buf, size, off, fi);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.read)
+ return fs->op.read(path, buf, size, off, fi);
+ else
+ return -ENOSYS;
}
int fuse_fs_write(struct fuse_fs *fs, const char *path, const char *buf,
- size_t size, off_t off, struct fuse_file_info *fi)
+ size_t size, off_t off, struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.write)
- return fs->op.write(path, buf, size, off, fi);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.write)
+ return fs->op.write(path, buf, size, off, fi);
+ else
+ return -ENOSYS;
}
int fuse_fs_fsync(struct fuse_fs *fs, const char *path, int datasync,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.fsync)
- return fs->op.fsync(path, datasync, fi);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.fsync)
+ return fs->op.fsync(path, datasync, fi);
+ else
+ return -ENOSYS;
}
int fuse_fs_fsyncdir(struct fuse_fs *fs, const char *path, int datasync,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.fsyncdir)
- return fs->op.fsyncdir(path, datasync, fi);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.fsyncdir)
+ return fs->op.fsyncdir(path, datasync, fi);
+ else
+ return -ENOSYS;
}
int fuse_fs_flush(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.flush)
- return fs->op.flush(path, fi);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.flush)
+ return fs->op.flush(path, fi);
+ else
+ return -ENOSYS;
}
int fuse_fs_statfs(struct fuse_fs *fs, const char *path, struct statvfs *buf)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.statfs)
- return fuse_compat_statfs(fs, path, buf);
- else {
- buf->f_namemax = 255;
- buf->f_bsize = 512;
- return 0;
- }
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.statfs)
+ return fuse_compat_statfs(fs, path, buf);
+ else {
+ buf->f_namemax = 255;
+ buf->f_bsize = 512;
+ return 0;
+ }
}
int fuse_fs_releasedir(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.releasedir)
- return fs->op.releasedir(path, fi);
- else
- return 0;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.releasedir)
+ return fs->op.releasedir(path, fi);
+ else
+ return 0;
}
static int fill_dir_old(struct fuse_dirhandle *dh, const char *name, int type,
- ino_t ino)
+ ino_t ino)
{
- int res;
- struct stat stbuf;
+ int res;
+ struct stat stbuf;
- memset(&stbuf, 0, sizeof(stbuf));
- stbuf.st_mode = type << 12;
- stbuf.st_ino = ino;
+ memset(&stbuf, 0, sizeof(stbuf));
+ stbuf.st_mode = type << 12;
+ stbuf.st_ino = ino;
- res = dh->filler(dh->buf, name, &stbuf, 0);
- return res ? -ENOMEM : 0;
+ res = dh->filler(dh->buf, name, &stbuf, 0);
+ return res ? -ENOMEM : 0;
}
int fuse_fs_readdir(struct fuse_fs *fs, const char *path, void *buf,
- fuse_fill_dir_t filler, off_t off,
- struct fuse_file_info *fi)
+ fuse_fill_dir_t filler, off_t off,
+ struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.readdir)
- return fs->op.readdir(path, buf, filler, off, fi);
- else if (fs->op.getdir) {
- struct fuse_dirhandle dh;
- dh.filler = filler;
- dh.buf = buf;
- return fs->op.getdir(path, &dh, fill_dir_old);
- } else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.readdir)
+ return fs->op.readdir(path, buf, filler, off, fi);
+ else if (fs->op.getdir) {
+ struct fuse_dirhandle dh;
+ dh.filler = filler;
+ dh.buf = buf;
+ return fs->op.getdir(path, &dh, fill_dir_old);
+ } else
+ return -ENOSYS;
}
int fuse_fs_create(struct fuse_fs *fs, const char *path, mode_t mode,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.create)
- return fs->op.create(path, mode, fi);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.create)
+ return fs->op.create(path, mode, fi);
+ else
+ return -ENOSYS;
}
int fuse_fs_lock(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi, int cmd, struct flock *lock)
+ struct fuse_file_info *fi, int cmd, struct flock *lock)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.lock)
- return fs->op.lock(path, fi, cmd, lock);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.lock)
+ return fs->op.lock(path, fi, cmd, lock);
+ else
+ return -ENOSYS;
}
int fuse_fs_chown(struct fuse_fs *fs, const char *path, uid_t uid, gid_t gid)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.chown)
- return fs->op.chown(path, uid, gid);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.chown)
+ return fs->op.chown(path, uid, gid);
+ else
+ return -ENOSYS;
}
int fuse_fs_truncate(struct fuse_fs *fs, const char *path, off_t size)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.truncate)
- return fs->op.truncate(path, size);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.truncate)
+ return fs->op.truncate(path, size);
+ else
+ return -ENOSYS;
}
int fuse_fs_ftruncate(struct fuse_fs *fs, const char *path, off_t size,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.ftruncate)
- return fs->op.ftruncate(path, size, fi);
- else if (fs->op.truncate)
- return fs->op.truncate(path, size);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.ftruncate)
+ return fs->op.ftruncate(path, size, fi);
+ else if (fs->op.truncate)
+ return fs->op.truncate(path, size);
+ else
+ return -ENOSYS;
}
int fuse_fs_utimens(struct fuse_fs *fs, const char *path,
- const struct timespec tv[2])
+ const struct timespec tv[2])
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.utimens)
- return fs->op.utimens(path, tv);
- else if(fs->op.utime) {
- struct utimbuf buf;
- buf.actime = tv[0].tv_sec;
- buf.modtime = tv[1].tv_sec;
- return fs->op.utime(path, &buf);
- } else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.utimens)
+ return fs->op.utimens(path, tv);
+ else if(fs->op.utime) {
+ struct utimbuf buf;
+ buf.actime = tv[0].tv_sec;
+ buf.modtime = tv[1].tv_sec;
+ return fs->op.utime(path, &buf);
+ } else
+ return -ENOSYS;
}
int fuse_fs_access(struct fuse_fs *fs, const char *path, int mask)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.access)
- return fs->op.access(path, mask);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.access)
+ return fs->op.access(path, mask);
+ else
+ return -ENOSYS;
}
int fuse_fs_readlink(struct fuse_fs *fs, const char *path, char *buf,
- size_t len)
+ size_t len)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.readlink)
- return fs->op.readlink(path, buf, len);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.readlink)
+ return fs->op.readlink(path, buf, len);
+ else
+ return -ENOSYS;
}
int fuse_fs_mknod(struct fuse_fs *fs, const char *path, mode_t mode,
- dev_t rdev)
+ dev_t rdev)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.mknod)
- return fs->op.mknod(path, mode, rdev);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.mknod)
+ return fs->op.mknod(path, mode, rdev);
+ else
+ return -ENOSYS;
}
int fuse_fs_mkdir(struct fuse_fs *fs, const char *path, mode_t mode)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.mkdir)
- return fs->op.mkdir(path, mode);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.mkdir)
+ return fs->op.mkdir(path, mode);
+ else
+ return -ENOSYS;
}
int fuse_fs_setxattr(struct fuse_fs *fs, const char *path, const char *name,
- const char *value, size_t size, int flags)
+ const char *value, size_t size, int flags)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.setxattr)
- return fs->op.setxattr(path, name, value, size, flags);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.setxattr)
+ return fs->op.setxattr(path, name, value, size, flags);
+ else
+ return -ENOSYS;
}
int fuse_fs_getxattr(struct fuse_fs *fs, const char *path, const char *name,
- char *value, size_t size)
+ char *value, size_t size)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.getxattr)
- return fs->op.getxattr(path, name, value, size);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.getxattr)
+ return fs->op.getxattr(path, name, value, size);
+ else
+ return -ENOSYS;
}
int fuse_fs_listxattr(struct fuse_fs *fs, const char *path, char *list,
- size_t size)
+ size_t size)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.listxattr)
- return fs->op.listxattr(path, list, size);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.listxattr)
+ return fs->op.listxattr(path, list, size);
+ else
+ return -ENOSYS;
}
int fuse_fs_bmap(struct fuse_fs *fs, const char *path, size_t blocksize,
- uint64_t *idx)
+ uint64_t *idx)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.bmap)
- return fs->op.bmap(path, blocksize, idx);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.bmap)
+ return fs->op.bmap(path, blocksize, idx);
+ else
+ return -ENOSYS;
}
int fuse_fs_removexattr(struct fuse_fs *fs, const char *path, const char *name)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.removexattr)
- return fs->op.removexattr(path, name);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.removexattr)
+ return fs->op.removexattr(path, name);
+ else
+ return -ENOSYS;
}
static int is_open(struct fuse *f, fuse_ino_t dir, const char *name)
{
- struct node *node;
- int isopen = 0;
- pthread_mutex_lock(&f->lock);
- node = lookup_node(f, dir, name);
- if (node && node->open_count > 0)
- isopen = 1;
- pthread_mutex_unlock(&f->lock);
- return isopen;
+ struct node *node;
+ int isopen = 0;
+ pthread_mutex_lock(&f->lock);
+ node = lookup_node(f, dir, name);
+ if (node && node->open_count > 0)
+ isopen = 1;
+ pthread_mutex_unlock(&f->lock);
+ return isopen;
}
static char *hidden_name(struct fuse *f, fuse_ino_t dir, const char *oldname,
- char *newname, size_t bufsize)
-{
- struct stat buf;
- struct node *node;
- struct node *newnode;
- char *newpath;
- int res;
- int failctr = 10;
-
- do {
- pthread_mutex_lock(&f->lock);
- node = lookup_node(f, dir, oldname);
- if (node == NULL) {
- pthread_mutex_unlock(&f->lock);
- return NULL;
- }
- do {
- f->hidectr ++;
- snprintf(newname, bufsize, ".fuse_hidden%08x%08x",
- (unsigned int) node->nodeid, f->hidectr);
- newnode = lookup_node(f, dir, newname);
- } while(newnode);
- pthread_mutex_unlock(&f->lock);
-
- newpath = get_path_name(f, dir, newname);
- if (!newpath)
- break;
-
- res = fuse_fs_getattr(f->fs, newpath, &buf);
- if (res == -ENOENT)
- break;
- free(newpath);
- newpath = NULL;
- } while(res == 0 && --failctr);
-
- return newpath;
+ char *newname, size_t bufsize)
+{
+ struct stat buf;
+ struct node *node;
+ struct node *newnode;
+ char *newpath;
+ int res;
+ int failctr = 10;
+
+ do {
+ pthread_mutex_lock(&f->lock);
+ node = lookup_node(f, dir, oldname);
+ if (node == NULL) {
+ pthread_mutex_unlock(&f->lock);
+ return NULL;
+ }
+ do {
+ f->hidectr ++;
+ snprintf(newname, bufsize, ".fuse_hidden%08x%08x",
+ (unsigned int) node->nodeid, f->hidectr);
+ newnode = lookup_node(f, dir, newname);
+ } while(newnode);
+ pthread_mutex_unlock(&f->lock);
+
+ newpath = get_path_name(f, dir, newname);
+ if (!newpath)
+ break;
+
+ res = fuse_fs_getattr(f->fs, newpath, &buf);
+ if (res == -ENOENT)
+ break;
+ free(newpath);
+ newpath = NULL;
+ } while(res == 0 && --failctr);
+
+ return newpath;
}
static int hide_node(struct fuse *f, const char *oldpath,
- fuse_ino_t dir, const char *oldname)
+ fuse_ino_t dir, const char *oldname)
{
- char newname[64];
- char *newpath;
- int err = -EBUSY;
+ char newname[64];
+ char *newpath;
+ int err = -EBUSY;
- newpath = hidden_name(f, dir, oldname, newname, sizeof(newname));
- if (newpath) {
- err = fuse_fs_rename(f->fs, oldpath, newpath);
- if (!err)
- err = rename_node(f, dir, oldname, dir, newname, 1);
- free(newpath);
- }
- return err;
+ newpath = hidden_name(f, dir, oldname, newname, sizeof(newname));
+ if (newpath) {
+ err = fuse_fs_rename(f->fs, oldpath, newpath);
+ if (!err)
+ err = rename_node(f, dir, oldname, dir, newname, 1);
+ free(newpath);
+ }
+ return err;
}
static int mtime_eq(const struct stat *stbuf, const struct timespec *ts)
{
- return stbuf->st_mtime == ts->tv_sec && ST_MTIM_NSEC(stbuf) == ts->tv_nsec;
+ return stbuf->st_mtime == ts->tv_sec &&
+ ST_MTIM_NSEC(stbuf) == ts->tv_nsec;
}
#ifndef CLOCK_MONOTONIC
@@ -1172,2122 +1180,2153 @@ static int mtime_eq(const struct stat *stbuf, const struct timespec *ts)
static void curr_time(struct timespec *now)
{
- static clockid_t clockid = CLOCK_MONOTONIC;
- int res = clock_gettime(clockid, now);
- if (res == -1 && errno == EINVAL) {
- clockid = CLOCK_REALTIME;
- res = clock_gettime(clockid, now);
- }
- if (res == -1) {
- perror("fuse: clock_gettime");
- abort();
- }
+ static clockid_t clockid = CLOCK_MONOTONIC;
+ int res = clock_gettime(clockid, now);
+ if (res == -1 && errno == EINVAL) {
+ clockid = CLOCK_REALTIME;
+ res = clock_gettime(clockid, now);
+ }
+ if (res == -1) {
+ perror("fuse: clock_gettime");
+ abort();
+ }
}
static void update_stat(struct node *node, const struct stat *stbuf)
{
- if (node->cache_valid && (!mtime_eq(stbuf, &node->mtime) ||
- stbuf->st_size != node->size))
- node->cache_valid = 0;
- node->mtime.tv_sec = stbuf->st_mtime;
- node->mtime.tv_nsec = ST_MTIM_NSEC(stbuf);
- node->size = stbuf->st_size;
- curr_time(&node->stat_updated);
+ if (node->cache_valid && (!mtime_eq(stbuf, &node->mtime) ||
+ stbuf->st_size != node->size))
+ node->cache_valid = 0;
+ node->mtime.tv_sec = stbuf->st_mtime;
+ node->mtime.tv_nsec = ST_MTIM_NSEC(stbuf);
+ node->size = stbuf->st_size;
+ curr_time(&node->stat_updated);
}
static int lookup_path(struct fuse *f, fuse_ino_t nodeid,
- const char *name, const char *path,
- struct fuse_entry_param *e, struct fuse_file_info *fi)
-{
- int res;
-
- memset(e, 0, sizeof(struct fuse_entry_param));
- if (fi)
- res = fuse_fs_fgetattr(f->fs, path, &e->attr, fi);
- else
- res = fuse_fs_getattr(f->fs, path, &e->attr);
- if (res == 0) {
- struct node *node;
-
- node = find_node(f, nodeid, name);
- if (node == NULL)
- res = -ENOMEM;
- else {
- e->ino = node->nodeid;
- e->generation = node->generation;
- e->entry_timeout = f->conf.entry_timeout;
- e->attr_timeout = f->conf.attr_timeout;
- if (f->conf.auto_cache) {
- pthread_mutex_lock(&f->lock);
- update_stat(node, &e->attr);
- pthread_mutex_unlock(&f->lock);
- }
- set_stat(f, e->ino, &e->attr);
- if (f->conf.debug)
- fprintf(stderr, " NODEID: %lu\n", (unsigned long) e->ino);
- }
- }
- return res;
+ const char *name, const char *path,
+ struct fuse_entry_param *e, struct fuse_file_info *fi)
+{
+ int res;
+
+ memset(e, 0, sizeof(struct fuse_entry_param));
+ if (fi)
+ res = fuse_fs_fgetattr(f->fs, path, &e->attr, fi);
+ else
+ res = fuse_fs_getattr(f->fs, path, &e->attr);
+ if (res == 0) {
+ struct node *node;
+
+ node = find_node(f, nodeid, name);
+ if (node == NULL)
+ res = -ENOMEM;
+ else {
+ e->ino = node->nodeid;
+ e->generation = node->generation;
+ e->entry_timeout = f->conf.entry_timeout;
+ e->attr_timeout = f->conf.attr_timeout;
+ if (f->conf.auto_cache) {
+ pthread_mutex_lock(&f->lock);
+ update_stat(node, &e->attr);
+ pthread_mutex_unlock(&f->lock);
+ }
+ set_stat(f, e->ino, &e->attr);
+ if (f->conf.debug)
+ fprintf(stderr, " NODEID: %lu\n",
+ (unsigned long) e->ino);
+ }
+ }
+ return res;
}
static struct fuse_context_i *fuse_get_context_internal(void)
{
- struct fuse_context_i *c;
-
- c = (struct fuse_context_i *) pthread_getspecific(fuse_context_key);
- if (c == NULL) {
- c = (struct fuse_context_i *) malloc(sizeof(struct fuse_context_i));
- if (c == NULL) {
- /* This is hard to deal with properly, so just abort. If
- memory is so low that the context cannot be allocated,
- there's not much hope for the filesystem anyway */
- fprintf(stderr, "fuse: failed to allocate thread specific data\n");
- abort();
- }
- pthread_setspecific(fuse_context_key, c);
- }
- return c;
+ struct fuse_context_i *c;
+
+ c = (struct fuse_context_i *) pthread_getspecific(fuse_context_key);
+ if (c == NULL) {
+ c = (struct fuse_context_i *)
+ malloc(sizeof(struct fuse_context_i));
+ if (c == NULL) {
+ /* This is hard to deal with properly, so just
+ abort. If memory is so low that the
+ context cannot be allocated, there's not
+ much hope for the filesystem anyway */
+ fprintf(stderr, "fuse: failed to allocate thread specific data\n");
+ abort();
+ }
+ pthread_setspecific(fuse_context_key, c);
+ }
+ return c;
}
static void fuse_freecontext(void *data)
{
- free(data);
+ free(data);
}
static int fuse_create_context_key(void)
{
- int err = 0;
- pthread_mutex_lock(&fuse_context_lock);
- if (!fuse_context_ref) {
- err = pthread_key_create(&fuse_context_key, fuse_freecontext);
- if (err) {
- fprintf(stderr, "fuse: failed to create thread specific key: %s\n",
- strerror(err));
- pthread_mutex_unlock(&fuse_context_lock);
- return -1;
- }
- }
- fuse_context_ref++;
- pthread_mutex_unlock(&fuse_context_lock);
- return 0;
+ int err = 0;
+ pthread_mutex_lock(&fuse_context_lock);
+ if (!fuse_context_ref) {
+ err = pthread_key_create(&fuse_context_key, fuse_freecontext);
+ if (err) {
+ fprintf(stderr, "fuse: failed to create thread specific key: %s\n",
+ strerror(err));
+ pthread_mutex_unlock(&fuse_context_lock);
+ return -1;
+ }
+ }
+ fuse_context_ref++;
+ pthread_mutex_unlock(&fuse_context_lock);
+ return 0;
}
static void fuse_delete_context_key(void)
{
- pthread_mutex_lock(&fuse_context_lock);
- fuse_context_ref--;
- if (!fuse_context_ref) {
- free(pthread_getspecific(fuse_context_key));
- pthread_key_delete(fuse_context_key);
- }
- pthread_mutex_unlock(&fuse_context_lock);
+ pthread_mutex_lock(&fuse_context_lock);
+ fuse_context_ref--;
+ if (!fuse_context_ref) {
+ free(pthread_getspecific(fuse_context_key));
+ pthread_key_delete(fuse_context_key);
+ }
+ pthread_mutex_unlock(&fuse_context_lock);
}
static struct fuse *req_fuse_prepare(fuse_req_t req)
{
- struct fuse_context_i *c = fuse_get_context_internal();
- const struct fuse_ctx *ctx = fuse_req_ctx(req);
- c->req = req;
- c->ctx.fuse = req_fuse(req);
- c->ctx.uid = ctx->uid;
- c->ctx.gid = ctx->gid;
- c->ctx.pid = ctx->pid;
- return c->ctx.fuse;
+ struct fuse_context_i *c = fuse_get_context_internal();
+ const struct fuse_ctx *ctx = fuse_req_ctx(req);
+ c->req = req;
+ c->ctx.fuse = req_fuse(req);
+ c->ctx.uid = ctx->uid;
+ c->ctx.gid = ctx->gid;
+ c->ctx.pid = ctx->pid;
+ return c->ctx.fuse;
}
static inline void reply_err(fuse_req_t req, int err)
{
- /* fuse_reply_err() uses non-negated errno values */
- fuse_reply_err(req, -err);
+ /* fuse_reply_err() uses non-negated errno values */
+ fuse_reply_err(req, -err);
}
static void reply_entry(fuse_req_t req, const struct fuse_entry_param *e,
- int err)
+ int err)
{
- if (!err) {
- struct fuse *f = req_fuse(req);
- if (fuse_reply_entry(req, e) == -ENOENT)
- forget_node(f, e->ino, 1);
- } else
- reply_err(req, err);
+ if (!err) {
+ struct fuse *f = req_fuse(req);
+ if (fuse_reply_entry(req, e) == -ENOENT)
+ forget_node(f, e->ino, 1);
+ } else
+ reply_err(req, err);
}
void fuse_fs_init(struct fuse_fs *fs, struct fuse_conn_info *conn)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.init)
- fs->user_data = fs->op.init(conn);
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.init)
+ fs->user_data = fs->op.init(conn);
}
static void fuse_lib_init(void *data, struct fuse_conn_info *conn)
{
- struct fuse *f = (struct fuse *) data;
- struct fuse_context_i *c = fuse_get_context_internal();
+ struct fuse *f = (struct fuse *) data;
+ struct fuse_context_i *c = fuse_get_context_internal();
- memset(c, 0, sizeof(*c));
- c->ctx.fuse = f;
- fuse_fs_init(f->fs, conn);
+ memset(c, 0, sizeof(*c));
+ c->ctx.fuse = f;
+ fuse_fs_init(f->fs, conn);
}
void fuse_fs_destroy(struct fuse_fs *fs)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.destroy)
- fs->op.destroy(fs->user_data);
- if (fs->m)
- fuse_put_module(fs->m);
- free(fs);
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.destroy)
+ fs->op.destroy(fs->user_data);
+ if (fs->m)
+ fuse_put_module(fs->m);
+ free(fs);
}
static void fuse_lib_destroy(void *data)
{
- struct fuse *f = (struct fuse *) data;
- struct fuse_context_i *c = fuse_get_context_internal();
+ struct fuse *f = (struct fuse *) data;
+ struct fuse_context_i *c = fuse_get_context_internal();
- memset(c, 0, sizeof(*c));
- c->ctx.fuse = f;
- fuse_fs_destroy(f->fs);
- f->fs = NULL;
+ memset(c, 0, sizeof(*c));
+ c->ctx.fuse = f;
+ fuse_fs_destroy(f->fs);
+ f->fs = NULL;
}
static void fuse_lib_lookup(fuse_req_t req, fuse_ino_t parent,
- const char *name)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_entry_param e;
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path_name(f, parent, name);
- if (path != NULL) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "LOOKUP %s\n", path);
- fuse_prepare_interrupt(f, req, &d);
- err = lookup_path(f, parent, name, path, &e, NULL);
- if (err == -ENOENT && f->conf.negative_timeout != 0.0) {
- e.ino = 0;
- e.entry_timeout = f->conf.negative_timeout;
- err = 0;
- }
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_entry(req, &e, err);
+ const char *name)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_entry_param e;
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path_name(f, parent, name);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "LOOKUP %s\n", path);
+ fuse_prepare_interrupt(f, req, &d);
+ err = lookup_path(f, parent, name, path, &e, NULL);
+ if (err == -ENOENT && f->conf.negative_timeout != 0.0) {
+ e.ino = 0;
+ e.entry_timeout = f->conf.negative_timeout;
+ err = 0;
+ }
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_entry(req, &e, err);
}
static void fuse_lib_forget(fuse_req_t req, fuse_ino_t ino,
- unsigned long nlookup)
+ unsigned long nlookup)
{
- struct fuse *f = req_fuse(req);
- if (f->conf.debug)
- fprintf(stderr, "FORGET %llu/%lu\n", (unsigned long long)ino, nlookup);
- forget_node(f, ino, nlookup);
- fuse_reply_none(req);
+ struct fuse *f = req_fuse(req);
+ if (f->conf.debug)
+ fprintf(stderr, "FORGET %llu/%lu\n", (unsigned long long)ino,
+ nlookup);
+ forget_node(f, ino, nlookup);
+ fuse_reply_none(req);
}
static void fuse_lib_getattr(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct stat buf;
- char *path;
- int err;
-
- (void) fi;
- memset(&buf, 0, sizeof(buf));
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_getattr(f->fs, path, &buf);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- if (!err) {
- if (f->conf.auto_cache) {
- pthread_mutex_lock(&f->lock);
- update_stat(get_node(f, ino), &buf);
- pthread_mutex_unlock(&f->lock);
- }
- set_stat(f, ino, &buf);
- fuse_reply_attr(req, &buf, f->conf.attr_timeout);
- } else
- reply_err(req, err);
+ struct fuse_file_info *fi)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct stat buf;
+ char *path;
+ int err;
+
+ (void) fi;
+ memset(&buf, 0, sizeof(buf));
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_getattr(f->fs, path, &buf);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ if (!err) {
+ if (f->conf.auto_cache) {
+ pthread_mutex_lock(&f->lock);
+ update_stat(get_node(f, ino), &buf);
+ pthread_mutex_unlock(&f->lock);
+ }
+ set_stat(f, ino, &buf);
+ fuse_reply_attr(req, &buf, f->conf.attr_timeout);
+ } else
+ reply_err(req, err);
}
int fuse_fs_chmod(struct fuse_fs *fs, const char *path, mode_t mode)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.chmod)
- return fs->op.chmod(path, mode);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.chmod)
+ return fs->op.chmod(path, mode);
+ else
+ return -ENOSYS;
}
static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
- int valid, struct fuse_file_info *fi)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct stat buf;
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- fuse_prepare_interrupt(f, req, &d);
- err = 0;
- if (!err && (valid & FUSE_SET_ATTR_MODE))
- err = fuse_fs_chmod(f->fs, path, attr->st_mode);
- if (!err && (valid & (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID))) {
- uid_t uid =
- (valid & FUSE_SET_ATTR_UID) ? attr->st_uid : (uid_t) -1;
- gid_t gid =
- (valid & FUSE_SET_ATTR_GID) ? attr->st_gid : (gid_t) -1;
- err = fuse_fs_chown(f->fs, path, uid, gid);
- }
- if (!err && (valid & FUSE_SET_ATTR_SIZE)) {
- if (fi)
- err = fuse_fs_ftruncate(f->fs, path, attr->st_size, fi);
- else
- err = fuse_fs_truncate(f->fs, path, attr->st_size);
- }
- if (!err && (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) ==
- (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) {
- struct timespec tv[2];
- tv[0].tv_sec = attr->st_atime;
- tv[0].tv_nsec = ST_ATIM_NSEC(attr);
- tv[1].tv_sec = attr->st_mtime;
- tv[1].tv_nsec = ST_MTIM_NSEC(attr);
- err = fuse_fs_utimens(f->fs, path, tv);
- }
- if (!err)
- err = fuse_fs_getattr(f->fs, path, &buf);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- if (!err) {
- if (f->conf.auto_cache) {
- pthread_mutex_lock(&f->lock);
- update_stat(get_node(f, ino), &buf);
- pthread_mutex_unlock(&f->lock);
- }
- set_stat(f, ino, &buf);
- fuse_reply_attr(req, &buf, f->conf.attr_timeout);
- } else
- reply_err(req, err);
+ int valid, struct fuse_file_info *fi)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct stat buf;
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ fuse_prepare_interrupt(f, req, &d);
+ err = 0;
+ if (!err && (valid & FUSE_SET_ATTR_MODE))
+ err = fuse_fs_chmod(f->fs, path, attr->st_mode);
+ if (!err && (valid & (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID))) {
+ uid_t uid = (valid & FUSE_SET_ATTR_UID) ?
+ attr->st_uid : (uid_t) -1;
+ gid_t gid = (valid & FUSE_SET_ATTR_GID) ?
+ attr->st_gid : (gid_t) -1;
+ err = fuse_fs_chown(f->fs, path, uid, gid);
+ }
+ if (!err && (valid & FUSE_SET_ATTR_SIZE)) {
+ if (fi)
+ err = fuse_fs_ftruncate(f->fs, path,
+ attr->st_size, fi);
+ else
+ err = fuse_fs_truncate(f->fs, path,
+ attr->st_size);
+ }
+ if (!err &&
+ (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) ==
+ (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) {
+ struct timespec tv[2];
+ tv[0].tv_sec = attr->st_atime;
+ tv[0].tv_nsec = ST_ATIM_NSEC(attr);
+ tv[1].tv_sec = attr->st_mtime;
+ tv[1].tv_nsec = ST_MTIM_NSEC(attr);
+ err = fuse_fs_utimens(f->fs, path, tv);
+ }
+ if (!err)
+ err = fuse_fs_getattr(f->fs, path, &buf);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ if (!err) {
+ if (f->conf.auto_cache) {
+ pthread_mutex_lock(&f->lock);
+ update_stat(get_node(f, ino), &buf);
+ pthread_mutex_unlock(&f->lock);
+ }
+ set_stat(f, ino, &buf);
+ fuse_reply_attr(req, &buf, f->conf.attr_timeout);
+ } else
+ reply_err(req, err);
}
static void fuse_lib_access(fuse_req_t req, fuse_ino_t ino, int mask)
{
- struct fuse *f = req_fuse_prepare(req);
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "ACCESS %s 0%o\n", path, mask);
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_access(f->fs, path, mask);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_err(req, err);
+ struct fuse *f = req_fuse_prepare(req);
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "ACCESS %s 0%o\n", path, mask);
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_access(f->fs, path, mask);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_err(req, err);
}
static void fuse_lib_readlink(fuse_req_t req, fuse_ino_t ino)
{
- struct fuse *f = req_fuse_prepare(req);
- char linkname[PATH_MAX + 1];
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_readlink(f->fs, path, linkname, sizeof(linkname));
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- if (!err) {
- linkname[PATH_MAX] = '\0';
- fuse_reply_readlink(req, linkname);
- } else
- reply_err(req, err);
+ struct fuse *f = req_fuse_prepare(req);
+ char linkname[PATH_MAX + 1];
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_readlink(f->fs, path, linkname, sizeof(linkname));
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ if (!err) {
+ linkname[PATH_MAX] = '\0';
+ fuse_reply_readlink(req, linkname);
+ } else
+ reply_err(req, err);
}
static void fuse_lib_mknod(fuse_req_t req, fuse_ino_t parent, const char *name,
- mode_t mode, dev_t rdev)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_entry_param e;
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path_name(f, parent, name);
- if (path) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "MKNOD %s\n", path);
- fuse_prepare_interrupt(f, req, &d);
- err = -ENOSYS;
- if (S_ISREG(mode)) {
- struct fuse_file_info fi;
-
- memset(&fi, 0, sizeof(fi));
- fi.flags = O_CREAT | O_EXCL | O_WRONLY;
- err = fuse_fs_create(f->fs, path, mode, &fi);
- if (!err) {
- err = lookup_path(f, parent, name, path, &e, &fi);
- fuse_fs_release(f->fs, path, &fi);
- }
- }
- if (err == -ENOSYS) {
- err = fuse_fs_mknod(f->fs, path, mode, rdev);
- if (!err)
- err = lookup_path(f, parent, name, path, &e, NULL);
- }
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_entry(req, &e, err);
+ mode_t mode, dev_t rdev)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_entry_param e;
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path_name(f, parent, name);
+ if (path) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "MKNOD %s\n", path);
+ fuse_prepare_interrupt(f, req, &d);
+ err = -ENOSYS;
+ if (S_ISREG(mode)) {
+ struct fuse_file_info fi;
+
+ memset(&fi, 0, sizeof(fi));
+ fi.flags = O_CREAT | O_EXCL | O_WRONLY;
+ err = fuse_fs_create(f->fs, path, mode, &fi);
+ if (!err) {
+ err = lookup_path(f, parent, name, path, &e,
+ &fi);
+ fuse_fs_release(f->fs, path, &fi);
+ }
+ }
+ if (err == -ENOSYS) {
+ err = fuse_fs_mknod(f->fs, path, mode, rdev);
+ if (!err)
+ err = lookup_path(f, parent, name, path, &e,
+ NULL);
+ }
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_entry(req, &e, err);
}
static void fuse_lib_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name,
- mode_t mode)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_entry_param e;
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path_name(f, parent, name);
- if (path != NULL) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "MKDIR %s\n", path);
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_mkdir(f->fs, path, mode);
- if (!err)
- err = lookup_path(f, parent, name, path, &e, NULL);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_entry(req, &e, err);
+ mode_t mode)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_entry_param e;
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path_name(f, parent, name);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "MKDIR %s\n", path);
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_mkdir(f->fs, path, mode);
+ if (!err)
+ err = lookup_path(f, parent, name, path, &e, NULL);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_entry(req, &e, err);
}
static void fuse_lib_unlink(fuse_req_t req, fuse_ino_t parent,
- const char *name)
-{
- struct fuse *f = req_fuse_prepare(req);
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_wrlock(&f->tree_lock);
- path = get_path_name(f, parent, name);
- if (path != NULL) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "UNLINK %s\n", path);
- fuse_prepare_interrupt(f, req, &d);
- if (!f->conf.hard_remove && is_open(f, parent, name))
- err = hide_node(f, path, parent, name);
- else {
- err = fuse_fs_unlink(f->fs, path);
- if (!err)
- remove_node(f, parent, name);
- }
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_err(req, err);
+ const char *name)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_wrlock(&f->tree_lock);
+ path = get_path_name(f, parent, name);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "UNLINK %s\n", path);
+ fuse_prepare_interrupt(f, req, &d);
+ if (!f->conf.hard_remove && is_open(f, parent, name))
+ err = hide_node(f, path, parent, name);
+ else {
+ err = fuse_fs_unlink(f->fs, path);
+ if (!err)
+ remove_node(f, parent, name);
+ }
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_err(req, err);
}
static void fuse_lib_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name)
{
- struct fuse *f = req_fuse_prepare(req);
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_wrlock(&f->tree_lock);
- path = get_path_name(f, parent, name);
- if (path != NULL) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "RMDIR %s\n", path);
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_rmdir(f->fs, path);
- fuse_finish_interrupt(f, req, &d);
- if (!err)
- remove_node(f, parent, name);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_err(req, err);
+ struct fuse *f = req_fuse_prepare(req);
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_wrlock(&f->tree_lock);
+ path = get_path_name(f, parent, name);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "RMDIR %s\n", path);
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_rmdir(f->fs, path);
+ fuse_finish_interrupt(f, req, &d);
+ if (!err)
+ remove_node(f, parent, name);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_err(req, err);
}
static void fuse_lib_symlink(fuse_req_t req, const char *linkname,
- fuse_ino_t parent, const char *name)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_entry_param e;
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path_name(f, parent, name);
- if (path != NULL) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "SYMLINK %s\n", path);
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_symlink(f->fs, linkname, path);
- if (!err)
- err = lookup_path(f, parent, name, path, &e, NULL);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_entry(req, &e, err);
+ fuse_ino_t parent, const char *name)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_entry_param e;
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path_name(f, parent, name);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "SYMLINK %s\n", path);
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_symlink(f->fs, linkname, path);
+ if (!err)
+ err = lookup_path(f, parent, name, path, &e, NULL);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_entry(req, &e, err);
}
static void fuse_lib_rename(fuse_req_t req, fuse_ino_t olddir,
- const char *oldname, fuse_ino_t newdir,
- const char *newname)
-{
- struct fuse *f = req_fuse_prepare(req);
- char *oldpath;
- char *newpath;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_wrlock(&f->tree_lock);
- oldpath = get_path_name(f, olddir, oldname);
- if (oldpath != NULL) {
- newpath = get_path_name(f, newdir, newname);
- if (newpath != NULL) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "RENAME %s -> %s\n", oldpath, newpath);
- err = 0;
- fuse_prepare_interrupt(f, req, &d);
- if (!f->conf.hard_remove && is_open(f, newdir, newname))
- err = hide_node(f, newpath, newdir, newname);
- if (!err) {
- err = fuse_fs_rename(f->fs, oldpath, newpath);
- if (!err)
- err = rename_node(f, olddir, oldname, newdir, newname, 0);
- }
- fuse_finish_interrupt(f, req, &d);
- free(newpath);
- }
- free(oldpath);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_err(req, err);
+ const char *oldname, fuse_ino_t newdir,
+ const char *newname)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ char *oldpath;
+ char *newpath;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_wrlock(&f->tree_lock);
+ oldpath = get_path_name(f, olddir, oldname);
+ if (oldpath != NULL) {
+ newpath = get_path_name(f, newdir, newname);
+ if (newpath != NULL) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "RENAME %s -> %s\n", oldpath,
+ newpath);
+ err = 0;
+ fuse_prepare_interrupt(f, req, &d);
+ if (!f->conf.hard_remove && is_open(f, newdir, newname))
+ err = hide_node(f, newpath, newdir, newname);
+ if (!err) {
+ err = fuse_fs_rename(f->fs, oldpath, newpath);
+ if (!err)
+ err = rename_node(f, olddir, oldname,
+ newdir, newname, 0);
+ }
+ fuse_finish_interrupt(f, req, &d);
+ free(newpath);
+ }
+ free(oldpath);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_err(req, err);
}
static void fuse_lib_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
- const char *newname)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_entry_param e;
- char *oldpath;
- char *newpath;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- oldpath = get_path(f, ino);
- if (oldpath != NULL) {
- newpath = get_path_name(f, newparent, newname);
- if (newpath != NULL) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "LINK %s\n", newpath);
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_link(f->fs, oldpath, newpath);
- if (!err)
- err = lookup_path(f, newparent, newname, newpath, &e, NULL);
- fuse_finish_interrupt(f, req, &d);
- free(newpath);
- }
- free(oldpath);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_entry(req, &e, err);
+ const char *newname)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_entry_param e;
+ char *oldpath;
+ char *newpath;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ oldpath = get_path(f, ino);
+ if (oldpath != NULL) {
+ newpath = get_path_name(f, newparent, newname);
+ if (newpath != NULL) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "LINK %s\n", newpath);
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_link(f->fs, oldpath, newpath);
+ if (!err)
+ err = lookup_path(f, newparent, newname,
+ newpath, &e, NULL);
+ fuse_finish_interrupt(f, req, &d);
+ free(newpath);
+ }
+ free(oldpath);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_entry(req, &e, err);
}
static void fuse_do_release(struct fuse *f, fuse_ino_t ino, const char *path,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct node *node;
- int unlink_hidden = 0;
+ struct node *node;
+ int unlink_hidden = 0;
- fuse_fs_release(f->fs, path ? path : "-", fi);
+ fuse_fs_release(f->fs, path ? path : "-", fi);
- pthread_mutex_lock(&f->lock);
- node = get_node(f, ino);
- assert(node->open_count > 0);
- --node->open_count;
- if (node->is_hidden && !node->open_count) {
- unlink_hidden = 1;
- node->is_hidden = 0;
- }
- pthread_mutex_unlock(&f->lock);
+ pthread_mutex_lock(&f->lock);
+ node = get_node(f, ino);
+ assert(node->open_count > 0);
+ --node->open_count;
+ if (node->is_hidden && !node->open_count) {
+ unlink_hidden = 1;
+ node->is_hidden = 0;
+ }
+ pthread_mutex_unlock(&f->lock);
- if(unlink_hidden && path)
- fuse_fs_unlink(f->fs, path);
+ if(unlink_hidden && path)
+ fuse_fs_unlink(f->fs, path);
}
static void fuse_lib_create(fuse_req_t req, fuse_ino_t parent,
- const char *name, mode_t mode,
- struct fuse_file_info *fi)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_intr_data d;
- struct fuse_entry_param e;
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path_name(f, parent, name);
- if (path) {
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_create(f->fs, path, mode, fi);
- if (!err) {
- err = lookup_path(f, parent, name, path, &e, fi);
- if (err)
- fuse_fs_release(f->fs, path, fi);
- else if (!S_ISREG(e.attr.st_mode)) {
- err = -EIO;
- fuse_fs_release(f->fs, path, fi);
- forget_node(f, e.ino, 1);
- } else {
- if (f->conf.direct_io)
- fi->direct_io = 1;
- if (f->conf.kernel_cache)
- fi->keep_cache = 1;
-
- }
- }
- fuse_finish_interrupt(f, req, &d);
- }
- if (!err) {
- pthread_mutex_lock(&f->lock);
- get_node(f, e.ino)->open_count++;
- pthread_mutex_unlock(&f->lock);
- if (fuse_reply_create(req, &e, fi) == -ENOENT) {
- /* The open syscall was interrupted, so it must be cancelled */
- fuse_prepare_interrupt(f, req, &d);
- fuse_do_release(f, e.ino, path, fi);
- fuse_finish_interrupt(f, req, &d);
- forget_node(f, e.ino, 1);
- } else if (f->conf.debug) {
- fprintf(stderr, " CREATE[%llu] flags: 0x%x %s\n",
- (unsigned long long) fi->fh, fi->flags, path);
- }
- } else
- reply_err(req, err);
-
- if (path)
- free(path);
-
- pthread_rwlock_unlock(&f->tree_lock);
+ const char *name, mode_t mode,
+ struct fuse_file_info *fi)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_intr_data d;
+ struct fuse_entry_param e;
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path_name(f, parent, name);
+ if (path) {
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_create(f->fs, path, mode, fi);
+ if (!err) {
+ err = lookup_path(f, parent, name, path, &e, fi);
+ if (err)
+ fuse_fs_release(f->fs, path, fi);
+ else if (!S_ISREG(e.attr.st_mode)) {
+ err = -EIO;
+ fuse_fs_release(f->fs, path, fi);
+ forget_node(f, e.ino, 1);
+ } else {
+ if (f->conf.direct_io)
+ fi->direct_io = 1;
+ if (f->conf.kernel_cache)
+ fi->keep_cache = 1;
+
+ }
+ }
+ fuse_finish_interrupt(f, req, &d);
+ }
+ if (!err) {
+ pthread_mutex_lock(&f->lock);
+ get_node(f, e.ino)->open_count++;
+ pthread_mutex_unlock(&f->lock);
+ if (fuse_reply_create(req, &e, fi) == -ENOENT) {
+ /* The open syscall was interrupted, so it
+ must be cancelled */
+ fuse_prepare_interrupt(f, req, &d);
+ fuse_do_release(f, e.ino, path, fi);
+ fuse_finish_interrupt(f, req, &d);
+ forget_node(f, e.ino, 1);
+ } else if (f->conf.debug) {
+ fprintf(stderr, " CREATE[%llu] flags: 0x%x %s\n",
+ (unsigned long long) fi->fh, fi->flags, path);
+ }
+ } else
+ reply_err(req, err);
+
+ if (path)
+ free(path);
+
+ pthread_rwlock_unlock(&f->tree_lock);
}
static double diff_timespec(const struct timespec *t1,
- const struct timespec *t2)
+ const struct timespec *t2)
{
- return (t1->tv_sec - t2->tv_sec) +
- ((double) t1->tv_nsec - (double) t2->tv_nsec) / 1000000000.0;
+ return (t1->tv_sec - t2->tv_sec) +
+ ((double) t1->tv_nsec - (double) t2->tv_nsec) / 1000000000.0;
}
static void open_auto_cache(struct fuse *f, fuse_ino_t ino, const char *path,
- struct fuse_file_info *fi)
-{
- struct node *node;
-
- pthread_mutex_lock(&f->lock);
- node = get_node(f, ino);
- if (node->cache_valid) {
- struct timespec now;
-
- curr_time(&now);
- if (diff_timespec(&now, &node->stat_updated) > f->conf.ac_attr_timeout) {
- struct stat stbuf;
- int err;
- pthread_mutex_unlock(&f->lock);
- err = fuse_fs_fgetattr(f->fs, path, &stbuf, fi);
- pthread_mutex_lock(&f->lock);
- if (!err)
- update_stat(node, &stbuf);
- else
- node->cache_valid = 0;
- }
- }
- if (node->cache_valid)
- fi->keep_cache = 1;
-
- node->cache_valid = 1;
- pthread_mutex_unlock(&f->lock);
+ struct fuse_file_info *fi)
+{
+ struct node *node;
+
+ pthread_mutex_lock(&f->lock);
+ node = get_node(f, ino);
+ if (node->cache_valid) {
+ struct timespec now;
+
+ curr_time(&now);
+ if (diff_timespec(&now, &node->stat_updated) >
+ f->conf.ac_attr_timeout) {
+ struct stat stbuf;
+ int err;
+ pthread_mutex_unlock(&f->lock);
+ err = fuse_fs_fgetattr(f->fs, path, &stbuf, fi);
+ pthread_mutex_lock(&f->lock);
+ if (!err)
+ update_stat(node, &stbuf);
+ else
+ node->cache_valid = 0;
+ }
+ }
+ if (node->cache_valid)
+ fi->keep_cache = 1;
+
+ node->cache_valid = 1;
+ pthread_mutex_unlock(&f->lock);
}
static void fuse_lib_open(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_intr_data d;
- char *path = NULL;
- int err = 0;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path) {
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_open(f->fs, path, fi);
- if (!err) {
- if (f->conf.direct_io)
- fi->direct_io = 1;
- if (f->conf.kernel_cache)
- fi->keep_cache = 1;
-
- if (f->conf.auto_cache)
- open_auto_cache(f, ino, path, fi);
- }
- fuse_finish_interrupt(f, req, &d);
- }
- if (!err) {
- pthread_mutex_lock(&f->lock);
- get_node(f, ino)->open_count++;
- pthread_mutex_unlock(&f->lock);
- if (fuse_reply_open(req, fi) == -ENOENT) {
- /* The open syscall was interrupted, so it must be cancelled */
- fuse_prepare_interrupt(f, req, &d);
- fuse_do_release(f, ino, path, fi);
- fuse_finish_interrupt(f, req, &d);
- } else if (f->conf.debug) {
- fprintf(stderr, "OPEN[%llu] flags: 0x%x %s\n",
- (unsigned long long) fi->fh, fi->flags, path);
- }
- } else
- reply_err(req, err);
-
- if (path)
- free(path);
- pthread_rwlock_unlock(&f->tree_lock);
+ struct fuse_file_info *fi)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_intr_data d;
+ char *path = NULL;
+ int err = 0;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path) {
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_open(f->fs, path, fi);
+ if (!err) {
+ if (f->conf.direct_io)
+ fi->direct_io = 1;
+ if (f->conf.kernel_cache)
+ fi->keep_cache = 1;
+
+ if (f->conf.auto_cache)
+ open_auto_cache(f, ino, path, fi);
+ }
+ fuse_finish_interrupt(f, req, &d);
+ }
+ if (!err) {
+ pthread_mutex_lock(&f->lock);
+ get_node(f, ino)->open_count++;
+ pthread_mutex_unlock(&f->lock);
+ if (fuse_reply_open(req, fi) == -ENOENT) {
+ /* The open syscall was interrupted, so it
+ must be cancelled */
+ fuse_prepare_interrupt(f, req, &d);
+ fuse_do_release(f, ino, path, fi);
+ fuse_finish_interrupt(f, req, &d);
+ } else if (f->conf.debug) {
+ fprintf(stderr, "OPEN[%llu] flags: 0x%x %s\n",
+ (unsigned long long) fi->fh, fi->flags, path);
+ }
+ } else
+ reply_err(req, err);
+
+ if (path)
+ free(path);
+ pthread_rwlock_unlock(&f->tree_lock);
}
static void fuse_lib_read(fuse_req_t req, fuse_ino_t ino, size_t size,
- off_t off, struct fuse_file_info *fi)
-{
- struct fuse *f = req_fuse_prepare(req);
- char *path;
- char *buf;
- int res;
-
- buf = (char *) malloc(size);
- if (buf == NULL) {
- reply_err(req, -ENOMEM);
- return;
- }
-
- res = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "READ[%llu] %lu bytes from %llu\n",
- (unsigned long long) fi->fh, (unsigned long) size,
- (unsigned long long) off);
-
- fuse_prepare_interrupt(f, req, &d);
- res = fuse_fs_read(f->fs, path, buf, size, off, fi);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
-
- if (res >= 0) {
- if (f->conf.debug)
- fprintf(stderr, " READ[%llu] %u bytes\n",
- (unsigned long long)fi->fh, res);
- if ((size_t) res > size)
- fprintf(stderr, "fuse: read too many bytes");
- fuse_reply_buf(req, buf, res);
- } else
- reply_err(req, res);
-
- free(buf);
+ off_t off, struct fuse_file_info *fi)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ char *path;
+ char *buf;
+ int res;
+
+ buf = (char *) malloc(size);
+ if (buf == NULL) {
+ reply_err(req, -ENOMEM);
+ return;
+ }
+
+ res = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "READ[%llu] %lu bytes from %llu\n",
+ (unsigned long long) fi->fh,
+ (unsigned long) size, (unsigned long long) off);
+
+ fuse_prepare_interrupt(f, req, &d);
+ res = fuse_fs_read(f->fs, path, buf, size, off, fi);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+
+ if (res >= 0) {
+ if (f->conf.debug)
+ fprintf(stderr, " READ[%llu] %u bytes\n",
+ (unsigned long long)fi->fh, res);
+ if ((size_t) res > size)
+ fprintf(stderr, "fuse: read too many bytes");
+ fuse_reply_buf(req, buf, res);
+ } else
+ reply_err(req, res);
+
+ free(buf);
}
static void fuse_lib_write(fuse_req_t req, fuse_ino_t ino, const char *buf,
- size_t size, off_t off, struct fuse_file_info *fi)
-{
- struct fuse *f = req_fuse_prepare(req);
- char *path;
- int res;
-
- res = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "WRITE%s[%llu] %lu bytes to %llu\n",
- fi->writepage ? "PAGE" : "", (unsigned long long) fi->fh,
- (unsigned long) size, (unsigned long long) off);
-
- fuse_prepare_interrupt(f, req, &d);
- res = fuse_fs_write(f->fs, path, buf, size, off, fi);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
-
- if (res >= 0) {
- if (f->conf.debug)
- fprintf(stderr, " WRITE%s[%llu] %u bytes\n",
- fi->writepage ? "PAGE" : "", (unsigned long long) fi->fh,
- res);
- if ((size_t) res > size)
- fprintf(stderr, "fuse: wrote too many bytes");
- fuse_reply_write(req, res);
- } else
- reply_err(req, res);
+ size_t size, off_t off, struct fuse_file_info *fi)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ char *path;
+ int res;
+
+ res = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "WRITE%s[%llu] %lu bytes to %llu\n",
+ fi->writepage ? "PAGE" : "",
+ (unsigned long long) fi->fh,
+ (unsigned long) size, (unsigned long long) off);
+
+ fuse_prepare_interrupt(f, req, &d);
+ res = fuse_fs_write(f->fs, path, buf, size, off, fi);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+
+ if (res >= 0) {
+ if (f->conf.debug)
+ fprintf(stderr, " WRITE%s[%llu] %u bytes\n",
+ fi->writepage ? "PAGE" : "",
+ (unsigned long long) fi->fh, res);
+ if ((size_t) res > size)
+ fprintf(stderr, "fuse: wrote too many bytes");
+ fuse_reply_write(req, res);
+ } else
+ reply_err(req, res);
}
static void fuse_lib_fsync(fuse_req_t req, fuse_ino_t ino, int datasync,
- struct fuse_file_info *fi)
-{
- struct fuse *f = req_fuse_prepare(req);
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "FSYNC[%llu]\n", (unsigned long long) fi->fh);
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_fsync(f->fs, path, datasync, fi);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_err(req, err);
+ struct fuse_file_info *fi)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "FSYNC[%llu]\n",
+ (unsigned long long) fi->fh);
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_fsync(f->fs, path, datasync, fi);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_err(req, err);
}
static struct fuse_dh *get_dirhandle(const struct fuse_file_info *llfi,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct fuse_dh *dh = (struct fuse_dh *) (uintptr_t) llfi->fh;
- memset(fi, 0, sizeof(struct fuse_file_info));
- fi->fh = dh->fh;
- fi->fh_old = dh->fh;
- return dh;
+ struct fuse_dh *dh = (struct fuse_dh *) (uintptr_t) llfi->fh;
+ memset(fi, 0, sizeof(struct fuse_file_info));
+ fi->fh = dh->fh;
+ fi->fh_old = dh->fh;
+ return dh;
}
static void fuse_lib_opendir(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *llfi)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_intr_data d;
- struct fuse_dh *dh;
- struct fuse_file_info fi;
- char *path;
- int err;
-
- dh = (struct fuse_dh *) malloc(sizeof(struct fuse_dh));
- if (dh == NULL) {
- reply_err(req, -ENOMEM);
- return;
- }
- memset(dh, 0, sizeof(struct fuse_dh));
- dh->fuse = f;
- dh->contents = NULL;
- dh->len = 0;
- dh->filled = 0;
- dh->nodeid = ino;
- fuse_mutex_init(&dh->lock);
-
- llfi->fh = (uintptr_t) dh;
-
- memset(&fi, 0, sizeof(fi));
- fi.flags = llfi->flags;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_opendir(f->fs, path, &fi);
- fuse_finish_interrupt(f, req, &d);
- dh->fh = fi.fh;
- }
- if (!err) {
- if (fuse_reply_open(req, llfi) == -ENOENT) {
- /* The opendir syscall was interrupted, so it must be cancelled */
- fuse_prepare_interrupt(f, req, &d);
- fuse_fs_releasedir(f->fs, path, &fi);
- fuse_finish_interrupt(f, req, &d);
- pthread_mutex_destroy(&dh->lock);
- free(dh);
- }
- } else {
- reply_err(req, err);
- free(dh);
- }
- free(path);
- pthread_rwlock_unlock(&f->tree_lock);
+ struct fuse_file_info *llfi)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_intr_data d;
+ struct fuse_dh *dh;
+ struct fuse_file_info fi;
+ char *path;
+ int err;
+
+ dh = (struct fuse_dh *) malloc(sizeof(struct fuse_dh));
+ if (dh == NULL) {
+ reply_err(req, -ENOMEM);
+ return;
+ }
+ memset(dh, 0, sizeof(struct fuse_dh));
+ dh->fuse = f;
+ dh->contents = NULL;
+ dh->len = 0;
+ dh->filled = 0;
+ dh->nodeid = ino;
+ fuse_mutex_init(&dh->lock);
+
+ llfi->fh = (uintptr_t) dh;
+
+ memset(&fi, 0, sizeof(fi));
+ fi.flags = llfi->flags;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_opendir(f->fs, path, &fi);
+ fuse_finish_interrupt(f, req, &d);
+ dh->fh = fi.fh;
+ }
+ if (!err) {
+ if (fuse_reply_open(req, llfi) == -ENOENT) {
+ /* The opendir syscall was interrupted, so it
+ must be cancelled */
+ fuse_prepare_interrupt(f, req, &d);
+ fuse_fs_releasedir(f->fs, path, &fi);
+ fuse_finish_interrupt(f, req, &d);
+ pthread_mutex_destroy(&dh->lock);
+ free(dh);
+ }
+ } else {
+ reply_err(req, err);
+ free(dh);
+ }
+ free(path);
+ pthread_rwlock_unlock(&f->tree_lock);
}
static int extend_contents(struct fuse_dh *dh, unsigned minsize)
{
- if (minsize > dh->size) {
- char *newptr;
- unsigned newsize = dh->size;
- if (!newsize)
- newsize = 1024;
- while (newsize < minsize)
- newsize *= 2;
-
- newptr = (char *) realloc(dh->contents, newsize);
- if (!newptr) {
- dh->error = -ENOMEM;
- return -1;
- }
- dh->contents = newptr;
- dh->size = newsize;
- }
- return 0;
+ if (minsize > dh->size) {
+ char *newptr;
+ unsigned newsize = dh->size;
+ if (!newsize)
+ newsize = 1024;
+ while (newsize < minsize)
+ newsize *= 2;
+
+ newptr = (char *) realloc(dh->contents, newsize);
+ if (!newptr) {
+ dh->error = -ENOMEM;
+ return -1;
+ }
+ dh->contents = newptr;
+ dh->size = newsize;
+ }
+ return 0;
}
static int fill_dir(void *dh_, const char *name, const struct stat *statp,
- off_t off)
-{
- struct fuse_dh *dh = (struct fuse_dh *) dh_;
- struct stat stbuf;
- size_t newlen;
-
- if (statp)
- stbuf = *statp;
- else {
- memset(&stbuf, 0, sizeof(stbuf));
- stbuf.st_ino = FUSE_UNKNOWN_INO;
- }
-
- if (!dh->fuse->conf.use_ino) {
- stbuf.st_ino = FUSE_UNKNOWN_INO;
- if (dh->fuse->conf.readdir_ino) {
- struct node *node;
- pthread_mutex_lock(&dh->fuse->lock);
- node = lookup_node(dh->fuse, dh->nodeid, name);
- if (node)
- stbuf.st_ino = (ino_t) node->nodeid;
- pthread_mutex_unlock(&dh->fuse->lock);
- }
- }
-
- if (off) {
- if (extend_contents(dh, dh->needlen) == -1)
- return 1;
-
- dh->filled = 0;
- newlen = dh->len + fuse_add_direntry(dh->req, dh->contents + dh->len,
- dh->needlen - dh->len, name,
- &stbuf, off);
- if (newlen > dh->needlen)
- return 1;
- } else {
- newlen = dh->len + fuse_add_direntry(dh->req, NULL, 0, name, NULL, 0);
- if (extend_contents(dh, newlen) == -1)
- return 1;
-
- fuse_add_direntry(dh->req, dh->contents + dh->len, dh->size - dh->len,
- name, &stbuf, newlen);
- }
- dh->len = newlen;
- return 0;
+ off_t off)
+{
+ struct fuse_dh *dh = (struct fuse_dh *) dh_;
+ struct stat stbuf;
+ size_t newlen;
+
+ if (statp)
+ stbuf = *statp;
+ else {
+ memset(&stbuf, 0, sizeof(stbuf));
+ stbuf.st_ino = FUSE_UNKNOWN_INO;
+ }
+
+ if (!dh->fuse->conf.use_ino) {
+ stbuf.st_ino = FUSE_UNKNOWN_INO;
+ if (dh->fuse->conf.readdir_ino) {
+ struct node *node;
+ pthread_mutex_lock(&dh->fuse->lock);
+ node = lookup_node(dh->fuse, dh->nodeid, name);
+ if (node)
+ stbuf.st_ino = (ino_t) node->nodeid;
+ pthread_mutex_unlock(&dh->fuse->lock);
+ }
+ }
+
+ if (off) {
+ if (extend_contents(dh, dh->needlen) == -1)
+ return 1;
+
+ dh->filled = 0;
+ newlen = dh->len +
+ fuse_add_direntry(dh->req, dh->contents + dh->len,
+ dh->needlen - dh->len, name,
+ &stbuf, off);
+ if (newlen > dh->needlen)
+ return 1;
+ } else {
+ newlen = dh->len +
+ fuse_add_direntry(dh->req, NULL, 0, name, NULL, 0);
+ if (extend_contents(dh, newlen) == -1)
+ return 1;
+
+ fuse_add_direntry(dh->req, dh->contents + dh->len,
+ dh->size - dh->len, name, &stbuf, newlen);
+ }
+ dh->len = newlen;
+ return 0;
}
static int readdir_fill(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
- size_t size, off_t off, struct fuse_dh *dh,
- struct fuse_file_info *fi)
-{
- int err = -ENOENT;
- char *path;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
-
- dh->len = 0;
- dh->error = 0;
- dh->needlen = size;
- dh->filled = 1;
- dh->req = req;
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_readdir(f->fs, path, dh, fill_dir, off, fi);
- fuse_finish_interrupt(f, req, &d);
- dh->req = NULL;
- if (!err)
- err = dh->error;
- if (err)
- dh->filled = 0;
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- return err;
+ size_t size, off_t off, struct fuse_dh *dh,
+ struct fuse_file_info *fi)
+{
+ int err = -ENOENT;
+ char *path;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+
+ dh->len = 0;
+ dh->error = 0;
+ dh->needlen = size;
+ dh->filled = 1;
+ dh->req = req;
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_readdir(f->fs, path, dh, fill_dir, off, fi);
+ fuse_finish_interrupt(f, req, &d);
+ dh->req = NULL;
+ if (!err)
+ err = dh->error;
+ if (err)
+ dh->filled = 0;
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ return err;
}
static void fuse_lib_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
- off_t off, struct fuse_file_info *llfi)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_file_info fi;
- struct fuse_dh *dh = get_dirhandle(llfi, &fi);
-
- pthread_mutex_lock(&dh->lock);
- /* According to SUS, directory contents need to be refreshed on
- rewinddir() */
- if (!off)
- dh->filled = 0;
-
- if (!dh->filled) {
- int err = readdir_fill(f, req, ino, size, off, dh, &fi);
- if (err) {
- reply_err(req, err);
- goto out;
- }
- }
- if (dh->filled) {
- if (off < dh->len) {
- if (off + size > dh->len)
- size = dh->len - off;
- } else
- size = 0;
- } else {
- size = dh->len;
- off = 0;
- }
- fuse_reply_buf(req, dh->contents + off, size);
- out:
- pthread_mutex_unlock(&dh->lock);
+ off_t off, struct fuse_file_info *llfi)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_file_info fi;
+ struct fuse_dh *dh = get_dirhandle(llfi, &fi);
+
+ pthread_mutex_lock(&dh->lock);
+ /* According to SUS, directory contents need to be refreshed on
+ rewinddir() */
+ if (!off)
+ dh->filled = 0;
+
+ if (!dh->filled) {
+ int err = readdir_fill(f, req, ino, size, off, dh, &fi);
+ if (err) {
+ reply_err(req, err);
+ goto out;
+ }
+ }
+ if (dh->filled) {
+ if (off < dh->len) {
+ if (off + size > dh->len)
+ size = dh->len - off;
+ } else
+ size = 0;
+ } else {
+ size = dh->len;
+ off = 0;
+ }
+ fuse_reply_buf(req, dh->contents + off, size);
+out:
+ pthread_mutex_unlock(&dh->lock);
}
static void fuse_lib_releasedir(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *llfi)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_intr_data d;
- struct fuse_file_info fi;
- struct fuse_dh *dh = get_dirhandle(llfi, &fi);
- char *path;
-
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- fuse_prepare_interrupt(f, req, &d);
- fuse_fs_releasedir(f->fs, path ? path : "-", &fi);
- fuse_finish_interrupt(f, req, &d);
- if (path)
- free(path);
- pthread_rwlock_unlock(&f->tree_lock);
- pthread_mutex_lock(&dh->lock);
- pthread_mutex_unlock(&dh->lock);
- pthread_mutex_destroy(&dh->lock);
- free(dh->contents);
- free(dh);
- reply_err(req, 0);
+ struct fuse_file_info *llfi)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_intr_data d;
+ struct fuse_file_info fi;
+ struct fuse_dh *dh = get_dirhandle(llfi, &fi);
+ char *path;
+
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ fuse_prepare_interrupt(f, req, &d);
+ fuse_fs_releasedir(f->fs, path ? path : "-", &fi);
+ fuse_finish_interrupt(f, req, &d);
+ if (path)
+ free(path);
+ pthread_rwlock_unlock(&f->tree_lock);
+ pthread_mutex_lock(&dh->lock);
+ pthread_mutex_unlock(&dh->lock);
+ pthread_mutex_destroy(&dh->lock);
+ free(dh->contents);
+ free(dh);
+ reply_err(req, 0);
}
static void fuse_lib_fsyncdir(fuse_req_t req, fuse_ino_t ino, int datasync,
- struct fuse_file_info *llfi)
+ struct fuse_file_info *llfi)
{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_file_info fi;
- char *path;
- int err;
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_file_info fi;
+ char *path;
+ int err;
- get_dirhandle(llfi, &fi);
+ get_dirhandle(llfi, &fi);
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_fsyncdir(f->fs, path, datasync, &fi);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_err(req, err);
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_fsyncdir(f->fs, path, datasync, &fi);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_err(req, err);
}
static void fuse_lib_statfs(fuse_req_t req, fuse_ino_t ino)
{
- struct fuse *f = req_fuse_prepare(req);
- struct statvfs buf;
- char *path;
- int err;
-
- memset(&buf, 0, sizeof(buf));
- pthread_rwlock_rdlock(&f->tree_lock);
- if (!ino) {
- err = -ENOMEM;
- path = strdup("/");
- } else {
- err = -ENOENT;
- path = get_path(f, ino);
- }
- if (path) {
- struct fuse_intr_data d;
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_statfs(f->fs, path, &buf);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
-
- if (!err)
- fuse_reply_statfs(req, &buf);
- else
- reply_err(req, err);
+ struct fuse *f = req_fuse_prepare(req);
+ struct statvfs buf;
+ char *path;
+ int err;
+
+ memset(&buf, 0, sizeof(buf));
+ pthread_rwlock_rdlock(&f->tree_lock);
+ if (!ino) {
+ err = -ENOMEM;
+ path = strdup("/");
+ } else {
+ err = -ENOENT;
+ path = get_path(f, ino);
+ }
+ if (path) {
+ struct fuse_intr_data d;
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_statfs(f->fs, path, &buf);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+
+ if (!err)
+ fuse_reply_statfs(req, &buf);
+ else
+ reply_err(req, err);
}
static void fuse_lib_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
- const char *value, size_t size, int flags)
-{
- struct fuse *f = req_fuse_prepare(req);
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_setxattr(f->fs, path, name, value, size, flags);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_err(req, err);
+ const char *value, size_t size, int flags)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_setxattr(f->fs, path, name, value, size, flags);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_err(req, err);
}
static int common_getxattr(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
- const char *name, char *value, size_t size)
+ const char *name, char *value, size_t size)
{
- int err;
- char *path;
+ int err;
+ char *path;
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_getxattr(f->fs, path, name, value, size);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- return err;
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_getxattr(f->fs, path, name, value, size);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ return err;
}
static void fuse_lib_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
- size_t size)
-{
- struct fuse *f = req_fuse_prepare(req);
- int res;
-
- if (size) {
- char *value = (char *) malloc(size);
- if (value == NULL) {
- reply_err(req, -ENOMEM);
- return;
- }
- res = common_getxattr(f, req, ino, name, value, size);
- if (res > 0)
- fuse_reply_buf(req, value, res);
- else
- reply_err(req, res);
- free(value);
- } else {
- res = common_getxattr(f, req, ino, name, NULL, 0);
- if (res >= 0)
- fuse_reply_xattr(req, res);
- else
- reply_err(req, res);
- }
+ size_t size)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ int res;
+
+ if (size) {
+ char *value = (char *) malloc(size);
+ if (value == NULL) {
+ reply_err(req, -ENOMEM);
+ return;
+ }
+ res = common_getxattr(f, req, ino, name, value, size);
+ if (res > 0)
+ fuse_reply_buf(req, value, res);
+ else
+ reply_err(req, res);
+ free(value);
+ } else {
+ res = common_getxattr(f, req, ino, name, NULL, 0);
+ if (res >= 0)
+ fuse_reply_xattr(req, res);
+ else
+ reply_err(req, res);
+ }
}
static int common_listxattr(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
- char *list, size_t size)
+ char *list, size_t size)
{
- char *path;
- int err;
+ char *path;
+ int err;
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_listxattr(f->fs, path, list, size);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- return err;
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_listxattr(f->fs, path, list, size);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ return err;
}
static void fuse_lib_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
{
- struct fuse *f = req_fuse_prepare(req);
- int res;
-
- if (size) {
- char *list = (char *) malloc(size);
- if (list == NULL) {
- reply_err(req, -ENOMEM);
- return;
- }
- res = common_listxattr(f, req, ino, list, size);
- if (res > 0)
- fuse_reply_buf(req, list, res);
- else
- reply_err(req, res);
- free(list);
- } else {
- res = common_listxattr(f, req, ino, NULL, 0);
- if (res >= 0)
- fuse_reply_xattr(req, res);
- else
- reply_err(req, res);
- }
+ struct fuse *f = req_fuse_prepare(req);
+ int res;
+
+ if (size) {
+ char *list = (char *) malloc(size);
+ if (list == NULL) {
+ reply_err(req, -ENOMEM);
+ return;
+ }
+ res = common_listxattr(f, req, ino, list, size);
+ if (res > 0)
+ fuse_reply_buf(req, list, res);
+ else
+ reply_err(req, res);
+ free(list);
+ } else {
+ res = common_listxattr(f, req, ino, NULL, 0);
+ if (res >= 0)
+ fuse_reply_xattr(req, res);
+ else
+ reply_err(req, res);
+ }
}
static void fuse_lib_removexattr(fuse_req_t req, fuse_ino_t ino,
- const char *name)
-{
- struct fuse *f = req_fuse_prepare(req);
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_removexattr(f->fs, path, name);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_err(req, err);
+ const char *name)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_removexattr(f->fs, path, name);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_err(req, err);
}
static struct lock *locks_conflict(struct node *node, const struct lock *lock)
{
- struct lock *l;
+ struct lock *l;
- for (l = node->locks; l; l = l->next)
- if (l->owner != lock->owner &&
- lock->start <= l->end && l->start <= lock->end &&
- (l->type == F_WRLCK || lock->type == F_WRLCK))
- break;
+ for (l = node->locks; l; l = l->next)
+ if (l->owner != lock->owner &&
+ lock->start <= l->end && l->start <= lock->end &&
+ (l->type == F_WRLCK || lock->type == F_WRLCK))
+ break;
- return l;
+ return l;
}
static void delete_lock(struct lock **lockp)
{
- struct lock *l = *lockp;
- *lockp = l->next;
- free(l);
+ struct lock *l = *lockp;
+ *lockp = l->next;
+ free(l);
}
static void insert_lock(struct lock **pos, struct lock *lock)
{
- lock->next = *pos;
- *pos = lock;
+ lock->next = *pos;
+ *pos = lock;
}
static int locks_insert(struct node *node, struct lock *lock)
{
- struct lock **lp;
- struct lock *newl1 = NULL;
- struct lock *newl2 = NULL;
-
- if (lock->type != F_UNLCK || lock->start != 0 || lock->end != OFFSET_MAX) {
- newl1 = malloc(sizeof(struct lock));
- newl2 = malloc(sizeof(struct lock));
-
- if (!newl1 || !newl2) {
- free(newl1);
- free(newl2);
- return -ENOLCK;
- }
- }
-
- for (lp = &node->locks; *lp;) {
- struct lock *l = *lp;
- if (l->owner != lock->owner)
- goto skip;
-
- if (lock->type == l->type) {
- if (l->end < lock->start - 1)
- goto skip;
- if (lock->end < l->start - 1)
- break;
- if (l->start <= lock->start && lock->end <= l->end)
- goto out;
- if (l->start < lock->start)
- lock->start = l->start;
- if (lock->end < l->end)
- lock->end = l->end;
- goto delete;
- } else {
- if (l->end < lock->start)
- goto skip;
- if (lock->end < l->start)
- break;
- if (lock->start <= l->start && l->end <= lock->end)
- goto delete;
- if (l->end <= lock->end) {
- l->end = lock->start - 1;
- goto skip;
- }
- if (lock->start <= l->start) {
- l->start = lock->end + 1;
- break;
- }
- *newl2 = *l;
- newl2->start = lock->end + 1;
- l->end = lock->start - 1;
- insert_lock(&l->next, newl2);
- newl2 = NULL;
- }
- skip:
- lp = &l->next;
- continue;
-
- delete:
- delete_lock(lp);
- }
- if (lock->type != F_UNLCK) {
- *newl1 = *lock;
- insert_lock(lp, newl1);
- newl1 = NULL;
- }
+ struct lock **lp;
+ struct lock *newl1 = NULL;
+ struct lock *newl2 = NULL;
+
+ if (lock->type != F_UNLCK || lock->start != 0 ||
+ lock->end != OFFSET_MAX) {
+ newl1 = malloc(sizeof(struct lock));
+ newl2 = malloc(sizeof(struct lock));
+
+ if (!newl1 || !newl2) {
+ free(newl1);
+ free(newl2);
+ return -ENOLCK;
+ }
+ }
+
+ for (lp = &node->locks; *lp;) {
+ struct lock *l = *lp;
+ if (l->owner != lock->owner)
+ goto skip;
+
+ if (lock->type == l->type) {
+ if (l->end < lock->start - 1)
+ goto skip;
+ if (lock->end < l->start - 1)
+ break;
+ if (l->start <= lock->start && lock->end <= l->end)
+ goto out;
+ if (l->start < lock->start)
+ lock->start = l->start;
+ if (lock->end < l->end)
+ lock->end = l->end;
+ goto delete;
+ } else {
+ if (l->end < lock->start)
+ goto skip;
+ if (lock->end < l->start)
+ break;
+ if (lock->start <= l->start && l->end <= lock->end)
+ goto delete;
+ if (l->end <= lock->end) {
+ l->end = lock->start - 1;
+ goto skip;
+ }
+ if (lock->start <= l->start) {
+ l->start = lock->end + 1;
+ break;
+ }
+ *newl2 = *l;
+ newl2->start = lock->end + 1;
+ l->end = lock->start - 1;
+ insert_lock(&l->next, newl2);
+ newl2 = NULL;
+ }
+ skip:
+ lp = &l->next;
+ continue;
+
+ delete:
+ delete_lock(lp);
+ }
+ if (lock->type != F_UNLCK) {
+ *newl1 = *lock;
+ insert_lock(lp, newl1);
+ newl1 = NULL;
+ }
out:
- free(newl1);
- free(newl2);
- return 0;
+ free(newl1);
+ free(newl2);
+ return 0;
}
static void flock_to_lock(struct flock *flock, struct lock *lock)
{
- memset(lock, 0, sizeof(struct lock));
- lock->type = flock->l_type;
- lock->start = flock->l_start;
- lock->end = flock->l_len ? flock->l_start + flock->l_len - 1 : OFFSET_MAX;
- lock->pid = flock->l_pid;
+ memset(lock, 0, sizeof(struct lock));
+ lock->type = flock->l_type;
+ lock->start = flock->l_start;
+ lock->end =
+ flock->l_len ? flock->l_start + flock->l_len - 1 : OFFSET_MAX;
+ lock->pid = flock->l_pid;
}
static void lock_to_flock(struct lock *lock, struct flock *flock)
{
- flock->l_type = lock->type;
- flock->l_start = lock->start;
- flock->l_len = (lock->end == OFFSET_MAX) ? 0 : lock->end - lock->start + 1;
- flock->l_pid = lock->pid;
+ flock->l_type = lock->type;
+ flock->l_start = lock->start;
+ flock->l_len =
+ (lock->end == OFFSET_MAX) ? 0 : lock->end - lock->start + 1;
+ flock->l_pid = lock->pid;
}
static int fuse_flush_common(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
- const char *path, struct fuse_file_info *fi)
-{
- struct fuse_intr_data d;
- struct flock lock;
- struct lock l;
- int err;
- int errlock;
-
- fuse_prepare_interrupt(f, req, &d);
- memset(&lock, 0, sizeof(lock));
- lock.l_type = F_UNLCK;
- lock.l_whence = SEEK_SET;
- err = fuse_fs_flush(f->fs, path, fi);
- errlock = fuse_fs_lock(f->fs, path, fi, F_SETLK, &lock);
- fuse_finish_interrupt(f, req, &d);
-
- if (errlock != -ENOSYS) {
- flock_to_lock(&lock, &l);
- l.owner = fi->lock_owner;
- pthread_mutex_lock(&f->lock);
- locks_insert(get_node(f, ino), &l);
- pthread_mutex_unlock(&f->lock);
-
- /* if op.lock() is defined FLUSH is needed regardless of op.flush() */
- if (err == -ENOSYS)
- err = 0;
- }
- return err;
+ const char *path, struct fuse_file_info *fi)
+{
+ struct fuse_intr_data d;
+ struct flock lock;
+ struct lock l;
+ int err;
+ int errlock;
+
+ fuse_prepare_interrupt(f, req, &d);
+ memset(&lock, 0, sizeof(lock));
+ lock.l_type = F_UNLCK;
+ lock.l_whence = SEEK_SET;
+ err = fuse_fs_flush(f->fs, path, fi);
+ errlock = fuse_fs_lock(f->fs, path, fi, F_SETLK, &lock);
+ fuse_finish_interrupt(f, req, &d);
+
+ if (errlock != -ENOSYS) {
+ flock_to_lock(&lock, &l);
+ l.owner = fi->lock_owner;
+ pthread_mutex_lock(&f->lock);
+ locks_insert(get_node(f, ino), &l);
+ pthread_mutex_unlock(&f->lock);
+
+ /* if op.lock() is defined FLUSH is needed regardless
+ of op.flush() */
+ if (err == -ENOSYS)
+ err = 0;
+ }
+ return err;
}
static void fuse_lib_release(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_intr_data d;
- char *path;
- int err = 0;
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_intr_data d;
+ char *path;
+ int err = 0;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (f->conf.debug)
- fprintf(stderr, "RELEASE%s[%llu] flags: 0x%x\n",
- fi->flush ? "+FLUSH" : "",
- (unsigned long long) fi->fh, fi->flags);
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (f->conf.debug)
+ fprintf(stderr, "RELEASE%s[%llu] flags: 0x%x\n",
+ fi->flush ? "+FLUSH" : "",
+ (unsigned long long) fi->fh, fi->flags);
- if (fi->flush) {
- err = fuse_flush_common(f, req, ino, path, fi);
- if (err == -ENOSYS)
- err = 0;
- }
+ if (fi->flush) {
+ err = fuse_flush_common(f, req, ino, path, fi);
+ if (err == -ENOSYS)
+ err = 0;
+ }
- fuse_prepare_interrupt(f, req, &d);
- fuse_do_release(f, ino, path, fi);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- pthread_rwlock_unlock(&f->tree_lock);
+ fuse_prepare_interrupt(f, req, &d);
+ fuse_do_release(f, ino, path, fi);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ pthread_rwlock_unlock(&f->tree_lock);
- reply_err(req, err);
+ reply_err(req, err);
}
static void fuse_lib_flush(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct fuse *f = req_fuse_prepare(req);
- char *path;
- int err;
+ struct fuse *f = req_fuse_prepare(req);
+ char *path;
+ int err;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path && f->conf.debug)
- fprintf(stderr, "FLUSH[%llu]\n", (unsigned long long) fi->fh);
- err = fuse_flush_common(f, req, ino, path, fi);
- free(path);
- pthread_rwlock_unlock(&f->tree_lock);
- reply_err(req, err);
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path && f->conf.debug)
+ fprintf(stderr, "FLUSH[%llu]\n", (unsigned long long) fi->fh);
+ err = fuse_flush_common(f, req, ino, path, fi);
+ free(path);
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_err(req, err);
}
static int fuse_lock_common(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi, struct flock *lock,
- int cmd)
-{
- struct fuse *f = req_fuse_prepare(req);
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_lock(f->fs, path, fi, cmd, lock);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- return err;
+ struct fuse_file_info *fi, struct flock *lock,
+ int cmd)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_lock(f->fs, path, fi, cmd, lock);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ return err;
}
static void fuse_lib_getlk(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi, struct flock *lock)
-{
- int err;
- struct lock l;
- struct lock *conflict;
- struct fuse *f = req_fuse(req);
-
- flock_to_lock(lock, &l);
- l.owner = fi->lock_owner;
- pthread_mutex_lock(&f->lock);
- conflict = locks_conflict(get_node(f, ino), &l);
- if (conflict)
- lock_to_flock(conflict, lock);
- pthread_mutex_unlock(&f->lock);
- if (!conflict)
- err = fuse_lock_common(req, ino, fi, lock, F_GETLK);
- else
- err = 0;
-
- if (!err)
- fuse_reply_lock(req, lock);
- else
- reply_err(req, err);
+ struct fuse_file_info *fi, struct flock *lock)
+{
+ int err;
+ struct lock l;
+ struct lock *conflict;
+ struct fuse *f = req_fuse(req);
+
+ flock_to_lock(lock, &l);
+ l.owner = fi->lock_owner;
+ pthread_mutex_lock(&f->lock);
+ conflict = locks_conflict(get_node(f, ino), &l);
+ if (conflict)
+ lock_to_flock(conflict, lock);
+ pthread_mutex_unlock(&f->lock);
+ if (!conflict)
+ err = fuse_lock_common(req, ino, fi, lock, F_GETLK);
+ else
+ err = 0;
+
+ if (!err)
+ fuse_reply_lock(req, lock);
+ else
+ reply_err(req, err);
}
static void fuse_lib_setlk(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi, struct flock *lock,
- int sleep)
-{
- int err = fuse_lock_common(req, ino, fi, lock, sleep ? F_SETLKW : F_SETLK);
- if (!err) {
- struct fuse *f = req_fuse(req);
- struct lock l;
- flock_to_lock(lock, &l);
- l.owner = fi->lock_owner;
- pthread_mutex_lock(&f->lock);
- locks_insert(get_node(f, ino), &l);
- pthread_mutex_unlock(&f->lock);
- }
- reply_err(req, err);
+ struct fuse_file_info *fi, struct flock *lock,
+ int sleep)
+{
+ int err = fuse_lock_common(req, ino, fi, lock,
+ sleep ? F_SETLKW : F_SETLK);
+ if (!err) {
+ struct fuse *f = req_fuse(req);
+ struct lock l;
+ flock_to_lock(lock, &l);
+ l.owner = fi->lock_owner;
+ pthread_mutex_lock(&f->lock);
+ locks_insert(get_node(f, ino), &l);
+ pthread_mutex_unlock(&f->lock);
+ }
+ reply_err(req, err);
}
static void fuse_lib_bmap(fuse_req_t req, fuse_ino_t ino, size_t blocksize,
- uint64_t idx)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_intr_data d;
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_bmap(f->fs, path, blocksize, &idx);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- if (!err)
- fuse_reply_bmap(req, idx);
- else
- reply_err(req, err);
+ uint64_t idx)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_intr_data d;
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_bmap(f->fs, path, blocksize, &idx);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ if (!err)
+ fuse_reply_bmap(req, idx);
+ else
+ reply_err(req, err);
}
static struct fuse_lowlevel_ops fuse_path_ops = {
- .init = fuse_lib_init,
- .destroy = fuse_lib_destroy,
- .lookup = fuse_lib_lookup,
- .forget = fuse_lib_forget,
- .getattr = fuse_lib_getattr,
- .setattr = fuse_lib_setattr,
- .access = fuse_lib_access,
- .readlink = fuse_lib_readlink,
- .mknod = fuse_lib_mknod,
- .mkdir = fuse_lib_mkdir,
- .unlink = fuse_lib_unlink,
- .rmdir = fuse_lib_rmdir,
- .symlink = fuse_lib_symlink,
- .rename = fuse_lib_rename,
- .link = fuse_lib_link,
- .create = fuse_lib_create,
- .open = fuse_lib_open,
- .read = fuse_lib_read,
- .write = fuse_lib_write,
- .flush = fuse_lib_flush,
- .release = fuse_lib_release,
- .fsync = fuse_lib_fsync,
- .opendir = fuse_lib_opendir,
- .readdir = fuse_lib_readdir,
- .releasedir = fuse_lib_releasedir,
- .fsyncdir = fuse_lib_fsyncdir,
- .statfs = fuse_lib_statfs,
- .setxattr = fuse_lib_setxattr,
- .getxattr = fuse_lib_getxattr,
- .listxattr = fuse_lib_listxattr,
- .removexattr = fuse_lib_removexattr,
- .getlk = fuse_lib_getlk,
- .setlk = fuse_lib_setlk,
- .bmap = fuse_lib_bmap,
+ .init = fuse_lib_init,
+ .destroy = fuse_lib_destroy,
+ .lookup = fuse_lib_lookup,
+ .forget = fuse_lib_forget,
+ .getattr = fuse_lib_getattr,
+ .setattr = fuse_lib_setattr,
+ .access = fuse_lib_access,
+ .readlink = fuse_lib_readlink,
+ .mknod = fuse_lib_mknod,
+ .mkdir = fuse_lib_mkdir,
+ .unlink = fuse_lib_unlink,
+ .rmdir = fuse_lib_rmdir,
+ .symlink = fuse_lib_symlink,
+ .rename = fuse_lib_rename,
+ .link = fuse_lib_link,
+ .create = fuse_lib_create,
+ .open = fuse_lib_open,
+ .read = fuse_lib_read,
+ .write = fuse_lib_write,
+ .flush = fuse_lib_flush,
+ .release = fuse_lib_release,
+ .fsync = fuse_lib_fsync,
+ .opendir = fuse_lib_opendir,
+ .readdir = fuse_lib_readdir,
+ .releasedir = fuse_lib_releasedir,
+ .fsyncdir = fuse_lib_fsyncdir,
+ .statfs = fuse_lib_statfs,
+ .setxattr = fuse_lib_setxattr,
+ .getxattr = fuse_lib_getxattr,
+ .listxattr = fuse_lib_listxattr,
+ .removexattr = fuse_lib_removexattr,
+ .getlk = fuse_lib_getlk,
+ .setlk = fuse_lib_setlk,
+ .bmap = fuse_lib_bmap,
};
static void free_cmd(struct fuse_cmd *cmd)
{
- free(cmd->buf);
- free(cmd);
+ free(cmd->buf);
+ free(cmd);
}
void fuse_process_cmd(struct fuse *f, struct fuse_cmd *cmd)
{
- fuse_session_process(f->se, cmd->buf, cmd->buflen, cmd->ch);
- free_cmd(cmd);
+ fuse_session_process(f->se, cmd->buf, cmd->buflen, cmd->ch);
+ free_cmd(cmd);
}
int fuse_exited(struct fuse *f)
{
- return fuse_session_exited(f->se);
+ return fuse_session_exited(f->se);
}
struct fuse_session *fuse_get_session(struct fuse *f)
{
- return f->se;
+ return f->se;
}
static struct fuse_cmd *fuse_alloc_cmd(size_t bufsize)
{
- struct fuse_cmd *cmd = (struct fuse_cmd *) malloc(sizeof(*cmd));
- if (cmd == NULL) {
- fprintf(stderr, "fuse: failed to allocate cmd\n");
- return NULL;
- }
- cmd->buf = (char *) malloc(bufsize);
- if (cmd->buf == NULL) {
- fprintf(stderr, "fuse: failed to allocate read buffer\n");
- free(cmd);
- return NULL;
- }
- return cmd;
+ struct fuse_cmd *cmd = (struct fuse_cmd *) malloc(sizeof(*cmd));
+ if (cmd == NULL) {
+ fprintf(stderr, "fuse: failed to allocate cmd\n");
+ return NULL;
+ }
+ cmd->buf = (char *) malloc(bufsize);
+ if (cmd->buf == NULL) {
+ fprintf(stderr, "fuse: failed to allocate read buffer\n");
+ free(cmd);
+ return NULL;
+ }
+ return cmd;
}
struct fuse_cmd *fuse_read_cmd(struct fuse *f)
{
- struct fuse_chan *ch = fuse_session_next_chan(f->se, NULL);
- size_t bufsize = fuse_chan_bufsize(ch);
- struct fuse_cmd *cmd = fuse_alloc_cmd(bufsize);
- if (cmd != NULL) {
- int res = fuse_chan_recv(&ch, cmd->buf, bufsize);
- if (res <= 0) {
- free_cmd(cmd);
- if (res < 0 && res != -EINTR && res != -EAGAIN)
- fuse_exit(f);
- return NULL;
- }
- cmd->buflen = res;
- cmd->ch = ch;
- }
- return cmd;
+ struct fuse_chan *ch = fuse_session_next_chan(f->se, NULL);
+ size_t bufsize = fuse_chan_bufsize(ch);
+ struct fuse_cmd *cmd = fuse_alloc_cmd(bufsize);
+ if (cmd != NULL) {
+ int res = fuse_chan_recv(&ch, cmd->buf, bufsize);
+ if (res <= 0) {
+ free_cmd(cmd);
+ if (res < 0 && res != -EINTR && res != -EAGAIN)
+ fuse_exit(f);
+ return NULL;
+ }
+ cmd->buflen = res;
+ cmd->ch = ch;
+ }
+ return cmd;
}
int fuse_loop(struct fuse *f)
{
- if (f)
- return fuse_session_loop(f->se);
- else
- return -1;
+ if (f)
+ return fuse_session_loop(f->se);
+ else
+ return -1;
}
int fuse_invalidate(struct fuse *f, const char *path)
{
- (void) f;
- (void) path;
- return -EINVAL;
+ (void) f;
+ (void) path;
+ return -EINVAL;
}
void fuse_exit(struct fuse *f)
{
- fuse_session_exit(f->se);
+ fuse_session_exit(f->se);
}
struct fuse_context *fuse_get_context(void)
{
- return &fuse_get_context_internal()->ctx;
+ return &fuse_get_context_internal()->ctx;
}
int fuse_interrupted(void)
{
- return fuse_req_interrupted(fuse_get_context_internal()->req);
+ return fuse_req_interrupted(fuse_get_context_internal()->req);
}
void fuse_set_getcontext_func(struct fuse_context *(*func)(void))
{
- (void) func;
- /* no-op */
+ (void) func;
+ /* no-op */
}
enum {
- KEY_HELP,
+ KEY_HELP,
};
#define FUSE_LIB_OPT(t, p, v) { t, offsetof(struct fuse_config, p), v }
static const struct fuse_opt fuse_lib_opts[] = {
- FUSE_OPT_KEY("-h", KEY_HELP),
- FUSE_OPT_KEY("--help", KEY_HELP),
- FUSE_OPT_KEY("debug", FUSE_OPT_KEY_KEEP),
- FUSE_OPT_KEY("-d", FUSE_OPT_KEY_KEEP),
- FUSE_LIB_OPT("debug", debug, 1),
- FUSE_LIB_OPT("-d", debug, 1),
- FUSE_LIB_OPT("hard_remove", hard_remove, 1),
- FUSE_LIB_OPT("use_ino", use_ino, 1),
- FUSE_LIB_OPT("readdir_ino", readdir_ino, 1),
- FUSE_LIB_OPT("direct_io", direct_io, 1),
- FUSE_LIB_OPT("kernel_cache", kernel_cache, 1),
- FUSE_LIB_OPT("auto_cache", auto_cache, 1),
- FUSE_LIB_OPT("noauto_cache", auto_cache, 0),
- FUSE_LIB_OPT("umask=", set_mode, 1),
- FUSE_LIB_OPT("umask=%o", umask, 0),
- FUSE_LIB_OPT("uid=", set_uid, 1),
- FUSE_LIB_OPT("uid=%d", uid, 0),
- FUSE_LIB_OPT("gid=", set_gid, 1),
- FUSE_LIB_OPT("gid=%d", gid, 0),
- FUSE_LIB_OPT("entry_timeout=%lf", entry_timeout, 0),
- FUSE_LIB_OPT("attr_timeout=%lf", attr_timeout, 0),
- FUSE_LIB_OPT("ac_attr_timeout=%lf", ac_attr_timeout, 0),
- FUSE_LIB_OPT("ac_attr_timeout=", ac_attr_timeout_set, 1),
- FUSE_LIB_OPT("negative_timeout=%lf", negative_timeout, 0),
- FUSE_LIB_OPT("intr", intr, 1),
- FUSE_LIB_OPT("intr_signal=%d", intr_signal, 0),
- FUSE_LIB_OPT("modules=%s", modules, 0),
- FUSE_OPT_END
+ FUSE_OPT_KEY("-h", KEY_HELP),
+ FUSE_OPT_KEY("--help", KEY_HELP),
+ FUSE_OPT_KEY("debug", FUSE_OPT_KEY_KEEP),
+ FUSE_OPT_KEY("-d", FUSE_OPT_KEY_KEEP),
+ FUSE_LIB_OPT("debug", debug, 1),
+ FUSE_LIB_OPT("-d", debug, 1),
+ FUSE_LIB_OPT("hard_remove", hard_remove, 1),
+ FUSE_LIB_OPT("use_ino", use_ino, 1),
+ FUSE_LIB_OPT("readdir_ino", readdir_ino, 1),
+ FUSE_LIB_OPT("direct_io", direct_io, 1),
+ FUSE_LIB_OPT("kernel_cache", kernel_cache, 1),
+ FUSE_LIB_OPT("auto_cache", auto_cache, 1),
+ FUSE_LIB_OPT("noauto_cache", auto_cache, 0),
+ FUSE_LIB_OPT("umask=", set_mode, 1),
+ FUSE_LIB_OPT("umask=%o", umask, 0),
+ FUSE_LIB_OPT("uid=", set_uid, 1),
+ FUSE_LIB_OPT("uid=%d", uid, 0),
+ FUSE_LIB_OPT("gid=", set_gid, 1),
+ FUSE_LIB_OPT("gid=%d", gid, 0),
+ FUSE_LIB_OPT("entry_timeout=%lf", entry_timeout, 0),
+ FUSE_LIB_OPT("attr_timeout=%lf", attr_timeout, 0),
+ FUSE_LIB_OPT("ac_attr_timeout=%lf", ac_attr_timeout, 0),
+ FUSE_LIB_OPT("ac_attr_timeout=", ac_attr_timeout_set, 1),
+ FUSE_LIB_OPT("negative_timeout=%lf", negative_timeout, 0),
+ FUSE_LIB_OPT("intr", intr, 1),
+ FUSE_LIB_OPT("intr_signal=%d", intr_signal, 0),
+ FUSE_LIB_OPT("modules=%s", modules, 0),
+ FUSE_OPT_END
};
static void fuse_lib_help(void)
{
- fprintf(stderr,
-" -o hard_remove immediate removal (don't hide files)\n"
-" -o use_ino let filesystem set inode numbers\n"
-" -o readdir_ino try to fill in d_ino in readdir\n"
-" -o direct_io use direct I/O\n"
-" -o kernel_cache cache files in kernel\n"
-" -o [no]auto_cache enable caching based on modification times\n"
-" -o umask=M set file permissions (octal)\n"
-" -o uid=N set file owner\n"
-" -o gid=N set file group\n"
-" -o entry_timeout=T cache timeout for names (1.0s)\n"
+ fprintf(stderr,
+" -o hard_remove immediate removal (don't hide files)\n"
+" -o use_ino let filesystem set inode numbers\n"
+" -o readdir_ino try to fill in d_ino in readdir\n"
+" -o direct_io use direct I/O\n"
+" -o kernel_cache cache files in kernel\n"
+" -o [no]auto_cache enable caching based on modification times\n"
+" -o umask=M set file permissions (octal)\n"
+" -o uid=N set file owner\n"
+" -o gid=N set file group\n"
+" -o entry_timeout=T cache timeout for names (1.0s)\n"
" -o negative_timeout=T cache timeout for deleted names (0.0s)\n"
-" -o attr_timeout=T cache timeout for attributes (1.0s)\n"
+" -o attr_timeout=T cache timeout for attributes (1.0s)\n"
" -o ac_attr_timeout=T auto cache timeout for attributes (attr_timeout)\n"
-" -o intr allow requests to be interrupted\n"
-" -o intr_signal=NUM signal to send on interrupt (%i)\n"
+" -o intr allow requests to be interrupted\n"
+" -o intr_signal=NUM signal to send on interrupt (%i)\n"
" -o modules=M1[:M2...] names of modules to push onto filesystem stack\n"
"\n", FUSE_DEFAULT_INTR_SIGNAL);
}
static void fuse_lib_help_modules(void)
{
- struct fuse_module *m;
- fprintf(stderr, "\nModule options:\n");
- pthread_mutex_lock(&fuse_context_lock);
- for (m = fuse_modules; m; m = m->next) {
- struct fuse_fs *fs = NULL;
- struct fuse_fs *newfs;
- struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
- if (fuse_opt_add_arg(&args, "") != -1 &&
- fuse_opt_add_arg(&args, "-h") != -1) {
- fprintf(stderr, "\n[%s]\n", m->name);
- newfs = m->factory(&args, &fs);
- assert(newfs == NULL);
- }
- fuse_opt_free_args(&args);
- }
- pthread_mutex_unlock(&fuse_context_lock);
+ struct fuse_module *m;
+ fprintf(stderr, "\nModule options:\n");
+ pthread_mutex_lock(&fuse_context_lock);
+ for (m = fuse_modules; m; m = m->next) {
+ struct fuse_fs *fs = NULL;
+ struct fuse_fs *newfs;
+ struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
+ if (fuse_opt_add_arg(&args, "") != -1 &&
+ fuse_opt_add_arg(&args, "-h") != -1) {
+ fprintf(stderr, "\n[%s]\n", m->name);
+ newfs = m->factory(&args, &fs);
+ assert(newfs == NULL);
+ }
+ fuse_opt_free_args(&args);
+ }
+ pthread_mutex_unlock(&fuse_context_lock);
}
static int fuse_lib_opt_proc(void *data, const char *arg, int key,
- struct fuse_args *outargs)
+ struct fuse_args *outargs)
{
- (void) arg; (void) outargs;
+ (void) arg; (void) outargs;
- if (key == KEY_HELP) {
- struct fuse_config *conf = (struct fuse_config *) data;
- fuse_lib_help();
- conf->help = 1;
- }
+ if (key == KEY_HELP) {
+ struct fuse_config *conf = (struct fuse_config *) data;
+ fuse_lib_help();
+ conf->help = 1;
+ }
- return 1;
+ return 1;
}
int fuse_is_lib_option(const char *opt)
{
- return fuse_lowlevel_is_lib_option(opt) ||
- fuse_opt_match(fuse_lib_opts, opt);
+ return fuse_lowlevel_is_lib_option(opt) ||
+ fuse_opt_match(fuse_lib_opts, opt);
}
static int fuse_init_intr_signal(int signum, int *installed)
{
- struct sigaction old_sa;
+ struct sigaction old_sa;
- if (sigaction(signum, NULL, &old_sa) == -1) {
- perror("fuse: cannot get old signal handler");
- return -1;
- }
+ if (sigaction(signum, NULL, &old_sa) == -1) {
+ perror("fuse: cannot get old signal handler");
+ return -1;
+ }
- if (old_sa.sa_handler == SIG_DFL) {
- struct sigaction sa;
+ if (old_sa.sa_handler == SIG_DFL) {
+ struct sigaction sa;
- memset(&sa, 0, sizeof(struct sigaction));
- sa.sa_handler = fuse_intr_sighandler;
- sigemptyset(&sa.sa_mask);
+ memset(&sa, 0, sizeof(struct sigaction));
+ sa.sa_handler = fuse_intr_sighandler;
+ sigemptyset(&sa.sa_mask);
- if (sigaction(signum, &sa, NULL) == -1) {
- perror("fuse: cannot set interrupt signal handler");
- return -1;
- }
- *installed = 1;
- }
- return 0;
+ if (sigaction(signum, &sa, NULL) == -1) {
+ perror("fuse: cannot set interrupt signal handler");
+ return -1;
+ }
+ *installed = 1;
+ }
+ return 0;
}
static void fuse_restore_intr_signal(int signum)
{
- struct sigaction sa;
+ struct sigaction sa;
- memset(&sa, 0, sizeof(struct sigaction));
- sa.sa_handler = SIG_DFL;
- sigaction(signum, &sa, NULL);
+ memset(&sa, 0, sizeof(struct sigaction));
+ sa.sa_handler = SIG_DFL;
+ sigaction(signum, &sa, NULL);
}
static int fuse_push_module(struct fuse *f, const char *module,
- struct fuse_args *args)
+ struct fuse_args *args)
{
- struct fuse_fs *fs[2] = { f->fs, NULL };
- struct fuse_fs *newfs;
- struct fuse_module *m = fuse_get_module(module);
+ struct fuse_fs *fs[2] = { f->fs, NULL };
+ struct fuse_fs *newfs;
+ struct fuse_module *m = fuse_get_module(module);
- if (!m)
- return -1;
+ if (!m)
+ return -1;
- newfs = m->factory(args, fs);
- if (!newfs) {
- fuse_put_module(m);
- return -1;
- }
- newfs->m = m;
- f->fs = newfs;
- return 0;
+ newfs = m->factory(args, fs);
+ if (!newfs) {
+ fuse_put_module(m);
+ return -1;
+ }
+ newfs->m = m;
+ f->fs = newfs;
+ return 0;
}
struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size,
- void *user_data)
+ void *user_data)
{
- struct fuse_fs *fs;
+ struct fuse_fs *fs;
- if (sizeof(struct fuse_operations) < op_size) {
- fprintf(stderr, "fuse: warning: library too old, some operations may not not work\n");
- op_size = sizeof(struct fuse_operations);
- }
+ if (sizeof(struct fuse_operations) < op_size) {
+ fprintf(stderr, "fuse: warning: library too old, some operations may not not work\n");
+ op_size = sizeof(struct fuse_operations);
+ }
- fs = (struct fuse_fs *) calloc(1, sizeof(struct fuse_fs));
- if (!fs) {
- fprintf(stderr, "fuse: failed to allocate fuse_fs object\n");
- return NULL;
- }
+ fs = (struct fuse_fs *) calloc(1, sizeof(struct fuse_fs));
+ if (!fs) {
+ fprintf(stderr, "fuse: failed to allocate fuse_fs object\n");
+ return NULL;
+ }
- fs->user_data = user_data;
- if (op)
- memcpy(&fs->op, op, op_size);
- return fs;
+ fs->user_data = user_data;
+ if (op)
+ memcpy(&fs->op, op, op_size);
+ return fs;
}
struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args,
- const struct fuse_operations *op,
- size_t op_size, void *user_data, int compat)
-{
- struct fuse *f;
- struct node *root;
- struct fuse_fs *fs;
- struct fuse_lowlevel_ops llop = fuse_path_ops;
-
- if (fuse_create_context_key() == -1)
- goto out;
-
- f = (struct fuse *) calloc(1, sizeof(struct fuse));
- if (f == NULL) {
- fprintf(stderr, "fuse: failed to allocate fuse object\n");
- goto out_delete_context_key;
- }
-
- fs = fuse_fs_new(op, op_size, user_data);
- if (!fs)
- goto out_free;
-
- fs->compat = compat;
- f->fs = fs;
-
- /* Oh f**k, this is ugly! */
- if (!fs->op.lock) {
- llop.getlk = NULL;
- llop.setlk = NULL;
- }
-
- f->conf.entry_timeout = 1.0;
- f->conf.attr_timeout = 1.0;
- f->conf.negative_timeout = 0.0;
- f->conf.intr_signal = FUSE_DEFAULT_INTR_SIGNAL;
-
- if (fuse_opt_parse(args, &f->conf, fuse_lib_opts, fuse_lib_opt_proc) == -1)
- goto out_free_fs;
-
- if (f->conf.modules) {
- char *module;
- char *next;
-
- for (module = f->conf.modules; module; module = next) {
- char *p;
- for (p = module; *p && *p != ':'; p++);
- next = *p ? p + 1 : NULL;
- *p = '\0';
- if (module[0] && fuse_push_module(f, module, args) == -1)
- goto out_free_fs;
- }
- }
-
- if (!f->conf.ac_attr_timeout_set)
- f->conf.ac_attr_timeout = f->conf.attr_timeout;
+ const struct fuse_operations *op,
+ size_t op_size, void *user_data, int compat)
+{
+ struct fuse *f;
+ struct node *root;
+ struct fuse_fs *fs;
+ struct fuse_lowlevel_ops llop = fuse_path_ops;
+
+ if (fuse_create_context_key() == -1)
+ goto out;
+
+ f = (struct fuse *) calloc(1, sizeof(struct fuse));
+ if (f == NULL) {
+ fprintf(stderr, "fuse: failed to allocate fuse object\n");
+ goto out_delete_context_key;
+ }
+
+ fs = fuse_fs_new(op, op_size, user_data);
+ if (!fs)
+ goto out_free;
+
+ fs->compat = compat;
+ f->fs = fs;
+
+ /* Oh f**k, this is ugly! */
+ if (!fs->op.lock) {
+ llop.getlk = NULL;
+ llop.setlk = NULL;
+ }
+
+ f->conf.entry_timeout = 1.0;
+ f->conf.attr_timeout = 1.0;
+ f->conf.negative_timeout = 0.0;
+ f->conf.intr_signal = FUSE_DEFAULT_INTR_SIGNAL;
+
+ if (fuse_opt_parse(args, &f->conf, fuse_lib_opts,
+ fuse_lib_opt_proc) == -1)
+ goto out_free_fs;
+
+ if (f->conf.modules) {
+ char *module;
+ char *next;
+
+ for (module = f->conf.modules; module; module = next) {
+ char *p;
+ for (p = module; *p && *p != ':'; p++);
+ next = *p ? p + 1 : NULL;
+ *p = '\0';
+ if (module[0] &&
+ fuse_push_module(f, module, args) == -1)
+ goto out_free_fs;
+ }
+ }
+
+ if (!f->conf.ac_attr_timeout_set)
+ f->conf.ac_attr_timeout = f->conf.attr_timeout;
#ifdef __FreeBSD__
- /*
- * In FreeBSD, we always use these settings as inode numbers are needed to
- * make getcwd(3) work.
- */
- f->conf.readdir_ino = 1;
+ /*
+ * In FreeBSD, we always use these settings as inode numbers
+ * are needed to make getcwd(3) work.
+ */
+ f->conf.readdir_ino = 1;
#endif
- if (compat && compat <= 25) {
- if (fuse_sync_compat_args(args) == -1)
- goto out_free_fs;
- }
-
- f->se = fuse_lowlevel_new_common(args, &llop, sizeof(llop), f);
- if (f->se == NULL) {
- if (f->conf.help)
- fuse_lib_help_modules();
- goto out_free_fs;
- }
-
- fuse_session_add_chan(f->se, ch);
-
- f->ctr = 0;
- f->generation = 0;
- /* FIXME: Dynamic hash table */
- f->name_table_size = 14057;
- f->name_table = (struct node **)
- calloc(1, sizeof(struct node *) * f->name_table_size);
- if (f->name_table == NULL) {
- fprintf(stderr, "fuse: memory allocation failed\n");
- goto out_free_session;
- }
-
- f->id_table_size = 14057;
- f->id_table = (struct node **)
- calloc(1, sizeof(struct node *) * f->id_table_size);
- if (f->id_table == NULL) {
- fprintf(stderr, "fuse: memory allocation failed\n");
- goto out_free_name_table;
- }
-
- fuse_mutex_init(&f->lock);
- pthread_rwlock_init(&f->tree_lock, NULL);
-
- root = (struct node *) calloc(1, sizeof(struct node));
- if (root == NULL) {
- fprintf(stderr, "fuse: memory allocation failed\n");
- goto out_free_id_table;
- }
-
- root->name = strdup("/");
- if (root->name == NULL) {
- fprintf(stderr, "fuse: memory allocation failed\n");
- goto out_free_root;
- }
-
- if (f->conf.intr &&
- fuse_init_intr_signal(f->conf.intr_signal, &f->intr_installed) == -1)
- goto out_free_root_name;
-
- root->parent = NULL;
- root->nodeid = FUSE_ROOT_ID;
- root->generation = 0;
- root->refctr = 1;
- root->nlookup = 1;
- hash_id(f, root);
-
- return f;
-
- out_free_root_name:
- free(root->name);
- out_free_root:
- free(root);
- out_free_id_table:
- free(f->id_table);
- out_free_name_table:
- free(f->name_table);
- out_free_session:
- fuse_session_destroy(f->se);
- out_free_fs:
- /* Horrible compatibility hack to stop the destructor from being
- called on the filesystem without init being called first */
- fs->op.destroy = NULL;
- fuse_fs_destroy(f->fs);
- free(f->conf.modules);
- out_free:
- free(f);
- out_delete_context_key:
- fuse_delete_context_key();
- out:
- return NULL;
+ if (compat && compat <= 25) {
+ if (fuse_sync_compat_args(args) == -1)
+ goto out_free_fs;
+ }
+
+ f->se = fuse_lowlevel_new_common(args, &llop, sizeof(llop), f);
+ if (f->se == NULL) {
+ if (f->conf.help)
+ fuse_lib_help_modules();
+ goto out_free_fs;
+ }
+
+ fuse_session_add_chan(f->se, ch);
+
+ f->ctr = 0;
+ f->generation = 0;
+ /* FIXME: Dynamic hash table */
+ f->name_table_size = 14057;
+ f->name_table = (struct node **)
+ calloc(1, sizeof(struct node *) * f->name_table_size);
+ if (f->name_table == NULL) {
+ fprintf(stderr, "fuse: memory allocation failed\n");
+ goto out_free_session;
+ }
+
+ f->id_table_size = 14057;
+ f->id_table = (struct node **)
+ calloc(1, sizeof(struct node *) * f->id_table_size);
+ if (f->id_table == NULL) {
+ fprintf(stderr, "fuse: memory allocation failed\n");
+ goto out_free_name_table;
+ }
+
+ fuse_mutex_init(&f->lock);
+ pthread_rwlock_init(&f->tree_lock, NULL);
+
+ root = (struct node *) calloc(1, sizeof(struct node));
+ if (root == NULL) {
+ fprintf(stderr, "fuse: memory allocation failed\n");
+ goto out_free_id_table;
+ }
+
+ root->name = strdup("/");
+ if (root->name == NULL) {
+ fprintf(stderr, "fuse: memory allocation failed\n");
+ goto out_free_root;
+ }
+
+ if (f->conf.intr &&
+ fuse_init_intr_signal(f->conf.intr_signal,
+ &f->intr_installed) == -1)
+ goto out_free_root_name;
+
+ root->parent = NULL;
+ root->nodeid = FUSE_ROOT_ID;
+ root->generation = 0;
+ root->refctr = 1;
+ root->nlookup = 1;
+ hash_id(f, root);
+
+ return f;
+
+out_free_root_name:
+ free(root->name);
+out_free_root:
+ free(root);
+out_free_id_table:
+ free(f->id_table);
+out_free_name_table:
+ free(f->name_table);
+out_free_session:
+ fuse_session_destroy(f->se);
+out_free_fs:
+ /* Horrible compatibility hack to stop the destructor from being
+ called on the filesystem without init being called first */
+ fs->op.destroy = NULL;
+ fuse_fs_destroy(f->fs);
+ free(f->conf.modules);
+out_free:
+ free(f);
+out_delete_context_key:
+ fuse_delete_context_key();
+out:
+ return NULL;
}
struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args,
- const struct fuse_operations *op, size_t op_size,
- void *user_data)
+ const struct fuse_operations *op, size_t op_size,
+ void *user_data)
{
- return fuse_new_common(ch, args, op, op_size, user_data, 0);
+ return fuse_new_common(ch, args, op, op_size, user_data, 0);
}
void fuse_destroy(struct fuse *f)
{
- size_t i;
-
- if (f->conf.intr && f->intr_installed)
- fuse_restore_intr_signal(f->conf.intr_signal);
-
- if (f->fs) {
- struct fuse_context_i *c = fuse_get_context_internal();
-
- memset(c, 0, sizeof(*c));
- c->ctx.fuse = f;
-
- for (i = 0; i < f->id_table_size; i++) {
- struct node *node;
-
- for (node = f->id_table[i]; node != NULL; node = node->id_next) {
- if (node->is_hidden) {
- char *path = get_path(f, node->nodeid);
- if (path) {
- fuse_fs_unlink(f->fs, path);
- free(path);
- }
- }
- }
- }
- }
- for (i = 0; i < f->id_table_size; i++) {
- struct node *node;
- struct node *next;
-
- for (node = f->id_table[i]; node != NULL; node = next) {
- next = node->id_next;
- free_node(node);
- }
- }
- free(f->id_table);
- free(f->name_table);
- pthread_mutex_destroy(&f->lock);
- pthread_rwlock_destroy(&f->tree_lock);
- fuse_session_destroy(f->se);
- free(f->conf.modules);
- free(f);
- fuse_delete_context_key();
+ size_t i;
+
+ if (f->conf.intr && f->intr_installed)
+ fuse_restore_intr_signal(f->conf.intr_signal);
+
+ if (f->fs) {
+ struct fuse_context_i *c = fuse_get_context_internal();
+
+ memset(c, 0, sizeof(*c));
+ c->ctx.fuse = f;
+
+ for (i = 0; i < f->id_table_size; i++) {
+ struct node *node;
+
+ for (node = f->id_table[i]; node != NULL;
+ node = node->id_next) {
+ if (node->is_hidden) {
+ char *path = get_path(f, node->nodeid);
+ if (path) {
+ fuse_fs_unlink(f->fs, path);
+ free(path);
+ }
+ }
+ }
+ }
+ }
+ for (i = 0; i < f->id_table_size; i++) {
+ struct node *node;
+ struct node *next;
+
+ for (node = f->id_table[i]; node != NULL; node = next) {
+ next = node->id_next;
+ free_node(node);
+ }
+ }
+ free(f->id_table);
+ free(f->name_table);
+ pthread_mutex_destroy(&f->lock);
+ pthread_rwlock_destroy(&f->tree_lock);
+ fuse_session_destroy(f->se);
+ free(f->conf.modules);
+ free(f);
+ fuse_delete_context_key();
}
static struct fuse *fuse_new_common_compat25(int fd, struct fuse_args *args,
- const struct fuse_operations *op,
- size_t op_size, int compat)
+ const struct fuse_operations *op,
+ size_t op_size, int compat)
{
- struct fuse *f = NULL;
- struct fuse_chan *ch = fuse_kern_chan_new(fd);
+ struct fuse *f = NULL;
+ struct fuse_chan *ch = fuse_kern_chan_new(fd);
- if (ch)
- f = fuse_new_common(ch, args, op, op_size, NULL, compat);
+ if (ch)
+ f = fuse_new_common(ch, args, op, op_size, NULL, compat);
- return f;
+ return f;
}
/* called with fuse_context_lock held or during initialization (before
main() has been called) */
void fuse_register_module(struct fuse_module *mod)
{
- mod->ctr = 0;
- mod->so = fuse_current_so;
- if (mod->so)
- mod->so->ctr++;
- mod->next = fuse_modules;
- fuse_modules = mod;
+ mod->ctr = 0;
+ mod->so = fuse_current_so;
+ if (mod->so)
+ mod->so->ctr++;
+ mod->next = fuse_modules;
+ fuse_modules = mod;
}
#ifndef __FreeBSD__
static struct fuse *fuse_new_common_compat(int fd, const char *opts,
- const struct fuse_operations *op,
- size_t op_size, int compat)
+ const struct fuse_operations *op,
+ size_t op_size, int compat)
{
- struct fuse *f;
- struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
+ struct fuse *f;
+ struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
- if (fuse_opt_add_arg(&args, "") == -1)
- return NULL;
- if (opts &&
- (fuse_opt_add_arg(&args, "-o") == -1 ||
- fuse_opt_add_arg(&args, opts) == -1)) {
- fuse_opt_free_args(&args);
- return NULL;
- }
- f = fuse_new_common_compat25(fd, &args, op, op_size, compat);
- fuse_opt_free_args(&args);
+ if (fuse_opt_add_arg(&args, "") == -1)
+ return NULL;
+ if (opts &&
+ (fuse_opt_add_arg(&args, "-o") == -1 ||
+ fuse_opt_add_arg(&args, opts) == -1)) {
+ fuse_opt_free_args(&args);
+ return NULL;
+ }
+ f = fuse_new_common_compat25(fd, &args, op, op_size, compat);
+ fuse_opt_free_args(&args);
- return f;
+ return f;
}
struct fuse *fuse_new_compat22(int fd, const char *opts,
- const struct fuse_operations_compat22 *op,
- size_t op_size)
+ const struct fuse_operations_compat22 *op,
+ size_t op_size)
{
- return fuse_new_common_compat(fd, opts, (struct fuse_operations *) op,
- op_size, 22);
+ return fuse_new_common_compat(fd, opts, (struct fuse_operations *) op,
+ op_size, 22);
}
struct fuse *fuse_new_compat2(int fd, const char *opts,
- const struct fuse_operations_compat2 *op)
+ const struct fuse_operations_compat2 *op)
{
- return fuse_new_common_compat(fd, opts, (struct fuse_operations *) op,
- sizeof(struct fuse_operations_compat2), 21);
+ return fuse_new_common_compat(fd, opts, (struct fuse_operations *) op,
+ sizeof(struct fuse_operations_compat2),
+ 21);
}
struct fuse *fuse_new_compat1(int fd, int flags,
- const struct fuse_operations_compat1 *op)
+ const struct fuse_operations_compat1 *op)
{
- const char *opts = NULL;
- if (flags & FUSE_DEBUG_COMPAT1)
- opts = "debug";
- return fuse_new_common_compat(fd, opts, (struct fuse_operations *) op,
- sizeof(struct fuse_operations_compat1), 11);
+ const char *opts = NULL;
+ if (flags & FUSE_DEBUG_COMPAT1)
+ opts = "debug";
+ return fuse_new_common_compat(fd, opts, (struct fuse_operations *) op,
+ sizeof(struct fuse_operations_compat1),
+ 11);
}
FUSE_SYMVER(".symver fuse_exited,__fuse_exited@");
@@ -3300,11 +3339,11 @@ FUSE_SYMVER(".symver fuse_new_compat22,fuse_new@FUSE_2.2");
#endif /* __FreeBSD__ */
struct fuse *fuse_new_compat25(int fd, struct fuse_args *args,
- const struct fuse_operations_compat25 *op,
- size_t op_size)
+ const struct fuse_operations_compat25 *op,
+ size_t op_size)
{
- return fuse_new_common_compat25(fd, args, (struct fuse_operations *) op,
- op_size, 25);
+ return fuse_new_common_compat25(fd, args, (struct fuse_operations *) op,
+ op_size, 25);
}
FUSE_SYMVER(".symver fuse_new_compat25,fuse_new@FUSE_2.5");
diff --git a/lib/fuse_i.h b/lib/fuse_i.h
index 55ce048..ec6e5d6 100644
--- a/lib/fuse_i.h
+++ b/lib/fuse_i.h
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
#include "fuse.h"
@@ -14,22 +14,22 @@ struct fuse_lowlevel_ops;
struct fuse_req;
struct fuse_cmd {
- char *buf;
- size_t buflen;
- struct fuse_chan *ch;
+ char *buf;
+ size_t buflen;
+ struct fuse_chan *ch;
};
struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args,
- const struct fuse_operations *op,
- size_t op_size, void *user_data, int compat);
+ const struct fuse_operations *op,
+ size_t op_size, void *user_data, int compat);
int fuse_sync_compat_args(struct fuse_args *args);
struct fuse_chan *fuse_kern_chan_new(int fd);
struct fuse_session *fuse_lowlevel_new_common(struct fuse_args *args,
- const struct fuse_lowlevel_ops *op,
- size_t op_size, void *userdata);
+ const struct fuse_lowlevel_ops *op,
+ size_t op_size, void *userdata);
void fuse_kern_unmount_compat22(const char *mountpoint);
void fuse_kern_unmount(const char *mountpoint, int fd);
diff --git a/lib/fuse_kern_chan.c b/lib/fuse_kern_chan.c
index 49e88b7..03291c3 100644
--- a/lib/fuse_kern_chan.c
+++ b/lib/fuse_kern_chan.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
#include "fuse_lowlevel.h"
@@ -16,80 +16,80 @@
#include <assert.h>
static int fuse_kern_chan_receive(struct fuse_chan **chp, char *buf,
- size_t size)
+ size_t size)
{
- struct fuse_chan *ch = *chp;
- int err;
- ssize_t res;
- struct fuse_session *se = fuse_chan_session(ch);
- assert(se != NULL);
+ struct fuse_chan *ch = *chp;
+ int err;
+ ssize_t res;
+ struct fuse_session *se = fuse_chan_session(ch);
+ assert(se != NULL);
- restart:
- res = read(fuse_chan_fd(ch), buf, size);
- err = errno;
+restart:
+ res = read(fuse_chan_fd(ch), buf, size);
+ err = errno;
- if (fuse_session_exited(se))
- return 0;
- if (res == -1) {
- /* ENOENT means the operation was interrupted, it's safe
- to restart */
- if (err == ENOENT)
- goto restart;
+ if (fuse_session_exited(se))
+ return 0;
+ if (res == -1) {
+ /* ENOENT means the operation was interrupted, it's safe
+ to restart */
+ if (err == ENOENT)
+ goto restart;
- if (err == ENODEV) {
- fuse_session_exit(se);
- return 0;
- }
- /* Errors occuring during normal operation: EINTR (read
- interrupted), EAGAIN (nonblocking I/O), ENODEV (filesystem
- umounted) */
- if (err != EINTR && err != EAGAIN)
- perror("fuse: reading device");
- return -err;
- }
- if ((size_t) res < sizeof(struct fuse_in_header)) {
- fprintf(stderr, "short read on fuse device\n");
- return -EIO;
- }
- return res;
+ if (err == ENODEV) {
+ fuse_session_exit(se);
+ return 0;
+ }
+ /* Errors occuring during normal operation: EINTR (read
+ interrupted), EAGAIN (nonblocking I/O), ENODEV (filesystem
+ umounted) */
+ if (err != EINTR && err != EAGAIN)
+ perror("fuse: reading device");
+ return -err;
+ }
+ if ((size_t) res < sizeof(struct fuse_in_header)) {
+ fprintf(stderr, "short read on fuse device\n");
+ return -EIO;
+ }
+ return res;
}
static int fuse_kern_chan_send(struct fuse_chan *ch, const struct iovec iov[],
- size_t count)
+ size_t count)
{
- if (iov) {
- ssize_t res = writev(fuse_chan_fd(ch), iov, count);
- int err = errno;
+ if (iov) {
+ ssize_t res = writev(fuse_chan_fd(ch), iov, count);
+ int err = errno;
- if (res == -1) {
- struct fuse_session *se = fuse_chan_session(ch);
+ if (res == -1) {
+ struct fuse_session *se = fuse_chan_session(ch);
- assert(se != NULL);
+ assert(se != NULL);
- /* ENOENT means the operation was interrupted */
- if (!fuse_session_exited(se) && err != ENOENT)
- perror("fuse: writing device");
- return -err;
- }
- }
- return 0;
+ /* ENOENT means the operation was interrupted */
+ if (!fuse_session_exited(se) && err != ENOENT)
+ perror("fuse: writing device");
+ return -err;
+ }
+ }
+ return 0;
}
static void fuse_kern_chan_destroy(struct fuse_chan *ch)
{
- close(fuse_chan_fd(ch));
+ close(fuse_chan_fd(ch));
}
#define MIN_BUFSIZE 0x21000
struct fuse_chan *fuse_kern_chan_new(int fd)
{
- struct fuse_chan_ops op = {
- .receive = fuse_kern_chan_receive,
- .send = fuse_kern_chan_send,
- .destroy = fuse_kern_chan_destroy,
- };
- size_t bufsize = getpagesize() + 0x1000;
- bufsize = bufsize < MIN_BUFSIZE ? MIN_BUFSIZE : bufsize;
- return fuse_chan_new(&op, fd, bufsize, NULL);
+ struct fuse_chan_ops op = {
+ .receive = fuse_kern_chan_receive,
+ .send = fuse_kern_chan_send,
+ .destroy = fuse_kern_chan_destroy,
+ };
+ size_t bufsize = getpagesize() + 0x1000;
+ bufsize = bufsize < MIN_BUFSIZE ? MIN_BUFSIZE : bufsize;
+ return fuse_chan_new(&op, fd, bufsize, NULL);
}
diff --git a/lib/fuse_loop.c b/lib/fuse_loop.c
index f7c17fa..104c5d4 100644
--- a/lib/fuse_loop.c
+++ b/lib/fuse_loop.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
#include "fuse_lowlevel.h"
@@ -14,26 +14,26 @@
int fuse_session_loop(struct fuse_session *se)
{
- int res = 0;
- struct fuse_chan *ch = fuse_session_next_chan(se, NULL);
- size_t bufsize = fuse_chan_bufsize(ch);
- char *buf = (char *) malloc(bufsize);
- if (!buf) {
- fprintf(stderr, "fuse: failed to allocate read buffer\n");
- return -1;
- }
+ int res = 0;
+ struct fuse_chan *ch = fuse_session_next_chan(se, NULL);
+ size_t bufsize = fuse_chan_bufsize(ch);
+ char *buf = (char *) malloc(bufsize);
+ if (!buf) {
+ fprintf(stderr, "fuse: failed to allocate read buffer\n");
+ return -1;
+ }
- while (!fuse_session_exited(se)) {
- struct fuse_chan *tmpch = ch;
- res = fuse_chan_recv(&tmpch, buf, bufsize);
- if (res == -EINTR)
- continue;
- if (res <= 0)
- break;
- fuse_session_process(se, buf, res, tmpch);
- }
+ while (!fuse_session_exited(se)) {
+ struct fuse_chan *tmpch = ch;
+ res = fuse_chan_recv(&tmpch, buf, bufsize);
+ if (res == -EINTR)
+ continue;
+ if (res <= 0)
+ break;
+ fuse_session_process(se, buf, res, tmpch);
+ }
- free(buf);
- fuse_session_reset(se);
- return res < 0 ? -1 : 0;
+ free(buf);
+ fuse_session_reset(se);
+ return res < 0 ? -1 : 0;
}
diff --git a/lib/fuse_loop_mt.c b/lib/fuse_loop_mt.c
index 533d9c3..dba8dbc 100644
--- a/lib/fuse_loop_mt.c
+++ b/lib/fuse_loop_mt.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB.
*/
#include "fuse_lowlevel.h"
@@ -20,202 +20,203 @@
#include <sys/time.h>
struct fuse_worker {
- struct fuse_worker *prev;
- struct fuse_worker *next;
- pthread_t thread_id;
- size_t bufsize;
- char *buf;
- struct fuse_mt *mt;
+ struct fuse_worker *prev;
+ struct fuse_worker *next;
+ pthread_t thread_id;
+ size_t bufsize;
+ char *buf;
+ struct fuse_mt *mt;
};
struct fuse_mt {
- pthread_mutex_t lock;
- int numworker;
- int numavail;
- struct fuse_session *se;
- struct fuse_chan *prevch;
- struct fuse_worker main;
- sem_t finish;
- int exit;
- int error;
+ pthread_mutex_t lock;
+ int numworker;
+ int numavail;
+ struct fuse_session *se;
+ struct fuse_chan *prevch;
+ struct fuse_worker main;
+ sem_t finish;
+ int exit;
+ int error;
};
static void list_add_worker(struct fuse_worker *w, struct fuse_worker *next)
{
- struct fuse_worker *prev = next->prev;
- w->next = next;
- w->prev = prev;
- prev->next = w;
- next->prev = w;
+ struct fuse_worker *prev = next->prev;
+ w->next = next;
+ w->prev = prev;
+ prev->next = w;
+ next->prev = w;
}
static void list_del_worker(struct fuse_worker *w)
{
- struct fuse_worker *prev = w->prev;
- struct fuse_worker *next = w->next;
- prev->next = next;
- next->prev = prev;
+ struct fuse_worker *prev = w->prev;
+ struct fuse_worker *next = w->next;
+ prev->next = next;
+ next->prev = prev;
}
static int fuse_start_thread(struct fuse_mt *mt);
static void *fuse_do_work(void *data)
{
- struct fuse_worker *w = (struct fuse_worker *) data;
- struct fuse_mt *mt = w->mt;
-
- while (!fuse_session_exited(mt->se)) {
- int isforget = 0;
- struct fuse_chan *ch = mt->prevch;
- int res = fuse_chan_recv(&ch, w->buf, w->bufsize);
- if (res == -EINTR)
- continue;
- if (res <= 0) {
- if (res < 0) {
- fuse_session_exit(mt->se);
- mt->error = -1;
- }
- break;
- }
-
- pthread_mutex_lock(&mt->lock);
- if (mt->exit) {
- pthread_mutex_unlock(&mt->lock);
- return NULL;
- }
-
- /*
- * This disgusting hack is needed so that zillions of threads
- * are not created on a burst of FORGET messages
- */
- if (((struct fuse_in_header *) w->buf)->opcode == FUSE_FORGET)
- isforget = 1;
-
- if (!isforget)
- mt->numavail--;
- if (mt->numavail == 0)
- fuse_start_thread(mt);
- pthread_mutex_unlock(&mt->lock);
-
- fuse_session_process(mt->se, w->buf, res, ch);
-
- pthread_mutex_lock(&mt->lock);
- if (!isforget)
- mt->numavail++;
- if (mt->numavail > 10) {
- if (mt->exit) {
- pthread_mutex_unlock(&mt->lock);
- return NULL;
- }
- list_del_worker(w);
- mt->numavail--;
- mt->numworker--;
- pthread_mutex_unlock(&mt->lock);
-
- pthread_detach(w->thread_id);
- free(w->buf);
- free(w);
- return NULL;
- }
- pthread_mutex_unlock(&mt->lock);
- }
-
- sem_post(&mt->finish);
- pause();
-
- return NULL;
+ struct fuse_worker *w = (struct fuse_worker *) data;
+ struct fuse_mt *mt = w->mt;
+
+ while (!fuse_session_exited(mt->se)) {
+ int isforget = 0;
+ struct fuse_chan *ch = mt->prevch;
+ int res = fuse_chan_recv(&ch, w->buf, w->bufsize);
+ if (res == -EINTR)
+ continue;
+ if (res <= 0) {
+ if (res < 0) {
+ fuse_session_exit(mt->se);
+ mt->error = -1;
+ }
+ break;
+ }
+
+ pthread_mutex_lock(&mt->lock);
+ if (mt->exit) {
+ pthread_mutex_unlock(&mt->lock);
+ return NULL;
+ }
+
+ /*
+ * This disgusting hack is needed so that zillions of threads
+ * are not created on a burst of FORGET messages
+ */
+ if (((struct fuse_in_header *) w->buf)->opcode == FUSE_FORGET)
+ isforget = 1;
+
+ if (!isforget)
+ mt->numavail--;
+ if (mt->numavail == 0)
+ fuse_start_thread(mt);
+ pthread_mutex_unlock(&mt->lock);
+
+ fuse_session_process(mt->se, w->buf, res, ch);
+
+ pthread_mutex_lock(&mt->lock);
+ if (!isforget)
+ mt->numavail++;
+ if (mt->numavail > 10) {
+ if (mt->exit) {
+ pthread_mutex_unlock(&mt->lock);
+ return NULL;
+ }
+ list_del_worker(w);
+ mt->numavail--;
+ mt->numworker--;
+ pthread_mutex_unlock(&mt->lock);
+
+ pthread_detach(w->thread_id);
+ free(w->buf);
+ free(w);
+ return NULL;
+ }
+ pthread_mutex_unlock(&mt->lock);
+ }
+
+ sem_post(&mt->finish);
+ pause();
+
+ return NULL;
}
static int fuse_start_thread(struct fuse_mt *mt)
{
- sigset_t oldset;
- sigset_t newset;
- int res;
- struct fuse_worker *w = malloc(sizeof(struct fuse_worker));
- if (!w) {
- fprintf(stderr, "fuse: failed to allocate worker structure\n");
- return -1;
- }
- memset(w, 0, sizeof(struct fuse_worker));
- w->bufsize = fuse_chan_bufsize(mt->prevch);
- w->buf = malloc(w->bufsize);
- w->mt = mt;
- if (!w->buf) {
- fprintf(stderr, "fuse: failed to allocate read buffer\n");
- free(w);
- return -1;
- }
-
- /* Disallow signal reception in worker threads */
- sigemptyset(&newset);
- sigaddset(&newset, SIGTERM);
- sigaddset(&newset, SIGINT);
- sigaddset(&newset, SIGHUP);
- sigaddset(&newset, SIGQUIT);
- pthread_sigmask(SIG_BLOCK, &newset, &oldset);
- res = pthread_create(&w->thread_id, NULL, fuse_do_work, w);
- pthread_sigmask(SIG_SETMASK, &oldset, NULL);
- if (res != 0) {
- fprintf(stderr, "fuse: error creating thread: %s\n", strerror(res));
- free(w->buf);
- free(w);
- return -1;
- }
- list_add_worker(w, &mt->main);
- mt->numavail ++;
- mt->numworker ++;
-
- return 0;
+ sigset_t oldset;
+ sigset_t newset;
+ int res;
+ struct fuse_worker *w = malloc(sizeof(struct fuse_worker));
+ if (!w) {
+ fprintf(stderr, "fuse: failed to allocate worker structure\n");
+ return -1;
+ }
+ memset(w, 0, sizeof(struct fuse_worker));
+ w->bufsize = fuse_chan_bufsize(mt->prevch);
+ w->buf = malloc(w->bufsize);
+ w->mt = mt;
+ if (!w->buf) {
+ fprintf(stderr, "fuse: failed to allocate read buffer\n");
+ free(w);
+ return -1;
+ }
+
+ /* Disallow signal reception in worker threads */
+ sigemptyset(&newset);
+ sigaddset(&newset, SIGTERM);
+ sigaddset(&newset, SIGINT);
+ sigaddset(&newset, SIGHUP);
+ sigaddset(&newset, SIGQUIT);
+ pthread_sigmask(SIG_BLOCK, &newset, &oldset);
+ res = pthread_create(&w->thread_id, NULL, fuse_do_work, w);
+ pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+ if (res != 0) {
+ fprintf(stderr, "fuse: error creating thread: %s\n",
+ strerror(res));
+ free(w->buf);
+ free(w);
+ return -1;
+ }
+ list_add_worker(w, &mt->main);
+ mt->numavail ++;
+ mt->numworker ++;
+
+ return 0;
}
static void fuse_join_worker(struct fuse_mt *mt, struct fuse_worker *w)
{
- pthread_join(w->thread_id, NULL);
- pthread_mutex_lock(&mt->lock);
- list_del_worker(w);
- pthread_mutex_unlock(&mt->lock);
- free(w->buf);
- free(w);
+ pthread_join(w->thread_id, NULL);
+ pthread_mutex_lock(&mt->lock);
+ list_del_worker(w);
+ pthread_mutex_unlock(&mt->lock);
+ free(w->buf);
+ free(w);
}
int fuse_session_loop_mt(struct fuse_session *se)
{
- int err;
- struct fuse_mt mt;
- struct fuse_worker *w;
-
- memset(&mt, 0, sizeof(struct fuse_mt));
- mt.se = se;
- mt.prevch = fuse_session_next_chan(se, NULL);
- mt.error = 0;
- mt.numworker = 0;
- mt.numavail = 0;
- mt.main.thread_id = pthread_self();
- mt.main.prev = mt.main.next = &mt.main;
- sem_init(&mt.finish, 0, 0);
- fuse_mutex_init(&mt.lock);
-
- pthread_mutex_lock(&mt.lock);
- err = fuse_start_thread(&mt);
- pthread_mutex_unlock(&mt.lock);
- if (!err) {
- /* sem_wait() is interruptible */
- while (!fuse_session_exited(se))
- sem_wait(&mt.finish);
-
- for (w = mt.main.next; w != &mt.main; w = w->next)
- pthread_cancel(w->thread_id);
- mt.exit = 1;
- pthread_mutex_unlock(&mt.lock);
-
- while (mt.main.next != &mt.main)
- fuse_join_worker(&mt, mt.main.next);
-
- err = mt.error;
- }
-
- pthread_mutex_destroy(&mt.lock);
- sem_destroy(&mt.finish);
- fuse_session_reset(se);
- return err;
+ int err;
+ struct fuse_mt mt;
+ struct fuse_worker *w;
+
+ memset(&mt, 0, sizeof(struct fuse_mt));
+ mt.se = se;
+ mt.prevch = fuse_session_next_chan(se, NULL);
+ mt.error = 0;
+ mt.numworker = 0;
+ mt.numavail = 0;
+ mt.main.thread_id = pthread_self();
+ mt.main.prev = mt.main.next = &mt.main;
+ sem_init(&mt.finish, 0, 0);
+ fuse_mutex_init(&mt.lock);
+
+ pthread_mutex_lock(&mt.lock);
+ err = fuse_start_thread(&mt);
+ pthread_mutex_unlock(&mt.lock);
+ if (!err) {
+ /* sem_wait() is interruptible */
+ while (!fuse_session_exited(se))
+ sem_wait(&mt.finish);
+
+ for (w = mt.main.next; w != &mt.main; w = w->next)
+ pthread_cancel(w->thread_id);
+ mt.exit = 1;
+ pthread_mutex_unlock(&mt.lock);
+
+ while (mt.main.next != &mt.main)
+ fuse_join_worker(&mt, mt.main.next);
+
+ err = mt.error;
+ }
+
+ pthread_mutex_destroy(&mt.lock);
+ sem_destroy(&mt.finish);
+ fuse_session_reset(se);
+ return err;
}
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
index d39a4a1..5c9dc56 100644
--- a/lib/fuse_lowlevel.c
+++ b/lib/fuse_lowlevel.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
#include "fuse_lowlevel.h"
@@ -28,1225 +28,1234 @@
struct fuse_ll;
struct fuse_req {
- struct fuse_ll *f;
- uint64_t unique;
- int ctr;
- pthread_mutex_t lock;
- struct fuse_ctx ctx;
- struct fuse_chan *ch;
- int interrupted;
- union {
- struct {
- uint64_t unique;
- } i;
- struct {
- fuse_interrupt_func_t func;
- void *data;
- } ni;
- } u;
- struct fuse_req *next;
- struct fuse_req *prev;
+ struct fuse_ll *f;
+ uint64_t unique;
+ int ctr;
+ pthread_mutex_t lock;
+ struct fuse_ctx ctx;
+ struct fuse_chan *ch;
+ int interrupted;
+ union {
+ struct {
+ uint64_t unique;
+ } i;
+ struct {
+ fuse_interrupt_func_t func;
+ void *data;
+ } ni;
+ } u;
+ struct fuse_req *next;
+ struct fuse_req *prev;
};
struct fuse_ll {
- int debug;
- int allow_root;
- struct fuse_lowlevel_ops op;
- int got_init;
- void *userdata;
- uid_t owner;
- struct fuse_conn_info conn;
- struct fuse_req list;
- struct fuse_req interrupts;
- pthread_mutex_t lock;
- int got_destroy;
+ int debug;
+ int allow_root;
+ struct fuse_lowlevel_ops op;
+ int got_init;
+ void *userdata;
+ uid_t owner;
+ struct fuse_conn_info conn;
+ struct fuse_req list;
+ struct fuse_req interrupts;
+ pthread_mutex_t lock;
+ int got_destroy;
};
static void convert_stat(const struct stat *stbuf, struct fuse_attr *attr)
{
- attr->ino = stbuf->st_ino;
- attr->mode = stbuf->st_mode;
- attr->nlink = stbuf->st_nlink;
- attr->uid = stbuf->st_uid;
- attr->gid = stbuf->st_gid;
- attr->rdev = stbuf->st_rdev;
- attr->size = stbuf->st_size;
- attr->blocks = stbuf->st_blocks;
- attr->atime = stbuf->st_atime;
- attr->mtime = stbuf->st_mtime;
- attr->ctime = stbuf->st_ctime;
- attr->atimensec = ST_ATIM_NSEC(stbuf);
- attr->mtimensec = ST_MTIM_NSEC(stbuf);
- attr->ctimensec = ST_CTIM_NSEC(stbuf);
+ attr->ino = stbuf->st_ino;
+ attr->mode = stbuf->st_mode;
+ attr->nlink = stbuf->st_nlink;
+ attr->uid = stbuf->st_uid;
+ attr->gid = stbuf->st_gid;
+ attr->rdev = stbuf->st_rdev;
+ attr->size = stbuf->st_size;
+ attr->blocks = stbuf->st_blocks;
+ attr->atime = stbuf->st_atime;
+ attr->mtime = stbuf->st_mtime;
+ attr->ctime = stbuf->st_ctime;
+ attr->atimensec = ST_ATIM_NSEC(stbuf);
+ attr->mtimensec = ST_MTIM_NSEC(stbuf);
+ attr->ctimensec = ST_CTIM_NSEC(stbuf);
}
static void convert_attr(const struct fuse_setattr_in *attr, struct stat *stbuf)
{
- stbuf->st_mode = attr->mode;
- stbuf->st_uid = attr->uid;
- stbuf->st_gid = attr->gid;
- stbuf->st_size = attr->size;
- stbuf->st_atime = attr->atime;
- stbuf->st_mtime = attr->mtime;
- ST_ATIM_NSEC_SET(stbuf, attr->atimensec);
- ST_MTIM_NSEC_SET(stbuf, attr->mtimensec);
+ stbuf->st_mode = attr->mode;
+ stbuf->st_uid = attr->uid;
+ stbuf->st_gid = attr->gid;
+ stbuf->st_size = attr->size;
+ stbuf->st_atime = attr->atime;
+ stbuf->st_mtime = attr->mtime;
+ ST_ATIM_NSEC_SET(stbuf, attr->atimensec);
+ ST_MTIM_NSEC_SET(stbuf, attr->mtimensec);
}
-static size_t iov_length(const struct iovec *iov, size_t count)
+static size_t iov_length(const struct iovec *iov, size_t count)
{
- size_t seg;
- size_t ret = 0;
+ size_t seg;
+ size_t ret = 0;
- for (seg = 0; seg < count; seg++)
- ret += iov[seg].iov_len;
- return ret;
+ for (seg = 0; seg < count; seg++)
+ ret += iov[seg].iov_len;
+ return ret;
}
static void list_init_req(struct fuse_req *req)
{
- req->next = req;
- req->prev = req;
+ req->next = req;
+ req->prev = req;
}
static void list_del_req(struct fuse_req *req)
{
- struct fuse_req *prev = req->prev;
- struct fuse_req *next = req->next;
- prev->next = next;
- next->prev = prev;
+ struct fuse_req *prev = req->prev;
+ struct fuse_req *next = req->next;
+ prev->next = next;
+ next->prev = prev;
}
static void list_add_req(struct fuse_req *req, struct fuse_req *next)
{
- struct fuse_req *prev = next->prev;
- req->next = next;
- req->prev = prev;
- prev->next = req;
- next->prev = req;
+ struct fuse_req *prev = next->prev;
+ req->next = next;
+ req->prev = prev;
+ prev->next = req;
+ next->prev = req;
}
static void destroy_req(fuse_req_t req)
{
- pthread_mutex_destroy(&req->lock);
- free(req);
+ pthread_mutex_destroy(&req->lock);
+ free(req);
}
static void free_req(fuse_req_t req)
{
- int ctr;
- struct fuse_ll *f = req->f;
+ int ctr;
+ struct fuse_ll *f = req->f;
- pthread_mutex_lock(&req->lock);
- req->u.ni.func = NULL;
- req->u.ni.data = NULL;
- pthread_mutex_unlock(&req->lock);
+ pthread_mutex_lock(&req->lock);
+ req->u.ni.func = NULL;
+ req->u.ni.data = NULL;
+ pthread_mutex_unlock(&req->lock);
- pthread_mutex_lock(&f->lock);
- list_del_req(req);
- ctr = --req->ctr;
- pthread_mutex_unlock(&f->lock);
- if (!ctr)
- destroy_req(req);
+ pthread_mutex_lock(&f->lock);
+ list_del_req(req);
+ ctr = --req->ctr;
+ pthread_mutex_unlock(&f->lock);
+ if (!ctr)
+ destroy_req(req);
}
static int send_reply_iov(fuse_req_t req, int error, struct iovec *iov,
- int count)
+ int count)
{
- struct fuse_out_header out;
- int res;
+ struct fuse_out_header out;
+ int res;
- if (error <= -1000 || error > 0) {
- fprintf(stderr, "fuse: bad error value: %i\n", error);
- error = -ERANGE;
- }
+ if (error <= -1000 || error > 0) {
+ fprintf(stderr, "fuse: bad error value: %i\n", error);
+ error = -ERANGE;
+ }
- out.unique = req->unique;
- out.error = error;
- iov[0].iov_base = &out;
- iov[0].iov_len = sizeof(struct fuse_out_header);
- out.len = iov_length(iov, count);
+ out.unique = req->unique;
+ out.error = error;
+ iov[0].iov_base = &out;
+ iov[0].iov_len = sizeof(struct fuse_out_header);
+ out.len = iov_length(iov, count);
- if (req->f->debug)
- fprintf(stderr, " unique: %llu, error: %i (%s), outsize: %i\n",
- (unsigned long long) out.unique, out.error,
- strerror(-out.error), out.len);
- res = fuse_chan_send(req->ch, iov, count);
- free_req(req);
+ if (req->f->debug)
+ fprintf(stderr,
+ " unique: %llu, error: %i (%s), outsize: %i\n",
+ (unsigned long long) out.unique, out.error,
+ strerror(-out.error), out.len);
+ res = fuse_chan_send(req->ch, iov, count);
+ free_req(req);
- return res;
+ return res;
}
static int send_reply(fuse_req_t req, int error, const void *arg,
- size_t argsize)
+ size_t argsize)
{
- struct iovec iov[2];
- int count = 1;
- if (argsize) {
- iov[1].iov_base = (void *) arg;
- iov[1].iov_len = argsize;
- count++;
- }
- return send_reply_iov(req, error, iov, count);
+ struct iovec iov[2];
+ int count = 1;
+ if (argsize) {
+ iov[1].iov_base = (void *) arg;
+ iov[1].iov_len = argsize;
+ count++;
+ }
+ return send_reply_iov(req, error, iov, count);
}
int fuse_reply_iov(fuse_req_t req, const struct iovec *iov, int count)
{
- int res;
- struct iovec *padded_iov;
+ int res;
+ struct iovec *padded_iov;
- padded_iov = malloc((count + 1) * sizeof(struct iovec));
- if (padded_iov == NULL)
- return fuse_reply_err(req, -ENOMEM);
+ padded_iov = malloc((count + 1) * sizeof(struct iovec));
+ if (padded_iov == NULL)
+ return fuse_reply_err(req, -ENOMEM);
- memcpy(padded_iov + 1, iov, count * sizeof(struct iovec));
- count++;
+ memcpy(padded_iov + 1, iov, count * sizeof(struct iovec));
+ count++;
- res = send_reply_iov(req, 0, padded_iov, count);
- free(padded_iov);
+ res = send_reply_iov(req, 0, padded_iov, count);
+ free(padded_iov);
- return res;
+ return res;
}
size_t fuse_dirent_size(size_t namelen)
{
- return FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + namelen);
+ return FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + namelen);
}
char *fuse_add_dirent(char *buf, const char *name, const struct stat *stbuf,
- off_t off)
+ off_t off)
{
- unsigned namelen = strlen(name);
- unsigned entlen = FUSE_NAME_OFFSET + namelen;
- unsigned entsize = fuse_dirent_size(namelen);
- unsigned padlen = entsize - entlen;
- struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
+ unsigned namelen = strlen(name);
+ unsigned entlen = FUSE_NAME_OFFSET + namelen;
+ unsigned entsize = fuse_dirent_size(namelen);
+ unsigned padlen = entsize - entlen;
+ struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
- dirent->ino = stbuf->st_ino;
- dirent->off = off;
- dirent->namelen = namelen;
- dirent->type = (stbuf->st_mode & 0170000) >> 12;
- strncpy(dirent->name, name, namelen);
- if (padlen)
- memset(buf + entlen, 0, padlen);
+ dirent->ino = stbuf->st_ino;
+ dirent->off = off;
+ dirent->namelen = namelen;
+ dirent->type = (stbuf->st_mode & 0170000) >> 12;
+ strncpy(dirent->name, name, namelen);
+ if (padlen)
+ memset(buf + entlen, 0, padlen);
- return buf + entsize;
+ return buf + entsize;
}
size_t fuse_add_direntry(fuse_req_t req, char *buf, size_t bufsize,
- const char *name, const struct stat *stbuf, off_t off)
+ const char *name, const struct stat *stbuf, off_t off)
{
- size_t entsize;
+ size_t entsize;
- (void) req;
- entsize = fuse_dirent_size(strlen(name));
- if (entsize <= bufsize && buf)
- fuse_add_dirent(buf, name, stbuf, off);
- return entsize;
+ (void) req;
+ entsize = fuse_dirent_size(strlen(name));
+ if (entsize <= bufsize && buf)
+ fuse_add_dirent(buf, name, stbuf, off);
+ return entsize;
}
static void convert_statfs(const struct statvfs *stbuf,
- struct fuse_kstatfs *kstatfs)
+ struct fuse_kstatfs *kstatfs)
{
- kstatfs->bsize = stbuf->f_bsize;
- kstatfs->frsize = stbuf->f_frsize;
- kstatfs->blocks = stbuf->f_blocks;
- kstatfs->bfree = stbuf->f_bfree;
- kstatfs->bavail = stbuf->f_bavail;
- kstatfs->files = stbuf->f_files;
- kstatfs->ffree = stbuf->f_ffree;
- kstatfs->namelen = stbuf->f_namemax;
+ kstatfs->bsize = stbuf->f_bsize;
+ kstatfs->frsize = stbuf->f_frsize;
+ kstatfs->blocks = stbuf->f_blocks;
+ kstatfs->bfree = stbuf->f_bfree;
+ kstatfs->bavail = stbuf->f_bavail;
+ kstatfs->files = stbuf->f_files;
+ kstatfs->ffree = stbuf->f_ffree;
+ kstatfs->namelen = stbuf->f_namemax;
}
static int send_reply_ok(fuse_req_t req, const void *arg, size_t argsize)
{
- return send_reply(req, 0, arg, argsize);
+ return send_reply(req, 0, arg, argsize);
}
int fuse_reply_err(fuse_req_t req, int err)
{
- return send_reply(req, -err, NULL, 0);
+ return send_reply(req, -err, NULL, 0);
}
void fuse_reply_none(fuse_req_t req)
{
- fuse_chan_send(req->ch, NULL, 0);
- free_req(req);
+ fuse_chan_send(req->ch, NULL, 0);
+ free_req(req);
}
static unsigned long calc_timeout_sec(double t)
{
- if (t > (double) ULONG_MAX)
- return ULONG_MAX;
- else if (t < 0.0)
- return 0;
- else
- return (unsigned long) t;
+ if (t > (double) ULONG_MAX)
+ return ULONG_MAX;
+ else if (t < 0.0)
+ return 0;
+ else
+ return (unsigned long) t;
}
static unsigned int calc_timeout_nsec(double t)
{
- double f = t - (double) calc_timeout_sec(t);
- if (f < 0.0)
- return 0;
- else if (f >= 0.999999999)
- return 999999999;
- else
- return (unsigned int) (f * 1.0e9);
+ double f = t - (double) calc_timeout_sec(t);
+ if (f < 0.0)
+ return 0;
+ else if (f >= 0.999999999)
+ return 999999999;
+ else
+ return (unsigned int) (f * 1.0e9);
}
static void fill_entry(struct fuse_entry_out *arg,
- const struct fuse_entry_param *e)
+ const struct fuse_entry_param *e)
{
- arg->nodeid = e->ino;
- arg->generation = e->generation;
- arg->entry_valid = calc_timeout_sec(e->entry_timeout);
- arg->entry_valid_nsec = calc_timeout_nsec(e->entry_timeout);
- arg->attr_valid = calc_timeout_sec(e->attr_timeout);
- arg->attr_valid_nsec = calc_timeout_nsec(e->attr_timeout);
- convert_stat(&e->attr, &arg->attr);
+ arg->nodeid = e->ino;
+ arg->generation = e->generation;
+ arg->entry_valid = calc_timeout_sec(e->entry_timeout);
+ arg->entry_valid_nsec = calc_timeout_nsec(e->entry_timeout);
+ arg->attr_valid = calc_timeout_sec(e->attr_timeout);
+ arg->attr_valid_nsec = calc_timeout_nsec(e->attr_timeout);
+ convert_stat(&e->attr, &arg->attr);
}
static void fill_open(struct fuse_open_out *arg,
- const struct fuse_file_info *f)
+ const struct fuse_file_info *f)
{
- arg->fh = f->fh;
- if (f->direct_io)
- arg->open_flags |= FOPEN_DIRECT_IO;
- if (f->keep_cache)
- arg->open_flags |= FOPEN_KEEP_CACHE;
+ arg->fh = f->fh;
+ if (f->direct_io)
+ arg->open_flags |= FOPEN_DIRECT_IO;
+ if (f->keep_cache)
+ arg->open_flags |= FOPEN_KEEP_CACHE;
}
int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e)
{
- struct fuse_entry_out arg;
+ struct fuse_entry_out arg;
- /* before ABI 7.4 e->ino == 0 was invalid, only ENOENT meant
- negative entry */
- if (!e->ino && req->f->conn.proto_minor < 4)
- return fuse_reply_err(req, ENOENT);
+ /* before ABI 7.4 e->ino == 0 was invalid, only ENOENT meant
+ negative entry */
+ if (!e->ino && req->f->conn.proto_minor < 4)
+ return fuse_reply_err(req, ENOENT);
- memset(&arg, 0, sizeof(arg));
- fill_entry(&arg, e);
- return send_reply_ok(req, &arg, sizeof(arg));
+ memset(&arg, 0, sizeof(arg));
+ fill_entry(&arg, e);
+ return send_reply_ok(req, &arg, sizeof(arg));
}
int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e,
- const struct fuse_file_info *f)
+ const struct fuse_file_info *f)
{
- struct {
- struct fuse_entry_out e;
- struct fuse_open_out o;
- } arg;
+ struct {
+ struct fuse_entry_out e;
+ struct fuse_open_out o;
+ } arg;
- memset(&arg, 0, sizeof(arg));
- fill_entry(&arg.e, e);
- fill_open(&arg.o, f);
- return send_reply_ok(req, &arg, sizeof(arg));
+ memset(&arg, 0, sizeof(arg));
+ fill_entry(&arg.e, e);
+ fill_open(&arg.o, f);
+ return send_reply_ok(req, &arg, sizeof(arg));
}
int fuse_reply_attr(fuse_req_t req, const struct stat *attr,
- double attr_timeout)
+ double attr_timeout)
{
- struct fuse_attr_out arg;
+ struct fuse_attr_out arg;
- memset(&arg, 0, sizeof(arg));
- arg.attr_valid = calc_timeout_sec(attr_timeout);
- arg.attr_valid_nsec = calc_timeout_nsec(attr_timeout);
- convert_stat(attr, &arg.attr);
+ memset(&arg, 0, sizeof(arg));
+ arg.attr_valid = calc_timeout_sec(attr_timeout);
+ arg.attr_valid_nsec = calc_timeout_nsec(attr_timeout);
+ convert_stat(attr, &arg.attr);
- return send_reply_ok(req, &arg, sizeof(arg));
+ return send_reply_ok(req, &arg, sizeof(arg));
}
int fuse_reply_readlink(fuse_req_t req, const char *linkname)
{
- return send_reply_ok(req, linkname, strlen(linkname));
+ return send_reply_ok(req, linkname, strlen(linkname));
}
int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *f)
{
- struct fuse_open_out arg;
+ struct fuse_open_out arg;
- memset(&arg, 0, sizeof(arg));
- fill_open(&arg, f);
- return send_reply_ok(req, &arg, sizeof(arg));
+ memset(&arg, 0, sizeof(arg));
+ fill_open(&arg, f);
+ return send_reply_ok(req, &arg, sizeof(arg));
}
int fuse_reply_write(fuse_req_t req, size_t count)
{
- struct fuse_write_out arg;
+ struct fuse_write_out arg;
- memset(&arg, 0, sizeof(arg));
- arg.size = count;
+ memset(&arg, 0, sizeof(arg));
+ arg.size = count;
- return send_reply_ok(req, &arg, sizeof(arg));
+ return send_reply_ok(req, &arg, sizeof(arg));
}
int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size)
{
- return send_reply_ok(req, buf, size);
+ return send_reply_ok(req, buf, size);
}
int fuse_reply_statfs(fuse_req_t req, const struct statvfs *stbuf)
{
- struct fuse_statfs_out arg;
- size_t size = req->f->conn.proto_minor < 4 ? FUSE_COMPAT_STATFS_SIZE : sizeof(arg);
+ struct fuse_statfs_out arg;
+ size_t size = req->f->conn.proto_minor < 4 ?
+ FUSE_COMPAT_STATFS_SIZE : sizeof(arg);
- memset(&arg, 0, sizeof(arg));
- convert_statfs(stbuf, &arg.st);
+ memset(&arg, 0, sizeof(arg));
+ convert_statfs(stbuf, &arg.st);
- return send_reply_ok(req, &arg, size);
+ return send_reply_ok(req, &arg, size);
}
int fuse_reply_xattr(fuse_req_t req, size_t count)
{
- struct fuse_getxattr_out arg;
+ struct fuse_getxattr_out arg;
- memset(&arg, 0, sizeof(arg));
- arg.size = count;
+ memset(&arg, 0, sizeof(arg));
+ arg.size = count;
- return send_reply_ok(req, &arg, sizeof(arg));
+ return send_reply_ok(req, &arg, sizeof(arg));
}
int fuse_reply_lock(fuse_req_t req, struct flock *lock)
{
- struct fuse_lk_out arg;
+ struct fuse_lk_out arg;
- memset(&arg, 0, sizeof(arg));
- arg.lk.type = lock->l_type;
- if (lock->l_type != F_UNLCK) {
- arg.lk.start = lock->l_start;
- if (lock->l_len == 0)
- arg.lk.end = OFFSET_MAX;
- else
- arg.lk.end = lock->l_start + lock->l_len - 1;
- }
- arg.lk.pid = lock->l_pid;
- return send_reply_ok(req, &arg, sizeof(arg));
+ memset(&arg, 0, sizeof(arg));
+ arg.lk.type = lock->l_type;
+ if (lock->l_type != F_UNLCK) {
+ arg.lk.start = lock->l_start;
+ if (lock->l_len == 0)
+ arg.lk.end = OFFSET_MAX;
+ else
+ arg.lk.end = lock->l_start + lock->l_len - 1;
+ }
+ arg.lk.pid = lock->l_pid;
+ return send_reply_ok(req, &arg, sizeof(arg));
}
int fuse_reply_bmap(fuse_req_t req, uint64_t idx)
{
- struct fuse_bmap_out arg;
+ struct fuse_bmap_out arg;
- memset(&arg, 0, sizeof(arg));
- arg.block = idx;
+ memset(&arg, 0, sizeof(arg));
+ arg.block = idx;
- return send_reply_ok(req, &arg, sizeof(arg));
+ return send_reply_ok(req, &arg, sizeof(arg));
}
static void do_lookup(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- char *name = (char *) inarg;
+ char *name = (char *) inarg;
- if (req->f->op.lookup)
- req->f->op.lookup(req, nodeid, name);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.lookup)
+ req->f->op.lookup(req, nodeid, name);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_forget(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_forget_in *arg = (struct fuse_forget_in *) inarg;
+ struct fuse_forget_in *arg = (struct fuse_forget_in *) inarg;
- if (req->f->op.forget)
- req->f->op.forget(req, nodeid, arg->nlookup);
- else
- fuse_reply_none(req);
+ if (req->f->op.forget)
+ req->f->op.forget(req, nodeid, arg->nlookup);
+ else
+ fuse_reply_none(req);
}
static void do_getattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- (void) inarg;
+ (void) inarg;
- if (req->f->op.getattr)
- req->f->op.getattr(req, nodeid, NULL);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.getattr)
+ req->f->op.getattr(req, nodeid, NULL);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_setattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_setattr_in *arg = (struct fuse_setattr_in *) inarg;
-
- if (req->f->op.setattr) {
- struct fuse_file_info *fi = NULL;
- struct fuse_file_info fi_store;
- struct stat stbuf;
- memset(&stbuf, 0, sizeof(stbuf));
- convert_attr(arg, &stbuf);
- if (arg->valid & FATTR_FH) {
- arg->valid &= ~FATTR_FH;
- memset(&fi_store, 0, sizeof(fi_store));
- fi = &fi_store;
- fi->fh = arg->fh;
- fi->fh_old = fi->fh;
- }
- req->f->op.setattr(req, nodeid, &stbuf, arg->valid, fi);
- } else
- fuse_reply_err(req, ENOSYS);
+ struct fuse_setattr_in *arg = (struct fuse_setattr_in *) inarg;
+
+ if (req->f->op.setattr) {
+ struct fuse_file_info *fi = NULL;
+ struct fuse_file_info fi_store;
+ struct stat stbuf;
+ memset(&stbuf, 0, sizeof(stbuf));
+ convert_attr(arg, &stbuf);
+ if (arg->valid & FATTR_FH) {
+ arg->valid &= ~FATTR_FH;
+ memset(&fi_store, 0, sizeof(fi_store));
+ fi = &fi_store;
+ fi->fh = arg->fh;
+ fi->fh_old = fi->fh;
+ }
+ req->f->op.setattr(req, nodeid, &stbuf, arg->valid, fi);
+ } else
+ fuse_reply_err(req, ENOSYS);
}
static void do_access(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_access_in *arg = (struct fuse_access_in *) inarg;
+ struct fuse_access_in *arg = (struct fuse_access_in *) inarg;
- if (req->f->op.access)
- req->f->op.access(req, nodeid, arg->mask);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.access)
+ req->f->op.access(req, nodeid, arg->mask);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_readlink(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- (void) inarg;
+ (void) inarg;
- if (req->f->op.readlink)
- req->f->op.readlink(req, nodeid);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.readlink)
+ req->f->op.readlink(req, nodeid);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_mknod(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_mknod_in *arg = (struct fuse_mknod_in *) inarg;
+ struct fuse_mknod_in *arg = (struct fuse_mknod_in *) inarg;
- if (req->f->op.mknod)
- req->f->op.mknod(req, nodeid, PARAM(arg), arg->mode, arg->rdev);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.mknod)
+ req->f->op.mknod(req, nodeid, PARAM(arg), arg->mode, arg->rdev);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_mkdir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_mkdir_in *arg = (struct fuse_mkdir_in *) inarg;
+ struct fuse_mkdir_in *arg = (struct fuse_mkdir_in *) inarg;
- if (req->f->op.mkdir)
- req->f->op.mkdir(req, nodeid, PARAM(arg), arg->mode);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.mkdir)
+ req->f->op.mkdir(req, nodeid, PARAM(arg), arg->mode);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_unlink(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- char *name = (char *) inarg;
+ char *name = (char *) inarg;
- if (req->f->op.unlink)
- req->f->op.unlink(req, nodeid, name);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.unlink)
+ req->f->op.unlink(req, nodeid, name);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_rmdir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- char *name = (char *) inarg;
+ char *name = (char *) inarg;
- if (req->f->op.rmdir)
- req->f->op.rmdir(req, nodeid, name);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.rmdir)
+ req->f->op.rmdir(req, nodeid, name);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_symlink(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- char *name = (char *) inarg;
- char *linkname = ((char *) inarg) + strlen((char *) inarg) + 1;
+ char *name = (char *) inarg;
+ char *linkname = ((char *) inarg) + strlen((char *) inarg) + 1;
- if (req->f->op.symlink)
- req->f->op.symlink(req, linkname, nodeid, name);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.symlink)
+ req->f->op.symlink(req, linkname, nodeid, name);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_rename(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_rename_in *arg = (struct fuse_rename_in *) inarg;
- char *oldname = PARAM(arg);
- char *newname = oldname + strlen(oldname) + 1;
+ struct fuse_rename_in *arg = (struct fuse_rename_in *) inarg;
+ char *oldname = PARAM(arg);
+ char *newname = oldname + strlen(oldname) + 1;
- if (req->f->op.rename)
- req->f->op.rename(req, nodeid, oldname, arg->newdir, newname);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.rename)
+ req->f->op.rename(req, nodeid, oldname, arg->newdir, newname);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_link(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_link_in *arg = (struct fuse_link_in *) inarg;
+ struct fuse_link_in *arg = (struct fuse_link_in *) inarg;
- if (req->f->op.link)
- req->f->op.link(req, arg->oldnodeid, nodeid, PARAM(arg));
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.link)
+ req->f->op.link(req, arg->oldnodeid, nodeid, PARAM(arg));
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_create(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_open_in *arg = (struct fuse_open_in *) inarg;
+ struct fuse_open_in *arg = (struct fuse_open_in *) inarg;
- if (req->f->op.create) {
- struct fuse_file_info fi;
+ if (req->f->op.create) {
+ struct fuse_file_info fi;
- memset(&fi, 0, sizeof(fi));
- fi.flags = arg->flags;
+ memset(&fi, 0, sizeof(fi));
+ fi.flags = arg->flags;
- req->f->op.create(req, nodeid, PARAM(arg), arg->mode, &fi);
- } else
- fuse_reply_err(req, ENOSYS);
+ req->f->op.create(req, nodeid, PARAM(arg), arg->mode, &fi);
+ } else
+ fuse_reply_err(req, ENOSYS);
}
static void do_open(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_open_in *arg = (struct fuse_open_in *) inarg;
- struct fuse_file_info fi;
+ struct fuse_open_in *arg = (struct fuse_open_in *) inarg;
+ struct fuse_file_info fi;
- memset(&fi, 0, sizeof(fi));
- fi.flags = arg->flags;
+ memset(&fi, 0, sizeof(fi));
+ fi.flags = arg->flags;
- if (req->f->op.open)
- req->f->op.open(req, nodeid, &fi);
- else
- fuse_reply_open(req, &fi);
+ if (req->f->op.open)
+ req->f->op.open(req, nodeid, &fi);
+ else
+ fuse_reply_open(req, &fi);
}
static void do_read(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_read_in *arg = (struct fuse_read_in *) inarg;
+ struct fuse_read_in *arg = (struct fuse_read_in *) inarg;
- if (req->f->op.read) {
- struct fuse_file_info fi;
+ if (req->f->op.read) {
+ struct fuse_file_info fi;
- memset(&fi, 0, sizeof(fi));
- fi.fh = arg->fh;
- fi.fh_old = fi.fh;
- req->f->op.read(req, nodeid, arg->size, arg->offset, &fi);
- } else
- fuse_reply_err(req, ENOSYS);
+ memset(&fi, 0, sizeof(fi));
+ fi.fh = arg->fh;
+ fi.fh_old = fi.fh;
+ req->f->op.read(req, nodeid, arg->size, arg->offset, &fi);
+ } else
+ fuse_reply_err(req, ENOSYS);
}
static void do_write(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_write_in *arg = (struct fuse_write_in *) inarg;
- struct fuse_file_info fi;
+ struct fuse_write_in *arg = (struct fuse_write_in *) inarg;
+ struct fuse_file_info fi;
- memset(&fi, 0, sizeof(fi));
- fi.fh = arg->fh;
- fi.fh_old = fi.fh;
- fi.writepage = arg->write_flags & 1;
+ memset(&fi, 0, sizeof(fi));
+ fi.fh = arg->fh;
+ fi.fh_old = fi.fh;
+ fi.writepage = arg->write_flags & 1;
- if (req->f->op.write)
- req->f->op.write(req, nodeid, PARAM(arg), arg->size, arg->offset, &fi);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.write)
+ req->f->op.write(req, nodeid, PARAM(arg), arg->size,
+ arg->offset, &fi);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_flush(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_flush_in *arg = (struct fuse_flush_in *) inarg;
- struct fuse_file_info fi;
+ struct fuse_flush_in *arg = (struct fuse_flush_in *) inarg;
+ struct fuse_file_info fi;
- memset(&fi, 0, sizeof(fi));
- fi.fh = arg->fh;
- fi.fh_old = fi.fh;
- fi.flush = 1;
- if (req->f->conn.proto_minor >= 7)
- fi.lock_owner = arg->lock_owner;
+ memset(&fi, 0, sizeof(fi));
+ fi.fh = arg->fh;
+ fi.fh_old = fi.fh;
+ fi.flush = 1;
+ if (req->f->conn.proto_minor >= 7)
+ fi.lock_owner = arg->lock_owner;
- if (req->f->op.flush)
- req->f->op.flush(req, nodeid, &fi);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.flush)
+ req->f->op.flush(req, nodeid, &fi);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_release(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_release_in *arg = (struct fuse_release_in *) inarg;
- struct fuse_file_info fi;
+ struct fuse_release_in *arg = (struct fuse_release_in *) inarg;
+ struct fuse_file_info fi;
- memset(&fi, 0, sizeof(fi));
- fi.flags = arg->flags;
- fi.fh = arg->fh;
- fi.fh_old = fi.fh;
- if (req->f->conn.proto_minor >= 8) {
- fi.flush = (arg->release_flags & FUSE_RELEASE_FLUSH) ? 1 : 0;
- fi.lock_owner = arg->lock_owner;
- }
+ memset(&fi, 0, sizeof(fi));
+ fi.flags = arg->flags;
+ fi.fh = arg->fh;
+ fi.fh_old = fi.fh;
+ if (req->f->conn.proto_minor >= 8) {
+ fi.flush = (arg->release_flags & FUSE_RELEASE_FLUSH) ? 1 : 0;
+ fi.lock_owner = arg->lock_owner;
+ }
- if (req->f->op.release)
- req->f->op.release(req, nodeid, &fi);
- else
- fuse_reply_err(req, 0);
+ if (req->f->op.release)
+ req->f->op.release(req, nodeid, &fi);
+ else
+ fuse_reply_err(req, 0);
}
static void do_fsync(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_fsync_in *arg = (struct fuse_fsync_in *) inarg;
- struct fuse_file_info fi;
+ struct fuse_fsync_in *arg = (struct fuse_fsync_in *) inarg;
+ struct fuse_file_info fi;
- memset(&fi, 0, sizeof(fi));
- fi.fh = arg->fh;
- fi.fh_old = fi.fh;
+ memset(&fi, 0, sizeof(fi));
+ fi.fh = arg->fh;
+ fi.fh_old = fi.fh;
- if (req->f->op.fsync)
- req->f->op.fsync(req, nodeid, arg->fsync_flags & 1, &fi);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.fsync)
+ req->f->op.fsync(req, nodeid, arg->fsync_flags & 1, &fi);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_opendir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_open_in *arg = (struct fuse_open_in *) inarg;
- struct fuse_file_info fi;
+ struct fuse_open_in *arg = (struct fuse_open_in *) inarg;
+ struct fuse_file_info fi;
- memset(&fi, 0, sizeof(fi));
- fi.flags = arg->flags;
+ memset(&fi, 0, sizeof(fi));
+ fi.flags = arg->flags;
- if (req->f->op.opendir)
- req->f->op.opendir(req, nodeid, &fi);
- else
- fuse_reply_open(req, &fi);
+ if (req->f->op.opendir)
+ req->f->op.opendir(req, nodeid, &fi);
+ else
+ fuse_reply_open(req, &fi);
}
static void do_readdir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_read_in *arg = (struct fuse_read_in *) inarg;
- struct fuse_file_info fi;
+ struct fuse_read_in *arg = (struct fuse_read_in *) inarg;
+ struct fuse_file_info fi;
- memset(&fi, 0, sizeof(fi));
- fi.fh = arg->fh;
- fi.fh_old = fi.fh;
+ memset(&fi, 0, sizeof(fi));
+ fi.fh = arg->fh;
+ fi.fh_old = fi.fh;
- if (req->f->op.readdir)
- req->f->op.readdir(req, nodeid, arg->size, arg->offset, &fi);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.readdir)
+ req->f->op.readdir(req, nodeid, arg->size, arg->offset, &fi);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_releasedir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_release_in *arg = (struct fuse_release_in *) inarg;
- struct fuse_file_info fi;
+ struct fuse_release_in *arg = (struct fuse_release_in *) inarg;
+ struct fuse_file_info fi;
- memset(&fi, 0, sizeof(fi));
- fi.flags = arg->flags;
- fi.fh = arg->fh;
- fi.fh_old = fi.fh;
+ memset(&fi, 0, sizeof(fi));
+ fi.flags = arg->flags;
+ fi.fh = arg->fh;
+ fi.fh_old = fi.fh;
- if (req->f->op.releasedir)
- req->f->op.releasedir(req, nodeid, &fi);
- else
- fuse_reply_err(req, 0);
+ if (req->f->op.releasedir)
+ req->f->op.releasedir(req, nodeid, &fi);
+ else
+ fuse_reply_err(req, 0);
}
static void do_fsyncdir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_fsync_in *arg = (struct fuse_fsync_in *) inarg;
- struct fuse_file_info fi;
+ struct fuse_fsync_in *arg = (struct fuse_fsync_in *) inarg;
+ struct fuse_file_info fi;
- memset(&fi, 0, sizeof(fi));
- fi.fh = arg->fh;
- fi.fh_old = fi.fh;
+ memset(&fi, 0, sizeof(fi));
+ fi.fh = arg->fh;
+ fi.fh_old = fi.fh;
- if (req->f->op.fsyncdir)
- req->f->op.fsyncdir(req, nodeid, arg->fsync_flags & 1, &fi);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.fsyncdir)
+ req->f->op.fsyncdir(req, nodeid, arg->fsync_flags & 1, &fi);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_statfs(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- (void) nodeid;
- (void) inarg;
+ (void) nodeid;
+ (void) inarg;
- if (req->f->op.statfs)
- req->f->op.statfs(req, nodeid);
- else {
- struct statvfs buf = {
- .f_namemax = 255,
- .f_bsize = 512,
- };
- fuse_reply_statfs(req, &buf);
- }
+ if (req->f->op.statfs)
+ req->f->op.statfs(req, nodeid);
+ else {
+ struct statvfs buf = {
+ .f_namemax = 255,
+ .f_bsize = 512,
+ };
+ fuse_reply_statfs(req, &buf);
+ }
}
static void do_setxattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_setxattr_in *arg = (struct fuse_setxattr_in *) inarg;
- char *name = PARAM(arg);
- char *value = name + strlen(name) + 1;
+ struct fuse_setxattr_in *arg = (struct fuse_setxattr_in *) inarg;
+ char *name = PARAM(arg);
+ char *value = name + strlen(name) + 1;
- if (req->f->op.setxattr)
- req->f->op.setxattr(req, nodeid, name, value, arg->size, arg->flags);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.setxattr)
+ req->f->op.setxattr(req, nodeid, name, value, arg->size,
+ arg->flags);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_getxattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_getxattr_in *arg = (struct fuse_getxattr_in *) inarg;
+ struct fuse_getxattr_in *arg = (struct fuse_getxattr_in *) inarg;
- if (req->f->op.getxattr)
- req->f->op.getxattr(req, nodeid, PARAM(arg), arg->size);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.getxattr)
+ req->f->op.getxattr(req, nodeid, PARAM(arg), arg->size);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_listxattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_getxattr_in *arg = (struct fuse_getxattr_in *) inarg;
+ struct fuse_getxattr_in *arg = (struct fuse_getxattr_in *) inarg;
- if (req->f->op.listxattr)
- req->f->op.listxattr(req, nodeid, arg->size);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.listxattr)
+ req->f->op.listxattr(req, nodeid, arg->size);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_removexattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- char *name = (char *) inarg;
+ char *name = (char *) inarg;
- if (req->f->op.removexattr)
- req->f->op.removexattr(req, nodeid, name);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.removexattr)
+ req->f->op.removexattr(req, nodeid, name);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void convert_fuse_file_lock(struct fuse_file_lock *fl,
- struct flock *flock)
+ struct flock *flock)
{
- memset(flock, 0, sizeof(struct flock));
- flock->l_type = fl->type;
- flock->l_whence = SEEK_SET;
- flock->l_start = fl->start;
- if (fl->end == OFFSET_MAX)
- flock->l_len = 0;
- else
- flock->l_len = fl->end - fl->start + 1;
- flock->l_pid = fl->pid;
+ memset(flock, 0, sizeof(struct flock));
+ flock->l_type = fl->type;
+ flock->l_whence = SEEK_SET;
+ flock->l_start = fl->start;
+ if (fl->end == OFFSET_MAX)
+ flock->l_len = 0;
+ else
+ flock->l_len = fl->end - fl->start + 1;
+ flock->l_pid = fl->pid;
}
static void do_getlk(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_lk_in *arg = (struct fuse_lk_in *) inarg;
- struct fuse_file_info fi;
- struct flock flock;
+ struct fuse_lk_in *arg = (struct fuse_lk_in *) inarg;
+ struct fuse_file_info fi;
+ struct flock flock;
- memset(&fi, 0, sizeof(fi));
- fi.fh = arg->fh;
- fi.lock_owner = arg->owner;
+ memset(&fi, 0, sizeof(fi));
+ fi.fh = arg->fh;
+ fi.lock_owner = arg->owner;
- convert_fuse_file_lock(&arg->lk, &flock);
- if (req->f->op.getlk)
- req->f->op.getlk(req, nodeid, &fi, &flock);
- else
- fuse_reply_err(req, ENOSYS);
+ convert_fuse_file_lock(&arg->lk, &flock);
+ if (req->f->op.getlk)
+ req->f->op.getlk(req, nodeid, &fi, &flock);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_setlk_common(fuse_req_t req, fuse_ino_t nodeid,
- const void *inarg, int sleep)
+ const void *inarg, int sleep)
{
- struct fuse_lk_in *arg = (struct fuse_lk_in *) inarg;
- struct fuse_file_info fi;
- struct flock flock;
+ struct fuse_lk_in *arg = (struct fuse_lk_in *) inarg;
+ struct fuse_file_info fi;
+ struct flock flock;
- memset(&fi, 0, sizeof(fi));
- fi.fh = arg->fh;
- fi.lock_owner = arg->owner;
+ memset(&fi, 0, sizeof(fi));
+ fi.fh = arg->fh;
+ fi.lock_owner = arg->owner;
- convert_fuse_file_lock(&arg->lk, &flock);
- if (req->f->op.setlk)
- req->f->op.setlk(req, nodeid, &fi, &flock, sleep);
- else
- fuse_reply_err(req, ENOSYS);
+ convert_fuse_file_lock(&arg->lk, &flock);
+ if (req->f->op.setlk)
+ req->f->op.setlk(req, nodeid, &fi, &flock, sleep);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_setlk(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- do_setlk_common(req, nodeid, inarg, 0);
+ do_setlk_common(req, nodeid, inarg, 0);
}
static void do_setlkw(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- do_setlk_common(req, nodeid, inarg, 1);
+ do_setlk_common(req, nodeid, inarg, 1);
}
static int find_interrupted(struct fuse_ll *f, struct fuse_req *req)
{
- struct fuse_req *curr;
-
- for (curr = f->list.next; curr != &f->list; curr = curr->next) {
- if (curr->unique == req->u.i.unique) {
- curr->ctr++;
- pthread_mutex_unlock(&f->lock);
-
- /* Ugh, ugly locking */
- pthread_mutex_lock(&curr->lock);
- pthread_mutex_lock(&f->lock);
- curr->interrupted = 1;
- pthread_mutex_unlock(&f->lock);
- if (curr->u.ni.func)
- curr->u.ni.func(curr, curr->u.ni.data);
- pthread_mutex_unlock(&curr->lock);
-
- pthread_mutex_lock(&f->lock);
- curr->ctr--;
- if (!curr->ctr)
- destroy_req(curr);
-
- return 1;
- }
- }
- for (curr = f->interrupts.next; curr != &f->interrupts;
- curr = curr->next) {
- if (curr->u.i.unique == req->u.i.unique)
- return 1;
- }
- return 0;
+ struct fuse_req *curr;
+
+ for (curr = f->list.next; curr != &f->list; curr = curr->next) {
+ if (curr->unique == req->u.i.unique) {
+ curr->ctr++;
+ pthread_mutex_unlock(&f->lock);
+
+ /* Ugh, ugly locking */
+ pthread_mutex_lock(&curr->lock);
+ pthread_mutex_lock(&f->lock);
+ curr->interrupted = 1;
+ pthread_mutex_unlock(&f->lock);
+ if (curr->u.ni.func)
+ curr->u.ni.func(curr, curr->u.ni.data);
+ pthread_mutex_unlock(&curr->lock);
+
+ pthread_mutex_lock(&f->lock);
+ curr->ctr--;
+ if (!curr->ctr)
+ destroy_req(curr);
+
+ return 1;
+ }
+ }
+ for (curr = f->interrupts.next; curr != &f->interrupts;
+ curr = curr->next) {
+ if (curr->u.i.unique == req->u.i.unique)
+ return 1;
+ }
+ return 0;
}
static void do_interrupt(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_interrupt_in *arg = (struct fuse_interrupt_in *) inarg;
- struct fuse_ll *f = req->f;
+ struct fuse_interrupt_in *arg = (struct fuse_interrupt_in *) inarg;
+ struct fuse_ll *f = req->f;
- (void) nodeid;
- if (f->debug)
- fprintf(stderr, "INTERRUPT: %llu\n", (unsigned long long) arg->unique);
+ (void) nodeid;
+ if (f->debug)
+ fprintf(stderr, "INTERRUPT: %llu\n",
+ (unsigned long long) arg->unique);
- req->u.i.unique = arg->unique;
+ req->u.i.unique = arg->unique;
- pthread_mutex_lock(&f->lock);
- if (find_interrupted(f, req))
- destroy_req(req);
- else
- list_add_req(req, &f->interrupts);
- pthread_mutex_unlock(&f->lock);
+ pthread_mutex_lock(&f->lock);
+ if (find_interrupted(f, req))
+ destroy_req(req);
+ else
+ list_add_req(req, &f->interrupts);
+ pthread_mutex_unlock(&f->lock);
}
static struct fuse_req *check_interrupt(struct fuse_ll *f, struct fuse_req *req)
{
- struct fuse_req *curr;
-
- for (curr = f->interrupts.next; curr != &f->interrupts; curr = curr->next) {
- if (curr->u.i.unique == req->unique) {
- req->interrupted = 1;
- list_del_req(curr);
- free(curr);
- return NULL;
- }
- }
- curr = f->interrupts.next;
- if (curr != &f->interrupts) {
- list_del_req(curr);
- list_init_req(curr);
- return curr;
- } else
- return NULL;
+ struct fuse_req *curr;
+
+ for (curr = f->interrupts.next; curr != &f->interrupts;
+ curr = curr->next) {
+ if (curr->u.i.unique == req->unique) {
+ req->interrupted = 1;
+ list_del_req(curr);
+ free(curr);
+ return NULL;
+ }
+ }
+ curr = f->interrupts.next;
+ if (curr != &f->interrupts) {
+ list_del_req(curr);
+ list_init_req(curr);
+ return curr;
+ } else
+ return NULL;
}
static void do_bmap(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_bmap_in *arg = (struct fuse_bmap_in *) inarg;
+ struct fuse_bmap_in *arg = (struct fuse_bmap_in *) inarg;
- if (req->f->op.bmap)
- req->f->op.bmap(req, nodeid, arg->blocksize, arg->block);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.bmap)
+ req->f->op.bmap(req, nodeid, arg->blocksize, arg->block);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_init_in *arg = (struct fuse_init_in *) inarg;
- struct fuse_init_out outarg;
- struct fuse_ll *f = req->f;
- size_t bufsize = fuse_chan_bufsize(req->ch);
-
- (void) nodeid;
- if (f->debug) {
- fprintf(stderr, "INIT: %u.%u\n", arg->major, arg->minor);
- if (arg->major > 7 || (arg->major == 7 && arg->minor >= 6)) {
- fprintf(stderr, "flags=0x%08x\n", arg->flags);
- fprintf(stderr, "max_readahead=0x%08x\n", arg->max_readahead);
- }
- }
- f->conn.proto_major = arg->major;
- f->conn.proto_minor = arg->minor;
-
- if (arg->major < 7) {
- fprintf(stderr, "fuse: unsupported protocol version: %u.%u\n",
- arg->major, arg->minor);
- fuse_reply_err(req, EPROTO);
- return;
- }
-
- if (arg->major > 7 || (arg->major == 7 && arg->minor >= 6)) {
- if (f->conn.async_read)
- f->conn.async_read = arg->flags & FUSE_ASYNC_READ;
- if (arg->max_readahead < f->conn.max_readahead)
- f->conn.max_readahead = arg->max_readahead;
- } else {
- f->conn.async_read = 0;
- f->conn.max_readahead = 0;
- }
-
- if (bufsize < FUSE_MIN_READ_BUFFER) {
- fprintf(stderr, "fuse: warning: buffer size too small: %zu\n",
- bufsize);
- bufsize = FUSE_MIN_READ_BUFFER;
- }
-
- bufsize -= 4096;
- if (bufsize < f->conn.max_write)
- f->conn.max_write = bufsize;
-
- f->got_init = 1;
- if (f->op.init)
- f->op.init(f->userdata, &f->conn);
-
- memset(&outarg, 0, sizeof(outarg));
- outarg.major = FUSE_KERNEL_VERSION;
- outarg.minor = FUSE_KERNEL_MINOR_VERSION;
- if (f->conn.async_read)
- outarg.flags |= FUSE_ASYNC_READ;
- if (f->op.getlk && f->op.setlk)
- outarg.flags |= FUSE_POSIX_LOCKS;
- outarg.max_readahead = f->conn.max_readahead;
- outarg.max_write = f->conn.max_write;
-
- if (f->debug) {
- fprintf(stderr, " INIT: %u.%u\n", outarg.major, outarg.minor);
- fprintf(stderr, " flags=0x%08x\n", outarg.flags);
- fprintf(stderr, " max_readahead=0x%08x\n", outarg.max_readahead);
- fprintf(stderr, " max_write=0x%08x\n", outarg.max_write);
- }
-
- send_reply_ok(req, &outarg, arg->minor < 5 ? 8 : sizeof(outarg));
+ struct fuse_init_in *arg = (struct fuse_init_in *) inarg;
+ struct fuse_init_out outarg;
+ struct fuse_ll *f = req->f;
+ size_t bufsize = fuse_chan_bufsize(req->ch);
+
+ (void) nodeid;
+ if (f->debug) {
+ fprintf(stderr, "INIT: %u.%u\n", arg->major, arg->minor);
+ if (arg->major > 7 || (arg->major == 7 && arg->minor >= 6)) {
+ fprintf(stderr, "flags=0x%08x\n", arg->flags);
+ fprintf(stderr, "max_readahead=0x%08x\n",
+ arg->max_readahead);
+ }
+ }
+ f->conn.proto_major = arg->major;
+ f->conn.proto_minor = arg->minor;
+
+ if (arg->major < 7) {
+ fprintf(stderr, "fuse: unsupported protocol version: %u.%u\n",
+ arg->major, arg->minor);
+ fuse_reply_err(req, EPROTO);
+ return;
+ }
+
+ if (arg->major > 7 || (arg->major == 7 && arg->minor >= 6)) {
+ if (f->conn.async_read)
+ f->conn.async_read = arg->flags & FUSE_ASYNC_READ;
+ if (arg->max_readahead < f->conn.max_readahead)
+ f->conn.max_readahead = arg->max_readahead;
+ } else {
+ f->conn.async_read = 0;
+ f->conn.max_readahead = 0;
+ }
+
+ if (bufsize < FUSE_MIN_READ_BUFFER) {
+ fprintf(stderr, "fuse: warning: buffer size too small: %zu\n",
+ bufsize);
+ bufsize = FUSE_MIN_READ_BUFFER;
+ }
+
+ bufsize -= 4096;
+ if (bufsize < f->conn.max_write)
+ f->conn.max_write = bufsize;
+
+ f->got_init = 1;
+ if (f->op.init)
+ f->op.init(f->userdata, &f->conn);
+
+ memset(&outarg, 0, sizeof(outarg));
+ outarg.major = FUSE_KERNEL_VERSION;
+ outarg.minor = FUSE_KERNEL_MINOR_VERSION;
+ if (f->conn.async_read)
+ outarg.flags |= FUSE_ASYNC_READ;
+ if (f->op.getlk && f->op.setlk)
+ outarg.flags |= FUSE_POSIX_LOCKS;
+ outarg.max_readahead = f->conn.max_readahead;
+ outarg.max_write = f->conn.max_write;
+
+ if (f->debug) {
+ fprintf(stderr, " INIT: %u.%u\n", outarg.major, outarg.minor);
+ fprintf(stderr, " flags=0x%08x\n", outarg.flags);
+ fprintf(stderr, " max_readahead=0x%08x\n",
+ outarg.max_readahead);
+ fprintf(stderr, " max_write=0x%08x\n", outarg.max_write);
+ }
+
+ send_reply_ok(req, &outarg, arg->minor < 5 ? 8 : sizeof(outarg));
}
static void do_destroy(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_ll *f = req->f;
+ struct fuse_ll *f = req->f;
- (void) nodeid;
- (void) inarg;
+ (void) nodeid;
+ (void) inarg;
- f->got_destroy = 1;
- if (f->op.destroy)
- f->op.destroy(f->userdata);
+ f->got_destroy = 1;
+ if (f->op.destroy)
+ f->op.destroy(f->userdata);
- send_reply_ok(req, NULL, 0);
+ send_reply_ok(req, NULL, 0);
}
void *fuse_req_userdata(fuse_req_t req)
{
- return req->f->userdata;
+ return req->f->userdata;
}
const struct fuse_ctx *fuse_req_ctx(fuse_req_t req)
{
- return &req->ctx;
+ return &req->ctx;
}
void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func,
- void *data)
+ void *data)
{
- pthread_mutex_lock(&req->lock);
- req->u.ni.func = func;
- req->u.ni.data = data;
- if (req->interrupted && func)
- func(req, data);
- pthread_mutex_unlock(&req->lock);
+ pthread_mutex_lock(&req->lock);
+ req->u.ni.func = func;
+ req->u.ni.data = data;
+ if (req->interrupted && func)
+ func(req, data);
+ pthread_mutex_unlock(&req->lock);
}
int fuse_req_interrupted(fuse_req_t req)
{
- int interrupted;
+ int interrupted;
- pthread_mutex_lock(&req->f->lock);
- interrupted = req->interrupted;
- pthread_mutex_unlock(&req->f->lock);
+ pthread_mutex_lock(&req->f->lock);
+ interrupted = req->interrupted;
+ pthread_mutex_unlock(&req->f->lock);
- return interrupted;
+ return interrupted;
}
static struct {
- void (*func)(fuse_req_t, fuse_ino_t, const void *);
- const char *name;
+ void (*func)(fuse_req_t, fuse_ino_t, const void *);
+ const char *name;
} fuse_ll_ops[] = {
- [FUSE_LOOKUP] = { do_lookup, "LOOKUP" },
- [FUSE_FORGET] = { do_forget, "FORGET" },
- [FUSE_GETATTR] = { do_getattr, "GETATTR" },
- [FUSE_SETATTR] = { do_setattr, "SETATTR" },
- [FUSE_READLINK] = { do_readlink, "READLINK" },
- [FUSE_SYMLINK] = { do_symlink, "SYMLINK" },
- [FUSE_MKNOD] = { do_mknod, "MKNOD" },
- [FUSE_MKDIR] = { do_mkdir, "MKDIR" },
- [FUSE_UNLINK] = { do_unlink, "UNLINK" },
- [FUSE_RMDIR] = { do_rmdir, "RMDIR" },
- [FUSE_RENAME] = { do_rename, "RENAME" },
- [FUSE_LINK] = { do_link, "LINK" },
- [FUSE_OPEN] = { do_open, "OPEN" },
- [FUSE_READ] = { do_read, "READ" },
- [FUSE_WRITE] = { do_write, "WRITE" },
- [FUSE_STATFS] = { do_statfs, "STATFS" },
- [FUSE_RELEASE] = { do_release, "RELEASE" },
- [FUSE_FSYNC] = { do_fsync, "FSYNC" },
- [FUSE_SETXATTR] = { do_setxattr, "SETXATTR" },
- [FUSE_GETXATTR] = { do_getxattr, "GETXATTR" },
- [FUSE_LISTXATTR] = { do_listxattr, "LISTXATTR" },
- [FUSE_REMOVEXATTR] = { do_removexattr, "REMOVEXATTR" },
- [FUSE_FLUSH] = { do_flush, "FLUSH" },
- [FUSE_INIT] = { do_init, "INIT" },
- [FUSE_OPENDIR] = { do_opendir, "OPENDIR" },
- [FUSE_READDIR] = { do_readdir, "READDIR" },
- [FUSE_RELEASEDIR] = { do_releasedir, "RELEASEDIR" },
- [FUSE_FSYNCDIR] = { do_fsyncdir, "FSYNCDIR" },
- [FUSE_GETLK] = { do_getlk, "GETLK" },
- [FUSE_SETLK] = { do_setlk, "SETLK" },
- [FUSE_SETLKW] = { do_setlkw, "SETLKW" },
- [FUSE_ACCESS] = { do_access, "ACCESS" },
- [FUSE_CREATE] = { do_create, "CREATE" },
- [FUSE_INTERRUPT] = { do_interrupt, "INTERRUPT" },
- [FUSE_BMAP] = { do_bmap, "BMAP" },
- [FUSE_DESTROY] = { do_destroy, "DESTROY" },
+ [FUSE_LOOKUP] = { do_lookup, "LOOKUP" },
+ [FUSE_FORGET] = { do_forget, "FORGET" },
+ [FUSE_GETATTR] = { do_getattr, "GETATTR" },
+ [FUSE_SETATTR] = { do_setattr, "SETATTR" },
+ [FUSE_READLINK] = { do_readlink, "READLINK" },
+ [FUSE_SYMLINK] = { do_symlink, "SYMLINK" },
+ [FUSE_MKNOD] = { do_mknod, "MKNOD" },
+ [FUSE_MKDIR] = { do_mkdir, "MKDIR" },
+ [FUSE_UNLINK] = { do_unlink, "UNLINK" },
+ [FUSE_RMDIR] = { do_rmdir, "RMDIR" },
+ [FUSE_RENAME] = { do_rename, "RENAME" },
+ [FUSE_LINK] = { do_link, "LINK" },
+ [FUSE_OPEN] = { do_open, "OPEN" },
+ [FUSE_READ] = { do_read, "READ" },
+ [FUSE_WRITE] = { do_write, "WRITE" },
+ [FUSE_STATFS] = { do_statfs, "STATFS" },
+ [FUSE_RELEASE] = { do_release, "RELEASE" },
+ [FUSE_FSYNC] = { do_fsync, "FSYNC" },
+ [FUSE_SETXATTR] = { do_setxattr, "SETXATTR" },
+ [FUSE_GETXATTR] = { do_getxattr, "GETXATTR" },
+ [FUSE_LISTXATTR] = { do_listxattr, "LISTXATTR" },
+ [FUSE_REMOVEXATTR] = { do_removexattr, "REMOVEXATTR" },
+ [FUSE_FLUSH] = { do_flush, "FLUSH" },
+ [FUSE_INIT] = { do_init, "INIT" },
+ [FUSE_OPENDIR] = { do_opendir, "OPENDIR" },
+ [FUSE_READDIR] = { do_readdir, "READDIR" },
+ [FUSE_RELEASEDIR] = { do_releasedir, "RELEASEDIR" },
+ [FUSE_FSYNCDIR] = { do_fsyncdir, "FSYNCDIR" },
+ [FUSE_GETLK] = { do_getlk, "GETLK" },
+ [FUSE_SETLK] = { do_setlk, "SETLK" },
+ [FUSE_SETLKW] = { do_setlkw, "SETLKW" },
+ [FUSE_ACCESS] = { do_access, "ACCESS" },
+ [FUSE_CREATE] = { do_create, "CREATE" },
+ [FUSE_INTERRUPT] = { do_interrupt, "INTERRUPT" },
+ [FUSE_BMAP] = { do_bmap, "BMAP" },
+ [FUSE_DESTROY] = { do_destroy, "DESTROY" },
};
#define FUSE_MAXOP (sizeof(fuse_ll_ops) / sizeof(fuse_ll_ops[0]))
static const char *opname(enum fuse_opcode opcode)
{
- if (opcode >= FUSE_MAXOP || !fuse_ll_ops[opcode].name)
- return "???";
- else
- return fuse_ll_ops[opcode].name;
+ if (opcode >= FUSE_MAXOP || !fuse_ll_ops[opcode].name)
+ return "???";
+ else
+ return fuse_ll_ops[opcode].name;
}
static void fuse_ll_process(void *data, const char *buf, size_t len,
- struct fuse_chan *ch)
-{
- struct fuse_ll *f = (struct fuse_ll *) data;
- struct fuse_in_header *in = (struct fuse_in_header *) buf;
- const void *inarg = buf + sizeof(struct fuse_in_header);
- struct fuse_req *req;
-
- if (f->debug)
- fprintf(stderr, "unique: %llu, opcode: %s (%i), nodeid: %lu, insize: %zu\n",
- (unsigned long long) in->unique,
- opname((enum fuse_opcode) in->opcode), in->opcode,
- (unsigned long) in->nodeid, len);
-
- req = (struct fuse_req *) calloc(1, sizeof(struct fuse_req));
- if (req == NULL) {
- fprintf(stderr, "fuse: failed to allocate request\n");
- return;
- }
-
- req->f = f;
- req->unique = in->unique;
- req->ctx.uid = in->uid;
- req->ctx.gid = in->gid;
- req->ctx.pid = in->pid;
- req->ch = ch;
- req->ctr = 1;
- list_init_req(req);
- fuse_mutex_init(&req->lock);
-
- if (!f->got_init && in->opcode != FUSE_INIT)
- 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 &&
- in->opcode != FUSE_RELEASE && in->opcode != FUSE_READDIR &&
- in->opcode != FUSE_FSYNCDIR && in->opcode != FUSE_RELEASEDIR) {
- fuse_reply_err(req, EACCES);
- } else if (in->opcode >= FUSE_MAXOP || !fuse_ll_ops[in->opcode].func)
- fuse_reply_err(req, ENOSYS);
- else {
- if (in->opcode != FUSE_INTERRUPT) {
- struct fuse_req *intr;
- pthread_mutex_lock(&f->lock);
- intr = check_interrupt(f, req);
- list_add_req(req, &f->list);
- pthread_mutex_unlock(&f->lock);
- if (intr)
- fuse_reply_err(intr, EAGAIN);
- }
- fuse_ll_ops[in->opcode].func(req, in->nodeid, inarg);
- }
+ struct fuse_chan *ch)
+{
+ struct fuse_ll *f = (struct fuse_ll *) data;
+ struct fuse_in_header *in = (struct fuse_in_header *) buf;
+ const void *inarg = buf + sizeof(struct fuse_in_header);
+ struct fuse_req *req;
+
+ if (f->debug)
+ fprintf(stderr,
+ "unique: %llu, opcode: %s (%i), nodeid: %lu, insize: %zu\n",
+ (unsigned long long) in->unique,
+ opname((enum fuse_opcode) in->opcode), in->opcode,
+ (unsigned long) in->nodeid, len);
+
+ req = (struct fuse_req *) calloc(1, sizeof(struct fuse_req));
+ if (req == NULL) {
+ fprintf(stderr, "fuse: failed to allocate request\n");
+ return;
+ }
+
+ req->f = f;
+ req->unique = in->unique;
+ req->ctx.uid = in->uid;
+ req->ctx.gid = in->gid;
+ req->ctx.pid = in->pid;
+ req->ch = ch;
+ req->ctr = 1;
+ list_init_req(req);
+ fuse_mutex_init(&req->lock);
+
+ if (!f->got_init && in->opcode != FUSE_INIT)
+ 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 &&
+ in->opcode != FUSE_RELEASE && in->opcode != FUSE_READDIR &&
+ in->opcode != FUSE_FSYNCDIR && in->opcode != FUSE_RELEASEDIR) {
+ fuse_reply_err(req, EACCES);
+ } else if (in->opcode >= FUSE_MAXOP || !fuse_ll_ops[in->opcode].func)
+ fuse_reply_err(req, ENOSYS);
+ else {
+ if (in->opcode != FUSE_INTERRUPT) {
+ struct fuse_req *intr;
+ pthread_mutex_lock(&f->lock);
+ intr = check_interrupt(f, req);
+ list_add_req(req, &f->list);
+ pthread_mutex_unlock(&f->lock);
+ if (intr)
+ fuse_reply_err(intr, EAGAIN);
+ }
+ fuse_ll_ops[in->opcode].func(req, in->nodeid, inarg);
+ }
}
enum {
- KEY_HELP,
- KEY_VERSION,
+ KEY_HELP,
+ KEY_VERSION,
};
static struct fuse_opt fuse_ll_opts[] = {
- { "debug", offsetof(struct fuse_ll, debug), 1 },
- { "-d", offsetof(struct fuse_ll, debug), 1 },
- { "allow_root", offsetof(struct fuse_ll, allow_root), 1 },
- { "max_write=%u", offsetof(struct fuse_ll, conn.max_write), 0 },
- { "max_readahead=%u", offsetof(struct fuse_ll, conn.max_readahead), 0 },
- { "async_read", offsetof(struct fuse_ll, conn.async_read), 1 },
- { "sync_read", offsetof(struct fuse_ll, conn.async_read), 0 },
- FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_DISCARD),
- FUSE_OPT_KEY("-h", KEY_HELP),
- FUSE_OPT_KEY("--help", KEY_HELP),
- FUSE_OPT_KEY("-V", KEY_VERSION),
- FUSE_OPT_KEY("--version", KEY_VERSION),
- FUSE_OPT_END
+ { "debug", offsetof(struct fuse_ll, debug), 1 },
+ { "-d", offsetof(struct fuse_ll, debug), 1 },
+ { "allow_root", offsetof(struct fuse_ll, allow_root), 1 },
+ { "max_write=%u", offsetof(struct fuse_ll, conn.max_write), 0 },
+ { "max_readahead=%u", offsetof(struct fuse_ll, conn.max_readahead), 0 },
+ { "async_read", offsetof(struct fuse_ll, conn.async_read), 1 },
+ { "sync_read", offsetof(struct fuse_ll, conn.async_read), 0 },
+ FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_DISCARD),
+ FUSE_OPT_KEY("-h", KEY_HELP),
+ FUSE_OPT_KEY("--help", KEY_HELP),
+ FUSE_OPT_KEY("-V", KEY_VERSION),
+ FUSE_OPT_KEY("--version", KEY_VERSION),
+ FUSE_OPT_END
};
static void fuse_ll_version(void)
{
- fprintf(stderr, "using FUSE kernel interface version %i.%i\n",
- FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
+ fprintf(stderr, "using FUSE kernel interface version %i.%i\n",
+ FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
}
static void fuse_ll_help(void)
{
- fprintf(stderr,
-" -o max_write=N set maximum size of write requests\n"
-" -o max_readahead=N set maximum readahead\n"
-" -o async_read perform reads asynchronously (default)\n"
-" -o sync_read perform reads synchronously\n");
+ fprintf(stderr,
+" -o max_write=N set maximum size of write requests\n"
+" -o max_readahead=N set maximum readahead\n"
+" -o async_read perform reads asynchronously (default)\n"
+" -o sync_read perform reads synchronously\n");
}
static int fuse_ll_opt_proc(void *data, const char *arg, int key,
- struct fuse_args *outargs)
+ struct fuse_args *outargs)
{
- (void) data; (void) outargs;
+ (void) data; (void) outargs;
- switch (key) {
- case KEY_HELP:
- fuse_ll_help();
- break;
+ switch (key) {
+ case KEY_HELP:
+ fuse_ll_help();
+ break;
- case KEY_VERSION:
- fuse_ll_version();
- break;
+ case KEY_VERSION:
+ fuse_ll_version();
+ break;
- default:
- fprintf(stderr, "fuse: unknown option `%s'\n", arg);
- }
+ default:
+ fprintf(stderr, "fuse: unknown option `%s'\n", arg);
+ }
- return -1;
+ return -1;
}
int fuse_lowlevel_is_lib_option(const char *opt)
{
- return fuse_opt_match(fuse_ll_opts, opt);
+ return fuse_opt_match(fuse_ll_opts, opt);
}
static void fuse_ll_destroy(void *data)
{
- struct fuse_ll *f = (struct fuse_ll *) data;
+ struct fuse_ll *f = (struct fuse_ll *) data;
- if (f->got_init && !f->got_destroy) {
- if (f->op.destroy)
- f->op.destroy(f->userdata);
- }
+ if (f->got_init && !f->got_destroy) {
+ if (f->op.destroy)
+ f->op.destroy(f->userdata);
+ }
- pthread_mutex_destroy(&f->lock);
- free(f);
+ pthread_mutex_destroy(&f->lock);
+ free(f);
}
/*
@@ -1255,158 +1264,158 @@ static void fuse_ll_destroy(void *data)
* version of a symbol to internal references.
*/
struct fuse_session *fuse_lowlevel_new_common(struct fuse_args *args,
- const struct fuse_lowlevel_ops *op,
- size_t op_size, void *userdata)
+ const struct fuse_lowlevel_ops *op,
+ size_t op_size, void *userdata)
{
- struct fuse_ll *f;
- struct fuse_session *se;
- struct fuse_session_ops sop = {
- .process = fuse_ll_process,
- .destroy = fuse_ll_destroy,
- };
+ struct fuse_ll *f;
+ struct fuse_session *se;
+ struct fuse_session_ops sop = {
+ .process = fuse_ll_process,
+ .destroy = fuse_ll_destroy,
+ };
- if (sizeof(struct fuse_lowlevel_ops) < op_size) {
- fprintf(stderr, "fuse: warning: library too old, some operations may not work\n");
- op_size = sizeof(struct fuse_lowlevel_ops);
- }
+ if (sizeof(struct fuse_lowlevel_ops) < op_size) {
+ fprintf(stderr, "fuse: warning: library too old, some operations may not work\n");
+ op_size = sizeof(struct fuse_lowlevel_ops);
+ }
- f = (struct fuse_ll *) calloc(1, sizeof(struct fuse_ll));
- if (f == NULL) {
- fprintf(stderr, "fuse: failed to allocate fuse object\n");
- goto out;
- }
+ f = (struct fuse_ll *) calloc(1, sizeof(struct fuse_ll));
+ if (f == NULL) {
+ fprintf(stderr, "fuse: failed to allocate fuse object\n");
+ goto out;
+ }
- f->conn.async_read = 1;
- f->conn.max_write = UINT_MAX;
- f->conn.max_readahead = UINT_MAX;
- list_init_req(&f->list);
- list_init_req(&f->interrupts);
- fuse_mutex_init(&f->lock);
+ f->conn.async_read = 1;
+ f->conn.max_write = UINT_MAX;
+ f->conn.max_readahead = UINT_MAX;
+ list_init_req(&f->list);
+ list_init_req(&f->interrupts);
+ fuse_mutex_init(&f->lock);
- if (fuse_opt_parse(args, f, fuse_ll_opts, fuse_ll_opt_proc) == -1)
- goto out_free;
+ if (fuse_opt_parse(args, f, fuse_ll_opts, fuse_ll_opt_proc) == -1)
+ goto out_free;
- memcpy(&f->op, op, op_size);
- f->owner = getuid();
- f->userdata = userdata;
+ memcpy(&f->op, op, op_size);
+ f->owner = getuid();
+ f->userdata = userdata;
- se = fuse_session_new(&sop, f);
- if (!se)
- goto out_free;
+ se = fuse_session_new(&sop, f);
+ if (!se)
+ goto out_free;
- return se;
+ return se;
- out_free:
- free(f);
- out:
- return NULL;
+out_free:
+ free(f);
+out:
+ return NULL;
}
struct fuse_session *fuse_lowlevel_new(struct fuse_args *args,
- const struct fuse_lowlevel_ops *op,
- size_t op_size, void *userdata)
+ const struct fuse_lowlevel_ops *op,
+ size_t op_size, void *userdata)
{
- return fuse_lowlevel_new_common(args, op, op_size, userdata);
+ return fuse_lowlevel_new_common(args, op, op_size, userdata);
}
#ifndef __FreeBSD__
static void fill_open_compat(struct fuse_open_out *arg,
- const struct fuse_file_info_compat *f)
+ const struct fuse_file_info_compat *f)
{
- arg->fh = f->fh;
- if (f->direct_io)
- arg->open_flags |= FOPEN_DIRECT_IO;
- if (f->keep_cache)
- arg->open_flags |= FOPEN_KEEP_CACHE;
+ arg->fh = f->fh;
+ if (f->direct_io)
+ arg->open_flags |= FOPEN_DIRECT_IO;
+ if (f->keep_cache)
+ arg->open_flags |= FOPEN_KEEP_CACHE;
}
static void convert_statfs_compat(const struct statfs *compatbuf,
- struct statvfs *buf)
+ struct statvfs *buf)
{
- buf->f_bsize = compatbuf->f_bsize;
- buf->f_blocks = compatbuf->f_blocks;
- buf->f_bfree = compatbuf->f_bfree;
- buf->f_bavail = compatbuf->f_bavail;
- buf->f_files = compatbuf->f_files;
- buf->f_ffree = compatbuf->f_ffree;
- buf->f_namemax = compatbuf->f_namelen;
+ buf->f_bsize = compatbuf->f_bsize;
+ buf->f_blocks = compatbuf->f_blocks;
+ buf->f_bfree = compatbuf->f_bfree;
+ buf->f_bavail = compatbuf->f_bavail;
+ buf->f_files = compatbuf->f_files;
+ buf->f_ffree = compatbuf->f_ffree;
+ buf->f_namemax = compatbuf->f_namelen;
}
int fuse_reply_open_compat(fuse_req_t req,
- const struct fuse_file_info_compat *f)
+ const struct fuse_file_info_compat *f)
{
- struct fuse_open_out arg;
+ struct fuse_open_out arg;
- memset(&arg, 0, sizeof(arg));
- fill_open_compat(&arg, f);
- return send_reply_ok(req, &arg, sizeof(arg));
+ memset(&arg, 0, sizeof(arg));
+ fill_open_compat(&arg, f);
+ return send_reply_ok(req, &arg, sizeof(arg));
}
int fuse_reply_statfs_compat(fuse_req_t req, const struct statfs *stbuf)
{
- struct statvfs newbuf;
+ struct statvfs newbuf;
- memset(&newbuf, 0, sizeof(newbuf));
- convert_statfs_compat(stbuf, &newbuf);
+ memset(&newbuf, 0, sizeof(newbuf));
+ convert_statfs_compat(stbuf, &newbuf);
- return fuse_reply_statfs(req, &newbuf);
+ return fuse_reply_statfs(req, &newbuf);
}
struct fuse_session *fuse_lowlevel_new_compat(const char *opts,
- const struct fuse_lowlevel_ops_compat *op,
- size_t op_size, void *userdata)
+ const struct fuse_lowlevel_ops_compat *op,
+ size_t op_size, void *userdata)
{
- struct fuse_session *se;
- struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
+ struct fuse_session *se;
+ struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
- if (opts &&
- (fuse_opt_add_arg(&args, "") == -1 ||
- fuse_opt_add_arg(&args, "-o") == -1 ||
- fuse_opt_add_arg(&args, opts) == -1)) {
- fuse_opt_free_args(&args);
- return NULL;
- }
- se = fuse_lowlevel_new(&args, (const struct fuse_lowlevel_ops *) op,
- op_size, userdata);
- fuse_opt_free_args(&args);
+ if (opts &&
+ (fuse_opt_add_arg(&args, "") == -1 ||
+ fuse_opt_add_arg(&args, "-o") == -1 ||
+ fuse_opt_add_arg(&args, opts) == -1)) {
+ fuse_opt_free_args(&args);
+ return NULL;
+ }
+ se = fuse_lowlevel_new(&args, (const struct fuse_lowlevel_ops *) op,
+ op_size, userdata);
+ fuse_opt_free_args(&args);
- return se;
+ return se;
}
struct fuse_ll_compat_conf {
- unsigned max_read;
- int set_max_read;
+ unsigned max_read;
+ int set_max_read;
};
static const struct fuse_opt fuse_ll_opts_compat[] = {
- { "max_read=", offsetof(struct fuse_ll_compat_conf, set_max_read), 1 },
- { "max_read=%u", offsetof(struct fuse_ll_compat_conf, max_read), 0 },
- FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_KEEP),
- FUSE_OPT_END
+ { "max_read=", offsetof(struct fuse_ll_compat_conf, set_max_read), 1 },
+ { "max_read=%u", offsetof(struct fuse_ll_compat_conf, max_read), 0 },
+ FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_KEEP),
+ FUSE_OPT_END
};
int fuse_sync_compat_args(struct fuse_args *args)
{
- struct fuse_ll_compat_conf conf;
+ struct fuse_ll_compat_conf conf;
- memset(&conf, 0, sizeof(conf));
- if (fuse_opt_parse(args, &conf, fuse_ll_opts_compat, NULL) == -1)
- return -1;
+ memset(&conf, 0, sizeof(conf));
+ if (fuse_opt_parse(args, &conf, fuse_ll_opts_compat, NULL) == -1)
+ return -1;
- if (fuse_opt_insert_arg(args, 1, "-osync_read"))
- return -1;
+ if (fuse_opt_insert_arg(args, 1, "-osync_read"))
+ return -1;
- if (conf.set_max_read) {
- char tmpbuf[64];
+ if (conf.set_max_read) {
+ char tmpbuf[64];
- sprintf(tmpbuf, "-omax_readahead=%u", conf.max_read);
- if (fuse_opt_insert_arg(args, 1, tmpbuf) == -1)
- return -1;
- }
- return 0;
+ sprintf(tmpbuf, "-omax_readahead=%u", conf.max_read);
+ if (fuse_opt_insert_arg(args, 1, tmpbuf) == -1)
+ return -1;
+ }
+ return 0;
}
FUSE_SYMVER(".symver fuse_reply_statfs_compat,fuse_reply_statfs@FUSE_2.4");
@@ -1417,22 +1426,22 @@ FUSE_SYMVER(".symver fuse_lowlevel_new_compat,fuse_lowlevel_new@FUSE_2.4");
int fuse_sync_compat_args(struct fuse_args *args)
{
- (void) args;
- return 0;
+ (void) args;
+ return 0;
}
#endif /* __FreeBSD__ */
struct fuse_session *fuse_lowlevel_new_compat25(struct fuse_args *args,
- const struct fuse_lowlevel_ops_compat25 *op,
- size_t op_size, void *userdata)
+ const struct fuse_lowlevel_ops_compat25 *op,
+ size_t op_size, void *userdata)
{
- if (fuse_sync_compat_args(args) == -1)
- return NULL;
+ if (fuse_sync_compat_args(args) == -1)
+ return NULL;
- return fuse_lowlevel_new_common(args,
- (const struct fuse_lowlevel_ops *) op,
- op_size, userdata);
+ return fuse_lowlevel_new_common(args,
+ (const struct fuse_lowlevel_ops *) op,
+ op_size, userdata);
}
FUSE_SYMVER(".symver fuse_lowlevel_new_compat25,fuse_lowlevel_new@FUSE_2.5");
diff --git a/lib/fuse_misc.h b/lib/fuse_misc.h
index 4f5236a..c2cfee1 100644
--- a/lib/fuse_misc.h
+++ b/lib/fuse_misc.h
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
#include "config.h"
@@ -22,11 +22,11 @@
/* Is this hack still needed? */
static inline void fuse_mutex_init(pthread_mutex_t *mut)
{
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
- pthread_mutex_init(mut, &attr);
- pthread_mutexattr_destroy(&attr);
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
+ pthread_mutex_init(mut, &attr);
+ pthread_mutexattr_destroy(&attr);
}
#endif
diff --git a/lib/fuse_mt.c b/lib/fuse_mt.c
index cbdc1a3..95c3a5c 100644
--- a/lib/fuse_mt.c
+++ b/lib/fuse_mt.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB.
*/
#include "fuse_i.h"
@@ -17,100 +17,100 @@
#include <assert.h>
struct procdata {
- struct fuse *f;
- struct fuse_chan *prevch;
- struct fuse_session *prevse;
- fuse_processor_t proc;
- void *data;
+ struct fuse *f;
+ struct fuse_chan *prevch;
+ struct fuse_session *prevse;
+ fuse_processor_t proc;
+ void *data;
};
static void mt_session_proc(void *data, const char *buf, size_t len,
- struct fuse_chan *ch)
+ struct fuse_chan *ch)
{
- struct procdata *pd = (struct procdata *) data;
- struct fuse_cmd *cmd = *(struct fuse_cmd **) buf;
+ struct procdata *pd = (struct procdata *) data;
+ struct fuse_cmd *cmd = *(struct fuse_cmd **) buf;
- (void) len;
- (void) ch;
- pd->proc(pd->f, cmd, pd->data);
+ (void) len;
+ (void) ch;
+ pd->proc(pd->f, cmd, pd->data);
}
static void mt_session_exit(void *data, int val)
{
- struct procdata *pd = (struct procdata *) data;
- if (val)
- fuse_session_exit(pd->prevse);
- else
- fuse_session_reset(pd->prevse);
+ struct procdata *pd = (struct procdata *) data;
+ if (val)
+ fuse_session_exit(pd->prevse);
+ else
+ fuse_session_reset(pd->prevse);
}
static int mt_session_exited(void *data)
{
- struct procdata *pd = (struct procdata *) data;
- return fuse_session_exited(pd->prevse);
+ struct procdata *pd = (struct procdata *) data;
+ return fuse_session_exited(pd->prevse);
}
static int mt_chan_receive(struct fuse_chan **chp, char *buf, size_t size)
{
- struct fuse_cmd *cmd;
- struct procdata *pd = (struct procdata *) fuse_chan_data(*chp);
+ struct fuse_cmd *cmd;
+ struct procdata *pd = (struct procdata *) fuse_chan_data(*chp);
- assert(size >= sizeof(cmd));
+ assert(size >= sizeof(cmd));
- cmd = fuse_read_cmd(pd->f);
- if (cmd == NULL)
- return 0;
+ cmd = fuse_read_cmd(pd->f);
+ if (cmd == NULL)
+ return 0;
- *(struct fuse_cmd **) buf = cmd;
+ *(struct fuse_cmd **) buf = cmd;
- return sizeof(cmd);
+ return sizeof(cmd);
}
int fuse_loop_mt_proc(struct fuse *f, fuse_processor_t proc, void *data)
{
- int res;
- struct procdata pd;
- struct fuse_session *prevse = fuse_get_session(f);
- struct fuse_session *se;
- struct fuse_chan *prevch = fuse_session_next_chan(prevse, NULL);
- struct fuse_chan *ch;
- struct fuse_session_ops sop = {
- .exit = mt_session_exit,
- .exited = mt_session_exited,
- .process = mt_session_proc,
- };
- struct fuse_chan_ops cop = {
- .receive = mt_chan_receive,
- };
-
- pd.f = f;
- pd.prevch = prevch;
- pd.prevse = prevse;
- pd.proc = proc;
- pd.data = data;
-
- se = fuse_session_new(&sop, &pd);
- if (se == NULL)
- return -1;
-
- ch = fuse_chan_new(&cop, fuse_chan_fd(prevch), sizeof(struct fuse_cmd *),
- &pd);
- if (ch == NULL) {
- fuse_session_destroy(se);
- return -1;
- }
- fuse_session_add_chan(se, ch);
- res = fuse_session_loop_mt(se);
- fuse_session_destroy(se);
- return res;
+ int res;
+ struct procdata pd;
+ struct fuse_session *prevse = fuse_get_session(f);
+ struct fuse_session *se;
+ struct fuse_chan *prevch = fuse_session_next_chan(prevse, NULL);
+ struct fuse_chan *ch;
+ struct fuse_session_ops sop = {
+ .exit = mt_session_exit,
+ .exited = mt_session_exited,
+ .process = mt_session_proc,
+ };
+ struct fuse_chan_ops cop = {
+ .receive = mt_chan_receive,
+ };
+
+ pd.f = f;
+ pd.prevch = prevch;
+ pd.prevse = prevse;
+ pd.proc = proc;
+ pd.data = data;
+
+ se = fuse_session_new(&sop, &pd);
+ if (se == NULL)
+ return -1;
+
+ ch = fuse_chan_new(&cop, fuse_chan_fd(prevch),
+ sizeof(struct fuse_cmd *), &pd);
+ if (ch == NULL) {
+ fuse_session_destroy(se);
+ return -1;
+ }
+ fuse_session_add_chan(se, ch);
+ res = fuse_session_loop_mt(se);
+ fuse_session_destroy(se);
+ return res;
}
int fuse_loop_mt(struct fuse *f)
{
- if (f == NULL)
- return -1;
+ if (f == NULL)
+ return -1;
- return fuse_session_loop_mt(fuse_get_session(f));
+ return fuse_session_loop_mt(fuse_get_session(f));
}
FUSE_SYMVER(".symver fuse_loop_mt_proc,__fuse_loop_mt@");
diff --git a/lib/fuse_opt.c b/lib/fuse_opt.c
index d10e624..8a9019b 100644
--- a/lib/fuse_opt.c
+++ b/lib/fuse_opt.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
#include "fuse_opt.h"
@@ -15,71 +15,71 @@
#include <assert.h>
struct fuse_opt_context {
- void *data;
- const struct fuse_opt *opt;
- fuse_opt_proc_t proc;
- int argctr;
- int argc;
- char **argv;
- struct fuse_args outargs;
- char *opts;
- int nonopt;
+ void *data;
+ const struct fuse_opt *opt;
+ fuse_opt_proc_t proc;
+ int argctr;
+ int argc;
+ char **argv;
+ struct fuse_args outargs;
+ char *opts;
+ int nonopt;
};
void fuse_opt_free_args(struct fuse_args *args)
{
- if (args) {
- if (args->argv && args->allocated) {
- int i;
- for (i = 0; i < args->argc; i++)
- free(args->argv[i]);
- free(args->argv);
- }
- args->argc = 0;
- args->argv = NULL;
- args->allocated = 0;
- }
+ if (args) {
+ if (args->argv && args->allocated) {
+ int i;
+ for (i = 0; i < args->argc; i++)
+ free(args->argv[i]);
+ free(args->argv);
+ }
+ args->argc = 0;
+ args->argv = NULL;
+ args->allocated = 0;
+ }
}
static int alloc_failed(void)
{
- fprintf(stderr, "fuse: memory allocation failed\n");
- return -1;
+ fprintf(stderr, "fuse: memory allocation failed\n");
+ return -1;
}
int fuse_opt_add_arg(struct fuse_args *args, const char *arg)
{
- char **newargv;
- char *newarg;
+ char **newargv;
+ char *newarg;
- assert(!args->argv || args->allocated);
+ assert(!args->argv || args->allocated);
- newargv = realloc(args->argv, (args->argc + 2) * sizeof(char *));
- newarg = newargv ? strdup(arg) : NULL;
- if (!newargv || !newarg)
- return alloc_failed();
+ newargv = realloc(args->argv, (args->argc + 2) * sizeof(char *));
+ newarg = newargv ? strdup(arg) : NULL;
+ if (!newargv || !newarg)
+ return alloc_failed();
- args->argv = newargv;
- args->allocated = 1;
- args->argv[args->argc++] = newarg;
- args->argv[args->argc] = NULL;
- return 0;
+ args->argv = newargv;
+ args->allocated = 1;
+ args->argv[args->argc++] = newarg;
+ args->argv[args->argc] = NULL;
+ return 0;
}
static int fuse_opt_insert_arg_common(struct fuse_args *args, int pos,
const char *arg)
{
- assert(pos <= args->argc);
- if (fuse_opt_add_arg(args, arg) == -1)
- return -1;
-
- if (pos != args->argc - 1) {
- char *newarg = args->argv[args->argc - 1];
- memmove(&args->argv[pos + 1], &args->argv[pos],
- sizeof(char *) * (args->argc - pos - 1));
- args->argv[pos] = newarg;
- }
- return 0;
+ assert(pos <= args->argc);
+ if (fuse_opt_add_arg(args, arg) == -1)
+ return -1;
+
+ if (pos != args->argc - 1) {
+ char *newarg = args->argv[args->argc - 1];
+ memmove(&args->argv[pos + 1], &args->argv[pos],
+ sizeof(char *) * (args->argc - pos - 1));
+ args->argv[pos] = newarg;
+ }
+ return 0;
}
int fuse_opt_insert_arg(struct fuse_args *args, int pos, const char *arg)
@@ -96,288 +96,290 @@ int fuse_opt_insert_arg_compat(struct fuse_args *args, int pos, const char *arg)
static int next_arg(struct fuse_opt_context *ctx, const char *opt)
{
- if (ctx->argctr + 1 >= ctx->argc) {
- fprintf(stderr, "fuse: missing argument after `%s'\n", opt);
- return -1;
- }
- ctx->argctr++;
- return 0;
+ if (ctx->argctr + 1 >= ctx->argc) {
+ fprintf(stderr, "fuse: missing argument after `%s'\n", opt);
+ return -1;
+ }
+ ctx->argctr++;
+ return 0;
}
static int add_arg(struct fuse_opt_context *ctx, const char *arg)
{
- return fuse_opt_add_arg(&ctx->outargs, arg);
+ return fuse_opt_add_arg(&ctx->outargs, arg);
}
int fuse_opt_add_opt(char **opts, const char *opt)
{
- char *newopts;
- if (!*opts)
- newopts = strdup(opt);
- else {
- unsigned oldlen = strlen(*opts);
- newopts = realloc(*opts, oldlen + 1 + strlen(opt) + 1);
- if (newopts) {
- newopts[oldlen] = ',';
- strcpy(newopts + oldlen + 1, opt);
- }
- }
- if (!newopts)
- return alloc_failed();
-
- *opts = newopts;
- return 0;
+ char *newopts;
+ if (!*opts)
+ newopts = strdup(opt);
+ else {
+ unsigned oldlen = strlen(*opts);
+ newopts = realloc(*opts, oldlen + 1 + strlen(opt) + 1);
+ if (newopts) {
+ newopts[oldlen] = ',';
+ strcpy(newopts + oldlen + 1, opt);
+ }
+ }
+ if (!newopts)
+ return alloc_failed();
+
+ *opts = newopts;
+ return 0;
}
static int add_opt(struct fuse_opt_context *ctx, const char *opt)
{
- return fuse_opt_add_opt(&ctx->opts, opt);
+ return fuse_opt_add_opt(&ctx->opts, opt);
}
static int call_proc(struct fuse_opt_context *ctx, const char *arg, int key,
- int iso)
+ int iso)
{
- if (key == FUSE_OPT_KEY_DISCARD)
- return 0;
-
- if (key != FUSE_OPT_KEY_KEEP && ctx->proc) {
- int res = ctx->proc(ctx->data, arg, key, &ctx->outargs);
- if (res == -1 || !res)
- return res;
- }
- if (iso)
- return add_opt(ctx, arg);
- else
- return add_arg(ctx, arg);
+ if (key == FUSE_OPT_KEY_DISCARD)
+ return 0;
+
+ if (key != FUSE_OPT_KEY_KEEP && ctx->proc) {
+ int res = ctx->proc(ctx->data, arg, key, &ctx->outargs);
+ if (res == -1 || !res)
+ return res;
+ }
+ if (iso)
+ return add_opt(ctx, arg);
+ else
+ return add_arg(ctx, arg);
}
static int match_template(const char *t, const char *arg, unsigned *sepp)
{
- int arglen = strlen(arg);
- const char *sep = strchr(t, '=');
- sep = sep ? sep : strchr(t, ' ');
- if (sep && (!sep[1] || sep[1] == '%')) {
- int tlen = sep - t;
- if (sep[0] == '=')
- tlen ++;
- if (arglen >= tlen && strncmp(arg, t, tlen) == 0) {
- *sepp = sep - t;
- return 1;
- }
- }
- if (strcmp(t, arg) == 0) {
- *sepp = 0;
- return 1;
- }
- return 0;
+ int arglen = strlen(arg);
+ const char *sep = strchr(t, '=');
+ sep = sep ? sep : strchr(t, ' ');
+ if (sep && (!sep[1] || sep[1] == '%')) {
+ int tlen = sep - t;
+ if (sep[0] == '=')
+ tlen ++;
+ if (arglen >= tlen && strncmp(arg, t, tlen) == 0) {
+ *sepp = sep - t;
+ return 1;
+ }
+ }
+ if (strcmp(t, arg) == 0) {
+ *sepp = 0;
+ return 1;
+ }
+ return 0;
}
static const struct fuse_opt *find_opt(const struct fuse_opt *opt,
- const char *arg, unsigned *sepp)
+ const char *arg, unsigned *sepp)
{
- for (; opt && opt->templ; opt++)
- if (match_template(opt->templ, arg, sepp))
- return opt;
- return NULL;
+ for (; opt && opt->templ; opt++)
+ if (match_template(opt->templ, arg, sepp))
+ return opt;
+ return NULL;
}
int fuse_opt_match(const struct fuse_opt *opts, const char *opt)
{
- unsigned dummy;
- return find_opt(opts, opt, &dummy) ? 1 : 0;
+ unsigned dummy;
+ return find_opt(opts, opt, &dummy) ? 1 : 0;
}
static int process_opt_param(void *var, const char *format, const char *param,
- const char *arg)
+ const char *arg)
{
- assert(format[0] == '%');
- if (format[1] == 's') {
- char *copy = strdup(param);
- if (!copy)
- return alloc_failed();
-
- *(char **) var = copy;
- } else {
- if (sscanf(param, format, var) != 1) {
- fprintf(stderr, "fuse: invalid parameter in option `%s'\n", arg);
- return -1;
- }
- }
- return 0;
+ assert(format[0] == '%');
+ if (format[1] == 's') {
+ char *copy = strdup(param);
+ if (!copy)
+ return alloc_failed();
+
+ *(char **) var = copy;
+ } else {
+ if (sscanf(param, format, var) != 1) {
+ fprintf(stderr, "fuse: invalid parameter in option `%s'\n", arg);
+ return -1;
+ }
+ }
+ return 0;
}
static int process_opt(struct fuse_opt_context *ctx,
- const struct fuse_opt *opt, unsigned sep,
- const char *arg, int iso)
+ const struct fuse_opt *opt, unsigned sep,
+ const char *arg, int iso)
{
- if (opt->offset == -1U) {
- if (call_proc(ctx, arg, opt->value, iso) == -1)
- return -1;
- } else {
- void *var = ctx->data + opt->offset;
- if (sep && opt->templ[sep + 1]) {
- const char *param = arg + sep;
- if (opt->templ[sep] == '=')
- param ++;
- if (process_opt_param(var, opt->templ + sep + 1,
- param, arg) == -1)
- return -1;
- } else
- *(int *)var = opt->value;
- }
- return 0;
+ if (opt->offset == -1U) {
+ if (call_proc(ctx, arg, opt->value, iso) == -1)
+ return -1;
+ } else {
+ void *var = ctx->data + opt->offset;
+ if (sep && opt->templ[sep + 1]) {
+ const char *param = arg + sep;
+ if (opt->templ[sep] == '=')
+ param ++;
+ if (process_opt_param(var, opt->templ + sep + 1,
+ param, arg) == -1)
+ return -1;
+ } else
+ *(int *)var = opt->value;
+ }
+ return 0;
}
static int process_opt_sep_arg(struct fuse_opt_context *ctx,
- const struct fuse_opt *opt, unsigned sep,
- const char *arg, int iso)
+ const struct fuse_opt *opt, unsigned sep,
+ const char *arg, int iso)
{
- int res;
- char *newarg;
- char *param;
+ int res;
+ char *newarg;
+ char *param;
- if (next_arg(ctx, arg) == -1)
- return -1;
+ if (next_arg(ctx, arg) == -1)
+ return -1;
- param = ctx->argv[ctx->argctr];
- newarg = malloc(sep + strlen(param) + 1);
- if (!newarg)
- return alloc_failed();
+ param = ctx->argv[ctx->argctr];
+ newarg = malloc(sep + strlen(param) + 1);
+ if (!newarg)
+ return alloc_failed();
- memcpy(newarg, arg, sep);
- strcpy(newarg + sep, param);
- res = process_opt(ctx, opt, sep, newarg, iso);
- free(newarg);
+ memcpy(newarg, arg, sep);
+ strcpy(newarg + sep, param);
+ res = process_opt(ctx, opt, sep, newarg, iso);
+ free(newarg);
- return res;
+ return res;
}
static int process_gopt(struct fuse_opt_context *ctx, const char *arg, int iso)
{
- unsigned sep;
- const struct fuse_opt *opt = find_opt(ctx->opt, arg, &sep);
- if (opt) {
- for (; opt; opt = find_opt(opt + 1, arg, &sep)) {
- int res;
- if (sep && opt->templ[sep] == ' ' && !arg[sep])
- res = process_opt_sep_arg(ctx, opt, sep, arg, iso);
- else
- res = process_opt(ctx, opt, sep, arg, iso);
- if (res == -1)
- return -1;
- }
- return 0;
- } else
- return call_proc(ctx, arg, FUSE_OPT_KEY_OPT, iso);
+ unsigned sep;
+ const struct fuse_opt *opt = find_opt(ctx->opt, arg, &sep);
+ if (opt) {
+ for (; opt; opt = find_opt(opt + 1, arg, &sep)) {
+ int res;
+ if (sep && opt->templ[sep] == ' ' && !arg[sep])
+ res = process_opt_sep_arg(ctx, opt, sep, arg,
+ iso);
+ else
+ res = process_opt(ctx, opt, sep, arg, iso);
+ if (res == -1)
+ return -1;
+ }
+ return 0;
+ } else
+ return call_proc(ctx, arg, FUSE_OPT_KEY_OPT, iso);
}
static int process_real_option_group(struct fuse_opt_context *ctx, char *opts)
{
- char *sep;
-
- do {
- int res;
- sep = strchr(opts, ',');
- if (sep)
- *sep = '\0';
- res = process_gopt(ctx, opts, 1);
- if (res == -1)
- return -1;
- opts = sep + 1;
- } while (sep);
-
- return 0;
+ char *sep;
+
+ do {
+ int res;
+ sep = strchr(opts, ',');
+ if (sep)
+ *sep = '\0';
+ res = process_gopt(ctx, opts, 1);
+ if (res == -1)
+ return -1;
+ opts = sep + 1;
+ } while (sep);
+
+ return 0;
}
static int process_option_group(struct fuse_opt_context *ctx, const char *opts)
{
- int res;
- char *copy;
- const char *sep = strchr(opts, ',');
- if (!sep)
- return process_gopt(ctx, opts, 1);
-
- copy = strdup(opts);
- if (!copy) {
- fprintf(stderr, "fuse: memory allocation failed\n");
- return -1;
- }
- res = process_real_option_group(ctx, copy);
- free(copy);
- return res;
+ int res;
+ char *copy;
+ const char *sep = strchr(opts, ',');
+ if (!sep)
+ return process_gopt(ctx, opts, 1);
+
+ copy = strdup(opts);
+ if (!copy) {
+ fprintf(stderr, "fuse: memory allocation failed\n");
+ return -1;
+ }
+ res = process_real_option_group(ctx, copy);
+ free(copy);
+ return res;
}
static int process_one(struct fuse_opt_context *ctx, const char *arg)
{
- if (ctx->nonopt || arg[0] != '-')
- return call_proc(ctx, arg, FUSE_OPT_KEY_NONOPT, 0);
- else if (arg[1] == 'o') {
- if (arg[2])
- return process_option_group(ctx, arg + 2);
- else {
- if (next_arg(ctx, arg) == -1)
- return -1;
-
- return process_option_group(ctx, ctx->argv[ctx->argctr]);
- }
- } else if (arg[1] == '-' && !arg[2]) {
- if (add_arg(ctx, arg) == -1)
- return -1;
- ctx->nonopt = ctx->outargs.argc;
- return 0;
- } else
- return process_gopt(ctx, arg, 0);
+ if (ctx->nonopt || arg[0] != '-')
+ return call_proc(ctx, arg, FUSE_OPT_KEY_NONOPT, 0);
+ else if (arg[1] == 'o') {
+ if (arg[2])
+ return process_option_group(ctx, arg + 2);
+ else {
+ if (next_arg(ctx, arg) == -1)
+ return -1;
+
+ return process_option_group(ctx,
+ ctx->argv[ctx->argctr]);
+ }
+ } else if (arg[1] == '-' && !arg[2]) {
+ if (add_arg(ctx, arg) == -1)
+ return -1;
+ ctx->nonopt = ctx->outargs.argc;
+ return 0;
+ } else
+ return process_gopt(ctx, arg, 0);
}
static int opt_parse(struct fuse_opt_context *ctx)
{
- if (ctx->argc) {
- if (add_arg(ctx, ctx->argv[0]) == -1)
- return -1;
- }
-
- for (ctx->argctr = 1; ctx->argctr < ctx->argc; ctx->argctr++)
- if (process_one(ctx, ctx->argv[ctx->argctr]) == -1)
- return -1;
-
- if (ctx->opts) {
- if (fuse_opt_insert_arg(&ctx->outargs, 1, "-o") == -1 ||
- fuse_opt_insert_arg(&ctx->outargs, 2, ctx->opts) == -1)
- return -1;
- }
- if (ctx->nonopt && ctx->nonopt == ctx->outargs.argc) {
- free(ctx->outargs.argv[ctx->outargs.argc - 1]);
- ctx->outargs.argv[--ctx->outargs.argc] = NULL;
- }
-
- return 0;
+ if (ctx->argc) {
+ if (add_arg(ctx, ctx->argv[0]) == -1)
+ return -1;
+ }
+
+ for (ctx->argctr = 1; ctx->argctr < ctx->argc; ctx->argctr++)
+ if (process_one(ctx, ctx->argv[ctx->argctr]) == -1)
+ return -1;
+
+ if (ctx->opts) {
+ if (fuse_opt_insert_arg(&ctx->outargs, 1, "-o") == -1 ||
+ fuse_opt_insert_arg(&ctx->outargs, 2, ctx->opts) == -1)
+ return -1;
+ }
+ if (ctx->nonopt && ctx->nonopt == ctx->outargs.argc) {
+ free(ctx->outargs.argv[ctx->outargs.argc - 1]);
+ ctx->outargs.argv[--ctx->outargs.argc] = NULL;
+ }
+
+ return 0;
}
int fuse_opt_parse(struct fuse_args *args, void *data,
- const struct fuse_opt opts[], fuse_opt_proc_t proc)
+ const struct fuse_opt opts[], fuse_opt_proc_t proc)
{
- int res;
- struct fuse_opt_context ctx = {
- .data = data,
- .opt = opts,
- .proc = proc,
- };
-
- if (!args || !args->argv || !args->argc)
- return 0;
-
- ctx.argc = args->argc;
- ctx.argv = args->argv;
-
- res = opt_parse(&ctx);
- if (res != -1) {
- struct fuse_args tmp = *args;
- *args = ctx.outargs;
- ctx.outargs = tmp;
- }
- free(ctx.opts);
- fuse_opt_free_args(&ctx.outargs);
- return res;
+ int res;
+ struct fuse_opt_context ctx = {
+ .data = data,
+ .opt = opts,
+ .proc = proc,
+ };
+
+ if (!args || !args->argv || !args->argc)
+ return 0;
+
+ ctx.argc = args->argc;
+ ctx.argv = args->argv;
+
+ res = opt_parse(&ctx);
+ if (res != -1) {
+ struct fuse_args tmp = *args;
+ *args = ctx.outargs;
+ ctx.outargs = tmp;
+ }
+ free(ctx.opts);
+ fuse_opt_free_args(&ctx.outargs);
+ return res;
}
/* This symbol version was mistakenly added to the version script */
diff --git a/lib/fuse_session.c b/lib/fuse_session.c
index cf2e20b..5efedd9 100644
--- a/lib/fuse_session.c
+++ b/lib/fuse_session.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
#include "fuse_lowlevel.h"
@@ -18,190 +18,191 @@
#include <errno.h>
struct fuse_session {
- struct fuse_session_ops op;
+ struct fuse_session_ops op;
- void *data;
+ void *data;
- volatile int exited;
+ volatile int exited;
- struct fuse_chan *ch;
+ struct fuse_chan *ch;
};
struct fuse_chan {
- struct fuse_chan_ops op;
+ struct fuse_chan_ops op;
- struct fuse_session *se;
+ struct fuse_session *se;
- int fd;
+ int fd;
- size_t bufsize;
+ size_t bufsize;
- void *data;
+ void *data;
- int compat;
+ int compat;
};
struct fuse_session *fuse_session_new(struct fuse_session_ops *op, void *data)
{
- struct fuse_session *se = (struct fuse_session *) malloc(sizeof(*se));
- if (se == NULL) {
- fprintf(stderr, "fuse: failed to allocate session\n");
- return NULL;
- }
+ struct fuse_session *se = (struct fuse_session *) malloc(sizeof(*se));
+ if (se == NULL) {
+ fprintf(stderr, "fuse: failed to allocate session\n");
+ return NULL;
+ }
- memset(se, 0, sizeof(*se));
- se->op = *op;
- se->data = data;
+ memset(se, 0, sizeof(*se));
+ se->op = *op;
+ se->data = data;
- return se;
+ return se;
}
void fuse_session_add_chan(struct fuse_session *se, struct fuse_chan *ch)
{
- assert(se->ch == NULL);
- assert(ch->se == NULL);
- se->ch = ch;
- ch->se = se;
+ assert(se->ch == NULL);
+ assert(ch->se == NULL);
+ se->ch = ch;
+ ch->se = se;
}
void fuse_session_remove_chan(struct fuse_chan *ch)
{
- struct fuse_session *se = ch->se;
- if (se) {
- assert(se->ch == ch);
- se->ch = NULL;
- ch->se = NULL;
- }
+ struct fuse_session *se = ch->se;
+ if (se) {
+ assert(se->ch == ch);
+ se->ch = NULL;
+ ch->se = NULL;
+ }
}
struct fuse_chan *fuse_session_next_chan(struct fuse_session *se,
- struct fuse_chan *ch)
+ struct fuse_chan *ch)
{
- assert(ch == NULL || ch == se->ch);
- if (ch == NULL)
- return se->ch;
- else
- return NULL;
+ assert(ch == NULL || ch == se->ch);
+ if (ch == NULL)
+ return se->ch;
+ else
+ return NULL;
}
void fuse_session_process(struct fuse_session *se, const char *buf, size_t len,
- struct fuse_chan *ch)
+ struct fuse_chan *ch)
{
- se->op.process(se->data, buf, len, ch);
+ se->op.process(se->data, buf, len, ch);
}
void fuse_session_destroy(struct fuse_session *se)
{
- if (se->op.destroy)
- se->op.destroy(se->data);
- if (se->ch != NULL)
- fuse_chan_destroy(se->ch);
- free(se);
+ if (se->op.destroy)
+ se->op.destroy(se->data);
+ if (se->ch != NULL)
+ fuse_chan_destroy(se->ch);
+ free(se);
}
void fuse_session_exit(struct fuse_session *se)
{
- if (se->op.exit)
- se->op.exit(se->data, 1);
- se->exited = 1;
+ if (se->op.exit)
+ se->op.exit(se->data, 1);
+ se->exited = 1;
}
void fuse_session_reset(struct fuse_session *se)
{
- if (se->op.exit)
- se->op.exit(se->data, 0);
- se->exited = 0;
+ if (se->op.exit)
+ se->op.exit(se->data, 0);
+ se->exited = 0;
}
int fuse_session_exited(struct fuse_session *se)
{
- if (se->op.exited)
- return se->op.exited(se->data);
- else
- return se->exited;
+ if (se->op.exited)
+ return se->op.exited(se->data);
+ else
+ return se->exited;
}
static struct fuse_chan *fuse_chan_new_common(struct fuse_chan_ops *op, int fd,
- size_t bufsize, void *data, int compat)
+ size_t bufsize, void *data,
+ int compat)
{
- struct fuse_chan *ch = (struct fuse_chan *) malloc(sizeof(*ch));
- if (ch == NULL) {
- fprintf(stderr, "fuse: failed to allocate channel\n");
- return NULL;
- }
+ struct fuse_chan *ch = (struct fuse_chan *) malloc(sizeof(*ch));
+ if (ch == NULL) {
+ fprintf(stderr, "fuse: failed to allocate channel\n");
+ return NULL;
+ }
- memset(ch, 0, sizeof(*ch));
- ch->op = *op;
- ch->fd = fd;
- ch->bufsize = bufsize;
- ch->data = data;
- ch->compat = compat;
+ memset(ch, 0, sizeof(*ch));
+ ch->op = *op;
+ ch->fd = fd;
+ ch->bufsize = bufsize;
+ ch->data = data;
+ ch->compat = compat;
- return ch;
+ return ch;
}
struct fuse_chan *fuse_chan_new(struct fuse_chan_ops *op, int fd,
- size_t bufsize, void *data)
+ size_t bufsize, void *data)
{
- return fuse_chan_new_common(op, fd, bufsize, data, 0);
+ return fuse_chan_new_common(op, fd, bufsize, data, 0);
}
struct fuse_chan *fuse_chan_new_compat24(struct fuse_chan_ops_compat24 *op,
- int fd, size_t bufsize, void *data)
+ int fd, size_t bufsize, void *data)
{
- return fuse_chan_new_common((struct fuse_chan_ops *) op, fd, bufsize,
- data, 24);
+ return fuse_chan_new_common((struct fuse_chan_ops *) op, fd, bufsize,
+ data, 24);
}
int fuse_chan_fd(struct fuse_chan *ch)
{
- return ch->fd;
+ return ch->fd;
}
size_t fuse_chan_bufsize(struct fuse_chan *ch)
{
- return ch->bufsize;
+ return ch->bufsize;
}
void *fuse_chan_data(struct fuse_chan *ch)
{
- return ch->data;
+ return ch->data;
}
struct fuse_session *fuse_chan_session(struct fuse_chan *ch)
{
- return ch->se;
+ return ch->se;
}
int fuse_chan_recv(struct fuse_chan **chp, char *buf, size_t size)
{
- struct fuse_chan *ch = *chp;
- if (ch->compat)
- return ((struct fuse_chan_ops_compat24 *) &ch->op)
- ->receive(ch, buf, size);
- else
- return ch->op.receive(chp, buf, size);
+ struct fuse_chan *ch = *chp;
+ if (ch->compat)
+ return ((struct fuse_chan_ops_compat24 *) &ch->op)
+ ->receive(ch, buf, size);
+ else
+ return ch->op.receive(chp, buf, size);
}
int fuse_chan_receive(struct fuse_chan *ch, char *buf, size_t size)
{
- int res;
+ int res;
- res = fuse_chan_recv(&ch, buf, size);
- return res >= 0 ? res : (res != -EINTR && res != -EAGAIN) ? -1 : 0;
+ res = fuse_chan_recv(&ch, buf, size);
+ return res >= 0 ? res : (res != -EINTR && res != -EAGAIN) ? -1 : 0;
}
int fuse_chan_send(struct fuse_chan *ch, const struct iovec iov[], size_t count)
{
- return ch->op.send(ch, iov, count);
+ return ch->op.send(ch, iov, count);
}
void fuse_chan_destroy(struct fuse_chan *ch)
{
- fuse_session_remove_chan(ch);
- if (ch->op.destroy)
- ch->op.destroy(ch);
- free(ch);
+ fuse_session_remove_chan(ch);
+ if (ch->op.destroy)
+ ch->op.destroy(ch);
+ free(ch);
}
#ifndef __FreeBSD__
diff --git a/lib/fuse_signals.c b/lib/fuse_signals.c
index 25998bf..88ac39e 100644
--- a/lib/fuse_signals.c
+++ b/lib/fuse_signals.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
#include "fuse_lowlevel.h"
@@ -16,57 +16,57 @@ static struct fuse_session *fuse_instance;
static void exit_handler(int sig)
{
- (void) sig;
- if (fuse_instance)
- fuse_session_exit(fuse_instance);
+ (void) sig;
+ if (fuse_instance)
+ fuse_session_exit(fuse_instance);
}
static int set_one_signal_handler(int sig, void (*handler)(int))
{
- struct sigaction sa;
- struct sigaction old_sa;
+ struct sigaction sa;
+ struct sigaction old_sa;
- memset(&sa, 0, sizeof(struct sigaction));
- sa.sa_handler = handler;
- sigemptyset(&(sa.sa_mask));
- sa.sa_flags = 0;
+ memset(&sa, 0, sizeof(struct sigaction));
+ sa.sa_handler = handler;
+ sigemptyset(&(sa.sa_mask));
+ sa.sa_flags = 0;
- if (sigaction(sig, NULL, &old_sa) == -1) {
- perror("fuse: cannot get old signal handler");
- return -1;
- }
+ if (sigaction(sig, NULL, &old_sa) == -1) {
+ perror("fuse: cannot get old signal handler");
+ return -1;
+ }
- if (old_sa.sa_handler == SIG_DFL &&
- sigaction(sig, &sa, NULL) == -1) {
- perror("fuse: cannot set signal handler");
- return -1;
- }
- return 0;
+ if (old_sa.sa_handler == SIG_DFL &&
+ sigaction(sig, &sa, NULL) == -1) {
+ perror("fuse: cannot set signal handler");
+ return -1;
+ }
+ return 0;
}
int fuse_set_signal_handlers(struct fuse_session *se)
{
- if (set_one_signal_handler(SIGHUP, exit_handler) == -1 ||
- set_one_signal_handler(SIGINT, exit_handler) == -1 ||
- set_one_signal_handler(SIGTERM, exit_handler) == -1 ||
- set_one_signal_handler(SIGPIPE, SIG_IGN) == -1)
- return -1;
+ if (set_one_signal_handler(SIGHUP, exit_handler) == -1 ||
+ set_one_signal_handler(SIGINT, exit_handler) == -1 ||
+ set_one_signal_handler(SIGTERM, exit_handler) == -1 ||
+ set_one_signal_handler(SIGPIPE, SIG_IGN) == -1)
+ return -1;
- fuse_instance = se;
- return 0;
+ fuse_instance = se;
+ return 0;
}
void fuse_remove_signal_handlers(struct fuse_session *se)
{
- if (fuse_instance != se)
- fprintf(stderr,
- "fuse: fuse_remove_signal_handlers: unknown session\n");
- else
- fuse_instance = NULL;
+ if (fuse_instance != se)
+ fprintf(stderr,
+ "fuse: fuse_remove_signal_handlers: unknown session\n");
+ else
+ fuse_instance = NULL;
- set_one_signal_handler(SIGHUP, SIG_DFL);
- set_one_signal_handler(SIGINT, SIG_DFL);
- set_one_signal_handler(SIGTERM, SIG_DFL);
- set_one_signal_handler(SIGPIPE, SIG_DFL);
+ set_one_signal_handler(SIGHUP, SIG_DFL);
+ set_one_signal_handler(SIGINT, SIG_DFL);
+ set_one_signal_handler(SIGTERM, SIG_DFL);
+ set_one_signal_handler(SIGPIPE, SIG_DFL);
}
diff --git a/lib/helper.c b/lib/helper.c
index fbbf4b2..a175ee9 100644
--- a/lib/helper.c
+++ b/lib/helper.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB.
*/
#include "config.h"
@@ -22,333 +22,336 @@
#include <errno.h>
enum {
- KEY_HELP,
- KEY_HELP_NOHEADER,
- KEY_VERSION,
+ KEY_HELP,
+ KEY_HELP_NOHEADER,
+ KEY_VERSION,
};
struct helper_opts {
- int singlethread;
- int foreground;
- int nodefault_subtype;
- char *mountpoint;
+ int singlethread;
+ int foreground;
+ int nodefault_subtype;
+ char *mountpoint;
};
#define FUSE_HELPER_OPT(t, p) { t, offsetof(struct helper_opts, p), 1 }
static const struct fuse_opt fuse_helper_opts[] = {
- FUSE_HELPER_OPT("-d", foreground),
- FUSE_HELPER_OPT("debug", foreground),
- FUSE_HELPER_OPT("-f", foreground),
- FUSE_HELPER_OPT("-s", singlethread),
- FUSE_HELPER_OPT("fsname=", nodefault_subtype),
- FUSE_HELPER_OPT("subtype=", nodefault_subtype),
-
- FUSE_OPT_KEY("-h", KEY_HELP),
- FUSE_OPT_KEY("--help", KEY_HELP),
- FUSE_OPT_KEY("-ho", KEY_HELP_NOHEADER),
- FUSE_OPT_KEY("-V", KEY_VERSION),
- FUSE_OPT_KEY("--version", KEY_VERSION),
- FUSE_OPT_KEY("-d", FUSE_OPT_KEY_KEEP),
- FUSE_OPT_KEY("debug", FUSE_OPT_KEY_KEEP),
- FUSE_OPT_KEY("fsname=", FUSE_OPT_KEY_KEEP),
- FUSE_OPT_KEY("subtype=", FUSE_OPT_KEY_KEEP),
- FUSE_OPT_END
+ FUSE_HELPER_OPT("-d", foreground),
+ FUSE_HELPER_OPT("debug", foreground),
+ FUSE_HELPER_OPT("-f", foreground),
+ FUSE_HELPER_OPT("-s", singlethread),
+ FUSE_HELPER_OPT("fsname=", nodefault_subtype),
+ FUSE_HELPER_OPT("subtype=", nodefault_subtype),
+
+ FUSE_OPT_KEY("-h", KEY_HELP),
+ FUSE_OPT_KEY("--help", KEY_HELP),
+ FUSE_OPT_KEY("-ho", KEY_HELP_NOHEADER),
+ FUSE_OPT_KEY("-V", KEY_VERSION),
+ FUSE_OPT_KEY("--version", KEY_VERSION),
+ FUSE_OPT_KEY("-d", FUSE_OPT_KEY_KEEP),
+ FUSE_OPT_KEY("debug", FUSE_OPT_KEY_KEEP),
+ FUSE_OPT_KEY("fsname=", FUSE_OPT_KEY_KEEP),
+ FUSE_OPT_KEY("subtype=", FUSE_OPT_KEY_KEEP),
+ FUSE_OPT_END
};
static void usage(const char *progname)
{
- fprintf(stderr,
- "usage: %s mountpoint [options]\n\n", progname);
- fprintf(stderr,
- "general options:\n"
- " -o opt,[opt...] mount options\n"
- " -h --help print help\n"
- " -V --version print version\n"
- "\n");
+ fprintf(stderr,
+ "usage: %s mountpoint [options]\n\n", progname);
+ fprintf(stderr,
+ "general options:\n"
+ " -o opt,[opt...] mount options\n"
+ " -h --help print help\n"
+ " -V --version print version\n"
+ "\n");
}
static void helper_help(void)
{
- fprintf(stderr,
- "FUSE options:\n"
- " -d -o debug enable debug output (implies -f)\n"
- " -f foreground operation\n"
- " -s disable multi-threaded operation\n"
- "\n"
- );
+ fprintf(stderr,
+ "FUSE options:\n"
+ " -d -o debug enable debug output (implies -f)\n"
+ " -f foreground operation\n"
+ " -s disable multi-threaded operation\n"
+ "\n"
+ );
}
static void helper_version(void)
{
- fprintf(stderr, "FUSE library version: %s\n", PACKAGE_VERSION);
+ fprintf(stderr, "FUSE library version: %s\n", PACKAGE_VERSION);
}
static int fuse_helper_opt_proc(void *data, const char *arg, int key,
- struct fuse_args *outargs)
+ struct fuse_args *outargs)
{
- struct helper_opts *hopts = data;
-
- switch (key) {
- case KEY_HELP:
- usage(outargs->argv[0]);
- /* fall through */
-
- case KEY_HELP_NOHEADER:
- helper_help();
- return fuse_opt_add_arg(outargs, "-h");
-
- case KEY_VERSION:
- helper_version();
- return 1;
-
- case FUSE_OPT_KEY_NONOPT:
- if (!hopts->mountpoint) {
- char mountpoint[PATH_MAX];
- if (realpath(arg, mountpoint) == NULL) {
- fprintf(stderr, "fuse: bad mount point `%s': %s\n", arg, strerror(errno));
- return -1;
- }
- return fuse_opt_add_opt(&hopts->mountpoint, mountpoint);
- } else {
- fprintf(stderr, "fuse: invalid argument `%s'\n", arg);
- return -1;
- }
-
- default:
- return 1;
- }
+ struct helper_opts *hopts = data;
+
+ switch (key) {
+ case KEY_HELP:
+ usage(outargs->argv[0]);
+ /* fall through */
+
+ case KEY_HELP_NOHEADER:
+ helper_help();
+ return fuse_opt_add_arg(outargs, "-h");
+
+ case KEY_VERSION:
+ helper_version();
+ return 1;
+
+ case FUSE_OPT_KEY_NONOPT:
+ if (!hopts->mountpoint) {
+ char mountpoint[PATH_MAX];
+ if (realpath(arg, mountpoint) == NULL) {
+ fprintf(stderr,
+ "fuse: bad mount point `%s': %s\n",
+ arg, strerror(errno));
+ return -1;
+ }
+ return fuse_opt_add_opt(&hopts->mountpoint, mountpoint);
+ } else {
+ fprintf(stderr, "fuse: invalid argument `%s'\n", arg);
+ return -1;
+ }
+
+ default:
+ return 1;
+ }
}
static int add_default_subtype(const char *progname, struct fuse_args *args)
{
- int res;
- char *subtype_opt;
- const char *basename = strrchr(progname, '/');
- if (basename == NULL)
- basename = progname;
- else if (basename[1] != '\0')
- basename++;
-
- subtype_opt = (char *) malloc(strlen(basename) + 64);
- if (subtype_opt == NULL) {
- fprintf(stderr, "fuse: memory allocation failed\n");
- return -1;
- }
- sprintf(subtype_opt, "-osubtype=%s", basename);
- res = fuse_opt_add_arg(args, subtype_opt);
- free(subtype_opt);
- return res;
+ int res;
+ char *subtype_opt;
+ const char *basename = strrchr(progname, '/');
+ if (basename == NULL)
+ basename = progname;
+ else if (basename[1] != '\0')
+ basename++;
+
+ subtype_opt = (char *) malloc(strlen(basename) + 64);
+ if (subtype_opt == NULL) {
+ fprintf(stderr, "fuse: memory allocation failed\n");
+ return -1;
+ }
+ sprintf(subtype_opt, "-osubtype=%s", basename);
+ res = fuse_opt_add_arg(args, subtype_opt);
+ free(subtype_opt);
+ return res;
}
int fuse_parse_cmdline(struct fuse_args *args, char **mountpoint,
- int *multithreaded, int *foreground)
+ int *multithreaded, int *foreground)
{
- int res;
- struct helper_opts hopts;
-
- memset(&hopts, 0, sizeof(hopts));
- res = fuse_opt_parse(args, &hopts, fuse_helper_opts, fuse_helper_opt_proc);
- if (res == -1)
- return -1;
-
- if (!hopts.nodefault_subtype) {
- res = add_default_subtype(args->argv[0], args);
- if (res == -1)
- goto err;
- }
- if (mountpoint)
- *mountpoint = hopts.mountpoint;
- else
- free(hopts.mountpoint);
-
- if (multithreaded)
- *multithreaded = !hopts.singlethread;
- if (foreground)
- *foreground = hopts.foreground;
- return 0;
-
- err:
- free(hopts.mountpoint);
- return -1;
+ int res;
+ struct helper_opts hopts;
+
+ memset(&hopts, 0, sizeof(hopts));
+ res = fuse_opt_parse(args, &hopts, fuse_helper_opts,
+ fuse_helper_opt_proc);
+ if (res == -1)
+ return -1;
+
+ if (!hopts.nodefault_subtype) {
+ res = add_default_subtype(args->argv[0], args);
+ if (res == -1)
+ goto err;
+ }
+ if (mountpoint)
+ *mountpoint = hopts.mountpoint;
+ else
+ free(hopts.mountpoint);
+
+ if (multithreaded)
+ *multithreaded = !hopts.singlethread;
+ if (foreground)
+ *foreground = hopts.foreground;
+ return 0;
+
+err:
+ free(hopts.mountpoint);
+ return -1;
}
int fuse_daemonize(int foreground)
{
- int res;
-
- if (!foreground) {
- res = daemon(0, 0);
- if (res == -1) {
- perror("fuse: failed to daemonize program\n");
- return -1;
- }
- }
- return 0;
+ int res;
+
+ if (!foreground) {
+ res = daemon(0, 0);
+ if (res == -1) {
+ perror("fuse: failed to daemonize program\n");
+ return -1;
+ }
+ }
+ return 0;
}
static struct fuse_chan *fuse_mount_common(const char *mountpoint,
- struct fuse_args *args)
+ struct fuse_args *args)
{
- struct fuse_chan *ch;
- int fd;
-
- /*
- * Make sure file descriptors 0, 1 and 2 are open, otherwise chaos
- * would ensue.
- */
- do {
- fd = open("/dev/null", O_RDWR);
- if (fd > 2)
- close(fd);
- } while (fd >= 0 && fd <= 2);
-
- fd = fuse_mount_compat25(mountpoint, args);
- if (fd == -1)
- return NULL;
-
- ch = fuse_kern_chan_new(fd);
- if (!ch)
- fuse_kern_unmount(mountpoint, fd);
-
- return ch;
+ struct fuse_chan *ch;
+ int fd;
+
+ /*
+ * Make sure file descriptors 0, 1 and 2 are open, otherwise chaos
+ * would ensue.
+ */
+ do {
+ fd = open("/dev/null", O_RDWR);
+ if (fd > 2)
+ close(fd);
+ } while (fd >= 0 && fd <= 2);
+
+ fd = fuse_mount_compat25(mountpoint, args);
+ if (fd == -1)
+ return NULL;
+
+ ch = fuse_kern_chan_new(fd);
+ if (!ch)
+ fuse_kern_unmount(mountpoint, fd);
+
+ return ch;
}
struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args)
{
- return fuse_mount_common(mountpoint, args);
+ return fuse_mount_common(mountpoint, args);
}
static void fuse_unmount_common(const char *mountpoint, struct fuse_chan *ch)
{
- int fd = ch ? fuse_chan_fd(ch) : -1;
- fuse_kern_unmount(mountpoint, fd);
- fuse_chan_destroy(ch);
+ int fd = ch ? fuse_chan_fd(ch) : -1;
+ fuse_kern_unmount(mountpoint, fd);
+ fuse_chan_destroy(ch);
}
void fuse_unmount(const char *mountpoint, struct fuse_chan *ch)
{
- fuse_unmount_common(mountpoint, ch);
+ fuse_unmount_common(mountpoint, ch);
}
static struct fuse *fuse_setup_common(int argc, char *argv[],
- const struct fuse_operations *op,
- size_t op_size,
- char **mountpoint,
- int *multithreaded,
- int *fd,
- void *user_data,
- int compat)
+ const struct fuse_operations *op,
+ size_t op_size,
+ char **mountpoint,
+ int *multithreaded,
+ int *fd,
+ void *user_data,
+ int compat)
{
- struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
- struct fuse_chan *ch;
- struct fuse *fuse;
- int foreground;
- int res;
-
- res = fuse_parse_cmdline(&args, mountpoint, multithreaded, &foreground);
- if (res == -1)
- return NULL;
-
- ch = fuse_mount_common(*mountpoint, &args);
- if (!ch) {
- fuse_opt_free_args(&args);
- goto err_free;
- }
-
- fuse = fuse_new_common(ch, &args, op, op_size, user_data, compat);
- fuse_opt_free_args(&args);
- if (fuse == NULL)
- goto err_unmount;
-
- res = fuse_daemonize(foreground);
- if (res == -1)
- goto err_unmount;
-
- res = fuse_set_signal_handlers(fuse_get_session(fuse));
- if (res == -1)
- goto err_unmount;
-
- if (fd)
- *fd = fuse_chan_fd(ch);
-
- return fuse;
-
- err_unmount:
- fuse_unmount_common(*mountpoint, ch);
- if (fuse)
- fuse_destroy(fuse);
- err_free:
- free(*mountpoint);
- return NULL;
+ struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
+ struct fuse_chan *ch;
+ struct fuse *fuse;
+ int foreground;
+ int res;
+
+ res = fuse_parse_cmdline(&args, mountpoint, multithreaded, &foreground);
+ if (res == -1)
+ return NULL;
+
+ ch = fuse_mount_common(*mountpoint, &args);
+ if (!ch) {
+ fuse_opt_free_args(&args);
+ goto err_free;
+ }
+
+ fuse = fuse_new_common(ch, &args, op, op_size, user_data, compat);
+ fuse_opt_free_args(&args);
+ if (fuse == NULL)
+ goto err_unmount;
+
+ res = fuse_daemonize(foreground);
+ if (res == -1)
+ goto err_unmount;
+
+ res = fuse_set_signal_handlers(fuse_get_session(fuse));
+ if (res == -1)
+ goto err_unmount;
+
+ if (fd)
+ *fd = fuse_chan_fd(ch);
+
+ return fuse;
+
+err_unmount:
+ fuse_unmount_common(*mountpoint, ch);
+ if (fuse)
+ fuse_destroy(fuse);
+err_free:
+ free(*mountpoint);
+ return NULL;
}
struct fuse *fuse_setup(int argc, char *argv[],
- const struct fuse_operations *op, size_t op_size,
- char **mountpoint, int *multithreaded, void *user_data)
+ const struct fuse_operations *op, size_t op_size,
+ char **mountpoint, int *multithreaded, void *user_data)
{
- return fuse_setup_common(argc, argv, op, op_size, mountpoint,
- multithreaded, NULL, user_data, 0);
+ return fuse_setup_common(argc, argv, op, op_size, mountpoint,
+ multithreaded, NULL, user_data, 0);
}
static void fuse_teardown_common(struct fuse *fuse, char *mountpoint)
{
- struct fuse_session *se = fuse_get_session(fuse);
- struct fuse_chan *ch = fuse_session_next_chan(se, NULL);
- fuse_remove_signal_handlers(se);
- fuse_unmount_common(mountpoint, ch);
- fuse_destroy(fuse);
- free(mountpoint);
+ struct fuse_session *se = fuse_get_session(fuse);
+ struct fuse_chan *ch = fuse_session_next_chan(se, NULL);
+ fuse_remove_signal_handlers(se);
+ fuse_unmount_common(mountpoint, ch);
+ fuse_destroy(fuse);
+ free(mountpoint);
}
void fuse_teardown(struct fuse *fuse, char *mountpoint)
{
- fuse_teardown_common(fuse, mountpoint);
+ fuse_teardown_common(fuse, mountpoint);
}
static int fuse_main_common(int argc, char *argv[],
- const struct fuse_operations *op, size_t op_size,
- void *user_data, int compat)
+ const struct fuse_operations *op, size_t op_size,
+ void *user_data, int compat)
{
- struct fuse *fuse;
- char *mountpoint;
- int multithreaded;
- int res;
-
- fuse = fuse_setup_common(argc, argv, op, op_size, &mountpoint,
- &multithreaded, NULL, user_data, compat);
- if (fuse == NULL)
- return 1;
-
- if (multithreaded)
- res = fuse_loop_mt(fuse);
- else
- res = fuse_loop(fuse);
-
- fuse_teardown_common(fuse, mountpoint);
- if (res == -1)
- return 1;
-
- return 0;
+ struct fuse *fuse;
+ char *mountpoint;
+ int multithreaded;
+ int res;
+
+ fuse = fuse_setup_common(argc, argv, op, op_size, &mountpoint,
+ &multithreaded, NULL, user_data, compat);
+ if (fuse == NULL)
+ return 1;
+
+ if (multithreaded)
+ res = fuse_loop_mt(fuse);
+ else
+ res = fuse_loop(fuse);
+
+ fuse_teardown_common(fuse, mountpoint);
+ if (res == -1)
+ return 1;
+
+ return 0;
}
int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,
- size_t op_size, void *user_data)
+ size_t op_size, void *user_data)
{
- return fuse_main_common(argc, argv, op, op_size, user_data, 0);
+ return fuse_main_common(argc, argv, op, op_size, user_data, 0);
}
#undef fuse_main
int fuse_main(void);
int fuse_main(void)
{
- fprintf(stderr, "fuse_main(): This function does not exist\n");
- return -1;
+ fprintf(stderr, "fuse_main(): This function does not exist\n");
+ return -1;
}
int fuse_version(void)
{
- return FUSE_VERSION;
+ return FUSE_VERSION;
}
#include "fuse_compat.h"
@@ -356,51 +359,53 @@ int fuse_version(void)
#ifndef __FreeBSD__
struct fuse *fuse_setup_compat22(int argc, char *argv[],
- const struct fuse_operations_compat22 *op,
- size_t op_size, char **mountpoint,
- int *multithreaded, int *fd)
+ const struct fuse_operations_compat22 *op,
+ size_t op_size, char **mountpoint,
+ int *multithreaded, int *fd)
{
- return fuse_setup_common(argc, argv, (struct fuse_operations *) op,
- op_size, mountpoint, multithreaded, fd, NULL, 22);
+ return fuse_setup_common(argc, argv, (struct fuse_operations *) op,
+ op_size, mountpoint, multithreaded, fd, NULL,
+ 22);
}
struct fuse *fuse_setup_compat2(int argc, char *argv[],
- const struct fuse_operations_compat2 *op,
- char **mountpoint, int *multithreaded,
- int *fd)
+ const struct fuse_operations_compat2 *op,
+ char **mountpoint, int *multithreaded,
+ int *fd)
{
- return fuse_setup_common(argc, argv, (struct fuse_operations *) op,
- sizeof(struct fuse_operations_compat2),
- mountpoint, multithreaded, fd, NULL, 21);
+ return fuse_setup_common(argc, argv, (struct fuse_operations *) op,
+ sizeof(struct fuse_operations_compat2),
+ mountpoint, multithreaded, fd, NULL, 21);
}
int fuse_main_real_compat22(int argc, char *argv[],
- const struct fuse_operations_compat22 *op,
- size_t op_size)
+ const struct fuse_operations_compat22 *op,
+ size_t op_size)
{
- return fuse_main_common(argc, argv, (struct fuse_operations *) op, op_size,
- NULL, 22);
+ return fuse_main_common(argc, argv, (struct fuse_operations *) op,
+ op_size, NULL, 22);
}
void fuse_main_compat1(int argc, char *argv[],
- const struct fuse_operations_compat1 *op)
+ const struct fuse_operations_compat1 *op)
{
- fuse_main_common(argc, argv, (struct fuse_operations *) op,
- sizeof(struct fuse_operations_compat1), NULL, 11);
+ fuse_main_common(argc, argv, (struct fuse_operations *) op,
+ sizeof(struct fuse_operations_compat1), NULL, 11);
}
int fuse_main_compat2(int argc, char *argv[],
- const struct fuse_operations_compat2 *op)
+ const struct fuse_operations_compat2 *op)
{
- return fuse_main_common(argc, argv, (struct fuse_operations *) op,
- sizeof(struct fuse_operations_compat2), NULL, 21);
+ return fuse_main_common(argc, argv, (struct fuse_operations *) op,
+ sizeof(struct fuse_operations_compat2), NULL,
+ 21);
}
int fuse_mount_compat1(const char *mountpoint, const char *args[])
{
- /* just ignore mount args for now */
- (void) args;
- return fuse_mount_compat22(mountpoint, NULL);
+ /* just ignore mount args for now */
+ (void) args;
+ return fuse_mount_compat22(mountpoint, NULL);
}
FUSE_SYMVER(".symver fuse_setup_compat2,__fuse_setup@");
@@ -413,31 +418,32 @@ FUSE_SYMVER(".symver fuse_main_real_compat22,fuse_main_real@FUSE_2.2");
struct fuse *fuse_setup_compat25(int argc, char *argv[],
- const struct fuse_operations_compat25 *op,
- size_t op_size, char **mountpoint,
- int *multithreaded, int *fd)
+ const struct fuse_operations_compat25 *op,
+ size_t op_size, char **mountpoint,
+ int *multithreaded, int *fd)
{
- return fuse_setup_common(argc, argv, (struct fuse_operations *) op,
- op_size, mountpoint, multithreaded, fd, NULL, 25);
+ return fuse_setup_common(argc, argv, (struct fuse_operations *) op,
+ op_size, mountpoint, multithreaded, fd, NULL,
+ 25);
}
int fuse_main_real_compat25(int argc, char *argv[],
- const struct fuse_operations_compat25 *op,
- size_t op_size)
+ const struct fuse_operations_compat25 *op,
+ size_t op_size)
{
- return fuse_main_common(argc, argv, (struct fuse_operations *) op, op_size,
- NULL, 25);
+ return fuse_main_common(argc, argv, (struct fuse_operations *) op,
+ op_size, NULL, 25);
}
void fuse_teardown_compat22(struct fuse *fuse, int fd, char *mountpoint)
{
- (void) fd;
- fuse_teardown_common(fuse, mountpoint);
+ (void) fd;
+ fuse_teardown_common(fuse, mountpoint);
}
int fuse_mount_compat25(const char *mountpoint, struct fuse_args *args)
{
- return fuse_kern_mount(mountpoint, args);
+ return fuse_kern_mount(mountpoint, args);
}
FUSE_SYMVER(".symver fuse_setup_compat25,fuse_setup@FUSE_2.5");
diff --git a/lib/modules/iconv.c b/lib/modules/iconv.c
index 350a472..c0e2b80 100644
--- a/lib/modules/iconv.c
+++ b/lib/modules/iconv.c
@@ -1,9 +1,9 @@
/*
- fuse iconv module: file name charset conversion
- Copyright (C) 2007 Miklos Szeredi <miklos@szeredi.hu>
+ fuse iconv module: file name charset conversion
+ Copyright (C) 2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
#define FUSE_USE_VERSION 26
@@ -20,689 +20,690 @@
#include <langinfo.h>
struct iconv {
- struct fuse_fs *next;
- pthread_mutex_t lock;
- char *from_code;
- char *to_code;
- iconv_t tofs;
- iconv_t fromfs;
+ struct fuse_fs *next;
+ pthread_mutex_t lock;
+ char *from_code;
+ char *to_code;
+ iconv_t tofs;
+ iconv_t fromfs;
};
struct iconv_dh {
- struct iconv *ic;
- void *prev_buf;
- fuse_fill_dir_t prev_filler;
+ struct iconv *ic;
+ void *prev_buf;
+ fuse_fill_dir_t prev_filler;
};
static struct iconv *iconv_get(void)
{
- return fuse_get_context()->private_data;
+ return fuse_get_context()->private_data;
}
static int iconv_convpath(struct iconv *ic, const char *path, char **newpathp,
- int fromfs)
-{
- size_t pathlen = strlen(path);
- size_t newpathlen = pathlen * 4;
- char *newpath = malloc(newpathlen + 1);
- size_t plen = newpathlen;
- char *p = newpath;
- size_t res;
- int err;
-
- if (!newpath)
- return -ENOMEM;
-
- pthread_mutex_lock(&ic->lock);
- do {
- res = iconv(fromfs ? ic->fromfs : ic->tofs, (char **) &path, &pathlen,
- &p, &plen);
- if (res == (size_t) -1) {
- char *tmp;
- size_t inc;
-
- err = -EILSEQ;
- if (errno != E2BIG)
- goto err;
-
- inc = (pathlen + 1) * 4;
- newpathlen += inc;
- tmp = realloc(newpath, newpathlen + 1);
- err = -ENOMEM;
- if (!tmp)
- goto err;
-
- p = tmp + (p - newpath);
- plen += inc;
- newpath = tmp;
- }
- } while (res == (size_t) -1);
- pthread_mutex_unlock(&ic->lock);
- *p = '\0';
- *newpathp = newpath;
- return 0;
-
- err:
- iconv(fromfs ? ic->fromfs : ic->tofs, NULL, NULL, NULL, NULL);
- pthread_mutex_unlock(&ic->lock);
- free(newpath);
- return err;
+ int fromfs)
+{
+ size_t pathlen = strlen(path);
+ size_t newpathlen = pathlen * 4;
+ char *newpath = malloc(newpathlen + 1);
+ size_t plen = newpathlen;
+ char *p = newpath;
+ size_t res;
+ int err;
+
+ if (!newpath)
+ return -ENOMEM;
+
+ pthread_mutex_lock(&ic->lock);
+ do {
+ res = iconv(fromfs ? ic->fromfs : ic->tofs, (char **) &path,
+ &pathlen, &p, &plen);
+ if (res == (size_t) -1) {
+ char *tmp;
+ size_t inc;
+
+ err = -EILSEQ;
+ if (errno != E2BIG)
+ goto err;
+
+ inc = (pathlen + 1) * 4;
+ newpathlen += inc;
+ tmp = realloc(newpath, newpathlen + 1);
+ err = -ENOMEM;
+ if (!tmp)
+ goto err;
+
+ p = tmp + (p - newpath);
+ plen += inc;
+ newpath = tmp;
+ }
+ } while (res == (size_t) -1);
+ pthread_mutex_unlock(&ic->lock);
+ *p = '\0';
+ *newpathp = newpath;
+ return 0;
+
+err:
+ iconv(fromfs ? ic->fromfs : ic->tofs, NULL, NULL, NULL, NULL);
+ pthread_mutex_unlock(&ic->lock);
+ free(newpath);
+ return err;
}
static int iconv_getattr(const char *path, struct stat *stbuf)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_getattr(ic->next, newpath, stbuf);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_getattr(ic->next, newpath, stbuf);
+ free(newpath);
+ }
+ return err;
}
static int iconv_fgetattr(const char *path, struct stat *stbuf,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_fgetattr(ic->next, newpath, stbuf, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_fgetattr(ic->next, newpath, stbuf, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_access(const char *path, int mask)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_access(ic->next, newpath, mask);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_access(ic->next, newpath, mask);
+ free(newpath);
+ }
+ return err;
}
static int iconv_readlink(const char *path, char *buf, size_t size)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_readlink(ic->next, newpath, buf, size);
- if (!err) {
- char *newlink;
- err = iconv_convpath(ic, buf, &newlink, 1);
- if (!err) {
- strncpy(buf, newlink, size - 1);
- buf[size - 1] = '\0';
- free(newlink);
- }
- }
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_readlink(ic->next, newpath, buf, size);
+ if (!err) {
+ char *newlink;
+ err = iconv_convpath(ic, buf, &newlink, 1);
+ if (!err) {
+ strncpy(buf, newlink, size - 1);
+ buf[size - 1] = '\0';
+ free(newlink);
+ }
+ }
+ free(newpath);
+ }
+ return err;
}
static int iconv_opendir(const char *path, struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_opendir(ic->next, newpath, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_opendir(ic->next, newpath, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_dir_fill(void *buf, const char *name,
- const struct stat *stbuf, off_t off)
+ const struct stat *stbuf, off_t off)
{
- struct iconv_dh *dh = buf;
- char *newname;
- int res = 0;
- if (iconv_convpath(dh->ic, name, &newname, 1) == 0) {
- res = dh->prev_filler(dh->prev_buf, newname, stbuf, off);
- free(newname);
- }
- return res;
+ struct iconv_dh *dh = buf;
+ char *newname;
+ int res = 0;
+ if (iconv_convpath(dh->ic, name, &newname, 1) == 0) {
+ res = dh->prev_filler(dh->prev_buf, newname, stbuf, off);
+ free(newname);
+ }
+ return res;
}
static int iconv_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
- off_t offset, struct fuse_file_info *fi)
-{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- struct iconv_dh dh;
- dh.ic = ic;
- dh.prev_buf = buf;
- dh.prev_filler = filler;
- err = fuse_fs_readdir(ic->next, newpath, &dh, iconv_dir_fill, offset,
- fi);
- free(newpath);
- }
- return err;
+ off_t offset, struct fuse_file_info *fi)
+{
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ struct iconv_dh dh;
+ dh.ic = ic;
+ dh.prev_buf = buf;
+ dh.prev_filler = filler;
+ err = fuse_fs_readdir(ic->next, newpath, &dh, iconv_dir_fill,
+ offset, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_releasedir(const char *path, struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_releasedir(ic->next, newpath, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_releasedir(ic->next, newpath, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_mknod(const char *path, mode_t mode, dev_t rdev)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_mknod(ic->next, newpath, mode, rdev);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_mknod(ic->next, newpath, mode, rdev);
+ free(newpath);
+ }
+ return err;
}
static int iconv_mkdir(const char *path, mode_t mode)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_mkdir(ic->next, newpath, mode);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_mkdir(ic->next, newpath, mode);
+ free(newpath);
+ }
+ return err;
}
static int iconv_unlink(const char *path)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_unlink(ic->next, newpath);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_unlink(ic->next, newpath);
+ free(newpath);
+ }
+ return err;
}
static int iconv_rmdir(const char *path)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_rmdir(ic->next, newpath);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_rmdir(ic->next, newpath);
+ free(newpath);
+ }
+ return err;
}
static int iconv_symlink(const char *from, const char *to)
{
- struct iconv *ic = iconv_get();
- char *newfrom;
- char *newto;
- int err = iconv_convpath(ic, from, &newfrom, 0);
- if (!err) {
- err = iconv_convpath(ic, to, &newto, 0);
- if (!err) {
- err = fuse_fs_symlink(ic->next, newfrom, newto);
- free(newto);
- }
- free(newfrom);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newfrom;
+ char *newto;
+ int err = iconv_convpath(ic, from, &newfrom, 0);
+ if (!err) {
+ err = iconv_convpath(ic, to, &newto, 0);
+ if (!err) {
+ err = fuse_fs_symlink(ic->next, newfrom, newto);
+ free(newto);
+ }
+ free(newfrom);
+ }
+ return err;
}
static int iconv_rename(const char *from, const char *to)
{
- struct iconv *ic = iconv_get();
- char *newfrom;
- char *newto;
- int err = iconv_convpath(ic, from, &newfrom, 0);
- if (!err) {
- err = iconv_convpath(ic, to, &newto, 0);
- if (!err) {
- err = fuse_fs_rename(ic->next, newfrom, newto);
- free(newto);
- }
- free(newfrom);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newfrom;
+ char *newto;
+ int err = iconv_convpath(ic, from, &newfrom, 0);
+ if (!err) {
+ err = iconv_convpath(ic, to, &newto, 0);
+ if (!err) {
+ err = fuse_fs_rename(ic->next, newfrom, newto);
+ free(newto);
+ }
+ free(newfrom);
+ }
+ return err;
}
static int iconv_link(const char *from, const char *to)
{
- struct iconv *ic = iconv_get();
- char *newfrom;
- char *newto;
- int err = iconv_convpath(ic, from, &newfrom, 0);
- if (!err) {
- err = iconv_convpath(ic, to, &newto, 0);
- if (!err) {
- err = fuse_fs_link(ic->next, newfrom, newto);
- free(newto);
- }
- free(newfrom);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newfrom;
+ char *newto;
+ int err = iconv_convpath(ic, from, &newfrom, 0);
+ if (!err) {
+ err = iconv_convpath(ic, to, &newto, 0);
+ if (!err) {
+ err = fuse_fs_link(ic->next, newfrom, newto);
+ free(newto);
+ }
+ free(newfrom);
+ }
+ return err;
}
static int iconv_chmod(const char *path, mode_t mode)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_chmod(ic->next, newpath, mode);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_chmod(ic->next, newpath, mode);
+ free(newpath);
+ }
+ return err;
}
static int iconv_chown(const char *path, uid_t uid, gid_t gid)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_chown(ic->next, newpath, uid, gid);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_chown(ic->next, newpath, uid, gid);
+ free(newpath);
+ }
+ return err;
}
static int iconv_truncate(const char *path, off_t size)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_truncate(ic->next, newpath, size);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_truncate(ic->next, newpath, size);
+ free(newpath);
+ }
+ return err;
}
static int iconv_ftruncate(const char *path, off_t size,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_ftruncate(ic->next, newpath, size, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_ftruncate(ic->next, newpath, size, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_utimens(const char *path, const struct timespec ts[2])
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_utimens(ic->next, newpath, ts);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_utimens(ic->next, newpath, ts);
+ free(newpath);
+ }
+ return err;
}
static int iconv_create(const char *path, mode_t mode,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_create(ic->next, newpath, mode, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_create(ic->next, newpath, mode, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_open_file(const char *path, struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_open(ic->next, newpath, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_open(ic->next, newpath, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_read(const char *path, char *buf, size_t size, off_t offset,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_read(ic->next, newpath, buf, size, offset, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_read(ic->next, newpath, buf, size, offset, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_write(const char *path, const char *buf, size_t size,
- off_t offset, struct fuse_file_info *fi)
+ off_t offset, struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_write(ic->next, newpath, buf, size, offset, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_write(ic->next, newpath, buf, size, offset, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_statfs(const char *path, struct statvfs *stbuf)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_statfs(ic->next, newpath, stbuf);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_statfs(ic->next, newpath, stbuf);
+ free(newpath);
+ }
+ return err;
}
static int iconv_flush(const char *path, struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_flush(ic->next, newpath, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_flush(ic->next, newpath, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_release(const char *path, struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_release(ic->next, newpath, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_release(ic->next, newpath, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_fsync(const char *path, int isdatasync,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_fsync(ic->next, newpath, isdatasync, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_fsync(ic->next, newpath, isdatasync, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_fsyncdir(const char *path, int isdatasync,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_fsyncdir(ic->next, newpath, isdatasync, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_fsyncdir(ic->next, newpath, isdatasync, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_setxattr(const char *path, const char *name,
- const char *value, size_t size, int flags)
+ const char *value, size_t size, int flags)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_setxattr(ic->next, newpath, name, value, size, flags);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_setxattr(ic->next, newpath, name, value, size,
+ flags);
+ free(newpath);
+ }
+ return err;
}
static int iconv_getxattr(const char *path, const char *name, char *value,
- size_t size)
+ size_t size)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_getxattr(ic->next, newpath, name, value, size);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_getxattr(ic->next, newpath, name, value, size);
+ free(newpath);
+ }
+ return err;
}
static int iconv_listxattr(const char *path, char *list, size_t size)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_listxattr(ic->next, newpath, list, size);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_listxattr(ic->next, newpath, list, size);
+ free(newpath);
+ }
+ return err;
}
static int iconv_removexattr(const char *path, const char *name)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_removexattr(ic->next, newpath, name);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_removexattr(ic->next, newpath, name);
+ free(newpath);
+ }
+ return err;
}
static int iconv_lock(const char *path, struct fuse_file_info *fi, int cmd,
- struct flock *lock)
+ struct flock *lock)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_lock(ic->next, newpath, fi, cmd, lock);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_lock(ic->next, newpath, fi, cmd, lock);
+ free(newpath);
+ }
+ return err;
}
static int iconv_bmap(const char *path, size_t blocksize, uint64_t *idx)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_bmap(ic->next, newpath, blocksize, idx);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_bmap(ic->next, newpath, blocksize, idx);
+ free(newpath);
+ }
+ return err;
}
static void *iconv_init(struct fuse_conn_info *conn)
{
- struct iconv *ic = iconv_get();
- fuse_fs_init(ic->next, conn);
- return ic;
+ struct iconv *ic = iconv_get();
+ fuse_fs_init(ic->next, conn);
+ return ic;
}
static void iconv_destroy(void *data)
{
- struct iconv *ic = data;
- fuse_fs_destroy(ic->next);
- iconv_close(ic->tofs);
- iconv_close(ic->fromfs);
- pthread_mutex_destroy(&ic->lock);
- free(ic->from_code);
- free(ic->to_code);
- free(ic);
+ struct iconv *ic = data;
+ fuse_fs_destroy(ic->next);
+ iconv_close(ic->tofs);
+ iconv_close(ic->fromfs);
+ pthread_mutex_destroy(&ic->lock);
+ free(ic->from_code);
+ free(ic->to_code);
+ free(ic);
}
static struct fuse_operations iconv_oper = {
- .destroy = iconv_destroy,
- .init = iconv_init,
- .getattr = iconv_getattr,
- .fgetattr = iconv_fgetattr,
- .access = iconv_access,
- .readlink = iconv_readlink,
- .opendir = iconv_opendir,
- .readdir = iconv_readdir,
- .releasedir = iconv_releasedir,
- .mknod = iconv_mknod,
- .mkdir = iconv_mkdir,
- .symlink = iconv_symlink,
- .unlink = iconv_unlink,
- .rmdir = iconv_rmdir,
- .rename = iconv_rename,
- .link = iconv_link,
- .chmod = iconv_chmod,
- .chown = iconv_chown,
- .truncate = iconv_truncate,
- .ftruncate = iconv_ftruncate,
- .utimens = iconv_utimens,
- .create = iconv_create,
- .open = iconv_open_file,
- .read = iconv_read,
- .write = iconv_write,
- .statfs = iconv_statfs,
- .flush = iconv_flush,
- .release = iconv_release,
- .fsync = iconv_fsync,
- .fsyncdir = iconv_fsyncdir,
- .setxattr = iconv_setxattr,
- .getxattr = iconv_getxattr,
- .listxattr = iconv_listxattr,
- .removexattr= iconv_removexattr,
- .lock = iconv_lock,
- .bmap = iconv_bmap,
+ .destroy = iconv_destroy,
+ .init = iconv_init,
+ .getattr = iconv_getattr,
+ .fgetattr = iconv_fgetattr,
+ .access = iconv_access,
+ .readlink = iconv_readlink,
+ .opendir = iconv_opendir,
+ .readdir = iconv_readdir,
+ .releasedir = iconv_releasedir,
+ .mknod = iconv_mknod,
+ .mkdir = iconv_mkdir,
+ .symlink = iconv_symlink,
+ .unlink = iconv_unlink,
+ .rmdir = iconv_rmdir,
+ .rename = iconv_rename,
+ .link = iconv_link,
+ .chmod = iconv_chmod,
+ .chown = iconv_chown,
+ .truncate = iconv_truncate,
+ .ftruncate = iconv_ftruncate,
+ .utimens = iconv_utimens,
+ .create = iconv_create,
+ .open = iconv_open_file,
+ .read = iconv_read,
+ .write = iconv_write,
+ .statfs = iconv_statfs,
+ .flush = iconv_flush,
+ .release = iconv_release,
+ .fsync = iconv_fsync,
+ .fsyncdir = iconv_fsyncdir,
+ .setxattr = iconv_setxattr,
+ .getxattr = iconv_getxattr,
+ .listxattr = iconv_listxattr,
+ .removexattr = iconv_removexattr,
+ .lock = iconv_lock,
+ .bmap = iconv_bmap,
};
static struct fuse_opt iconv_opts[] = {
- FUSE_OPT_KEY("-h", 0),
- FUSE_OPT_KEY("--help", 0),
- { "from_code=%s", offsetof(struct iconv, from_code), 0 },
- { "to_code=%s", offsetof(struct iconv, to_code), 1 },
- FUSE_OPT_END
+ FUSE_OPT_KEY("-h", 0),
+ FUSE_OPT_KEY("--help", 0),
+ { "from_code=%s", offsetof(struct iconv, from_code), 0 },
+ { "to_code=%s", offsetof(struct iconv, to_code), 1 },
+ FUSE_OPT_END
};
static void iconv_help(void)
{
- char *old = strdup(setlocale(LC_CTYPE, ""));
- char *charmap = strdup(nl_langinfo(CODESET));
- setlocale(LC_CTYPE, old);
- free(old);
- fprintf(stderr,
+ char *old = strdup(setlocale(LC_CTYPE, ""));
+ char *charmap = strdup(nl_langinfo(CODESET));
+ setlocale(LC_CTYPE, old);
+ free(old);
+ fprintf(stderr,
" -o from_code=CHARSET original encoding of file names (default: UTF-8)\n"
-" -o to_code=CHARSET new encoding of the file names (default: %s)\n",
- charmap);
- free(charmap);
+" -o to_code=CHARSET new encoding of the file names (default: %s)\n",
+ charmap);
+ free(charmap);
}
static int iconv_opt_proc(void *data, const char *arg, int key,
- struct fuse_args *outargs)
+ struct fuse_args *outargs)
{
- (void) data; (void) arg; (void) outargs;
+ (void) data; (void) arg; (void) outargs;
- if (!key) {
- iconv_help();
- return -1;
- }
+ if (!key) {
+ iconv_help();
+ return -1;
+ }
- return 1;
+ return 1;
}
static struct fuse_fs *iconv_new(struct fuse_args *args,
- struct fuse_fs *next[])
-{
- struct fuse_fs *fs;
- struct iconv *ic;
- char *old = NULL;
- const char *from;
- const char *to;
-
- ic = calloc(1, sizeof(struct iconv));
- if (ic == NULL) {
- fprintf(stderr, "fuse-iconv: memory allocation failed\n");
- return NULL;
- }
-
- if (fuse_opt_parse(args, ic, iconv_opts, iconv_opt_proc) == -1)
- goto out_free;
-
- if (!next[0] || next[1]) {
- fprintf(stderr, "fuse-iconv: exactly one next filesystem required\n");
- goto out_free;
- }
-
- from = ic->from_code ? ic->from_code : "UTF-8";
- to = ic->to_code ? ic->to_code : "";
- /* FIXME: detect charset equivalence? */
- if (!to[0])
- old = strdup(setlocale(LC_CTYPE, ""));
- ic->tofs = iconv_open(from, to);
- if (ic->tofs == (iconv_t) -1) {
- fprintf(stderr, "fuse-iconv: cannot convert from %s to %s\n",
- to, from);
- goto out_free;
- }
- ic->fromfs = iconv_open(to, from);
- if (ic->tofs == (iconv_t) -1) {
- fprintf(stderr, "fuse-iconv: cannot convert from %s to %s\n",
- from, to);
- goto out_iconv_close_to;
- }
- if (old) {
- setlocale(LC_CTYPE, old);
- free(old);
- }
-
- ic->next = next[0];
- fs = fuse_fs_new(&iconv_oper, sizeof(iconv_oper), ic);
- if (!fs)
- goto out_iconv_close_from;
-
- return fs;
-
- out_iconv_close_from:
- iconv_close(ic->fromfs);
- out_iconv_close_to:
- iconv_close(ic->tofs);
- out_free:
- free(ic->from_code);
- free(ic->to_code);
- free(ic);
- return NULL;
+ struct fuse_fs *next[])
+{
+ struct fuse_fs *fs;
+ struct iconv *ic;
+ char *old = NULL;
+ const char *from;
+ const char *to;
+
+ ic = calloc(1, sizeof(struct iconv));
+ if (ic == NULL) {
+ fprintf(stderr, "fuse-iconv: memory allocation failed\n");
+ return NULL;
+ }
+
+ if (fuse_opt_parse(args, ic, iconv_opts, iconv_opt_proc) == -1)
+ goto out_free;
+
+ if (!next[0] || next[1]) {
+ fprintf(stderr, "fuse-iconv: exactly one next filesystem required\n");
+ goto out_free;
+ }
+
+ from = ic->from_code ? ic->from_code : "UTF-8";
+ to = ic->to_code ? ic->to_code : "";
+ /* FIXME: detect charset equivalence? */
+ if (!to[0])
+ old = strdup(setlocale(LC_CTYPE, ""));
+ ic->tofs = iconv_open(from, to);
+ if (ic->tofs == (iconv_t) -1) {
+ fprintf(stderr, "fuse-iconv: cannot convert from %s to %s\n",
+ to, from);
+ goto out_free;
+ }
+ ic->fromfs = iconv_open(to, from);
+ if (ic->tofs == (iconv_t) -1) {
+ fprintf(stderr, "fuse-iconv: cannot convert from %s to %s\n",
+ from, to);
+ goto out_iconv_close_to;
+ }
+ if (old) {
+ setlocale(LC_CTYPE, old);
+ free(old);
+ }
+
+ ic->next = next[0];
+ fs = fuse_fs_new(&iconv_oper, sizeof(iconv_oper), ic);
+ if (!fs)
+ goto out_iconv_close_from;
+
+ return fs;
+
+out_iconv_close_from:
+ iconv_close(ic->fromfs);
+out_iconv_close_to:
+ iconv_close(ic->tofs);
+out_free:
+ free(ic->from_code);
+ free(ic->to_code);
+ free(ic);
+ return NULL;
}
FUSE_REGISTER_MODULE(iconv, iconv_new);
diff --git a/lib/modules/subdir.c b/lib/modules/subdir.c
index f22c023..6f7b187 100644
--- a/lib/modules/subdir.c
+++ b/lib/modules/subdir.c
@@ -1,9 +1,9 @@
/*
- fuse subdir module: offset paths with a base directory
- Copyright (C) 2007 Miklos Szeredi <miklos@szeredi.hu>
+ fuse subdir module: offset paths with a base directory
+ Copyright (C) 2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
#define FUSE_USE_VERSION 26
@@ -16,647 +16,650 @@
#include <errno.h>
struct subdir {
- char *base;
- size_t baselen;
- int rellinks;
- struct fuse_fs *next;
+ char *base;
+ size_t baselen;
+ int rellinks;
+ struct fuse_fs *next;
};
static struct subdir *subdir_get(void)
{
- return fuse_get_context()->private_data;
+ return fuse_get_context()->private_data;
}
static char *subdir_addpath(struct subdir *d, const char *path)
{
- unsigned newlen = d->baselen + strlen(path);
- char *newpath = malloc(newlen + 2);
- if (newpath) {
- if (path[0] == '/')
- path++;
- strcpy(newpath, d->base);
- strcpy(newpath + d->baselen, path);
- if (!newpath[0])
- strcpy(newpath, ".");
- }
- return newpath;
+ unsigned newlen = d->baselen + strlen(path);
+ char *newpath = malloc(newlen + 2);
+ if (newpath) {
+ if (path[0] == '/')
+ path++;
+ strcpy(newpath, d->base);
+ strcpy(newpath + d->baselen, path);
+ if (!newpath[0])
+ strcpy(newpath, ".");
+ }
+ return newpath;
}
static int subdir_getattr(const char *path, struct stat *stbuf)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_getattr(d->next, newpath, stbuf);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_getattr(d->next, newpath, stbuf);
+ free(newpath);
+ }
+ return err;
}
static int subdir_fgetattr(const char *path, struct stat *stbuf,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_fgetattr(d->next, newpath, stbuf, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_fgetattr(d->next, newpath, stbuf, fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_access(const char *path, int mask)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_access(d->next, newpath, mask);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_access(d->next, newpath, mask);
+ free(newpath);
+ }
+ return err;
}
static int count_components(const char *p)
{
- int ctr;
+ int ctr;
- for (; *p == '/'; p++);
- for (ctr = 0; *p; ctr++) {
- for (; *p && *p != '/'; p++);
- for (; *p == '/'; p++);
- }
- return ctr;
+ for (; *p == '/'; p++);
+ for (ctr = 0; *p; ctr++) {
+ for (; *p && *p != '/'; p++);
+ for (; *p == '/'; p++);
+ }
+ return ctr;
}
static void strip_common(const char **sp, const char **tp)
{
- const char *s = *sp;
- const char *t = *tp;
- do {
- for (; *s == '/'; s++);
- for (; *t == '/'; t++);
- *tp = t;
- *sp = s;
- for (; *s == *t && *s && *s != '/'; s++, t++);
- } while ((*s == *t && *s) || (!*s && *t == '/') || (*s == '/' && !*t));
+ const char *s = *sp;
+ const char *t = *tp;
+ do {
+ for (; *s == '/'; s++);
+ for (; *t == '/'; t++);
+ *tp = t;
+ *sp = s;
+ for (; *s == *t && *s && *s != '/'; s++, t++);
+ } while ((*s == *t && *s) || (!*s && *t == '/') || (*s == '/' && !*t));
}
static void transform_symlink(struct subdir *d, const char *path,
- char *buf, size_t size)
+ char *buf, size_t size)
{
- const char *l = buf;
- size_t llen;
- char *s;
- int dotdots;
- int i;
+ const char *l = buf;
+ size_t llen;
+ char *s;
+ int dotdots;
+ int i;
- if (l[0] != '/' || d->base[0] != '/')
- return;
+ if (l[0] != '/' || d->base[0] != '/')
+ return;
- strip_common(&l, &path);
- if (l - buf < (long) d->baselen)
- return;
+ strip_common(&l, &path);
+ if (l - buf < (long) d->baselen)
+ return;
- dotdots = count_components(path);
- if (!dotdots)
- return;
- dotdots--;
+ dotdots = count_components(path);
+ if (!dotdots)
+ return;
+ dotdots--;
- llen = strlen(l);
- if (dotdots * 3 + llen + 2 > size)
- return;
+ llen = strlen(l);
+ if (dotdots * 3 + llen + 2 > size)
+ return;
- s = buf + dotdots * 3;
- if (llen)
- memmove(s, l, llen + 1);
- else if (!dotdots)
- strcpy(s, ".");
- else
- *s = '\0';
+ s = buf + dotdots * 3;
+ if (llen)
+ memmove(s, l, llen + 1);
+ else if (!dotdots)
+ strcpy(s, ".");
+ else
+ *s = '\0';
- for (s = buf, i = 0; i < dotdots; i++, s += 3)
- memcpy(s, "../", 3);
+ for (s = buf, i = 0; i < dotdots; i++, s += 3)
+ memcpy(s, "../", 3);
}
static int subdir_readlink(const char *path, char *buf, size_t size)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_readlink(d->next, newpath, buf, size);
- if (!err && d->rellinks)
- transform_symlink(d, newpath, buf, size);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_readlink(d->next, newpath, buf, size);
+ if (!err && d->rellinks)
+ transform_symlink(d, newpath, buf, size);
+ free(newpath);
+ }
+ return err;
}
static int subdir_opendir(const char *path, struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_opendir(d->next, newpath, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_opendir(d->next, newpath, fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_readdir(const char *path, void *buf,
- fuse_fill_dir_t filler, off_t offset,
- struct fuse_file_info *fi)
+ fuse_fill_dir_t filler, off_t offset,
+ struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_readdir(d->next, newpath, buf, filler, offset, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_readdir(d->next, newpath, buf, filler, offset,
+ fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_releasedir(const char *path, struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_releasedir(d->next, newpath, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_releasedir(d->next, newpath, fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_mknod(const char *path, mode_t mode, dev_t rdev)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_mknod(d->next, newpath, mode, rdev);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_mknod(d->next, newpath, mode, rdev);
+ free(newpath);
+ }
+ return err;
}
static int subdir_mkdir(const char *path, mode_t mode)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_mkdir(d->next, newpath, mode);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_mkdir(d->next, newpath, mode);
+ free(newpath);
+ }
+ return err;
}
static int subdir_unlink(const char *path)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_unlink(d->next, newpath);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_unlink(d->next, newpath);
+ free(newpath);
+ }
+ return err;
}
static int subdir_rmdir(const char *path)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_rmdir(d->next, newpath);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_rmdir(d->next, newpath);
+ free(newpath);
+ }
+ return err;
}
static int subdir_symlink(const char *from, const char *path)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_symlink(d->next, from, newpath);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_symlink(d->next, from, newpath);
+ free(newpath);
+ }
+ return err;
}
static int subdir_rename(const char *from, const char *to)
{
- struct subdir *d = subdir_get();
- char *newfrom = subdir_addpath(d, from);
- char *newto = subdir_addpath(d, to);
- int err = -ENOMEM;
- if (newfrom && newto)
- err = fuse_fs_rename(d->next, newfrom, newto);
- free(newfrom);
- free(newto);
- return err;
+ struct subdir *d = subdir_get();
+ char *newfrom = subdir_addpath(d, from);
+ char *newto = subdir_addpath(d, to);
+ int err = -ENOMEM;
+ if (newfrom && newto)
+ err = fuse_fs_rename(d->next, newfrom, newto);
+ free(newfrom);
+ free(newto);
+ return err;
}
static int subdir_link(const char *from, const char *to)
{
- struct subdir *d = subdir_get();
- char *newfrom = subdir_addpath(d, from);
- char *newto = subdir_addpath(d, to);
- int err = -ENOMEM;
- if (newfrom && newto)
- err = fuse_fs_link(d->next, newfrom, newto);
- free(newfrom);
- free(newto);
- return err;
+ struct subdir *d = subdir_get();
+ char *newfrom = subdir_addpath(d, from);
+ char *newto = subdir_addpath(d, to);
+ int err = -ENOMEM;
+ if (newfrom && newto)
+ err = fuse_fs_link(d->next, newfrom, newto);
+ free(newfrom);
+ free(newto);
+ return err;
}
static int subdir_chmod(const char *path, mode_t mode)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_chmod(d->next, newpath, mode);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_chmod(d->next, newpath, mode);
+ free(newpath);
+ }
+ return err;
}
static int subdir_chown(const char *path, uid_t uid, gid_t gid)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_chown(d->next, newpath, uid, gid);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_chown(d->next, newpath, uid, gid);
+ free(newpath);
+ }
+ return err;
}
static int subdir_truncate(const char *path, off_t size)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_truncate(d->next, newpath, size);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_truncate(d->next, newpath, size);
+ free(newpath);
+ }
+ return err;
}
static int subdir_ftruncate(const char *path, off_t size,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_ftruncate(d->next, newpath, size, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_ftruncate(d->next, newpath, size, fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_utimens(const char *path, const struct timespec ts[2])
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_utimens(d->next, newpath, ts);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_utimens(d->next, newpath, ts);
+ free(newpath);
+ }
+ return err;
}
-static int subdir_create(const char *path, mode_t mode, struct fuse_file_info *fi)
+static int subdir_create(const char *path, mode_t mode,
+ struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_create(d->next, newpath, mode, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_create(d->next, newpath, mode, fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_open(const char *path, struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_open(d->next, newpath, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_open(d->next, newpath, fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_read(const char *path, char *buf, size_t size, off_t offset,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_read(d->next, newpath, buf, size, offset, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_read(d->next, newpath, buf, size, offset, fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_write(const char *path, const char *buf, size_t size,
- off_t offset, struct fuse_file_info *fi)
+ off_t offset, struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_write(d->next, newpath, buf, size, offset, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_write(d->next, newpath, buf, size, offset, fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_statfs(const char *path, struct statvfs *stbuf)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_statfs(d->next, newpath, stbuf);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_statfs(d->next, newpath, stbuf);
+ free(newpath);
+ }
+ return err;
}
static int subdir_flush(const char *path, struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_flush(d->next, newpath, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_flush(d->next, newpath, fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_release(const char *path, struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_release(d->next, newpath, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_release(d->next, newpath, fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_fsync(const char *path, int isdatasync,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_fsync(d->next, newpath, isdatasync, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_fsync(d->next, newpath, isdatasync, fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_fsyncdir(const char *path, int isdatasync,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_fsyncdir(d->next, newpath, isdatasync, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_fsyncdir(d->next, newpath, isdatasync, fi);
+ free(newpath);
+ }
+ return err;
}
-static int subdir_setxattr(const char *path, const char *name, const char *value,
- size_t size, int flags)
+static int subdir_setxattr(const char *path, const char *name,
+ const char *value, size_t size, int flags)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_setxattr(d->next, newpath, name, value, size, flags);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_setxattr(d->next, newpath, name, value, size,
+ flags);
+ free(newpath);
+ }
+ return err;
}
static int subdir_getxattr(const char *path, const char *name, char *value,
- size_t size)
+ size_t size)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_getxattr(d->next, newpath, name, value, size);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_getxattr(d->next, newpath, name, value, size);
+ free(newpath);
+ }
+ return err;
}
static int subdir_listxattr(const char *path, char *list, size_t size)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_listxattr(d->next, newpath, list, size);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_listxattr(d->next, newpath, list, size);
+ free(newpath);
+ }
+ return err;
}
static int subdir_removexattr(const char *path, const char *name)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_removexattr(d->next, newpath, name);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_removexattr(d->next, newpath, name);
+ free(newpath);
+ }
+ return err;
}
static int subdir_lock(const char *path, struct fuse_file_info *fi, int cmd,
- struct flock *lock)
+ struct flock *lock)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_lock(d->next, newpath, fi, cmd, lock);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_lock(d->next, newpath, fi, cmd, lock);
+ free(newpath);
+ }
+ return err;
}
static int subdir_bmap(const char *path, size_t blocksize, uint64_t *idx)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_bmap(d->next, newpath, blocksize, idx);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_bmap(d->next, newpath, blocksize, idx);
+ free(newpath);
+ }
+ return err;
}
static void *subdir_init(struct fuse_conn_info *conn)
{
- struct subdir *d = subdir_get();
- fuse_fs_init(d->next, conn);
- return d;
+ struct subdir *d = subdir_get();
+ fuse_fs_init(d->next, conn);
+ return d;
}
static void subdir_destroy(void *data)
{
- struct subdir *d = data;
- fuse_fs_destroy(d->next);
- free(d->base);
- free(d);
+ struct subdir *d = data;
+ fuse_fs_destroy(d->next);
+ free(d->base);
+ free(d);
}
static struct fuse_operations subdir_oper = {
- .destroy = subdir_destroy,
- .init = subdir_init,
- .getattr = subdir_getattr,
- .fgetattr = subdir_fgetattr,
- .access = subdir_access,
- .readlink = subdir_readlink,
- .opendir = subdir_opendir,
- .readdir = subdir_readdir,
- .releasedir = subdir_releasedir,
- .mknod = subdir_mknod,
- .mkdir = subdir_mkdir,
- .symlink = subdir_symlink,
- .unlink = subdir_unlink,
- .rmdir = subdir_rmdir,
- .rename = subdir_rename,
- .link = subdir_link,
- .chmod = subdir_chmod,
- .chown = subdir_chown,
- .truncate = subdir_truncate,
- .ftruncate = subdir_ftruncate,
- .utimens = subdir_utimens,
- .create = subdir_create,
- .open = subdir_open,
- .read = subdir_read,
- .write = subdir_write,
- .statfs = subdir_statfs,
- .flush = subdir_flush,
- .release = subdir_release,
- .fsync = subdir_fsync,
- .fsyncdir = subdir_fsyncdir,
- .setxattr = subdir_setxattr,
- .getxattr = subdir_getxattr,
- .listxattr = subdir_listxattr,
- .removexattr= subdir_removexattr,
- .lock = subdir_lock,
- .bmap = subdir_bmap,
+ .destroy = subdir_destroy,
+ .init = subdir_init,
+ .getattr = subdir_getattr,
+ .fgetattr = subdir_fgetattr,
+ .access = subdir_access,
+ .readlink = subdir_readlink,
+ .opendir = subdir_opendir,
+ .readdir = subdir_readdir,
+ .releasedir = subdir_releasedir,
+ .mknod = subdir_mknod,
+ .mkdir = subdir_mkdir,
+ .symlink = subdir_symlink,
+ .unlink = subdir_unlink,
+ .rmdir = subdir_rmdir,
+ .rename = subdir_rename,
+ .link = subdir_link,
+ .chmod = subdir_chmod,
+ .chown = subdir_chown,
+ .truncate = subdir_truncate,
+ .ftruncate = subdir_ftruncate,
+ .utimens = subdir_utimens,
+ .create = subdir_create,
+ .open = subdir_open,
+ .read = subdir_read,
+ .write = subdir_write,
+ .statfs = subdir_statfs,
+ .flush = subdir_flush,
+ .release = subdir_release,
+ .fsync = subdir_fsync,
+ .fsyncdir = subdir_fsyncdir,
+ .setxattr = subdir_setxattr,
+ .getxattr = subdir_getxattr,
+ .listxattr = subdir_listxattr,
+ .removexattr = subdir_removexattr,
+ .lock = subdir_lock,
+ .bmap = subdir_bmap,
};
static struct fuse_opt subdir_opts[] = {
- FUSE_OPT_KEY("-h", 0),
- FUSE_OPT_KEY("--help", 0),
- { "subdir=%s", offsetof(struct subdir, base), 0 },
- { "rellinks", offsetof(struct subdir, rellinks), 1 },
- { "norellinks", offsetof(struct subdir, rellinks), 0 },
- FUSE_OPT_END
+ FUSE_OPT_KEY("-h", 0),
+ FUSE_OPT_KEY("--help", 0),
+ { "subdir=%s", offsetof(struct subdir, base), 0 },
+ { "rellinks", offsetof(struct subdir, rellinks), 1 },
+ { "norellinks", offsetof(struct subdir, rellinks), 0 },
+ FUSE_OPT_END
};
static void subdir_help(void)
{
- fprintf(stderr,
-" -o subdir=DIR prepend this directory to all paths (mandatory)\n"
-" -o [no]rellinks transform absolute symlinks to relative\n");
+ fprintf(stderr,
+" -o subdir=DIR prepend this directory to all paths (mandatory)\n"
+" -o [no]rellinks transform absolute symlinks to relative\n");
}
static int subdir_opt_proc(void *data, const char *arg, int key,
- struct fuse_args *outargs)
+ struct fuse_args *outargs)
{
- (void) data; (void) arg; (void) outargs;
+ (void) data; (void) arg; (void) outargs;
- if (!key) {
- subdir_help();
- return -1;
- }
+ if (!key) {
+ subdir_help();
+ return -1;
+ }
- return 1;
+ return 1;
}
static struct fuse_fs *subdir_new(struct fuse_args *args,
- struct fuse_fs *next[])
-{
- struct fuse_fs *fs;
- struct subdir *d;
-
- d = calloc(1, sizeof(struct subdir));
- if (d == NULL) {
- fprintf(stderr, "fuse-subdir: memory allocation failed\n");
- return NULL;
- }
-
- if (fuse_opt_parse(args, d, subdir_opts, subdir_opt_proc) == -1)
- goto out_free;
-
- if (!next[0] || next[1]) {
- fprintf(stderr, "fuse-subdir: exactly one next filesystem required\n");
- goto out_free;
- }
-
- if (!d->base) {
- fprintf(stderr, "fuse-subdir: missing 'subdir' option\n");
- goto out_free;
- }
-
- if (d->base[0] && d->base[strlen(d->base)-1] != '/') {
- char *tmp = realloc(d->base, strlen(d->base) + 2);
- if (!tmp) {
- fprintf(stderr, "fuse-subdir: memory allocation failed\n");
- goto out_free;
- }
- d->base = tmp;
- strcat(d->base, "/");
- }
- d->baselen = strlen(d->base);
- d->next = next[0];
- fs = fuse_fs_new(&subdir_oper, sizeof(subdir_oper), d);
- if (!fs)
- goto out_free;
- return fs;
-
- out_free:
- free(d->base);
- free(d);
- return NULL;
+ struct fuse_fs *next[])
+{
+ struct fuse_fs *fs;
+ struct subdir *d;
+
+ d = calloc(1, sizeof(struct subdir));
+ if (d == NULL) {
+ fprintf(stderr, "fuse-subdir: memory allocation failed\n");
+ return NULL;
+ }
+
+ if (fuse_opt_parse(args, d, subdir_opts, subdir_opt_proc) == -1)
+ goto out_free;
+
+ if (!next[0] || next[1]) {
+ fprintf(stderr, "fuse-subdir: exactly one next filesystem required\n");
+ goto out_free;
+ }
+
+ if (!d->base) {
+ fprintf(stderr, "fuse-subdir: missing 'subdir' option\n");
+ goto out_free;
+ }
+
+ if (d->base[0] && d->base[strlen(d->base)-1] != '/') {
+ char *tmp = realloc(d->base, strlen(d->base) + 2);
+ if (!tmp) {
+ fprintf(stderr, "fuse-subdir: memory allocation failed\n");
+ goto out_free;
+ }
+ d->base = tmp;
+ strcat(d->base, "/");
+ }
+ d->baselen = strlen(d->base);
+ d->next = next[0];
+ fs = fuse_fs_new(&subdir_oper, sizeof(subdir_oper), d);
+ if (!fs)
+ goto out_free;
+ return fs;
+
+out_free:
+ free(d->base);
+ free(d);
+ return NULL;
}
FUSE_REGISTER_MODULE(subdir, subdir_new);
diff --git a/lib/mount.c b/lib/mount.c
index 8a5c5ab..14fbfb5 100644
--- a/lib/mount.c
+++ b/lib/mount.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB.
*/
#include "config.h"
@@ -25,8 +25,8 @@
#include <sys/wait.h>
#include <sys/mount.h>
-#define FUSERMOUNT_PROG "fusermount"
-#define FUSE_COMMFD_ENV "_FUSE_COMMFD"
+#define FUSERMOUNT_PROG "fusermount"
+#define FUSE_COMMFD_ENV "_FUSE_COMMFD"
#ifndef HAVE_FORK
#define fork() vfork()
@@ -37,551 +37,555 @@
#endif
enum {
- KEY_KERN_FLAG,
- KEY_KERN_OPT,
- KEY_FUSERMOUNT_OPT,
- KEY_SUBTYPE_OPT,
- KEY_MTAB_OPT,
- KEY_ALLOW_ROOT,
- KEY_RO,
- KEY_HELP,
- KEY_VERSION,
+ KEY_KERN_FLAG,
+ KEY_KERN_OPT,
+ KEY_FUSERMOUNT_OPT,
+ KEY_SUBTYPE_OPT,
+ KEY_MTAB_OPT,
+ KEY_ALLOW_ROOT,
+ KEY_RO,
+ KEY_HELP,
+ KEY_VERSION,
};
struct mount_opts {
- int allow_other;
- int allow_root;
- int ishelp;
- int flags;
- int nonempty;
- int blkdev;
- char *fsname;
- char *subtype;
- char *subtype_opt;
- char *mtab_opts;
- char *fusermount_opts;
- char *kernel_opts;
+ int allow_other;
+ int allow_root;
+ int ishelp;
+ int flags;
+ int nonempty;
+ int blkdev;
+ char *fsname;
+ char *subtype;
+ char *subtype_opt;
+ char *mtab_opts;
+ char *fusermount_opts;
+ char *kernel_opts;
};
#define FUSE_MOUNT_OPT(t, p) { t, offsetof(struct mount_opts, p), 1 }
static const struct fuse_opt fuse_mount_opts[] = {
- FUSE_MOUNT_OPT("allow_other", allow_other),
- FUSE_MOUNT_OPT("allow_root", allow_root),
- FUSE_MOUNT_OPT("nonempty", nonempty),
- FUSE_MOUNT_OPT("blkdev", blkdev),
- FUSE_MOUNT_OPT("fsname=%s", fsname),
- FUSE_MOUNT_OPT("subtype=%s", subtype),
- FUSE_OPT_KEY("allow_other", KEY_KERN_OPT),
- FUSE_OPT_KEY("allow_root", KEY_ALLOW_ROOT),
- FUSE_OPT_KEY("nonempty", KEY_FUSERMOUNT_OPT),
- FUSE_OPT_KEY("blkdev", KEY_FUSERMOUNT_OPT),
- FUSE_OPT_KEY("fsname=", KEY_FUSERMOUNT_OPT),
- FUSE_OPT_KEY("subtype=", KEY_SUBTYPE_OPT),
- FUSE_OPT_KEY("large_read", KEY_KERN_OPT),
- FUSE_OPT_KEY("blksize=", KEY_KERN_OPT),
- FUSE_OPT_KEY("default_permissions", KEY_KERN_OPT),
- FUSE_OPT_KEY("max_read=", KEY_KERN_OPT),
- FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_KEEP),
- FUSE_OPT_KEY("user=", KEY_MTAB_OPT),
- FUSE_OPT_KEY("-r", KEY_RO),
- FUSE_OPT_KEY("ro", KEY_KERN_FLAG),
- FUSE_OPT_KEY("rw", KEY_KERN_FLAG),
- FUSE_OPT_KEY("suid", KEY_KERN_FLAG),
- FUSE_OPT_KEY("nosuid", KEY_KERN_FLAG),
- FUSE_OPT_KEY("dev", KEY_KERN_FLAG),
- FUSE_OPT_KEY("nodev", KEY_KERN_FLAG),
- FUSE_OPT_KEY("exec", KEY_KERN_FLAG),
- FUSE_OPT_KEY("noexec", KEY_KERN_FLAG),
- FUSE_OPT_KEY("async", KEY_KERN_FLAG),
- FUSE_OPT_KEY("sync", KEY_KERN_FLAG),
- FUSE_OPT_KEY("dirsync", KEY_KERN_FLAG),
- FUSE_OPT_KEY("atime", KEY_KERN_FLAG),
- FUSE_OPT_KEY("noatime", KEY_KERN_FLAG),
- FUSE_OPT_KEY("-h", KEY_HELP),
- FUSE_OPT_KEY("--help", KEY_HELP),
- FUSE_OPT_KEY("-V", KEY_VERSION),
- FUSE_OPT_KEY("--version", KEY_VERSION),
- FUSE_OPT_END
+ FUSE_MOUNT_OPT("allow_other", allow_other),
+ FUSE_MOUNT_OPT("allow_root", allow_root),
+ FUSE_MOUNT_OPT("nonempty", nonempty),
+ FUSE_MOUNT_OPT("blkdev", blkdev),
+ FUSE_MOUNT_OPT("fsname=%s", fsname),
+ FUSE_MOUNT_OPT("subtype=%s", subtype),
+ FUSE_OPT_KEY("allow_other", KEY_KERN_OPT),
+ FUSE_OPT_KEY("allow_root", KEY_ALLOW_ROOT),
+ FUSE_OPT_KEY("nonempty", KEY_FUSERMOUNT_OPT),
+ FUSE_OPT_KEY("blkdev", KEY_FUSERMOUNT_OPT),
+ FUSE_OPT_KEY("fsname=", KEY_FUSERMOUNT_OPT),
+ FUSE_OPT_KEY("subtype=", KEY_SUBTYPE_OPT),
+ FUSE_OPT_KEY("large_read", KEY_KERN_OPT),
+ FUSE_OPT_KEY("blksize=", KEY_KERN_OPT),
+ FUSE_OPT_KEY("default_permissions", KEY_KERN_OPT),
+ FUSE_OPT_KEY("max_read=", KEY_KERN_OPT),
+ FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_KEEP),
+ FUSE_OPT_KEY("user=", KEY_MTAB_OPT),
+ FUSE_OPT_KEY("-r", KEY_RO),
+ FUSE_OPT_KEY("ro", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("rw", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("suid", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("nosuid", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("dev", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("nodev", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("exec", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("noexec", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("async", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("sync", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("dirsync", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("atime", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("noatime", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("-h", KEY_HELP),
+ FUSE_OPT_KEY("--help", KEY_HELP),
+ FUSE_OPT_KEY("-V", KEY_VERSION),
+ FUSE_OPT_KEY("--version", KEY_VERSION),
+ FUSE_OPT_END
};
static void mount_help(void)
{
- fprintf(stderr,
- " -o allow_other allow access to other users\n"
- " -o allow_root allow access to root\n"
- " -o nonempty allow mounts over non-empty file/dir\n"
- " -o default_permissions enable permission checking by kernel\n"
- " -o fsname=NAME set filesystem name\n"
- " -o subtype=NAME set filesystem type\n"
- " -o large_read issue large read requests (2.4 only)\n"
- " -o max_read=N set maximum size of read requests\n"
- "\n"
- );
+ fprintf(stderr,
+" -o allow_other allow access to other users\n"
+" -o allow_root allow access to root\n"
+" -o nonempty allow mounts over non-empty file/dir\n"
+" -o default_permissions enable permission checking by kernel\n"
+" -o fsname=NAME set filesystem name\n"
+" -o subtype=NAME set filesystem type\n"
+" -o large_read issue large read requests (2.4 only)\n"
+" -o max_read=N set maximum size of read requests\n"
+"\n");
}
static void exec_fusermount(const char *argv[])
{
- execv(FUSERMOUNT_DIR "/" FUSERMOUNT_PROG, (char **) argv);
- execvp(FUSERMOUNT_PROG, (char **) argv);
+ execv(FUSERMOUNT_DIR "/" FUSERMOUNT_PROG, (char **) argv);
+ execvp(FUSERMOUNT_PROG, (char **) argv);
}
static void mount_version(void)
{
- int pid = fork();
- if (!pid) {
- const char *argv[] = { FUSERMOUNT_PROG, "--version", NULL };
- exec_fusermount(argv);
- _exit(1);
- } else if (pid != -1)
- waitpid(pid, NULL, 0);
+ int pid = fork();
+ if (!pid) {
+ const char *argv[] = { FUSERMOUNT_PROG, "--version", NULL };
+ exec_fusermount(argv);
+ _exit(1);
+ } else if (pid != -1)
+ waitpid(pid, NULL, 0);
}
struct mount_flags {
- const char *opt;
- unsigned long flag;
- int on;
+ const char *opt;
+ unsigned long flag;
+ int on;
};
static struct mount_flags mount_flags[] = {
- {"rw", MS_RDONLY, 0},
- {"ro", MS_RDONLY, 1},
- {"suid", MS_NOSUID, 0},
- {"nosuid", MS_NOSUID, 1},
- {"dev", MS_NODEV, 0},
- {"nodev", MS_NODEV, 1},
- {"exec", MS_NOEXEC, 0},
- {"noexec", MS_NOEXEC, 1},
- {"async", MS_SYNCHRONOUS, 0},
- {"sync", MS_SYNCHRONOUS, 1},
- {"atime", MS_NOATIME, 0},
- {"noatime", MS_NOATIME, 1},
- {"dirsync", MS_DIRSYNC, 1},
- {NULL, 0, 0}
+ {"rw", MS_RDONLY, 0},
+ {"ro", MS_RDONLY, 1},
+ {"suid", MS_NOSUID, 0},
+ {"nosuid", MS_NOSUID, 1},
+ {"dev", MS_NODEV, 0},
+ {"nodev", MS_NODEV, 1},
+ {"exec", MS_NOEXEC, 0},
+ {"noexec", MS_NOEXEC, 1},
+ {"async", MS_SYNCHRONOUS, 0},
+ {"sync", MS_SYNCHRONOUS, 1},
+ {"atime", MS_NOATIME, 0},
+ {"noatime", MS_NOATIME, 1},
+ {"dirsync", MS_DIRSYNC, 1},
+ {NULL, 0, 0}
};
static void set_mount_flag(const char *s, int *flags)
{
- int i;
-
- for (i = 0; mount_flags[i].opt != NULL; i++) {
- const char *opt = mount_flags[i].opt;
- if (strcmp(opt, s) == 0) {
- if (mount_flags[i].on)
- *flags |= mount_flags[i].flag;
- else
- *flags &= ~mount_flags[i].flag;
- return;
- }
- }
- fprintf(stderr, "fuse: internal error, can't find mount flag\n");
- abort();
+ int i;
+
+ for (i = 0; mount_flags[i].opt != NULL; i++) {
+ const char *opt = mount_flags[i].opt;
+ if (strcmp(opt, s) == 0) {
+ if (mount_flags[i].on)
+ *flags |= mount_flags[i].flag;
+ else
+ *flags &= ~mount_flags[i].flag;
+ return;
+ }
+ }
+ fprintf(stderr, "fuse: internal error, can't find mount flag\n");
+ abort();
}
static int fuse_mount_opt_proc(void *data, const char *arg, int key,
- struct fuse_args *outargs)
+ struct fuse_args *outargs)
{
- struct mount_opts *mo = data;
-
- switch (key) {
- case KEY_ALLOW_ROOT:
- if (fuse_opt_add_opt(&mo->kernel_opts, "allow_other") == -1 ||
- fuse_opt_add_arg(outargs, "-oallow_root") == -1)
- return -1;
- return 0;
-
- case KEY_RO:
- arg = "ro";
- /* fall through */
- case KEY_KERN_FLAG:
- set_mount_flag(arg, &mo->flags);
- return 0;
-
- case KEY_KERN_OPT:
- return fuse_opt_add_opt(&mo->kernel_opts, arg);
-
- case KEY_FUSERMOUNT_OPT:
- return fuse_opt_add_opt(&mo->fusermount_opts, arg);
-
- case KEY_SUBTYPE_OPT:
- return fuse_opt_add_opt(&mo->subtype_opt, arg);
-
- case KEY_MTAB_OPT:
- return fuse_opt_add_opt(&mo->mtab_opts, arg);
-
- case KEY_HELP:
- mount_help();
- mo->ishelp = 1;
- break;
-
- case KEY_VERSION:
- mount_version();
- mo->ishelp = 1;
- break;
- }
- return 1;
+ struct mount_opts *mo = data;
+
+ switch (key) {
+ case KEY_ALLOW_ROOT:
+ if (fuse_opt_add_opt(&mo->kernel_opts, "allow_other") == -1 ||
+ fuse_opt_add_arg(outargs, "-oallow_root") == -1)
+ return -1;
+ return 0;
+
+ case KEY_RO:
+ arg = "ro";
+ /* fall through */
+ case KEY_KERN_FLAG:
+ set_mount_flag(arg, &mo->flags);
+ return 0;
+
+ case KEY_KERN_OPT:
+ return fuse_opt_add_opt(&mo->kernel_opts, arg);
+
+ case KEY_FUSERMOUNT_OPT:
+ return fuse_opt_add_opt(&mo->fusermount_opts, arg);
+
+ case KEY_SUBTYPE_OPT:
+ return fuse_opt_add_opt(&mo->subtype_opt, arg);
+
+ case KEY_MTAB_OPT:
+ return fuse_opt_add_opt(&mo->mtab_opts, arg);
+
+ case KEY_HELP:
+ mount_help();
+ mo->ishelp = 1;
+ break;
+
+ case KEY_VERSION:
+ mount_version();
+ mo->ishelp = 1;
+ break;
+ }
+ return 1;
}
/* return value:
- * >= 0 => fd
- * -1 => error
+ * >= 0 => fd
+ * -1 => error
*/
static int receive_fd(int fd)
{
- struct msghdr msg;
- struct iovec iov;
- char buf[1];
- int rv;
- size_t ccmsg[CMSG_SPACE(sizeof(int)) / sizeof(size_t)];
- struct cmsghdr *cmsg;
-
- iov.iov_base = buf;
- iov.iov_len = 1;
-
- msg.msg_name = 0;
- msg.msg_namelen = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- /* old BSD implementations should use msg_accrights instead of
- * msg_control; the interface is different. */
- msg.msg_control = ccmsg;
- msg.msg_controllen = sizeof(ccmsg);
-
- while(((rv = recvmsg(fd, &msg, 0)) == -1) && errno == EINTR);
- if (rv == -1) {
- perror("recvmsg");
- return -1;
- }
- if(!rv) {
- /* EOF */
- return -1;
- }
-
- cmsg = CMSG_FIRSTHDR(&msg);
- if (!cmsg->cmsg_type == SCM_RIGHTS) {
- fprintf(stderr, "got control message of unknown type %d\n",
- cmsg->cmsg_type);
- return -1;
- }
- return *(int*)CMSG_DATA(cmsg);
+ struct msghdr msg;
+ struct iovec iov;
+ char buf[1];
+ int rv;
+ size_t ccmsg[CMSG_SPACE(sizeof(int)) / sizeof(size_t)];
+ struct cmsghdr *cmsg;
+
+ iov.iov_base = buf;
+ iov.iov_len = 1;
+
+ msg.msg_name = 0;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ /* old BSD implementations should use msg_accrights instead of
+ * msg_control; the interface is different. */
+ msg.msg_control = ccmsg;
+ msg.msg_controllen = sizeof(ccmsg);
+
+ while(((rv = recvmsg(fd, &msg, 0)) == -1) && errno == EINTR);
+ if (rv == -1) {
+ perror("recvmsg");
+ return -1;
+ }
+ if(!rv) {
+ /* EOF */
+ return -1;
+ }
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+ if (!cmsg->cmsg_type == SCM_RIGHTS) {
+ fprintf(stderr, "got control message of unknown type %d\n",
+ cmsg->cmsg_type);
+ return -1;
+ }
+ return *(int*)CMSG_DATA(cmsg);
}
void fuse_kern_unmount(const char *mountpoint, int fd)
{
- int res;
- int pid;
-
- if (!mountpoint)
- return;
-
- if (fd != -1) {
- struct pollfd pfd;
-
- pfd.fd = fd;
- pfd.events = 0;
- res = poll(&pfd, 1, 0);
- /* If file poll returns POLLERR on the device file descriptor,
- then the filesystem is already unmounted */
- if (res == 1 && (pfd.revents & POLLERR))
- return;
-
- /* Need to close file descriptor, otherwise synchronous umount
- would recurse into filesystem, and deadlock */
- close(fd);
- }
-
- if (geteuid() == 0) {
- fuse_mnt_umount("fuse", mountpoint, 1);
- return;
- }
-
- res = umount2(mountpoint, 2);
- if (res == 0)
- return;
-
- pid = fork();
- if(pid == -1)
- return;
-
- if(pid == 0) {
- const char *argv[] =
- { FUSERMOUNT_PROG, "-u", "-q", "-z", "--", mountpoint, NULL };
-
- exec_fusermount(argv);
- _exit(1);
- }
- waitpid(pid, NULL, 0);
+ int res;
+ int pid;
+
+ if (!mountpoint)
+ return;
+
+ if (fd != -1) {
+ struct pollfd pfd;
+
+ pfd.fd = fd;
+ pfd.events = 0;
+ res = poll(&pfd, 1, 0);
+ /* If file poll returns POLLERR on the device file descriptor,
+ then the filesystem is already unmounted */
+ if (res == 1 && (pfd.revents & POLLERR))
+ return;
+
+ /* Need to close file descriptor, otherwise synchronous umount
+ would recurse into filesystem, and deadlock */
+ close(fd);
+ }
+
+ if (geteuid() == 0) {
+ fuse_mnt_umount("fuse", mountpoint, 1);
+ return;
+ }
+
+ res = umount2(mountpoint, 2);
+ if (res == 0)
+ return;
+
+ pid = fork();
+ if(pid == -1)
+ return;
+
+ if(pid == 0) {
+ const char *argv[] = { FUSERMOUNT_PROG, "-u", "-q", "-z",
+ "--", mountpoint, NULL };
+
+ exec_fusermount(argv);
+ _exit(1);
+ }
+ waitpid(pid, NULL, 0);
}
void fuse_unmount_compat22(const char *mountpoint)
{
- fuse_kern_unmount(mountpoint, -1);
+ fuse_kern_unmount(mountpoint, -1);
}
static int fuse_mount_fusermount(const char *mountpoint, const char *opts,
- int quiet)
+ int quiet)
{
- int fds[2], pid;
- int res;
- int rv;
-
- if (!mountpoint) {
- fprintf(stderr, "fuse: missing mountpoint\n");
- return -1;
- }
-
- res = socketpair(PF_UNIX, SOCK_STREAM, 0, fds);
- if(res == -1) {
- perror("fuse: socketpair() failed");
- return -1;
- }
-
- pid = fork();
- if(pid == -1) {
- perror("fuse: fork() failed");
- close(fds[0]);
- close(fds[1]);
- return -1;
- }
-
- if(pid == 0) {
- char env[10];
- const char *argv[32];
- int a = 0;
-
- if (quiet) {
- int fd = open("/dev/null", O_RDONLY);
- dup2(fd, 1);
- dup2(fd, 2);
- }
-
- argv[a++] = FUSERMOUNT_PROG;
- if (opts) {
- argv[a++] = "-o";
- argv[a++] = opts;
- }
- argv[a++] = "--";
- argv[a++] = mountpoint;
- argv[a++] = NULL;
-
- close(fds[1]);
- fcntl(fds[0], F_SETFD, 0);
- snprintf(env, sizeof(env), "%i", fds[0]);
- setenv(FUSE_COMMFD_ENV, env, 1);
- exec_fusermount(argv);
- perror("fuse: failed to exec fusermount");
- _exit(1);
- }
-
- close(fds[0]);
- rv = receive_fd(fds[1]);
- close(fds[1]);
- waitpid(pid, NULL, 0); /* bury zombie */
-
- return rv;
+ int fds[2], pid;
+ int res;
+ int rv;
+
+ if (!mountpoint) {
+ fprintf(stderr, "fuse: missing mountpoint\n");
+ return -1;
+ }
+
+ res = socketpair(PF_UNIX, SOCK_STREAM, 0, fds);
+ if(res == -1) {
+ perror("fuse: socketpair() failed");
+ return -1;
+ }
+
+ pid = fork();
+ if(pid == -1) {
+ perror("fuse: fork() failed");
+ close(fds[0]);
+ close(fds[1]);
+ return -1;
+ }
+
+ if(pid == 0) {
+ char env[10];
+ const char *argv[32];
+ int a = 0;
+
+ if (quiet) {
+ int fd = open("/dev/null", O_RDONLY);
+ dup2(fd, 1);
+ dup2(fd, 2);
+ }
+
+ argv[a++] = FUSERMOUNT_PROG;
+ if (opts) {
+ argv[a++] = "-o";
+ argv[a++] = opts;
+ }
+ argv[a++] = "--";
+ argv[a++] = mountpoint;
+ argv[a++] = NULL;
+
+ close(fds[1]);
+ fcntl(fds[0], F_SETFD, 0);
+ snprintf(env, sizeof(env), "%i", fds[0]);
+ setenv(FUSE_COMMFD_ENV, env, 1);
+ exec_fusermount(argv);
+ perror("fuse: failed to exec fusermount");
+ _exit(1);
+ }
+
+ close(fds[0]);
+ rv = receive_fd(fds[1]);
+ close(fds[1]);
+ waitpid(pid, NULL, 0); /* bury zombie */
+
+ return rv;
}
int fuse_mount_compat22(const char *mountpoint, const char *opts)
{
- return fuse_mount_fusermount(mountpoint, opts, 0);
+ return fuse_mount_fusermount(mountpoint, opts, 0);
}
static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
- const char *mnt_opts)
+ const char *mnt_opts)
{
- char tmp[128];
- const char *devname = "/dev/fuse";
- char *source = NULL;
- char *type = NULL;
- struct stat stbuf;
- int fd;
- int res;
-
- if (!mnt) {
- fprintf(stderr, "fuse: missing mountpoint\n");
- return -1;
- }
-
- res = lstat(mnt, &stbuf);
- if (res == -1) {
- fprintf(stderr ,"fuse: failed to access mountpoint %s: %s\n",
- mnt, strerror(errno));
- return -1;
- }
-
- if (!mo->nonempty) {
- res = fuse_mnt_check_empty("fuse", mnt, stbuf.st_mode, stbuf.st_size);
- if (res == -1)
- return -1;
- }
-
- fd = open(devname, O_RDWR);
- if (fd == -1) {
- if (errno == ENODEV || errno == ENOENT)
- fprintf(stderr,
- "fuse: device not found, try 'modprobe fuse' first\n");
- else
- fprintf(stderr, "fuse: failed to open %s: %s\n", devname,
- strerror(errno));
- return -1;
- }
-
- snprintf(tmp, sizeof(tmp), "fd=%i,rootmode=%o,user_id=%i,group_id=%i", fd,
- stbuf.st_mode & S_IFMT, getuid(), getgid());
-
- res = fuse_opt_add_opt(&mo->kernel_opts, tmp);
- if (res == -1)
- goto out_close;
-
- source = malloc((mo->fsname ? strlen(mo->fsname) : 0) +
- (mo->subtype ? strlen(mo->subtype) : 0) +
- strlen(devname) + 32);
-
- type = malloc((mo->subtype ? strlen(mo->subtype) : 0) + 32);
- if (!type || !source) {
- fprintf(stderr, "fuse: failed to allocate memory\n");
- goto out_close;
- }
-
- strcpy(type, mo->blkdev ? "fuseblk" : "fuse");
- if (mo->subtype) {
- strcat(type, ".");
- strcat(type, mo->subtype);
- }
- strcpy(source,
- mo->fsname ? mo->fsname : (mo->subtype ? mo->subtype : devname));
-
- res = mount(source, mnt, type, mo->flags, mo->kernel_opts);
- if (res == -1 && errno == ENODEV && mo->subtype) {
- /* Probably missing subtype support */
- strcpy(type, mo->blkdev ? "fuseblk" : "fuse");
- if (mo->fsname) {
- if (!mo->blkdev)
- sprintf(source, "%s#%s", mo->subtype, mo->fsname);
- } else {
- strcpy(source, type);
- }
- res = mount(source, mnt, type, mo->flags, mo->kernel_opts);
- }
- if (res == -1) {
- /*
- * Maybe kernel doesn't support unprivileged mounts, in this
- * case try falling back to fusermount
- */
- if (errno == EPERM) {
- res = -2;
- } else {
- int errno_save = errno;
- if (mo->blkdev && errno == ENODEV && !fuse_mnt_check_fuseblk())
- fprintf(stderr, "fuse: 'fuseblk' support missing\n");
- else
- fprintf(stderr, "fuse: mount failed: %s\n",
- strerror(errno_save));
- }
-
- goto out_close;
- }
-
- if (geteuid() == 0) {
- char *newmnt = fuse_mnt_resolve_path("fuse", mnt);
- res = -1;
- if (!newmnt)
- goto out_umount;
-
- res = fuse_mnt_add_mount("fuse", source, newmnt, type, mnt_opts);
- free(newmnt);
- if (res == -1)
- goto out_umount;
- }
-
- return fd;
-
- out_umount:
- umount2(mnt, 2); /* lazy umount */
- out_close:
- free(type);
- free(source);
- close(fd);
- return res;
+ char tmp[128];
+ const char *devname = "/dev/fuse";
+ char *source = NULL;
+ char *type = NULL;
+ struct stat stbuf;
+ int fd;
+ int res;
+
+ if (!mnt) {
+ fprintf(stderr, "fuse: missing mountpoint\n");
+ return -1;
+ }
+
+ res = lstat(mnt, &stbuf);
+ if (res == -1) {
+ fprintf(stderr ,"fuse: failed to access mountpoint %s: %s\n",
+ mnt, strerror(errno));
+ return -1;
+ }
+
+ if (!mo->nonempty) {
+ res = fuse_mnt_check_empty("fuse", mnt, stbuf.st_mode,
+ stbuf.st_size);
+ if (res == -1)
+ return -1;
+ }
+
+ fd = open(devname, O_RDWR);
+ if (fd == -1) {
+ if (errno == ENODEV || errno == ENOENT)
+ fprintf(stderr, "fuse: device not found, try 'modprobe fuse' first\n");
+ else
+ fprintf(stderr, "fuse: failed to open %s: %s\n",
+ devname, strerror(errno));
+ return -1;
+ }
+
+ snprintf(tmp, sizeof(tmp), "fd=%i,rootmode=%o,user_id=%i,group_id=%i",
+ fd, stbuf.st_mode & S_IFMT, getuid(), getgid());
+
+ res = fuse_opt_add_opt(&mo->kernel_opts, tmp);
+ if (res == -1)
+ goto out_close;
+
+ source = malloc((mo->fsname ? strlen(mo->fsname) : 0) +
+ (mo->subtype ? strlen(mo->subtype) : 0) +
+ strlen(devname) + 32);
+
+ type = malloc((mo->subtype ? strlen(mo->subtype) : 0) + 32);
+ if (!type || !source) {
+ fprintf(stderr, "fuse: failed to allocate memory\n");
+ goto out_close;
+ }
+
+ strcpy(type, mo->blkdev ? "fuseblk" : "fuse");
+ if (mo->subtype) {
+ strcat(type, ".");
+ strcat(type, mo->subtype);
+ }
+ strcpy(source,
+ mo->fsname ? mo->fsname : (mo->subtype ? mo->subtype : devname));
+
+ res = mount(source, mnt, type, mo->flags, mo->kernel_opts);
+ if (res == -1 && errno == ENODEV && mo->subtype) {
+ /* Probably missing subtype support */
+ strcpy(type, mo->blkdev ? "fuseblk" : "fuse");
+ if (mo->fsname) {
+ if (!mo->blkdev)
+ sprintf(source, "%s#%s", mo->subtype,
+ mo->fsname);
+ } else {
+ strcpy(source, type);
+ }
+ res = mount(source, mnt, type, mo->flags, mo->kernel_opts);
+ }
+ if (res == -1) {
+ /*
+ * Maybe kernel doesn't support unprivileged mounts, in this
+ * case try falling back to fusermount
+ */
+ if (errno == EPERM) {
+ res = -2;
+ } else {
+ int errno_save = errno;
+ if (mo->blkdev && errno == ENODEV &&
+ !fuse_mnt_check_fuseblk())
+ fprintf(stderr,
+ "fuse: 'fuseblk' support missing\n");
+ else
+ fprintf(stderr, "fuse: mount failed: %s\n",
+ strerror(errno_save));
+ }
+
+ goto out_close;
+ }
+
+ if (geteuid() == 0) {
+ char *newmnt = fuse_mnt_resolve_path("fuse", mnt);
+ res = -1;
+ if (!newmnt)
+ goto out_umount;
+
+ res = fuse_mnt_add_mount("fuse", source, newmnt, type,
+ mnt_opts);
+ free(newmnt);
+ if (res == -1)
+ goto out_umount;
+ }
+
+ return fd;
+
+out_umount:
+ umount2(mnt, 2); /* lazy umount */
+out_close:
+ free(type);
+ free(source);
+ close(fd);
+ return res;
}
static int get_mnt_flag_opts(char **mnt_optsp, int flags)
{
- int i;
+ int i;
- if (!(flags & MS_RDONLY) && fuse_opt_add_opt(mnt_optsp, "rw") == -1)
- return -1;
+ if (!(flags & MS_RDONLY) && fuse_opt_add_opt(mnt_optsp, "rw") == -1)
+ return -1;
- for (i = 0; mount_flags[i].opt != NULL; i++) {
- if (mount_flags[i].on && (flags & mount_flags[i].flag) &&
- fuse_opt_add_opt(mnt_optsp, mount_flags[i].opt) == -1)
- return -1;
- }
- return 0;
+ for (i = 0; mount_flags[i].opt != NULL; i++) {
+ if (mount_flags[i].on && (flags & mount_flags[i].flag) &&
+ fuse_opt_add_opt(mnt_optsp, mount_flags[i].opt) == -1)
+ return -1;
+ }
+ return 0;
}
int fuse_kern_mount(const char *mountpoint, struct fuse_args *args)
{
- struct mount_opts mo;
- int res = -1;
- char *mnt_opts = NULL;
-
- memset(&mo, 0, sizeof(mo));
- mo.flags = MS_NOSUID | MS_NODEV;
-
- if (args &&
- fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == -1)
- return -1;
-
- if (mo.allow_other && mo.allow_root) {
- fprintf(stderr, "fuse: 'allow_other' and 'allow_root' options are mutually exclusive\n");
- goto out;
- }
- res = 0;
- if (mo.ishelp)
- goto out;
-
- res = -1;
- if (get_mnt_flag_opts(&mnt_opts, mo.flags) == -1)
- goto out;
- if (mo.kernel_opts && fuse_opt_add_opt(&mnt_opts, mo.kernel_opts) == -1)
- goto out;
- if (mo.mtab_opts && fuse_opt_add_opt(&mnt_opts, mo.mtab_opts) == -1)
- goto out;
-
- res = fuse_mount_sys(mountpoint, &mo, mnt_opts);
- if (res == -2) {
- if (mo.fusermount_opts &&
- fuse_opt_add_opt(&mnt_opts, mo.fusermount_opts) == -1)
- goto out;
-
- if (mo.subtype) {
- char *tmp_opts = NULL;
-
- res = -1;
- if (fuse_opt_add_opt(&tmp_opts, mnt_opts) == -1 ||
- fuse_opt_add_opt(&tmp_opts, mo.subtype_opt) == -1) {
- free(tmp_opts);
- goto out;
- }
-
- res = fuse_mount_fusermount(mountpoint, tmp_opts, 1);
- free(tmp_opts);
- if (res == -1)
- res = fuse_mount_fusermount(mountpoint, mnt_opts, 0);
- } else {
- res = fuse_mount_fusermount(mountpoint, mnt_opts, 0);
- }
- }
- out:
- free(mnt_opts);
- free(mo.fsname);
- free(mo.subtype);
- free(mo.fusermount_opts);
- free(mo.subtype_opt);
- free(mo.kernel_opts);
- free(mo.mtab_opts);
- return res;
+ struct mount_opts mo;
+ int res = -1;
+ char *mnt_opts = NULL;
+
+ memset(&mo, 0, sizeof(mo));
+ mo.flags = MS_NOSUID | MS_NODEV;
+
+ if (args &&
+ fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == -1)
+ return -1;
+
+ if (mo.allow_other && mo.allow_root) {
+ fprintf(stderr, "fuse: 'allow_other' and 'allow_root' options are mutually exclusive\n");
+ goto out;
+ }
+ res = 0;
+ if (mo.ishelp)
+ goto out;
+
+ res = -1;
+ if (get_mnt_flag_opts(&mnt_opts, mo.flags) == -1)
+ goto out;
+ if (mo.kernel_opts && fuse_opt_add_opt(&mnt_opts, mo.kernel_opts) == -1)
+ goto out;
+ if (mo.mtab_opts && fuse_opt_add_opt(&mnt_opts, mo.mtab_opts) == -1)
+ goto out;
+
+ res = fuse_mount_sys(mountpoint, &mo, mnt_opts);
+ if (res == -2) {
+ if (mo.fusermount_opts &&
+ fuse_opt_add_opt(&mnt_opts, mo.fusermount_opts) == -1)
+ goto out;
+
+ if (mo.subtype) {
+ char *tmp_opts = NULL;
+
+ res = -1;
+ if (fuse_opt_add_opt(&tmp_opts, mnt_opts) == -1 ||
+ fuse_opt_add_opt(&tmp_opts, mo.subtype_opt) == -1) {
+ free(tmp_opts);
+ goto out;
+ }
+
+ res = fuse_mount_fusermount(mountpoint, tmp_opts, 1);
+ free(tmp_opts);
+ if (res == -1)
+ res = fuse_mount_fusermount(mountpoint,
+ mnt_opts, 0);
+ } else {
+ res = fuse_mount_fusermount(mountpoint, mnt_opts, 0);
+ }
+ }
+out:
+ free(mnt_opts);
+ free(mo.fsname);
+ free(mo.subtype);
+ free(mo.fusermount_opts);
+ free(mo.subtype_opt);
+ free(mo.kernel_opts);
+ free(mo.mtab_opts);
+ return res;
}
FUSE_SYMVER(".symver fuse_mount_compat22,fuse_mount@FUSE_2.2");
diff --git a/lib/mount_bsd.c b/lib/mount_bsd.c
index 5197464..fb4f12a 100644
--- a/lib/mount_bsd.c
+++ b/lib/mount_bsd.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2005-2006 Csaba Henk <csaba.henk@creo.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2005-2006 Csaba Henk <csaba.henk@creo.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB.
*/
#include "fuse_i.h"
@@ -22,343 +22,349 @@
#include <string.h>
#include <paths.h>
-#define FUSERMOUNT_PROG "mount_fusefs"
-#define FUSE_DEV_TRUNK "/dev/fuse"
+#define FUSERMOUNT_PROG "mount_fusefs"
+#define FUSE_DEV_TRUNK "/dev/fuse"
enum {
- KEY_ALLOW_ROOT,
- KEY_RO,
- KEY_HELP,
- KEY_VERSION,
- KEY_KERN
+ KEY_ALLOW_ROOT,
+ KEY_RO,
+ KEY_HELP,
+ KEY_VERSION,
+ KEY_KERN
};
struct mount_opts {
- int allow_other;
- int allow_root;
- int ishelp;
- char *kernel_opts;
+ int allow_other;
+ int allow_root;
+ int ishelp;
+ char *kernel_opts;
};
static const struct fuse_opt fuse_mount_opts[] = {
- { "allow_other", offsetof(struct mount_opts, allow_other), 1 },
- { "allow_root", offsetof(struct mount_opts, allow_root), 1 },
- FUSE_OPT_KEY("allow_root", KEY_ALLOW_ROOT),
- FUSE_OPT_KEY("-r", KEY_RO),
- FUSE_OPT_KEY("-h", KEY_HELP),
- FUSE_OPT_KEY("--help", KEY_HELP),
- FUSE_OPT_KEY("-V", KEY_VERSION),
- FUSE_OPT_KEY("--version", KEY_VERSION),
- /* standard FreeBSD mount options */
- FUSE_OPT_KEY("dev", KEY_KERN),
- FUSE_OPT_KEY("async", KEY_KERN),
- FUSE_OPT_KEY("atime", KEY_KERN),
- FUSE_OPT_KEY("dev", KEY_KERN),
- FUSE_OPT_KEY("exec", KEY_KERN),
- FUSE_OPT_KEY("suid", KEY_KERN),
- FUSE_OPT_KEY("symfollow", KEY_KERN),
- FUSE_OPT_KEY("rdonly", KEY_KERN),
- FUSE_OPT_KEY("sync", KEY_KERN),
- FUSE_OPT_KEY("union", KEY_KERN),
- FUSE_OPT_KEY("userquota", KEY_KERN),
- FUSE_OPT_KEY("groupquota", KEY_KERN),
- FUSE_OPT_KEY("clusterr", KEY_KERN),
- FUSE_OPT_KEY("clusterw", KEY_KERN),
- FUSE_OPT_KEY("suiddir", KEY_KERN),
- FUSE_OPT_KEY("snapshot", KEY_KERN),
- FUSE_OPT_KEY("multilabel", KEY_KERN),
- FUSE_OPT_KEY("acls", KEY_KERN),
- FUSE_OPT_KEY("force", KEY_KERN),
- FUSE_OPT_KEY("update", KEY_KERN),
- FUSE_OPT_KEY("ro", KEY_KERN),
- FUSE_OPT_KEY("rw", KEY_KERN),
- FUSE_OPT_KEY("auto", KEY_KERN),
- /* options supported under both Linux and FBSD */
- FUSE_OPT_KEY("allow_other", KEY_KERN),
- FUSE_OPT_KEY("default_permissions", KEY_KERN),
- /* FBSD FUSE specific mount options */
- FUSE_OPT_KEY("private", KEY_KERN),
- FUSE_OPT_KEY("neglect_shares", KEY_KERN),
- FUSE_OPT_KEY("push_symlinks_in", KEY_KERN),
- /* stock FBSD mountopt parsing routine lets anything be negated... */
- FUSE_OPT_KEY("nodev", KEY_KERN),
- FUSE_OPT_KEY("noasync", KEY_KERN),
- FUSE_OPT_KEY("noatime", KEY_KERN),
- FUSE_OPT_KEY("nodev", KEY_KERN),
- FUSE_OPT_KEY("noexec", KEY_KERN),
- FUSE_OPT_KEY("nosuid", KEY_KERN),
- FUSE_OPT_KEY("nosymfollow", KEY_KERN),
- FUSE_OPT_KEY("nordonly", KEY_KERN),
- FUSE_OPT_KEY("nosync", KEY_KERN),
- FUSE_OPT_KEY("nounion", KEY_KERN),
- FUSE_OPT_KEY("nouserquota", KEY_KERN),
- FUSE_OPT_KEY("nogroupquota", KEY_KERN),
- FUSE_OPT_KEY("noclusterr", KEY_KERN),
- FUSE_OPT_KEY("noclusterw", KEY_KERN),
- FUSE_OPT_KEY("nosuiddir", KEY_KERN),
- FUSE_OPT_KEY("nosnapshot", KEY_KERN),
- FUSE_OPT_KEY("nomultilabel", KEY_KERN),
- FUSE_OPT_KEY("noacls", KEY_KERN),
- FUSE_OPT_KEY("noforce", KEY_KERN),
- FUSE_OPT_KEY("noupdate", KEY_KERN),
- FUSE_OPT_KEY("noro", KEY_KERN),
- FUSE_OPT_KEY("norw", KEY_KERN),
- FUSE_OPT_KEY("noauto", KEY_KERN),
- FUSE_OPT_KEY("noallow_other", KEY_KERN),
- FUSE_OPT_KEY("nodefault_permissions", KEY_KERN),
- FUSE_OPT_KEY("noprivate", KEY_KERN),
- FUSE_OPT_KEY("noneglect_shares", KEY_KERN),
- FUSE_OPT_KEY("nopush_symlinks_in", KEY_KERN),
- /* Linux specific mount options, but let just the mount util handle them */
- FUSE_OPT_KEY("fsname=", KEY_KERN),
- FUSE_OPT_KEY("nonempty", KEY_KERN),
- FUSE_OPT_KEY("large_read", KEY_KERN),
- FUSE_OPT_KEY("max_read=", KEY_KERN),
- FUSE_OPT_END
+ { "allow_other", offsetof(struct mount_opts, allow_other), 1 },
+ { "allow_root", offsetof(struct mount_opts, allow_root), 1 },
+ FUSE_OPT_KEY("allow_root", KEY_ALLOW_ROOT),
+ FUSE_OPT_KEY("-r", KEY_RO),
+ FUSE_OPT_KEY("-h", KEY_HELP),
+ FUSE_OPT_KEY("--help", KEY_HELP),
+ FUSE_OPT_KEY("-V", KEY_VERSION),
+ FUSE_OPT_KEY("--version", KEY_VERSION),
+ /* standard FreeBSD mount options */
+ FUSE_OPT_KEY("dev", KEY_KERN),
+ FUSE_OPT_KEY("async", KEY_KERN),
+ FUSE_OPT_KEY("atime", KEY_KERN),
+ FUSE_OPT_KEY("dev", KEY_KERN),
+ FUSE_OPT_KEY("exec", KEY_KERN),
+ FUSE_OPT_KEY("suid", KEY_KERN),
+ FUSE_OPT_KEY("symfollow", KEY_KERN),
+ FUSE_OPT_KEY("rdonly", KEY_KERN),
+ FUSE_OPT_KEY("sync", KEY_KERN),
+ FUSE_OPT_KEY("union", KEY_KERN),
+ FUSE_OPT_KEY("userquota", KEY_KERN),
+ FUSE_OPT_KEY("groupquota", KEY_KERN),
+ FUSE_OPT_KEY("clusterr", KEY_KERN),
+ FUSE_OPT_KEY("clusterw", KEY_KERN),
+ FUSE_OPT_KEY("suiddir", KEY_KERN),
+ FUSE_OPT_KEY("snapshot", KEY_KERN),
+ FUSE_OPT_KEY("multilabel", KEY_KERN),
+ FUSE_OPT_KEY("acls", KEY_KERN),
+ FUSE_OPT_KEY("force", KEY_KERN),
+ FUSE_OPT_KEY("update", KEY_KERN),
+ FUSE_OPT_KEY("ro", KEY_KERN),
+ FUSE_OPT_KEY("rw", KEY_KERN),
+ FUSE_OPT_KEY("auto", KEY_KERN),
+ /* options supported under both Linux and FBSD */
+ FUSE_OPT_KEY("allow_other", KEY_KERN),
+ FUSE_OPT_KEY("default_permissions", KEY_KERN),
+ /* FBSD FUSE specific mount options */
+ FUSE_OPT_KEY("private", KEY_KERN),
+ FUSE_OPT_KEY("neglect_shares", KEY_KERN),
+ FUSE_OPT_KEY("push_symlinks_in", KEY_KERN),
+ /* stock FBSD mountopt parsing routine lets anything be negated... */
+ FUSE_OPT_KEY("nodev", KEY_KERN),
+ FUSE_OPT_KEY("noasync", KEY_KERN),
+ FUSE_OPT_KEY("noatime", KEY_KERN),
+ FUSE_OPT_KEY("nodev", KEY_KERN),
+ FUSE_OPT_KEY("noexec", KEY_KERN),
+ FUSE_OPT_KEY("nosuid", KEY_KERN),
+ FUSE_OPT_KEY("nosymfollow", KEY_KERN),
+ FUSE_OPT_KEY("nordonly", KEY_KERN),
+ FUSE_OPT_KEY("nosync", KEY_KERN),
+ FUSE_OPT_KEY("nounion", KEY_KERN),
+ FUSE_OPT_KEY("nouserquota", KEY_KERN),
+ FUSE_OPT_KEY("nogroupquota", KEY_KERN),
+ FUSE_OPT_KEY("noclusterr", KEY_KERN),
+ FUSE_OPT_KEY("noclusterw", KEY_KERN),
+ FUSE_OPT_KEY("nosuiddir", KEY_KERN),
+ FUSE_OPT_KEY("nosnapshot", KEY_KERN),
+ FUSE_OPT_KEY("nomultilabel", KEY_KERN),
+ FUSE_OPT_KEY("noacls", KEY_KERN),
+ FUSE_OPT_KEY("noforce", KEY_KERN),
+ FUSE_OPT_KEY("noupdate", KEY_KERN),
+ FUSE_OPT_KEY("noro", KEY_KERN),
+ FUSE_OPT_KEY("norw", KEY_KERN),
+ FUSE_OPT_KEY("noauto", KEY_KERN),
+ FUSE_OPT_KEY("noallow_other", KEY_KERN),
+ FUSE_OPT_KEY("nodefault_permissions", KEY_KERN),
+ FUSE_OPT_KEY("noprivate", KEY_KERN),
+ FUSE_OPT_KEY("noneglect_shares", KEY_KERN),
+ FUSE_OPT_KEY("nopush_symlinks_in", KEY_KERN),
+ /*
+ * Linux specific mount options, but let just the mount util
+ * handle them
+ */
+ FUSE_OPT_KEY("fsname=", KEY_KERN),
+ FUSE_OPT_KEY("nonempty", KEY_KERN),
+ FUSE_OPT_KEY("large_read", KEY_KERN),
+ FUSE_OPT_KEY("max_read=", KEY_KERN),
+ FUSE_OPT_END
};
static void mount_help(void)
{
- fprintf(stderr,
- " -o allow_root allow access to root\n"
- );
- system(FUSERMOUNT_PROG " --help");
- fputc('\n', stderr);
+ fprintf(stderr,
+ " -o allow_root allow access to root\n"
+ );
+ system(FUSERMOUNT_PROG " --help");
+ fputc('\n', stderr);
}
static void mount_version(void)
{
- system(FUSERMOUNT_PROG " --version");
+ system(FUSERMOUNT_PROG " --version");
}
static int fuse_mount_opt_proc(void *data, const char *arg, int key,
- struct fuse_args *outargs)
+ struct fuse_args *outargs)
{
- struct mount_opts *mo = data;
-
- switch (key) {
- case KEY_ALLOW_ROOT:
- if (fuse_opt_add_opt(&mo->kernel_opts, "allow_other") == -1 ||
- fuse_opt_add_arg(outargs, "-oallow_root") == -1)
- return -1;
- return 0;
-
- case KEY_RO:
- arg = "ro";
- /* fall through */
-
- case KEY_KERN:
- return fuse_opt_add_opt(&mo->kernel_opts, arg);
-
- case KEY_HELP:
- mount_help();
- mo->ishelp = 1;
- break;
-
- case KEY_VERSION:
- mount_version();
- mo->ishelp = 1;
- break;
- }
- return 1;
+ struct mount_opts *mo = data;
+
+ switch (key) {
+ case KEY_ALLOW_ROOT:
+ if (fuse_opt_add_opt(&mo->kernel_opts, "allow_other") == -1 ||
+ fuse_opt_add_arg(outargs, "-oallow_root") == -1)
+ return -1;
+ return 0;
+
+ case KEY_RO:
+ arg = "ro";
+ /* fall through */
+
+ case KEY_KERN:
+ return fuse_opt_add_opt(&mo->kernel_opts, arg);
+
+ case KEY_HELP:
+ mount_help();
+ mo->ishelp = 1;
+ break;
+
+ case KEY_VERSION:
+ mount_version();
+ mo->ishelp = 1;
+ break;
+ }
+ return 1;
}
void fuse_unmount_compat22(const char *mountpoint)
{
- char dev[128];
- char *ssc, *umount_cmd;
- FILE *sf;
- int rv;
- char *seekscript =
- "exec 2>/dev/null; " /* error message is annoying in help output */
- "/usr/bin/fstat " FUSE_DEV_TRUNK "* | "
- "/usr/bin/awk 'BEGIN{ getline; if (! ($3 == \"PID\" && $10 == \"NAME\")) exit 1; }; "
- " { if ($3 == %d) print $10; }' | "
- "/usr/bin/sort | "
- "/usr/bin/uniq | "
- "/usr/bin/awk '{ i += 1; if (i > 1){ exit 1; }; printf; }; END{ if (i == 0) exit 1; }'";
-
- (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;
- 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);
+ char dev[128];
+ char *ssc, *umount_cmd;
+ FILE *sf;
+ int rv;
+ char *seekscript =
+ /* error message is annoying in help output */
+ "exec 2>/dev/null; "
+ "/usr/bin/fstat " FUSE_DEV_TRUNK "* | "
+ "/usr/bin/awk 'BEGIN{ getline; if (! ($3 == \"PID\" && $10 == \"NAME\")) exit 1; }; "
+ " { if ($3 == %d) print $10; }' | "
+ "/usr/bin/sort | "
+ "/usr/bin/uniq | "
+ "/usr/bin/awk '{ i += 1; if (i > 1){ exit 1; }; printf; }; END{ if (i == 0) exit 1; }'";
+
+ (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;
+ 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);
}
void fuse_kern_unmount(const char *mountpoint, int fd)
{
- char *ep, *umount_cmd, dev[128];
- struct stat sbuf;
+ char *ep, *umount_cmd, dev[128];
+ struct stat sbuf;
- (void)mountpoint;
+ (void)mountpoint;
- if (fstat(fd, &sbuf) == -1)
- return;
+ if (fstat(fd, &sbuf) == -1)
+ return;
- devname_r(sbuf.st_rdev, S_IFCHR, dev, 128);
+ devname_r(sbuf.st_rdev, S_IFCHR, dev, 128);
- if (strncmp(dev, "fuse", 4))
- return;
+ if (strncmp(dev, "fuse", 4))
+ return;
- strtol(dev + 4, &ep, 10);
- if (*ep != '\0')
- return;
+ strtol(dev + 4, &ep, 10);
+ if (*ep != '\0')
+ return;
- asprintf(&umount_cmd, "/sbin/umount " _PATH_DEV "%s", dev);
- system(umount_cmd);
+ asprintf(&umount_cmd, "/sbin/umount " _PATH_DEV "%s", dev);
+ system(umount_cmd);
}
/* Check if kernel is doing init in background */
static int init_backgrounded(void)
{
- int ibg, len;
+ int ibg, len;
- len = sizeof(ibg);
+ len = sizeof(ibg);
- if (sysctlbyname("vfs.fuse.init_backgrounded", &ibg, &len, NULL, 0))
- return 0;
+ if (sysctlbyname("vfs.fuse.init_backgrounded", &ibg, &len, NULL, 0))
+ return 0;
- return ibg;
+ return ibg;
}
static int fuse_mount_core(const char *mountpoint, const char *opts)
{
- const char *mountprog = FUSERMOUNT_PROG;
- int fd;
- char *fdnam, *dev;
- int pid;
+ const char *mountprog = FUSERMOUNT_PROG;
+ int fd;
+ char *fdnam, *dev;
+ int pid;
- fdnam = getenv("FUSE_DEV_FD");
+ fdnam = getenv("FUSE_DEV_FD");
- if (fdnam) {
- char *ep;
+ if (fdnam) {
+ char *ep;
- fd = strtol(fdnam, &ep, 10);
+ fd = strtol(fdnam, &ep, 10);
- if (*ep != '\0') {
- fprintf(stderr, "invalid value given in FUSE_DEV_FD\n");
- return -1;
- }
+ if (*ep != '\0') {
+ fprintf(stderr, "invalid value given in FUSE_DEV_FD\n");
+ return -1;
+ }
- if (fd < 0)
- return -1;
+ if (fd < 0)
+ return -1;
- goto mount;
- }
+ goto mount;
+ }
- dev = getenv("FUSE_DEV_NAME");
+ dev = getenv("FUSE_DEV_NAME");
- if (! dev)
- dev = FUSE_DEV_TRUNK;
+ if (! dev)
+ dev = FUSE_DEV_TRUNK;
- if ((fd = open(dev, O_RDWR)) < 0) {
- perror("fuse: failed to open fuse device");
- return -1;
- }
+ 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) {
- if (! init_backgrounded()) {
- /*
- * If init is not backgrounded, we have to call the mount util
- * backgrounded, to avoid deadlock.
- */
-
- 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;
- execvp(mountprog, (char **) argv);
- perror("fuse: failed to exec mount program");
- exit(1);
- }
-
- exit(0);
- }
-
- waitpid(pid, NULL, 0);
+ if (getenv("FUSE_NO_MOUNT") || ! mountpoint)
+ goto out;
+
+ pid = fork();
+
+ if (pid == -1) {
+ perror("fuse: fork() failed");
+ close(fd);
+ return -1;
+ }
+
+ if (pid == 0) {
+ if (! init_backgrounded()) {
+ /*
+ * If init is not backgrounded, we have to
+ * call the mount util backgrounded, to avoid
+ * deadlock.
+ */
+
+ 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;
+ execvp(mountprog, (char **) argv);
+ perror("fuse: failed to exec mount program");
+ exit(1);
+ }
+
+ exit(0);
+ }
+
+ waitpid(pid, NULL, 0);
out:
- return fd;
+ return fd;
}
int fuse_kern_mount(const char *mountpoint, struct fuse_args *args)
{
- struct mount_opts mo;
- int res = -1;
-
- memset(&mo, 0, sizeof(mo));
- /* mount util should not try to spawn the daemon */
- setenv("MOUNT_FUSEFS_SAFE", "1", 1);
- /* to notify the mount util it's called from lib */
- setenv("MOUNT_FUSEFS_CALL_BY_LIB", "1", 1);
-
- if (args &&
- fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == -1)
- return -1;
-
- if (mo.allow_other && mo.allow_root) {
- fprintf(stderr, "fuse: 'allow_other' and 'allow_root' options are mutually exclusive\n");
- goto out;
- }
- if (mo.ishelp)
- return 0;
-
- res = fuse_mount_core(mountpoint, mo.kernel_opts);
- out:
- free(mo.kernel_opts);
- return res;
+ struct mount_opts mo;
+ int res = -1;
+
+ memset(&mo, 0, sizeof(mo));
+ /* mount util should not try to spawn the daemon */
+ setenv("MOUNT_FUSEFS_SAFE", "1", 1);
+ /* to notify the mount util it's called from lib */
+ setenv("MOUNT_FUSEFS_CALL_BY_LIB", "1", 1);
+
+ if (args &&
+ fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == -1)
+ return -1;
+
+ if (mo.allow_other && mo.allow_root) {
+ fprintf(stderr, "fuse: 'allow_other' and 'allow_root' options are mutually exclusive\n");
+ goto out;
+ }
+ if (mo.ishelp)
+ return 0;
+
+ res = fuse_mount_core(mountpoint, mo.kernel_opts);
+out:
+ free(mo.kernel_opts);
+ return res;
}
FUSE_SYMVER(".symver fuse_unmount_compat22,fuse_unmount@FUSE_2.2");
diff --git a/lib/mount_util.c b/lib/mount_util.c
index 9ce431a..39a1e6f 100644
--- a/lib/mount_util.c
+++ b/lib/mount_util.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB.
*/
#include "mount_util.h"
@@ -21,220 +21,223 @@
static int mtab_needs_update(const char *mnt)
{
- struct stat stbuf;
+ struct stat stbuf;
- /* If mtab is within new mount, don't touch it */
- if (strncmp(mnt, _PATH_MOUNTED, strlen(mnt)) == 0 &&
- _PATH_MOUNTED[strlen(mnt)] == '/')
- return 0;
+ /* If mtab is within new mount, don't touch it */
+ if (strncmp(mnt, _PATH_MOUNTED, strlen(mnt)) == 0 &&
+ _PATH_MOUNTED[strlen(mnt)] == '/')
+ return 0;
- if (lstat(_PATH_MOUNTED, &stbuf) != -1 && S_ISLNK(stbuf.st_mode))
- return 0;
+ if (lstat(_PATH_MOUNTED, &stbuf) != -1 && S_ISLNK(stbuf.st_mode))
+ return 0;
- return 1;
+ return 1;
}
int fuse_mnt_add_mount(const char *progname, const char *fsname,
- const char *mnt, const char *type, const char *opts)
+ const char *mnt, const char *type, const char *opts)
{
- int res;
- int status;
-
- if (!mtab_needs_update(mnt))
- return 0;
-
- res = fork();
- if (res == -1) {
- fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno));
- return -1;
- }
- if (res == 0) {
- char templ[] = "/tmp/fusermountXXXXXX";
- char *tmp;
-
- setuid(geteuid());
-
- /*
- * hide in a directory, where mount isn't able to resolve
- * fsname as a valid path
- */
- tmp = mkdtemp(templ);
- if (!tmp) {
- fprintf(stderr, "%s: failed to create temporary directory\n",
- progname);
- exit(1);
- }
- if (chdir(tmp)) {
- fprintf(stderr, "%s: failed to chdir to %s: %s\n",
- progname, tmp, strerror(errno));
- exit(1);
- }
- rmdir(tmp);
- execl("/bin/mount", "/bin/mount", "-i", "-f", "-t", type, "-o", opts,
- fsname, mnt, NULL);
- fprintf(stderr, "%s: failed to execute /bin/mount: %s\n", progname,
- strerror(errno));
- exit(1);
- }
- res = waitpid(res, &status, 0);
- if (res == -1) {
- fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno));
- return -1;
- }
- if (status != 0)
- return -1;
-
- return 0;
+ int res;
+ int status;
+
+ if (!mtab_needs_update(mnt))
+ return 0;
+
+ res = fork();
+ if (res == -1) {
+ fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno));
+ return -1;
+ }
+ if (res == 0) {
+ char templ[] = "/tmp/fusermountXXXXXX";
+ char *tmp;
+
+ setuid(geteuid());
+
+ /*
+ * hide in a directory, where mount isn't able to resolve
+ * fsname as a valid path
+ */
+ tmp = mkdtemp(templ);
+ if (!tmp) {
+ fprintf(stderr,
+ "%s: failed to create temporary directory\n",
+ progname);
+ exit(1);
+ }
+ if (chdir(tmp)) {
+ fprintf(stderr, "%s: failed to chdir to %s: %s\n",
+ progname, tmp, strerror(errno));
+ exit(1);
+ }
+ rmdir(tmp);
+ execl("/bin/mount", "/bin/mount", "-i", "-f", "-t", type,
+ "-o", opts, fsname, mnt, NULL);
+ fprintf(stderr, "%s: failed to execute /bin/mount: %s\n",
+ progname, strerror(errno));
+ exit(1);
+ }
+ res = waitpid(res, &status, 0);
+ if (res == -1) {
+ fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno));
+ return -1;
+ }
+ if (status != 0)
+ return -1;
+
+ return 0;
}
int fuse_mnt_umount(const char *progname, const char *mnt, int lazy)
{
- int res;
- int status;
-
- if (!mtab_needs_update(mnt)) {
- res = umount2(mnt, lazy ? 2 : 0);
- if (res == -1)
- fprintf(stderr, "%s: failed to unmount %s: %s\n", progname,
- mnt, strerror(errno));
- return res;
- }
-
- res = fork();
- if (res == -1) {
- fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno));
- return -1;
- }
- if (res == 0) {
- setuid(geteuid());
- execl("/bin/umount", "/bin/umount", "-i", mnt, lazy ? "-l" : NULL,
- NULL);
- fprintf(stderr, "%s: failed to execute /bin/umount: %s\n", progname,
- strerror(errno));
- exit(1);
- }
- res = waitpid(res, &status, 0);
- if (res == -1) {
- fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno));
- return -1;
- }
- if (status != 0)
- return -1;
-
- return 0;
+ int res;
+ int status;
+
+ if (!mtab_needs_update(mnt)) {
+ res = umount2(mnt, lazy ? 2 : 0);
+ if (res == -1)
+ fprintf(stderr, "%s: failed to unmount %s: %s\n",
+ progname, mnt, strerror(errno));
+ return res;
+ }
+
+ res = fork();
+ if (res == -1) {
+ fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno));
+ return -1;
+ }
+ if (res == 0) {
+ setuid(geteuid());
+ execl("/bin/umount", "/bin/umount", "-i", mnt,
+ lazy ? "-l" : NULL, NULL);
+ fprintf(stderr, "%s: failed to execute /bin/umount: %s\n",
+ progname, strerror(errno));
+ exit(1);
+ }
+ res = waitpid(res, &status, 0);
+ if (res == -1) {
+ fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno));
+ return -1;
+ }
+ if (status != 0)
+ return -1;
+
+ return 0;
}
char *fuse_mnt_resolve_path(const char *progname, const char *orig)
{
- char buf[PATH_MAX];
- char *copy;
- char *dst;
- char *end;
- char *lastcomp;
- const char *toresolv;
-
- if (!orig[0]) {
- fprintf(stderr, "%s: invalid mountpoint '%s'\n", progname, orig);
- return NULL;
- }
-
- copy = strdup(orig);
- if (copy == NULL) {
- fprintf(stderr, "%s: failed to allocate memory\n", progname);
- return NULL;
- }
-
- toresolv = copy;
- lastcomp = NULL;
- for (end = copy + strlen(copy) - 1; end > copy && *end == '/'; end --);
- if (end[0] != '/') {
- char *tmp;
- end[1] = '\0';
- tmp = strrchr(copy, '/');
- if (tmp == NULL) {
- lastcomp = copy;
- toresolv = ".";
- } else {
- lastcomp = tmp + 1;
- if (tmp == copy)
- toresolv = "/";
- }
- if (strcmp(lastcomp, ".") == 0 || strcmp(lastcomp, "..") == 0) {
- lastcomp = NULL;
- toresolv = copy;
- }
- else if (tmp)
- tmp[0] = '\0';
- }
- if (realpath(toresolv, buf) == NULL) {
- fprintf(stderr, "%s: bad mount point %s: %s\n", progname, orig,
- strerror(errno));
- free(copy);
- return NULL;
- }
- if (lastcomp == NULL)
- dst = strdup(buf);
- else {
- dst = (char *) malloc(strlen(buf) + 1 + strlen(lastcomp) + 1);
- if (dst) {
- unsigned buflen = strlen(buf);
- if (buflen && buf[buflen-1] == '/')
- sprintf(dst, "%s%s", buf, lastcomp);
- else
- sprintf(dst, "%s/%s", buf, lastcomp);
- }
- }
- free(copy);
- if (dst == NULL)
- fprintf(stderr, "%s: failed to allocate memory\n", progname);
- return dst;
+ char buf[PATH_MAX];
+ char *copy;
+ char *dst;
+ char *end;
+ char *lastcomp;
+ const char *toresolv;
+
+ if (!orig[0]) {
+ fprintf(stderr, "%s: invalid mountpoint '%s'\n", progname,
+ orig);
+ return NULL;
+ }
+
+ copy = strdup(orig);
+ if (copy == NULL) {
+ fprintf(stderr, "%s: failed to allocate memory\n", progname);
+ return NULL;
+ }
+
+ toresolv = copy;
+ lastcomp = NULL;
+ for (end = copy + strlen(copy) - 1; end > copy && *end == '/'; end --);
+ if (end[0] != '/') {
+ char *tmp;
+ end[1] = '\0';
+ tmp = strrchr(copy, '/');
+ if (tmp == NULL) {
+ lastcomp = copy;
+ toresolv = ".";
+ } else {
+ lastcomp = tmp + 1;
+ if (tmp == copy)
+ toresolv = "/";
+ }
+ if (strcmp(lastcomp, ".") == 0 || strcmp(lastcomp, "..") == 0) {
+ lastcomp = NULL;
+ toresolv = copy;
+ }
+ else if (tmp)
+ tmp[0] = '\0';
+ }
+ if (realpath(toresolv, buf) == NULL) {
+ fprintf(stderr, "%s: bad mount point %s: %s\n", progname, orig,
+ strerror(errno));
+ free(copy);
+ return NULL;
+ }
+ if (lastcomp == NULL)
+ dst = strdup(buf);
+ else {
+ dst = (char *) malloc(strlen(buf) + 1 + strlen(lastcomp) + 1);
+ if (dst) {
+ unsigned buflen = strlen(buf);
+ if (buflen && buf[buflen-1] == '/')
+ sprintf(dst, "%s%s", buf, lastcomp);
+ else
+ sprintf(dst, "%s/%s", buf, lastcomp);
+ }
+ }
+ free(copy);
+ if (dst == NULL)
+ fprintf(stderr, "%s: failed to allocate memory\n", progname);
+ return dst;
}
int fuse_mnt_check_empty(const char *progname, const char *mnt,
- mode_t rootmode, off_t rootsize)
+ mode_t rootmode, off_t rootsize)
{
- int isempty = 1;
-
- if (S_ISDIR(rootmode)) {
- struct dirent *ent;
- DIR *dp = opendir(mnt);
- if (dp == NULL) {
- fprintf(stderr, "%s: failed to open mountpoint for reading: %s\n",
- progname, strerror(errno));
- return -1;
- }
- while ((ent = readdir(dp)) != NULL) {
- if (strcmp(ent->d_name, ".") != 0 &&
- strcmp(ent->d_name, "..") != 0) {
- isempty = 0;
- break;
- }
- }
- closedir(dp);
- } else if (rootsize)
- isempty = 0;
-
- if (!isempty) {
- fprintf(stderr, "%s: mountpoint is not empty\n", progname);
- fprintf(stderr, "%s: if you are sure this is safe, use the 'nonempty' mount option\n", progname);
- return -1;
- }
- return 0;
+ int isempty = 1;
+
+ if (S_ISDIR(rootmode)) {
+ struct dirent *ent;
+ DIR *dp = opendir(mnt);
+ if (dp == NULL) {
+ fprintf(stderr,
+ "%s: failed to open mountpoint for reading: %s\n",
+ progname, strerror(errno));
+ return -1;
+ }
+ while ((ent = readdir(dp)) != NULL) {
+ if (strcmp(ent->d_name, ".") != 0 &&
+ strcmp(ent->d_name, "..") != 0) {
+ isempty = 0;
+ break;
+ }
+ }
+ closedir(dp);
+ } else if (rootsize)
+ isempty = 0;
+
+ if (!isempty) {
+ fprintf(stderr, "%s: mountpoint is not empty\n", progname);
+ fprintf(stderr, "%s: if you are sure this is safe, use the 'nonempty' mount option\n", progname);
+ return -1;
+ }
+ return 0;
}
int fuse_mnt_check_fuseblk(void)
{
- char buf[256];
- FILE *f = fopen("/proc/filesystems", "r");
- if (!f)
- return 1;
-
- while (fgets(buf, sizeof(buf), f))
- if (strstr(buf, "fuseblk\n")) {
- fclose(f);
- return 1;
- }
-
- fclose(f);
- return 0;
+ char buf[256];
+ FILE *f = fopen("/proc/filesystems", "r");
+ if (!f)
+ return 1;
+
+ while (fgets(buf, sizeof(buf), f))
+ if (strstr(buf, "fuseblk\n")) {
+ fclose(f);
+ return 1;
+ }
+
+ fclose(f);
+ return 0;
}
diff --git a/lib/mount_util.h b/lib/mount_util.h
index 29de2be..cf54d9d 100644
--- a/lib/mount_util.h
+++ b/lib/mount_util.h
@@ -1,17 +1,17 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB.
*/
#include <sys/types.h>
int fuse_mnt_add_mount(const char *progname, const char *fsname,
- const char *mnt, const char *type, const char *opts);
+ const char *mnt, const char *type, const char *opts);
int fuse_mnt_umount(const char *progname, const char *mnt, int lazy);
char *fuse_mnt_resolve_path(const char *progname, const char *orig);
int fuse_mnt_check_empty(const char *progname, const char *mnt,
- mode_t rootmode, off_t rootsize);
+ mode_t rootmode, off_t rootsize);
int fuse_mnt_check_fuseblk(void);
diff --git a/lib/ulockmgr.c b/lib/ulockmgr.c
index e38fdc5..6703cd0 100644
--- a/lib/ulockmgr.c
+++ b/lib/ulockmgr.c
@@ -1,9 +1,9 @@
/*
- libulockmgr: Userspace Lock Manager Library
- Copyright (C) 2006 Miklos Szeredi <miklos@szeredi.hu>
+ libulockmgr: Userspace Lock Manager Library
+ Copyright (C) 2006 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
/* #define DEBUG 1 */
@@ -22,28 +22,28 @@
#include <sys/wait.h>
struct message {
- unsigned intr : 1;
- unsigned nofd : 1;
- pthread_t thr;
- int cmd;
- int fd;
- struct flock lock;
- int error;
+ unsigned intr : 1;
+ unsigned nofd : 1;
+ pthread_t thr;
+ int cmd;
+ int fd;
+ struct flock lock;
+ int error;
};
struct fd_store {
- struct fd_store *next;
- int fd;
- int inuse;
+ struct fd_store *next;
+ int fd;
+ int inuse;
};
struct owner {
- struct owner *next;
- struct owner *prev;
- struct fd_store *fds;
- void *id;
- size_t id_len;
- int cfd;
+ struct owner *next;
+ struct owner *prev;
+ struct fd_store *fds;
+ void *id;
+ size_t id_len;
+ int cfd;
};
static pthread_mutex_t ulockmgr_lock;
@@ -54,19 +54,19 @@ static struct owner owner_list = { .next = &owner_list, .prev = &owner_list };
static void list_del_owner(struct owner *owner)
{
- struct owner *prev = owner->prev;
- struct owner *next = owner->next;
- prev->next = next;
- next->prev = prev;
+ struct owner *prev = owner->prev;
+ struct owner *next = owner->next;
+ prev->next = next;
+ next->prev = prev;
}
static void list_add_owner(struct owner *owner, struct owner *next)
{
- struct owner *prev = next->prev;
- owner->next = next;
- owner->prev = prev;
- prev->next = owner;
- next->prev = owner;
+ struct owner *prev = next->prev;
+ owner->next = next;
+ owner->prev = prev;
+ prev->next = owner;
+ next->prev = owner;
}
/*
@@ -74,365 +74,367 @@ static void list_add_owner(struct owner *owner, struct owner *next)
* on AF_UNIX, SOCK_STREAM sockets, that could cause it to return
* zero, even if data was available. Retrying the recv will return
* the data in this case.
-*/
+ */
static int do_recv(int sock, void *buf, size_t len, int flags)
{
- int res = recv(sock, buf, len, flags);
- if (res == 0)
- res = recv(sock, buf, len, flags);
+ int res = recv(sock, buf, len, flags);
+ if (res == 0)
+ res = recv(sock, buf, len, flags);
- return res;
+ return res;
}
static int ulockmgr_send_message(int sock, void *buf, size_t buflen,
- int *fdp, int numfds)
+ int *fdp, int numfds)
{
- struct msghdr msg;
- struct cmsghdr *p_cmsg;
- struct iovec vec;
- size_t cmsgbuf[CMSG_SPACE(sizeof(int) * MAX_SEND_FDS) / sizeof(size_t)];
- int res;
-
- assert(numfds <= MAX_SEND_FDS);
- msg.msg_control = cmsgbuf;
- msg.msg_controllen = sizeof(cmsgbuf);
- p_cmsg = CMSG_FIRSTHDR(&msg);
- p_cmsg->cmsg_level = SOL_SOCKET;
- p_cmsg->cmsg_type = SCM_RIGHTS;
- p_cmsg->cmsg_len = CMSG_LEN(sizeof(int) * numfds);
- memcpy(CMSG_DATA(p_cmsg), fdp, sizeof(int) * numfds);
- msg.msg_controllen = p_cmsg->cmsg_len;
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- msg.msg_iov = &vec;
- msg.msg_iovlen = 1;
- msg.msg_flags = 0;
- vec.iov_base = buf;
- vec.iov_len = buflen;
- res = sendmsg(sock, &msg, MSG_NOSIGNAL);
- if (res == -1) {
- perror("libulockmgr: sendmsg");
- return -1;
- }
- if ((size_t) res != buflen) {
- fprintf(stderr, "libulockmgr: sendmsg short\n");
- return -1;
- }
- return 0;
+ struct msghdr msg;
+ struct cmsghdr *p_cmsg;
+ struct iovec vec;
+ size_t cmsgbuf[CMSG_SPACE(sizeof(int) * MAX_SEND_FDS) / sizeof(size_t)];
+ int res;
+
+ assert(numfds <= MAX_SEND_FDS);
+ msg.msg_control = cmsgbuf;
+ msg.msg_controllen = sizeof(cmsgbuf);
+ p_cmsg = CMSG_FIRSTHDR(&msg);
+ p_cmsg->cmsg_level = SOL_SOCKET;
+ p_cmsg->cmsg_type = SCM_RIGHTS;
+ p_cmsg->cmsg_len = CMSG_LEN(sizeof(int) * numfds);
+ memcpy(CMSG_DATA(p_cmsg), fdp, sizeof(int) * numfds);
+ msg.msg_controllen = p_cmsg->cmsg_len;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &vec;
+ msg.msg_iovlen = 1;
+ msg.msg_flags = 0;
+ vec.iov_base = buf;
+ vec.iov_len = buflen;
+ res = sendmsg(sock, &msg, MSG_NOSIGNAL);
+ if (res == -1) {
+ perror("libulockmgr: sendmsg");
+ return -1;
+ }
+ if ((size_t) res != buflen) {
+ fprintf(stderr, "libulockmgr: sendmsg short\n");
+ return -1;
+ }
+ return 0;
}
static int ulockmgr_start_daemon(void)
{
- int sv[2];
- int res;
- char tmp[64];
-
- res = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
- if (res == -1) {
- perror("libulockmgr: socketpair");
- return -1;
- }
- snprintf(tmp, sizeof(tmp), "exec ulockmgr_server %i", sv[0]);
- res = system(tmp);
- close(sv[0]);
- if (res == -1 || !WIFEXITED(res) || WEXITSTATUS(res) != 0) {
- close(sv[1]);
- return -1;
- }
- ulockmgr_cfd = sv[1];
- return 0;
+ int sv[2];
+ int res;
+ char tmp[64];
+
+ res = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
+ if (res == -1) {
+ perror("libulockmgr: socketpair");
+ return -1;
+ }
+ snprintf(tmp, sizeof(tmp), "exec ulockmgr_server %i", sv[0]);
+ res = system(tmp);
+ close(sv[0]);
+ if (res == -1 || !WIFEXITED(res) || WEXITSTATUS(res) != 0) {
+ close(sv[1]);
+ return -1;
+ }
+ ulockmgr_cfd = sv[1];
+ return 0;
}
static struct owner *ulockmgr_new_owner(const void *id, size_t id_len)
{
- int sv[2];
- int res;
- char c = 'm';
- struct owner *o;
-
- if (ulockmgr_cfd == -1 && ulockmgr_start_daemon() == -1)
- return NULL;
-
- o = calloc(1, sizeof(struct owner) + id_len);
- if (!o) {
- fprintf(stderr, "libulockmgr: failed to allocate memory\n");
- return NULL;
- }
- o->id = o + 1;
- o->id_len = id_len;
- res = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
- if (res == -1) {
- perror("libulockmgr: socketpair");
- goto out_free;
- }
- res = ulockmgr_send_message(ulockmgr_cfd, &c, sizeof(c), &sv[0], 1);
- close(sv[0]);
- if (res == -1) {
- close(ulockmgr_cfd);
- ulockmgr_cfd = -1;
- goto out_close;
- }
-
- o->cfd = sv[1];
- memcpy(o->id, id, id_len);
- list_add_owner(o, &owner_list);
-
- return o;
-
- out_close:
- close(sv[1]);
- out_free:
- free(o);
- return NULL;
+ int sv[2];
+ int res;
+ char c = 'm';
+ struct owner *o;
+
+ if (ulockmgr_cfd == -1 && ulockmgr_start_daemon() == -1)
+ return NULL;
+
+ o = calloc(1, sizeof(struct owner) + id_len);
+ if (!o) {
+ fprintf(stderr, "libulockmgr: failed to allocate memory\n");
+ return NULL;
+ }
+ o->id = o + 1;
+ o->id_len = id_len;
+ res = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
+ if (res == -1) {
+ perror("libulockmgr: socketpair");
+ goto out_free;
+ }
+ res = ulockmgr_send_message(ulockmgr_cfd, &c, sizeof(c), &sv[0], 1);
+ close(sv[0]);
+ if (res == -1) {
+ close(ulockmgr_cfd);
+ ulockmgr_cfd = -1;
+ goto out_close;
+ }
+
+ o->cfd = sv[1];
+ memcpy(o->id, id, id_len);
+ list_add_owner(o, &owner_list);
+
+ return o;
+
+out_close:
+ close(sv[1]);
+out_free:
+ free(o);
+ return NULL;
}
static int ulockmgr_send_request(struct message *msg, const void *id,
- size_t id_len)
+ size_t id_len)
{
- int sv[2];
- int cfd;
- struct owner *o;
- struct fd_store *f = NULL;
- struct fd_store *newf = NULL;
- struct fd_store **fp;
- int fd = msg->fd;
- int cmd = msg->cmd;
- int res;
- int unlockall = (cmd == F_SETLK && msg->lock.l_type == F_UNLCK &&
- msg->lock.l_start == 0 && msg->lock.l_len == 0);
-
- for (o = owner_list.next; o != &owner_list; o = o->next)
- if (o->id_len == id_len && memcmp(o->id, id, id_len) == 0)
- break;
-
- if (o == &owner_list)
- o = NULL;
-
- if (!o && cmd != F_GETLK && msg->lock.l_type != F_UNLCK)
- o = ulockmgr_new_owner(id, id_len);
-
- if (!o) {
- if (cmd == F_GETLK) {
- res = fcntl(msg->fd, F_GETLK, &msg->lock);
- return (res == -1) ? -errno : 0;
- } else if (msg->lock.l_type == F_UNLCK)
- return 0;
- else
- return -ENOLCK;
- }
-
- if (unlockall)
- msg->nofd = 1;
- else {
- for (fp = &o->fds; *fp; fp = &(*fp)->next) {
- f = *fp;
- if (f->fd == fd) {
- msg->nofd = 1;
- break;
- }
- }
- }
-
- if (!msg->nofd) {
- newf = f = calloc(1, sizeof(struct fd_store));
- if (!f) {
- fprintf(stderr, "libulockmgr: failed to allocate memory\n");
- return -ENOLCK;
- }
- }
-
- res = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
- if (res == -1) {
- perror("libulockmgr: socketpair");
- free(newf);
- return -ENOLCK;
- }
-
- cfd = sv[1];
- sv[1] = msg->fd;
- res = ulockmgr_send_message(o->cfd, msg, sizeof(struct message), sv,
- msg->nofd ? 1 : 2);
- close(sv[0]);
- if (res == -1) {
- free(newf);
- close(cfd);
- return -EIO;
- }
-
- if (newf) {
- newf->fd = msg->fd;
- newf->next = o->fds;
- o->fds = newf;
- }
- if (f)
- f->inuse++;
-
- res = do_recv(cfd, msg, sizeof(struct message), MSG_WAITALL);
- if (res == -1) {
- perror("libulockmgr: recv");
- msg->error = EIO;
- } else if (res != sizeof(struct message)) {
- fprintf(stderr, "libulockmgr: recv short\n");
- msg->error = EIO;
- } else if (cmd == F_SETLKW && msg->error == EAGAIN) {
- pthread_mutex_unlock(&ulockmgr_lock);
- while (1) {
- sigset_t old;
- sigset_t unblock;
- int errno_save;
-
- sigemptyset(&unblock);
- sigaddset(&unblock, SIGUSR1);
- pthread_sigmask(SIG_UNBLOCK, &unblock, &old);
- res = do_recv(cfd, msg, sizeof(struct message), MSG_WAITALL);
- errno_save = errno;
- pthread_sigmask(SIG_SETMASK, &old, NULL);
- if (res == sizeof(struct message))
- break;
- else if (res >= 0) {
- fprintf(stderr, "libulockmgr: recv short\n");
- msg->error = EIO;
- break;
- } else if (errno_save != EINTR) {
- errno = errno_save;
- perror("libulockmgr: recv");
- msg->error = EIO;
- break;
- }
- msg->intr = 1;
- res = send(o->cfd, msg, sizeof(struct message), MSG_NOSIGNAL);
- if (res == -1) {
- perror("libulockmgr: send");
- msg->error = EIO;
- break;
- }
- if (res != sizeof(struct message)) {
- fprintf(stderr, "libulockmgr: send short\n");
- msg->error = EIO;
- break;
- }
- }
- pthread_mutex_lock(&ulockmgr_lock);
-
- }
- if (f)
- f->inuse--;
- close(cfd);
- if (unlockall) {
- for (fp = &o->fds; *fp;) {
- f = *fp;
- if (f->fd == fd && !f->inuse) {
- *fp = f->next;
- free(f);
- } else
- fp = &f->next;
- }
- if (!o->fds) {
- list_del_owner(o);
- close(o->cfd);
- free(o);
- }
- /* Force OK on unlock-all, since it _will_ succeed once the
- owner is deleted */
- msg->error = 0;
- }
-
- return -msg->error;
+ int sv[2];
+ int cfd;
+ struct owner *o;
+ struct fd_store *f = NULL;
+ struct fd_store *newf = NULL;
+ struct fd_store **fp;
+ int fd = msg->fd;
+ int cmd = msg->cmd;
+ int res;
+ int unlockall = (cmd == F_SETLK && msg->lock.l_type == F_UNLCK &&
+ msg->lock.l_start == 0 && msg->lock.l_len == 0);
+
+ for (o = owner_list.next; o != &owner_list; o = o->next)
+ if (o->id_len == id_len && memcmp(o->id, id, id_len) == 0)
+ break;
+
+ if (o == &owner_list)
+ o = NULL;
+
+ if (!o && cmd != F_GETLK && msg->lock.l_type != F_UNLCK)
+ o = ulockmgr_new_owner(id, id_len);
+
+ if (!o) {
+ if (cmd == F_GETLK) {
+ res = fcntl(msg->fd, F_GETLK, &msg->lock);
+ return (res == -1) ? -errno : 0;
+ } else if (msg->lock.l_type == F_UNLCK)
+ return 0;
+ else
+ return -ENOLCK;
+ }
+
+ if (unlockall)
+ msg->nofd = 1;
+ else {
+ for (fp = &o->fds; *fp; fp = &(*fp)->next) {
+ f = *fp;
+ if (f->fd == fd) {
+ msg->nofd = 1;
+ break;
+ }
+ }
+ }
+
+ if (!msg->nofd) {
+ newf = f = calloc(1, sizeof(struct fd_store));
+ if (!f) {
+ fprintf(stderr, "libulockmgr: failed to allocate memory\n");
+ return -ENOLCK;
+ }
+ }
+
+ res = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
+ if (res == -1) {
+ perror("libulockmgr: socketpair");
+ free(newf);
+ return -ENOLCK;
+ }
+
+ cfd = sv[1];
+ sv[1] = msg->fd;
+ res = ulockmgr_send_message(o->cfd, msg, sizeof(struct message), sv,
+ msg->nofd ? 1 : 2);
+ close(sv[0]);
+ if (res == -1) {
+ free(newf);
+ close(cfd);
+ return -EIO;
+ }
+
+ if (newf) {
+ newf->fd = msg->fd;
+ newf->next = o->fds;
+ o->fds = newf;
+ }
+ if (f)
+ f->inuse++;
+
+ res = do_recv(cfd, msg, sizeof(struct message), MSG_WAITALL);
+ if (res == -1) {
+ perror("libulockmgr: recv");
+ msg->error = EIO;
+ } else if (res != sizeof(struct message)) {
+ fprintf(stderr, "libulockmgr: recv short\n");
+ msg->error = EIO;
+ } else if (cmd == F_SETLKW && msg->error == EAGAIN) {
+ pthread_mutex_unlock(&ulockmgr_lock);
+ while (1) {
+ sigset_t old;
+ sigset_t unblock;
+ int errno_save;
+
+ sigemptyset(&unblock);
+ sigaddset(&unblock, SIGUSR1);
+ pthread_sigmask(SIG_UNBLOCK, &unblock, &old);
+ res = do_recv(cfd, msg, sizeof(struct message),
+ MSG_WAITALL);
+ errno_save = errno;
+ pthread_sigmask(SIG_SETMASK, &old, NULL);
+ if (res == sizeof(struct message))
+ break;
+ else if (res >= 0) {
+ fprintf(stderr, "libulockmgr: recv short\n");
+ msg->error = EIO;
+ break;
+ } else if (errno_save != EINTR) {
+ errno = errno_save;
+ perror("libulockmgr: recv");
+ msg->error = EIO;
+ break;
+ }
+ msg->intr = 1;
+ res = send(o->cfd, msg, sizeof(struct message),
+ MSG_NOSIGNAL);
+ if (res == -1) {
+ perror("libulockmgr: send");
+ msg->error = EIO;
+ break;
+ }
+ if (res != sizeof(struct message)) {
+ fprintf(stderr, "libulockmgr: send short\n");
+ msg->error = EIO;
+ break;
+ }
+ }
+ pthread_mutex_lock(&ulockmgr_lock);
+
+ }
+ if (f)
+ f->inuse--;
+ close(cfd);
+ if (unlockall) {
+ for (fp = &o->fds; *fp;) {
+ f = *fp;
+ if (f->fd == fd && !f->inuse) {
+ *fp = f->next;
+ free(f);
+ } else
+ fp = &f->next;
+ }
+ if (!o->fds) {
+ list_del_owner(o);
+ close(o->cfd);
+ free(o);
+ }
+ /* Force OK on unlock-all, since it _will_ succeed once the
+ owner is deleted */
+ msg->error = 0;
+ }
+
+ return -msg->error;
}
#ifdef DEBUG
static uint32_t owner_hash(const unsigned char *id, size_t id_len)
{
- uint32_t h = 0;
- size_t i;
- for (i = 0; i < id_len; i++)
- h = ((h << 8) | (h >> 24)) ^ id[i];
+ uint32_t h = 0;
+ size_t i;
+ for (i = 0; i < id_len; i++)
+ h = ((h << 8) | (h >> 24)) ^ id[i];
- return h;
+ return h;
}
#endif
static int ulockmgr_canonicalize(int fd, struct flock *lock)
{
- off_t offset;
- if (lock->l_whence == SEEK_CUR) {
- offset = lseek(fd, 0, SEEK_CUR);
- if (offset == (off_t) -1)
- return -errno;
- } else if (lock->l_whence == SEEK_END) {
- struct stat stbuf;
- int res = fstat(fd, &stbuf);
- if (res == -1)
- return -errno;
-
- offset = stbuf.st_size;
- } else
- offset = 0;
-
- lock->l_whence = SEEK_SET;
- lock->l_start += offset;
-
- if (lock->l_start < 0)
- return -EINVAL;
-
- if (lock->l_len < 0) {
- lock->l_start += lock->l_len;
- if (lock->l_start < 0)
- return -EINVAL;
- lock->l_len = -lock->l_len;
- }
- if (lock->l_len && lock->l_start + lock->l_len - 1 < 0)
- return -EINVAL;
-
- return 0;
+ off_t offset;
+ if (lock->l_whence == SEEK_CUR) {
+ offset = lseek(fd, 0, SEEK_CUR);
+ if (offset == (off_t) -1)
+ return -errno;
+ } else if (lock->l_whence == SEEK_END) {
+ struct stat stbuf;
+ int res = fstat(fd, &stbuf);
+ if (res == -1)
+ return -errno;
+
+ offset = stbuf.st_size;
+ } else
+ offset = 0;
+
+ lock->l_whence = SEEK_SET;
+ lock->l_start += offset;
+
+ if (lock->l_start < 0)
+ return -EINVAL;
+
+ if (lock->l_len < 0) {
+ lock->l_start += lock->l_len;
+ if (lock->l_start < 0)
+ return -EINVAL;
+ lock->l_len = -lock->l_len;
+ }
+ if (lock->l_len && lock->l_start + lock->l_len - 1 < 0)
+ return -EINVAL;
+
+ return 0;
}
int ulockmgr_op(int fd, int cmd, struct flock *lock, const void *owner,
- size_t owner_len)
+ size_t owner_len)
{
- int err;
- struct message msg;
- sigset_t old;
- sigset_t block;
+ int err;
+ struct message msg;
+ sigset_t old;
+ sigset_t block;
- if (cmd != F_GETLK && cmd != F_SETLK && cmd != F_SETLKW)
- return -EINVAL;
+ if (cmd != F_GETLK && cmd != F_SETLK && cmd != F_SETLKW)
+ return -EINVAL;
- if (lock->l_whence != SEEK_SET && lock->l_whence != SEEK_CUR &&
- lock->l_whence != SEEK_END)
- return -EINVAL;
+ if (lock->l_whence != SEEK_SET && lock->l_whence != SEEK_CUR &&
+ lock->l_whence != SEEK_END)
+ return -EINVAL;
#ifdef DEBUG
- fprintf(stderr, "libulockmgr: %i %i %i %lli %lli own: 0x%08x\n",
- cmd, lock->l_type, lock->l_whence, lock->l_start, lock->l_len,
- owner_hash(owner, owner_len));
+ fprintf(stderr, "libulockmgr: %i %i %i %lli %lli own: 0x%08x\n",
+ cmd, lock->l_type, lock->l_whence, lock->l_start, lock->l_len,
+ owner_hash(owner, owner_len));
#endif
- /* Unlock should never block anyway */
- if (cmd == F_SETLKW && lock->l_type == F_UNLCK)
- cmd = F_SETLK;
-
- memset(&msg, 0, sizeof(struct message));
- msg.cmd = cmd;
- msg.fd = fd;
- msg.lock = *lock;
- err = ulockmgr_canonicalize(fd, &msg.lock);
- if (err)
- return err;
-
- sigemptyset(&block);
- sigaddset(&block, SIGUSR1);
- pthread_sigmask(SIG_BLOCK, &block, &old);
- pthread_mutex_lock(&ulockmgr_lock);
- err = ulockmgr_send_request(&msg, owner, owner_len);
- pthread_mutex_unlock(&ulockmgr_lock);
- pthread_sigmask(SIG_SETMASK, &old, NULL);
- if (!err && cmd == F_GETLK) {
- if (msg.lock.l_type == F_UNLCK)
- lock->l_type = F_UNLCK;
- else
- *lock = msg.lock;
- }
-
- return err;
+ /* Unlock should never block anyway */
+ if (cmd == F_SETLKW && lock->l_type == F_UNLCK)
+ cmd = F_SETLK;
+
+ memset(&msg, 0, sizeof(struct message));
+ msg.cmd = cmd;
+ msg.fd = fd;
+ msg.lock = *lock;
+ err = ulockmgr_canonicalize(fd, &msg.lock);
+ if (err)
+ return err;
+
+ sigemptyset(&block);
+ sigaddset(&block, SIGUSR1);
+ pthread_sigmask(SIG_BLOCK, &block, &old);
+ pthread_mutex_lock(&ulockmgr_lock);
+ err = ulockmgr_send_request(&msg, owner, owner_len);
+ pthread_mutex_unlock(&ulockmgr_lock);
+ pthread_sigmask(SIG_SETMASK, &old, NULL);
+ if (!err && cmd == F_GETLK) {
+ if (msg.lock.l_type == F_UNLCK)
+ lock->l_type = F_UNLCK;
+ else
+ *lock = msg.lock;
+ }
+
+ return err;
}
diff --git a/test/stracedecode.c b/test/stracedecode.c
index 7908f43..27b883c 100644
--- a/test/stracedecode.c
+++ b/test/stracedecode.c
@@ -3,195 +3,195 @@
#include "fuse_kernel.h"
static struct {
- const char *name;
+ const char *name;
} fuse_ll_ops[] = {
- [FUSE_LOOKUP] = { "LOOKUP" },
- [FUSE_FORGET] = { "FORGET" },
- [FUSE_GETATTR] = { "GETATTR" },
- [FUSE_SETATTR] = { "SETATTR" },
- [FUSE_READLINK] = { "READLINK" },
- [FUSE_SYMLINK] = { "SYMLINK" },
- [FUSE_MKNOD] = { "MKNOD" },
- [FUSE_MKDIR] = { "MKDIR" },
- [FUSE_UNLINK] = { "UNLINK" },
- [FUSE_RMDIR] = { "RMDIR" },
- [FUSE_RENAME] = { "RENAME" },
- [FUSE_LINK] = { "LINK" },
- [FUSE_OPEN] = { "OPEN" },
- [FUSE_READ] = { "READ" },
- [FUSE_WRITE] = { "WRITE" },
- [FUSE_STATFS] = { "STATFS" },
- [FUSE_RELEASE] = { "RELEASE" },
- [FUSE_FSYNC] = { "FSYNC" },
- [FUSE_SETXATTR] = { "SETXATTR" },
- [FUSE_GETXATTR] = { "GETXATTR" },
- [FUSE_LISTXATTR] = { "LISTXATTR" },
- [FUSE_REMOVEXATTR] = { "REMOVEXATTR" },
- [FUSE_FLUSH] = { "FLUSH" },
- [FUSE_INIT] = { "INIT" },
- [FUSE_OPENDIR] = { "OPENDIR" },
- [FUSE_READDIR] = { "READDIR" },
- [FUSE_RELEASEDIR] = { "RELEASEDIR" },
- [FUSE_FSYNCDIR] = { "FSYNCDIR" },
- [FUSE_GETLK] = { "GETLK" },
- [FUSE_SETLK] = { "SETLK" },
- [FUSE_SETLKW] = { "SETLKW" },
- [FUSE_ACCESS] = { "ACCESS" },
- [FUSE_CREATE] = { "CREATE" },
- [FUSE_INTERRUPT] = { "INTERRUPT" },
- [FUSE_BMAP] = { "BMAP" },
- [FUSE_DESTROY] = { "DESTROY" },
+ [FUSE_LOOKUP] = { "LOOKUP" },
+ [FUSE_FORGET] = { "FORGET" },
+ [FUSE_GETATTR] = { "GETATTR" },
+ [FUSE_SETATTR] = { "SETATTR" },
+ [FUSE_READLINK] = { "READLINK" },
+ [FUSE_SYMLINK] = { "SYMLINK" },
+ [FUSE_MKNOD] = { "MKNOD" },
+ [FUSE_MKDIR] = { "MKDIR" },
+ [FUSE_UNLINK] = { "UNLINK" },
+ [FUSE_RMDIR] = { "RMDIR" },
+ [FUSE_RENAME] = { "RENAME" },
+ [FUSE_LINK] = { "LINK" },
+ [FUSE_OPEN] = { "OPEN" },
+ [FUSE_READ] = { "READ" },
+ [FUSE_WRITE] = { "WRITE" },
+ [FUSE_STATFS] = { "STATFS" },
+ [FUSE_RELEASE] = { "RELEASE" },
+ [FUSE_FSYNC] = { "FSYNC" },
+ [FUSE_SETXATTR] = { "SETXATTR" },
+ [FUSE_GETXATTR] = { "GETXATTR" },
+ [FUSE_LISTXATTR] = { "LISTXATTR" },
+ [FUSE_REMOVEXATTR] = { "REMOVEXATTR" },
+ [FUSE_FLUSH] = { "FLUSH" },
+ [FUSE_INIT] = { "INIT" },
+ [FUSE_OPENDIR] = { "OPENDIR" },
+ [FUSE_READDIR] = { "READDIR" },
+ [FUSE_RELEASEDIR] = { "RELEASEDIR" },
+ [FUSE_FSYNCDIR] = { "FSYNCDIR" },
+ [FUSE_GETLK] = { "GETLK" },
+ [FUSE_SETLK] = { "SETLK" },
+ [FUSE_SETLKW] = { "SETLKW" },
+ [FUSE_ACCESS] = { "ACCESS" },
+ [FUSE_CREATE] = { "CREATE" },
+ [FUSE_INTERRUPT] = { "INTERRUPT" },
+ [FUSE_BMAP] = { "BMAP" },
+ [FUSE_DESTROY] = { "DESTROY" },
};
#define FUSE_MAXOP (sizeof(fuse_ll_ops) / sizeof(fuse_ll_ops[0]))
static const char *opname(enum fuse_opcode opcode)
{
- if (opcode >= FUSE_MAXOP || !fuse_ll_ops[opcode].name)
- return "???";
- else
- return fuse_ll_ops[opcode].name;
+ if (opcode >= FUSE_MAXOP || !fuse_ll_ops[opcode].name)
+ return "???";
+ else
+ return fuse_ll_ops[opcode].name;
}
static void process_buf(int dir, char *buf, int len)
{
- static unsigned long long prevuniq = -1;
- static int prevopcode;
-
- if (!dir) {
- struct fuse_in_header *in = (struct fuse_in_header *) buf;
- buf += sizeof(struct fuse_in_header);
-
- printf("unique: %llu, opcode: %s (%i), nodeid: %lu, len: %i, insize: %i\n",
- (unsigned long long) in->unique,
- opname((enum fuse_opcode) in->opcode), in->opcode,
- (unsigned long) in->nodeid, in->len, len);
-
- switch (in->opcode) {
- case FUSE_READ: {
- struct fuse_read_in *arg = (struct fuse_read_in *) buf;
- printf("-READ fh:%llu off:%llu siz:%u rfl:%u own:%llu fl:%u\n",
- arg->fh, arg->offset, arg->size, arg->read_flags,
- arg->lock_owner, arg->flags);
- break;
- }
- case FUSE_WRITE: {
- struct fuse_write_in *arg = (struct fuse_write_in *) buf;
- printf("-WRITE fh:%llu off:%llu siz:%u wfl:%u own:%llu fl:%u\n",
- arg->fh, arg->offset, arg->size, arg->write_flags,
- arg->lock_owner, arg->flags);
- break;
- }
- }
- prevuniq = in->unique;
- prevopcode = in->opcode;
- } else {
- struct fuse_out_header *out = (struct fuse_out_header *) buf;
- buf += sizeof(struct fuse_out_header);
-
- printf(" unique: %llu, error: %i (%s), len: %i, outsize: %i\n",
- (unsigned long long) out->unique, out->error,
- strerror(-out->error), out->len, len);
-
- if (out->unique == prevuniq) {
- switch (prevopcode) {
- case FUSE_GETATTR: {
- struct fuse_attr_out *arg = (struct fuse_attr_out *) buf;
- printf("+ATTR v:%llu.%09u i:%llu s:%llu b:%llu\n",
- arg->attr_valid, arg->attr_valid_nsec,
- arg->attr.ino, arg->attr.size, arg->attr.blocks);
- break;
- }
- case FUSE_LOOKUP: {
- struct fuse_entry_out *arg = (struct fuse_entry_out *) buf;
- printf("+ENTRY nodeid:%llu v:%llu.%09u i:%llu s:%llu b:%llu\n",
- arg->nodeid, arg->attr_valid, arg->attr_valid_nsec,
- arg->attr.ino, arg->attr.size, arg->attr.blocks);
- break;
- }
- }
- }
- }
+ static unsigned long long prevuniq = -1;
+ static int prevopcode;
+
+ if (!dir) {
+ struct fuse_in_header *in = (struct fuse_in_header *) buf;
+ buf += sizeof(struct fuse_in_header);
+
+ printf("unique: %llu, opcode: %s (%i), nodeid: %lu, len: %i, insize: %i\n",
+ (unsigned long long) in->unique,
+ opname((enum fuse_opcode) in->opcode), in->opcode,
+ (unsigned long) in->nodeid, in->len, len);
+
+ switch (in->opcode) {
+ case FUSE_READ: {
+ struct fuse_read_in *arg = (struct fuse_read_in *) buf;
+ printf("-READ fh:%llu off:%llu siz:%u rfl:%u own:%llu fl:%u\n",
+ arg->fh, arg->offset, arg->size, arg->read_flags,
+ arg->lock_owner, arg->flags);
+ break;
+ }
+ case FUSE_WRITE: {
+ struct fuse_write_in *arg = (struct fuse_write_in *) buf;
+ printf("-WRITE fh:%llu off:%llu siz:%u wfl:%u own:%llu fl:%u\n",
+ arg->fh, arg->offset, arg->size, arg->write_flags,
+ arg->lock_owner, arg->flags);
+ break;
+ }
+ }
+ prevuniq = in->unique;
+ prevopcode = in->opcode;
+ } else {
+ struct fuse_out_header *out = (struct fuse_out_header *) buf;
+ buf += sizeof(struct fuse_out_header);
+
+ printf(" unique: %llu, error: %i (%s), len: %i, outsize: %i\n",
+ (unsigned long long) out->unique, out->error,
+ strerror(-out->error), out->len, len);
+
+ if (out->unique == prevuniq) {
+ switch (prevopcode) {
+ case FUSE_GETATTR: {
+ struct fuse_attr_out *arg = (struct fuse_attr_out *) buf;
+ printf("+ATTR v:%llu.%09u i:%llu s:%llu b:%llu\n",
+ arg->attr_valid, arg->attr_valid_nsec,
+ arg->attr.ino, arg->attr.size, arg->attr.blocks);
+ break;
+ }
+ case FUSE_LOOKUP: {
+ struct fuse_entry_out *arg = (struct fuse_entry_out *) buf;
+ printf("+ENTRY nodeid:%llu v:%llu.%09u i:%llu s:%llu b:%llu\n",
+ arg->nodeid, arg->attr_valid, arg->attr_valid_nsec,
+ arg->attr.ino, arg->attr.size, arg->attr.blocks);
+ break;
+ }
+ }
+ }
+ }
}
int main(void)
{
- FILE *in = stdin;
- while (1) {
- int dir;
- int res;
- char buf[1048576];
- unsigned len = 0;
-
- memset(buf, 0, sizeof(buf));
- while (1) {
- char str[32];
-
- res = fscanf(in, "%30s", str);
- if (res != 1 && feof(in))
- return 0;
-
- if (res == 0)
- continue;
-
- if (strncmp(str, "read(", 5) == 0) {
- dir = 0;
- break;
- } else if (strncmp(str, "writev(", 7) == 0) {
- dir = 1;
- break;
- }
- }
-
- while (1) {
- int c = getc(in);
- if (c == '"') {
- while (1) {
- int val;
-
- c = getc(in);
- if (c == EOF) {
- fprintf(stderr, "eof in string\n");
- break;
- }
- if (c == '\n') {
- fprintf(stderr, "eol in string\n");
- break;
- }
- if (c == '"')
- break;
- if (c != '\\') {
- val = c;
- } else {
- c = getc(in);
- switch (c) {
- case 'n': val = '\n'; break;
- case 'r': val = '\r'; break;
- case 't': val = '\t'; break;
- case '"': val = '"'; break;
- case '\\': val = '\\'; break;
- case 'x':
- res = scanf("%x", &val);
- if (res != 1) {
- fprintf(stderr, "parse error\n");
- continue;
- }
- break;
- default:
- fprintf(stderr, "unknown sequence: '\\%c'\n", c);
- continue;
- }
- }
- buf[len++] = val;
- }
- }
- if (c == '\n')
- break;
- }
- process_buf(dir, buf, len);
- memset(buf, 0, len);
- len = 0;
- }
+ FILE *in = stdin;
+ while (1) {
+ int dir;
+ int res;
+ char buf[1048576];
+ unsigned len = 0;
+
+ memset(buf, 0, sizeof(buf));
+ while (1) {
+ char str[32];
+
+ res = fscanf(in, "%30s", str);
+ if (res != 1 && feof(in))
+ return 0;
+
+ if (res == 0)
+ continue;
+
+ if (strncmp(str, "read(", 5) == 0) {
+ dir = 0;
+ break;
+ } else if (strncmp(str, "writev(", 7) == 0) {
+ dir = 1;
+ break;
+ }
+ }
+
+ while (1) {
+ int c = getc(in);
+ if (c == '"') {
+ while (1) {
+ int val;
+
+ c = getc(in);
+ if (c == EOF) {
+ fprintf(stderr, "eof in string\n");
+ break;
+ }
+ if (c == '\n') {
+ fprintf(stderr, "eol in string\n");
+ break;
+ }
+ if (c == '"')
+ break;
+ if (c != '\\') {
+ val = c;
+ } else {
+ c = getc(in);
+ switch (c) {
+ case 'n': val = '\n'; break;
+ case 'r': val = '\r'; break;
+ case 't': val = '\t'; break;
+ case '"': val = '"'; break;
+ case '\\': val = '\\'; break;
+ case 'x':
+ res = scanf("%x", &val);
+ if (res != 1) {
+ fprintf(stderr, "parse error\n");
+ continue;
+ }
+ break;
+ default:
+ fprintf(stderr, "unknown sequence: '\\%c'\n", c);
+ continue;
+ }
+ }
+ buf[len++] = val;
+ }
+ }
+ if (c == '\n')
+ break;
+ }
+ process_buf(dir, buf, len);
+ memset(buf, 0, len);
+ len = 0;
+ }
}
diff --git a/test/test.c b/test/test.c
index f9aa823..a2ce3cd 100644
--- a/test/test.c
+++ b/test/test.c
@@ -27,37 +27,37 @@ static int testdata2len = sizeof(testdata2) - 1;
static void test_perror(const char *func, const char *msg)
{
- fprintf(stderr, "[%s] %s() - %s: %s\n", testname, func, msg,
- strerror(errno));
+ fprintf(stderr, "[%s] %s() - %s: %s\n", testname, func, msg,
+ strerror(errno));
}
static void test_error(const char *func, const char *msg, ...)
- __attribute__ ((format (printf, 2, 3)));
+ __attribute__ ((format (printf, 2, 3)));
static void start_test(const char *fmt, ...)
- __attribute__ ((format (printf, 1, 2)));
+ __attribute__ ((format (printf, 1, 2)));
static void test_error(const char *func, const char *msg, ...)
{
- va_list ap;
- fprintf(stderr, "[%s] %s() - ", testname, func);
- va_start(ap, msg);
- vfprintf(stderr, msg, ap);
- va_end(ap);
- fprintf(stderr, "\n");
+ va_list ap;
+ fprintf(stderr, "[%s] %s() - ", testname, func);
+ va_start(ap, msg);
+ vfprintf(stderr, msg, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
}
static void success(void)
{
- fprintf(stderr, "[%s] OK\n", testname);
+ fprintf(stderr, "[%s] OK\n", testname);
}
static void start_test(const char *fmt, ...)
{
- va_list ap;
- va_start(ap, fmt);
- vsprintf(testname, fmt, ap);
- va_end(ap);
+ va_list ap;
+ va_start(ap, fmt);
+ vsprintf(testname, fmt, ap);
+ va_end(ap);
}
#define PERROR(msg) test_perror(__FUNCTION__, msg)
@@ -65,1271 +65,1287 @@ static void start_test(const char *fmt, ...)
static int check_size(const char *path, int len)
{
- struct stat stbuf;
- int res = stat(path, &stbuf);
- if (res == -1) {
- PERROR("stat");
- return -1;
- }
- if (stbuf.st_size != len) {
- ERROR("length %u instead of %u", (int) stbuf.st_size, (int) len);
- return -1;
- }
- return 0;
+ struct stat stbuf;
+ int res = stat(path, &stbuf);
+ if (res == -1) {
+ PERROR("stat");
+ return -1;
+ }
+ if (stbuf.st_size != len) {
+ ERROR("length %u instead of %u", (int) stbuf.st_size,
+ (int) len);
+ return -1;
+ }
+ return 0;
}
static int fcheck_size(int fd, int len)
{
- struct stat stbuf;
- int res = fstat(fd, &stbuf);
- if (res == -1) {
- PERROR("fstat");
- return -1;
- }
- if (stbuf.st_size != len) {
- ERROR("length %u instead of %u", (int) stbuf.st_size, (int) len);
- return -1;
- }
- return 0;
+ struct stat stbuf;
+ int res = fstat(fd, &stbuf);
+ if (res == -1) {
+ PERROR("fstat");
+ return -1;
+ }
+ if (stbuf.st_size != len) {
+ ERROR("length %u instead of %u", (int) stbuf.st_size,
+ (int) len);
+ return -1;
+ }
+ return 0;
}
static int check_type(const char *path, mode_t type)
{
- struct stat stbuf;
- int res = lstat(path, &stbuf);
- if (res == -1) {
- PERROR("lstat");
- return -1;
- }
- if ((stbuf.st_mode & S_IFMT) != type) {
- ERROR("type 0%o instead of 0%o", stbuf.st_mode & S_IFMT, type);
- return -1;
- }
- return 0;
+ struct stat stbuf;
+ int res = lstat(path, &stbuf);
+ if (res == -1) {
+ PERROR("lstat");
+ return -1;
+ }
+ if ((stbuf.st_mode & S_IFMT) != type) {
+ ERROR("type 0%o instead of 0%o", stbuf.st_mode & S_IFMT, type);
+ return -1;
+ }
+ return 0;
}
static int fcheck_type(int fd, mode_t type)
{
- struct stat stbuf;
- int res = fstat(fd, &stbuf);
- if (res == -1) {
- PERROR("fstat");
- return -1;
- }
- if ((stbuf.st_mode & S_IFMT) != type) {
- ERROR("type 0%o instead of 0%o", stbuf.st_mode & S_IFMT, type);
- return -1;
- }
- return 0;
+ struct stat stbuf;
+ int res = fstat(fd, &stbuf);
+ if (res == -1) {
+ PERROR("fstat");
+ return -1;
+ }
+ if ((stbuf.st_mode & S_IFMT) != type) {
+ ERROR("type 0%o instead of 0%o", stbuf.st_mode & S_IFMT, type);
+ return -1;
+ }
+ return 0;
}
static int check_mode(const char *path, mode_t mode)
{
- struct stat stbuf;
- int res = lstat(path, &stbuf);
- if (res == -1) {
- PERROR("lstat");
- return -1;
- }
- if ((stbuf.st_mode & 07777) != mode) {
- ERROR("mode 0%o instead of 0%o", stbuf.st_mode & 07777, mode);
- return -1;
- }
- return 0;
+ struct stat stbuf;
+ int res = lstat(path, &stbuf);
+ if (res == -1) {
+ PERROR("lstat");
+ return -1;
+ }
+ if ((stbuf.st_mode & 07777) != mode) {
+ ERROR("mode 0%o instead of 0%o", stbuf.st_mode & 07777, mode);
+ return -1;
+ }
+ return 0;
}
static int fcheck_mode(int fd, mode_t mode)
{
- struct stat stbuf;
- int res = fstat(fd, &stbuf);
- if (res == -1) {
- PERROR("fstat");
- return -1;
- }
- if ((stbuf.st_mode & 07777) != mode) {
- ERROR("mode 0%o instead of 0%o", stbuf.st_mode & 07777, mode);
- return -1;
- }
- return 0;
+ struct stat stbuf;
+ int res = fstat(fd, &stbuf);
+ if (res == -1) {
+ PERROR("fstat");
+ return -1;
+ }
+ if ((stbuf.st_mode & 07777) != mode) {
+ ERROR("mode 0%o instead of 0%o", stbuf.st_mode & 07777, mode);
+ return -1;
+ }
+ return 0;
}
static int check_times(const char *path, time_t atime, time_t mtime)
{
- int err = 0;
- struct stat stbuf;
- int res = lstat(path, &stbuf);
- if (res == -1) {
- PERROR("lstat");
- return -1;
- }
- if (stbuf.st_atime != atime) {
- ERROR("atime %li instead of %li", stbuf.st_atime, atime);
- err--;
- }
- if (stbuf.st_mtime != mtime) {
- ERROR("mtime %li instead of %li", stbuf.st_mtime, mtime);
- err--;
- }
- if (err)
- return -1;
-
- return 0;
+ int err = 0;
+ struct stat stbuf;
+ int res = lstat(path, &stbuf);
+ if (res == -1) {
+ PERROR("lstat");
+ return -1;
+ }
+ if (stbuf.st_atime != atime) {
+ ERROR("atime %li instead of %li", stbuf.st_atime, atime);
+ err--;
+ }
+ if (stbuf.st_mtime != mtime) {
+ ERROR("mtime %li instead of %li", stbuf.st_mtime, mtime);
+ err--;
+ }
+ if (err)
+ return -1;
+
+ return 0;
}
static int fcheck_times(int fd, time_t atime, time_t mtime)
{
- int err = 0;
- struct stat stbuf;
- int res = fstat(fd, &stbuf);
- if (res == -1) {
- PERROR("fstat");
- return -1;
- }
- if (stbuf.st_atime != atime) {
- ERROR("atime %li instead of %li", stbuf.st_atime, atime);
- err--;
- }
- if (stbuf.st_mtime != mtime) {
- ERROR("mtime %li instead of %li", stbuf.st_mtime, mtime);
- err--;
- }
- if (err)
- return -1;
-
- return 0;
+ int err = 0;
+ struct stat stbuf;
+ int res = fstat(fd, &stbuf);
+ if (res == -1) {
+ PERROR("fstat");
+ return -1;
+ }
+ if (stbuf.st_atime != atime) {
+ ERROR("atime %li instead of %li", stbuf.st_atime, atime);
+ err--;
+ }
+ if (stbuf.st_mtime != mtime) {
+ ERROR("mtime %li instead of %li", stbuf.st_mtime, mtime);
+ err--;
+ }
+ if (err)
+ return -1;
+
+ return 0;
}
static int check_nlink(const char *path, nlink_t nlink)
{
- struct stat stbuf;
- int res = lstat(path, &stbuf);
- if (res == -1) {
- PERROR("lstat");
- return -1;
- }
- if (stbuf.st_nlink != nlink) {
- ERROR("nlink %li instead of %li", (long) stbuf.st_nlink, (long) nlink);
- return -1;
- }
- return 0;
+ struct stat stbuf;
+ int res = lstat(path, &stbuf);
+ if (res == -1) {
+ PERROR("lstat");
+ return -1;
+ }
+ if (stbuf.st_nlink != nlink) {
+ ERROR("nlink %li instead of %li", (long) stbuf.st_nlink,
+ (long) nlink);
+ return -1;
+ }
+ return 0;
}
static int fcheck_nlink(int fd, nlink_t nlink)
{
- struct stat stbuf;
- int res = fstat(fd, &stbuf);
- if (res == -1) {
- PERROR("fstat");
- return -1;
- }
- if (stbuf.st_nlink != nlink) {
- ERROR("nlink %li instead of %li", (long) stbuf.st_nlink, (long) nlink);
- return -1;
- }
- return 0;
+ struct stat stbuf;
+ int res = fstat(fd, &stbuf);
+ if (res == -1) {
+ PERROR("fstat");
+ return -1;
+ }
+ if (stbuf.st_nlink != nlink) {
+ ERROR("nlink %li instead of %li", (long) stbuf.st_nlink,
+ (long) nlink);
+ return -1;
+ }
+ return 0;
}
static int check_nonexist(const char *path)
{
- struct stat stbuf;
- int res = lstat(path, &stbuf);
- if (res == 0) {
- ERROR("file should not exist");
- return -1;
- }
- if (errno != ENOENT) {
- ERROR("file should not exist: %s", strerror(errno));
- return -1;
- }
- return 0;
+ struct stat stbuf;
+ int res = lstat(path, &stbuf);
+ if (res == 0) {
+ ERROR("file should not exist");
+ return -1;
+ }
+ if (errno != ENOENT) {
+ ERROR("file should not exist: %s", strerror(errno));
+ return -1;
+ }
+ return 0;
}
static int check_buffer(const char *buf, const char *data, unsigned len)
{
- if (memcmp(buf, data, len) != 0) {
- ERROR("data mismatch");
- return -1;
- }
- return 0;
+ if (memcmp(buf, data, len) != 0) {
+ ERROR("data mismatch");
+ return -1;
+ }
+ return 0;
}
static int check_data(const char *path, const char *data, int offset,
- unsigned len)
+ unsigned len)
{
- char buf[4096];
- int res;
- int fd = open(path, O_RDONLY);
- if (fd == -1) {
- PERROR("open");
- return -1;
- }
- if (lseek(fd, offset, SEEK_SET) == (off_t) -1) {
- PERROR("lseek");
- close(fd);
- return -1;
- }
- while (len) {
- int rdlen = len < sizeof(buf) ? len : sizeof(buf);
- res = read(fd, buf, rdlen);
- if (res == -1) {
- PERROR("read");
- close(fd);
- return -1;
- }
- if (res != rdlen) {
- ERROR("short read: %u instead of %u", res, rdlen);
- close(fd);
- return -1;
- }
- if (check_buffer(buf, data, rdlen) != 0) {
- close(fd);
- return -1;
- }
- data += rdlen;
- len -= rdlen;
- }
- res = close(fd);
- if (res == -1) {
- PERROR("close");
- return -1;
- }
- return 0;
+ char buf[4096];
+ int res;
+ int fd = open(path, O_RDONLY);
+ if (fd == -1) {
+ PERROR("open");
+ return -1;
+ }
+ if (lseek(fd, offset, SEEK_SET) == (off_t) -1) {
+ PERROR("lseek");
+ close(fd);
+ return -1;
+ }
+ while (len) {
+ int rdlen = len < sizeof(buf) ? len : sizeof(buf);
+ res = read(fd, buf, rdlen);
+ if (res == -1) {
+ PERROR("read");
+ close(fd);
+ return -1;
+ }
+ if (res != rdlen) {
+ ERROR("short read: %u instead of %u", res, rdlen);
+ close(fd);
+ return -1;
+ }
+ if (check_buffer(buf, data, rdlen) != 0) {
+ close(fd);
+ return -1;
+ }
+ data += rdlen;
+ len -= rdlen;
+ }
+ res = close(fd);
+ if (res == -1) {
+ PERROR("close");
+ return -1;
+ }
+ return 0;
}
static int fcheck_data(int fd, const char *data, int offset,
- unsigned len)
+ unsigned len)
{
- char buf[4096];
- int res;
- if (lseek(fd, offset, SEEK_SET) == (off_t) -1) {
- PERROR("lseek");
- return -1;
- }
- while (len) {
- int rdlen = len < sizeof(buf) ? len : sizeof(buf);
- res = read(fd, buf, rdlen);
- if (res == -1) {
- PERROR("read");
- return -1;
- }
- if (res != rdlen) {
- ERROR("short read: %u instead of %u", res, rdlen);
- return -1;
- }
- if (check_buffer(buf, data, rdlen) != 0) {
- return -1;
- }
- data += rdlen;
- len -= rdlen;
- }
- return 0;
+ char buf[4096];
+ int res;
+ if (lseek(fd, offset, SEEK_SET) == (off_t) -1) {
+ PERROR("lseek");
+ return -1;
+ }
+ while (len) {
+ int rdlen = len < sizeof(buf) ? len : sizeof(buf);
+ res = read(fd, buf, rdlen);
+ if (res == -1) {
+ PERROR("read");
+ return -1;
+ }
+ if (res != rdlen) {
+ ERROR("short read: %u instead of %u", res, rdlen);
+ return -1;
+ }
+ if (check_buffer(buf, data, rdlen) != 0) {
+ return -1;
+ }
+ data += rdlen;
+ len -= rdlen;
+ }
+ return 0;
}
static int check_dir_contents(const char *path, const char **contents)
{
- int i;
- int res;
- int err = 0;
- int found[MAX_ENTRIES];
- const char *cont[MAX_ENTRIES];
- DIR *dp;
-
- for (i = 0; contents[i]; i++) {
- assert(i < MAX_ENTRIES - 3);
- found[i] = 0;
- cont[i] = contents[i];
- }
- found[i] = 0;
- cont[i++] = ".";
- found[i] = 0;
- cont[i++] = "..";
- cont[i] = NULL;
-
- dp = opendir(path);
- if (dp == NULL) {
- PERROR("opendir");
- return -1;
- }
- memset(found, 0, sizeof(found));
- while(1) {
- struct dirent *de;
- errno = 0;
- de = readdir(dp);
- if (de == NULL) {
- if (errno) {
- PERROR("readdir");
- closedir(dp);
- return -1;
- }
- break;
- }
- for (i = 0; cont[i] != NULL; i++) {
- assert(i < MAX_ENTRIES);
- if (strcmp(cont[i], de->d_name) == 0) {
- if (found[i]) {
- ERROR("duplicate entry <%s>", de->d_name);
- err--;
- } else
- found[i] = 1;
- break;
- }
- }
- if (!cont[i]) {
- ERROR("unexpected entry <%s>", de->d_name);
- err --;
- }
- }
- for (i = 0; cont[i] != NULL; i++) {
- if (!found[i]) {
- ERROR("missing entry <%s>", cont[i]);
- err--;
- }
- }
- res = closedir(dp);
- if (res == -1) {
- PERROR("closedir");
- return -1;
- }
- if (err)
- return -1;
-
- return 0;
+ int i;
+ int res;
+ int err = 0;
+ int found[MAX_ENTRIES];
+ const char *cont[MAX_ENTRIES];
+ DIR *dp;
+
+ for (i = 0; contents[i]; i++) {
+ assert(i < MAX_ENTRIES - 3);
+ found[i] = 0;
+ cont[i] = contents[i];
+ }
+ found[i] = 0;
+ cont[i++] = ".";
+ found[i] = 0;
+ cont[i++] = "..";
+ cont[i] = NULL;
+
+ dp = opendir(path);
+ if (dp == NULL) {
+ PERROR("opendir");
+ return -1;
+ }
+ memset(found, 0, sizeof(found));
+ while(1) {
+ struct dirent *de;
+ errno = 0;
+ de = readdir(dp);
+ if (de == NULL) {
+ if (errno) {
+ PERROR("readdir");
+ closedir(dp);
+ return -1;
+ }
+ break;
+ }
+ for (i = 0; cont[i] != NULL; i++) {
+ assert(i < MAX_ENTRIES);
+ if (strcmp(cont[i], de->d_name) == 0) {
+ if (found[i]) {
+ ERROR("duplicate entry <%s>",
+ de->d_name);
+ err--;
+ } else
+ found[i] = 1;
+ break;
+ }
+ }
+ if (!cont[i]) {
+ ERROR("unexpected entry <%s>", de->d_name);
+ err --;
+ }
+ }
+ for (i = 0; cont[i] != NULL; i++) {
+ if (!found[i]) {
+ ERROR("missing entry <%s>", cont[i]);
+ err--;
+ }
+ }
+ res = closedir(dp);
+ if (res == -1) {
+ PERROR("closedir");
+ return -1;
+ }
+ if (err)
+ return -1;
+
+ return 0;
}
static int create_file(const char *path, const char *data, int len)
{
- int res;
- int fd;
-
- unlink(path);
- fd = creat(path, 0644);
- if (fd == -1) {
- PERROR("creat");
- return -1;
- }
- if (len) {
- res = write(fd, data, len);
- if (res == -1) {
- PERROR("write");
- close(fd);
- return -1;
- }
- if (res != len) {
- ERROR("write is short: %u instead of %u", res, len);
- close(fd);
- return -1;
- }
- }
- res = close(fd);
- if (res == -1) {
- PERROR("close");
- return -1;
- }
- res = check_type(path, S_IFREG);
- if (res == -1)
- return -1;
- res = check_mode(path, 0644);
- if (res == -1)
- return -1;
- res = check_nlink(path, 1);
- if (res == -1)
- return -1;
- res = check_size(path, len);
- if (res == -1)
- return -1;
-
- if (len) {
- res = check_data(path, data, 0, len);
- if (res == -1)
- return -1;
- }
-
- return 0;
+ int res;
+ int fd;
+
+ unlink(path);
+ fd = creat(path, 0644);
+ if (fd == -1) {
+ PERROR("creat");
+ return -1;
+ }
+ if (len) {
+ res = write(fd, data, len);
+ if (res == -1) {
+ PERROR("write");
+ close(fd);
+ return -1;
+ }
+ if (res != len) {
+ ERROR("write is short: %u instead of %u", res, len);
+ close(fd);
+ return -1;
+ }
+ }
+ res = close(fd);
+ if (res == -1) {
+ PERROR("close");
+ return -1;
+ }
+ res = check_type(path, S_IFREG);
+ if (res == -1)
+ return -1;
+ res = check_mode(path, 0644);
+ if (res == -1)
+ return -1;
+ res = check_nlink(path, 1);
+ if (res == -1)
+ return -1;
+ res = check_size(path, len);
+ if (res == -1)
+ return -1;
+
+ if (len) {
+ res = check_data(path, data, 0, len);
+ if (res == -1)
+ return -1;
+ }
+
+ return 0;
}
static int cleanup_dir(const char *path, const char **dir_files, int quiet)
{
- int i;
- int err = 0;
-
- for (i = 0; dir_files[i]; i++) {
- int res;
- char fpath[1024];
- sprintf(fpath, "%s/%s", path, dir_files[i]);
- res = unlink(fpath);
- if (res == -1 && !quiet) {
- PERROR("unlink");
- err --;
- }
- }
- if (err)
- return -1;
-
- return 0;
+ int i;
+ int err = 0;
+
+ for (i = 0; dir_files[i]; i++) {
+ int res;
+ char fpath[1024];
+ sprintf(fpath, "%s/%s", path, dir_files[i]);
+ res = unlink(fpath);
+ if (res == -1 && !quiet) {
+ PERROR("unlink");
+ err --;
+ }
+ }
+ if (err)
+ return -1;
+
+ return 0;
}
static int create_dir(const char *path, const char **dir_files)
{
- int res;
- int i;
-
- rmdir(path);
- res = mkdir(path, 0755);
- if (res == -1) {
- PERROR("mkdir");
- return -1;
- }
- res = check_type(path, S_IFDIR);
- if (res == -1)
- return -1;
- res = check_mode(path, 0755);
- if (res == -1)
- return -1;
-
- for (i = 0; dir_files[i]; i++) {
- char fpath[1024];
- sprintf(fpath, "%s/%s", path, dir_files[i]);
- res = create_file(fpath, "", 0);
- if (res == -1) {
- cleanup_dir(path, dir_files, 1);
- return -1;
- }
- }
- res = check_dir_contents(path, dir_files);
- if (res == -1) {
- cleanup_dir(path, dir_files, 1);
- return -1;
- }
-
- return 0;
+ int res;
+ int i;
+
+ rmdir(path);
+ res = mkdir(path, 0755);
+ if (res == -1) {
+ PERROR("mkdir");
+ return -1;
+ }
+ res = check_type(path, S_IFDIR);
+ if (res == -1)
+ return -1;
+ res = check_mode(path, 0755);
+ if (res == -1)
+ return -1;
+
+ for (i = 0; dir_files[i]; i++) {
+ char fpath[1024];
+ sprintf(fpath, "%s/%s", path, dir_files[i]);
+ res = create_file(fpath, "", 0);
+ if (res == -1) {
+ cleanup_dir(path, dir_files, 1);
+ return -1;
+ }
+ }
+ res = check_dir_contents(path, dir_files);
+ if (res == -1) {
+ cleanup_dir(path, dir_files, 1);
+ return -1;
+ }
+
+ return 0;
}
static int test_truncate(int len)
{
- const char *data = testdata;
- int datalen = testdatalen;
- int res;
-
- start_test("truncate(%u)", (int) len);
- res = create_file(testfile, data, datalen);
- if (res == -1)
- return -1;
-
- res = truncate(testfile, len);
- if (res == -1) {
- PERROR("truncate");
- return -1;
- }
- res = check_size(testfile, len);
- if (res == -1)
- return -1;
-
- if (len > 0) {
- if (len <= datalen) {
- res = check_data(testfile, data, 0, len);
- if (res == -1)
- return -1;
- } else {
- res = check_data(testfile, data, 0, datalen);
- if (res == -1)
- return -1;
- res = check_data(testfile, zerodata, datalen, len - datalen);
- if (res == -1)
- return -1;
- }
- }
- res = unlink(testfile);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile);
- if (res == -1)
- return -1;
-
- success();
- return 0;
+ const char *data = testdata;
+ int datalen = testdatalen;
+ int res;
+
+ start_test("truncate(%u)", (int) len);
+ res = create_file(testfile, data, datalen);
+ if (res == -1)
+ return -1;
+
+ res = truncate(testfile, len);
+ if (res == -1) {
+ PERROR("truncate");
+ return -1;
+ }
+ res = check_size(testfile, len);
+ if (res == -1)
+ return -1;
+
+ if (len > 0) {
+ if (len <= datalen) {
+ res = check_data(testfile, data, 0, len);
+ if (res == -1)
+ return -1;
+ } else {
+ res = check_data(testfile, data, 0, datalen);
+ if (res == -1)
+ return -1;
+ res = check_data(testfile, zerodata, datalen,
+ len - datalen);
+ if (res == -1)
+ return -1;
+ }
+ }
+ res = unlink(testfile);
+ if (res == -1) {
+ PERROR("unlink");
+ return -1;
+ }
+ res = check_nonexist(testfile);
+ if (res == -1)
+ return -1;
+
+ success();
+ return 0;
}
static int test_ftruncate(int len, int mode)
{
- const char *data = testdata;
- int datalen = testdatalen;
- int res;
- int fd;
-
- start_test("ftruncate(%u) mode: 0%03o", len, mode);
- res = create_file(testfile, data, datalen);
- if (res == -1)
- return -1;
-
- fd = open(testfile, O_WRONLY);
- if (fd == -1) {
- PERROR("open");
- return -1;
- }
-
- res = fchmod(fd, mode);
- if (res == -1) {
- PERROR("fchmod");
- close(fd);
- return -1;
- }
- res = check_mode(testfile, mode);
- if (res == -1) {
- close(fd);
- return -1;
- }
- res = ftruncate(fd, len);
- if (res == -1) {
- PERROR("ftruncate");
- close(fd);
- return -1;
- }
- close(fd);
- res = check_size(testfile, len);
- if (res == -1)
- return -1;
-
- if (len > 0) {
- if (len <= datalen) {
- res = check_data(testfile, data, 0, len);
- if (res == -1)
- return -1;
- } else {
- res = check_data(testfile, data, 0, datalen);
- if (res == -1)
- return -1;
- res = check_data(testfile, zerodata, datalen, len - datalen);
- if (res == -1)
- return -1;
- }
- }
- res = unlink(testfile);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile);
- if (res == -1)
- return -1;
-
- success();
- return 0;
+ const char *data = testdata;
+ int datalen = testdatalen;
+ int res;
+ int fd;
+
+ start_test("ftruncate(%u) mode: 0%03o", len, mode);
+ res = create_file(testfile, data, datalen);
+ if (res == -1)
+ return -1;
+
+ fd = open(testfile, O_WRONLY);
+ if (fd == -1) {
+ PERROR("open");
+ return -1;
+ }
+
+ res = fchmod(fd, mode);
+ if (res == -1) {
+ PERROR("fchmod");
+ close(fd);
+ return -1;
+ }
+ res = check_mode(testfile, mode);
+ if (res == -1) {
+ close(fd);
+ return -1;
+ }
+ res = ftruncate(fd, len);
+ if (res == -1) {
+ PERROR("ftruncate");
+ close(fd);
+ return -1;
+ }
+ close(fd);
+ res = check_size(testfile, len);
+ if (res == -1)
+ return -1;
+
+ if (len > 0) {
+ if (len <= datalen) {
+ res = check_data(testfile, data, 0, len);
+ if (res == -1)
+ return -1;
+ } else {
+ res = check_data(testfile, data, 0, datalen);
+ if (res == -1)
+ return -1;
+ res = check_data(testfile, zerodata, datalen,
+ len - datalen);
+ if (res == -1)
+ return -1;
+ }
+ }
+ res = unlink(testfile);
+ if (res == -1) {
+ PERROR("unlink");
+ return -1;
+ }
+ res = check_nonexist(testfile);
+ if (res == -1)
+ return -1;
+
+ success();
+ return 0;
}
static int test_utime(void)
{
- struct utimbuf utm;
- time_t atime = 987631200;
- time_t mtime = 123116400;
- int res;
-
- start_test("utime");
- res = create_file(testfile, NULL, 0);
- if (res == -1)
- return -1;
-
- utm.actime = atime;
- utm.modtime = mtime;
- res = utime(testfile, &utm);
- if (res == -1) {
- PERROR("utime");
- return -1;
- }
- res = check_times(testfile, atime, mtime);
- if (res == -1) {
- return -1;
- }
- res = unlink(testfile);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile);
- if (res == -1)
- return -1;
-
- success();
- return 0;
+ struct utimbuf utm;
+ time_t atime = 987631200;
+ time_t mtime = 123116400;
+ int res;
+
+ start_test("utime");
+ res = create_file(testfile, NULL, 0);
+ if (res == -1)
+ return -1;
+
+ utm.actime = atime;
+ utm.modtime = mtime;
+ res = utime(testfile, &utm);
+ if (res == -1) {
+ PERROR("utime");
+ return -1;
+ }
+ res = check_times(testfile, atime, mtime);
+ if (res == -1) {
+ return -1;
+ }
+ res = unlink(testfile);
+ if (res == -1) {
+ PERROR("unlink");
+ return -1;
+ }
+ res = check_nonexist(testfile);
+ if (res == -1)
+ return -1;
+
+ success();
+ return 0;
}
static int test_create(void)
{
- const char *data = testdata;
- int datalen = testdatalen;
- int err = 0;
- int res;
- int fd;
-
- start_test("create");
- unlink(testfile);
- fd = creat(testfile, 0644);
- if (fd == -1) {
- PERROR("creat");
- return -1;
- }
- res = write(fd, data, datalen);
- if (res == -1) {
- PERROR("write");
- close(fd);
- return -1;
- }
- if (res != datalen) {
- ERROR("write is short: %u instead of %u", res, datalen);
- close(fd);
- return -1;
- }
- res = close(fd);
- if (res == -1) {
- PERROR("close");
- return -1;
- }
- res = check_type(testfile, S_IFREG);
- if (res == -1)
- return -1;
- err += check_mode(testfile, 0644);
- err += check_nlink(testfile, 1);
- err += check_size(testfile, datalen);
- err += check_data(testfile, data, 0, datalen);
- res = unlink(testfile);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile);
- if (res == -1)
- return -1;
- if (err)
- return -1;
-
- success();
- return 0;
+ const char *data = testdata;
+ int datalen = testdatalen;
+ int err = 0;
+ int res;
+ int fd;
+
+ start_test("create");
+ unlink(testfile);
+ fd = creat(testfile, 0644);
+ if (fd == -1) {
+ PERROR("creat");
+ return -1;
+ }
+ res = write(fd, data, datalen);
+ if (res == -1) {
+ PERROR("write");
+ close(fd);
+ return -1;
+ }
+ if (res != datalen) {
+ ERROR("write is short: %u instead of %u", res, datalen);
+ close(fd);
+ return -1;
+ }
+ res = close(fd);
+ if (res == -1) {
+ PERROR("close");
+ return -1;
+ }
+ res = check_type(testfile, S_IFREG);
+ if (res == -1)
+ return -1;
+ err += check_mode(testfile, 0644);
+ err += check_nlink(testfile, 1);
+ err += check_size(testfile, datalen);
+ err += check_data(testfile, data, 0, datalen);
+ res = unlink(testfile);
+ if (res == -1) {
+ PERROR("unlink");
+ return -1;
+ }
+ res = check_nonexist(testfile);
+ if (res == -1)
+ return -1;
+ if (err)
+ return -1;
+
+ success();
+ return 0;
}
static int test_create_unlink(void)
{
- const char *data = testdata;
- int datalen = testdatalen;
- int err = 0;
- int res;
- int fd;
-
- start_test("create+unlink");
- unlink(testfile);
- fd = open(testfile, O_CREAT | O_RDWR | O_TRUNC, 0644);
- if (fd == -1) {
- PERROR("creat");
- return -1;
- }
- res = unlink(testfile);
- if (res == -1) {
- PERROR("unlink");
- close(fd);
- return -1;
- }
- res = check_nonexist(testfile);
- if (res == -1)
- return -1;
- res = write(fd, data, datalen);
- if (res == -1) {
- PERROR("write");
- close(fd);
- return -1;
- }
- if (res != datalen) {
- ERROR("write is short: %u instead of %u", res, datalen);
- close(fd);
- return -1;
- }
- err += fcheck_type(fd, S_IFREG);
- err += fcheck_mode(fd, 0644);
- err += fcheck_nlink(fd, 0);
- err += fcheck_size(fd, datalen);
- err += fcheck_data(fd, data, 0, datalen);
- res = close(fd);
- if (res == -1) {
- PERROR("close");
- err--;
- }
- if (err)
- return -1;
-
- success();
- return 0;
+ const char *data = testdata;
+ int datalen = testdatalen;
+ int err = 0;
+ int res;
+ int fd;
+
+ start_test("create+unlink");
+ unlink(testfile);
+ fd = open(testfile, O_CREAT | O_RDWR | O_TRUNC, 0644);
+ if (fd == -1) {
+ PERROR("creat");
+ return -1;
+ }
+ res = unlink(testfile);
+ if (res == -1) {
+ PERROR("unlink");
+ close(fd);
+ return -1;
+ }
+ res = check_nonexist(testfile);
+ if (res == -1)
+ return -1;
+ res = write(fd, data, datalen);
+ if (res == -1) {
+ PERROR("write");
+ close(fd);
+ return -1;
+ }
+ if (res != datalen) {
+ ERROR("write is short: %u instead of %u", res, datalen);
+ close(fd);
+ return -1;
+ }
+ err += fcheck_type(fd, S_IFREG);
+ err += fcheck_mode(fd, 0644);
+ err += fcheck_nlink(fd, 0);
+ err += fcheck_size(fd, datalen);
+ err += fcheck_data(fd, data, 0, datalen);
+ res = close(fd);
+ if (res == -1) {
+ PERROR("close");
+ err--;
+ }
+ if (err)
+ return -1;
+
+ success();
+ return 0;
}
static int test_mknod(void)
{
- int err = 0;
- int res;
-
- start_test("mknod");
- unlink(testfile);
- res = mknod(testfile, 0644, 0);
- if (res == -1) {
- PERROR("mknod");
- return -1;
- }
- res = check_type(testfile, S_IFREG);
- if (res == -1)
- return -1;
- err += check_mode(testfile, 0644);
- err += check_nlink(testfile, 1);
- err += check_size(testfile, 0);
- res = unlink(testfile);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile);
- if (res == -1)
- return -1;
- if (err)
- return -1;
-
- success();
- return 0;
+ int err = 0;
+ int res;
+
+ start_test("mknod");
+ unlink(testfile);
+ res = mknod(testfile, 0644, 0);
+ if (res == -1) {
+ PERROR("mknod");
+ return -1;
+ }
+ res = check_type(testfile, S_IFREG);
+ if (res == -1)
+ return -1;
+ err += check_mode(testfile, 0644);
+ err += check_nlink(testfile, 1);
+ err += check_size(testfile, 0);
+ res = unlink(testfile);
+ if (res == -1) {
+ PERROR("unlink");
+ return -1;
+ }
+ res = check_nonexist(testfile);
+ if (res == -1)
+ return -1;
+ if (err)
+ return -1;
+
+ success();
+ return 0;
}
#define test_open(exist, flags, mode) do_test_open(exist, flags, #flags, mode)
static int do_test_open(int exist, int flags, const char *flags_str, int mode)
{
- char buf[4096];
- const char *data = testdata;
- int datalen = testdatalen;
- unsigned currlen = 0;
- int err = 0;
- int res;
- int fd;
- off_t off;
-
- start_test("open(%s, %s, 0%03o)", exist ? "+" : "-", flags_str, mode);
- unlink(testfile);
- if (exist) {
- res = create_file(testfile, testdata2, testdata2len);
- if (res == -1)
- return -1;
-
- currlen = testdata2len;
- }
-
- fd = open(testfile, flags, mode);
- if ((flags & O_CREAT) && (flags & O_EXCL) && exist) {
- if (fd != -1) {
- ERROR("open should have failed");
- close(fd);
- return -1;
- } else if (errno == EEXIST)
- goto succ;
- }
- if (!(flags & O_CREAT) && !exist) {
- if (fd != -1) {
- ERROR("open should have failed");
- close(fd);
- return -1;
- } else if (errno == ENOENT)
- goto succ;
- }
- if (fd == -1) {
- PERROR("open");
- return -1;
- }
-
- if (flags & O_TRUNC)
- currlen = 0;
-
- err += check_type(testfile, S_IFREG);
- if (exist)
- err += check_mode(testfile, 0644);
- else
- err += check_mode(testfile, mode);
- err += check_nlink(testfile, 1);
- err += check_size(testfile, currlen);
- if (exist && !(flags & O_TRUNC) && (mode & 0400))
- err += check_data(testfile, testdata2, 0, testdata2len);
-
- res = write(fd, data, datalen);
- if ((flags & O_ACCMODE) != O_RDONLY) {
- if (res == -1) {
- PERROR("write");
- err --;
- } else if (res != datalen) {
- ERROR("write is short: %u instead of %u", res, datalen);
- err --;
- } else {
- if (datalen > (int) currlen)
- currlen = datalen;
-
- err += check_size(testfile, currlen);
-
- if (mode & 0400) {
- err += check_data(testfile, data, 0, datalen);
- if (exist && !(flags & O_TRUNC) && testdata2len > datalen)
- err += check_data(testfile, testdata2 + datalen, datalen,
- testdata2len - datalen);
- }
- }
- } else {
- if (res != -1) {
- ERROR("write should have failed");
- err --;
- } else if (errno != EBADF) {
- PERROR("write");
- err --;
- }
- }
- off = lseek(fd, SEEK_SET, 0);
- if (off == (off_t) -1) {
- PERROR("lseek");
- err--;
- } else if (off != 0) {
- ERROR("offset should have returned 0");
- err --;
- }
- res = read(fd, buf, sizeof(buf));
- if ((flags & O_ACCMODE) != O_WRONLY) {
- if (res == -1) {
- PERROR("read");
- err--;
- } else {
- int readsize = currlen < sizeof(buf) ? currlen : sizeof(buf);
- if (res != readsize) {
- ERROR("read is short: %i instead of %u", res, readsize);
- err--;
- } else {
- if ((flags & O_ACCMODE) != O_RDONLY) {
- err += check_buffer(buf, data, datalen);
- if (exist && !(flags & O_TRUNC) && testdata2len > datalen)
- err += check_buffer(buf + datalen, testdata2 + datalen,
- testdata2len - datalen);
- } else if (exist)
- err += check_buffer(buf, testdata2, testdata2len);
- }
- }
- } else {
- if (res != -1) {
- ERROR("read should have failed");
- err --;
- } else if (errno != EBADF) {
- PERROR("read");
- err --;
- }
- }
-
- res = close(fd);
- if (res == -1) {
- PERROR("close");
- return -1;
- }
- res = unlink(testfile);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile);
- if (res == -1)
- return -1;
- if (err)
- return -1;
-
- succ:
- success();
- return 0;
+ char buf[4096];
+ const char *data = testdata;
+ int datalen = testdatalen;
+ unsigned currlen = 0;
+ int err = 0;
+ int res;
+ int fd;
+ off_t off;
+
+ start_test("open(%s, %s, 0%03o)", exist ? "+" : "-", flags_str, mode);
+ unlink(testfile);
+ if (exist) {
+ res = create_file(testfile, testdata2, testdata2len);
+ if (res == -1)
+ return -1;
+
+ currlen = testdata2len;
+ }
+
+ fd = open(testfile, flags, mode);
+ if ((flags & O_CREAT) && (flags & O_EXCL) && exist) {
+ if (fd != -1) {
+ ERROR("open should have failed");
+ close(fd);
+ return -1;
+ } else if (errno == EEXIST)
+ goto succ;
+ }
+ if (!(flags & O_CREAT) && !exist) {
+ if (fd != -1) {
+ ERROR("open should have failed");
+ close(fd);
+ return -1;
+ } else if (errno == ENOENT)
+ goto succ;
+ }
+ if (fd == -1) {
+ PERROR("open");
+ return -1;
+ }
+
+ if (flags & O_TRUNC)
+ currlen = 0;
+
+ err += check_type(testfile, S_IFREG);
+ if (exist)
+ err += check_mode(testfile, 0644);
+ else
+ err += check_mode(testfile, mode);
+ err += check_nlink(testfile, 1);
+ err += check_size(testfile, currlen);
+ if (exist && !(flags & O_TRUNC) && (mode & 0400))
+ err += check_data(testfile, testdata2, 0, testdata2len);
+
+ res = write(fd, data, datalen);
+ if ((flags & O_ACCMODE) != O_RDONLY) {
+ if (res == -1) {
+ PERROR("write");
+ err --;
+ } else if (res != datalen) {
+ ERROR("write is short: %u instead of %u", res, datalen);
+ err --;
+ } else {
+ if (datalen > (int) currlen)
+ currlen = datalen;
+
+ err += check_size(testfile, currlen);
+
+ if (mode & 0400) {
+ err += check_data(testfile, data, 0, datalen);
+ if (exist && !(flags & O_TRUNC) &&
+ testdata2len > datalen)
+ err += check_data(testfile,
+ testdata2 + datalen,
+ datalen,
+ testdata2len - datalen);
+ }
+ }
+ } else {
+ if (res != -1) {
+ ERROR("write should have failed");
+ err --;
+ } else if (errno != EBADF) {
+ PERROR("write");
+ err --;
+ }
+ }
+ off = lseek(fd, SEEK_SET, 0);
+ if (off == (off_t) -1) {
+ PERROR("lseek");
+ err--;
+ } else if (off != 0) {
+ ERROR("offset should have returned 0");
+ err --;
+ }
+ res = read(fd, buf, sizeof(buf));
+ if ((flags & O_ACCMODE) != O_WRONLY) {
+ if (res == -1) {
+ PERROR("read");
+ err--;
+ } else {
+ int readsize =
+ currlen < sizeof(buf) ? currlen : sizeof(buf);
+ if (res != readsize) {
+ ERROR("read is short: %i instead of %u",
+ res, readsize);
+ err--;
+ } else {
+ if ((flags & O_ACCMODE) != O_RDONLY) {
+ err += check_buffer(buf, data, datalen);
+ if (exist && !(flags & O_TRUNC) &&
+ testdata2len > datalen)
+ err += check_buffer(buf + datalen,
+ testdata2 + datalen,
+ testdata2len - datalen);
+ } else if (exist)
+ err += check_buffer(buf, testdata2,
+ testdata2len);
+ }
+ }
+ } else {
+ if (res != -1) {
+ ERROR("read should have failed");
+ err --;
+ } else if (errno != EBADF) {
+ PERROR("read");
+ err --;
+ }
+ }
+
+ res = close(fd);
+ if (res == -1) {
+ PERROR("close");
+ return -1;
+ }
+ res = unlink(testfile);
+ if (res == -1) {
+ PERROR("unlink");
+ return -1;
+ }
+ res = check_nonexist(testfile);
+ if (res == -1)
+ return -1;
+ if (err)
+ return -1;
+
+succ:
+ success();
+ return 0;
}
-#define test_open_acc(flags, mode, err) do_test_open_acc(flags, #flags, mode, err)
+#define test_open_acc(flags, mode, err) \
+ do_test_open_acc(flags, #flags, mode, err)
static int do_test_open_acc(int flags, const char *flags_str, int mode, int err)
{
- const char *data = testdata;
- int datalen = testdatalen;
- int res;
- int fd;
-
- start_test("open_acc(%s) mode: 0%03o error: '%s'", flags_str, mode,
- strerror(err));
- unlink(testfile);
- res = create_file(testfile, data, datalen);
- if (res == -1)
- return -1;
-
- res = chmod(testfile, mode);
- if (res == -1) {
- PERROR("chmod");
- return -1;
- }
-
- res = check_mode(testfile, mode);
- if (res == -1)
- return -1;
-
- fd = open(testfile, flags);
- if (fd == -1) {
- if (err != errno) {
- PERROR("open");
- return -1;
- }
- } else {
- if (err) {
- ERROR("open should have failed");
- close(fd);
- return -1;
- }
- close(fd);
- }
- success();
- return 0;
+ const char *data = testdata;
+ int datalen = testdatalen;
+ int res;
+ int fd;
+
+ start_test("open_acc(%s) mode: 0%03o error: '%s'", flags_str, mode,
+ strerror(err));
+ unlink(testfile);
+ res = create_file(testfile, data, datalen);
+ if (res == -1)
+ return -1;
+
+ res = chmod(testfile, mode);
+ if (res == -1) {
+ PERROR("chmod");
+ return -1;
+ }
+
+ res = check_mode(testfile, mode);
+ if (res == -1)
+ return -1;
+
+ fd = open(testfile, flags);
+ if (fd == -1) {
+ if (err != errno) {
+ PERROR("open");
+ return -1;
+ }
+ } else {
+ if (err) {
+ ERROR("open should have failed");
+ close(fd);
+ return -1;
+ }
+ close(fd);
+ }
+ success();
+ return 0;
}
static int test_symlink(void)
{
- char buf[1024];
- const char *data = testdata;
- int datalen = testdatalen;
- int linklen = strlen(testfile);
- int err = 0;
- int res;
-
- start_test("symlink");
- res = create_file(testfile, data, datalen);
- if (res == -1)
- return -1;
-
- unlink(testfile2);
- res = symlink(testfile, testfile2);
- if (res == -1) {
- PERROR("symlink");
- return -1;
- }
- res = check_type(testfile2, S_IFLNK);
- if (res == -1)
- return -1;
- err += check_mode(testfile2, 0777);
- err += check_nlink(testfile2, 1);
- res = readlink(testfile2, buf, sizeof(buf));
- if (res == -1) {
- PERROR("readlink");
- err--;
- }
- if (res != linklen) {
- ERROR("short readlink: %u instead of %u", res, linklen);
- err--;
- }
- if (memcmp(buf, testfile, linklen) != 0) {
- ERROR("link mismatch");
- err--;
- }
- err += check_size(testfile2, datalen);
- err += check_data(testfile2, data, 0, datalen);
- res = unlink(testfile2);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile2);
- if (res == -1)
- return -1;
- if (err)
- return -1;
-
- success();
- return 0;
+ char buf[1024];
+ const char *data = testdata;
+ int datalen = testdatalen;
+ int linklen = strlen(testfile);
+ int err = 0;
+ int res;
+
+ start_test("symlink");
+ res = create_file(testfile, data, datalen);
+ if (res == -1)
+ return -1;
+
+ unlink(testfile2);
+ res = symlink(testfile, testfile2);
+ if (res == -1) {
+ PERROR("symlink");
+ return -1;
+ }
+ res = check_type(testfile2, S_IFLNK);
+ if (res == -1)
+ return -1;
+ err += check_mode(testfile2, 0777);
+ err += check_nlink(testfile2, 1);
+ res = readlink(testfile2, buf, sizeof(buf));
+ if (res == -1) {
+ PERROR("readlink");
+ err--;
+ }
+ if (res != linklen) {
+ ERROR("short readlink: %u instead of %u", res, linklen);
+ err--;
+ }
+ if (memcmp(buf, testfile, linklen) != 0) {
+ ERROR("link mismatch");
+ err--;
+ }
+ err += check_size(testfile2, datalen);
+ err += check_data(testfile2, data, 0, datalen);
+ res = unlink(testfile2);
+ if (res == -1) {
+ PERROR("unlink");
+ return -1;
+ }
+ res = check_nonexist(testfile2);
+ if (res == -1)
+ return -1;
+ if (err)
+ return -1;
+
+ success();
+ return 0;
}
static int test_link(void)
{
- const char *data = testdata;
- int datalen = testdatalen;
- int err = 0;
- int res;
-
- start_test("link");
- res = create_file(testfile, data, datalen);
- if (res == -1)
- return -1;
-
- unlink(testfile2);
- res = link(testfile, testfile2);
- if (res == -1) {
- PERROR("link");
- return -1;
- }
- res = check_type(testfile2, S_IFREG);
- if (res == -1)
- return -1;
- err += check_mode(testfile2, 0644);
- err += check_nlink(testfile2, 2);
- err += check_size(testfile2, datalen);
- err += check_data(testfile2, data, 0, datalen);
- res = unlink(testfile);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile);
- if (res == -1)
- return -1;
-
- err += check_nlink(testfile2, 1);
- res = unlink(testfile2);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile2);
- if (res == -1)
- return -1;
- if (err)
- return -1;
-
- success();
- return 0;
+ const char *data = testdata;
+ int datalen = testdatalen;
+ int err = 0;
+ int res;
+
+ start_test("link");
+ res = create_file(testfile, data, datalen);
+ if (res == -1)
+ return -1;
+
+ unlink(testfile2);
+ res = link(testfile, testfile2);
+ if (res == -1) {
+ PERROR("link");
+ return -1;
+ }
+ res = check_type(testfile2, S_IFREG);
+ if (res == -1)
+ return -1;
+ err += check_mode(testfile2, 0644);
+ err += check_nlink(testfile2, 2);
+ err += check_size(testfile2, datalen);
+ err += check_data(testfile2, data, 0, datalen);
+ res = unlink(testfile);
+ if (res == -1) {
+ PERROR("unlink");
+ return -1;
+ }
+ res = check_nonexist(testfile);
+ if (res == -1)
+ return -1;
+
+ err += check_nlink(testfile2, 1);
+ res = unlink(testfile2);
+ if (res == -1) {
+ PERROR("unlink");
+ return -1;
+ }
+ res = check_nonexist(testfile2);
+ if (res == -1)
+ return -1;
+ if (err)
+ return -1;
+
+ success();
+ return 0;
}
static int test_rename_file(void)
{
- const char *data = testdata;
- int datalen = testdatalen;
- int err = 0;
- int res;
-
- start_test("rename file");
- res = create_file(testfile, data, datalen);
- if (res == -1)
- return -1;
-
- unlink(testfile2);
- res = rename(testfile, testfile2);
- if (res == -1) {
- PERROR("rename");
- return -1;
- }
- res = check_nonexist(testfile);
- if (res == -1)
- return -1;
- res = check_type(testfile2, S_IFREG);
- if (res == -1)
- return -1;
- err += check_mode(testfile2, 0644);
- err += check_nlink(testfile2, 1);
- err += check_size(testfile2, datalen);
- err += check_data(testfile2, data, 0, datalen);
- res = unlink(testfile2);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile2);
- if (res == -1)
- return -1;
- if (err)
- return -1;
-
- success();
- return 0;
+ const char *data = testdata;
+ int datalen = testdatalen;
+ int err = 0;
+ int res;
+
+ start_test("rename file");
+ res = create_file(testfile, data, datalen);
+ if (res == -1)
+ return -1;
+
+ unlink(testfile2);
+ res = rename(testfile, testfile2);
+ if (res == -1) {
+ PERROR("rename");
+ return -1;
+ }
+ res = check_nonexist(testfile);
+ if (res == -1)
+ return -1;
+ res = check_type(testfile2, S_IFREG);
+ if (res == -1)
+ return -1;
+ err += check_mode(testfile2, 0644);
+ err += check_nlink(testfile2, 1);
+ err += check_size(testfile2, datalen);
+ err += check_data(testfile2, data, 0, datalen);
+ res = unlink(testfile2);
+ if (res == -1) {
+ PERROR("unlink");
+ return -1;
+ }
+ res = check_nonexist(testfile2);
+ if (res == -1)
+ return -1;
+ if (err)
+ return -1;
+
+ success();
+ return 0;
}
static int test_rename_dir(void)
{
- int err = 0;
- int res;
-
- start_test("rename dir");
- res = create_dir(testdir, testdir_files);
- if (res == -1)
- return -1;
-
- rmdir(testdir2);
- res = rename(testdir, testdir2);
- if (res == -1) {
- PERROR("rename");
- cleanup_dir(testdir, testdir_files, 1);
- return -1;
- }
- res = check_nonexist(testdir);
- if (res == -1) {
- cleanup_dir(testdir, testdir_files, 1);
- return -1;
- }
- res = check_type(testdir2, S_IFDIR);
- if (res == -1) {
- cleanup_dir(testdir2, testdir_files, 1);
- return -1;
- }
- err += check_mode(testdir2, 0755);
- err += check_dir_contents(testdir2, testdir_files);
- err += cleanup_dir(testdir2, testdir_files, 0);
- res = rmdir(testdir2);
- if (res == -1) {
- PERROR("rmdir");
- return -1;
- }
- res = check_nonexist(testdir2);
- if (res == -1)
- return -1;
- if (err)
- return -1;
-
- success();
- return 0;
+ int err = 0;
+ int res;
+
+ start_test("rename dir");
+ res = create_dir(testdir, testdir_files);
+ if (res == -1)
+ return -1;
+
+ rmdir(testdir2);
+ res = rename(testdir, testdir2);
+ if (res == -1) {
+ PERROR("rename");
+ cleanup_dir(testdir, testdir_files, 1);
+ return -1;
+ }
+ res = check_nonexist(testdir);
+ if (res == -1) {
+ cleanup_dir(testdir, testdir_files, 1);
+ return -1;
+ }
+ res = check_type(testdir2, S_IFDIR);
+ if (res == -1) {
+ cleanup_dir(testdir2, testdir_files, 1);
+ return -1;
+ }
+ err += check_mode(testdir2, 0755);
+ err += check_dir_contents(testdir2, testdir_files);
+ err += cleanup_dir(testdir2, testdir_files, 0);
+ res = rmdir(testdir2);
+ if (res == -1) {
+ PERROR("rmdir");
+ return -1;
+ }
+ res = check_nonexist(testdir2);
+ if (res == -1)
+ return -1;
+ if (err)
+ return -1;
+
+ success();
+ return 0;
}
static int test_mkfifo(void)
{
- int res;
- int err = 0;
-
- start_test("mkfifo");
- unlink(testfile);
- res = mkfifo(testfile, 0644);
- if (res == -1) {
- PERROR("mkfifo");
- return -1;
- }
- res = check_type(testfile, S_IFIFO);
- if (res == -1)
- return -1;
- err += check_mode(testfile, 0644);
- err += check_nlink(testfile, 1);
- res = unlink(testfile);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile);
- if (res == -1)
- return -1;
- if (err)
- return -1;
-
- success();
- return 0;
+ int res;
+ int err = 0;
+
+ start_test("mkfifo");
+ unlink(testfile);
+ res = mkfifo(testfile, 0644);
+ if (res == -1) {
+ PERROR("mkfifo");
+ return -1;
+ }
+ res = check_type(testfile, S_IFIFO);
+ if (res == -1)
+ return -1;
+ err += check_mode(testfile, 0644);
+ err += check_nlink(testfile, 1);
+ res = unlink(testfile);
+ if (res == -1) {
+ PERROR("unlink");
+ return -1;
+ }
+ res = check_nonexist(testfile);
+ if (res == -1)
+ return -1;
+ if (err)
+ return -1;
+
+ success();
+ return 0;
}
static int test_mkdir(void)
{
- int res;
- int err = 0;
- const char *dir_contents[] = {NULL};
-
- start_test("mkdir");
- rmdir(testdir);
- res = mkdir(testdir, 0755);
- if (res == -1) {
- PERROR("mkdir");
- return -1;
- }
- res = check_type(testdir, S_IFDIR);
- if (res == -1)
- return -1;
- err += check_mode(testdir, 0755);
- err += check_nlink(testdir, 2);
- err += check_dir_contents(testdir, dir_contents);
- res = rmdir(testdir);
- if (res == -1) {
- PERROR("rmdir");
- return -1;
- }
- res = check_nonexist(testdir);
- if (res == -1)
- return -1;
- if (err)
- return -1;
-
- success();
- return 0;
+ int res;
+ int err = 0;
+ const char *dir_contents[] = {NULL};
+
+ start_test("mkdir");
+ rmdir(testdir);
+ res = mkdir(testdir, 0755);
+ if (res == -1) {
+ PERROR("mkdir");
+ return -1;
+ }
+ res = check_type(testdir, S_IFDIR);
+ if (res == -1)
+ return -1;
+ err += check_mode(testdir, 0755);
+ err += check_nlink(testdir, 2);
+ err += check_dir_contents(testdir, dir_contents);
+ res = rmdir(testdir);
+ if (res == -1) {
+ PERROR("rmdir");
+ return -1;
+ }
+ res = check_nonexist(testdir);
+ if (res == -1)
+ return -1;
+ if (err)
+ return -1;
+
+ success();
+ return 0;
}
int main(int argc, char *argv[])
{
- const char *basepath;
- int err = 0;
-
- umask(0);
- if (argc != 2) {
- fprintf(stderr, "usage: %s testdir\n", argv[0]);
- return 1;
- }
- basepath = argv[1];
- assert(strlen(basepath) < 512);
- if (basepath[0] != '/') {
- fprintf(stderr, "testdir must be an absolute path\n");
- return 1;
- }
-
- sprintf(testfile, "%s/testfile", basepath);
- sprintf(testfile2, "%s/testfile2", basepath);
- sprintf(testdir, "%s/testdir", basepath);
- sprintf(testdir2, "%s/testdir2", basepath);
- err += test_create();
- err += test_create_unlink();
- err += test_mknod();
- err += test_symlink();
- err += test_link();
- err += test_mkfifo();
- err += test_mkdir();
- err += test_rename_file();
- err += test_rename_dir();
- err += test_utime();
- err += test_truncate(0);
- err += test_truncate(testdatalen / 2);
- err += test_truncate(testdatalen);
- err += test_truncate(testdatalen + 100);
- err += test_ftruncate(0, 0600);
- err += test_ftruncate(testdatalen / 2, 0600);
- err += test_ftruncate(testdatalen, 0600);
- err += test_ftruncate(testdatalen + 100, 0600);
- err += test_ftruncate(0, 0400);
- err += test_ftruncate(0, 0200);
- err += test_ftruncate(0, 0000);
- err += test_open(0, O_RDONLY, 0);
- err += test_open(1, O_RDONLY, 0);
- err += test_open(1, O_RDWR, 0);
- err += test_open(1, O_WRONLY, 0);
- err += test_open(0, O_RDWR | O_CREAT, 0600);
- err += test_open(1, O_RDWR | O_CREAT, 0600);
- err += test_open(0, O_RDWR | O_CREAT | O_TRUNC, 0600);
- err += test_open(1, O_RDWR | O_CREAT | O_TRUNC, 0600);
- err += test_open(0, O_RDONLY | O_CREAT, 0600);
- err += test_open(0, O_RDONLY | O_CREAT, 0400);
- err += test_open(0, O_RDONLY | O_CREAT, 0200);
- err += test_open(0, O_RDONLY | O_CREAT, 0000);
- err += test_open(0, O_WRONLY | O_CREAT, 0600);
- err += test_open(0, O_WRONLY | O_CREAT, 0400);
- err += test_open(0, O_WRONLY | O_CREAT, 0200);
- err += test_open(0, O_WRONLY | O_CREAT, 0000);
- err += test_open(0, O_RDWR | O_CREAT, 0400);
- err += test_open(0, O_RDWR | O_CREAT, 0200);
- err += test_open(0, O_RDWR | O_CREAT, 0000);
- err += test_open(0, O_RDWR | O_CREAT | O_EXCL, 0600);
- err += test_open(1, O_RDWR | O_CREAT | O_EXCL, 0600);
- err += test_open(0, O_RDWR | O_CREAT | O_EXCL, 0000);
- err += test_open(1, O_RDWR | O_CREAT | O_EXCL, 0000);
- err += test_open_acc(O_RDONLY, 0600, 0);
- err += test_open_acc(O_WRONLY, 0600, 0);
- err += test_open_acc(O_RDWR, 0600, 0);
- err += test_open_acc(O_RDONLY, 0400, 0);
- err += test_open_acc(O_RDONLY | O_TRUNC, 0400, EACCES);
- err += test_open_acc(O_WRONLY, 0400, EACCES);
- err += test_open_acc(O_RDWR, 0400, EACCES);
- err += test_open_acc(O_RDONLY, 0200, EACCES);
- err += test_open_acc(O_WRONLY, 0200, 0);
- err += test_open_acc(O_RDWR, 0200, EACCES);
- err += test_open_acc(O_RDONLY, 0000, EACCES);
- err += test_open_acc(O_WRONLY, 0000, EACCES);
- err += test_open_acc(O_RDWR, 0000, EACCES);
-
- unlink(testfile);
- unlink(testfile2);
- rmdir(testdir);
- rmdir(testdir2);
-
- if (err) {
- fprintf(stderr, "%i tests failed\n", -err);
- return 1;
- }
-
- return 0;
+ const char *basepath;
+ int err = 0;
+
+ umask(0);
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s testdir\n", argv[0]);
+ return 1;
+ }
+ basepath = argv[1];
+ assert(strlen(basepath) < 512);
+ if (basepath[0] != '/') {
+ fprintf(stderr, "testdir must be an absolute path\n");
+ return 1;
+ }
+
+ sprintf(testfile, "%s/testfile", basepath);
+ sprintf(testfile2, "%s/testfile2", basepath);
+ sprintf(testdir, "%s/testdir", basepath);
+ sprintf(testdir2, "%s/testdir2", basepath);
+ err += test_create();
+ err += test_create_unlink();
+ err += test_mknod();
+ err += test_symlink();
+ err += test_link();
+ err += test_mkfifo();
+ err += test_mkdir();
+ err += test_rename_file();
+ err += test_rename_dir();
+ err += test_utime();
+ err += test_truncate(0);
+ err += test_truncate(testdatalen / 2);
+ err += test_truncate(testdatalen);
+ err += test_truncate(testdatalen + 100);
+ err += test_ftruncate(0, 0600);
+ err += test_ftruncate(testdatalen / 2, 0600);
+ err += test_ftruncate(testdatalen, 0600);
+ err += test_ftruncate(testdatalen + 100, 0600);
+ err += test_ftruncate(0, 0400);
+ err += test_ftruncate(0, 0200);
+ err += test_ftruncate(0, 0000);
+ err += test_open(0, O_RDONLY, 0);
+ err += test_open(1, O_RDONLY, 0);
+ err += test_open(1, O_RDWR, 0);
+ err += test_open(1, O_WRONLY, 0);
+ err += test_open(0, O_RDWR | O_CREAT, 0600);
+ err += test_open(1, O_RDWR | O_CREAT, 0600);
+ err += test_open(0, O_RDWR | O_CREAT | O_TRUNC, 0600);
+ err += test_open(1, O_RDWR | O_CREAT | O_TRUNC, 0600);
+ err += test_open(0, O_RDONLY | O_CREAT, 0600);
+ err += test_open(0, O_RDONLY | O_CREAT, 0400);
+ err += test_open(0, O_RDONLY | O_CREAT, 0200);
+ err += test_open(0, O_RDONLY | O_CREAT, 0000);
+ err += test_open(0, O_WRONLY | O_CREAT, 0600);
+ err += test_open(0, O_WRONLY | O_CREAT, 0400);
+ err += test_open(0, O_WRONLY | O_CREAT, 0200);
+ err += test_open(0, O_WRONLY | O_CREAT, 0000);
+ err += test_open(0, O_RDWR | O_CREAT, 0400);
+ err += test_open(0, O_RDWR | O_CREAT, 0200);
+ err += test_open(0, O_RDWR | O_CREAT, 0000);
+ err += test_open(0, O_RDWR | O_CREAT | O_EXCL, 0600);
+ err += test_open(1, O_RDWR | O_CREAT | O_EXCL, 0600);
+ err += test_open(0, O_RDWR | O_CREAT | O_EXCL, 0000);
+ err += test_open(1, O_RDWR | O_CREAT | O_EXCL, 0000);
+ err += test_open_acc(O_RDONLY, 0600, 0);
+ err += test_open_acc(O_WRONLY, 0600, 0);
+ err += test_open_acc(O_RDWR, 0600, 0);
+ err += test_open_acc(O_RDONLY, 0400, 0);
+ err += test_open_acc(O_RDONLY | O_TRUNC, 0400, EACCES);
+ err += test_open_acc(O_WRONLY, 0400, EACCES);
+ err += test_open_acc(O_RDWR, 0400, EACCES);
+ err += test_open_acc(O_RDONLY, 0200, EACCES);
+ err += test_open_acc(O_WRONLY, 0200, 0);
+ err += test_open_acc(O_RDWR, 0200, EACCES);
+ err += test_open_acc(O_RDONLY, 0000, EACCES);
+ err += test_open_acc(O_WRONLY, 0000, EACCES);
+ err += test_open_acc(O_RDWR, 0000, EACCES);
+
+ unlink(testfile);
+ unlink(testfile2);
+ rmdir(testdir);
+ rmdir(testdir2);
+
+ if (err) {
+ fprintf(stderr, "%i tests failed\n", -err);
+ return 1;
+ }
+
+ return 0;
}
diff --git a/util/fusermount.c b/util/fusermount.c
index 716caff..e3c98c5 100644
--- a/util/fusermount.c
+++ b/util/fusermount.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU GPL.
- See the file COPYING.
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
*/
/* This program does the mounting and unmounting of FUSE filesystems */
@@ -27,7 +27,7 @@
#include <sys/socket.h>
#include <sys/utsname.h>
-#define FUSE_COMMFD_ENV "_FUSE_COMMFD"
+#define FUSE_COMMFD_ENV "_FUSE_COMMFD"
#define FUSE_DEV_OLD "/proc/fs/fuse/dev"
#define FUSE_DEV_NEW "/dev/fuse"
@@ -45,13 +45,13 @@ static int mount_max = 1000;
static const char *get_user_name(void)
{
- struct passwd *pw = getpwuid(getuid());
- if (pw != NULL && pw->pw_name != NULL)
- return pw->pw_name;
- else {
- fprintf(stderr, "%s: could not determine username\n", progname);
- return NULL;
- }
+ struct passwd *pw = getpwuid(getuid());
+ if (pw != NULL && pw->pw_name != NULL)
+ return pw->pw_name;
+ else {
+ fprintf(stderr, "%s: could not determine username\n", progname);
+ return NULL;
+ }
}
static uid_t oldfsuid;
@@ -59,868 +59,897 @@ static gid_t oldfsgid;
static void drop_privs(void)
{
- if (getuid() != 0) {
- oldfsuid = setfsuid(getuid());
- oldfsgid = setfsgid(getgid());
- }
+ if (getuid() != 0) {
+ oldfsuid = setfsuid(getuid());
+ oldfsgid = setfsgid(getgid());
+ }
}
static void restore_privs(void)
{
- if (getuid() != 0) {
- setfsuid(oldfsuid);
- setfsgid(oldfsgid);
- }
+ if (getuid() != 0) {
+ setfsuid(oldfsuid);
+ setfsgid(oldfsgid);
+ }
}
#ifndef IGNORE_MTAB
static int add_mount(const char *source, const char *mnt, const char *type,
- const char *opts)
+ const char *opts)
{
- return fuse_mnt_add_mount(progname, source, mnt, type, opts);
+ return fuse_mnt_add_mount(progname, source, mnt, type, opts);
}
static int unmount_fuse(const char *mnt, int quiet, int lazy)
{
- if (getuid() != 0) {
- struct mntent *entp;
- FILE *fp;
- const char *user = NULL;
- char uidstr[32];
- unsigned uidlen = 0;
- int found;
- const char *mtab = _PATH_MOUNTED;
-
- user = get_user_name();
- if (user == NULL)
- return -1;
-
- fp = setmntent(mtab, "r");
- if (fp == NULL) {
- fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab,
- strerror(errno));
- return -1;
- }
-
- uidlen = sprintf(uidstr, "%u", getuid());
-
- found = 0;
- while ((entp = getmntent(fp)) != NULL) {
- if (!found && strcmp(entp->mnt_dir, mnt) == 0 &&
- (strcmp(entp->mnt_type, "fuse") == 0 ||
- strcmp(entp->mnt_type, "fuseblk") == 0 ||
- strncmp(entp->mnt_type, "fuse.", 5) == 0 ||
- strncmp(entp->mnt_type, "fuseblk.", 8) == 0)) {
- char *p = strstr(entp->mnt_opts, "user=");
- if (p && (p == entp->mnt_opts || *(p-1) == ',') &&
- strcmp(p + 5, user) == 0) {
- found = 1;
- break;
- }
- /* /etc/mtab is a link pointing to /proc/mounts: */
- else if ((p = strstr(entp->mnt_opts, "user_id=")) &&
- (p == entp->mnt_opts || *(p-1) == ',') &&
- strncmp(p + 8, uidstr, uidlen) == 0 &&
- (*(p+8+uidlen) == ',' || *(p+8+uidlen) == '\0')) {
- found = 1;
- break;
- }
- }
- }
- endmntent(fp);
-
- if (!found) {
- if (!quiet)
- fprintf(stderr, "%s: entry for %s not found in %s\n", progname,
- mnt, mtab);
- return -1;
- }
- }
-
- return fuse_mnt_umount(progname, mnt, lazy);
+ if (getuid() != 0) {
+ struct mntent *entp;
+ FILE *fp;
+ const char *user = NULL;
+ char uidstr[32];
+ unsigned uidlen = 0;
+ int found;
+ const char *mtab = _PATH_MOUNTED;
+
+ user = get_user_name();
+ if (user == NULL)
+ return -1;
+
+ fp = setmntent(mtab, "r");
+ if (fp == NULL) {
+ fprintf(stderr,
+ "%s: failed to open %s: %s\n", progname, mtab,
+ strerror(errno));
+ return -1;
+ }
+
+ uidlen = sprintf(uidstr, "%u", getuid());
+
+ found = 0;
+ while ((entp = getmntent(fp)) != NULL) {
+ if (!found && strcmp(entp->mnt_dir, mnt) == 0 &&
+ (strcmp(entp->mnt_type, "fuse") == 0 ||
+ strcmp(entp->mnt_type, "fuseblk") == 0 ||
+ strncmp(entp->mnt_type, "fuse.", 5) == 0 ||
+ strncmp(entp->mnt_type, "fuseblk.", 8) == 0)) {
+ char *p = strstr(entp->mnt_opts, "user=");
+ if (p &&
+ (p == entp->mnt_opts || *(p-1) == ',') &&
+ strcmp(p + 5, user) == 0) {
+ found = 1;
+ break;
+ }
+ /* /etc/mtab is a link pointing to
+ /proc/mounts: */
+ else if ((p =
+ strstr(entp->mnt_opts, "user_id=")) &&
+ (p == entp->mnt_opts ||
+ *(p-1) == ',') &&
+ strncmp(p + 8, uidstr, uidlen) == 0 &&
+ (*(p+8+uidlen) == ',' ||
+ *(p+8+uidlen) == '\0')) {
+ found = 1;
+ break;
+ }
+ }
+ }
+ endmntent(fp);
+
+ if (!found) {
+ if (!quiet)
+ fprintf(stderr,
+ "%s: entry for %s not found in %s\n",
+ progname, mnt, mtab);
+ return -1;
+ }
+ }
+
+ return fuse_mnt_umount(progname, mnt, lazy);
}
static int count_fuse_fs(void)
{
- struct mntent *entp;
- int count = 0;
- const char *mtab = _PATH_MOUNTED;
- FILE *fp = setmntent(mtab, "r");
- if (fp == NULL) {
- fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab,
- strerror(errno));
- return -1;
- }
- while ((entp = getmntent(fp)) != NULL) {
- if (strcmp(entp->mnt_type, "fuse") == 0 ||
- strncmp(entp->mnt_type, "fuse.", 5) == 0)
- count ++;
- }
- endmntent(fp);
- return count;
+ struct mntent *entp;
+ int count = 0;
+ const char *mtab = _PATH_MOUNTED;
+ FILE *fp = setmntent(mtab, "r");
+ if (fp == NULL) {
+ fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab,
+ strerror(errno));
+ return -1;
+ }
+ while ((entp = getmntent(fp)) != NULL) {
+ if (strcmp(entp->mnt_type, "fuse") == 0 ||
+ strncmp(entp->mnt_type, "fuse.", 5) == 0)
+ count ++;
+ }
+ endmntent(fp);
+ return count;
}
#else /* IGNORE_MTAB */
static int count_fuse_fs()
{
- return 0;
+ return 0;
}
static int add_mount(const char *source, const char *mnt, const char *type,
- const char *opts)
+ const char *opts)
{
- (void) source;
- (void) mnt;
- (void) type;
- (void) opts;
- return 0;
+ (void) source;
+ (void) mnt;
+ (void) type;
+ (void) opts;
+ return 0;
}
static int unmount_fuse(const char *mnt, int quiet, int lazy)
{
- return fuse_mnt_umount(progname, mnt, lazy);
+ return fuse_mnt_umount(progname, mnt, lazy);
}
#endif /* IGNORE_MTAB */
static void strip_line(char *line)
{
- char *s = strchr(line, '#');
- if (s != NULL)
- s[0] = '\0';
- for (s = line + strlen(line) - 1; s >= line && isspace((unsigned char) *s); s--);
- s[1] = '\0';
- for (s = line; isspace((unsigned char) *s); s++);
- if (s != line)
- memmove(line, s, strlen(s)+1);
+ char *s = strchr(line, '#');
+ if (s != NULL)
+ s[0] = '\0';
+ for (s = line + strlen(line) - 1;
+ s >= line && isspace((unsigned char) *s); s--);
+ s[1] = '\0';
+ for (s = line; isspace((unsigned char) *s); s++);
+ if (s != line)
+ memmove(line, s, strlen(s)+1);
}
static void parse_line(char *line, int linenum)
{
- int tmp;
- if (strcmp(line, "user_allow_other") == 0)
- user_allow_other = 1;
- else if (sscanf(line, "mount_max = %i", &tmp) == 1)
- mount_max = tmp;
- else if(line[0])
- fprintf(stderr, "%s: unknown parameter in %s at line %i: '%s'\n",
- progname, FUSE_CONF, linenum, line);
+ int tmp;
+ if (strcmp(line, "user_allow_other") == 0)
+ user_allow_other = 1;
+ else if (sscanf(line, "mount_max = %i", &tmp) == 1)
+ mount_max = tmp;
+ else if(line[0])
+ fprintf(stderr,
+ "%s: unknown parameter in %s at line %i: '%s'\n",
+ progname, FUSE_CONF, linenum, line);
}
static void read_conf(void)
{
- FILE *fp = fopen(FUSE_CONF, "r");
- if (fp != NULL) {
- int linenum = 1;
- char line[256];
- int isnewline = 1;
- while (fgets(line, sizeof(line), fp) != NULL) {
- if (isnewline) {
- if (line[strlen(line)-1] == '\n') {
- strip_line(line);
- parse_line(line, linenum);
- } else {
- fprintf(stderr, "%s: reading %s: line %i too long\n",
- progname, FUSE_CONF, linenum);
- isnewline = 0;
- }
- } else if(line[strlen(line)-1] == '\n')
- isnewline = 1;
- if (isnewline)
- linenum ++;
- }
- fclose(fp);
- } else if (errno != ENOENT) {
- fprintf(stderr, "%s: failed to open %s: %s\n", progname, FUSE_CONF,
- strerror(errno));
- }
+ FILE *fp = fopen(FUSE_CONF, "r");
+ if (fp != NULL) {
+ int linenum = 1;
+ char line[256];
+ int isnewline = 1;
+ while (fgets(line, sizeof(line), fp) != NULL) {
+ if (isnewline) {
+ if (line[strlen(line)-1] == '\n') {
+ strip_line(line);
+ parse_line(line, linenum);
+ } else {
+ fprintf(stderr, "%s: reading %s: line %i too long\n",
+ progname, FUSE_CONF, linenum);
+ isnewline = 0;
+ }
+ } else if(line[strlen(line)-1] == '\n')
+ isnewline = 1;
+ if (isnewline)
+ linenum ++;
+ }
+ fclose(fp);
+ } else if (errno != ENOENT) {
+ fprintf(stderr, "%s: failed to open %s: %s\n",
+ progname, FUSE_CONF, strerror(errno));
+ }
}
static int begins_with(const char *s, const char *beg)
{
- if (strncmp(s, beg, strlen(beg)) == 0)
- return 1;
- else
- return 0;
+ if (strncmp(s, beg, strlen(beg)) == 0)
+ return 1;
+ else
+ return 0;
}
struct mount_flags {
- const char *opt;
- unsigned long flag;
- int on;
- int safe;
+ const char *opt;
+ unsigned long flag;
+ int on;
+ int safe;
};
static struct mount_flags mount_flags[] = {
- {"rw", MS_RDONLY, 0, 1},
- {"ro", MS_RDONLY, 1, 1},
- {"suid", MS_NOSUID, 0, 0},
- {"nosuid", MS_NOSUID, 1, 1},
- {"dev", MS_NODEV, 0, 0},
- {"nodev", MS_NODEV, 1, 1},
- {"exec", MS_NOEXEC, 0, 1},
- {"noexec", MS_NOEXEC, 1, 1},
- {"async", MS_SYNCHRONOUS, 0, 1},
- {"sync", MS_SYNCHRONOUS, 1, 1},
- {"atime", MS_NOATIME, 0, 1},
- {"noatime", MS_NOATIME, 1, 1},
- {"dirsync", MS_DIRSYNC, 1, 1},
- {NULL, 0, 0, 0}
+ {"rw", MS_RDONLY, 0, 1},
+ {"ro", MS_RDONLY, 1, 1},
+ {"suid", MS_NOSUID, 0, 0},
+ {"nosuid", MS_NOSUID, 1, 1},
+ {"dev", MS_NODEV, 0, 0},
+ {"nodev", MS_NODEV, 1, 1},
+ {"exec", MS_NOEXEC, 0, 1},
+ {"noexec", MS_NOEXEC, 1, 1},
+ {"async", MS_SYNCHRONOUS, 0, 1},
+ {"sync", MS_SYNCHRONOUS, 1, 1},
+ {"atime", MS_NOATIME, 0, 1},
+ {"noatime", MS_NOATIME, 1, 1},
+ {"dirsync", MS_DIRSYNC, 1, 1},
+ {NULL, 0, 0, 0}
};
static int find_mount_flag(const char *s, unsigned len, int *on, int *flag)
{
- int i;
-
- for (i = 0; mount_flags[i].opt != NULL; i++) {
- const char *opt = mount_flags[i].opt;
- if (strlen(opt) == len && strncmp(opt, s, len) == 0) {
- *on = mount_flags[i].on;
- *flag = mount_flags[i].flag;
- if (!mount_flags[i].safe && getuid() != 0) {
- *flag = 0;
- fprintf(stderr, "%s: unsafe option %s ignored\n",
- progname, opt);
- }
- return 1;
- }
- }
- return 0;
+ int i;
+
+ for (i = 0; mount_flags[i].opt != NULL; i++) {
+ const char *opt = mount_flags[i].opt;
+ if (strlen(opt) == len && strncmp(opt, s, len) == 0) {
+ *on = mount_flags[i].on;
+ *flag = mount_flags[i].flag;
+ if (!mount_flags[i].safe && getuid() != 0) {
+ *flag = 0;
+ fprintf(stderr,
+ "%s: unsafe option %s ignored\n",
+ progname, opt);
+ }
+ return 1;
+ }
+ }
+ return 0;
}
static int add_option(char **optsp, const char *opt, unsigned expand)
{
- char *newopts;
- if (*optsp == NULL)
- newopts = strdup(opt);
- else {
- unsigned oldsize = strlen(*optsp);
- unsigned newsize = oldsize + 1 + strlen(opt) + expand + 1;
- newopts = (char *) realloc(*optsp, newsize);
- if (newopts)
- sprintf(newopts + oldsize, ",%s", opt);
- }
- if (newopts == NULL) {
- fprintf(stderr, "%s: failed to allocate memory\n", progname);
- return -1;
- }
- *optsp = newopts;
- return 0;
+ char *newopts;
+ if (*optsp == NULL)
+ newopts = strdup(opt);
+ else {
+ unsigned oldsize = strlen(*optsp);
+ unsigned newsize = oldsize + 1 + strlen(opt) + expand + 1;
+ newopts = (char *) realloc(*optsp, newsize);
+ if (newopts)
+ sprintf(newopts + oldsize, ",%s", opt);
+ }
+ if (newopts == NULL) {
+ fprintf(stderr, "%s: failed to allocate memory\n", progname);
+ return -1;
+ }
+ *optsp = newopts;
+ return 0;
}
static int get_mnt_opts(int flags, char *opts, char **mnt_optsp)
{
- int i;
- int l;
-
- if (!(flags & MS_RDONLY) && add_option(mnt_optsp, "rw", 0) == -1)
- return -1;
-
- for (i = 0; mount_flags[i].opt != NULL; i++) {
- if (mount_flags[i].on && (flags & mount_flags[i].flag) &&
- add_option(mnt_optsp, mount_flags[i].opt, 0) == -1)
- return -1;
- }
-
- if (add_option(mnt_optsp, opts, 0) == -1)
- return -1;
- /* remove comma from end of opts*/
- l = strlen(*mnt_optsp);
- if ((*mnt_optsp)[l-1] == ',')
- (*mnt_optsp)[l-1] = '\0';
- if (getuid() != 0) {
- const char *user = get_user_name();
- if (user == NULL)
- return -1;
-
- if (add_option(mnt_optsp, "user=", strlen(user)) == -1)
- return -1;
- strcat(*mnt_optsp, user);
- }
- return 0;
+ int i;
+ int l;
+
+ if (!(flags & MS_RDONLY) && add_option(mnt_optsp, "rw", 0) == -1)
+ return -1;
+
+ for (i = 0; mount_flags[i].opt != NULL; i++) {
+ if (mount_flags[i].on && (flags & mount_flags[i].flag) &&
+ add_option(mnt_optsp, mount_flags[i].opt, 0) == -1)
+ return -1;
+ }
+
+ if (add_option(mnt_optsp, opts, 0) == -1)
+ return -1;
+ /* remove comma from end of opts*/
+ l = strlen(*mnt_optsp);
+ if ((*mnt_optsp)[l-1] == ',')
+ (*mnt_optsp)[l-1] = '\0';
+ if (getuid() != 0) {
+ const char *user = get_user_name();
+ if (user == NULL)
+ return -1;
+
+ if (add_option(mnt_optsp, "user=", strlen(user)) == -1)
+ return -1;
+ strcat(*mnt_optsp, user);
+ }
+ return 0;
}
static int opt_eq(const char *s, unsigned len, const char *opt)
{
- if(strlen(opt) == len && strncmp(s, opt, len) == 0)
- return 1;
- else
- return 0;
+ if(strlen(opt) == len && strncmp(s, opt, len) == 0)
+ return 1;
+ else
+ return 0;
}
static int get_string_opt(const char *s, unsigned len, const char *opt,
- char **val)
+ char **val)
{
- unsigned opt_len = strlen(opt);
-
- if (*val)
- free(*val);
- *val = (char *) malloc(len - opt_len + 1);
- if (!*val) {
- fprintf(stderr, "%s: failed to allocate memory\n", progname);
- return 0;
- }
-
- memcpy(*val, s + opt_len, len - opt_len);
- (*val)[len - opt_len] = '\0';
- return 1;
+ unsigned opt_len = strlen(opt);
+
+ if (*val)
+ free(*val);
+ *val = (char *) malloc(len - opt_len + 1);
+ if (!*val) {
+ fprintf(stderr, "%s: failed to allocate memory\n", progname);
+ return 0;
+ }
+
+ memcpy(*val, s + opt_len, len - opt_len);
+ (*val)[len - opt_len] = '\0';
+ return 1;
}
static int do_mount(const char *mnt, char **typep, mode_t rootmode,
- int fd, const char *opts, const char *dev, char **sourcep,
- char **mnt_optsp, off_t rootsize)
+ int fd, const char *opts, const char *dev, char **sourcep,
+ char **mnt_optsp, off_t rootsize)
{
- int res;
- int flags = MS_NOSUID | MS_NODEV;
- char *optbuf;
- char *mnt_opts = NULL;
- const char *s;
- char *d;
- char *fsname = NULL;
- char *subtype = NULL;
- char *source = NULL;
- char *type = NULL;
- int check_empty = 1;
- int blkdev = 0;
-
- optbuf = (char *) malloc(strlen(opts) + 128);
- if (!optbuf) {
- fprintf(stderr, "%s: failed to allocate memory\n", progname);
- return -1;
- }
-
- for (s = opts, d = optbuf; *s;) {
- unsigned len;
- const char *fsname_str = "fsname=";
- const char *subtype_str = "subtype=";
- for (len = 0; s[len] && s[len] != ','; len++);
- if (begins_with(s, fsname_str)) {
- if (!get_string_opt(s, len, fsname_str, &fsname))
- goto err;
- } else if (begins_with(s, subtype_str)) {
- if (!get_string_opt(s, len, subtype_str, &subtype))
- goto err;
- } else if (opt_eq(s, len, "blkdev")) {
- if (getuid() != 0) {
- fprintf(stderr, "%s: option blkdev is privileged\n", progname);
- goto err;
- }
- blkdev = 1;
- } else if (opt_eq(s, len, "nonempty")) {
- check_empty = 0;
- } else if (!begins_with(s, "fd=") &&
- !begins_with(s, "rootmode=") &&
- !begins_with(s, "user_id=") &&
- !begins_with(s, "group_id=")) {
- int on;
- int flag;
- int skip_option = 0;
- if (opt_eq(s, len, "large_read")) {
- struct utsname utsname;
- unsigned kmaj, kmin;
- res = uname(&utsname);
- if (res == 0 &&
- sscanf(utsname.release, "%u.%u", &kmaj, &kmin) == 2 &&
- (kmaj > 2 || (kmaj == 2 && kmin > 4))) {
- fprintf(stderr, "%s: note: 'large_read' mount option is deprecated for %i.%i kernels\n", progname, kmaj, kmin);
- skip_option = 1;
- }
- }
- if (getuid() != 0 && !user_allow_other &&
- (opt_eq(s, len, "allow_other") ||
- opt_eq(s, len, "allow_root"))) {
- fprintf(stderr, "%s: option %.*s only allowed if 'user_allow_other' is set in /etc/fuse.conf\n", progname, len, s);
- goto err;
- }
- if (!skip_option) {
- if (find_mount_flag(s, len, &on, &flag)) {
- if (on)
- flags |= flag;
- else
- flags &= ~flag;
- } else {
- memcpy(d, s, len);
- d += len;
- *d++ = ',';
- }
- }
- }
- s += len;
- if (*s)
- s++;
- }
- *d = '\0';
- res = get_mnt_opts(flags, optbuf, &mnt_opts);
- if (res == -1)
- goto err;
-
- sprintf(d, "fd=%i,rootmode=%o,user_id=%i,group_id=%i",
- fd, rootmode, getuid(), getgid());
-
- if (check_empty &&
- fuse_mnt_check_empty(progname, mnt, rootmode, rootsize) == -1)
- goto err;
-
- source = malloc((fsname ? strlen(fsname) : 0) +
- (subtype ? strlen(subtype) : 0) + strlen(dev) + 32);
-
- type = malloc((subtype ? strlen(subtype) : 0) + 32);
- if (!type || !source) {
- fprintf(stderr, "%s: failed to allocate memory\n", progname);
- goto err;
- }
-
- if (subtype)
- sprintf(type, "%s.%s", blkdev ? "fuseblk" : "fuse", subtype);
- else
- strcpy(type, blkdev ? "fuseblk" : "fuse");
-
- if (fsname)
- strcpy(source, fsname);
- else
- strcpy(source, subtype ? subtype : dev);
-
- res = mount(source, mnt, type, flags, optbuf);
- if (res == -1 && errno == ENODEV && subtype) {
- /* Probably missing subtype support */
- strcpy(type, blkdev ? "fuseblk" : "fuse");
- if (fsname) {
- if (!blkdev)
- sprintf(source, "%s#%s", subtype, fsname);
- } else {
- strcpy(source, type);
- }
-
- res = mount(source, mnt, type, flags, optbuf);
- }
- if (res == -1 && errno == EINVAL) {
- /* It could be an old version not supporting group_id */
- sprintf(d, "fd=%i,rootmode=%o,user_id=%i", fd, rootmode, getuid());
- res = mount(source, mnt, type, flags, optbuf);
- }
- if (res == -1) {
- int errno_save = errno;
- if (blkdev && errno == ENODEV && !fuse_mnt_check_fuseblk())
- fprintf(stderr, "%s: 'fuseblk' support missing\n", progname);
- else
- fprintf(stderr, "%s: mount failed: %s\n", progname, strerror(errno_save));
- goto err;
- } else {
- *sourcep = source;
- *typep = type;
- *mnt_optsp = mnt_opts;
- }
- free(optbuf);
-
- return res;
-
- err:
- free(fsname);
- free(subtype);
- free(source);
- free(type);
- free(mnt_opts);
- free(optbuf);
- return -1;
+ int res;
+ int flags = MS_NOSUID | MS_NODEV;
+ char *optbuf;
+ char *mnt_opts = NULL;
+ const char *s;
+ char *d;
+ char *fsname = NULL;
+ char *subtype = NULL;
+ char *source = NULL;
+ char *type = NULL;
+ int check_empty = 1;
+ int blkdev = 0;
+
+ optbuf = (char *) malloc(strlen(opts) + 128);
+ if (!optbuf) {
+ fprintf(stderr, "%s: failed to allocate memory\n", progname);
+ return -1;
+ }
+
+ for (s = opts, d = optbuf; *s;) {
+ unsigned len;
+ const char *fsname_str = "fsname=";
+ const char *subtype_str = "subtype=";
+ for (len = 0; s[len] && s[len] != ','; len++);
+ if (begins_with(s, fsname_str)) {
+ if (!get_string_opt(s, len, fsname_str, &fsname))
+ goto err;
+ } else if (begins_with(s, subtype_str)) {
+ if (!get_string_opt(s, len, subtype_str, &subtype))
+ goto err;
+ } else if (opt_eq(s, len, "blkdev")) {
+ if (getuid() != 0) {
+ fprintf(stderr,
+ "%s: option blkdev is privileged\n",
+ progname);
+ goto err;
+ }
+ blkdev = 1;
+ } else if (opt_eq(s, len, "nonempty")) {
+ check_empty = 0;
+ } else if (!begins_with(s, "fd=") &&
+ !begins_with(s, "rootmode=") &&
+ !begins_with(s, "user_id=") &&
+ !begins_with(s, "group_id=")) {
+ int on;
+ int flag;
+ int skip_option = 0;
+ if (opt_eq(s, len, "large_read")) {
+ struct utsname utsname;
+ unsigned kmaj, kmin;
+ res = uname(&utsname);
+ if (res == 0 &&
+ sscanf(utsname.release, "%u.%u",
+ &kmaj, &kmin) == 2 &&
+ (kmaj > 2 || (kmaj == 2 && kmin > 4))) {
+ fprintf(stderr, "%s: note: 'large_read' mount option is deprecated for %i.%i kernels\n", progname, kmaj, kmin);
+ skip_option = 1;
+ }
+ }
+ if (getuid() != 0 && !user_allow_other &&
+ (opt_eq(s, len, "allow_other") ||
+ opt_eq(s, len, "allow_root"))) {
+ fprintf(stderr, "%s: option %.*s only allowed if 'user_allow_other' is set in /etc/fuse.conf\n", progname, len, s);
+ goto err;
+ }
+ if (!skip_option) {
+ if (find_mount_flag(s, len, &on, &flag)) {
+ if (on)
+ flags |= flag;
+ else
+ flags &= ~flag;
+ } else {
+ memcpy(d, s, len);
+ d += len;
+ *d++ = ',';
+ }
+ }
+ }
+ s += len;
+ if (*s)
+ s++;
+ }
+ *d = '\0';
+ res = get_mnt_opts(flags, optbuf, &mnt_opts);
+ if (res == -1)
+ goto err;
+
+ sprintf(d, "fd=%i,rootmode=%o,user_id=%i,group_id=%i",
+ fd, rootmode, getuid(), getgid());
+
+ if (check_empty &&
+ fuse_mnt_check_empty(progname, mnt, rootmode, rootsize) == -1)
+ goto err;
+
+ source = malloc((fsname ? strlen(fsname) : 0) +
+ (subtype ? strlen(subtype) : 0) + strlen(dev) + 32);
+
+ type = malloc((subtype ? strlen(subtype) : 0) + 32);
+ if (!type || !source) {
+ fprintf(stderr, "%s: failed to allocate memory\n", progname);
+ goto err;
+ }
+
+ if (subtype)
+ sprintf(type, "%s.%s", blkdev ? "fuseblk" : "fuse", subtype);
+ else
+ strcpy(type, blkdev ? "fuseblk" : "fuse");
+
+ if (fsname)
+ strcpy(source, fsname);
+ else
+ strcpy(source, subtype ? subtype : dev);
+
+ res = mount(source, mnt, type, flags, optbuf);
+ if (res == -1 && errno == ENODEV && subtype) {
+ /* Probably missing subtype support */
+ strcpy(type, blkdev ? "fuseblk" : "fuse");
+ if (fsname) {
+ if (!blkdev)
+ sprintf(source, "%s#%s", subtype, fsname);
+ } else {
+ strcpy(source, type);
+ }
+
+ res = mount(source, mnt, type, flags, optbuf);
+ }
+ if (res == -1 && errno == EINVAL) {
+ /* It could be an old version not supporting group_id */
+ sprintf(d, "fd=%i,rootmode=%o,user_id=%i",
+ fd, rootmode, getuid());
+ res = mount(source, mnt, type, flags, optbuf);
+ }
+ if (res == -1) {
+ int errno_save = errno;
+ if (blkdev && errno == ENODEV && !fuse_mnt_check_fuseblk())
+ fprintf(stderr, "%s: 'fuseblk' support missing\n",
+ progname);
+ else
+ fprintf(stderr, "%s: mount failed: %s\n", progname,
+ strerror(errno_save));
+ goto err;
+ } else {
+ *sourcep = source;
+ *typep = type;
+ *mnt_optsp = mnt_opts;
+ }
+ free(optbuf);
+
+ return res;
+
+err:
+ free(fsname);
+ free(subtype);
+ free(source);
+ free(type);
+ free(mnt_opts);
+ free(optbuf);
+ return -1;
}
static int check_version(const char *dev)
{
- int res;
- int majorver;
- int minorver;
- const char *version_file;
- FILE *vf;
-
- if (strcmp(dev, FUSE_DEV_OLD) != 0)
- return 0;
-
- version_file = FUSE_VERSION_FILE_OLD;
- vf = fopen(version_file, "r");
- if (vf == NULL) {
- fprintf(stderr, "%s: kernel interface too old\n", progname);
- return -1;
- }
- res = fscanf(vf, "%i.%i", &majorver, &minorver);
- fclose(vf);
- if (res != 2) {
- fprintf(stderr, "%s: error reading %s\n", progname, version_file);
- return -1;
- }
- if (majorver < 3) {
- fprintf(stderr, "%s: kernel interface too old\n", progname);
- return -1;
- }
- return 0;
+ int res;
+ int majorver;
+ int minorver;
+ const char *version_file;
+ FILE *vf;
+
+ if (strcmp(dev, FUSE_DEV_OLD) != 0)
+ return 0;
+
+ version_file = FUSE_VERSION_FILE_OLD;
+ vf = fopen(version_file, "r");
+ if (vf == NULL) {
+ fprintf(stderr, "%s: kernel interface too old\n", progname);
+ return -1;
+ }
+ res = fscanf(vf, "%i.%i", &majorver, &minorver);
+ fclose(vf);
+ if (res != 2) {
+ fprintf(stderr, "%s: error reading %s\n", progname,
+ version_file);
+ return -1;
+ }
+ if (majorver < 3) {
+ fprintf(stderr, "%s: kernel interface too old\n", progname);
+ return -1;
+ }
+ return 0;
}
static int check_perm(const char **mntp, struct stat *stbuf, int *currdir_fd,
- int *mountpoint_fd)
+ int *mountpoint_fd)
{
- int res;
- const char *mnt = *mntp;
- const char *origmnt = mnt;
-
- res = lstat(mnt, stbuf);
- if (res == -1) {
- fprintf(stderr, "%s: failed to access mountpoint %s: %s\n",
- progname, mnt, strerror(errno));
- return -1;
- }
-
- /* No permission checking is done for root */
- if (getuid() == 0)
- return 0;
-
- if (S_ISDIR(stbuf->st_mode)) {
- *currdir_fd = open(".", O_RDONLY);
- if (*currdir_fd == -1) {
- fprintf(stderr, "%s: failed to open current directory: %s\n",
- progname, strerror(errno));
- return -1;
- }
- res = chdir(mnt);
- if (res == -1) {
- fprintf(stderr, "%s: failed to chdir to mountpoint: %s\n",
- progname, strerror(errno));
- return -1;
- }
- mnt = *mntp = ".";
- res = lstat(mnt, stbuf);
- if (res == -1) {
- fprintf(stderr, "%s: failed to access mountpoint %s: %s\n",
- progname, origmnt, strerror(errno));
- return -1;
- }
-
- if ((stbuf->st_mode & S_ISVTX) && stbuf->st_uid != getuid()) {
- fprintf(stderr, "%s: mountpoint %s not owned by user\n",
- progname, origmnt);
- return -1;
- }
-
- res = access(mnt, W_OK);
- if (res == -1) {
- fprintf(stderr, "%s: user has no write access to mountpoint %s\n",
- progname, origmnt);
- return -1;
- }
- } else if (S_ISREG(stbuf->st_mode)) {
- static char procfile[256];
- *mountpoint_fd = open(mnt, O_WRONLY);
- if (*mountpoint_fd == -1) {
- fprintf(stderr, "%s: failed to open %s: %s\n", progname, mnt,
- strerror(errno));
- return -1;
- }
- res = fstat(*mountpoint_fd, stbuf);
- if (res == -1) {
- fprintf(stderr, "%s: failed to access mountpoint %s: %s\n",
- progname, mnt, strerror(errno));
- return -1;
- }
- if (!S_ISREG(stbuf->st_mode)) {
- fprintf(stderr, "%s: mountpoint %s is no longer a regular file\n",
- progname, mnt);
- return -1;
- }
-
- sprintf(procfile, "/proc/self/fd/%i", *mountpoint_fd);
- *mntp = procfile;
- } else {
- fprintf(stderr,
- "%s: mountpoint %s is not a directory or a regular file\n",
- progname, mnt);
- return -1;
- }
-
-
- return 0;
+ int res;
+ const char *mnt = *mntp;
+ const char *origmnt = mnt;
+
+ res = lstat(mnt, stbuf);
+ if (res == -1) {
+ fprintf(stderr, "%s: failed to access mountpoint %s: %s\n",
+ progname, mnt, strerror(errno));
+ return -1;
+ }
+
+ /* No permission checking is done for root */
+ if (getuid() == 0)
+ return 0;
+
+ if (S_ISDIR(stbuf->st_mode)) {
+ *currdir_fd = open(".", O_RDONLY);
+ if (*currdir_fd == -1) {
+ fprintf(stderr,
+ "%s: failed to open current directory: %s\n",
+ progname, strerror(errno));
+ return -1;
+ }
+ res = chdir(mnt);
+ if (res == -1) {
+ fprintf(stderr,
+ "%s: failed to chdir to mountpoint: %s\n",
+ progname, strerror(errno));
+ return -1;
+ }
+ mnt = *mntp = ".";
+ res = lstat(mnt, stbuf);
+ if (res == -1) {
+ fprintf(stderr,
+ "%s: failed to access mountpoint %s: %s\n",
+ progname, origmnt, strerror(errno));
+ return -1;
+ }
+
+ if ((stbuf->st_mode & S_ISVTX) && stbuf->st_uid != getuid()) {
+ fprintf(stderr, "%s: mountpoint %s not owned by user\n",
+ progname, origmnt);
+ return -1;
+ }
+
+ res = access(mnt, W_OK);
+ if (res == -1) {
+ fprintf(stderr, "%s: user has no write access to mountpoint %s\n",
+ progname, origmnt);
+ return -1;
+ }
+ } else if (S_ISREG(stbuf->st_mode)) {
+ static char procfile[256];
+ *mountpoint_fd = open(mnt, O_WRONLY);
+ if (*mountpoint_fd == -1) {
+ fprintf(stderr, "%s: failed to open %s: %s\n",
+ progname, mnt, strerror(errno));
+ return -1;
+ }
+ res = fstat(*mountpoint_fd, stbuf);
+ if (res == -1) {
+ fprintf(stderr,
+ "%s: failed to access mountpoint %s: %s\n",
+ progname, mnt, strerror(errno));
+ return -1;
+ }
+ if (!S_ISREG(stbuf->st_mode)) {
+ fprintf(stderr,
+ "%s: mountpoint %s is no longer a regular file\n",
+ progname, mnt);
+ return -1;
+ }
+
+ sprintf(procfile, "/proc/self/fd/%i", *mountpoint_fd);
+ *mntp = procfile;
+ } else {
+ fprintf(stderr,
+ "%s: mountpoint %s is not a directory or a regular file\n",
+ progname, mnt);
+ return -1;
+ }
+
+
+ return 0;
}
static int try_open(const char *dev, char **devp, int silent)
{
- int fd = open(dev, O_RDWR);
- if (fd != -1) {
- *devp = strdup(dev);
- if (*devp == NULL) {
- fprintf(stderr, "%s: failed to allocate memory\n", progname);
- close(fd);
- fd = -1;
- }
- } else if (errno == ENODEV ||
- errno == ENOENT) /* check for ENOENT too, for the udev case */
- return -2;
- else if (!silent) {
- fprintf(stderr, "%s: failed to open %s: %s\n", progname, dev,
- strerror(errno));
- }
- return fd;
+ int fd = open(dev, O_RDWR);
+ if (fd != -1) {
+ *devp = strdup(dev);
+ if (*devp == NULL) {
+ fprintf(stderr, "%s: failed to allocate memory\n",
+ progname);
+ close(fd);
+ fd = -1;
+ }
+ } else if (errno == ENODEV ||
+ errno == ENOENT)/* check for ENOENT too, for the udev case */
+ return -2;
+ else if (!silent) {
+ fprintf(stderr, "%s: failed to open %s: %s\n", progname, dev,
+ strerror(errno));
+ }
+ return fd;
}
static int try_open_fuse_device(char **devp)
{
- int fd;
- int err;
+ int fd;
+ int err;
- drop_privs();
- fd = try_open(FUSE_DEV_NEW, devp, 0);
- restore_privs();
- if (fd >= 0)
- return fd;
+ drop_privs();
+ fd = try_open(FUSE_DEV_NEW, devp, 0);
+ restore_privs();
+ if (fd >= 0)
+ return fd;
- err = fd;
- fd = try_open(FUSE_DEV_OLD, devp, 1);
- if (fd >= 0)
- return fd;
+ err = fd;
+ fd = try_open(FUSE_DEV_OLD, devp, 1);
+ if (fd >= 0)
+ return fd;
- return err;
+ return err;
}
static int open_fuse_device(char **devp)
{
- int fd = try_open_fuse_device(devp);
- if (fd >= -1)
- return fd;
+ int fd = try_open_fuse_device(devp);
+ if (fd >= -1)
+ return fd;
- fprintf(stderr, "%s: fuse device not found, try 'modprobe fuse' first\n",
- progname);
+ fprintf(stderr,
+ "%s: fuse device not found, try 'modprobe fuse' first\n",
+ progname);
- return -1;
+ return -1;
}
static int mount_fuse(const char *mnt, const char *opts)
{
- int res;
- int fd;
- char *dev;
- struct stat stbuf;
- char *type = NULL;
- char *source = NULL;
- char *mnt_opts = NULL;
- const char *real_mnt = mnt;
- int currdir_fd = -1;
- int mountpoint_fd = -1;
-
- fd = open_fuse_device(&dev);
- if (fd == -1)
- return -1;
-
- drop_privs();
- read_conf();
-
- if (getuid() != 0 && mount_max != -1) {
- int mount_count = count_fuse_fs();
- if (mount_count >= mount_max) {
- fprintf(stderr, "%s: too many FUSE filesystems mounted; mount_max=N can be set in /etc/fuse.conf\n", progname);
- close(fd);
- return -1;
- }
- }
-
- res = check_version(dev);
- if (res != -1) {
- res = check_perm(&real_mnt, &stbuf, &currdir_fd, &mountpoint_fd);
- restore_privs();
- if (res != -1)
- res = do_mount(real_mnt, &type, stbuf.st_mode & S_IFMT, fd, opts,
- dev, &source, &mnt_opts, stbuf.st_size);
- } else
- restore_privs();
-
- if (currdir_fd != -1) {
- fchdir(currdir_fd);
- close(currdir_fd);
- }
- if (mountpoint_fd != -1)
- close(mountpoint_fd);
-
- if (res == -1) {
- close(fd);
- return -1;
- }
-
- if (geteuid() == 0) {
- res = add_mount(source, mnt, type, mnt_opts);
- if (res == -1) {
- umount2(mnt, 2); /* lazy umount */
- close(fd);
- return -1;
- }
- }
-
- free(source);
- free(type);
- free(mnt_opts);
- free(dev);
-
- return fd;
+ int res;
+ int fd;
+ char *dev;
+ struct stat stbuf;
+ char *type = NULL;
+ char *source = NULL;
+ char *mnt_opts = NULL;
+ const char *real_mnt = mnt;
+ int currdir_fd = -1;
+ int mountpoint_fd = -1;
+
+ fd = open_fuse_device(&dev);
+ if (fd == -1)
+ return -1;
+
+ drop_privs();
+ read_conf();
+
+ if (getuid() != 0 && mount_max != -1) {
+ int mount_count = count_fuse_fs();
+ if (mount_count >= mount_max) {
+ fprintf(stderr, "%s: too many FUSE filesystems mounted; mount_max=N can be set in /etc/fuse.conf\n", progname);
+ close(fd);
+ return -1;
+ }
+ }
+
+ res = check_version(dev);
+ if (res != -1) {
+ res = check_perm(&real_mnt, &stbuf, &currdir_fd,
+ &mountpoint_fd);
+ restore_privs();
+ if (res != -1)
+ res = do_mount(real_mnt, &type, stbuf.st_mode & S_IFMT,
+ fd, opts, dev, &source, &mnt_opts,
+ stbuf.st_size);
+ } else
+ restore_privs();
+
+ if (currdir_fd != -1) {
+ fchdir(currdir_fd);
+ close(currdir_fd);
+ }
+ if (mountpoint_fd != -1)
+ close(mountpoint_fd);
+
+ if (res == -1) {
+ close(fd);
+ return -1;
+ }
+
+ if (geteuid() == 0) {
+ res = add_mount(source, mnt, type, mnt_opts);
+ if (res == -1) {
+ umount2(mnt, 2); /* lazy umount */
+ close(fd);
+ return -1;
+ }
+ }
+
+ free(source);
+ free(type);
+ free(mnt_opts);
+ free(dev);
+
+ return fd;
}
static int send_fd(int sock_fd, int fd)
{
- int retval;
- struct msghdr msg;
- struct cmsghdr *p_cmsg;
- struct iovec vec;
- size_t cmsgbuf[CMSG_SPACE(sizeof(fd)) / sizeof(size_t)];
- int *p_fds;
- char sendchar = 0;
-
- msg.msg_control = cmsgbuf;
- msg.msg_controllen = sizeof(cmsgbuf);
- p_cmsg = CMSG_FIRSTHDR(&msg);
- p_cmsg->cmsg_level = SOL_SOCKET;
- p_cmsg->cmsg_type = SCM_RIGHTS;
- p_cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
- p_fds = (int *) CMSG_DATA(p_cmsg);
- *p_fds = fd;
- msg.msg_controllen = p_cmsg->cmsg_len;
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- msg.msg_iov = &vec;
- msg.msg_iovlen = 1;
- msg.msg_flags = 0;
- /* "To pass file descriptors or credentials you need to send/read at
- * least one byte" (man 7 unix) */
- vec.iov_base = &sendchar;
- vec.iov_len = sizeof(sendchar);
- while ((retval = sendmsg(sock_fd, &msg, 0)) == -1 && errno == EINTR);
- if (retval != 1) {
- perror("sending file descriptor");
- return -1;
- }
- return 0;
+ int retval;
+ struct msghdr msg;
+ struct cmsghdr *p_cmsg;
+ struct iovec vec;
+ size_t cmsgbuf[CMSG_SPACE(sizeof(fd)) / sizeof(size_t)];
+ int *p_fds;
+ char sendchar = 0;
+
+ msg.msg_control = cmsgbuf;
+ msg.msg_controllen = sizeof(cmsgbuf);
+ p_cmsg = CMSG_FIRSTHDR(&msg);
+ p_cmsg->cmsg_level = SOL_SOCKET;
+ p_cmsg->cmsg_type = SCM_RIGHTS;
+ p_cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
+ p_fds = (int *) CMSG_DATA(p_cmsg);
+ *p_fds = fd;
+ msg.msg_controllen = p_cmsg->cmsg_len;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &vec;
+ msg.msg_iovlen = 1;
+ msg.msg_flags = 0;
+ /* "To pass file descriptors or credentials you need to send/read at
+ * least one byte" (man 7 unix) */
+ vec.iov_base = &sendchar;
+ vec.iov_len = sizeof(sendchar);
+ while ((retval = sendmsg(sock_fd, &msg, 0)) == -1 && errno == EINTR);
+ if (retval != 1) {
+ perror("sending file descriptor");
+ return -1;
+ }
+ return 0;
}
static void usage(void)
{
- fprintf(stderr,
- "%s: [options] mountpoint\n"
- "Options:\n"
- " -h print help\n"
- " -V print version\n"
- " -o opt[,opt...] mount options\n"
- " -u unmount\n"
- " -q quiet\n"
- " -z lazy unmount\n",
- progname);
- exit(1);
+ fprintf(stderr,
+ "%s: [options] mountpoint\n"
+ "Options:\n"
+ " -h print help\n"
+ " -V print version\n"
+ " -o opt[,opt...] mount options\n"
+ " -u unmount\n"
+ " -q quiet\n"
+ " -z lazy unmount\n",
+ progname);
+ exit(1);
}
static void show_version(void)
{
- printf("fusermount version: %s\n", PACKAGE_VERSION);
- exit(0);
+ printf("fusermount version: %s\n", PACKAGE_VERSION);
+ exit(0);
}
int main(int argc, char *argv[])
{
- int ch;
- int fd;
- int res;
- char *origmnt;
- char *mnt;
- static int unmount = 0;
- static int lazy = 0;
- static int quiet = 0;
- char *commfd;
- int cfd;
- const char *opts = "";
-
- static const struct option long_opts[] = {
- {"unmount", no_argument, NULL, 'u'},
- {"lazy", no_argument, NULL, 'z'},
- {"quiet", no_argument, NULL, 'q'},
- {"help", no_argument, NULL, 'h'},
- {"version", no_argument, NULL, 'V'},
- {0, 0, 0, 0}};
-
- progname = strdup(argv[0]);
- if (progname == NULL) {
- fprintf(stderr, "%s: failed to allocate memory\n", argv[0]);
- exit(1);
- }
-
- while ((ch = getopt_long(argc, argv, "hVo:uzq", long_opts, NULL)) != -1) {
- switch (ch) {
- case 'h':
- usage();
- break;
-
- case 'V':
- show_version();
- break;
-
- case 'o':
- opts = optarg;
- break;
-
- case 'u':
- unmount = 1;
- break;
-
- case 'z':
- lazy = 1;
- break;
-
- case 'q':
- quiet = 1;
- break;
-
- default:
- exit(1);
- }
- }
-
- if (lazy && !unmount) {
- fprintf(stderr, "%s: -z can only be used with -u\n", progname);
- exit(1);
- }
-
- if (optind >= argc) {
- fprintf(stderr, "%s: missing mountpoint argument\n", progname);
- exit(1);
- }
-
- origmnt = argv[optind];
-
- drop_privs();
- mnt = fuse_mnt_resolve_path(progname, origmnt);
- restore_privs();
- if (mnt == NULL)
- exit(1);
-
- umask(033);
- if (unmount) {
- if (geteuid() == 0)
- res = unmount_fuse(mnt, quiet, lazy);
- else {
- res = umount2(mnt, lazy ? 2 : 0);
- if (res == -1 && !quiet)
- fprintf(stderr, "%s: failed to unmount %s: %s\n", progname,
- mnt, strerror(errno));
- }
- if (res == -1)
- exit(1);
- return 0;
- }
-
- commfd = getenv(FUSE_COMMFD_ENV);
- if (commfd == NULL) {
- fprintf(stderr, "%s: old style mounting not supported\n", progname);
- exit(1);
- }
-
- fd = mount_fuse(mnt, opts);
- if (fd == -1)
- exit(1);
-
- cfd = atoi(commfd);
- res = send_fd(cfd, fd);
- if (res == -1)
- exit(1);
-
- return 0;
+ int ch;
+ int fd;
+ int res;
+ char *origmnt;
+ char *mnt;
+ static int unmount = 0;
+ static int lazy = 0;
+ static int quiet = 0;
+ char *commfd;
+ int cfd;
+ const char *opts = "";
+
+ static const struct option long_opts[] = {
+ {"unmount", no_argument, NULL, 'u'},
+ {"lazy", no_argument, NULL, 'z'},
+ {"quiet", no_argument, NULL, 'q'},
+ {"help", no_argument, NULL, 'h'},
+ {"version", no_argument, NULL, 'V'},
+ {0, 0, 0, 0}};
+
+ progname = strdup(argv[0]);
+ if (progname == NULL) {
+ fprintf(stderr, "%s: failed to allocate memory\n", argv[0]);
+ exit(1);
+ }
+
+ while ((ch = getopt_long(argc, argv, "hVo:uzq", long_opts,
+ NULL)) != -1) {
+ switch (ch) {
+ case 'h':
+ usage();
+ break;
+
+ case 'V':
+ show_version();
+ break;
+
+ case 'o':
+ opts = optarg;
+ break;
+
+ case 'u':
+ unmount = 1;
+ break;
+
+ case 'z':
+ lazy = 1;
+ break;
+
+ case 'q':
+ quiet = 1;
+ break;
+
+ default:
+ exit(1);
+ }
+ }
+
+ if (lazy && !unmount) {
+ fprintf(stderr, "%s: -z can only be used with -u\n", progname);
+ exit(1);
+ }
+
+ if (optind >= argc) {
+ fprintf(stderr, "%s: missing mountpoint argument\n", progname);
+ exit(1);
+ }
+
+ origmnt = argv[optind];
+
+ drop_privs();
+ mnt = fuse_mnt_resolve_path(progname, origmnt);
+ restore_privs();
+ if (mnt == NULL)
+ exit(1);
+
+ umask(033);
+ if (unmount) {
+ if (geteuid() == 0)
+ res = unmount_fuse(mnt, quiet, lazy);
+ else {
+ res = umount2(mnt, lazy ? 2 : 0);
+ if (res == -1 && !quiet)
+ fprintf(stderr,
+ "%s: failed to unmount %s: %s\n",
+ progname, mnt, strerror(errno));
+ }
+ if (res == -1)
+ exit(1);
+ return 0;
+ }
+
+ commfd = getenv(FUSE_COMMFD_ENV);
+ if (commfd == NULL) {
+ fprintf(stderr, "%s: old style mounting not supported\n",
+ progname);
+ exit(1);
+ }
+
+ fd = mount_fuse(mnt, opts);
+ if (fd == -1)
+ exit(1);
+
+ cfd = atoi(commfd);
+ res = send_fd(cfd, fd);
+ if (res == -1)
+ exit(1);
+
+ return 0;
}
diff --git a/util/mount.fuse.c b/util/mount.fuse.c
index 4cc0394..7bd0e83 100644
--- a/util/mount.fuse.c
+++ b/util/mount.fuse.c
@@ -1,3 +1,11 @@
+/*
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
+*/
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -8,184 +16,193 @@ static char *progname;
static char *xstrdup(const char *s)
{
- char *t = strdup(s);
- if (!t) {
- fprintf(stderr, "%s: failed to allocate memory\n", progname);
- exit(1);
- }
- return t;
+ char *t = strdup(s);
+ if (!t) {
+ fprintf(stderr, "%s: failed to allocate memory\n", progname);
+ exit(1);
+ }
+ return t;
}
static void *xrealloc(void *oldptr, size_t size)
{
- void *ptr = realloc(oldptr, size);
- if (!ptr) {
- fprintf(stderr, "%s: failed to allocate memory\n", progname);
- exit(1);
- }
- return ptr;
+ void *ptr = realloc(oldptr, size);
+ if (!ptr) {
+ fprintf(stderr, "%s: failed to allocate memory\n", progname);
+ exit(1);
+ }
+ return ptr;
}
static void add_arg(char **cmdp, const char *opt)
{
- size_t optlen = strlen(opt);
- size_t cmdlen = *cmdp ? strlen(*cmdp) : 0;
- char *cmd = xrealloc(*cmdp, cmdlen + optlen * 4 + 4);
- char *s;
- s = cmd + cmdlen;
- if (*cmdp)
- *s++ = ' ';
-
- *s++ = '\'';
- for (; *opt; opt++) {
- if (*opt == '\'') {
- *s++ = '\'';
- *s++ = '\\';
- *s++ = '\'';
- *s++ = '\'';
- } else
- *s++ = *opt;
- }
- *s++ = '\'';
- *s = '\0';
- *cmdp = cmd;
+ size_t optlen = strlen(opt);
+ size_t cmdlen = *cmdp ? strlen(*cmdp) : 0;
+ char *cmd = xrealloc(*cmdp, cmdlen + optlen * 4 + 4);
+ char *s;
+ s = cmd + cmdlen;
+ if (*cmdp)
+ *s++ = ' ';
+
+ *s++ = '\'';
+ for (; *opt; opt++) {
+ if (*opt == '\'') {
+ *s++ = '\'';
+ *s++ = '\\';
+ *s++ = '\'';
+ *s++ = '\'';
+ } else
+ *s++ = *opt;
+ }
+ *s++ = '\'';
+ *s = '\0';
+ *cmdp = cmd;
}
int main(int argc, char *argv[])
{
- char *type = NULL;
- char *source;
- const char *mountpoint;
- char *basename;
- char *options = NULL;
- char *command = NULL;
- char *setuid = NULL;
- int i;
-
- progname = argv[0];
- basename = strrchr(argv[0], '/');
- if (basename)
- basename++;
- else
- basename = argv[0];
-
- if (strncmp(basename, "mount.fuse.", 11) == 0)
- type = basename + 11;
- if (strncmp(basename, "mount.fuseblk.", 14) == 0)
- type = basename + 14;
-
- if (type && !type[0])
- type = NULL;
-
- if (argc < 3) {
- fprintf(stderr, "usage: %s %s destination [-t type] [-o opt[,opts...]]\n",
- progname, type ? "source" : "type#[source]");
- exit(1);
- }
-
- source = argv[1];
- if (!source[0])
- source = NULL;
-
- mountpoint = argv[2];
-
- for (i = 3; i < argc; i++) {
- if (strcmp(argv[i], "-v") == 0) {
- continue;
- } else if (strcmp(argv[i], "-t") == 0) {
- i++;
-
- if (i == argc) {
- fprintf(stderr,
- "%s: missing argument to option '-t'\n", progname);
- exit(1);
- }
- type = argv[i];
- if (strncmp(type, "fuse.", 5) == 0)
- type += 5;
- else if (strncmp(type, "fuseblk.", 8) == 0)
- type += 8;
-
- if (!type[0]) {
- fprintf(stderr,
- "%s: empty type given as argument to option '-t'\n",
- progname);
- exit(1);
- }
- } else if (strcmp(argv[i], "-o") == 0) {
- char *opts;
- char *opt;
- i++;
- if (i == argc)
- break;
-
- opts = xstrdup(argv[i]);
- opt = strtok(opts, ",");
- while (opt) {
- int j;
- int ignore = 0;
- const char *ignore_opts[] = { "", "user", "nouser", "users",
- "auto", "noauto", "_netdev",
- NULL};
- if (strncmp(opt, "setuid=", 7) == 0) {
- setuid = xstrdup(opt + 7);
- ignore = 1;
- }
- for (j = 0; ignore_opts[j]; j++)
- if (strcmp(opt, ignore_opts[j]) == 0)
- ignore = 1;
-
- if (!ignore) {
- int oldlen = options ? strlen(options) : 0;
- options = xrealloc(options, oldlen + 1 + strlen(opt) + 1);
- if (!oldlen)
- strcpy(options, opt);
- else {
- strcat(options, ",");
- strcat(options, opt);
- }
- }
- opt = strtok(NULL, ",");
- }
- }
- }
-
- if (!type) {
- type = xstrdup(source);
- source = strchr(type, '#');
- if (source)
- *source++ = '\0';
-
- if (!type[0]) {
- fprintf(stderr, "%s: empty filesystem type\n", progname);
- exit(1);
- }
- }
-
- add_arg(&command, type);
- if (source)
- add_arg(&command, source);
- add_arg(&command, mountpoint);
- if (options) {
- add_arg(&command, "-o");
- add_arg(&command, options);
- }
-
- if (setuid && setuid[0]) {
- char *sucommand = command;
- command = NULL;
- add_arg(&command, "su");
- add_arg(&command, "-");
- add_arg(&command, setuid);
- add_arg(&command, "-c");
- add_arg(&command, sucommand);
- } else if (!getenv("HOME")) {
- /* Hack to make filesystems work in the boot environment */
- setenv("HOME", "/root", 0);
- }
-
- execl("/bin/sh", "/bin/sh", "-c", command, NULL);
- fprintf(stderr, "%s: failed to execute /bin/sh: %s\n", progname,
- strerror(errno));
- return 1;
+ char *type = NULL;
+ char *source;
+ const char *mountpoint;
+ char *basename;
+ char *options = NULL;
+ char *command = NULL;
+ char *setuid = NULL;
+ int i;
+
+ progname = argv[0];
+ basename = strrchr(argv[0], '/');
+ if (basename)
+ basename++;
+ else
+ basename = argv[0];
+
+ if (strncmp(basename, "mount.fuse.", 11) == 0)
+ type = basename + 11;
+ if (strncmp(basename, "mount.fuseblk.", 14) == 0)
+ type = basename + 14;
+
+ if (type && !type[0])
+ type = NULL;
+
+ if (argc < 3) {
+ fprintf(stderr,
+ "usage: %s %s destination [-t type] [-o opt[,opts...]]\n",
+ progname, type ? "source" : "type#[source]");
+ exit(1);
+ }
+
+ source = argv[1];
+ if (!source[0])
+ source = NULL;
+
+ mountpoint = argv[2];
+
+ for (i = 3; i < argc; i++) {
+ if (strcmp(argv[i], "-v") == 0) {
+ continue;
+ } else if (strcmp(argv[i], "-t") == 0) {
+ i++;
+
+ if (i == argc) {
+ fprintf(stderr,
+ "%s: missing argument to option '-t'\n",
+ progname);
+ exit(1);
+ }
+ type = argv[i];
+ if (strncmp(type, "fuse.", 5) == 0)
+ type += 5;
+ else if (strncmp(type, "fuseblk.", 8) == 0)
+ type += 8;
+
+ if (!type[0]) {
+ fprintf(stderr,
+ "%s: empty type given as argument to option '-t'\n",
+ progname);
+ exit(1);
+ }
+ } else if (strcmp(argv[i], "-o") == 0) {
+ char *opts;
+ char *opt;
+ i++;
+ if (i == argc)
+ break;
+
+ opts = xstrdup(argv[i]);
+ opt = strtok(opts, ",");
+ while (opt) {
+ int j;
+ int ignore = 0;
+ const char *ignore_opts[] = { "",
+ "user",
+ "nouser",
+ "users",
+ "auto",
+ "noauto",
+ "_netdev",
+ NULL};
+ if (strncmp(opt, "setuid=", 7) == 0) {
+ setuid = xstrdup(opt + 7);
+ ignore = 1;
+ }
+ for (j = 0; ignore_opts[j]; j++)
+ if (strcmp(opt, ignore_opts[j]) == 0)
+ ignore = 1;
+
+ if (!ignore) {
+ int oldlen =
+ options ? strlen(options) : 0;
+ options = xrealloc(options, oldlen + 1 + strlen(opt) + 1);
+ if (!oldlen)
+ strcpy(options, opt);
+ else {
+ strcat(options, ",");
+ strcat(options, opt);
+ }
+ }
+ opt = strtok(NULL, ",");
+ }
+ }
+ }
+
+ if (!type) {
+ type = xstrdup(source);
+ source = strchr(type, '#');
+ if (source)
+ *source++ = '\0';
+
+ if (!type[0]) {
+ fprintf(stderr, "%s: empty filesystem type\n",
+ progname);
+ exit(1);
+ }
+ }
+
+ add_arg(&command, type);
+ if (source)
+ add_arg(&command, source);
+ add_arg(&command, mountpoint);
+ if (options) {
+ add_arg(&command, "-o");
+ add_arg(&command, options);
+ }
+
+ if (setuid && setuid[0]) {
+ char *sucommand = command;
+ command = NULL;
+ add_arg(&command, "su");
+ add_arg(&command, "-");
+ add_arg(&command, setuid);
+ add_arg(&command, "-c");
+ add_arg(&command, sucommand);
+ } else if (!getenv("HOME")) {
+ /* Hack to make filesystems work in the boot environment */
+ setenv("HOME", "/root", 0);
+ }
+
+ execl("/bin/sh", "/bin/sh", "-c", command, NULL);
+ fprintf(stderr, "%s: failed to execute /bin/sh: %s\n", progname,
+ strerror(errno));
+ return 1;
}
diff --git a/util/ulockmgr_server.c b/util/ulockmgr_server.c
index 4f831b0..8ffdfef 100644
--- a/util/ulockmgr_server.c
+++ b/util/ulockmgr_server.c
@@ -1,9 +1,9 @@
/*
- ulockmgr_server: Userspace Lock Manager Server
- Copyright (C) 2006 Miklos Szeredi <miklos@szeredi.hu>
+ ulockmgr_server: Userspace Lock Manager Server
+ Copyright (C) 2006 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU GPL.
- See the file COPYING.
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
*/
/* #define DEBUG 1 */
@@ -23,381 +23,388 @@
#include <sys/wait.h>
struct message {
- unsigned intr : 1;
- unsigned nofd : 1;
- pthread_t thr;
- int cmd;
- int fd;
- struct flock lock;
- int error;
+ unsigned intr : 1;
+ unsigned nofd : 1;
+ pthread_t thr;
+ int cmd;
+ int fd;
+ struct flock lock;
+ int error;
};
struct fd_store {
- struct fd_store *next;
- int fd;
- int origfd;
- int inuse;
+ struct fd_store *next;
+ int fd;
+ int origfd;
+ int inuse;
};
struct owner {
- struct fd_store *fds;
- pthread_mutex_t lock;
+ struct fd_store *fds;
+ pthread_mutex_t lock;
};
struct req_data {
- struct owner *o;
- int cfd;
- struct fd_store *f;
- struct message msg;
+ struct owner *o;
+ int cfd;
+ struct fd_store *f;
+ struct message msg;
};
#define MAX_SEND_FDS 2
static int receive_message(int sock, void *buf, size_t buflen, int *fdp,
- int *numfds)
+ int *numfds)
{
- struct msghdr msg;
- struct iovec iov;
- size_t ccmsg[CMSG_SPACE(sizeof(int) * MAX_SEND_FDS) / sizeof(size_t)];
- struct cmsghdr *cmsg;
- int res;
- int i;
-
- assert(*numfds <= MAX_SEND_FDS);
- iov.iov_base = buf;
- iov.iov_len = buflen;
-
- memset(&msg, 0, sizeof(msg));
- memset(ccmsg, -1, sizeof(ccmsg));
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = ccmsg;
- msg.msg_controllen = sizeof(ccmsg);
-
- res = recvmsg(sock, &msg, MSG_WAITALL);
- if (!res) {
- /* retry on zero return, see do_recv() in ulockmgr.c */
- res = recvmsg(sock, &msg, MSG_WAITALL);
- if (!res)
- return 0;
- }
- if (res == -1) {
- perror("ulockmgr_server: recvmsg");
- return -1;
- }
- if ((size_t) res != buflen) {
- fprintf(stderr, "ulockmgr_server: short message received\n");
- return -1;
- }
-
- cmsg = CMSG_FIRSTHDR(&msg);
- if (cmsg) {
- if (!cmsg->cmsg_type == SCM_RIGHTS) {
- fprintf(stderr, "ulockmgr_server: unknown control message %d\n",
- cmsg->cmsg_type);
- return -1;
- }
- memcpy(fdp, CMSG_DATA(cmsg), sizeof(int) * *numfds);
- if (msg.msg_flags & MSG_CTRUNC) {
- fprintf(stderr, "ulockmgr_server: control message truncated\n");
- for (i = 0; i < *numfds; i++)
- close(fdp[i]);
- *numfds = 0;
- }
- } else {
- if (msg.msg_flags & MSG_CTRUNC) {
- fprintf(stderr, "ulockmgr_server: control message truncated(*)\n");
-
- /* There's a bug in the Linux kernel, that if not all file
- descriptors were allocated, then the cmsg header is not
- filled in */
- cmsg = (struct cmsghdr *) ccmsg;
- memcpy(fdp, CMSG_DATA(cmsg), sizeof(int) * *numfds);
- for (i = 0; i < *numfds; i++)
- close(fdp[i]);
- }
- *numfds = 0;
- }
- return res;
+ struct msghdr msg;
+ struct iovec iov;
+ size_t ccmsg[CMSG_SPACE(sizeof(int) * MAX_SEND_FDS) / sizeof(size_t)];
+ struct cmsghdr *cmsg;
+ int res;
+ int i;
+
+ assert(*numfds <= MAX_SEND_FDS);
+ iov.iov_base = buf;
+ iov.iov_len = buflen;
+
+ memset(&msg, 0, sizeof(msg));
+ memset(ccmsg, -1, sizeof(ccmsg));
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = ccmsg;
+ msg.msg_controllen = sizeof(ccmsg);
+
+ res = recvmsg(sock, &msg, MSG_WAITALL);
+ if (!res) {
+ /* retry on zero return, see do_recv() in ulockmgr.c */
+ res = recvmsg(sock, &msg, MSG_WAITALL);
+ if (!res)
+ return 0;
+ }
+ if (res == -1) {
+ perror("ulockmgr_server: recvmsg");
+ return -1;
+ }
+ if ((size_t) res != buflen) {
+ fprintf(stderr, "ulockmgr_server: short message received\n");
+ return -1;
+ }
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+ if (cmsg) {
+ if (!cmsg->cmsg_type == SCM_RIGHTS) {
+ fprintf(stderr,
+ "ulockmgr_server: unknown control message %d\n",
+ cmsg->cmsg_type);
+ return -1;
+ }
+ memcpy(fdp, CMSG_DATA(cmsg), sizeof(int) * *numfds);
+ if (msg.msg_flags & MSG_CTRUNC) {
+ fprintf(stderr,
+ "ulockmgr_server: control message truncated\n");
+ for (i = 0; i < *numfds; i++)
+ close(fdp[i]);
+ *numfds = 0;
+ }
+ } else {
+ if (msg.msg_flags & MSG_CTRUNC) {
+ fprintf(stderr,
+ "ulockmgr_server: control message truncated(*)\n");
+
+ /* There's a bug in the Linux kernel, that if
+ not all file descriptors were allocated,
+ then the cmsg header is not filled in */
+ cmsg = (struct cmsghdr *) ccmsg;
+ memcpy(fdp, CMSG_DATA(cmsg), sizeof(int) * *numfds);
+ for (i = 0; i < *numfds; i++)
+ close(fdp[i]);
+ }
+ *numfds = 0;
+ }
+ return res;
}
static int closefrom(int minfd)
{
- DIR *dir = opendir("/proc/self/fd");
- if (dir) {
- int dfd = dirfd(dir);
- struct dirent *ent;
- while ((ent = readdir(dir))) {
- char *end;
- int fd = strtol(ent->d_name, &end, 10);
- if (ent->d_name[0] && !end[0] && fd >= minfd && fd != dfd)
- close(fd);
- }
- closedir(dir);
- }
- return 0;
+ DIR *dir = opendir("/proc/self/fd");
+ if (dir) {
+ int dfd = dirfd(dir);
+ struct dirent *ent;
+ while ((ent = readdir(dir))) {
+ char *end;
+ int fd = strtol(ent->d_name, &end, 10);
+ if (ent->d_name[0] && !end[0] && fd >= minfd &&
+ fd != dfd)
+ close(fd);
+ }
+ closedir(dir);
+ }
+ return 0;
}
static void send_reply(int cfd, struct message *msg)
{
- int res = send(cfd, msg, sizeof(struct message), MSG_NOSIGNAL);
- if (res == -1)
- perror("ulockmgr_server: sending reply");
+ int res = send(cfd, msg, sizeof(struct message), MSG_NOSIGNAL);
+ if (res == -1)
+ perror("ulockmgr_server: sending reply");
#ifdef DEBUG
- fprintf(stderr, "ulockmgr_server: error: %i\n", msg->error);
+ fprintf(stderr, "ulockmgr_server: error: %i\n", msg->error);
#endif
}
static void *process_request(void *d_)
{
- struct req_data *d = d_;
- int res;
-
- assert(d->msg.cmd == F_SETLKW);
- res = fcntl(d->f->fd, F_SETLK, &d->msg.lock);
- if (res == -1 && errno == EAGAIN) {
- d->msg.error = EAGAIN;
- d->msg.thr = pthread_self();
- send_reply(d->cfd, &d->msg);
- res = fcntl(d->f->fd, F_SETLKW, &d->msg.lock);
- }
- d->msg.error = (res == -1) ? errno : 0;
- pthread_mutex_lock(&d->o->lock);
- d->f->inuse--;
- pthread_mutex_unlock(&d->o->lock);
- send_reply(d->cfd, &d->msg);
- close(d->cfd);
- free(d);
-
- return NULL;
+ struct req_data *d = d_;
+ int res;
+
+ assert(d->msg.cmd == F_SETLKW);
+ res = fcntl(d->f->fd, F_SETLK, &d->msg.lock);
+ if (res == -1 && errno == EAGAIN) {
+ d->msg.error = EAGAIN;
+ d->msg.thr = pthread_self();
+ send_reply(d->cfd, &d->msg);
+ res = fcntl(d->f->fd, F_SETLKW, &d->msg.lock);
+ }
+ d->msg.error = (res == -1) ? errno : 0;
+ pthread_mutex_lock(&d->o->lock);
+ d->f->inuse--;
+ pthread_mutex_unlock(&d->o->lock);
+ send_reply(d->cfd, &d->msg);
+ close(d->cfd);
+ free(d);
+
+ return NULL;
}
static void process_message(struct owner *o, struct message *msg, int cfd,
- int fd)
+ int fd)
{
- struct fd_store *f = NULL;
- struct fd_store *newf = NULL;
- struct fd_store **fp;
- struct req_data *d;
- pthread_t tid;
- int res;
+ struct fd_store *f = NULL;
+ struct fd_store *newf = NULL;
+ struct fd_store **fp;
+ struct req_data *d;
+ pthread_t tid;
+ int res;
#ifdef DEBUG
- fprintf(stderr, "ulockmgr_server: %i %i %i %lli %lli\n",
- msg->cmd, msg->lock.l_type, msg->lock.l_whence, msg->lock.l_start,
- msg->lock.l_len);
+ fprintf(stderr, "ulockmgr_server: %i %i %i %lli %lli\n",
+ msg->cmd, msg->lock.l_type, msg->lock.l_whence,
+ msg->lock.l_start, msg->lock.l_len);
#endif
- if (msg->cmd == F_SETLK && msg->lock.l_type == F_UNLCK &&
- msg->lock.l_start == 0 && msg->lock.l_len == 0) {
- for (fp = &o->fds; *fp;) {
- f = *fp;
- if (f->origfd == msg->fd && !f->inuse) {
- close(f->fd);
- *fp = f->next;
- free(f);
- } else
- fp = &f->next;
- }
- if (!msg->nofd)
- close(fd);
-
- msg->error = 0;
- send_reply(cfd, msg);
- close(cfd);
- return;
- }
-
- if (msg->nofd) {
- for (fp = &o->fds; *fp; fp = &(*fp)->next) {
- f = *fp;
- if (f->origfd == msg->fd)
- break;
- }
- if (!*fp) {
- fprintf(stderr, "ulockmgr_server: fd %i not found\n", msg->fd);
- msg->error = EIO;
- send_reply(cfd, msg);
- close(cfd);
- return;
- }
- } else {
- newf = f = malloc(sizeof(struct fd_store));
- if (!f) {
- msg->error = ENOLCK;
- send_reply(cfd, msg);
- close(cfd);
- return;
- }
-
- f->fd = fd;
- f->origfd = msg->fd;
- f->inuse = 0;
- }
-
- if (msg->cmd == F_GETLK || msg->cmd == F_SETLK ||
- msg->lock.l_type == F_UNLCK) {
- res = fcntl(f->fd, msg->cmd, &msg->lock);
- msg->error = (res == -1) ? errno : 0;
- send_reply(cfd, msg);
- close(cfd);
- if (newf) {
- newf->next = o->fds;
- o->fds = newf;
- }
- return;
- }
-
- d = malloc(sizeof(struct req_data));
- if (!d) {
- msg->error = ENOLCK;
- send_reply(cfd, msg);
- close(cfd);
- free(newf);
- return;
- }
-
- f->inuse++;
- d->o = o;
- d->cfd = cfd;
- d->f = f;
- d->msg = *msg;
- res = pthread_create(&tid, NULL, process_request, d);
- if (res) {
- msg->error = ENOLCK;
- send_reply(cfd, msg);
- close(cfd);
- free(d);
- f->inuse--;
- free(newf);
- return;
- }
-
- if (newf) {
- newf->next = o->fds;
- o->fds = newf;
- }
- pthread_detach(tid);
+ if (msg->cmd == F_SETLK && msg->lock.l_type == F_UNLCK &&
+ msg->lock.l_start == 0 && msg->lock.l_len == 0) {
+ for (fp = &o->fds; *fp;) {
+ f = *fp;
+ if (f->origfd == msg->fd && !f->inuse) {
+ close(f->fd);
+ *fp = f->next;
+ free(f);
+ } else
+ fp = &f->next;
+ }
+ if (!msg->nofd)
+ close(fd);
+
+ msg->error = 0;
+ send_reply(cfd, msg);
+ close(cfd);
+ return;
+ }
+
+ if (msg->nofd) {
+ for (fp = &o->fds; *fp; fp = &(*fp)->next) {
+ f = *fp;
+ if (f->origfd == msg->fd)
+ break;
+ }
+ if (!*fp) {
+ fprintf(stderr, "ulockmgr_server: fd %i not found\n",
+ msg->fd);
+ msg->error = EIO;
+ send_reply(cfd, msg);
+ close(cfd);
+ return;
+ }
+ } else {
+ newf = f = malloc(sizeof(struct fd_store));
+ if (!f) {
+ msg->error = ENOLCK;
+ send_reply(cfd, msg);
+ close(cfd);
+ return;
+ }
+
+ f->fd = fd;
+ f->origfd = msg->fd;
+ f->inuse = 0;
+ }
+
+ if (msg->cmd == F_GETLK || msg->cmd == F_SETLK ||
+ msg->lock.l_type == F_UNLCK) {
+ res = fcntl(f->fd, msg->cmd, &msg->lock);
+ msg->error = (res == -1) ? errno : 0;
+ send_reply(cfd, msg);
+ close(cfd);
+ if (newf) {
+ newf->next = o->fds;
+ o->fds = newf;
+ }
+ return;
+ }
+
+ d = malloc(sizeof(struct req_data));
+ if (!d) {
+ msg->error = ENOLCK;
+ send_reply(cfd, msg);
+ close(cfd);
+ free(newf);
+ return;
+ }
+
+ f->inuse++;
+ d->o = o;
+ d->cfd = cfd;
+ d->f = f;
+ d->msg = *msg;
+ res = pthread_create(&tid, NULL, process_request, d);
+ if (res) {
+ msg->error = ENOLCK;
+ send_reply(cfd, msg);
+ close(cfd);
+ free(d);
+ f->inuse--;
+ free(newf);
+ return;
+ }
+
+ if (newf) {
+ newf->next = o->fds;
+ o->fds = newf;
+ }
+ pthread_detach(tid);
}
static void sigusr1_handler(int sig)
{
- (void) sig;
- /* Nothing to do */
+ (void) sig;
+ /* Nothing to do */
}
static void process_owner(int cfd)
{
- struct owner o;
- struct sigaction sa;
-
- memset(&sa, 0, sizeof(struct sigaction));
- sa.sa_handler = sigusr1_handler;
- sigemptyset(&sa.sa_mask);
-
- if (sigaction(SIGUSR1, &sa, NULL) == -1) {
- perror("ulockmgr_server: cannot set sigusr1 signal handler");
- exit(1);
- }
-
- memset(&o, 0, sizeof(struct owner));
- pthread_mutex_init(&o.lock, NULL);
- while (1) {
- struct message msg;
- int rfds[2];
- int res;
- int numfds = 2;
-
- res = receive_message(cfd, &msg, sizeof(msg), rfds, &numfds);
- if (!res)
- break;
- if (res == -1)
- exit(1);
-
- if (msg.intr) {
- if (numfds != 0)
- fprintf(stderr, "ulockmgr_server: too many fds for intr\n");
- pthread_kill(msg.thr, SIGUSR1);
- } else {
- if (numfds != 2)
- continue;
-
- pthread_mutex_lock(&o.lock);
- process_message(&o, &msg, rfds[0], rfds[1]);
- pthread_mutex_unlock(&o.lock);
- }
- }
- if (o.fds)
- fprintf(stderr, "ulockmgr_server: open file descriptors on exit\n");
+ struct owner o;
+ struct sigaction sa;
+
+ memset(&sa, 0, sizeof(struct sigaction));
+ sa.sa_handler = sigusr1_handler;
+ sigemptyset(&sa.sa_mask);
+
+ if (sigaction(SIGUSR1, &sa, NULL) == -1) {
+ perror("ulockmgr_server: cannot set sigusr1 signal handler");
+ exit(1);
+ }
+
+ memset(&o, 0, sizeof(struct owner));
+ pthread_mutex_init(&o.lock, NULL);
+ while (1) {
+ struct message msg;
+ int rfds[2];
+ int res;
+ int numfds = 2;
+
+ res = receive_message(cfd, &msg, sizeof(msg), rfds, &numfds);
+ if (!res)
+ break;
+ if (res == -1)
+ exit(1);
+
+ if (msg.intr) {
+ if (numfds != 0)
+ fprintf(stderr,
+ "ulockmgr_server: too many fds for intr\n");
+ pthread_kill(msg.thr, SIGUSR1);
+ } else {
+ if (numfds != 2)
+ continue;
+
+ pthread_mutex_lock(&o.lock);
+ process_message(&o, &msg, rfds[0], rfds[1]);
+ pthread_mutex_unlock(&o.lock);
+ }
+ }
+ if (o.fds)
+ fprintf(stderr,
+ "ulockmgr_server: open file descriptors on exit\n");
}
int main(int argc, char *argv[])
{
- int nullfd;
- char *end;
- int cfd;
- sigset_t empty;
-
- if (argc != 2 || !argv[1][0])
- goto out_inval;
-
- cfd = strtol(argv[1], &end, 10);
- if (*end)
- goto out_inval;
-
- if (daemon(0, 1) == -1) {
- perror("ulockmgr_server: daemon");
- exit(1);
- }
-
- sigemptyset(&empty);
- sigprocmask(SIG_SETMASK, &empty, NULL);
-
- if (dup2(cfd, 4) == -1) {
- perror("ulockmgr_server: dup2");
- exit(1);
- }
- cfd = 4;
- nullfd = open("/dev/null", O_RDWR);
- dup2(nullfd, 0);
- dup2(nullfd, 1);
- close(3);
- closefrom(5);
- while (1) {
- char c;
- int sock;
- int pid;
- int numfds = 1;
- int res = receive_message(cfd, &c, sizeof(c), &sock, &numfds);
- if (!res)
- break;
- if (res == -1)
- exit(1);
- assert(numfds == 1);
-
- pid = fork();
- if (pid == -1) {
- perror("ulockmgr_server: fork");
- close(sock);
- continue;
- }
- if (pid == 0) {
- close(cfd);
- pid = fork();
- if (pid == -1) {
- perror("ulockmgr_server: fork");
- _exit(1);
- }
- if (pid == 0)
- process_owner(sock);
- _exit(0);
- }
- waitpid(pid, NULL, 0);
- close(sock);
- }
- return 0;
-
- out_inval:
- fprintf(stderr, "%s should be started by libulockmgr\n", argv[0]);
- return 1;
+ int nullfd;
+ char *end;
+ int cfd;
+ sigset_t empty;
+
+ if (argc != 2 || !argv[1][0])
+ goto out_inval;
+
+ cfd = strtol(argv[1], &end, 10);
+ if (*end)
+ goto out_inval;
+
+ if (daemon(0, 1) == -1) {
+ perror("ulockmgr_server: daemon");
+ exit(1);
+ }
+
+ sigemptyset(&empty);
+ sigprocmask(SIG_SETMASK, &empty, NULL);
+
+ if (dup2(cfd, 4) == -1) {
+ perror("ulockmgr_server: dup2");
+ exit(1);
+ }
+ cfd = 4;
+ nullfd = open("/dev/null", O_RDWR);
+ dup2(nullfd, 0);
+ dup2(nullfd, 1);
+ close(3);
+ closefrom(5);
+ while (1) {
+ char c;
+ int sock;
+ int pid;
+ int numfds = 1;
+ int res = receive_message(cfd, &c, sizeof(c), &sock, &numfds);
+ if (!res)
+ break;
+ if (res == -1)
+ exit(1);
+ assert(numfds == 1);
+
+ pid = fork();
+ if (pid == -1) {
+ perror("ulockmgr_server: fork");
+ close(sock);
+ continue;
+ }
+ if (pid == 0) {
+ close(cfd);
+ pid = fork();
+ if (pid == -1) {
+ perror("ulockmgr_server: fork");
+ _exit(1);
+ }
+ if (pid == 0)
+ process_owner(sock);
+ _exit(0);
+ }
+ waitpid(pid, NULL, 0);
+ close(sock);
+ }
+ return 0;
+
+out_inval:
+ fprintf(stderr, "%s should be started by libulockmgr\n", argv[0]);
+ return 1;
}