Browse Source

Merge pull request #1104 from trapexit/ll

Remove libfuse abstraction in prep for adding request data
foo
trapexit 2 years ago
committed by GitHub
parent
commit
a2a12afb34
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 100
      libfuse/include/fuse.h
  2. 190
      libfuse/include/fuse_lowlevel.h
  3. 14
      libfuse/include/fuse_pollhandle.h
  4. 1451
      libfuse/lib/fuse.c
  5. 517
      libfuse/lib/fuse_lowlevel.c
  6. 4
      src/mergerfs.cpp

100
libfuse/include/fuse.h

@ -475,8 +475,9 @@ struct fuse_operations
*
* Introduced in version 2.9
*/
int (*write_buf) (const fuse_file_info_t *ffi,
struct fuse_bufvec *buf,
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);
/**

190
libfuse/include/fuse_lowlevel.h

@ -25,6 +25,7 @@
#include "extern_c.h"
#include "fuse_common.h"
#include "fuse_kernel.h"
#include <fcntl.h>
#include <stdint.h>
@ -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
@ -908,39 +906,7 @@ struct fuse_lowlevel_ops
* @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);
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
@ -1054,14 +1020,7 @@ struct fuse_lowlevel_ops
* @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);
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

14
libfuse/include/fuse_pollhandle.h

@ -0,0 +1,14 @@
#pragma once
#include <stdint.h>
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;
};

1451
libfuse/lib/fuse.c
File diff suppressed because it is too large
View File

517
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 <stdio.h>
#include <stdlib.h>
@ -42,13 +43,6 @@
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;
};
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,
@ -1009,478 +986,249 @@ fuse_reply_poll(fuse_req_t req,
static
void
do_lookup(fuse_req_t req,
uint64_t nodeid,
const void *inarg)
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)
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)
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)
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_)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
{
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)
struct fuse_in_header *hdr_)
{
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)
{
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)
struct fuse_in_header *hdr_)
{
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)
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)
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)
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)
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)
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_)
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)
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)
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)
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)
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)
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)
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)
struct fuse_in_header *hdr_)
{
char *name = (char *) inarg;
req->f->op.removexattr(req, nodeid, name);
req->f->op.removexattr(req,hdr_);
}
static
@ -1502,19 +1250,9 @@ convert_fuse_file_lock(struct fuse_file_lock *fl,
static
void
do_getlk(fuse_req_t req,
uint64_t nodeid,
const void *inarg)
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
@ -1564,26 +1302,23 @@ do_setlk_common(fuse_req_t req,
static
void
do_setlk(fuse_req_t req,
uint64_t nodeid,
const void *inarg)
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)
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);
}
@ -1591,43 +1326,17 @@ do_interrupt(fuse_req_t req,
static
void
do_bmap(fuse_req_t req,
uint64_t nodeid,
const void *inarg)
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)
{
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))
struct fuse_in_header *hdr_)
{
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
@ -1639,57 +1348,29 @@ fuse_pollhandle_destroy(fuse_pollhandle_t *ph)
static
void
do_poll(fuse_req_t req,
uint64_t nodeid,
const void *inarg)
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)
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)
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);
@ -1873,14 +1554,10 @@ do_init(fuse_req_t req,
static
void
do_destroy(fuse_req_t req,
uint64_t nodeid,
const void *inarg)
struct fuse_in_header *hdr_)
{
struct fuse_ll *f = req->f;
(void) nodeid;
(void) inarg;
f->got_destroy = 1;
f->op.destroy(f->userdata);
@ -1920,8 +1597,7 @@ list_init_nreq(struct fuse_notify_req *nreq)
static
void
do_notify_reply(fuse_req_t req,
uint64_t nodeid,
const void *inarg)
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_)
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,7 +1892,7 @@ 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[] =
{
@ -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;

4
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;
}

Loading…
Cancel
Save