#include <sys/cdefs.h>
#if !defined(lint)
__RCSID("$NetBSD: fs.c,v 1.2 2023/07/14 02:43:50 pho Exp $");
#endif
#include <err.h>
#include <fuse_internal.h>
#include <stdlib.h>
#include <string.h>
#include <sys/dirent.h>
#include <sys/errno.h>
struct fuse_fs {
void* op;
int op_version;
void* user_data;
};
#define UNKNOWN_VERSION(op_version) \
errc(EXIT_FAILURE, ENOSYS, "%s: unknown fuse_operations version: %d", \
__func__, op_version)
static void*
clone_op(const void* op, int op_version) {
void* cloned;
switch (op_version) {
#define CLONE_OP(VER) \
case VER: \
cloned = malloc(sizeof(struct __CONCAT(fuse_operations_v,VER))); \
if (!cloned) \
return NULL; \
memcpy(cloned, op, sizeof(struct __CONCAT(fuse_operations_v,VER))); \
return cloned
CLONE_OP(11);
CLONE_OP(21);
CLONE_OP(22);
CLONE_OP(23);
CLONE_OP(25);
CLONE_OP(26);
CLONE_OP(28);
CLONE_OP(29);
CLONE_OP(30);
CLONE_OP(34);
CLONE_OP(35);
CLONE_OP(38);
#undef CLONE_OP
default:
UNKNOWN_VERSION(op_version);
}
}
struct fuse_fs*
__fuse_fs_new(const void* op, int op_version, void* user_data) {
struct fuse_fs* fs;
fs = malloc(sizeof(struct fuse_fs));
if (!fs)
err(EXIT_FAILURE, __func__);
fs->op = clone_op(op, op_version);
if (!fs->op)
err(EXIT_FAILURE, __func__);
fs->op_version = op_version;
fs->user_data = user_data;
return fs;
}
static void
clobber_context_user_data(struct fuse_fs* fs) {
fuse_get_context()->private_data = fs->user_data;
}
int
fuse_fs_getattr_v27(struct fuse_fs *fs, const char *path, struct stat *buf) {
return fuse_fs_getattr_v30(fs, path, buf, NULL);
}
int
fuse_fs_getattr_v30(struct fuse_fs* fs, const char* path,
struct stat* buf, struct fuse_file_info* fi) {
clobber_context_user_data(fs);
switch (fs->op_version) {
#define CALL_OLD_GETATTR(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->getattr) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->getattr(path, buf); \
else \
return -ENOSYS
CALL_OLD_GETATTR(11);
CALL_OLD_GETATTR(21);
CALL_OLD_GETATTR(22);
CALL_OLD_GETATTR(23);
CALL_OLD_GETATTR(25);
CALL_OLD_GETATTR(26);
CALL_OLD_GETATTR(28);
CALL_OLD_GETATTR(29);
#undef CALL_OLD_GETATTR
#define CALL_GETATTR(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->getattr) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->getattr(path, buf, fi); \
else \
return -ENOSYS
CALL_GETATTR(30);
CALL_GETATTR(34);
CALL_GETATTR(35);
CALL_GETATTR(38);
#undef CALL_GETATTR
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_fgetattr(struct fuse_fs* fs, const char* path, struct stat* buf,
struct fuse_file_info* fi) {
clobber_context_user_data(fs);
switch (fs->op_version) {
case 11:
case 21:
case 22:
case 23:
return fuse_fs_getattr_v30(fs, path, buf, fi);
#define CALL_FGETATTR_OR_OLD_GETATTR(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->fgetattr) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->fgetattr(path, buf, fi); \
else if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->getattr) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->getattr(path, buf); \
else \
return -ENOSYS
CALL_FGETATTR_OR_OLD_GETATTR(25);
CALL_FGETATTR_OR_OLD_GETATTR(26);
CALL_FGETATTR_OR_OLD_GETATTR(28);
CALL_FGETATTR_OR_OLD_GETATTR(29);
#undef CALL_FGETATTR_OR_OLD_GETATTR
case 30:
case 34:
case 35:
case 38:
return fuse_fs_getattr_v30(fs, path, buf, fi);
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_rename_v27(struct fuse_fs* fs, const char* oldpath, const char* newpath) {
return fuse_fs_rename_v30(fs, oldpath, newpath, 0);
}
int
fuse_fs_rename_v30(struct fuse_fs* fs, const char* oldpath,
const char* newpath, unsigned int flags) {
clobber_context_user_data(fs);
switch (fs->op_version) {
#define CALL_OLD_RENAME(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->rename) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->rename(oldpath, newpath); \
else \
return -ENOSYS
CALL_OLD_RENAME(11);
CALL_OLD_RENAME(21);
CALL_OLD_RENAME(22);
CALL_OLD_RENAME(23);
CALL_OLD_RENAME(25);
CALL_OLD_RENAME(26);
CALL_OLD_RENAME(28);
CALL_OLD_RENAME(29);
#undef CALL_OLD_RENAME
#define CALL_RENAME(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->rename) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->rename(oldpath, newpath, flags); \
else \
return -ENOSYS
CALL_RENAME(30);
CALL_RENAME(34);
CALL_RENAME(35);
CALL_RENAME(38);
#undef CALL_RENAME
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_unlink(struct fuse_fs* fs, const char* path) {
clobber_context_user_data(fs);
switch (fs->op_version) {
#define CALL_UNLINK(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->unlink) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->unlink(path); \
else \
return -ENOSYS
CALL_UNLINK(11);
CALL_UNLINK(21);
CALL_UNLINK(22);
CALL_UNLINK(23);
CALL_UNLINK(25);
CALL_UNLINK(26);
CALL_UNLINK(28);
CALL_UNLINK(29);
CALL_UNLINK(30);
CALL_UNLINK(34);
CALL_UNLINK(35);
CALL_UNLINK(38);
#undef CALL_UNLINK
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_rmdir(struct fuse_fs* fs, const char* path) {
clobber_context_user_data(fs);
switch (fs->op_version) {
#define CALL_RMDIR(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->rmdir) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->rmdir(path); \
else \
return -ENOSYS
CALL_RMDIR(11);
CALL_RMDIR(21);
CALL_RMDIR(22);
CALL_RMDIR(23);
CALL_RMDIR(25);
CALL_RMDIR(26);
CALL_RMDIR(28);
CALL_RMDIR(29);
CALL_RMDIR(30);
CALL_RMDIR(34);
CALL_RMDIR(35);
CALL_RMDIR(38);
#undef CALL_RMDIR
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_symlink(struct fuse_fs* fs, const char* linkname, const char* path) {
clobber_context_user_data(fs);
switch (fs->op_version) {
#define CALL_SYMLINK(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->symlink) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->symlink(linkname, path); \
else \
return -ENOSYS
CALL_SYMLINK(11);
CALL_SYMLINK(21);
CALL_SYMLINK(22);
CALL_SYMLINK(23);
CALL_SYMLINK(25);
CALL_SYMLINK(26);
CALL_SYMLINK(28);
CALL_SYMLINK(29);
CALL_SYMLINK(30);
CALL_SYMLINK(34);
CALL_SYMLINK(35);
CALL_SYMLINK(38);
#undef CALL_SYMLINK
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_link(struct fuse_fs* fs, const char* oldpath, const char* newpath) {
clobber_context_user_data(fs);
switch (fs->op_version) {
#define CALL_LINK(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->link) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->link(oldpath, newpath); \
else \
return -ENOSYS
CALL_LINK(11);
CALL_LINK(21);
CALL_LINK(22);
CALL_LINK(23);
CALL_LINK(25);
CALL_LINK(26);
CALL_LINK(28);
CALL_LINK(29);
CALL_LINK(30);
CALL_LINK(34);
CALL_LINK(35);
CALL_LINK(38);
#undef CALL_LINK
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_release(struct fuse_fs* fs, const char* path, struct fuse_file_info* fi) {
clobber_context_user_data(fs);
switch (fs->op_version) {
#define CALL_OLD_RELEASE(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->release) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->release(path, fi->flags); \
else \
return 0
CALL_OLD_RELEASE(11);
CALL_OLD_RELEASE(21);
#undef CALL_OLD_RELEASE
#define CALL_RELEASE(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->release) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->release(path, fi); \
else \
return 0
CALL_RELEASE(22);
CALL_RELEASE(23);
CALL_RELEASE(25);
CALL_RELEASE(26);
CALL_RELEASE(28);
CALL_RELEASE(29);
CALL_RELEASE(30);
CALL_RELEASE(34);
CALL_RELEASE(35);
CALL_RELEASE(38);
#undef CALL_RELEASE
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_open(struct fuse_fs* fs, const char* path, struct fuse_file_info* fi) {
clobber_context_user_data(fs);
switch (fs->op_version) {
#define CALL_OLD_OPEN(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->open) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->open(path, fi->flags); \
else \
return 0
CALL_OLD_OPEN(11);
CALL_OLD_OPEN(21);
#undef CALL_OLD_OPEN
#define CALL_OPEN(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->open) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->open(path, fi); \
else \
return 0
CALL_OPEN(22);
CALL_OPEN(23);
CALL_OPEN(25);
CALL_OPEN(26);
CALL_OPEN(28);
CALL_OPEN(29);
CALL_OPEN(30);
CALL_OPEN(34);
CALL_OPEN(35);
CALL_OPEN(38);
#undef CALL_OPEN
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_read(struct fuse_fs* fs, const char* path, char* buf,
size_t size, off_t off, struct fuse_file_info* fi) {
clobber_context_user_data(fs);
switch (fs->op_version) {
#define CALL_OLD_READ(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->read) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->read(path, buf, size, off); \
else \
return -ENOSYS
CALL_OLD_READ(11);
CALL_OLD_READ(21);
#undef CALL_OLD_READ
#define CALL_READ(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->read) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->read(path, buf, size, off, fi); \
else \
return -ENOSYS
CALL_READ(22);
CALL_READ(23);
CALL_READ(25);
CALL_READ(26);
CALL_READ(28);
CALL_READ(29);
CALL_READ(30);
CALL_READ(34);
CALL_READ(35);
CALL_READ(38);
#undef CALL_READ
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_read_buf(struct fuse_fs* fs, const char* path,
struct fuse_bufvec** bufp, size_t size, off_t off,
struct fuse_file_info* fi) {
clobber_context_user_data(fs);
switch (fs->op_version) {
case 11:
case 21:
case 22:
case 23:
case 25:
case 26:
case 28:
return -ENOSYS;
#define CALL_READ_BUF(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->read_buf) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->read_buf(path, bufp, size, off, fi); \
else \
return -ENOSYS
CALL_READ_BUF(29);
CALL_READ_BUF(30);
CALL_READ_BUF(34);
CALL_READ_BUF(35);
CALL_READ_BUF(38);
#undef CALL_READ_BUF
default:
UNKNOWN_VERSION(fs->op_version);
}
}
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) {
clobber_context_user_data(fs);
switch (fs->op_version) {
#define CALL_OLD_WRITE(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->write) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->write(path, buf, size, off); \
else \
return -ENOSYS
CALL_OLD_WRITE(11);
CALL_OLD_WRITE(21);
#undef CALL_OLD_WRITE
#define CALL_WRITE(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->write) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->write(path, buf, size, off, fi); \
else \
return -ENOSYS
CALL_WRITE(22);
CALL_WRITE(23);
CALL_WRITE(25);
CALL_WRITE(26);
CALL_WRITE(28);
CALL_WRITE(29);
CALL_WRITE(30);
CALL_WRITE(34);
CALL_WRITE(35);
CALL_WRITE(38);
#undef CALL_WRITE
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_write_buf(struct fuse_fs* fs, const char* path,
struct fuse_bufvec* bufp, off_t off,
struct fuse_file_info* fi) {
clobber_context_user_data(fs);
switch (fs->op_version) {
case 11:
case 21:
case 22:
case 23:
case 25:
case 26:
case 28:
return -ENOSYS;
#define CALL_WRITE_BUF(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->write_buf) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->write_buf(path, bufp, off, fi); \
else \
return -ENOSYS
CALL_WRITE_BUF(29);
CALL_WRITE_BUF(30);
CALL_WRITE_BUF(34);
CALL_WRITE_BUF(35);
CALL_WRITE_BUF(38);
#undef CALL_WRITE_BUF
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_fsync(struct fuse_fs* fs, const char* path, int datasync, struct fuse_file_info* fi) {
clobber_context_user_data(fs);
switch (fs->op_version) {
#define CALL_OLD_FSYNC(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->fsync) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->fsync(path, datasync); \
else \
return -ENOSYS
CALL_OLD_FSYNC(11);
CALL_OLD_FSYNC(21);
#undef CALL_OLD_FSYNC
#define CALL_FSYNC(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->fsync) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->fsync(path, datasync, fi); \
else \
return -ENOSYS
CALL_FSYNC(22);
CALL_FSYNC(23);
CALL_FSYNC(25);
CALL_FSYNC(26);
CALL_FSYNC(28);
CALL_FSYNC(29);
CALL_FSYNC(30);
CALL_FSYNC(34);
CALL_FSYNC(35);
CALL_FSYNC(38);
#undef CALL_FSYNC
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_flush(struct fuse_fs* fs, const char* path, struct fuse_file_info* fi) {
clobber_context_user_data(fs);
switch (fs->op_version) {
case 11:
return -ENOSYS;
case 21:
if (((const struct fuse_operations_v21 *)fs->op)->flush)
return ((const struct fuse_operations_v21 *)fs->op)->flush(path);
else
return -ENOSYS;
#define CALL_FLUSH(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->flush) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->flush(path, fi); \
else \
return -ENOSYS
CALL_FLUSH(22);
CALL_FLUSH(23);
CALL_FLUSH(25);
CALL_FLUSH(26);
CALL_FLUSH(28);
CALL_FLUSH(29);
CALL_FLUSH(30);
CALL_FLUSH(34);
CALL_FLUSH(35);
CALL_FLUSH(38);
#undef CALL_FLUSH
default:
UNKNOWN_VERSION(fs->op_version);
}
}
static void
zero_statvfs(struct statvfs* dst) {
dst->f_bsize = 0;
dst->f_frsize = 0;
dst->f_blocks = 0;
dst->f_bfree = 0;
dst->f_bavail = 0;
dst->f_files = 0;
dst->f_ffree = 0;
dst->f_fresvd = 0;
}
static void
fuse_statfs_to_statvfs(struct statvfs* dst, const struct fuse_statfs* src) {
dst->f_bsize = (unsigned long)src->block_size;
dst->f_frsize = (unsigned long)src->block_size;
dst->f_blocks = (fsblkcnt_t)src->blocks;
dst->f_bfree = (fsblkcnt_t)src->blocks_free;
dst->f_bavail = (fsblkcnt_t)src->blocks_free;
dst->f_files = (fsfilcnt_t)src->files;
dst->f_ffree = (fsfilcnt_t)src->files_free;
}
static void
linux_statfs_to_statvfs(struct statvfs* dst, const struct statfs* src) {
dst->f_bsize = (unsigned long)src->f_bsize;
dst->f_frsize = (unsigned long)src->f_bsize;
dst->f_blocks = src->f_blocks;
dst->f_bfree = src->f_bfree;
dst->f_bavail = src->f_bavail;
dst->f_files = src->f_files;
dst->f_ffree = src->f_ffree;
}
int
fuse_fs_statfs(struct fuse_fs* fs, const char* path, struct statvfs* buf) {
clobber_context_user_data(fs);
zero_statvfs(buf);
switch (fs->op_version) {
case 11:
if (((const struct fuse_operations_v11*)fs->op)->statfs) {
struct fuse_statfs statfs_v11;
int ret;
ret = ((const struct fuse_operations_v11*)fs->op)->statfs(path, &statfs_v11);
if (ret == 0)
fuse_statfs_to_statvfs(buf, &statfs_v11);
return ret;
}
else
return 0;
#define CALL_LINUX_STATFS(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->statfs) { \
struct statfs statfs_v22; \
int ret; \
\
ret = ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->statfs(path, &statfs_v22); \
if (ret == 0) \
linux_statfs_to_statvfs(buf, &statfs_v22); \
\
return ret; \
} \
else \
return 0;
CALL_LINUX_STATFS(22);
CALL_LINUX_STATFS(23);
#undef CALL_STATFS
#define CALL_STATFS(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->statfs) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->statfs(path, buf); \
else \
return 0;
CALL_STATFS(25);
CALL_STATFS(26);
CALL_STATFS(28);
CALL_STATFS(29);
CALL_STATFS(30);
CALL_STATFS(34);
CALL_STATFS(35);
CALL_STATFS(38);
#undef CALL_STATFS
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_opendir(struct fuse_fs* fs, const char* path, struct fuse_file_info* fi) {
clobber_context_user_data(fs);
switch (fs->op_version) {
case 11:
case 21:
case 22:
return 0;
#define CALL_OPENDIR(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->opendir) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->opendir(path, fi); \
else \
return 0
CALL_OPENDIR(23);
CALL_OPENDIR(25);
CALL_OPENDIR(26);
CALL_OPENDIR(28);
CALL_OPENDIR(29);
CALL_OPENDIR(30);
CALL_OPENDIR(34);
CALL_OPENDIR(35);
CALL_OPENDIR(38);
#undef CALL_OPENDIR
default:
UNKNOWN_VERSION(fs->op_version);
}
}
struct fuse_fill_dir_v23_shim {
void* dirh;
fuse_fill_dir_t_v23 fill_dir_v23;
};
static mode_t
dt_to_mode(int dt) {
switch (dt) {
case DT_UNKNOWN: return 0;
case DT_FIFO: return S_IFIFO;
case DT_CHR: return S_IFCHR;
case DT_DIR: return S_IFCHR;
case DT_BLK: return S_IFBLK;
case DT_REG: return S_IFREG;
case DT_LNK: return S_IFLNK;
case DT_SOCK: return S_IFSOCK;
case DT_WHT: return S_IFWHT;
default:
errx(EXIT_FAILURE, "%s: unknown dirent type: %d",
__func__, dt);
}
}
static int
fuse_dirfil_v11_to_fill_dir_v23(fuse_dirh_t handle, const char* name, int type) {
struct fuse_fill_dir_v23_shim* shim = handle;
struct stat stbuf;
int res;
memset(&stbuf, 0, sizeof(stbuf));
stbuf.st_mode = dt_to_mode(type);
res = shim->fill_dir_v23(shim->dirh, name, &stbuf, 0);
return res ? -ENOMEM : 0;
}
static int
fuse_dirfil_v22_to_fill_dir_v23(fuse_dirh_t handle, const char* name, int type, ino_t ino) {
struct fuse_fill_dir_v23_shim* shim = handle;
struct stat stbuf;
int res;
memset(&stbuf, 0, sizeof(stbuf));
stbuf.st_mode = dt_to_mode(type);
stbuf.st_ino = ino;
res = shim->fill_dir_v23(shim->dirh, name, &stbuf, 0);
return res ? -ENOMEM : 0;
}
struct fuse_fill_dir_v30_shim {
void* dirh;
fuse_fill_dir_t_v30 fill_dir_v30;
};
static int
fuse_fill_dir_v23_to_v30(void* buf, const char* name,
const struct stat* stat, off_t off) {
struct fuse_fill_dir_v30_shim* shim = buf;
return shim->fill_dir_v30(shim->dirh, name, stat, off, (enum fuse_fill_dir_flags)0);
}
int
fuse_fs_readdir_v27(struct fuse_fs* fs, const char* path, void* buf,
fuse_fill_dir_t_v23 filler, off_t off,
struct fuse_file_info* fi) {
struct fuse_fill_dir_v23_shim v23_shim;
v23_shim.dirh = buf;
v23_shim.fill_dir_v23 = filler;
clobber_context_user_data(fs);
switch (fs->op_version) {
#define CALL_GETDIR_V11(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->getdir) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->getdir(path, &v23_shim, fuse_dirfil_v11_to_fill_dir_v23); \
else \
return -ENOSYS
CALL_GETDIR_V11(11);
CALL_GETDIR_V11(21);
#undef CALL_GETDIR_V11
case 22:
if (((const struct fuse_operations_v22*)fs->op)->getdir)
return ((const struct fuse_operations_v22*)fs->op)->getdir(path, &v23_shim, fuse_dirfil_v22_to_fill_dir_v23);
else
return -ENOSYS;
#define CALL_READDIR_OR_GETDIR(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->readdir) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->readdir(path, buf, filler, off, fi); \
else if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->getdir) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->getdir(path, &v23_shim, fuse_dirfil_v22_to_fill_dir_v23); \
else \
return -ENOSYS
CALL_READDIR_OR_GETDIR(23);
CALL_READDIR_OR_GETDIR(25);
CALL_READDIR_OR_GETDIR(26);
CALL_READDIR_OR_GETDIR(28);
CALL_READDIR_OR_GETDIR(29);
#undef CALL_READDIR_OR_GETDIR
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_readdir_v30(struct fuse_fs* fs, const char* path, void* buf,
fuse_fill_dir_t_v30 filler, off_t off,
struct fuse_file_info* fi, enum fuse_readdir_flags flags) {
clobber_context_user_data(fs);
if (fs->op_version < 30) {
struct fuse_fill_dir_v30_shim v30_shim;
v30_shim.dirh = buf;
v30_shim.fill_dir_v30 = filler;
return fuse_fs_readdir_v27(fs, path, &v30_shim, fuse_fill_dir_v23_to_v30, off, fi);
}
else {
switch (fs->op_version) {
#define CALL_READDIR(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->readdir) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->readdir(path, buf, filler, off, fi, flags); \
else \
return -ENOSYS
CALL_READDIR(30);
CALL_READDIR(34);
CALL_READDIR(35);
CALL_READDIR(38);
#undef CALL_READDIR
default:
UNKNOWN_VERSION(fs->op_version);
}
}
}
int
fuse_fs_fsyncdir(struct fuse_fs* fs, const char* path, int datasync, struct fuse_file_info* fi) {
clobber_context_user_data(fs);
switch (fs->op_version) {
case 11:
case 21:
case 22:
return -ENOSYS;
#define CALL_FSYNCDIR(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->fsyncdir) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->fsyncdir(path, datasync, fi); \
else \
return -ENOSYS
CALL_FSYNCDIR(23);
CALL_FSYNCDIR(25);
CALL_FSYNCDIR(26);
CALL_FSYNCDIR(28);
CALL_FSYNCDIR(29);
CALL_FSYNCDIR(30);
CALL_FSYNCDIR(34);
CALL_FSYNCDIR(35);
CALL_FSYNCDIR(38);
#undef CALL_FSYNCDIR
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_releasedir(struct fuse_fs* fs, const char* path, struct fuse_file_info* fi) {
clobber_context_user_data(fs);
switch (fs->op_version) {
case 11:
case 21:
case 22:
return 0;
#define CALL_RELEASEDIR(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->releasedir) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->releasedir(path, fi); \
else \
return 0
CALL_RELEASEDIR(23);
CALL_RELEASEDIR(25);
CALL_RELEASEDIR(26);
CALL_RELEASEDIR(28);
CALL_RELEASEDIR(29);
CALL_RELEASEDIR(30);
CALL_RELEASEDIR(34);
CALL_RELEASEDIR(35);
CALL_RELEASEDIR(38);
#undef CALL_RELEASEDIR
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_create(struct fuse_fs* fs, const char* path, mode_t mode, struct fuse_file_info* fi) {
clobber_context_user_data(fs);
switch (fs->op_version) {
case 11:
case 21:
case 22:
case 23:
return -ENOSYS;
#define CALL_CREATE(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->create) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->create(path, mode, fi); \
else \
return -ENOSYS
CALL_CREATE(25);
CALL_CREATE(26);
CALL_CREATE(28);
CALL_CREATE(29);
CALL_CREATE(30);
CALL_CREATE(34);
CALL_CREATE(35);
CALL_CREATE(38);
#undef CALL_CREATE
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_lock(struct fuse_fs* fs, const char* path, struct fuse_file_info* fi,
int cmd, struct flock* lock) {
clobber_context_user_data(fs);
switch (fs->op_version) {
case 11:
case 21:
case 22:
case 23:
case 25:
return -ENOSYS;
#define CALL_LOCK(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->lock) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->lock(path, fi, cmd, lock); \
else \
return -ENOSYS
CALL_LOCK(26);
CALL_LOCK(28);
CALL_LOCK(29);
CALL_LOCK(30);
CALL_LOCK(34);
CALL_LOCK(35);
CALL_LOCK(38);
#undef CALL_LOCK
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_flock(struct fuse_fs* fs, const char* path, struct fuse_file_info* fi, int op) {
clobber_context_user_data(fs);
switch (fs->op_version) {
case 11:
case 21:
case 22:
case 23:
case 25:
case 26:
case 28:
return -ENOSYS;
#define CALL_FLOCK(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->flock) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->flock(path, fi, op); \
else \
return -ENOSYS
CALL_FLOCK(29);
CALL_FLOCK(30);
CALL_FLOCK(34);
CALL_FLOCK(35);
CALL_FLOCK(38);
#undef CALL_FLOCK
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_chmod_v27(struct fuse_fs *fs, const char *path, mode_t mode) {
return fuse_fs_chmod_v30(fs, path, mode, NULL);
}
int
fuse_fs_chmod_v30(struct fuse_fs* fs, const char* path,
mode_t mode, struct fuse_file_info* fi) {
clobber_context_user_data(fs);
switch (fs->op_version) {
#define CALL_OLD_CHMOD(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->chmod) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->chmod(path, mode); \
else \
return -ENOSYS
CALL_OLD_CHMOD(11);
CALL_OLD_CHMOD(21);
CALL_OLD_CHMOD(22);
CALL_OLD_CHMOD(23);
CALL_OLD_CHMOD(25);
CALL_OLD_CHMOD(26);
CALL_OLD_CHMOD(28);
CALL_OLD_CHMOD(29);
#undef CALL_OLD_CHMOD
#define CALL_CHMOD(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->chmod) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->chmod(path, mode, fi); \
else \
return -ENOSYS
CALL_CHMOD(30);
CALL_CHMOD(34);
CALL_CHMOD(35);
CALL_CHMOD(38);
#undef CALL_CHMOD
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int fuse_fs_chown_v27(struct fuse_fs *fs, const char *path, uid_t uid, gid_t gid) {
return fuse_fs_chown_v30(fs, path, uid, gid, NULL);
}
int
fuse_fs_chown_v30(struct fuse_fs* fs, const char* path,
uid_t uid, gid_t gid, struct fuse_file_info* fi) {
clobber_context_user_data(fs);
switch (fs->op_version) {
#define CALL_OLD_CHOWN(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->chown) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->chown(path, uid, gid); \
else \
return -ENOSYS
CALL_OLD_CHOWN(11);
CALL_OLD_CHOWN(21);
CALL_OLD_CHOWN(22);
CALL_OLD_CHOWN(23);
CALL_OLD_CHOWN(25);
CALL_OLD_CHOWN(26);
CALL_OLD_CHOWN(28);
CALL_OLD_CHOWN(29);
#undef CALL_OLD_CHOWN
#define CALL_CHOWN(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->chown) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->chown(path, uid, gid, fi); \
else \
return -ENOSYS
CALL_CHOWN(30);
CALL_CHOWN(34);
CALL_CHOWN(35);
CALL_CHOWN(38);
#undef CALL_CHOWN
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int fuse_fs_truncate_v27(struct fuse_fs *fs, const char *path, off_t size) {
return fuse_fs_truncate_v30(fs, path, size, NULL);
}
int
fuse_fs_truncate_v30(struct fuse_fs* fs, const char* path, off_t size, struct fuse_file_info* fi) {
clobber_context_user_data(fs);
switch (fs->op_version) {
#define CALL_OLD_TRUNCATE(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->truncate) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->truncate(path, size); \
else \
return -ENOSYS
CALL_OLD_TRUNCATE(11);
CALL_OLD_TRUNCATE(21);
CALL_OLD_TRUNCATE(22);
CALL_OLD_TRUNCATE(23);
CALL_OLD_TRUNCATE(25);
CALL_OLD_TRUNCATE(26);
CALL_OLD_TRUNCATE(28);
CALL_OLD_TRUNCATE(29);
#undef CALL_OLD_TRUNCATE
#define CALL_TRUNCATE(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->truncate) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->truncate(path, size, fi); \
else \
return -ENOSYS
CALL_TRUNCATE(30);
CALL_TRUNCATE(34);
CALL_TRUNCATE(35);
CALL_TRUNCATE(38);
#undef CALL_TRUNCATE
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_ftruncate(struct fuse_fs* fs, const char* path, off_t size, struct fuse_file_info* fi) {
clobber_context_user_data(fs);
switch (fs->op_version) {
#define CALL_OLD_TRUNCATE(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->truncate) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->truncate(path, size); \
else \
return -ENOSYS
CALL_OLD_TRUNCATE(11);
CALL_OLD_TRUNCATE(21);
CALL_OLD_TRUNCATE(22);
CALL_OLD_TRUNCATE(23);
#undef CALL_OLD_TRUNCATE
#define CALL_FTRUNCATE_OR_TRUNCATE(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->ftruncate) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->ftruncate(path, size, fi); \
else if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->truncate) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->truncate(path, size); \
else \
return -ENOSYS
CALL_FTRUNCATE_OR_TRUNCATE(25);
CALL_FTRUNCATE_OR_TRUNCATE(26);
CALL_FTRUNCATE_OR_TRUNCATE(28);
CALL_FTRUNCATE_OR_TRUNCATE(29);
#undef CALL_FTRUNCATE_OR_TRUNCATE
#define CALL_TRUNCATE(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->truncate) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->truncate(path, size, fi); \
else \
return -ENOSYS
CALL_TRUNCATE(30);
CALL_TRUNCATE(34);
CALL_TRUNCATE(35);
CALL_TRUNCATE(38);
#undef CALL_TRUNCATE
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_utimens_v27(struct fuse_fs *fs, const char *path, const struct timespec tv[2]) {
return fuse_fs_utimens_v30(fs, path, tv, NULL);
}
int
fuse_fs_utimens_v30(struct fuse_fs* fs, const char* path,
const struct timespec tv[2], struct fuse_file_info* fi) {
struct utimbuf timbuf;
timbuf.actime = tv[0].tv_sec;
timbuf.modtime = tv[1].tv_sec;
clobber_context_user_data(fs);
switch (fs->op_version) {
#define CALL_UTIME(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->utime) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->utime(path, &timbuf); \
else \
return -ENOSYS
CALL_UTIME(11);
CALL_UTIME(21);
CALL_UTIME(22);
CALL_UTIME(23);
CALL_UTIME(25);
#undef CALL_UTIME
#define CALL_UTIMENS_OR_UTIME(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->utimens) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->utimens(path, tv); \
else if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->utime) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->utime(path, &timbuf); \
else \
return -ENOSYS
CALL_UTIMENS_OR_UTIME(26);
CALL_UTIMENS_OR_UTIME(28);
CALL_UTIMENS_OR_UTIME(29);
#undef CALL_UTIMENS_OR_UTIME
#define CALL_UTIMENS(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->utimens) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->utimens(path, tv, fi); \
else \
return -ENOSYS
CALL_UTIMENS(30);
CALL_UTIMENS(34);
CALL_UTIMENS(35);
CALL_UTIMENS(38);
#undef CALL_UTIMENS
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_access(struct fuse_fs* fs, const char* path, int mask) {
clobber_context_user_data(fs);
switch (fs->op_version) {
case 11:
case 21:
case 22:
case 23:
return -ENOSYS;
#define CALL_ACCESS(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->access) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->access(path, mask); \
else \
return -ENOSYS
CALL_ACCESS(25);
CALL_ACCESS(26);
CALL_ACCESS(28);
CALL_ACCESS(29);
CALL_ACCESS(30);
CALL_ACCESS(34);
CALL_ACCESS(35);
CALL_ACCESS(38);
#undef CALL_ACCESS
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_readlink(struct fuse_fs* fs, const char* path, char* buf, size_t len) {
clobber_context_user_data(fs);
switch (fs->op_version) {
#define CALL_READLINK(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->readlink) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->readlink(path, buf, len); \
else \
return -ENOSYS
CALL_READLINK(11);
CALL_READLINK(21);
CALL_READLINK(22);
CALL_READLINK(23);
CALL_READLINK(25);
CALL_READLINK(26);
CALL_READLINK(28);
CALL_READLINK(29);
CALL_READLINK(30);
CALL_READLINK(34);
CALL_READLINK(35);
CALL_READLINK(38);
#undef CALL_READLINK
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_mknod(struct fuse_fs* fs, const char* path, mode_t mode, dev_t rdev) {
clobber_context_user_data(fs);
switch (fs->op_version) {
#define CALL_MKNOD(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->mknod) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->mknod(path, mode, rdev); \
else \
return -ENOSYS
CALL_MKNOD(11);
CALL_MKNOD(21);
CALL_MKNOD(22);
CALL_MKNOD(23);
CALL_MKNOD(25);
CALL_MKNOD(26);
CALL_MKNOD(28);
CALL_MKNOD(29);
CALL_MKNOD(30);
CALL_MKNOD(34);
CALL_MKNOD(35);
CALL_MKNOD(38);
#undef CALL_MKNOD
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_mkdir(struct fuse_fs* fs, const char* path, mode_t mode) {
clobber_context_user_data(fs);
switch (fs->op_version) {
#define CALL_MKDIR(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->mkdir) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->mkdir(path, mode); \
else \
return -ENOSYS
CALL_MKDIR(11);
CALL_MKDIR(21);
CALL_MKDIR(22);
CALL_MKDIR(23);
CALL_MKDIR(25);
CALL_MKDIR(26);
CALL_MKDIR(28);
CALL_MKDIR(29);
CALL_MKDIR(30);
CALL_MKDIR(34);
CALL_MKDIR(35);
CALL_MKDIR(38);
#undef CALL_MKDIR
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int fuse_fs_setxattr(struct fuse_fs* fs, const char* path, const char* name,
const char* value, size_t size, int flags) {
clobber_context_user_data(fs);
switch (fs->op_version) {
case 11:
return -ENOSYS;
#define CALL_SETXATTR(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->setxattr) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->setxattr(path, name, value, size, flags); \
else \
return -ENOSYS
CALL_SETXATTR(21);
CALL_SETXATTR(22);
CALL_SETXATTR(23);
CALL_SETXATTR(25);
CALL_SETXATTR(26);
CALL_SETXATTR(28);
CALL_SETXATTR(29);
CALL_SETXATTR(30);
CALL_SETXATTR(34);
CALL_SETXATTR(35);
CALL_SETXATTR(38);
#undef CALL_SETXATTR
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_getxattr(struct fuse_fs* fs, const char* path, const char* name,
char* value, size_t size) {
clobber_context_user_data(fs);
switch (fs->op_version) {
case 11:
return -ENOSYS;
#define CALL_GETXATTR(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->getxattr) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->getxattr(path, name, value, size); \
else \
return -ENOSYS
CALL_GETXATTR(21);
CALL_GETXATTR(22);
CALL_GETXATTR(23);
CALL_GETXATTR(25);
CALL_GETXATTR(26);
CALL_GETXATTR(28);
CALL_GETXATTR(29);
CALL_GETXATTR(30);
CALL_GETXATTR(34);
CALL_GETXATTR(35);
CALL_GETXATTR(38);
#undef CALL_GETXATTR
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int fuse_fs_listxattr(struct fuse_fs* fs, const char* path, char* list, size_t size) {
clobber_context_user_data(fs);
switch (fs->op_version) {
case 11:
return -ENOSYS;
#define CALL_LISTXATTR(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->listxattr) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->listxattr(path, list, size); \
else \
return -ENOSYS
CALL_LISTXATTR(21);
CALL_LISTXATTR(22);
CALL_LISTXATTR(23);
CALL_LISTXATTR(25);
CALL_LISTXATTR(26);
CALL_LISTXATTR(28);
CALL_LISTXATTR(29);
CALL_LISTXATTR(30);
CALL_LISTXATTR(34);
CALL_LISTXATTR(35);
CALL_LISTXATTR(38);
#undef CALL_LISTXATTR
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_removexattr(struct fuse_fs* fs, const char* path, const char* name) {
clobber_context_user_data(fs);
switch (fs->op_version) {
case 11:
return -ENOSYS;
#define CALL_REMOVEXATTR(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->removexattr) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->removexattr(path, name); \
else \
return -ENOSYS
CALL_REMOVEXATTR(21);
CALL_REMOVEXATTR(22);
CALL_REMOVEXATTR(23);
CALL_REMOVEXATTR(25);
CALL_REMOVEXATTR(26);
CALL_REMOVEXATTR(28);
CALL_REMOVEXATTR(29);
CALL_REMOVEXATTR(30);
CALL_REMOVEXATTR(34);
CALL_REMOVEXATTR(35);
CALL_REMOVEXATTR(38);
#undef CALL_REMOVEXATTR
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_bmap(struct fuse_fs* fs, const char* path, size_t blocksize, uint64_t *idx) {
clobber_context_user_data(fs);
switch (fs->op_version) {
case 11:
case 22:
case 23:
case 25:
return -ENOSYS;
#define CALL_BMAP(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->bmap) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->bmap(path, blocksize, idx); \
else \
return -ENOSYS
CALL_BMAP(26);
CALL_BMAP(28);
CALL_BMAP(29);
CALL_BMAP(30);
CALL_BMAP(34);
CALL_BMAP(35);
CALL_BMAP(38);
#undef CALL_BMAP
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int fuse_fs_ioctl_v28(struct fuse_fs* fs, const char* path, int cmd, void* arg,
struct fuse_file_info* fi, unsigned int flags, void* data) {
return fuse_fs_ioctl_v35(fs, path, (unsigned int)cmd, arg, fi, flags, data);
}
int fuse_fs_ioctl_v35(struct fuse_fs* fs, const char* path, unsigned int cmd, void* arg,
struct fuse_file_info* fi, unsigned int flags, void* data) {
clobber_context_user_data(fs);
switch (fs->op_version) {
case 11:
case 22:
case 23:
case 25:
case 26:
return -ENOSYS;
#define CALL_OLD_IOCTL(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->ioctl) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->ioctl(path, (int)cmd, arg, fi, flags, data); \
else \
return -ENOSYS
CALL_OLD_IOCTL(28);
CALL_OLD_IOCTL(29);
CALL_OLD_IOCTL(30);
CALL_OLD_IOCTL(34);
#undef CALL_OLD_IOCTL
#define CALL_IOCTL(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->ioctl) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->ioctl(path, cmd, arg, fi, flags, data); \
else \
return -ENOSYS
CALL_IOCTL(35);
CALL_IOCTL(38);
#undef CALL_IOCTL
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_poll(struct fuse_fs* fs, const char* path, struct fuse_file_info* fi,
struct fuse_pollhandle* ph, unsigned* reventsp) {
clobber_context_user_data(fs);
switch (fs->op_version) {
case 11:
case 22:
case 23:
case 25:
case 26:
return -ENOSYS;
#define CALL_POLL(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->poll) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->poll(path, fi, ph, reventsp); \
else \
return -ENOSYS
CALL_POLL(28);
CALL_POLL(29);
CALL_POLL(30);
CALL_POLL(34);
CALL_POLL(35);
CALL_POLL(38);
#undef CALL_POLL
default:
UNKNOWN_VERSION(fs->op_version);
}
}
int
fuse_fs_fallocate(struct fuse_fs* fs, const char* path, int mode, off_t offset,
off_t length, struct fuse_file_info* fi) {
clobber_context_user_data(fs);
switch (fs->op_version) {
case 11:
case 22:
case 23:
case 25:
case 26:
case 28:
return -ENOSYS;
#define CALL_FALLOCATE(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->fallocate) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->fallocate(path, mode, offset, length, fi); \
else \
return -ENOSYS
CALL_FALLOCATE(29);
CALL_FALLOCATE(30);
CALL_FALLOCATE(34);
CALL_FALLOCATE(35);
CALL_FALLOCATE(38);
#undef CALL_FALLOCATE
default:
UNKNOWN_VERSION(fs->op_version);
}
}
ssize_t
fuse_fs_copy_file_range(struct fuse_fs *fs,
const char *path_in, struct fuse_file_info *fi_in, off_t off_in,
const char *path_out, struct fuse_file_info *fi_out, off_t off_out,
size_t len, int flags) {
clobber_context_user_data(fs);
switch (fs->op_version) {
case 11:
case 22:
case 23:
case 25:
case 26:
case 28:
case 29:
case 30:
return -ENOSYS;
#define CALL_COPY_FILE_RANGE(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->copy_file_range) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->copy_file_range(path_in, fi_in, off_in, path_out, fi_out, off_out, len, flags); \
else \
return -ENOSYS
CALL_COPY_FILE_RANGE(34);
CALL_COPY_FILE_RANGE(35);
CALL_COPY_FILE_RANGE(38);
#undef CALL_COPY_FILE_RANGE
default:
UNKNOWN_VERSION(fs->op_version);
}
}
off_t
fuse_fs_lseek(struct fuse_fs* fs, const char* path, off_t off, int whence,
struct fuse_file_info* fi) {
clobber_context_user_data(fs);
switch (fs->op_version) {
case 11:
case 22:
case 23:
case 25:
case 26:
case 28:
case 29:
case 30:
case 34:
case 35:
return -ENOSYS;
#define CALL_LSEEK(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->lseek) \
return ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->lseek(path, off, whence, fi); \
else \
return -ENOSYS
CALL_LSEEK(38);
#undef CALL_LSEEK
default:
UNKNOWN_VERSION(fs->op_version);
}
}
void
fuse_fs_init_v27(struct fuse_fs *fs, struct fuse_conn_info *conn) {
fuse_fs_init_v30(fs, conn, NULL);
}
void
fuse_fs_init_v30(struct fuse_fs* fs, struct fuse_conn_info* conn,
struct fuse_config* cfg) {
clobber_context_user_data(fs);
switch (fs->op_version) {
case 11:
case 21:
case 22:
break;
#define CALL_NULLARY_INIT(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->init) \
fs->user_data = ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->init(); \
break
CALL_NULLARY_INIT(23);
CALL_NULLARY_INIT(25);
#undef CALL_NULLARY_INIT
#define CALL_UNARY_INIT(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->init) \
fs->user_data = ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->init(conn); \
break
CALL_UNARY_INIT(26);
CALL_UNARY_INIT(28);
CALL_UNARY_INIT(29);
#undef CALL_INIT
#define CALL_BINARY_INIT(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->init) \
fs->user_data = ((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->init(conn, cfg); \
break
CALL_BINARY_INIT(30);
CALL_BINARY_INIT(34);
CALL_BINARY_INIT(35);
CALL_BINARY_INIT(38);
#undef CALL_BINARY_INIT
default:
UNKNOWN_VERSION(fs->op_version);
}
}
void
fuse_fs_destroy(struct fuse_fs *fs) {
clobber_context_user_data(fs);
switch (fs->op_version) {
case 11:
case 21:
case 22:
break;
#define CALL_DESTROY(VER) \
case VER: \
if (((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->destroy) \
((const struct __CONCAT(fuse_operations_v,VER)*)fs->op)->destroy(fs->user_data); \
break
CALL_DESTROY(23);
CALL_DESTROY(25);
CALL_DESTROY(26);
CALL_DESTROY(28);
CALL_DESTROY(29);
CALL_DESTROY(30);
CALL_DESTROY(34);
CALL_DESTROY(35);
CALL_DESTROY(38);
#undef CALL_DESTROY
default:
UNKNOWN_VERSION(fs->op_version);
}
free(fs->op);
free(fs);
}