From 7606430188c3bd4c83f429fa2b0b1f7871b00dea Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Sat, 12 Nov 2022 22:26:26 -0500 Subject: [PATCH] Remove libfuse abstraction in prep for adding request data --- libfuse/include/fuse.h | 102 +- libfuse/include/fuse_kernel.h | 24 +- libfuse/include/fuse_lowlevel.h | 194 ++-- libfuse/include/fuse_pollhandle.h | 14 + libfuse/lib/fuse.c | 1527 +++++++++++++---------------- libfuse/lib/fuse_lowlevel.c | 741 ++++---------- src/mergerfs.cpp | 4 +- 7 files changed, 996 insertions(+), 1610 deletions(-) create mode 100644 libfuse/include/fuse_pollhandle.h diff --git a/libfuse/include/fuse.h b/libfuse/include/fuse.h index 3e6df2e9..29fdfe3b 100644 --- a/libfuse/include/fuse.h +++ b/libfuse/include/fuse.h @@ -475,9 +475,10 @@ struct fuse_operations * * Introduced in version 2.9 */ - int (*write_buf) (const fuse_file_info_t *ffi, - struct fuse_bufvec *buf, - off_t off); + int (*write) (const fuse_file_info_t *ffi, + const char *data, + size_t size, + off_t off); /** Store data from an open file in a buffer * @@ -729,101 +730,6 @@ struct fuse_fs; * fuse_fs_releasedir and fuse_fs_statfs, which return 0. */ -int fuse_fs_getattr(struct fuse_fs *fs, - const char *path, - struct stat *buf, - fuse_timeouts_t *timeout); - -int fuse_fs_fgetattr(struct fuse_fs *fs, - struct stat *buf, - fuse_file_info_t *fi, - fuse_timeouts_t *timeout); - -int fuse_fs_rename(struct fuse_fs *fs, const char *oldpath, - 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, - struct stat *st, - fuse_timeouts_t *timeouts); -int fuse_fs_link(struct fuse_fs *fs, - const char *oldpath, - const char *newpath, - struct stat *st, - fuse_timeouts_t *timeouts); -int fuse_fs_release(struct fuse_fs *fs, - fuse_file_info_t *fi); -int fuse_fs_open(struct fuse_fs *fs, const char *path, - fuse_file_info_t *fi); -int fuse_fs_read_buf(struct fuse_fs *fs, - struct fuse_bufvec **bufp, size_t size, off_t off, - fuse_file_info_t *fi); -int fuse_fs_write_buf(struct fuse_fs *fs, - struct fuse_bufvec *buf, off_t off, - fuse_file_info_t *fi); -int fuse_fs_fsync(struct fuse_fs *fs, int datasync, - fuse_file_info_t *fi); -int fuse_fs_flush(struct fuse_fs *fs, - fuse_file_info_t *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, - fuse_file_info_t *fi); -int fuse_fs_readdir(struct fuse_fs *fs, - fuse_file_info_t *fi, - fuse_dirents_t *buf); -int fuse_fs_fsyncdir(struct fuse_fs *fs, int datasync, - fuse_file_info_t *fi); -int fuse_fs_releasedir(struct fuse_fs *fs, - fuse_file_info_t *fi); -int fuse_fs_create(struct fuse_fs *fs, const char *path, mode_t mode, - fuse_file_info_t *fi); -int fuse_fs_lock(struct fuse_fs *fs, - fuse_file_info_t *fi, int cmd, struct flock *lock); -int fuse_fs_flock(struct fuse_fs *fs, - fuse_file_info_t *fi, int op); -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, off_t size, - fuse_file_info_t *fi); -int fuse_fs_utimens(struct fuse_fs *fs, const char *path, - 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); -int fuse_fs_mknod(struct fuse_fs *fs, const char *path, mode_t mode, - 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); -int fuse_fs_getxattr(struct fuse_fs *fs, const char *path, const char *name, - char *value, size_t size); -int fuse_fs_listxattr(struct fuse_fs *fs, const char *path, char *list, - size_t size); -int fuse_fs_removexattr(struct fuse_fs *fs, const char *path, - const char *name); -int fuse_fs_bmap(struct fuse_fs *fs, const char *path, size_t blocksize, - uint64_t *idx); -int fuse_fs_ioctl(struct fuse_fs *fs, unsigned long cmd, void *arg, - fuse_file_info_t *fi, unsigned int flags, - void *data, uint32_t *out_bufsz); -int fuse_fs_poll(struct fuse_fs *fs, - fuse_file_info_t *fi, fuse_pollhandle_t *ph, - unsigned *reventsp); -int fuse_fs_fallocate(struct fuse_fs *fs, int mode, - off_t offset, off_t length, fuse_file_info_t *fi); -void fuse_fs_init(struct fuse_fs *fs, struct fuse_conn_info *conn); -void fuse_fs_destroy(struct fuse_fs *fs); - -int fuse_fs_prepare_hide(struct fuse_fs *fs, const char *path, uint64_t *fh); -int fuse_fs_free_hide(struct fuse_fs *fs, uint64_t fh); -ssize_t fuse_fs_copy_file_range(struct fuse_fs *fs, - fuse_file_info_t *fi_in, off_t off_in, - fuse_file_info_t *fi_out, off_t off_out, - size_t len, int flags); - int fuse_notify_poll(fuse_pollhandle_t *ph); /** diff --git a/libfuse/include/fuse_kernel.h b/libfuse/include/fuse_kernel.h index 76ee8f9e..1e0495b5 100644 --- a/libfuse/include/fuse_kernel.h +++ b/libfuse/include/fuse_kernel.h @@ -282,18 +282,18 @@ struct fuse_file_lock { /** * Bitmasks for fuse_setattr_in.valid */ -#define FATTR_MODE (1 << 0) -#define FATTR_UID (1 << 1) -#define FATTR_GID (1 << 2) -#define FATTR_SIZE (1 << 3) -#define FATTR_ATIME (1 << 4) -#define FATTR_MTIME (1 << 5) -#define FATTR_FH (1 << 6) -#define FATTR_ATIME_NOW (1 << 7) -#define FATTR_MTIME_NOW (1 << 8) -#define FATTR_LOCKOWNER (1 << 9) -#define FATTR_CTIME (1 << 10) -#define FATTR_KILL_SUIDGID (1 << 11) +#define FATTR_MODE (1 << 0) +#define FATTR_UID (1 << 1) +#define FATTR_GID (1 << 2) +#define FATTR_SIZE (1 << 3) +#define FATTR_ATIME (1 << 4) +#define FATTR_MTIME (1 << 5) +#define FATTR_FH (1 << 6) +#define FATTR_ATIME_NOW (1 << 7) +#define FATTR_MTIME_NOW (1 << 8) +#define FATTR_LOCKOWNER (1 << 9) +#define FATTR_CTIME (1 << 10) +#define FATTR_KILL_SUIDGID (1 << 11) /** * Flags returned by the OPEN request diff --git a/libfuse/include/fuse_lowlevel.h b/libfuse/include/fuse_lowlevel.h index 39347369..e432f759 100644 --- a/libfuse/include/fuse_lowlevel.h +++ b/libfuse/include/fuse_lowlevel.h @@ -25,6 +25,7 @@ #include "extern_c.h" #include "fuse_common.h" +#include "fuse_kernel.h" #include #include @@ -117,12 +118,6 @@ struct fuse_ctx mode_t umask; }; -struct fuse_forget_data -{ - uint64_t ino; - uint64_t nlookup; -}; - /* ----------------------------------------------------------- * * Request methods and replies * * ----------------------------------------------------------- */ @@ -183,7 +178,8 @@ struct fuse_lowlevel_ops * @param parent inode number of the parent directory * @param name the name to look up */ - void (*lookup)(fuse_req_t req, uint64_t parent, const char *name); + void (*lookup)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Forget about an inode @@ -221,7 +217,8 @@ struct fuse_lowlevel_ops * @param ino the inode number * @param nlookup the number of lookups to forget */ - void (*forget)(fuse_req_t req, uint64_t ino, uint64_t nlookup); + void (*forget)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Get file attributes @@ -229,12 +226,9 @@ struct fuse_lowlevel_ops * 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, uint64_t ino, fuse_file_info_t *fi); + void (*getattr)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Set file attributes @@ -263,8 +257,8 @@ struct fuse_lowlevel_ops * Changed in version 2.5: * file information filled in for ftruncate */ - void (*setattr)(fuse_req_t req, uint64_t ino, struct stat *attr, - int to_set, fuse_file_info_t *fi); + void (*setattr)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Read symbolic link @@ -276,7 +270,8 @@ struct fuse_lowlevel_ops * @param req request handle * @param ino the inode number */ - void (*readlink)(fuse_req_t req, uint64_t ino); + void (*readlink)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Create file node @@ -294,8 +289,8 @@ struct fuse_lowlevel_ops * @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, uint64_t parent, const char *name, - mode_t mode, dev_t rdev); + void (*mknod)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Create a directory @@ -309,8 +304,8 @@ struct fuse_lowlevel_ops * @param name to create * @param mode with which to create the new file */ - void (*mkdir)(fuse_req_t req, uint64_t parent, const char *name, - mode_t mode); + void (*mkdir)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Remove a file @@ -327,7 +322,8 @@ struct fuse_lowlevel_ops * @param parent inode number of the parent directory * @param name to remove */ - void (*unlink)(fuse_req_t req, uint64_t parent, const char *name); + void (*unlink)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Remove a directory @@ -344,7 +340,8 @@ struct fuse_lowlevel_ops * @param parent inode number of the parent directory * @param name to remove */ - void (*rmdir)(fuse_req_t req, uint64_t parent, const char *name); + void (*rmdir)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Create a symbolic link @@ -358,8 +355,8 @@ struct fuse_lowlevel_ops * @param parent inode number of the parent directory * @param name to create */ - void (*symlink)(fuse_req_t req, const char *link, uint64_t parent, - const char *name); + void (*symlink)(fuse_req_t req, + struct fuse_in_header *hdr); /** Rename a file * @@ -378,8 +375,8 @@ struct fuse_lowlevel_ops * @param newparent inode number of the new parent directory * @param newname new name */ - void (*rename)(fuse_req_t req, uint64_t parent, const char *name, - uint64_t newparent, const char *newname); + void (*rename)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Create a hard link @@ -393,8 +390,8 @@ struct fuse_lowlevel_ops * @param newparent inode number of the new parent directory * @param newname new name to create */ - void (*link)(fuse_req_t req, uint64_t ino, uint64_t newparent, - const char *newname); + void (*link)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Open a file @@ -421,8 +418,8 @@ struct fuse_lowlevel_ops * @param ino the inode number * @param fi file information */ - void (*open)(fuse_req_t req, uint64_t ino, - fuse_file_info_t *fi); + void (*open)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Read data @@ -449,8 +446,8 @@ struct fuse_lowlevel_ops * @param off offset to read from * @param fi file information */ - void (*read)(fuse_req_t req, uint64_t ino, size_t size, off_t off, - fuse_file_info_t *fi); + void (*read)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Write data @@ -475,8 +472,8 @@ struct fuse_lowlevel_ops * @param off offset to write to * @param fi file information */ - void (*write)(fuse_req_t req, uint64_t ino, const char *buf, - size_t size, off_t off, fuse_file_info_t *fi); + void (*write)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Flush method @@ -507,8 +504,8 @@ struct fuse_lowlevel_ops * @param ino the inode number * @param fi file information */ - void (*flush)(fuse_req_t req, uint64_t ino, - fuse_file_info_t *fi); + void (*flush)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Release an open file @@ -534,8 +531,8 @@ struct fuse_lowlevel_ops * @param ino the inode number * @param fi file information */ - void (*release)(fuse_req_t req, uint64_t ino, - fuse_file_info_t *fi); + void (*release)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Synchronize file contents @@ -551,8 +548,8 @@ struct fuse_lowlevel_ops * @param datasync flag indicating if only data should be flushed * @param fi file information */ - void (*fsync)(fuse_req_t req, uint64_t ino, int datasync, - fuse_file_info_t *fi); + void (*fsync)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Open a directory @@ -575,8 +572,8 @@ struct fuse_lowlevel_ops * @param ino the inode number * @param fi file information */ - void (*opendir)(fuse_req_t req, uint64_t ino, - fuse_file_info_t *fi); + void (*opendir)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Read directory @@ -599,12 +596,11 @@ struct fuse_lowlevel_ops * @param off offset to continue reading the directory stream * @param fi file information */ - void (*readdir)(fuse_req_t req, uint64_t ino, size_t size, off_t off, - fuse_file_info_t *llffi); + void (*readdir)(fuse_req_t req, + struct fuse_in_header *hdr); - void (*readdir_plus)(fuse_req_t req, uint64_t ino, - size_t size, off_t off, - fuse_file_info_t *ffi); + void (*readdir_plus)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Release an open directory @@ -622,8 +618,8 @@ struct fuse_lowlevel_ops * @param ino the inode number * @param fi file information */ - void (*releasedir)(fuse_req_t req, uint64_t ino, - fuse_file_info_t *fi); + void (*releasedir)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Synchronize directory contents @@ -642,8 +638,8 @@ struct fuse_lowlevel_ops * @param datasync flag indicating if only data should be flushed * @param fi file information */ - void (*fsyncdir)(fuse_req_t req, uint64_t ino, int datasync, - fuse_file_info_t *fi); + void (*fsyncdir)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Get file system statistics @@ -655,7 +651,8 @@ struct fuse_lowlevel_ops * @param req request handle * @param ino the inode number, zero means "undefined" */ - void (*statfs)(fuse_req_t req, uint64_t ino); + void (*statfs)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Set an extended attribute @@ -663,8 +660,8 @@ struct fuse_lowlevel_ops * Valid replies: * fuse_reply_err */ - void (*setxattr)(fuse_req_t req, uint64_t ino, const char *name, - const char *value, size_t size, int flags); + void (*setxattr)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Get an extended attribute @@ -689,8 +686,8 @@ struct fuse_lowlevel_ops * @param name of the extended attribute * @param size maximum size of the value to send */ - void (*getxattr)(fuse_req_t req, uint64_t ino, const char *name, - size_t size); + void (*getxattr)(fuse_req_t req, + struct fuse_in_header *hdr); /** * List extended attribute names @@ -715,7 +712,8 @@ struct fuse_lowlevel_ops * @param ino the inode number * @param size maximum size of the list to send */ - void (*listxattr)(fuse_req_t req, uint64_t ino, size_t size); + void (*listxattr)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Remove an extended attribute @@ -727,7 +725,8 @@ struct fuse_lowlevel_ops * @param ino the inode number * @param name of the extended attribute */ - void (*removexattr)(fuse_req_t req, uint64_t ino, const char *name); + void (*removexattr)(fuse_req_t req, + const struct fuse_in_header *hdr); /** * Check file access permissions @@ -747,7 +746,8 @@ struct fuse_lowlevel_ops * @param ino the inode number * @param mask requested access mode */ - void (*access)(fuse_req_t req, uint64_t ino, int mask); + void (*access)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Create and open a file @@ -782,8 +782,8 @@ struct fuse_lowlevel_ops * @param mode file type and mode with which to create the new file * @param fi file information */ - void (*create)(fuse_req_t req, uint64_t parent, const char *name, - mode_t mode, fuse_file_info_t *fi); + void (*create)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Test for a POSIX file lock @@ -799,9 +799,8 @@ struct fuse_lowlevel_ops * @param fi file information * @param lock the region/type to test */ - void (*getlk)(fuse_req_t req, uint64_t ino, - fuse_file_info_t *fi, struct flock *lock); - + void (*getlk)(fuse_req_t req, + const struct fuse_in_header *hdr); /** * Acquire, modify or release a POSIX file lock * @@ -847,8 +846,8 @@ struct fuse_lowlevel_ops * @param blocksize unit of block index * @param idx block index within file */ - void (*bmap)(fuse_req_t req, uint64_t ino, size_t blocksize, - uint64_t idx); + void (*bmap)(fuse_req_t req, + const struct fuse_in_header *hdr); /** * Ioctl @@ -877,9 +876,8 @@ struct fuse_lowlevel_ops * @param in_bufsz number of fetched bytes * @param out_bufsz maximum size of output data */ - void (*ioctl)(fuse_req_t req, uint64_t ino, unsigned long cmd, void *arg, - fuse_file_info_t *fi, unsigned flags, - const void *in_buf, uint32_t in_bufsz, uint32_t out_bufsz); + void (*ioctl)(fuse_req_t req, + const struct fuse_in_header *hdr); /** * Poll for IO readiness @@ -907,40 +905,8 @@ struct fuse_lowlevel_ops * @param fi file information * @param ph poll handle to be used for notification */ - void (*poll)(fuse_req_t req, - uint64_t ino, - fuse_file_info_t *fi, - fuse_pollhandle_t *ph); - - /** - * Write data made available in a buffer - * - * This is a more generic version of the ->write() method. If - * FUSE_CAP_SPLICE_READ is set in fuse_conn_info.want and the - * kernel supports splicing from the fuse device, then the - * data will be made available in pipe for supporting zero - * copy data transfer. - * - * buf->count is guaranteed to be one (and thus buf->idx is - * always zero). The write_buf handler must ensure that - * bufv->off is correctly updated (reflecting the number of - * bytes read from bufv->buf[0]). - * - * Introduced in version 2.9 - * - * Valid replies: - * fuse_reply_write - * fuse_reply_err - * - * @param req request handle - * @param ino the inode number - * @param bufv buffer containing the data - * @param off offset to write to - * @param fi file information - */ - void (*write_buf)(fuse_req_t req, uint64_t ino, - struct fuse_bufvec *bufv, off_t off, - fuse_file_info_t *fi); + void (*poll)(fuse_req_t req, + const struct fuse_in_header *hdr); /** * Callback function for the retrieve request @@ -974,8 +940,8 @@ struct fuse_lowlevel_ops * * @param req request handle */ - void (*forget_multi)(fuse_req_t req, size_t count, - struct fuse_forget_data *forgets); + void (*forget_multi)(fuse_req_t req, + struct fuse_in_header *hdr); /** * Acquire, modify or release a BSD file lock @@ -1014,8 +980,8 @@ struct fuse_lowlevel_ops * @param mode determines the operation to be performed on the given range, * see fallocate(2) */ - void (*fallocate)(fuse_req_t req, uint64_t ino, int mode, - off_t offset, off_t length, fuse_file_info_t *fi); + void (*fallocate)(fuse_req_t req, + const struct fuse_in_header *hdr); /** * Copy a range of data from one file to another @@ -1053,15 +1019,8 @@ struct fuse_lowlevel_ops * @param len maximum size of the data to copy * @param flags passed along with the copy_file_range() syscall */ - void (*copy_file_range)(fuse_req_t req, - uint64_t ino_in, - off_t off_in, - fuse_file_info_t *fi_in, - uint64_t ino_out, - off_t off_out, - fuse_file_info_t *fi_out, - size_t len, - int flags); + void (*copy_file_range)(fuse_req_t req, + const struct fuse_in_header *hdr); }; /** @@ -1164,7 +1123,8 @@ int fuse_reply_readlink(fuse_req_t req, const char *link); * @param fi file information * @return zero for success, -errno for failure to send reply */ -int fuse_reply_open(fuse_req_t req, const fuse_file_info_t *fi); +int fuse_reply_open(fuse_req_t req, + const fuse_file_info_t *fi); /** * Reply with number of bytes written diff --git a/libfuse/include/fuse_pollhandle.h b/libfuse/include/fuse_pollhandle.h new file mode 100644 index 00000000..76a62610 --- /dev/null +++ b/libfuse/include/fuse_pollhandle.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +struct fuse_chan; +struct fuse_ll; + +typedef struct fuse_pollhandle_t fuse_pollhandle_t; +struct fuse_pollhandle_t +{ + uint64_t kh; + struct fuse_chan *ch; + struct fuse_ll *f; +}; diff --git a/libfuse/lib/fuse.c b/libfuse/lib/fuse.c index cbad1242..511ba14d 100644 --- a/libfuse/lib/fuse.c +++ b/libfuse/lib/fuse.c @@ -22,6 +22,7 @@ #include "fuse_lowlevel.h" #include "fuse_misc.h" #include "fuse_opt.h" +#include "fuse_pollhandle.h" #include #include @@ -53,6 +54,8 @@ #define NODE_TABLE_MIN_SIZE 8192 +#define PARAM(inarg) ((void*)(((char*)(inarg)) + sizeof(*(inarg)))) + static int g_LOG_METRICS = 0; struct fuse_config @@ -231,6 +234,13 @@ filename_free(struct fuse *f_, free(fn_); } +static +void* +fuse_hdr_arg(const struct fuse_in_header *hdr_) +{ + return (void*)&hdr_[1]; +} + static void list_add(struct list_head *new, @@ -397,7 +407,7 @@ free_node(struct fuse *f_, filename_free(f_,node_->name); if(node_->is_hidden) - fuse_fs_free_hide(f_->fs,node_->hidden_fh); + f_->fs->op.free_hide(node_->hidden_fh); free_node_mem(f_,node_); } @@ -1409,104 +1419,6 @@ req_fuse(fuse_req_t req) return (struct fuse*)fuse_req_userdata(req); } -int -fuse_fs_getattr(struct fuse_fs *fs, - const char *path, - struct stat *buf, - fuse_timeouts_t *timeout) -{ - return fs->op.getattr(path,buf,timeout); -} - -int -fuse_fs_fgetattr(struct fuse_fs *fs, - struct stat *buf, - fuse_file_info_t *fi, - fuse_timeouts_t *timeout) -{ - return fs->op.fgetattr(fi,buf,timeout); -} - -int -fuse_fs_rename(struct fuse_fs *fs, - const char *oldpath, - const char *newpath) -{ - return fs->op.rename(oldpath,newpath); -} - -int -fuse_fs_prepare_hide(struct fuse_fs *fs_, - const char *path_, - uint64_t *fh_) -{ - return fs_->op.prepare_hide(path_,fh_); -} - -int -fuse_fs_free_hide(struct fuse_fs *fs_, - uint64_t fh_) -{ - return fs_->op.free_hide(fh_); -} - -int -fuse_fs_unlink(struct fuse_fs *fs, - const char *path) -{ - return fs->op.unlink(path); -} - -int -fuse_fs_rmdir(struct fuse_fs *fs, - const char *path) -{ - return fs->op.rmdir(path); -} - -int -fuse_fs_symlink(struct fuse_fs *fs_, - const char *linkname_, - const char *path_, - struct stat *st_, - fuse_timeouts_t *timeouts_) -{ - return fs_->op.symlink(linkname_,path_,st_,timeouts_); -} - -int -fuse_fs_link(struct fuse_fs *fs, - const char *oldpath, - const char *newpath, - struct stat *st_, - fuse_timeouts_t *timeouts_) -{ - return fs->op.link(oldpath,newpath,st_,timeouts_); -} - -int -fuse_fs_release(struct fuse_fs *fs, - fuse_file_info_t *fi) -{ - return fs->op.release(fi); -} - -int -fuse_fs_opendir(struct fuse_fs *fs, - const char *path, - fuse_file_info_t *fi) -{ - return fs->op.opendir(path,fi); -} - -int -fuse_fs_open(struct fuse_fs *fs, - const char *path, - fuse_file_info_t *fi) -{ - return fs->op.open(path,fi); -} - static void fuse_free_buf(struct fuse_bufvec *buf) @@ -1521,290 +1433,6 @@ fuse_free_buf(struct fuse_bufvec *buf) } } -int -fuse_fs_read_buf(struct fuse_fs *fs, - struct fuse_bufvec **bufp, - size_t size, - off_t off, - fuse_file_info_t *fi) -{ - int res; - - res = fs->op.read_buf(fi,bufp,size,off); - if(res < 0) - return res; - - return 0; -} - -int -fuse_fs_write_buf(struct fuse_fs *fs, - struct fuse_bufvec *buf, - off_t off, - fuse_file_info_t *fi) -{ - return fs->op.write_buf(fi,buf,off); -} - -int -fuse_fs_fsync(struct fuse_fs *fs, - int datasync, - fuse_file_info_t *fi) -{ - return fs->op.fsync(fi,datasync); -} - -int -fuse_fs_fsyncdir(struct fuse_fs *fs, - int datasync, - fuse_file_info_t *fi) -{ - return fs->op.fsyncdir(fi,datasync); -} - -int -fuse_fs_flush(struct fuse_fs *fs, - fuse_file_info_t *fi) -{ - return fs->op.flush(fi); -} - -int -fuse_fs_statfs(struct fuse_fs *fs, - const char *path, - struct statvfs *buf) -{ - return fs->op.statfs(path,buf); -} - -int -fuse_fs_releasedir(struct fuse_fs *fs, - fuse_file_info_t *fi) -{ - return fs->op.releasedir(fi); -} - -int -fuse_fs_readdir(struct fuse_fs *fs, - fuse_file_info_t *fi, - fuse_dirents_t *buf) -{ - return fs->op.readdir(fi,buf); -} - -int -fuse_fs_readdir_plus(struct fuse_fs *fs_, - fuse_file_info_t *ffi_, - fuse_dirents_t *buf_) -{ - return fs_->op.readdir_plus(ffi_,buf_); -} - -int -fuse_fs_create(struct fuse_fs *fs, - const char *path, - mode_t mode, - fuse_file_info_t *fi) -{ - return fs->op.create(path,mode,fi); -} - -int -fuse_fs_lock(struct fuse_fs *fs, - fuse_file_info_t *fi, - int cmd, - struct flock *lock) -{ - return fs->op.lock(fi,cmd,lock); -} - -int -fuse_fs_flock(struct fuse_fs *fs, - fuse_file_info_t *fi, - int op) -{ - return fs->op.flock(fi,op); -} - -int -fuse_fs_chown(struct fuse_fs *fs, - const char *path, - uid_t uid, - gid_t gid) -{ - return fs->op.chown(path,uid,gid); -} - -int -fuse_fs_fchown(struct fuse_fs *fs_, - const fuse_file_info_t *ffi_, - const uid_t uid_, - const gid_t gid_) -{ - return fs_->op.fchown(ffi_,uid_,gid_); -} - -int -fuse_fs_truncate(struct fuse_fs *fs, - const char *path, - off_t size) -{ - return fs->op.truncate(path,size); -} - -int -fuse_fs_ftruncate(struct fuse_fs *fs, - off_t size, - fuse_file_info_t *fi) -{ - return fs->op.ftruncate(fi,size); -} - -int -fuse_fs_utimens(struct fuse_fs *fs, - const char *path, - const struct timespec tv[2]) -{ - return fs->op.utimens(path,tv); -} - -int -fuse_fs_futimens(struct fuse_fs *fs_, - const fuse_file_info_t *ffi_, - const struct timespec tv_[2]) -{ - return fs_->op.futimens(ffi_,tv_); -} - -int -fuse_fs_access(struct fuse_fs *fs, - const char *path, - int mask) -{ - return fs->op.access(path,mask); -} - -int -fuse_fs_readlink(struct fuse_fs *fs, - const char *path, - char *buf, - size_t len) -{ - return fs->op.readlink(path,buf,len); -} - -int -fuse_fs_mknod(struct fuse_fs *fs, - const char *path, - mode_t mode, - dev_t rdev) -{ - return fs->op.mknod(path,mode,rdev); -} - -int -fuse_fs_mkdir(struct fuse_fs *fs, - const char *path, - mode_t mode) -{ - return fs->op.mkdir(path,mode); -} - -int -fuse_fs_setxattr(struct fuse_fs *fs, - const char *path, - const char *name, - const char *value, - size_t size, - int flags) -{ - return fs->op.setxattr(path,name,value,size,flags); -} - -int -fuse_fs_getxattr(struct fuse_fs *fs, - const char *path, - const char *name, - char *value, - size_t size) -{ - return fs->op.getxattr(path,name,value,size); -} - -int -fuse_fs_listxattr(struct fuse_fs *fs, - const char *path, - char *list, - size_t size) -{ - return fs->op.listxattr(path,list,size); -} - -int -fuse_fs_bmap(struct fuse_fs *fs, - const char *path, - size_t blocksize, - uint64_t *idx) -{ - return fs->op.bmap(path,blocksize,idx); -} - -int -fuse_fs_removexattr(struct fuse_fs *fs, - const char *path, - const char *name) -{ - return fs->op.removexattr(path,name); -} - -int -fuse_fs_ioctl(struct fuse_fs *fs, - unsigned long cmd, - void *arg, - fuse_file_info_t *fi, - unsigned int flags, - void *data, - uint32_t *out_size) -{ - return fs->op.ioctl(fi,cmd,arg,flags,data,out_size); -} - -int -fuse_fs_poll(struct fuse_fs *fs, - fuse_file_info_t *fi, - fuse_pollhandle_t *ph, - unsigned *reventsp) -{ - return fs->op.poll(fi,ph,reventsp); -} - -int -fuse_fs_fallocate(struct fuse_fs *fs, - int mode, - off_t offset, - off_t length, - fuse_file_info_t *fi) -{ - return fs->op.fallocate(fi,mode,offset,length); -} - -ssize_t -fuse_fs_copy_file_range(struct fuse_fs *fs_, - fuse_file_info_t *ffi_in_, - off_t off_in_, - fuse_file_info_t *ffi_out_, - off_t off_out_, - size_t len_, - int flags_) -{ - return fs_->op.copy_file_range(ffi_in_, - off_in_, - ffi_out_, - off_out_, - len_, - flags_); -} - static int node_open(const struct node *node_) @@ -1866,8 +1494,8 @@ lookup_path(struct fuse *f, memset(e,0,sizeof(struct fuse_entry_param)); rv = ((fi == NULL) ? - fuse_fs_getattr(f->fs,path,&e->attr,&e->timeout) : - fuse_fs_fgetattr(f->fs,&e->attr,fi,&e->timeout)); + f->fs->op.getattr(path,&e->attr,&e->timeout) : + f->fs->op.fgetattr(fi,&e->attr,&e->timeout)); if(rv) return rv; @@ -1989,13 +1617,6 @@ reply_entry(fuse_req_t req, } } -void -fuse_fs_init(struct fuse_fs *fs, - struct fuse_conn_info *conn) -{ - fs->op.init(conn); -} - static void fuse_lib_init(void *data, @@ -2007,15 +1628,7 @@ fuse_lib_init(void *data, memset(c,0,sizeof(*c)); c->ctx.fuse = f; conn->want |= FUSE_CAP_EXPORT_SUPPORT; - fuse_fs_init(f->fs,conn); -} - -void -fuse_fs_destroy(struct fuse_fs *fs) -{ - if(fs->op.destroy) - fs->op.destroy(); - free(fs); + f->fs->op.init(conn); } static @@ -2027,29 +1640,35 @@ fuse_lib_destroy(void *data) memset(c,0,sizeof(*c)); c->ctx.fuse = f; - fuse_fs_destroy(f->fs); + f->fs->op.destroy(); + free(f->fs); f->fs = NULL; } static void -fuse_lib_lookup(fuse_req_t req, - uint64_t parent, - const char *name) +fuse_lib_lookup(fuse_req_t req, + struct fuse_in_header *hdr_) { int err; + uint64_t nodeid; char *path; + const char *name; + struct fuse *f; struct node *dot = NULL; - struct fuse *f = req_fuse_prepare(req); struct fuse_entry_param e = {0}; + name = fuse_hdr_arg(hdr_); + nodeid = hdr_->nodeid; + f = req_fuse_prepare(req); + if(name[0] == '.') { if(name[1] == '\0') { name = NULL; pthread_mutex_lock(&f->lock); - dot = get_node_nocheck(f,parent); + dot = get_node_nocheck(f,nodeid); if(dot == NULL) { pthread_mutex_unlock(&f->lock); @@ -2061,7 +1680,7 @@ fuse_lib_lookup(fuse_req_t req, } else if((name[1] == '.') && (name[2] == '\0')) { - if(parent == 1) + if(nodeid == 1) { reply_entry(req,&e,-ENOENT); return; @@ -2069,21 +1688,21 @@ fuse_lib_lookup(fuse_req_t req, name = NULL; pthread_mutex_lock(&f->lock); - parent = get_node(f,parent)->parent->nodeid; + nodeid = get_node(f,nodeid)->parent->nodeid; pthread_mutex_unlock(&f->lock); } } - err = get_path_name(f,parent,name,&path); + err = get_path_name(f,nodeid,name,&path); if(!err) { - err = lookup_path(f,parent,name,path,&e,NULL); + err = lookup_path(f,nodeid,name,path,&e,NULL); if(err == -ENOENT) { e.ino = 0; err = 0; } - free_path(f,parent,path); + free_path(f,nodeid,path); } if(dot) @@ -2098,34 +1717,43 @@ fuse_lib_lookup(fuse_req_t req, static void -do_forget(struct fuse *f, - const uint64_t ino, - const uint64_t nlookup) +do_forget(struct fuse *f, + const uint64_t nodeid, + const uint64_t nlookup) { - forget_node(f,ino,nlookup); + forget_node(f,nodeid,nlookup); } static void -fuse_lib_forget(fuse_req_t req, - const uint64_t ino, - const uint64_t nlookup) +fuse_lib_forget(fuse_req_t req, + struct fuse_in_header *hdr_) { - do_forget(req_fuse(req),ino,nlookup); + struct fuse *f; + struct fuse_forget_in *arg; + + f = req_fuse(req); + arg = fuse_hdr_arg(hdr_); + + do_forget(f,hdr_->nodeid,arg->nlookup); fuse_reply_none(req); } static void -fuse_lib_forget_multi(fuse_req_t req, - size_t count, - struct fuse_forget_data *forgets) +fuse_lib_forget_multi(fuse_req_t req, + struct fuse_in_header *hdr_) { - struct fuse *f = req_fuse(req); - size_t i; + struct fuse *f; + struct fuse_batch_forget_in *arg; + struct fuse_forget_one *entry; + + f = req_fuse(req); + arg = fuse_hdr_arg(hdr_); + entry = PARAM(arg); - for(i = 0; i < count; i++) - do_forget(f,forgets[i].ino,forgets[i].nlookup); + for(uint32_t i = 0; i < arg->count; i++) + do_forget(f,entry[i].nodeid,entry[i].nlookup); fuse_reply_none(req); } @@ -2133,11 +1761,9 @@ fuse_lib_forget_multi(fuse_req_t req, static void -fuse_lib_getattr(fuse_req_t req, - uint64_t ino, - fuse_file_info_t *fi) +fuse_lib_getattr(fuse_req_t req, + struct fuse_in_header *hdr_) { - int err; char *path; struct fuse *f; @@ -2145,17 +1771,21 @@ fuse_lib_getattr(fuse_req_t req, struct node *node; fuse_timeouts_t timeout; fuse_file_info_t ffi = {0}; + const struct fuse_getattr_in *arg; - f = req_fuse_prepare(req); - if(fi == NULL) + arg = fuse_hdr_arg(hdr_); + f = req_fuse_prepare(req); + + if(arg->getattr_flags & FUSE_GETATTR_FH) + { + ffi.fh = arg->fh; + } + else { pthread_mutex_lock(&f->lock); - node = get_node(f,ino); + node = get_node(f,hdr_->nodeid); if(node->is_hidden) - { - fi = &ffi; - fi->fh = node->hidden_fh; - } + ffi.fh = node->hidden_fh; pthread_mutex_unlock(&f->lock); } @@ -2163,25 +1793,25 @@ fuse_lib_getattr(fuse_req_t req, err = 0; path = NULL; - if(fi == NULL) - err = get_path(f,ino,&path); + if(ffi.fh == 0) + err = get_path(f,hdr_->nodeid,&path); if(!err) { - err = ((fi == NULL) ? - fuse_fs_getattr(f->fs,path,&buf,&timeout) : - fuse_fs_fgetattr(f->fs,&buf,fi,&timeout)); + err = ((ffi.fh == 0) ? + f->fs->op.getattr(path,&buf,&timeout) : + f->fs->op.fgetattr(&ffi,&buf,&timeout)); - free_path(f,ino,path); + free_path(f,hdr_->nodeid,path); } if(!err) { pthread_mutex_lock(&f->lock); - node = get_node(f,ino); + node = get_node(f,hdr_->nodeid); update_stat(node,&buf); pthread_mutex_unlock(&f->lock); - set_stat(f,ino,&buf); + set_stat(f,hdr_->nodeid,&buf); fuse_reply_attr(req,&buf,timeout.attr); } else @@ -2190,42 +1820,33 @@ fuse_lib_getattr(fuse_req_t req, } } -int -fuse_fs_chmod(struct fuse_fs *fs, - const char *path, - mode_t mode) -{ - return fs->op.chmod(path,mode); -} - -int -fuse_fs_fchmod(struct fuse_fs *fs_, - const fuse_file_info_t *ffi_, - const mode_t mode_) -{ - return fs_->op.fchmod(ffi_,mode_); -} - static void -fuse_lib_setattr(fuse_req_t req, - uint64_t ino, - struct stat *attr, - int valid, - fuse_file_info_t *fi) +fuse_lib_setattr(fuse_req_t req, + struct fuse_in_header *hdr_) { struct fuse *f = req_fuse_prepare(req); - struct stat buf; + struct stat stbuf = {0}; char *path; int err; struct node *node; fuse_timeouts_t timeout; + fuse_file_info_t *fi; fuse_file_info_t ffi = {0}; + struct fuse_setattr_in *arg; - if(fi == NULL) + arg = fuse_hdr_arg(hdr_); + + fi = NULL; + if(arg->valid & FATTR_FH) + { + fi = &ffi; + fi->fh = arg->fh; + } + else { pthread_mutex_lock(&f->lock); - node = get_node(f,ino); + node = get_node(f,hdr_->nodeid); if(node->is_hidden) { fi = &ffi; @@ -2234,38 +1855,36 @@ fuse_lib_setattr(fuse_req_t req, pthread_mutex_unlock(&f->lock); } - memset(&buf,0,sizeof(buf)); - err = 0; path = NULL; if(fi == NULL) - err = get_path(f,ino,&path); + err = get_path(f,hdr_->nodeid,&path); if(!err) { err = 0; - if(!err && (valid & FATTR_MODE)) + if(!err && (arg->valid & FATTR_MODE)) err = ((fi == NULL) ? - fuse_fs_chmod(f->fs,path,attr->st_mode) : - fuse_fs_fchmod(f->fs,fi,attr->st_mode)); + f->fs->op.chmod(path,arg->mode) : + f->fs->op.fchmod(fi,arg->mode)); - if(!err && (valid & (FATTR_UID | FATTR_GID))) + if(!err && (arg->valid & (FATTR_UID | FATTR_GID))) { - uid_t uid = ((valid & FATTR_UID) ? attr->st_uid : (uid_t)-1); - gid_t gid = ((valid & FATTR_GID) ? attr->st_gid : (gid_t)-1); + uid_t uid = ((arg->valid & FATTR_UID) ? arg->uid : (uid_t)-1); + gid_t gid = ((arg->valid & FATTR_GID) ? arg->gid : (gid_t)-1); err = ((fi == NULL) ? - fuse_fs_chown(f->fs,path,uid,gid) : - fuse_fs_fchown(f->fs,fi,uid,gid)); + f->fs->op.chown(path,uid,gid) : + f->fs->op.fchown(fi,uid,gid)); } - if(!err && (valid & FATTR_SIZE)) + if(!err && (arg->valid & FATTR_SIZE)) err = ((fi == NULL) ? - fuse_fs_truncate(f->fs,path,attr->st_size) : - fuse_fs_ftruncate(f->fs,attr->st_size,fi)); + f->fs->op.truncate(path,arg->size) : + f->fs->op.ftruncate(fi,arg->size)); #ifdef HAVE_UTIMENSAT - if(!err && (valid & (FATTR_ATIME | FATTR_MTIME))) + if(!err && (arg->valid & (FATTR_ATIME | FATTR_MTIME))) { struct timespec tv[2]; @@ -2274,50 +1893,49 @@ fuse_lib_setattr(fuse_req_t req, tv[0].tv_nsec = UTIME_OMIT; tv[1].tv_nsec = UTIME_OMIT; - if(valid & FATTR_ATIME_NOW) + if(arg->valid & FATTR_ATIME_NOW) tv[0].tv_nsec = UTIME_NOW; - else if(valid & FATTR_ATIME) - tv[0] = attr->st_atim; + else if(arg->valid & FATTR_ATIME) + tv[0] = (struct timespec){ arg->atime, arg->atimensec }; - if(valid & FATTR_MTIME_NOW) + if(arg->valid & FATTR_MTIME_NOW) tv[1].tv_nsec = UTIME_NOW; - else if(valid & FATTR_MTIME) - tv[1] = attr->st_mtim; + else if(arg->valid & FATTR_MTIME) + tv[1] = (struct timespec){ arg->mtime, arg->mtimensec }; err = ((fi == NULL) ? - fuse_fs_utimens(f->fs,path,tv) : - fuse_fs_futimens(f->fs,fi,tv)); + f->fs->op.utimens(path,tv) : + f->fs->op.futimens(fi,tv)); } else #endif - if(!err && ((valid & (FATTR_ATIME|FATTR_MTIME)) == (FATTR_ATIME|FATTR_MTIME))) + if(!err && ((arg->valid & (FATTR_ATIME|FATTR_MTIME)) == (FATTR_ATIME|FATTR_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); + tv[0].tv_sec = arg->atime; + tv[0].tv_nsec = arg->atimensec; + tv[1].tv_sec = arg->mtime; + tv[1].tv_nsec = arg->mtimensec; err = ((fi == NULL) ? - fuse_fs_utimens(f->fs,path,tv) : - fuse_fs_futimens(f->fs,fi,tv)); + f->fs->op.utimens(path,tv) : + f->fs->op.futimens(fi,tv)); } if(!err) err = ((fi == NULL) ? - fuse_fs_getattr(f->fs,path,&buf,&timeout) : - fuse_fs_fgetattr(f->fs,&buf,fi,&timeout)); + f->fs->op.getattr(path,&stbuf,&timeout) : + f->fs->op.fgetattr(fi,&stbuf,&timeout)); - free_path(f,ino,path); + free_path(f,hdr_->nodeid,path); } - if(!err) { pthread_mutex_lock(&f->lock); - update_stat(get_node(f,ino),&buf); + update_stat(get_node(f,hdr_->nodeid),&stbuf); pthread_mutex_unlock(&f->lock); - set_stat(f,ino,&buf); - fuse_reply_attr(req,&buf,timeout.attr); + set_stat(f,hdr_->nodeid,&stbuf); + fuse_reply_attr(req,&stbuf,timeout.attr); } else { @@ -2327,19 +1945,23 @@ fuse_lib_setattr(fuse_req_t req, static void -fuse_lib_access(fuse_req_t req, - uint64_t ino, - int mask) +fuse_lib_access(fuse_req_t req, + struct fuse_in_header *hdr_) { - struct fuse *f = req_fuse_prepare(req); - char *path; int err; + char *path; + struct fuse *f; + struct fuse_access_in *arg; - err = get_path(f,ino,&path); + arg = fuse_hdr_arg(hdr_); + + f = req_fuse_prepare(req); + + err = get_path(f,hdr_->nodeid,&path); if(!err) { - err = fuse_fs_access(f->fs,path,mask); - free_path(f,ino,path); + err = f->fs->op.access(path,arg->mask); + free_path(f,hdr_->nodeid,path); } reply_err(req,err); @@ -2347,19 +1969,21 @@ fuse_lib_access(fuse_req_t req, static void -fuse_lib_readlink(fuse_req_t req, - uint64_t ino) +fuse_lib_readlink(fuse_req_t req, + struct fuse_in_header *hdr_) { - struct fuse *f = req_fuse_prepare(req); - char linkname[PATH_MAX + 1]; - char *path; int err; + char *path; + struct fuse *f; + char linkname[PATH_MAX + 1]; - err = get_path(f,ino,&path); + f = req_fuse_prepare(req); + + err = get_path(f,hdr_->nodeid,&path); if(!err) { - err = fuse_fs_readlink(f->fs,path,linkname,sizeof(linkname)); - free_path(f,ino,path); + err = f->fs->op.readlink(path,linkname,sizeof(linkname)); + free_path(f,hdr_->nodeid,path); } if(!err) @@ -2375,99 +1999,119 @@ fuse_lib_readlink(fuse_req_t req, static void -fuse_lib_mknod(fuse_req_t req, - uint64_t parent, - const char *name, - mode_t mode, - dev_t rdev) +fuse_lib_mknod(fuse_req_t req, + struct fuse_in_header *hdr_) { - struct fuse *f = req_fuse_prepare(req); - struct fuse_entry_param e; - char *path; int err; + char *path; + struct fuse *f; + const char* name; + struct fuse_entry_param e; + struct fuse_mknod_in *arg; + + arg = fuse_hdr_arg(hdr_); + name = PARAM(arg); + if(req->f->conn.proto_minor >= 12) + req->ctx.umask = arg->umask; + else + name = (char*)arg + FUSE_COMPAT_MKNOD_IN_SIZE; - err = get_path_name(f,parent,name,&path); + f = req_fuse_prepare(req); + + err = get_path_name(f,hdr_->nodeid,name,&path); if(!err) { err = -ENOSYS; - if(S_ISREG(mode)) + if(S_ISREG(arg->mode)) { fuse_file_info_t fi; memset(&fi,0,sizeof(fi)); fi.flags = O_CREAT | O_EXCL | O_WRONLY; - err = fuse_fs_create(f->fs,path,mode,&fi); + err = f->fs->op.create(path,arg->mode,&fi); if(!err) { - err = lookup_path(f,parent,name,path,&e, - &fi); - fuse_fs_release(f->fs,&fi); + err = lookup_path(f,hdr_->nodeid,name,path,&e,&fi); + f->fs->op.release(&fi); } } + if(err == -ENOSYS) { - err = fuse_fs_mknod(f->fs,path,mode,rdev); + err = f->fs->op.mknod(path,arg->mode,arg->rdev); if(!err) - err = lookup_path(f,parent,name,path,&e,NULL); + err = lookup_path(f,hdr_->nodeid,name,path,&e,NULL); } - free_path(f,parent,path); + + free_path(f,hdr_->nodeid,path); } + reply_entry(req,&e,err); } static void -fuse_lib_mkdir(fuse_req_t req, - uint64_t parent, - const char *name, - mode_t mode) +fuse_lib_mkdir(fuse_req_t req, + struct fuse_in_header *hdr_) { - struct fuse *f = req_fuse_prepare(req); - struct fuse_entry_param e; - char *path; int err; + char *path; + struct fuse *f; + const char *name; + struct fuse_entry_param e; + struct fuse_mkdir_in *arg; + + arg = fuse_hdr_arg(hdr_); + name = PARAM(arg); + if(req->f->conn.proto_minor >= 12) + req->ctx.umask = arg->umask; + + f = req_fuse_prepare(req); - err = get_path_name(f,parent,name,&path); + err = get_path_name(f,hdr_->nodeid,name,&path); if(!err) { - err = fuse_fs_mkdir(f->fs,path,mode); + err = f->fs->op.mkdir(path,arg->mode); if(!err) - err = lookup_path(f,parent,name,path,&e,NULL); - free_path(f,parent,path); + err = lookup_path(f,hdr_->nodeid,name,path,&e,NULL); + free_path(f,hdr_->nodeid,path); } + reply_entry(req,&e,err); } static void -fuse_lib_unlink(fuse_req_t req, - uint64_t parent, - const char *name) +fuse_lib_unlink(fuse_req_t req, + struct fuse_in_header *hdr_) { int err; char *path; struct fuse *f; + const char *name; struct node *wnode; + name = PARAM(hdr_); + f = req_fuse_prepare(req); - err = get_path_wrlock(f,parent,name,&path,&wnode); + err = get_path_wrlock(f,hdr_->nodeid,name,&path,&wnode); if(!err) { pthread_mutex_lock(&f->lock); if(node_open(wnode)) { - err = fuse_fs_prepare_hide(f->fs,path,&wnode->hidden_fh); + err = f->fs->op.prepare_hide(path,&wnode->hidden_fh); if(!err) wnode->is_hidden = 1; } pthread_mutex_unlock(&f->lock); - err = fuse_fs_unlink(f->fs,path); + err = f->fs->op.unlink(path); if(!err) - remove_node(f,parent,name); + remove_node(f,hdr_->nodeid,name); - free_path_wrlock(f,parent,wnode,path); + free_path_wrlock(f,hdr_->nodeid,wnode,path); } reply_err(req,err); @@ -2475,22 +2119,26 @@ fuse_lib_unlink(fuse_req_t req, static void -fuse_lib_rmdir(fuse_req_t req, - uint64_t parent, - const char *name) +fuse_lib_rmdir(fuse_req_t req, + struct fuse_in_header *hdr_) { - struct fuse *f = req_fuse_prepare(req); - struct node *wnode; - char *path; int err; + char *path; + struct fuse *f; + const char *name; + struct node *wnode; + + name = PARAM(hdr_); + + f = req_fuse_prepare(req); - err = get_path_wrlock(f,parent,name,&path,&wnode); + err = get_path_wrlock(f,hdr_->nodeid,name,&path,&wnode); if(!err) { - err = fuse_fs_rmdir(f->fs,path); + err = f->fs->op.rmdir(path); if(!err) - remove_node(f,parent,name); - free_path_wrlock(f,parent,wnode,path); + remove_node(f,hdr_->nodeid,name); + free_path_wrlock(f,hdr_->nodeid,wnode,path); } reply_err(req,err); @@ -2498,25 +2146,28 @@ fuse_lib_rmdir(fuse_req_t req, static void -fuse_lib_symlink(fuse_req_t req_, - const char *linkname_, - uint64_t parent_, - const char *name_) +fuse_lib_symlink(fuse_req_t req_, + struct fuse_in_header *hdr_) { int rv; char *path; struct fuse *f; + const char *name; + const char *linkname; struct fuse_entry_param e = {0}; + name = fuse_hdr_arg(hdr_); + linkname = (name + strlen(name) + 1); + f = req_fuse_prepare(req_); - rv = get_path_name(f,parent_,name_,&path); + rv = get_path_name(f,hdr_->nodeid,name,&path); if(rv == 0) { - rv = fuse_fs_symlink(f->fs,linkname_,path,&e.attr,&e.timeout); + rv = f->fs->op.symlink(linkname,path,&e.attr,&e.timeout); if(rv == 0) - rv = set_path_info(f,parent_,name_,&e); - free_path(f,parent_,path); + rv = set_path_info(f,hdr_->nodeid,name,&e); + free_path(f,hdr_->nodeid,path); } reply_entry(req_,&e,rv); @@ -2524,21 +2175,25 @@ fuse_lib_symlink(fuse_req_t req_, static void -fuse_lib_rename(fuse_req_t req, - uint64_t olddir, - const char *oldname, - uint64_t newdir, - const char *newname) +fuse_lib_rename(fuse_req_t req, + struct fuse_in_header *hdr_) { int err; struct fuse *f; char *oldpath; char *newpath; + const char *oldname; + const char *newname; struct node *wnode1; struct node *wnode2; + struct fuse_rename_in *arg; + + arg = fuse_hdr_arg(hdr_); + oldname = PARAM(arg); + newname = (oldname + strlen(oldname) + 1); f = req_fuse_prepare(req); - err = get_path2(f,olddir,oldname,newdir,newname, + err = get_path2(f,hdr_->nodeid,oldname,arg->newdir,newname, &oldpath,&newpath,&wnode1,&wnode2); if(!err) @@ -2546,17 +2201,17 @@ fuse_lib_rename(fuse_req_t req, pthread_mutex_lock(&f->lock); if(node_open(wnode2)) { - err = fuse_fs_prepare_hide(f->fs,newpath,&wnode2->hidden_fh); + err = f->fs->op.prepare_hide(newpath,&wnode2->hidden_fh); if(!err) wnode2->is_hidden = 1; } pthread_mutex_unlock(&f->lock); - err = fuse_fs_rename(f->fs,oldpath,newpath); + err = f->fs->op.rename(oldpath,newpath); if(!err) - err = rename_node(f,olddir,oldname,newdir,newname); + err = rename_node(f,hdr_->nodeid,oldname,arg->newdir,newname); - free_path2(f,olddir,newdir,wnode1,wnode2,oldpath,newpath); + free_path2(f,hdr_->nodeid,arg->newdir,wnode1,wnode2,oldpath,newpath); } reply_err(req,err); @@ -2564,27 +2219,32 @@ fuse_lib_rename(fuse_req_t req, static void -fuse_lib_link(fuse_req_t req, - uint64_t ino, - uint64_t newparent, - const char *newname) +fuse_lib_link(fuse_req_t req, + struct fuse_in_header *hdr_) { int rv; char *oldpath; char *newpath; struct fuse *f; + const char *newname; + struct fuse_link_in *arg; struct fuse_entry_param e = {0}; + arg = fuse_hdr_arg(hdr_); + newname = PARAM(arg); + f = req_fuse_prepare(req); - rv = get_path2(f,ino,NULL,newparent,newname, + rv = get_path2(f, + arg->oldnodeid,NULL, + hdr_->nodeid,newname, &oldpath,&newpath,NULL,NULL); if(!rv) { - rv = fuse_fs_link(f->fs,oldpath,newpath,&e.attr,&e.timeout); + rv = f->fs->op.link(oldpath,newpath,&e.attr,&e.timeout); if(rv == 0) - rv = set_path_info(f,newparent,newname,&e); - free_path2(f,ino,newparent,NULL,NULL,oldpath,newpath); + rv = set_path_info(f,hdr_->nodeid,newname,&e); + free_path2(f,arg->oldnodeid,hdr_->nodeid,NULL,NULL,oldpath,newpath); } reply_entry(req,&e,rv); @@ -2601,7 +2261,7 @@ fuse_do_release(struct fuse *f, int was_hidden; fh = 0; - fuse_fs_release(f->fs,fi); + f->fs->op.release(fi); pthread_mutex_lock(&f->lock); node = get_node(f,ino); @@ -2617,38 +2277,49 @@ fuse_do_release(struct fuse *f, pthread_mutex_unlock(&f->lock); if(was_hidden) - fuse_fs_free_hide(f->fs,fh); + f->fs->op.free_hide(fh); } static void -fuse_lib_create(fuse_req_t req, - uint64_t parent, - const char *name, - mode_t mode, - fuse_file_info_t *fi) +fuse_lib_create(fuse_req_t req, + struct fuse_in_header *hdr_) { int err; char *path; struct fuse *f; + const char *name; + fuse_file_info_t ffi = {0}; struct fuse_entry_param e; + struct fuse_create_in *arg; + + arg = fuse_hdr_arg(hdr_); + name = PARAM(arg); + + ffi.flags = arg->flags; + + if(req->f->conn.proto_minor >= 12) + req->ctx.umask = arg->umask; + else + name = (char*)arg + sizeof(struct fuse_open_in); f = req_fuse_prepare(req); - err = get_path_name(f,parent,name,&path); + + err = get_path_name(f,hdr_->nodeid,name,&path); if(!err) { - err = fuse_fs_create(f->fs,path,mode,fi); + err = f->fs->op.create(path,arg->mode,&ffi); if(!err) { - err = lookup_path(f,parent,name,path,&e,fi); + err = lookup_path(f,hdr_->nodeid,name,path,&e,&ffi); if(err) { - fuse_fs_release(f->fs,fi); + f->fs->op.release(&ffi); } else if(!S_ISREG(e.attr.st_mode)) { err = -EIO; - fuse_fs_release(f->fs,fi); + f->fs->op.release(&ffi); forget_node(f,e.ino,1); } } @@ -2660,11 +2331,11 @@ fuse_lib_create(fuse_req_t req, get_node(f,e.ino)->open_count++; pthread_mutex_unlock(&f->lock); - if(fuse_reply_create(req,&e,fi) == -ENOENT) + if(fuse_reply_create(req,&e,&ffi) == -ENOENT) { /* The open syscall was interrupted,so it must be cancelled */ - fuse_do_release(f,e.ino,fi); + fuse_do_release(f,e.ino,&ffi); forget_node(f,e.ino,1); } } @@ -2673,7 +2344,7 @@ fuse_lib_create(fuse_req_t req, reply_err(req,err); } - free_path(f,parent,path); + free_path(f,hdr_->nodeid,path); } static @@ -2695,7 +2366,7 @@ open_auto_cache(struct fuse *f, struct stat stbuf; pthread_mutex_unlock(&f->lock); - err = fuse_fs_fgetattr(f->fs,&stbuf,fi,&timeout); + err = f->fs->op.fgetattr(fi,&stbuf,&timeout); pthread_mutex_lock(&f->lock); if(!err) @@ -2714,58 +2385,73 @@ open_auto_cache(struct fuse *f, static void -fuse_lib_open(fuse_req_t req, - uint64_t ino, - fuse_file_info_t *fi) +fuse_lib_open(fuse_req_t req, + struct fuse_in_header *hdr_) { int err; char *path; struct fuse *f; + fuse_file_info_t ffi = {0}; + struct fuse_open_in *arg; + + arg = fuse_hdr_arg(hdr_); + + ffi.flags = arg->flags; f = req_fuse_prepare(req); - err = get_path(f,ino,&path); + + err = get_path(f,hdr_->nodeid,&path); if(!err) { - err = fuse_fs_open(f->fs,path,fi); + err = f->fs->op.open(path,&ffi); if(!err) { - if(fi && fi->auto_cache) - open_auto_cache(f,ino,path,fi); + if(ffi.auto_cache) + open_auto_cache(f,hdr_->nodeid,path,&ffi); } } if(!err) { pthread_mutex_lock(&f->lock); - get_node(f,ino)->open_count++; + get_node(f,hdr_->nodeid)->open_count++; pthread_mutex_unlock(&f->lock); /* The open syscall was interrupted,so it must be cancelled */ - if(fuse_reply_open(req,fi) == -ENOENT) - fuse_do_release(f,ino,fi); + if(fuse_reply_open(req,&ffi) == -ENOENT) + fuse_do_release(f,hdr_->nodeid,&ffi); } else { reply_err(req,err); } - free_path(f,ino,path); + free_path(f,hdr_->nodeid,path); } static void -fuse_lib_read(fuse_req_t req, - uint64_t ino, - size_t size, - off_t off, - fuse_file_info_t *fi) +fuse_lib_read(fuse_req_t req, + struct fuse_in_header *hdr_) { - struct fuse *f = req_fuse_prepare(req); - struct fuse_bufvec *buf = NULL; int res; + struct fuse *f; + fuse_file_info_t ffi = {0}; + struct fuse_bufvec *buf = NULL; + struct fuse_read_in *arg; + + arg = fuse_hdr_arg(hdr_); + ffi.fh = arg->fh; + if(req->f->conn.proto_minor >= 9) + { + ffi.flags = arg->flags; + ffi.lock_owner = arg->lock_owner; + } + + f = req_fuse_prepare(req); - res = fuse_fs_read_buf(f->fs,&buf,size,off,fi); + res = f->fs->op.read_buf(&ffi,&buf,arg->size,arg->offset); - if(res == 0) + if(res >= 0) fuse_reply_data(req,buf,FUSE_BUF_SPLICE_MOVE); else reply_err(req,res); @@ -2775,17 +2461,33 @@ fuse_lib_read(fuse_req_t req, static void -fuse_lib_write_buf(fuse_req_t req, - uint64_t ino, - struct fuse_bufvec *buf, - off_t off, - fuse_file_info_t *fi) +fuse_lib_write(fuse_req_t req, + struct fuse_in_header *hdr_) { int res; - struct fuse *f = req_fuse_prepare(req); + char *data; + struct fuse *f; + fuse_file_info_t ffi = {0}; + struct fuse_write_in *arg; + + arg = fuse_hdr_arg(hdr_); + ffi.fh = arg->fh; + ffi.writepage = !!(arg->write_flags & 1); + if(req->f->conn.proto_minor < 9) + { + data = ((char*)arg) + FUSE_COMPAT_WRITE_IN_SIZE; + } + else + { + ffi.flags = arg->flags; + ffi.lock_owner = arg->lock_owner; + data = PARAM(arg); + } - res = fuse_fs_write_buf(f->fs,buf,off,fi); - free_path(f,ino,NULL); + f = req_fuse_prepare(req); + + res = f->fs->op.write(&ffi,data,arg->size,arg->offset); + free_path(f,hdr_->nodeid,NULL); if(res >= 0) fuse_reply_write(req,res); @@ -2795,15 +2497,21 @@ fuse_lib_write_buf(fuse_req_t req, static void -fuse_lib_fsync(fuse_req_t req, - uint64_t ino, - int datasync, - fuse_file_info_t *fi) +fuse_lib_fsync(fuse_req_t req, + struct fuse_in_header *hdr_) { int err; - struct fuse *f = req_fuse_prepare(req); + struct fuse *f; + struct fuse_fsync_in *arg; + fuse_file_info_t ffi = {0}; - err = fuse_fs_fsync(f->fs,datasync,fi); + arg = fuse_hdr_arg(hdr_); + ffi.fh = arg->fh; + + f = req_fuse_prepare(req); + + err = f->fs->op.fsync(&ffi, + !!(arg->fsync_flags & 1)); reply_err(req,err); } @@ -2821,15 +2529,21 @@ get_dirhandle(const fuse_file_info_t *llfi, static void -fuse_lib_opendir(fuse_req_t req, - uint64_t ino, - fuse_file_info_t *llfi) +fuse_lib_opendir(fuse_req_t req, + struct fuse_in_header *hdr_) { int err; char *path; struct fuse_dh *dh; - fuse_file_info_t fi; - struct fuse *f = req_fuse_prepare(req); + fuse_file_info_t llffi = {0}; + fuse_file_info_t ffi = {0}; + struct fuse *f; + struct fuse_open_in *arg; + + arg = fuse_hdr_arg(hdr_); + llffi.flags = arg->flags; + + f = req_fuse_prepare(req); dh = (struct fuse_dh *)calloc(1,sizeof(struct fuse_dh)); if(dh == NULL) @@ -2841,27 +2555,25 @@ fuse_lib_opendir(fuse_req_t req, fuse_dirents_init(&dh->d); fuse_mutex_init(&dh->lock); - llfi->fh = (uintptr_t)dh; - - memset(&fi,0,sizeof(fi)); - fi.flags = llfi->flags; + llffi.fh = (uintptr_t)dh; + ffi.flags = llffi.flags; - err = get_path(f,ino,&path); + err = get_path(f,hdr_->nodeid,&path); if(!err) { - err = fuse_fs_opendir(f->fs,path,&fi); - dh->fh = fi.fh; - llfi->keep_cache = fi.keep_cache; - llfi->cache_readdir = fi.cache_readdir; + err = f->fs->op.opendir(path,&ffi); + dh->fh = ffi.fh; + llffi.keep_cache = ffi.keep_cache; + llffi.cache_readdir = ffi.cache_readdir; } if(!err) { - if(fuse_reply_open(req,llfi) == -ENOENT) + if(fuse_reply_open(req,&llffi) == -ENOENT) { /* The opendir syscall was interrupted,so it must be cancelled */ - fuse_fs_releasedir(f->fs,&fi); + f->fs->op.releasedir(&ffi); pthread_mutex_destroy(&dh->lock); free(dh); } @@ -2872,7 +2584,8 @@ fuse_lib_opendir(fuse_req_t req, pthread_mutex_destroy(&dh->lock); free(dh); } - free_path(f,ino,path); + + free_path(f,hdr_->nodeid,path); } static @@ -2902,27 +2615,31 @@ readdir_buf(fuse_dirents_t *d_, static void -fuse_lib_readdir(fuse_req_t req_, - uint64_t ino_, - size_t size_, - off_t off_, - fuse_file_info_t *llffi_) +fuse_lib_readdir(fuse_req_t req_, + struct fuse_in_header *hdr_) { int rv; + size_t size; struct fuse *f; fuse_dirents_t *d; struct fuse_dh *dh; - fuse_file_info_t fi; + fuse_file_info_t ffi = {0}; + fuse_file_info_t llffi = {0}; + struct fuse_read_in *arg; + + arg = fuse_hdr_arg(hdr_); + size = arg->size; + llffi.fh = arg->fh; f = req_fuse_prepare(req_); - dh = get_dirhandle(llffi_,&fi); + dh = get_dirhandle(&llffi,&ffi); d = &dh->d; pthread_mutex_lock(&dh->lock); rv = 0; - if((off_ == 0) || (kv_size(d->data) == 0)) - rv = fuse_fs_readdir(f->fs,&fi,d); + if((arg->offset == 0) || (kv_size(d->data) == 0)) + rv = f->fs->op.readdir(&ffi,d); if(rv) { @@ -2930,11 +2647,11 @@ fuse_lib_readdir(fuse_req_t req_, goto out; } - size_ = readdir_buf_size(d,size_,off_); + size = readdir_buf_size(d,size,arg->offset); fuse_reply_buf(req_, - readdir_buf(d,off_), - size_); + readdir_buf(d,arg->offset), + size); out: pthread_mutex_unlock(&dh->lock); @@ -2942,27 +2659,31 @@ fuse_lib_readdir(fuse_req_t req_, static void -fuse_lib_readdir_plus(fuse_req_t req_, - uint64_t ino_, - size_t size_, - off_t off_, - fuse_file_info_t *llffi_) +fuse_lib_readdir_plus(fuse_req_t req_, + struct fuse_in_header *hdr_) { int rv; + size_t size; struct fuse *f; fuse_dirents_t *d; struct fuse_dh *dh; - fuse_file_info_t fi; + fuse_file_info_t ffi = {0}; + fuse_file_info_t llffi = {0}; + struct fuse_read_in *arg; + + arg = fuse_hdr_arg(hdr_); + size = arg->size; + llffi.fh = arg->fh; f = req_fuse_prepare(req_); - dh = get_dirhandle(llffi_,&fi); + dh = get_dirhandle(&llffi,&ffi); d = &dh->d; pthread_mutex_lock(&dh->lock); rv = 0; - if((off_ == 0) || (kv_size(d->data) == 0)) - rv = fuse_fs_readdir_plus(f->fs,&fi,d); + if((arg->offset == 0) || (kv_size(d->data) == 0)) + rv = f->fs->op.readdir_plus(&ffi,d); if(rv) { @@ -2970,11 +2691,11 @@ fuse_lib_readdir_plus(fuse_req_t req_, goto out; } - size_ = readdir_buf_size(d,size_,off_); + size = readdir_buf_size(d,size,arg->offset); fuse_reply_buf(req_, - readdir_buf(d,off_), - size_); + readdir_buf(d,arg->offset), + size); out: pthread_mutex_unlock(&dh->lock); @@ -2982,18 +2703,23 @@ fuse_lib_readdir_plus(fuse_req_t req_, static void -fuse_lib_releasedir(fuse_req_t req_, - uint64_t ino_, - fuse_file_info_t *llfi_) +fuse_lib_releasedir(fuse_req_t req_, + struct fuse_in_header *hdr_) { struct fuse *f; struct fuse_dh *dh; - fuse_file_info_t fi; + fuse_file_info_t ffi; + fuse_file_info_t llffi = {0}; + struct fuse_release_in *arg; + + arg = fuse_hdr_arg(hdr_); + llffi.fh = arg->fh; + llffi.flags = arg->flags; f = req_fuse_prepare(req_); - dh = get_dirhandle(llfi_,&fi); + dh = get_dirhandle(&llffi,&ffi); - fuse_fs_releasedir(f->fs,&fi); + f->fs->op.releasedir(&ffi); /* Done to keep race condition between last readdir reply and the unlock */ pthread_mutex_lock(&dh->lock); @@ -3006,40 +2732,47 @@ fuse_lib_releasedir(fuse_req_t req_, static void -fuse_lib_fsyncdir(fuse_req_t req, - uint64_t ino, - int datasync, - fuse_file_info_t *llfi) +fuse_lib_fsyncdir(fuse_req_t req, + struct fuse_in_header *hdr_) { int err; - fuse_file_info_t fi; - struct fuse *f = req_fuse_prepare(req); + struct fuse *f; + fuse_file_info_t ffi; + fuse_file_info_t llffi = {0}; + struct fuse_fsync_in *arg; - get_dirhandle(llfi,&fi); + arg = fuse_hdr_arg(hdr_); + llffi.fh = arg->fh; - err = fuse_fs_fsyncdir(f->fs,datasync,&fi); + f = req_fuse_prepare(req); + + get_dirhandle(&llffi,&ffi); + + err = f->fs->op.fsyncdir(&ffi, + !!(arg->fsync_flags & FUSE_FSYNC_FDATASYNC)); reply_err(req,err); } static void -fuse_lib_statfs(fuse_req_t req, - uint64_t ino) +fuse_lib_statfs(fuse_req_t req, + struct fuse_in_header *hdr_) { - struct fuse *f = req_fuse_prepare(req); - struct statvfs buf; - char *path = NULL; int err = 0; + char *path = NULL; + struct fuse *f; + struct statvfs buf = {0}; - memset(&buf,0,sizeof(buf)); - if(ino) - err = get_path(f,ino,&path); + f = req_fuse_prepare(req); + + if(hdr_->nodeid) + err = get_path(f,hdr_->nodeid,&path); if(!err) { - err = fuse_fs_statfs(f->fs,path ? path : "/",&buf); - free_path(f,ino,path); + err = f->fs->op.statfs(path ? path : "/",&buf); + free_path(f,hdr_->nodeid,path); } if(!err) @@ -3050,22 +2783,27 @@ fuse_lib_statfs(fuse_req_t req, static void -fuse_lib_setxattr(fuse_req_t req, - uint64_t ino, - const char *name, - const char *value, - size_t size, - int flags) +fuse_lib_setxattr(fuse_req_t req, + struct fuse_in_header *hdr_) { - struct fuse *f = req_fuse_prepare(req); - char *path; int err; + char *path; + const char *name; + const char *value; + struct fuse *f; + struct fuse_setxattr_in *arg; - err = get_path(f,ino,&path); + arg = fuse_hdr_arg(hdr_); + name = PARAM(arg); + value = (name + strlen(name) + 1); + + f = req_fuse_prepare(req); + + err = get_path(f,hdr_->nodeid,&path); if(!err) { - err = fuse_fs_setxattr(f->fs,path,name,value,size,flags); - free_path(f,ino,path); + err = f->fs->op.setxattr(path,name,value,arg->size,arg->flags); + free_path(f,hdr_->nodeid,path); } reply_err(req,err); @@ -3086,7 +2824,7 @@ common_getxattr(struct fuse *f, err = get_path(f,ino,&path); if(!err) { - err = fuse_fs_getxattr(f->fs,path,name,value,size); + err = f->fs->op.getxattr(path,name,value,size); free_path(f,ino,path); } @@ -3096,24 +2834,29 @@ common_getxattr(struct fuse *f, static void -fuse_lib_getxattr(fuse_req_t req, - uint64_t ino, - const char *name, - size_t size) +fuse_lib_getxattr(fuse_req_t req, + struct fuse_in_header *hdr_) { - struct fuse *f = req_fuse_prepare(req); int res; + struct fuse *f; + const char* name; + struct fuse_getxattr_in *arg; + + arg = fuse_hdr_arg(hdr_); + name = PARAM(arg); + + f = req_fuse_prepare(req); - if(size) + if(arg->size) { - char *value = (char *)malloc(size); + char *value = (char*)malloc(arg->size); if(value == NULL) { reply_err(req,-ENOMEM); return; } - res = common_getxattr(f,req,ino,name,value,size); + res = common_getxattr(f,req,hdr_->nodeid,name,value,arg->size); if(res > 0) fuse_reply_buf(req,value,res); else @@ -3122,7 +2865,7 @@ fuse_lib_getxattr(fuse_req_t req, } else { - res = common_getxattr(f,req,ino,name,NULL,0); + res = common_getxattr(f,req,hdr_->nodeid,name,NULL,0); if(res >= 0) fuse_reply_xattr(req,res); else @@ -3144,7 +2887,7 @@ common_listxattr(struct fuse *f, err = get_path(f,ino,&path); if(!err) { - err = fuse_fs_listxattr(f->fs,path,list,size); + err = f->fs->op.listxattr(path,list,size); free_path(f,ino,path); } @@ -3153,23 +2896,27 @@ common_listxattr(struct fuse *f, static void -fuse_lib_listxattr(fuse_req_t req, - uint64_t ino, - size_t size) +fuse_lib_listxattr(fuse_req_t req, + struct fuse_in_header *hdr_) { - struct fuse *f = req_fuse_prepare(req); int res; + struct fuse *f; + struct fuse_getxattr_in *arg; - if(size) + arg = fuse_hdr_arg(hdr_); + + f = req_fuse_prepare(req); + + if(arg->size) { - char *list = (char *)malloc(size); + char *list = (char*)malloc(arg->size); if(list == NULL) { reply_err(req,-ENOMEM); return; } - res = common_listxattr(f,req,ino,list,size); + res = common_listxattr(f,req,hdr_->nodeid,list,arg->size); if(res > 0) fuse_reply_buf(req,list,res); else @@ -3178,7 +2925,7 @@ fuse_lib_listxattr(fuse_req_t req, } else { - res = common_listxattr(f,req,ino,NULL,0); + res = common_listxattr(f,req,hdr_->nodeid,NULL,0); if(res >= 0) fuse_reply_xattr(req,res); else @@ -3188,19 +2935,23 @@ fuse_lib_listxattr(fuse_req_t req, static void -fuse_lib_removexattr(fuse_req_t req, - uint64_t ino, - const char *name) +fuse_lib_removexattr(fuse_req_t req, + const struct fuse_in_header *hdr_) { - struct fuse *f = req_fuse_prepare(req); - char *path; int err; + char *path; + const char *name; + struct fuse *f; - err = get_path(f,ino,&path); + name = fuse_hdr_arg(hdr_); + + f = req_fuse_prepare(req); + + err = get_path(f,hdr_->nodeid,&path); if(!err) { - err = fuse_fs_removexattr(f->fs,path,name); - free_path(f,ino,path); + err = f->fs->op.removexattr(path,name); + free_path(f,hdr_->nodeid,path); } reply_err(req,err); @@ -3208,28 +2959,27 @@ fuse_lib_removexattr(fuse_req_t req, static void -fuse_lib_copy_file_range(fuse_req_t req_, - uint64_t nodeid_in_, - off_t off_in_, - fuse_file_info_t *ffi_in_, - uint64_t nodeid_out_, - off_t off_out_, - fuse_file_info_t *ffi_out_, - size_t len_, - int flags_) +fuse_lib_copy_file_range(fuse_req_t req_, + const struct fuse_in_header *hdr_) { ssize_t rv; struct fuse *f; + fuse_file_info_t ffi_in = {0}; + fuse_file_info_t ffi_out = {0}; + const struct fuse_copy_file_range_in *arg; + + arg = fuse_hdr_arg(hdr_); + ffi_in.fh = arg->fh_in; + ffi_out.fh = arg->fh_out; f = req_fuse_prepare(req_); - rv = fuse_fs_copy_file_range(f->fs, - ffi_in_, - off_in_, - ffi_out_, - off_out_, - len_, - flags_); + rv = f->fs->op.copy_file_range(&ffi_in, + arg->off_in, + &ffi_out, + arg->off_out, + arg->len, + arg->flags); if(rv >= 0) fuse_reply_write(req_,rv); @@ -3394,8 +3144,8 @@ fuse_flush_common(struct fuse *f, memset(&lock,0,sizeof(lock)); lock.l_type = F_UNLCK; lock.l_whence = SEEK_SET; - err = fuse_fs_flush(f->fs,fi); - errlock = fuse_fs_lock(f->fs,fi,F_SETLK,&lock); + err = f->fs->op.flush(fi); + errlock = f->fs->op.lock(fi,F_SETLK,&lock); if(errlock != -ENOSYS) { @@ -3416,35 +3166,62 @@ fuse_flush_common(struct fuse *f, static void -fuse_lib_release(fuse_req_t req, - uint64_t ino, - fuse_file_info_t *fi) +fuse_lib_release(fuse_req_t req, + struct fuse_in_header *hdr_) { int err = 0; - struct fuse *f = req_fuse_prepare(req); + struct fuse *f; + fuse_file_info_t ffi = {0}; + struct fuse_release_in *arg; + + arg = fuse_hdr_arg(hdr_); + ffi.fh = arg->fh; + ffi.flags = arg->flags; + if(req->f->conn.proto_minor >= 8) + { + ffi.flush = !!(arg->release_flags & FUSE_RELEASE_FLUSH); + ffi.lock_owner = arg->lock_owner; + } + else + { + ffi.flock_release = 1; + ffi.lock_owner = arg->lock_owner; + } - if(fi->flush) + f = req_fuse_prepare(req); + + if(ffi.flush) { - err = fuse_flush_common(f,req,ino,fi); + err = fuse_flush_common(f,req,hdr_->nodeid,&ffi); if(err == -ENOSYS) err = 0; } - fuse_do_release(f,ino,fi); + fuse_do_release(f,hdr_->nodeid,&ffi); reply_err(req,err); } static void -fuse_lib_flush(fuse_req_t req, - uint64_t ino, - fuse_file_info_t *fi) +fuse_lib_flush(fuse_req_t req, + struct fuse_in_header *hdr_) { int err; - struct fuse *f = req_fuse_prepare(req); + struct fuse *f; + fuse_file_info_t ffi = {0}; + struct fuse_flush_in *arg; - err = fuse_flush_common(f,req,ino,fi); + arg = fuse_hdr_arg(hdr_); + + ffi.fh = arg->fh; + ffi.flush = 1; + if(req->f->conn.proto_minor >= 7) + ffi.lock_owner = arg->lock_owner; + + f = req_fuse_prepare(req); + + err = fuse_flush_common(f,req,hdr_->nodeid,&ffi); reply_err(req,err); } @@ -3460,37 +3237,62 @@ fuse_lock_common(fuse_req_t req, int err; struct fuse *f = req_fuse_prepare(req); - err = fuse_fs_lock(f->fs,fi,cmd,lock); + err = f->fs->op.lock(fi,cmd,lock); return err; } static void -fuse_lib_getlk(fuse_req_t req, - uint64_t ino, - fuse_file_info_t *fi, - struct flock *lock) +convert_fuse_file_lock(const struct fuse_file_lock *fl, + 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; +} + +static +void +fuse_lib_getlk(fuse_req_t req, + const struct fuse_in_header *hdr_) { int err; - struct lock l; + struct fuse *f; + struct lock lk; + struct flock flk; struct lock *conflict; - struct fuse *f = req_fuse(req); + fuse_file_info_t ffi = {0}; + const struct fuse_lk_in *arg; + + arg = fuse_hdr_arg(hdr_); + ffi.fh = arg->fh; + ffi.lock_owner = arg->owner; + + convert_fuse_file_lock(&arg->lk,&flk); - flock_to_lock(lock,&l); - l.owner = fi->lock_owner; + f = req_fuse(req); + + flock_to_lock(&flk,&lk); + lk.owner = ffi.lock_owner; pthread_mutex_lock(&f->lock); - conflict = locks_conflict(get_node(f,ino),&l); + conflict = locks_conflict(get_node(f,hdr_->nodeid),&lk); if(conflict) - lock_to_flock(conflict,lock); + lock_to_flock(conflict,&flk); pthread_mutex_unlock(&f->lock); if(!conflict) - err = fuse_lock_common(req,ino,fi,lock,F_GETLK); + err = fuse_lock_common(req,hdr_->nodeid,&ffi,&flk,F_GETLK); else err = 0; if(!err) - fuse_reply_lock(req,lock); + fuse_reply_lock(req,&flk); else reply_err(req,err); } @@ -3529,78 +3331,101 @@ fuse_lib_flock(fuse_req_t req, int err; struct fuse *f = req_fuse_prepare(req); - err = fuse_fs_flock(f->fs,fi,op); + err = f->fs->op.flock(fi,op); reply_err(req,err); } static void -fuse_lib_bmap(fuse_req_t req, - uint64_t ino, - size_t blocksize, - uint64_t idx) +fuse_lib_bmap(fuse_req_t req, + const struct fuse_in_header *hdr_) { int err; char *path; - struct fuse *f = req_fuse_prepare(req); + struct fuse *f; + uint64_t block; + const struct fuse_bmap_in *arg; - err = get_path(f,ino,&path); + arg = fuse_hdr_arg(hdr_); + block = arg->block; + + f = req_fuse_prepare(req); + + err = get_path(f,hdr_->nodeid,&path); if(!err) { - err = fuse_fs_bmap(f->fs,path,blocksize,&idx); - free_path(f,ino,path); + err = f->fs->op.bmap(path,arg->blocksize,&block); + free_path(f,hdr_->nodeid,path); } if(!err) - fuse_reply_bmap(req,idx); + fuse_reply_bmap(req,block); else reply_err(req,err); } static void -fuse_lib_ioctl(fuse_req_t req, - uint64_t ino, - unsigned long cmd, - void *arg, - fuse_file_info_t *llfi, - unsigned int flags, - const void *in_buf, - uint32_t in_bufsz, - uint32_t out_bufsz_) +fuse_lib_ioctl(fuse_req_t req, + const struct fuse_in_header *hdr_) { int err; char *out_buf = NULL; struct fuse *f = req_fuse_prepare(req); - fuse_file_info_t fi; - uint32_t out_bufsz = out_bufsz_; + fuse_file_info_t ffi; + fuse_file_info_t llffi = {0}; + const void *in_buf; + uint32_t out_size; + const struct fuse_ioctl_in *arg; + + arg = fuse_hdr_arg(hdr_); + if((arg->flags & FUSE_IOCTL_DIR) && !(req->f->conn.want & FUSE_CAP_IOCTL_DIR)) + { + fuse_reply_err(req,ENOTTY); + return; + } + + if((sizeof(void*) == 4) && + (req->f->conn.proto_minor >= 16) && + !(arg->flags & FUSE_IOCTL_32BIT)) + { + req->ioctl_64bit = 1; + } + + llffi.fh = arg->fh; + out_size = arg->out_size; + in_buf = (arg->in_size ? PARAM(arg) : NULL); err = -EPERM; - if(flags & FUSE_IOCTL_UNRESTRICTED) + if(arg->flags & FUSE_IOCTL_UNRESTRICTED) goto err; - if(flags & FUSE_IOCTL_DIR) - get_dirhandle(llfi,&fi); + if(arg->flags & FUSE_IOCTL_DIR) + get_dirhandle(&llffi,&ffi); else - fi = *llfi; + ffi = llffi; - if(out_bufsz) + if(out_size) { err = -ENOMEM; - out_buf = malloc(out_bufsz); + out_buf = malloc(out_size); if(!out_buf) goto err; } - assert(!in_bufsz || !out_bufsz || in_bufsz == out_bufsz); + assert(!arg->in_size || !out_size || arg->in_size == out_size); if(out_buf) - memcpy(out_buf,in_buf,in_bufsz); + memcpy(out_buf,in_buf,arg->in_size); - err = fuse_fs_ioctl(f->fs,cmd,arg,&fi,flags, - out_buf ?: (void *)in_buf,&out_bufsz); + err = f->fs->op.ioctl(&ffi, + arg->cmd, + (void*)(uintptr_t)arg->arg, + arg->flags, + out_buf ?: (void *)in_buf, + &out_size); - fuse_reply_ioctl(req,err,out_buf,out_bufsz); + fuse_reply_ioctl(req,err,out_buf,out_size); goto out; err: reply_err(req,err); @@ -3610,16 +3435,34 @@ fuse_lib_ioctl(fuse_req_t req, static void -fuse_lib_poll(fuse_req_t req, - uint64_t ino, - fuse_file_info_t *fi, - fuse_pollhandle_t *ph) +fuse_lib_poll(fuse_req_t req, + const struct fuse_in_header *hdr_) { int err; struct fuse *f = req_fuse_prepare(req); unsigned revents = 0; + fuse_file_info_t ffi = {0}; + fuse_pollhandle_t *ph = NULL; + const struct fuse_poll_in *arg; - err = fuse_fs_poll(f->fs,fi,ph,&revents); + arg = fuse_hdr_arg(hdr_); + ffi.fh = arg->fh; + + if(arg->flags & FUSE_POLL_SCHEDULE_NOTIFY) + { + ph = (fuse_pollhandle_t*)malloc(sizeof(fuse_pollhandle_t)); + if(ph == NULL) + { + fuse_reply_err(req,ENOMEM); + return; + } + + ph->kh = arg->kh; + ph->ch = req->ch; + ph->f = req->f; + } + + err = f->fs->op.poll(&ffi,ph,&revents); if(!err) fuse_reply_poll(req,revents); @@ -3629,17 +3472,23 @@ fuse_lib_poll(fuse_req_t req, static void -fuse_lib_fallocate(fuse_req_t req, - uint64_t ino, - int mode, - off_t offset, - off_t length, - fuse_file_info_t *fi) +fuse_lib_fallocate(fuse_req_t req, + const struct fuse_in_header *hdr_) { int err; - struct fuse *f = req_fuse_prepare(req); + struct fuse *f; + fuse_file_info_t ffi = {0}; + const struct fuse_fallocate_in *arg; + + arg = fuse_hdr_arg(hdr_); + ffi.fh = arg->fh; + + f = req_fuse_prepare(req); - err = fuse_fs_fallocate(f->fs,mode,offset,length,fi); + err = f->fs->op.fallocate(arg->mode, + arg->offset, + arg->length, + &ffi); reply_err(req,err); } @@ -3800,7 +3649,7 @@ static struct fuse_lowlevel_ops fuse_path_ops = .statfs = fuse_lib_statfs, .symlink = fuse_lib_symlink, .unlink = fuse_lib_unlink, - .write_buf = fuse_lib_write_buf, + .write = fuse_lib_write, }; int @@ -4204,7 +4053,7 @@ fuse_new_common(struct fuse_chan *ch, /* 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->fs); out_free: free(f); out_delete_context_key: @@ -4241,7 +4090,7 @@ fuse_destroy(struct fuse *f) for(node = f->id_table.array[i]; node != NULL; node = node->id_next) { if(node->is_hidden) - fuse_fs_free_hide(f->fs,node->hidden_fh); + f->fs->op.free_hide(node->hidden_fh); } } } diff --git a/libfuse/lib/fuse_lowlevel.c b/libfuse/lib/fuse_lowlevel.c index c1787729..eeb10465 100644 --- a/libfuse/lib/fuse_lowlevel.c +++ b/libfuse/lib/fuse_lowlevel.c @@ -16,6 +16,7 @@ #include "fuse_kernel.h" #include "fuse_opt.h" #include "fuse_misc.h" +#include "fuse_pollhandle.h" #include #include @@ -35,19 +36,12 @@ #endif -#define PARAM(inarg) (((char *)(inarg)) + sizeof(*(inarg))) +#define PARAM(inarg) (((char*)(inarg)) + sizeof(*(inarg))) #define OFFSET_MAX 0x7fffffffffffffffLL #define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) - -struct fuse_pollhandle_t -{ - uint64_t kh; - struct fuse_chan *ch; - struct fuse_ll *f; -}; + const typeof( ((type*)0)->member ) *__mptr = (ptr); \ + (type *)( (char*)__mptr - offsetof(type,member) );}) static size_t pagesize; static lfmp_t g_FMP_fuse_req; @@ -92,23 +86,6 @@ convert_stat(const struct stat *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; - stbuf_->st_ctime = attr_->ctime; - ST_ATIM_NSEC_SET(stbuf_,attr_->atimensec); - ST_MTIM_NSEC_SET(stbuf_,attr_->mtimensec); - ST_CTIM_NSEC_SET(stbuf_,attr_->ctimensec); -} - static size_t iov_length(const struct iovec *iov, @@ -1008,479 +985,250 @@ fuse_reply_poll(fuse_req_t req, static void -do_lookup(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_lookup(fuse_req_t req, + struct fuse_in_header *hdr_) { - char *name = (char*)inarg; - - req->f->op.lookup(req,nodeid,name); + req->f->op.lookup(req,hdr_); } static void -do_forget(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_forget(fuse_req_t req, + struct fuse_in_header *hdr_) { - struct fuse_forget_in *arg = (struct fuse_forget_in*)inarg; - - req->f->op.forget(req,nodeid,arg->nlookup); + req->f->op.forget(req,hdr_); } static void -do_batch_forget(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_batch_forget(fuse_req_t req, + struct fuse_in_header *hdr_) { - struct fuse_batch_forget_in *arg = (void *) inarg; - struct fuse_forget_one *param = (void *) PARAM(arg); - - (void)nodeid; - - req->f->op.forget_multi(req, - arg->count, - (struct fuse_forget_data*)param); + req->f->op.forget_multi(req,hdr_); } static void -do_getattr(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_getattr(fuse_req_t req, + struct fuse_in_header *hdr_) { - fuse_file_info_t *fip = NULL; - fuse_file_info_t fi = {0}; - - if(req->f->conn.proto_minor >= 9) - { - struct fuse_getattr_in *arg = (struct fuse_getattr_in*)inarg; - - if(arg->getattr_flags & FUSE_GETATTR_FH) - { - fi.fh = arg->fh; - fip = &fi; - } - } - - req->f->op.getattr(req, nodeid, fip); + req->f->op.getattr(req, hdr_); } static void -do_setattr(fuse_req_t req_, - uint64_t nodeid_, - const void *inarg_) +do_setattr(fuse_req_t req_, + struct fuse_in_header *hdr_) { - struct stat stbuf = {0}; - fuse_file_info_t *fi; - fuse_file_info_t fi_store; - struct fuse_setattr_in *arg; - - fi = NULL; - arg = (struct fuse_setattr_in*)inarg_; - - 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; - } - - arg->valid &= - (FATTR_MODE | - FATTR_UID | - FATTR_GID | - FATTR_SIZE | - FATTR_ATIME | - FATTR_MTIME | - FATTR_CTIME | - FATTR_ATIME_NOW | - FATTR_MTIME_NOW); - - req_->f->op.setattr(req_,nodeid_,&stbuf,arg->valid,fi); + req_->f->op.setattr(req_,hdr_); } static void -do_access(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_access(fuse_req_t req, + struct fuse_in_header *hdr_) { - struct fuse_access_in *arg = (struct fuse_access_in *)inarg; - - req->f->op.access(req, nodeid, arg->mask); + req->f->op.access(req,hdr_); } static void -do_readlink(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_readlink(fuse_req_t req, + struct fuse_in_header *hdr_) { - (void)inarg; - - req->f->op.readlink(req, nodeid); + req->f->op.readlink(req,hdr_); } static void -do_mknod(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_mknod(fuse_req_t req, + struct fuse_in_header *hdr_) { - struct fuse_mknod_in *arg = (struct fuse_mknod_in *) inarg; - char *name = PARAM(arg); - - if (req->f->conn.proto_minor >= 12) - req->ctx.umask = arg->umask; - else - name = (char*)inarg + FUSE_COMPAT_MKNOD_IN_SIZE; - - req->f->op.mknod(req, nodeid, name, arg->mode, arg->rdev); + req->f->op.mknod(req,hdr_); } static void -do_mkdir(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_mkdir(fuse_req_t req, + struct fuse_in_header *hdr_) { - struct fuse_mkdir_in *arg = (struct fuse_mkdir_in *) inarg; - - if(req->f->conn.proto_minor >= 12) - req->ctx.umask = arg->umask; - - req->f->op.mkdir(req, nodeid, PARAM(arg), arg->mode); + req->f->op.mkdir(req,hdr_); } static void -do_unlink(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_unlink(fuse_req_t req, + struct fuse_in_header *hdr_) { - char *name = (char*)inarg; - - req->f->op.unlink(req,nodeid,name); + req->f->op.unlink(req,hdr_); } static void -do_rmdir(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_rmdir(fuse_req_t req, + struct fuse_in_header *hdr_) { - char *name = (char*)inarg; - - req->f->op.rmdir(req, nodeid, name); + req->f->op.rmdir(req,hdr_); } static void -do_symlink(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_symlink(fuse_req_t req, + struct fuse_in_header *hdr_) { - char *name = (char*)inarg; - char *linkname = (name + strlen(name) + 1); - - req->f->op.symlink(req, linkname, nodeid, name); + req->f->op.symlink(req,hdr_); } static void -do_rename(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_rename(fuse_req_t req, + struct fuse_in_header *hdr_) { - struct fuse_rename_in *arg = (struct fuse_rename_in*)inarg; - char *oldname = PARAM(arg); - char *newname = oldname + strlen(oldname) + 1; - - req->f->op.rename(req, nodeid, oldname, arg->newdir, newname); + req->f->op.rename(req,hdr_); } static void -do_link(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_link(fuse_req_t req, + struct fuse_in_header *hdr_) { - struct fuse_link_in *arg = (struct fuse_link_in*)inarg; - - req->f->op.link(req,arg->oldnodeid,nodeid,PARAM(arg)); + req->f->op.link(req,hdr_); } static void -do_create(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_create(fuse_req_t req, + struct fuse_in_header *hdr_) { - struct fuse_create_in *arg = (struct fuse_create_in*)inarg; - fuse_file_info_t fi = {0}; - char *name = PARAM(arg); - - fi.flags = arg->flags; - - if (req->f->conn.proto_minor >= 12) - req->ctx.umask = arg->umask; - else - name = (char*)inarg + sizeof(struct fuse_open_in); - - req->f->op.create(req, nodeid, name, arg->mode, &fi); + req->f->op.create(req,hdr_); } static void -do_open(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_open(fuse_req_t req, + struct fuse_in_header *hdr_) { - fuse_file_info_t fi = {0}; - struct fuse_open_in *arg = (struct fuse_open_in*)inarg; - - fi.flags = arg->flags; - - req->f->op.open(req, nodeid, &fi); + req->f->op.open(req,hdr_); } static void -do_read(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_read(fuse_req_t req, + struct fuse_in_header *hdr_) { - fuse_file_info_t fi = {0}; - struct fuse_read_in *arg = (struct fuse_read_in*)inarg; - - fi.fh = arg->fh; - if (req->f->conn.proto_minor >= 9) - { - fi.lock_owner = arg->lock_owner; - fi.flags = arg->flags; - } - - req->f->op.read(req, nodeid, arg->size, arg->offset, &fi); + req->f->op.read(req,hdr_); } static void -do_write(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_write(fuse_req_t req, + struct fuse_in_header *hdr_) { - char *param; - fuse_file_info_t fi = {0}; - struct fuse_write_in *arg = (struct fuse_write_in*)inarg; - - fi.fh = arg->fh; - fi.writepage = arg->write_flags & 1; - - if(req->f->conn.proto_minor < 9) - { - param = ((char*)arg) + FUSE_COMPAT_WRITE_IN_SIZE; - } - else - { - fi.lock_owner = arg->lock_owner; - fi.flags = arg->flags; - param = PARAM(arg); - } - - req->f->op.write(req,nodeid,param,arg->size,arg->offset,&fi); + req->f->op.write(req,hdr_); } static void -do_flush(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_flush(fuse_req_t req, + struct fuse_in_header *hdr_) { - fuse_file_info_t fi = {0}; - struct fuse_flush_in *arg = (struct fuse_flush_in *) inarg; - - fi.fh = arg->fh; - fi.flush = 1; - if(req->f->conn.proto_minor >= 7) - fi.lock_owner = arg->lock_owner; - - req->f->op.flush(req,nodeid,&fi); + req->f->op.flush(req,hdr_); } static void -do_release(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_release(fuse_req_t req, + struct fuse_in_header *hdr_) { - fuse_file_info_t fi = {0}; - struct fuse_release_in *arg = (struct fuse_release_in*)inarg; - - fi.flags = arg->flags; - fi.fh = arg->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(arg->release_flags & FUSE_RELEASE_FLOCK_UNLOCK) - { - fi.flock_release = 1; - fi.lock_owner = arg->lock_owner; - } - - req->f->op.release(req,nodeid,&fi); + req->f->op.release(req,hdr_); } static void -do_fsync(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_fsync(fuse_req_t req, + struct fuse_in_header *hdr_) { - fuse_file_info_t fi = {0}; - struct fuse_fsync_in *arg = (struct fuse_fsync_in*)inarg; - - fi.fh = arg->fh; - - req->f->op.fsync(req,nodeid,arg->fsync_flags & 1, &fi); + req->f->op.fsync(req,hdr_); } static void -do_opendir(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_opendir(fuse_req_t req, + struct fuse_in_header *hdr_) { - fuse_file_info_t fi = {0}; - struct fuse_open_in *arg = (struct fuse_open_in*)inarg; - - fi.flags = arg->flags; - - req->f->op.opendir(req,nodeid,&fi); + req->f->op.opendir(req,hdr_); } static void -do_readdir(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_readdir(fuse_req_t req, + struct fuse_in_header *hdr_) { - fuse_file_info_t fi = {0}; - struct fuse_read_in *arg = (struct fuse_read_in*)inarg; - - fi.fh = arg->fh; - - req->f->op.readdir(req,nodeid,arg->size,arg->offset,&fi); + req->f->op.readdir(req,hdr_); } static void -do_readdir_plus(fuse_req_t req_, - uint64_t nodeid_, - const void *inarg_) +do_readdir_plus(fuse_req_t req_, + struct fuse_in_header *hdr_) { - const struct fuse_read_in *arg; - fuse_file_info_t ffi = {0}; - - arg = (struct fuse_read_in*)inarg_; - ffi.fh = arg->fh; - - req_->f->op.readdir_plus(req_,nodeid_,arg->size,arg->offset,&ffi); + req_->f->op.readdir_plus(req_,hdr_); } static void -do_releasedir(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_releasedir(fuse_req_t req, + struct fuse_in_header *hdr_) { - fuse_file_info_t fi = {0}; - struct fuse_release_in *arg = (struct fuse_release_in*)inarg; - - fi.flags = arg->flags; - fi.fh = arg->fh; - - req->f->op.releasedir(req,nodeid,&fi); + req->f->op.releasedir(req,hdr_); } static void -do_fsyncdir(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_fsyncdir(fuse_req_t req, + struct fuse_in_header *hdr_) { - fuse_file_info_t fi = {0}; - struct fuse_fsync_in *arg = (struct fuse_fsync_in*)inarg; - - fi.fh = arg->fh; - - req->f->op.fsyncdir(req,nodeid,arg->fsync_flags & 1,&fi); + req->f->op.fsyncdir(req,hdr_); } static void -do_statfs(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_statfs(fuse_req_t req, + struct fuse_in_header *hdr_) { - (void)nodeid; - (void)inarg; - - req->f->op.statfs(req, nodeid); + req->f->op.statfs(req,hdr_); } static void -do_setxattr(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_setxattr(fuse_req_t req, + struct fuse_in_header *hdr_) { - struct fuse_setxattr_in *arg = (struct fuse_setxattr_in*)inarg; - char *name = PARAM(arg); - char *value = name + strlen(name) + 1; - - req->f->op.setxattr(req, nodeid, name, value, arg->size, arg->flags); + req->f->op.setxattr(req,hdr_); } static void -do_getxattr(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_getxattr(fuse_req_t req, + struct fuse_in_header *hdr_) { - struct fuse_getxattr_in *arg = (struct fuse_getxattr_in*)inarg; - - req->f->op.getxattr(req, nodeid, PARAM(arg), arg->size); + req->f->op.getxattr(req,hdr_); } static void -do_listxattr(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_listxattr(fuse_req_t req, + struct fuse_in_header *hdr_) { - struct fuse_getxattr_in *arg = (struct fuse_getxattr_in*)inarg; - - req->f->op.listxattr(req, nodeid, arg->size); + req->f->op.listxattr(req,hdr_); } static void -do_removexattr(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_removexattr(fuse_req_t req, + struct fuse_in_header *hdr_) { - char *name = (char *) inarg; - - req->f->op.removexattr(req, nodeid, name); + req->f->op.removexattr(req,hdr_); } static @@ -1501,20 +1249,10 @@ convert_fuse_file_lock(struct fuse_file_lock *fl, static void -do_getlk(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_getlk(fuse_req_t req, + struct fuse_in_header *hdr_) { - fuse_file_info_t fi = {0}; - struct flock flock; - struct fuse_lk_in *arg = (struct fuse_lk_in*)inarg; - - fi.fh = arg->fh; - fi.lock_owner = arg->owner; - - convert_fuse_file_lock(&arg->lk, &flock); - - req->f->op.getlk(req, nodeid, &fi, &flock); + req->f->op.getlk(req,hdr_); } static @@ -1526,7 +1264,7 @@ do_setlk_common(fuse_req_t req, { struct flock flock; fuse_file_info_t fi = {0}; - struct fuse_lk_in *arg = (struct fuse_lk_in *) inarg; + struct fuse_lk_in *arg = (struct fuse_lk_in*)inarg; fi.fh = arg->fh; fi.lock_owner = arg->owner; @@ -1563,71 +1301,42 @@ do_setlk_common(fuse_req_t req, static void -do_setlk(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_setlk(fuse_req_t req, + struct fuse_in_header *hdr_) { - do_setlk_common(req, nodeid, inarg, 0); + do_setlk_common(req, hdr_->nodeid, &hdr_[1], 0); } static void -do_setlkw(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_setlkw(fuse_req_t req, + struct fuse_in_header *hdr_) { - do_setlk_common(req, nodeid, inarg, 1); + do_setlk_common(req, hdr_->nodeid, &hdr_[1], 1); } static void do_interrupt(fuse_req_t req, - uint64_t nodeid, - const void *inarg) + struct fuse_in_header *hdr_) { destroy_req(req); } static void -do_bmap(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_bmap(fuse_req_t req, + struct fuse_in_header *hdr_) { - struct fuse_bmap_in *arg = (struct fuse_bmap_in*)inarg; - - req->f->op.bmap(req,nodeid,arg->blocksize,arg->block); + req->f->op.bmap(req,hdr_); } static void do_ioctl(fuse_req_t req, - uint64_t nodeid, - const void *inarg) + struct fuse_in_header *hdr_) { - fuse_file_info_t fi = {0}; - struct fuse_ioctl_in *arg = (struct fuse_ioctl_in *) inarg; - unsigned int flags = arg->flags; - void *in_buf = arg->in_size ? PARAM(arg) : NULL; - - if((flags & FUSE_IOCTL_DIR) && !(req->f->conn.want & FUSE_CAP_IOCTL_DIR)) - { - fuse_reply_err(req,ENOTTY); - return; - } - - fi.fh = arg->fh; - - if((sizeof(void *) == 4) && - (req->f->conn.proto_minor >= 16) && - !(flags & FUSE_IOCTL_32BIT)) - { - req->ioctl_64bit = 1; - } - - req->f->op.ioctl(req, nodeid, (unsigned long)arg->cmd, - (void *)(uintptr_t)arg->arg, &fi, flags, - in_buf, arg->in_size, arg->out_size); + req->f->op.ioctl(req, hdr_); } void @@ -1638,58 +1347,30 @@ fuse_pollhandle_destroy(fuse_pollhandle_t *ph) static void -do_poll(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_poll(fuse_req_t req, + struct fuse_in_header *hdr_) { - fuse_file_info_t fi = {0}; - fuse_pollhandle_t *ph = NULL; - struct fuse_poll_in *arg = (struct fuse_poll_in *) inarg; - - fi.fh = arg->fh; - - if(arg->flags & FUSE_POLL_SCHEDULE_NOTIFY) - { - ph = malloc(sizeof(fuse_pollhandle_t)); - if (ph == NULL) { - fuse_reply_err(req, ENOMEM); - return; - } - ph->kh = arg->kh; - ph->ch = req->ch; - ph->f = req->f; - } - - req->f->op.poll(req,nodeid,&fi,ph); + req->f->op.poll(req,hdr_); } static void -do_fallocate(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_fallocate(fuse_req_t req, + struct fuse_in_header *hdr_) { - fuse_file_info_t fi = {0}; - struct fuse_fallocate_in *arg = (struct fuse_fallocate_in *) inarg; - - fi.fh = arg->fh; - - req->f->op.fallocate(req, nodeid, arg->mode, arg->offset, arg->length, &fi); + req->f->op.fallocate(req,hdr_); } static void -do_init(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_init(fuse_req_t req, + struct fuse_in_header *hdr_) { struct fuse_init_out outarg = {0}; - struct fuse_init_in *arg = (struct fuse_init_in *) inarg; + struct fuse_init_in *arg = (struct fuse_init_in *) &hdr_[1]; struct fuse_ll *f = req->f; size_t bufsize = fuse_chan_bufsize(req->ch); - (void)nodeid; - if(f->debug) debug_fuse_init_in(arg); @@ -1872,15 +1553,11 @@ do_init(fuse_req_t req, static void -do_destroy(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_destroy(fuse_req_t req, + struct fuse_in_header *hdr_) { struct fuse_ll *f = req->f; - (void) nodeid; - (void) inarg; - f->got_destroy = 1; f->op.destroy(f->userdata); @@ -1919,9 +1596,8 @@ list_init_nreq(struct fuse_notify_req *nreq) static void -do_notify_reply(fuse_req_t req, - uint64_t nodeid, - const void *inarg) +do_notify_reply(fuse_req_t req, + struct fuse_in_header *hdr_) { struct fuse_ll *f = req->f; struct fuse_notify_req *nreq; @@ -1940,32 +1616,15 @@ do_notify_reply(fuse_req_t req, pthread_mutex_unlock(&f->lock); if(nreq != head) - nreq->reply(nreq, req, nodeid, inarg); + nreq->reply(nreq, req, hdr_->nodeid, &hdr_[1]); } static void -do_copy_file_range(fuse_req_t req_, - uint64_t nodeid_in_, - const void *arg_) - +do_copy_file_range(fuse_req_t req_, + struct fuse_in_header *hdr_) { - fuse_file_info_t ffi_in = {0}; - fuse_file_info_t ffi_out = {0}; - struct fuse_copy_file_range_in *arg = (struct fuse_copy_file_range_in*)arg_; - - ffi_in.fh = arg->fh_in; - ffi_out.fh = arg->fh_out; - - req_->f->op.copy_file_range(req_, - nodeid_in_, - arg->off_in, - &ffi_in, - arg->nodeid_out, - arg->off_out, - &ffi_out, - arg->len, - arg->flags); + req_->f->op.copy_file_range(req_,hdr_); } static @@ -2233,53 +1892,53 @@ fuse_req_ctx(fuse_req_t req) } static struct { - void (*func)(fuse_req_t, uint64_t, const void *); + void (*func)(fuse_req_t, struct fuse_in_header *); 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_READDIRPLUS] = { do_readdir_plus, "READDIR_PLUS" }, - [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_IOCTL] = { do_ioctl, "IOCTL" }, - [FUSE_POLL] = { do_poll, "POLL" }, - [FUSE_FALLOCATE] = { do_fallocate, "FALLOCATE" }, - [FUSE_DESTROY] = { do_destroy, "DESTROY" }, - [FUSE_NOTIFY_REPLY] = { do_notify_reply, "NOTIFY_REPLY" }, - [FUSE_BATCH_FORGET] = { do_batch_forget, "BATCH_FORGET" }, - [FUSE_COPY_FILE_RANGE] = { do_copy_file_range, "COPY_FILE_RANGE" }, + [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_READDIRPLUS] = { do_readdir_plus, "READDIR_PLUS" }, + [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_IOCTL] = { do_ioctl, "IOCTL" }, + [FUSE_POLL] = { do_poll, "POLL" }, + [FUSE_FALLOCATE] = { do_fallocate, "FALLOCATE" }, + [FUSE_DESTROY] = { do_destroy, "DESTROY" }, + [FUSE_NOTIFY_REPLY] = { do_notify_reply, "NOTIFY_REPLY" }, + [FUSE_BATCH_FORGET] = { do_batch_forget, "BATCH_FORGET" }, + [FUSE_COPY_FILE_RANGE] = { do_copy_file_range, "COPY_FILE_RANGE" }, }; #define FUSE_MAXOP (sizeof(fuse_ll_ops) / sizeof(fuse_ll_ops[0])) @@ -2292,7 +1951,6 @@ fuse_ll_process_buf(void *data, { struct fuse_ll *f = (struct fuse_ll*)data; struct fuse_in_header *in; - const void *inarg; struct fuse_req *req; int err; @@ -2338,8 +1996,7 @@ fuse_ll_process_buf(void *data, if(in->opcode >= FUSE_MAXOP) goto reply_err; - inarg = (void*)&in[1]; - fuse_ll_ops[in->opcode].func(req, in->nodeid, inarg); + fuse_ll_ops[in->opcode].func(req, in); return; @@ -2349,34 +2006,34 @@ fuse_ll_process_buf(void *data, } enum { - KEY_HELP, - KEY_VERSION, + KEY_HELP, + KEY_VERSION, }; static const struct fuse_opt fuse_ll_opts[] = { - { "debug", offsetof(struct fuse_ll, debug), 1 }, - { "-d", offsetof(struct fuse_ll, debug), 1 }, - { "max_readahead=%u", offsetof(struct fuse_ll, conn.max_readahead), 0 }, - { "max_background=%u", offsetof(struct fuse_ll, conn.max_background), 0 }, - { "congestion_threshold=%u", - offsetof(struct fuse_ll, conn.congestion_threshold), 0 }, - { "no_remote_lock", offsetof(struct fuse_ll, no_remote_posix_lock), 1}, - { "no_remote_lock", offsetof(struct fuse_ll, no_remote_flock), 1}, - { "no_remote_flock", offsetof(struct fuse_ll, no_remote_flock), 1}, - { "no_remote_posix_lock", offsetof(struct fuse_ll, no_remote_posix_lock), 1}, - { "splice_write", offsetof(struct fuse_ll, splice_write), 1}, - { "no_splice_write", offsetof(struct fuse_ll, no_splice_write), 1}, - { "splice_move", offsetof(struct fuse_ll, splice_move), 1}, - { "no_splice_move", offsetof(struct fuse_ll, no_splice_move), 1}, - { "splice_read", offsetof(struct fuse_ll, splice_read), 1}, - { "no_splice_read", offsetof(struct fuse_ll, no_splice_read), 1}, - 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 }, + { "max_readahead=%u", offsetof(struct fuse_ll, conn.max_readahead), 0 }, + { "max_background=%u", offsetof(struct fuse_ll, conn.max_background), 0 }, + { "congestion_threshold=%u", + offsetof(struct fuse_ll, conn.congestion_threshold), 0 }, + { "no_remote_lock", offsetof(struct fuse_ll, no_remote_posix_lock), 1}, + { "no_remote_lock", offsetof(struct fuse_ll, no_remote_flock), 1}, + { "no_remote_flock", offsetof(struct fuse_ll, no_remote_flock), 1}, + { "no_remote_posix_lock", offsetof(struct fuse_ll, no_remote_posix_lock), 1}, + { "splice_write", offsetof(struct fuse_ll, splice_write), 1}, + { "no_splice_write", offsetof(struct fuse_ll, no_splice_write), 1}, + { "splice_move", offsetof(struct fuse_ll, splice_move), 1}, + { "no_splice_move", offsetof(struct fuse_ll, no_splice_move), 1}, + { "splice_read", offsetof(struct fuse_ll, splice_read), 1}, + { "no_splice_read", offsetof(struct fuse_ll, no_splice_read), 1}, + 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 diff --git a/src/mergerfs.cpp b/src/mergerfs.cpp index 24a76eaa..f947c251 100644 --- a/src/mergerfs.cpp +++ b/src/mergerfs.cpp @@ -66,7 +66,7 @@ #include "fuse_truncate.hpp" #include "fuse_unlink.hpp" #include "fuse_utimens.hpp" -#include "fuse_write_buf.hpp" +#include "fuse_write.hpp" #include "fuse.h" @@ -129,7 +129,7 @@ namespace l ops_.truncate = FUSE::truncate; ops_.unlink = FUSE::unlink; ops_.utimens = FUSE::utimens; - ops_.write_buf = (nullrw_ ? FUSE::write_buf_null : FUSE::write_buf); + ops_.write = (nullrw_ ? FUSE::write_null : FUSE::write); return; }