Browse Source

Rework how fuse request context is handled (#1543)

pull/1544/head
trapexit 3 days ago
committed by GitHub
parent
commit
0371f03def
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 685
      libfuse/include/fuse.h
  2. 28
      libfuse/include/fuse_common.h
  3. 185
      libfuse/include/fuse_lowlevel.h
  4. 15
      libfuse/include/fuse_req.h
  5. 16
      libfuse/include/fuse_req_ctx.h
  6. 1679
      libfuse/lib/fuse.cpp
  7. 21
      libfuse/lib/fuse_i.h
  8. 2
      libfuse/lib/fuse_loop.cpp
  9. 191
      libfuse/lib/fuse_lowlevel.cpp
  10. 57
      libfuse/lib/helper.c
  11. 6
      src/fuse_access.cpp
  12. 4
      src/fuse_access.hpp
  13. 8
      src/fuse_bmap.cpp
  14. 9
      src/fuse_bmap.hpp
  15. 6
      src/fuse_chmod.cpp
  16. 5
      src/fuse_chmod.hpp
  17. 6
      src/fuse_chown.cpp
  18. 5
      src/fuse_chown.hpp
  19. 3
      src/fuse_copy_file_range.cpp
  20. 3
      src/fuse_copy_file_range.hpp
  21. 30
      src/fuse_create.cpp
  22. 3
      src/fuse_create.hpp
  23. 6
      src/fuse_fallocate.cpp
  24. 3
      src/fuse_fallocate.hpp
  25. 6
      src/fuse_fchmod.cpp
  26. 5
      src/fuse_fchmod.hpp
  27. 6
      src/fuse_fchown.cpp
  28. 3
      src/fuse_fchown.hpp
  29. 6
      src/fuse_fgetattr.cpp
  30. 3
      src/fuse_fgetattr.hpp
  31. 6
      src/fuse_flock.cpp
  32. 3
      src/fuse_flock.hpp
  33. 3
      src/fuse_flush.cpp
  34. 3
      src/fuse_flush.hpp
  35. 3
      src/fuse_fsync.cpp
  36. 3
      src/fuse_fsync.hpp
  37. 3
      src/fuse_fsyncdir.cpp
  38. 3
      src/fuse_fsyncdir.hpp
  39. 6
      src/fuse_ftruncate.cpp
  40. 3
      src/fuse_ftruncate.hpp
  41. 6
      src/fuse_futimens.cpp
  42. 3
      src/fuse_futimens.hpp
  43. 18
      src/fuse_getattr.cpp
  44. 9
      src/fuse_getattr.hpp
  45. 6
      src/fuse_getxattr.cpp
  46. 5
      src/fuse_getxattr.hpp
  47. 19
      src/fuse_ioctl.cpp
  48. 3
      src/fuse_ioctl.hpp
  49. 65
      src/fuse_link.cpp
  50. 3
      src/fuse_link.hpp
  51. 6
      src/fuse_listxattr.cpp
  52. 5
      src/fuse_listxattr.hpp
  53. 3
      src/fuse_lock.cpp
  54. 3
      src/fuse_lock.hpp
  55. 10
      src/fuse_mkdir.cpp
  56. 5
      src/fuse_mkdir.hpp
  57. 10
      src/fuse_mknod.cpp
  58. 5
      src/fuse_mknod.hpp
  59. 40
      src/fuse_open.cpp
  60. 3
      src/fuse_open.hpp
  61. 3
      src/fuse_opendir.cpp
  62. 3
      src/fuse_opendir.hpp
  63. 13
      src/fuse_passthrough.hpp
  64. 4
      src/fuse_poll.cpp
  65. 3
      src/fuse_poll.hpp
  66. 8
      src/fuse_read.cpp
  67. 6
      src/fuse_read.hpp
  68. 10
      src/fuse_readdir.cpp
  69. 6
      src/fuse_readdir.hpp
  70. 3
      src/fuse_readdir_base.hpp
  71. 8
      src/fuse_readdir_cor.cpp
  72. 3
      src/fuse_readdir_cor.hpp
  73. 8
      src/fuse_readdir_cosr.cpp
  74. 3
      src/fuse_readdir_cosr.hpp
  75. 3
      src/fuse_readdir_plus.cpp
  76. 3
      src/fuse_readdir_plus.hpp
  77. 6
      src/fuse_readdir_seq.cpp
  78. 3
      src/fuse_readdir_seq.hpp
  79. 6
      src/fuse_readlink.cpp
  80. 5
      src/fuse_readlink.hpp
  81. 22
      src/fuse_release.cpp
  82. 3
      src/fuse_release.hpp
  83. 3
      src/fuse_releasedir.cpp
  84. 3
      src/fuse_releasedir.hpp
  85. 2
      src/fuse_removemapping.cpp
  86. 2
      src/fuse_removemapping.hpp
  87. 6
      src/fuse_removexattr.cpp
  88. 5
      src/fuse_removexattr.hpp
  89. 51
      src/fuse_rename.cpp
  90. 5
      src/fuse_rename.hpp
  91. 6
      src/fuse_rmdir.cpp
  92. 5
      src/fuse_rmdir.hpp
  93. 3
      src/fuse_setupmapping.cpp
  94. 3
      src/fuse_setupmapping.hpp
  95. 16
      src/fuse_setxattr.cpp
  96. 5
      src/fuse_setxattr.hpp
  97. 6
      src/fuse_statfs.cpp
  98. 5
      src/fuse_statfs.hpp
  99. 6
      src/fuse_statx.hpp
  100. 15
      src/fuse_statx_supported.icpp

685
libfuse/include/fuse.h

@ -12,6 +12,7 @@
#include "extern_c.h"
#include "fuse_common.h"
#include "fuse_kernel.h"
#include "fuse_req_ctx.h"
#include <fcntl.h>
#include <time.h>
@ -28,12 +29,6 @@ EXTERN_C_BEGIN
* Basic FUSE API *
* ----------------------------------------------------------- */
/** Handle for a FUSE filesystem */
struct fuse;
/** Structure containing a raw command */
struct fuse_cmd;
struct fuse_dirents_t;
typedef struct fuse_dirents_t fuse_dirents_t;
@ -61,516 +56,192 @@ typedef struct fuse_dirents_t fuse_dirents_t;
*/
struct fuse_operations
{
/** Get file attributes.
*
* Similar to stat(). The 'st_dev' and 'st_blksize' fields are
* ignored. The 'st_ino' field is ignored except if the 'use_ino'
* mount option is given.
*/
int (*getattr) (const char *, struct stat *, fuse_timeouts_t *);
/** Read the target of a symbolic link
*
* The buffer should be filled with a null terminated string. The
* buffer size argument includes the space for the terminating
* null character. If the linkname is too long to fit in the
* buffer, it should be truncated. The return value should be 0
* for success.
*/
int (*readlink) (const char *, char *, size_t);
/** Create a file node
*
* This is called for creation of all non-directory, non-symlink
* nodes. If the filesystem defines a create() method, then for
* regular files that will be called instead.
*/
int (*mknod) (const char *, mode_t, dev_t);
/** Create a directory
*
* Note that the mode argument may not have the type specification
* bits set, i.e. S_ISDIR(mode) can be false. To obtain the
* correct directory type bits use mode|S_IFDIR
* */
int (*mkdir) (const char *, mode_t);
/** Remove a file */
int (*unlink) (const char *);
/** Remove a directory */
int (*rmdir) (const char *);
/** Create a symbolic link */
int (*symlink) (const char *, const char *, struct stat *, fuse_timeouts_t *);
/** Rename a file */
int (*rename) (const char *, const char *);
/** Create a hard link to a file */
int (*link) (const char *, const char *, struct stat *, fuse_timeouts_t *);
/** Change the permission bits of a file */
int (*chmod) (const char *, mode_t);
int (*fchmod)(const uint64_t, const mode_t);
/** Change the owner and group of a file */
int (*chown) (const char *, uid_t, gid_t);
int (*fchown)(const uint64_t, const uid_t, const gid_t);
/** Change the size of a file */
int (*truncate) (const char *, off_t);
/** File open operation
*
* No creation (O_CREAT, O_EXCL) and by default also no
* truncation (O_TRUNC) flags will be passed to open(). If an
* application specifies O_TRUNC, fuse first calls truncate()
* and then open(). Only if 'atomic_o_trunc' has been
* specified and kernel version is 2.6.24 or later, O_TRUNC is
* passed on to open.
*
* Unless the 'default_permissions' mount option is given,
* open should check if the operation is permitted for the
* given flags. Optionally open may also return an arbitrary
* filehandle in the fuse_file_info structure, which will be
* passed to all file operations.
*
* Changed in version 2.2
*/
int (*open) (const char *, fuse_file_info_t *);
/** Get file system statistics
*
* The 'f_frsize', 'f_favail', 'f_fsid' and 'f_flag' fields are ignored
*
* Replaced 'struct statfs' parameter with 'struct statvfs' in
* version 2.5
*/
int (*statfs) (const char *, struct statvfs *);
/** Possibly flush cached data
*
* BIG NOTE: This is not equivalent to fsync(). It's not a
* request to sync dirty data.
*
* Flush is called on each close() of a file descriptor. So if a
* filesystem wants to return write errors in close() and the file
* has cached dirty data, this is a good place to write back data
* and return any errors. Since many applications ignore close()
* errors this is not always useful.
*
* NOTE: The flush() method may be called more than once for each
* open(). This happens if more than one file descriptor refers
* to an opened file due to dup(), dup2() or fork() calls. It is
* not possible to determine if a flush is final, so each flush
* should be treated equally. Multiple write-flush sequences are
* relatively rare, so this shouldn't be a problem.
*
* Filesystems shouldn't assume that flush will always be called
* after some writes, or that if will be called at all.
*
* Changed in version 2.2
*/
int (*flush) (const fuse_file_info_t *);
/** Release an open file
*
* Release is called when there are no more references to an open
* file: all file descriptors are closed and all memory mappings
* are unmapped.
*
* For every open() call there will be exactly one release() call
* with the same flags and file descriptor. It is possible to
* have a file opened more than once, in which case only the last
* release will mean, that no more reads/writes will happen on the
* file. The return value of release is ignored.
*
* Changed in version 2.2
*/
int (*release) (const fuse_file_info_t *);
/** Synchronize file contents
*
* If the datasync parameter is non-zero, then only the user data
* should be flushed, not the meta data.
*
* Changed in version 2.2
*/
int (*fsync) (const uint64_t, int);
/** Set extended attributes */
int (*setxattr) (const char *, const char *, const char *, size_t, int);
/** Get extended attributes */
int (*getxattr) (const char *, const char *, char *, size_t);
/** List extended attributes */
int (*listxattr) (const char *, char *, size_t);
/** Remove extended attributes */
int (*removexattr) (const char *, const char *);
/** Open directory
*
* Unless the 'default_permissions' mount option is given,
* this method should check if opendir is permitted for this
* directory. Optionally opendir may also return an arbitrary
* filehandle in the fuse_file_info structure, which will be
* passed to readdir, closedir and fsyncdir.
*
* Introduced in version 2.3
*/
int (*opendir) (const char *,
int (*getattr)(const fuse_req_ctx_t *,
const char *,
struct stat *,
fuse_timeouts_t *);
int (*readlink)(const fuse_req_ctx_t *,
const char *,
char *,
size_t);
int (*mknod)(const fuse_req_ctx_t *,
const char *,
mode_t,
dev_t);
int (*mkdir)(const fuse_req_ctx_t *,
const char *,
mode_t);
int (*unlink)(const fuse_req_ctx_t *,
const char *);
int (*rmdir)(const fuse_req_ctx_t *,
const char *);
int (*symlink)(const fuse_req_ctx_t *,
const char *,
const char *,
struct stat *,
fuse_timeouts_t *);
int (*rename)(const fuse_req_ctx_t *,
const char *,
const char *);
int (*link)(const fuse_req_ctx_t *,
const char *,
const char *,
struct stat *,
fuse_timeouts_t *);
int (*chmod)(const fuse_req_ctx_t *,
const char *,
mode_t);
int (*fchmod)(const fuse_req_ctx_t *,
const uint64_t,
const mode_t);
int (*chown)(const fuse_req_ctx_t *,
const char *,
uid_t,
gid_t);
int (*fchown)(const fuse_req_ctx_t *,
const uint64_t,
const uid_t,
const gid_t);
int (*truncate)(const fuse_req_ctx_t *,
const char *,
off_t);
int (*open)(const fuse_req_ctx_t *,
const char *,
fuse_file_info_t *);
/** Read directory
*
* This supersedes the old getdir() interface. New applications
* should use this.
*
* The filesystem may choose between two modes of operation:
*
* 1) The readdir implementation ignores the offset parameter, and
* passes zero to the filler function's offset. The filler
* function will not return '1' (unless an error happens), so the
* whole directory is read in a single readdir operation. This
* works just like the old getdir() method.
*
* 2) The readdir implementation keeps track of the offsets of the
* directory entries. It uses the offset parameter and always
* passes non-zero offset to the filler function. When the buffer
* is full (or an error happens) the filler function will return
* '1'.
*
* Introduced in version 2.3
*/
int (*readdir)(const fuse_file_info_t *,
int (*statfs)(const fuse_req_ctx_t *,
const char *,
struct statvfs *);
int (*flush)(const fuse_req_ctx_t *,
const fuse_file_info_t *);
int (*release)(const fuse_req_ctx_t *,
const fuse_file_info_t *);
int (*fsync)(const fuse_req_ctx_t *,
const uint64_t,
int);
int (*setxattr)(const fuse_req_ctx_t *,
const char *,
const char *,
const char *,
size_t,
int);
int (*getxattr)(const fuse_req_ctx_t *,
const char *,
const char *,
char *,
size_t);
int (*listxattr)(const fuse_req_ctx_t *,
const char *,
char *,
size_t);
int (*removexattr)(const fuse_req_ctx_t *,
const char *,
const char *);
int (*opendir)(const fuse_req_ctx_t *,
const char *,
fuse_file_info_t *);
int (*readdir)(const fuse_req_ctx_t *,
const fuse_file_info_t *,
fuse_dirents_t *);
int (*readdir_plus)(const fuse_file_info_t *,
int (*readdir_plus)(const fuse_req_ctx_t *,
const fuse_file_info_t *,
fuse_dirents_t *);
/** Release directory
*
* Introduced in version 2.3
*/
int (*releasedir) (const fuse_file_info_t *);
/** Synchronize directory contents
*
* If the datasync parameter is non-zero, then only the user data
* should be flushed, not the meta data
*
* Introduced in version 2.3
*/
int (*fsyncdir) (const fuse_file_info_t *, int);
/**
* Initialize filesystem
*
* The return value will passed in the private_data field of
* fuse_context to all file operations and as a parameter to the
* destroy() method.
*
* Introduced in version 2.3
* Changed in version 2.6
*/
int (*releasedir)(const fuse_req_ctx_t *,
const fuse_file_info_t *);
int (*fsyncdir)(const fuse_req_ctx_t *,
const fuse_file_info_t *,
int);
void *(*init)(struct fuse_conn_info *conn);
/**
* Clean up filesystem
*
* Called on filesystem exit.
*
* Introduced in version 2.3
*/
void (*destroy)(void);
/**
* Check file access permissions
*
* This will be called for the access() system call. If the
* 'default_permissions' mount option is given, this method is not
* called.
*
* This method is not called under Linux kernel versions 2.4.x
*
* Introduced in version 2.5
*/
int (*access) (const char *, int);
/**
* Create and open a file
*
* If the file does not exist, first create it with the specified
* mode, and then open it.
*
* If this method is not implemented or under Linux kernel
* versions earlier than 2.6.15, the mknod() and open() methods
* will be called instead.
*
* Introduced in version 2.5
*/
int (*create) (const char *, mode_t, fuse_file_info_t *);
/**
* Change the size of an open file
*
* This method is called instead of the truncate() method if the
* truncation was invoked from an ftruncate() system call.
*
* If this method is not implemented or under Linux kernel
* versions earlier than 2.6.15, the truncate() method will be
* called instead.
*
* Introduced in version 2.5
*/
int (*ftruncate) (const uint64_t, off_t);
/**
* Get attributes from an open file
*
* This method is called instead of the getattr() method if the
* file information is available.
*
* Currently this is only called after the create() method if that
* is implemented (see above). Later it may be called for
* invocations of fstat() too.
*
* Introduced in version 2.5
*/
int (*fgetattr) (const uint64_t, struct stat *, fuse_timeouts_t *);
/**
* Perform POSIX file locking operation
*
* The cmd argument will be either F_GETLK, F_SETLK or F_SETLKW.
*
* For the meaning of fields in 'struct flock' see the man page
* for fcntl(2). The l_whence field will always be set to
* SEEK_SET.
*
* For checking lock ownership, the 'fuse_file_info->owner'
* argument must be used.
*
* For F_GETLK operation, the library will first check currently
* held locks, and if a conflicting lock is found it will return
* information without calling this method. This ensures, that
* for local locks the l_pid field is correctly filled in. The
* results may not be accurate in case of race conditions and in
* the presence of hard links, but it's unlikely that an
* application would rely on accurate GETLK results in these
* cases. If a conflicting lock is not found, this method will be
* called, and the filesystem may fill out l_pid by a meaningful
* value, or it may leave this field zero.
*
* For F_SETLK and F_SETLKW the l_pid field will be set to the pid
* of the process performing the locking operation.
*
* Note: if this method is not implemented, the kernel will still
* allow file locking to work locally. Hence it is only
* interesting for network filesystems and similar.
*
* Introduced in version 2.6
*/
int (*lock) (const fuse_file_info_t *,
int (*access)(const fuse_req_ctx_t *,
const char *,
int);
int (*create)(const fuse_req_ctx_t *,
const char *,
mode_t,
fuse_file_info_t *);
int (*ftruncate)(const fuse_req_ctx_t *,
const uint64_t,
off_t);
int (*fgetattr)(const fuse_req_ctx_t *,
const uint64_t,
struct stat *,
fuse_timeouts_t *);
int (*lock)(const fuse_req_ctx_t *,
const fuse_file_info_t *,
int cmd,
struct flock *);
/**
* Change the access and modification times of a file with
* nanosecond resolution
*
* This supersedes the old utime() interface. New applications
* should use this.
*
* See the utimensat(2) man page for details.
*
* Introduced in version 2.6
*/
int (*utimens)(const char *, const struct timespec tv[2]);
int (*futimens)(const uint64_t fh, const struct timespec tv[2]);
/**
* Map block index within file to block index within device
*
* Note: This makes sense only for block device backed filesystems
* mounted with the 'blkdev' option
*
* Introduced in version 2.6
*/
int (*bmap) (const char *, size_t blocksize, uint64_t *idx);
/**
* Ioctl
*
* flags will have FUSE_IOCTL_COMPAT set for 32bit ioctls in
* 64bit environment. The size and direction of data is
* determined by _IOC_*() decoding of cmd. For _IOC_NONE,
* data will be NULL, for _IOC_WRITE data is out area, for
* _IOC_READ in area and if both are set in/out area. In all
* non-NULL cases, the area is of _IOC_SIZE(cmd) bytes.
*
* If flags has FUSE_IOCTL_DIR then the fuse_file_info refers to a
* directory file handle.
*
* Introduced in version 2.8
*/
int (*ioctl) (const fuse_file_info_t *ffi,
int (*utimens)(const fuse_req_ctx_t *,
const char *,
const struct timespec tv[2]);
int (*futimens)(const fuse_req_ctx_t *,
const uint64_t fh,
const struct timespec tv[2]);
int (*bmap)(const fuse_req_ctx_t *,
const char *,
size_t blocksize,
uint64_t *idx);
int (*ioctl)(const fuse_req_ctx_t *ctx,
const fuse_file_info_t *ffi,
unsigned long cmd,
void *arg,
unsigned int flags,
void *data,
uint32_t *out_bufsz);
/**
* Poll for IO readiness events
*
* Note: If ph is non-NULL, the client should notify
* when IO readiness events occur by calling
* fuse_notify_poll() with the specified ph.
*
* Regardless of the number of times poll with a non-NULL ph
* is received, single notification is enough to clear all.
* Notifying more times incurs overhead but doesn't harm
* correctness.
*
* The callee is responsible for destroying ph with
* fuse_pollhandle_destroy() when no longer in use.
*
* Introduced in version 2.8
*/
int (*poll) (const fuse_file_info_t *ffi,
int (*poll)(const fuse_req_ctx_t *,
const fuse_file_info_t *ffi,
fuse_pollhandle_t *ph,
unsigned *reventsp);
/** Write contents of buffer to an open file
*
* Similar to the write() method, but data is supplied in a
* generic buffer. Use fuse_buf_copy() to transfer data to
* the destination.
*
* Introduced in version 2.9
*/
int (*write) (const fuse_file_info_t *ffi,
int (*write)(const fuse_req_ctx_t *,
const fuse_file_info_t *ffi,
const char *data,
size_t size,
off_t off);
/** Store data from an open file in a buffer
*
* Similar to the read() method, but data is stored and
* returned in a generic buffer.
*
* No actual copying of data has to take place, the source
* file descriptor may simply be stored in the buffer for
* later data transfer.
*
* The buffer must be allocated dynamically and stored at the
* location pointed to by bufp. If the buffer contains memory
* regions, they too must be allocated using malloc(). The
* allocated memory will be freed by the caller.
*
* Introduced in version 2.9
*/
int (*read)(const fuse_file_info_t *ffi,
int (*read)(const fuse_req_ctx_t *,
const fuse_file_info_t *ffi,
char *buf,
size_t size,
off_t off);
/**
* Perform BSD file locking operation
*
* The op argument will be either LOCK_SH, LOCK_EX or LOCK_UN
*
* Nonblocking requests will be indicated by ORing LOCK_NB to
* the above operations
*
* For more information see the flock(2) manual page.
*
* Additionally fi->owner will be set to a value unique to
* this open file. This same value will be supplied to
* ->release() when the file is released.
*
* Note: if this method is not implemented, the kernel will still
* allow file locking to work locally. Hence it is only
* interesting for network filesystems and similar.
*
* Introduced in version 2.9
*/
int (*flock) (const fuse_file_info_t *, int op);
/**
* Allocates space for an open file
*
* This function ensures that required space is allocated for specified
* file. If this function returns success then any subsequent write
* request to specified range is guaranteed not to fail because of lack
* of space on the file system media.
*
* Introduced in version 2.9.1
*/
int (*fallocate) (const uint64_t, int, off_t, off_t);
/**
* Copy a range of data from one file to another
*
* Performs an optimized copy between two file descriptors without
* the additional cost of transferring data through the FUSE kernel
* module to user space (glibc) and then back into the FUSE filesystem
* again.
*
* In case this method is not implemented, glibc falls back to
* reading data from the source and writing to the
* destination. Effectively doing an inefficient copy of the
* data.
*/
ssize_t (*copy_file_range)(const fuse_file_info_t *src_fi,
int (*flock)(const fuse_req_ctx_t *,
const fuse_file_info_t *,
int op);
int (*fallocate)(const fuse_req_ctx_t *,
const uint64_t,
int,
off_t,
off_t);
ssize_t (*copy_file_range)(const fuse_req_ctx_t *,
const fuse_file_info_t *src_fi,
off_t src_off,
const fuse_file_info_t *dst_fi,
off_t dst_off,
const size_t size,
const unsigned int flags);
ssize_t (*setupmapping)(uint64_t *fh_,
ssize_t (*setupmapping)(const fuse_req_ctx_t *,
uint64_t *fh_,
uint64_t foffset_,
uint64_t len_,
uint64_t flags_,
uint64_t moffset_);
int (*removemapping)();
int (*syncfs)();
int (*tmpfile)(const char *, mode_t, fuse_file_info_t *);
int (*statx)(const char *fusepath,
int (*removemapping)(const fuse_req_ctx_t *);
int (*syncfs)(const fuse_req_ctx_t *);
int (*tmpfile)(const fuse_req_ctx_t *,
const char *,
mode_t,
fuse_file_info_t *);
int (*statx)(const fuse_req_ctx_t *,
const char *fusepath,
const uint32_t flags,
const uint32_t mask,
struct fuse_statx *st,
fuse_timeouts_t *timeout);
int (*statx_fh)(const uint64_t fh,
int (*statx_fh)(const fuse_req_ctx_t *,
const uint64_t fh,
const uint32_t flags,
const uint32_t mask,
struct fuse_statx *st,
fuse_timeouts_t *timeout);
};
/** Extra context that may be needed by some filesystems
*
* The uid, gid and pid fields are not filled in case of a writepage
* operation.
*/
struct fuse_context
{
uint64_t unique;
uint64_t nodeid;
uint32_t opcode;
uid_t uid;
gid_t gid;
pid_t pid;
mode_t umask;
struct fuse *fuse;
};
/**
* Main function of FUSE.
*
@ -593,11 +264,6 @@ struct fuse_context
* @param op the file system operation
* @return 0 on success, nonzero on failure
*/
/*
int fuse_main(int argc, char *argv[], const struct fuse_operations *op);
*/
#define fuse_main(argc, argv, op) \
fuse_main_real(argc, argv, op, sizeof(*(op)))
/* ----------------------------------------------------------- *
* More detailed API *
@ -612,8 +278,9 @@ struct fuse_context
* @param op_size the size of the fuse_operations structure
* @return the created FUSE handle
*/
struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args,
const struct fuse_operations *op, size_t op_size);
struct fuse *fuse_new(struct fuse_chan *ch,
struct fuse_args *args,
const struct fuse_operations *op);
/**
* Destroy the FUSE handle.
@ -625,7 +292,7 @@ struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args,
*
* @param f the FUSE handle
*/
void fuse_destroy(struct fuse *f);
void fuse_destroy();
/**
* Exit from event loop
@ -686,7 +353,9 @@ int fuse_is_lib_option(const char *opt);
*
* Do not call this directly, use fuse_main()
*/
int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op, size_t op_size);
int fuse_main(int argc,
char *argv[],
const struct fuse_operations *op);
void fuse_populate_maintenance_thread(struct fuse *fuse);
@ -709,13 +378,6 @@ int fuse_clean_cache(struct fuse *fuse);
* Stacking API
*/
/**
* Fuse filesystem object
*
* This is opaque object represents a filesystem layer
*/
struct fuse_fs;
/*
* These functions call the relevant filesystem operation, and return
* the result.
@ -727,18 +389,6 @@ struct fuse_fs;
int fuse_notify_poll(fuse_pollhandle_t *ph);
/**
* Create a new fuse filesystem object
*
* This is usually called from the factory of a fuse module to create
* a new instance of a filesystem.
*
* @param op the filesystem operations
* @param op_size the size of the fuse_operations structure
* @return a new filesystem object
*/
struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size);
/* ----------------------------------------------------------- *
* Advanced API for event handling, don't worry about this... *
* ----------------------------------------------------------- */
@ -746,40 +396,31 @@ struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size);
/* NOTE: the following functions are deprecated, and will be removed
from the 3.0 API. Use the lowlevel session functions instead */
/** Function type used to process commands */
typedef void (*fuse_processor_t)(struct fuse *, struct fuse_cmd *, void *);
/** This is the part of fuse_main() before the event loop */
struct fuse *fuse_setup(int argc, char *argv[],
const struct fuse_operations *op, size_t op_size,
struct fuse *fuse_setup(int argc,
char *argv[],
const struct fuse_operations *op,
char **mountpoint);
/** This is the part of fuse_main() after the event loop */
void fuse_teardown(struct fuse *fuse, char *mountpoint);
/** Multi threaded event loop, which calls the custom command
processor function */
int fuse_loop_mt_proc(struct fuse *f, fuse_processor_t proc, void *data);
void fuse_teardown(char *mountpoint);
/** Return the exited flag, which indicates if fuse_exit() has been
called */
int fuse_exited(struct fuse *f);
int fuse_exited();
/** This function is obsolete and implemented as a no-op */
void fuse_set_getcontext_func(struct fuse_context *(*func)(void));
/** Get session from fuse object */
struct fuse_session *fuse_get_session(struct fuse *f);
struct fuse_session *fuse_get_session();
void fuse_gc1();
void fuse_gc();
void fuse_invalidate_all_nodes();
int fuse_get_dev_fuse_fd(const struct fuse_context *fc);
int fuse_passthrough_open(const struct fuse_context *fc,
const int fd);
int fuse_passthrough_close(const struct fuse_context *fc,
const int backing_id);
int fuse_passthrough_open(const int fd);
int fuse_passthrough_close(const int backing_id);
EXTERN_C_END

28
libfuse/include/fuse_common.h

@ -1,19 +1,4 @@
/*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
This program can be distributed under the terms of the GNU LGPLv2.
See the file COPYING.LIB.
*/
/** @file */
#if !defined(_FUSE_H_) && !defined(_FUSE_LOWLEVEL_H_)
#error "Never include <fuse_common.h> directly; use <fuse.h> or <fuse_lowlevel.h> instead."
#endif
#ifndef _FUSE_COMMON_H_
#define _FUSE_COMMON_H_
#pragma once
#include "extern_c.h"
#include "fuse_opt.h"
@ -22,15 +7,6 @@
#include <stdint.h>
#include <sys/types.h>
/** Major version of FUSE library interface */
#define FUSE_MAJOR_VERSION 2
/** Minor version of FUSE library interface */
#define FUSE_MINOR_VERSION 9
#define FUSE_MAKE_VERSION(maj, min) ((maj) * 10 + (min))
#define FUSE_VERSION FUSE_MAKE_VERSION(FUSE_MAJOR_VERSION, FUSE_MINOR_VERSION)
/* This interface uses 64 bit off_t */
#if _FILE_OFFSET_BITS != 64
#error Please add -D_FILE_OFFSET_BITS=64 to your compile flags!
@ -449,5 +425,3 @@ int fuse_set_signal_handlers(struct fuse_session *se);
void fuse_remove_signal_handlers(struct fuse_session *se);
EXTERN_C_END
#endif /* _FUSE_COMMON_H_ */

185
libfuse/include/fuse_lowlevel.h

@ -1,17 +1,9 @@
/*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
This program can be distributed under the terms of the GNU LGPLv2.
See the file COPYING.LIB.
*/
#ifndef _FUSE_LOWLEVEL_H_
#define _FUSE_LOWLEVEL_H_
#pragma once
#include "extern_c.h"
#include "fuse_common.h"
#include "fuse_kernel.h"
#include "fuse_req.h"
#include <fcntl.h>
#include <stdint.h>
@ -30,9 +22,6 @@ EXTERN_C_BEGIN
/** The node ID of the root inode */
#define FUSE_ROOT_ID 1
/** Request pointer type */
typedef struct fuse_req *fuse_req_t;
/**
* Session
*
@ -88,18 +77,6 @@ struct fuse_entry_param
fuse_timeouts_t timeout;
};
/** Additional context associated with requests */
struct fuse_ctx
{
uint64_t unique;
uint64_t nodeid;
uint32_t opcode;
uid_t uid;
gid_t gid;
pid_t pid;
mode_t umask;
};
/* ----------------------------------------------------------- *
* Request methods and replies *
* ----------------------------------------------------------- */
@ -127,55 +104,55 @@ struct fuse_ctx
*/
struct fuse_lowlevel_ops
{
void (*access)(fuse_req_t req, struct fuse_in_header *hdr);
void (*bmap)(fuse_req_t req, const struct fuse_in_header *hdr);
void (*copy_file_range)(fuse_req_t req, const struct fuse_in_header *hdr);
void (*create)(fuse_req_t req, struct fuse_in_header *hdr);
void (*access)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*bmap)(fuse_req_t *req, const struct fuse_in_header *hdr);
void (*copy_file_range)(fuse_req_t *req, const struct fuse_in_header *hdr);
void (*create)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*destroy)(void *userdata);
void (*fallocate)(fuse_req_t req, const struct fuse_in_header *hdr);
void (*flock)(fuse_req_t req, uint64_t ino, fuse_file_info_t *fi, int op);
void (*flush)(fuse_req_t req, struct fuse_in_header *hdr);
void (*forget)(fuse_req_t req, struct fuse_in_header *hdr);
void (*forget_multi)(fuse_req_t req, struct fuse_in_header *hdr);
void (*fsync)(fuse_req_t req, struct fuse_in_header *hdr);
void (*fsyncdir)(fuse_req_t req, struct fuse_in_header *hdr);
void (*getattr)(fuse_req_t req, struct fuse_in_header *hdr);
void (*getlk)(fuse_req_t req, const struct fuse_in_header *hdr);
void (*getxattr)(fuse_req_t req, struct fuse_in_header *hdr);
void (*fallocate)(fuse_req_t *req, const struct fuse_in_header *hdr);
void (*flock)(fuse_req_t *req, uint64_t ino, fuse_file_info_t *fi, int op);
void (*flush)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*forget)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*forget_multi)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*fsync)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*fsyncdir)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*getattr)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*getlk)(fuse_req_t *req, const struct fuse_in_header *hdr);
void (*getxattr)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*init)(void *userdata, struct fuse_conn_info *conn);
void (*ioctl)(fuse_req_t req, const struct fuse_in_header *hdr);
void (*link)(fuse_req_t req, struct fuse_in_header *hdr);
void (*listxattr)(fuse_req_t req, struct fuse_in_header *hdr);
void (*lookup)(fuse_req_t req, struct fuse_in_header *hdr);
void (*lseek)(fuse_req_t req, struct fuse_in_header *hdr);
void (*mkdir)(fuse_req_t req, struct fuse_in_header *hdr);
void (*mknod)(fuse_req_t req, struct fuse_in_header *hdr);
void (*open)(fuse_req_t req, struct fuse_in_header *hdr);
void (*opendir)(fuse_req_t req, struct fuse_in_header *hdr);
void (*poll)(fuse_req_t req, const struct fuse_in_header *hdr);
void (*read)(fuse_req_t req, struct fuse_in_header *hdr);
void (*readdir)(fuse_req_t req, struct fuse_in_header *hdr);
void (*readdir_plus)(fuse_req_t req, struct fuse_in_header *hdr);
void (*readlink)(fuse_req_t req, struct fuse_in_header *hdr);
void (*release)(fuse_req_t req, struct fuse_in_header *hdr);
void (*releasedir)(fuse_req_t req, struct fuse_in_header *hdr);
void (*removemapping)(fuse_req_t req, const struct fuse_in_header *hdr);
void (*removexattr)(fuse_req_t req, const struct fuse_in_header *hdr);
void (*rename)(fuse_req_t req, struct fuse_in_header *hdr);
void (*rename2)(fuse_req_t req, struct fuse_in_header *hdr);
void (*retrieve_reply)(fuse_req_t req, void *cookie, uint64_t ino, off_t offset);
void (*rmdir)(fuse_req_t req, struct fuse_in_header *hdr);
void (*setattr)(fuse_req_t req, struct fuse_in_header *hdr);
void (*setlk)(fuse_req_t req, uint64_t ino, fuse_file_info_t *fi, struct flock *lock, int sleep);
void (*setupmapping)(fuse_req_t req, const struct fuse_in_header *hdr);
void (*setxattr)(fuse_req_t req, struct fuse_in_header *hdr);
void (*statfs)(fuse_req_t req, struct fuse_in_header *hdr);
void (*statx)(fuse_req_t req, struct fuse_in_header *hdr);
void (*symlink)(fuse_req_t req, struct fuse_in_header *hdr);
void (*syncfs)(fuse_req_t req, const struct fuse_in_header *hdr);
void (*tmpfile)(fuse_req_t req, const struct fuse_in_header *hdr);
void (*unlink)(fuse_req_t req, struct fuse_in_header *hdr);
void (*write)(fuse_req_t req, struct fuse_in_header *hdr);
void (*ioctl)(fuse_req_t *req, const struct fuse_in_header *hdr);
void (*link)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*listxattr)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*lookup)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*lseek)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*mkdir)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*mknod)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*open)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*opendir)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*poll)(fuse_req_t *req, const struct fuse_in_header *hdr);
void (*read)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*readdir)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*readdir_plus)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*readlink)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*release)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*releasedir)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*removemapping)(fuse_req_t *req, const struct fuse_in_header *hdr);
void (*removexattr)(fuse_req_t *req, const struct fuse_in_header *hdr);
void (*rename)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*rename2)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*retrieve_reply)(fuse_req_t *req, void *cookie, uint64_t ino, off_t offset);
void (*rmdir)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*setattr)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*setlk)(fuse_req_t *req, uint64_t ino, fuse_file_info_t *fi, struct flock *lock, int sleep);
void (*setupmapping)(fuse_req_t *req, const struct fuse_in_header *hdr);
void (*setxattr)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*statfs)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*statx)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*symlink)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*syncfs)(fuse_req_t *req, const struct fuse_in_header *hdr);
void (*tmpfile)(fuse_req_t *req, const struct fuse_in_header *hdr);
void (*unlink)(fuse_req_t *req, struct fuse_in_header *hdr);
void (*write)(fuse_req_t *req, struct fuse_in_header *hdr);
};
/**
@ -191,7 +168,7 @@ struct fuse_lowlevel_ops
* @param err the positive error value, or zero for success
* @return zero for success, -errno for failure to send reply
*/
int fuse_reply_err(fuse_req_t req, int err);
int fuse_reply_err(fuse_req_t *req, int err);
/**
* Don't send reply
@ -201,7 +178,7 @@ int fuse_reply_err(fuse_req_t req, int err);
*
* @param req request handle
*/
void fuse_reply_none(fuse_req_t req);
void fuse_reply_none(fuse_req_t *req);
/**
* Reply with a directory entry
@ -216,7 +193,7 @@ void fuse_reply_none(fuse_req_t req);
* @param e the entry parameters
* @return zero for success, -errno for failure to send reply
*/
int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e);
int fuse_reply_entry(fuse_req_t *req, const struct fuse_entry_param *e);
/**
* Reply with a directory entry and open parameters
@ -235,7 +212,8 @@ int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e);
* @param fi file information
* @return zero for success, -errno for failure to send reply
*/
int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e,
int fuse_reply_create(fuse_req_t *req,
const struct fuse_entry_param *e,
const fuse_file_info_t *fi);
/**
@ -249,12 +227,12 @@ int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e,
* @param attr_timeout validity timeout (in seconds) for the attributes
* @return zero for success, -errno for failure to send reply
*/
int fuse_reply_attr(fuse_req_t req,
int fuse_reply_attr(fuse_req_t *req,
const struct stat *attr,
const uint64_t timeout);
int fuse_reply_statx(fuse_req_t req,
int fuse_reply_statx(fuse_req_t *req,
int flags,
struct fuse_statx *st,
const uint64_t timeout);
@ -269,7 +247,7 @@ int fuse_reply_statx(fuse_req_t req,
* @param link symbolic link contents
* @return zero for success, -errno for failure to send reply
*/
int fuse_reply_readlink(fuse_req_t req, const char *link);
int fuse_reply_readlink(fuse_req_t *req, const char *link);
/**
* Reply with open parameters
@ -284,7 +262,7 @@ 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,
int fuse_reply_open(fuse_req_t *req,
const fuse_file_info_t *fi);
/**
@ -297,7 +275,7 @@ int fuse_reply_open(fuse_req_t req,
* @param count the number of bytes written
* @return zero for success, -errno for failure to send reply
*/
int fuse_reply_write(fuse_req_t req, size_t count);
int fuse_reply_write(fuse_req_t *req, size_t count);
/**
* Reply with data
@ -310,9 +288,9 @@ int fuse_reply_write(fuse_req_t req, size_t count);
* @param size the size of data in bytes
* @return zero for success, -errno for failure to send reply
*/
int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size);
int fuse_reply_buf(fuse_req_t *req, const char *buf, size_t size);
int fuse_reply_data(fuse_req_t req,
int fuse_reply_data(fuse_req_t *req,
char *buf,
size_t bufsize);
@ -327,7 +305,7 @@ int fuse_reply_data(fuse_req_t req,
* @param count the size of vector
* @return zero for success, -errno for failure to send reply
*/
int fuse_reply_iov(fuse_req_t req, const struct iovec *iov, int count);
int fuse_reply_iov(fuse_req_t *req, const struct iovec *iov, int count);
/**
* Reply with filesystem statistics
@ -339,7 +317,7 @@ int fuse_reply_iov(fuse_req_t req, const struct iovec *iov, int count);
* @param stbuf filesystem statistics
* @return zero for success, -errno for failure to send reply
*/
int fuse_reply_statfs(fuse_req_t req, const struct statvfs *stbuf);
int fuse_reply_statfs(fuse_req_t *req, const struct statvfs *stbuf);
/**
* Reply with needed buffer size
@ -351,7 +329,7 @@ int fuse_reply_statfs(fuse_req_t req, const struct statvfs *stbuf);
* @param count the buffer size needed in bytes
* @return zero for success, -errno for failure to send reply
*/
int fuse_reply_xattr(fuse_req_t req, size_t count);
int fuse_reply_xattr(fuse_req_t *req, size_t count);
/**
* Reply with file lock information
@ -363,7 +341,7 @@ int fuse_reply_xattr(fuse_req_t req, size_t count);
* @param lock the lock information
* @return zero for success, -errno for failure to send reply
*/
int fuse_reply_lock(fuse_req_t req, const struct flock *lock);
int fuse_reply_lock(fuse_req_t *req, const struct flock *lock);
/**
* Reply with block index
@ -375,7 +353,7 @@ int fuse_reply_lock(fuse_req_t req, const struct flock *lock);
* @param idx block index within device
* @return zero for success, -errno for failure to send reply
*/
int fuse_reply_bmap(fuse_req_t req, uint64_t idx);
int fuse_reply_bmap(fuse_req_t *req, uint64_t idx);
/**
* Reply to ask for data fetch and output buffer preparation. ioctl
@ -392,7 +370,7 @@ int fuse_reply_bmap(fuse_req_t req, uint64_t idx);
* @param out_count number of entries in out_iov
* @return zero for success, -errno for failure to send reply
*/
int fuse_reply_ioctl_retry(fuse_req_t req,
int fuse_reply_ioctl_retry(fuse_req_t *req,
const struct iovec *in_iov, size_t in_count,
const struct iovec *out_iov, size_t out_count);
@ -407,7 +385,7 @@ int fuse_reply_ioctl_retry(fuse_req_t req,
* @param buf buffer containing output data
* @param size length of output data
*/
int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, uint32_t size);
int fuse_reply_ioctl(fuse_req_t *req, int result, const void *buf, uint32_t size);
/**
* Reply to finish ioctl with iov buffer
@ -420,7 +398,7 @@ int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, uint32_t size)
* @param iov the vector containing the data
* @param count the size of vector
*/
int fuse_reply_ioctl_iov(fuse_req_t req, int result, const struct iovec *iov,
int fuse_reply_ioctl_iov(fuse_req_t *req, int result, const struct iovec *iov,
int count);
/**
@ -429,7 +407,7 @@ int fuse_reply_ioctl_iov(fuse_req_t req, int result, const struct iovec *iov,
* @param req request handle
* @param revents poll result event mask
*/
int fuse_reply_poll(fuse_req_t req, unsigned revents);
int fuse_reply_poll(fuse_req_t *req, unsigned revents);
/* ----------------------------------------------------------- *
* Notification *
@ -551,25 +529,6 @@ int fuse_lowlevel_notify_retrieve(struct fuse_chan *ch, uint64_t ino,
* Utility functions *
* ----------------------------------------------------------- */
/**
* Get the userdata from the request
*
* @param req request handle
* @return the user data passed to fuse_lowlevel_new()
*/
void *fuse_req_userdata(fuse_req_t req);
/**
* Get the context from the request
*
* The pointer returned by this function will only be valid for the
* request's lifetime
*
* @param req request handle
* @return the context structure
*/
const struct fuse_ctx *fuse_req_ctx(fuse_req_t req);
/**
* Get the current supplementary group IDs for the specified request
*
@ -589,7 +548,7 @@ const struct fuse_ctx *fuse_req_ctx(fuse_req_t req);
* @param list array of group IDs to be filled in
* @return the total number of supplementary group IDs or -errno on failure
*/
int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[]);
int fuse_req_getgroups(fuse_req_t *req, int size, gid_t list[]);
/* ----------------------------------------------------------- *
* Filesystem setup *
@ -679,5 +638,3 @@ struct fuse_session *fuse_chan_session(struct fuse_chan *ch);
void fuse_chan_destroy(struct fuse_chan *ch);
EXTERN_C_END
#endif /* _FUSE_LOWLEVEL_H_ */

15
libfuse/include/fuse_req.h

@ -0,0 +1,15 @@
#pragma once
#include "fuse_req_ctx.h"
struct fuse_ll;
struct fuse_chan;
typedef struct fuse_req_t fuse_req_t;
struct fuse_req_t
{
fuse_req_ctx_t ctx;
struct fuse_ll *f;
struct fuse_chan *ch;
unsigned int ioctl_64bit : 1;
};

16
libfuse/include/fuse_req_ctx.h

@ -0,0 +1,16 @@
#pragma once
#include <stdint.h>
typedef struct fuse_req_ctx_t fuse_req_ctx_t;
struct fuse_req_ctx_t
{
uint32_t len;
uint32_t opcode;
uint64_t unique;
uint64_t nodeid;
uint32_t uid;
uint32_t gid;
uint32_t pid;
uint32_t umask;
};

1679
libfuse/lib/fuse.cpp
File diff suppressed because it is too large
View File

21
libfuse/lib/fuse_i.h

@ -32,20 +32,11 @@ struct fuse_session
struct fuse_chan *ch;
};
struct fuse_req
{
struct fuse_ll *f;
uint64_t unique;
struct fuse_ctx ctx;
struct fuse_chan *ch;
unsigned int ioctl_64bit : 1;
};
struct fuse_notify_req
{
uint64_t unique;
void (*reply)(struct fuse_notify_req *,
fuse_req_t,
fuse_req_t*,
uint64_t,
const void *);
struct fuse_notify_req *next;
@ -81,9 +72,9 @@ struct fuse_cmd
EXTERN_C_BEGIN
struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args,
const struct fuse_operations *op,
size_t op_size);
struct fuse *fuse_new_common(struct fuse_chan *ch,
struct fuse_args *args,
const struct fuse_operations *op);
struct fuse_chan *fuse_kern_chan_new(int fd);
@ -101,9 +92,9 @@ int fuse_send_reply_iov_nofree(fuse_req_t req, int error, struct iovec *iov,
void fuse_free_req(fuse_req_t req);
struct fuse *fuse_setup_common(int argc, char *argv[],
struct fuse *fuse_setup_common(int argc,
char *argv[],
const struct fuse_operations *op,
size_t op_size,
char **mountpoint,
int *fd);

2
libfuse/lib/fuse_loop.cpp

@ -335,7 +335,7 @@ fuse_loop_mt(struct fuse *f_)
MaintenanceThread::setup();
fuse_populate_maintenance_thread(f_);
res = fuse_session_loop_mt(fuse_get_session(f_),
res = fuse_session_loop_mt(fuse_get_session(),
fuse_config_get_read_thread_count(),
fuse_config_get_process_thread_count(),
fuse_config_get_process_thread_queue_depth(),

191
libfuse/lib/fuse_lowlevel.cpp

@ -55,7 +55,7 @@ void
fuse_ll_constructor(void)
{
pagesize = sysconf(_SC_PAGESIZE);
lfmp_init(&g_FMP_fuse_req,sizeof(struct fuse_req),1);
lfmp_init(&g_FMP_fuse_req,sizeof(struct fuse_req_t),1);
}
static
@ -104,18 +104,18 @@ iov_length(const struct iovec *iov,
static
void
destroy_req(fuse_req_t req)
destroy_req(fuse_req_t *req)
{
lfmp_free(&g_FMP_fuse_req,req);
}
static
struct fuse_req*
fuse_req_t*
fuse_ll_alloc_req(struct fuse_ll *f)
{
struct fuse_req *req;
fuse_req_t *req;
req = (struct fuse_req*)lfmp_calloc(&g_FMP_fuse_req);
req = (fuse_req_t*)lfmp_calloc(&g_FMP_fuse_req);
if(req == NULL)
{
fprintf(stderr, "fuse: failed to allocate request\n");
@ -151,7 +151,7 @@ fuse_send_msg(struct fuse_ll *f,
#define MAX_ERRNO 4095
int
fuse_send_reply_iov_nofree(fuse_req_t req,
fuse_send_reply_iov_nofree(fuse_req_t *req,
int error,
struct iovec *iov,
int count)
@ -167,7 +167,7 @@ fuse_send_reply_iov_nofree(fuse_req_t req,
error = -ERANGE;
}
out.unique = req->unique;
out.unique = req->ctx.unique;
out.error = error;
iov[0].iov_base = &out;
@ -178,7 +178,7 @@ fuse_send_reply_iov_nofree(fuse_req_t req,
static
int
send_reply_iov(fuse_req_t req,
send_reply_iov(fuse_req_t *req,
int error,
struct iovec *iov,
int count)
@ -193,7 +193,7 @@ send_reply_iov(fuse_req_t req,
static
int
send_reply(fuse_req_t req,
send_reply(fuse_req_t *req,
int error,
const void *arg,
size_t argsize)
@ -227,7 +227,7 @@ convert_statfs(const struct statvfs *stbuf,
static
int
send_reply_ok(fuse_req_t req,
send_reply_ok(fuse_req_t *req,
const void *arg,
size_t argsize)
{
@ -235,14 +235,14 @@ send_reply_ok(fuse_req_t req,
}
int
fuse_reply_err(fuse_req_t req_,
fuse_reply_err(fuse_req_t *req_,
int err_)
{
return send_reply(req_,err_,NULL,0);
}
void
fuse_reply_none(fuse_req_t req)
fuse_reply_none(fuse_req_t *req)
{
destroy_req(req);
}
@ -287,7 +287,7 @@ fill_open(struct fuse_open_out *arg_,
}
int
fuse_reply_entry(fuse_req_t req,
fuse_reply_entry(fuse_req_t *req,
const struct fuse_entry_param *e)
{
struct fuse_entry_out arg = {0};
@ -316,7 +316,7 @@ struct fuse_create_out
};
int
fuse_reply_create(fuse_req_t req,
fuse_reply_create(fuse_req_t *req,
const struct fuse_entry_param *e,
const fuse_file_info_t *f)
{
@ -333,7 +333,7 @@ fuse_reply_create(fuse_req_t req,
}
int
fuse_reply_attr(fuse_req_t req,
fuse_reply_attr(fuse_req_t *req,
const struct stat *attr,
const uint64_t timeout)
{
@ -349,7 +349,7 @@ fuse_reply_attr(fuse_req_t req,
}
int
fuse_reply_statx(fuse_req_t req_,
fuse_reply_statx(fuse_req_t *req_,
int flags_,
struct fuse_statx *st_,
uint64_t timeout_)
@ -365,14 +365,14 @@ fuse_reply_statx(fuse_req_t req_,
}
int
fuse_reply_readlink(fuse_req_t req,
fuse_reply_readlink(fuse_req_t *req,
const char *linkname)
{
return send_reply_ok(req, linkname, strlen(linkname));
}
int
fuse_reply_open(fuse_req_t req,
fuse_reply_open(fuse_req_t *req,
const fuse_file_info_t *f)
{
struct fuse_open_out arg = {0};
@ -383,7 +383,7 @@ fuse_reply_open(fuse_req_t req,
}
int
fuse_reply_write(fuse_req_t req,
fuse_reply_write(fuse_req_t *req,
size_t count)
{
struct fuse_write_out arg = {0};
@ -394,7 +394,7 @@ fuse_reply_write(fuse_req_t req,
}
int
fuse_reply_buf(fuse_req_t req,
fuse_reply_buf(fuse_req_t *req,
const char *buf,
size_t size)
{
@ -482,7 +482,7 @@ fuse_send_data_iov(struct fuse_ll *f,
}
int
fuse_reply_data(fuse_req_t req,
fuse_reply_data(fuse_req_t *req,
char *buf_,
const size_t bufsize_)
{
@ -495,7 +495,7 @@ fuse_reply_data(fuse_req_t req,
iov[1].iov_base = buf_;
iov[1].iov_len = bufsize_;
out.unique = req->unique;
out.unique = req->ctx.unique;
out.error = 0;
res = fuse_send_msg(req->f,req->ch,iov,2);
@ -511,7 +511,7 @@ fuse_reply_data(fuse_req_t req,
}
int
fuse_reply_statfs(fuse_req_t req,
fuse_reply_statfs(fuse_req_t *req,
const struct statvfs *stbuf)
{
struct fuse_statfs_out arg = {0};
@ -524,7 +524,7 @@ fuse_reply_statfs(fuse_req_t req,
}
int
fuse_reply_xattr(fuse_req_t req,
fuse_reply_xattr(fuse_req_t *req,
size_t count)
{
struct fuse_getxattr_out arg = {0};
@ -535,7 +535,7 @@ fuse_reply_xattr(fuse_req_t req,
}
int
fuse_reply_lock(fuse_req_t req,
fuse_reply_lock(fuse_req_t *req,
const struct flock *lock)
{
struct fuse_lk_out arg = {0};
@ -555,7 +555,7 @@ fuse_reply_lock(fuse_req_t req,
}
int
fuse_reply_bmap(fuse_req_t req,
fuse_reply_bmap(fuse_req_t *req,
uint64_t idx)
{
struct fuse_bmap_out arg = {0};
@ -587,7 +587,7 @@ fuse_ioctl_iovec_copy(const struct iovec *iov,
}
int
fuse_reply_ioctl_retry(fuse_req_t req,
fuse_reply_ioctl_retry(fuse_req_t *req,
const struct iovec *in_iov,
size_t in_count,
const struct iovec *out_iov,
@ -667,7 +667,7 @@ fuse_reply_ioctl_retry(fuse_req_t req,
}
int
fuse_reply_ioctl(fuse_req_t req,
fuse_reply_ioctl(fuse_req_t *req,
int result,
const void *buf,
uint32_t size)
@ -697,7 +697,7 @@ fuse_reply_ioctl(fuse_req_t req,
}
int
fuse_reply_ioctl_iov(fuse_req_t req,
fuse_reply_ioctl_iov(fuse_req_t *req,
int result,
const struct iovec *iov,
int count)
@ -723,7 +723,7 @@ fuse_reply_ioctl_iov(fuse_req_t req,
}
int
fuse_reply_poll(fuse_req_t req,
fuse_reply_poll(fuse_req_t *req,
unsigned revents)
{
struct fuse_poll_out arg = {0};
@ -735,7 +735,7 @@ fuse_reply_poll(fuse_req_t req,
static
void
do_lookup(fuse_req_t req,
do_lookup(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.lookup(req,hdr_);
@ -743,7 +743,7 @@ do_lookup(fuse_req_t req,
static
void
do_forget(fuse_req_t req,
do_forget(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.forget(req,hdr_);
@ -751,7 +751,7 @@ do_forget(fuse_req_t req,
static
void
do_batch_forget(fuse_req_t req,
do_batch_forget(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.forget_multi(req,hdr_);
@ -759,7 +759,7 @@ do_batch_forget(fuse_req_t req,
static
void
do_getattr(fuse_req_t req,
do_getattr(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.getattr(req, hdr_);
@ -767,7 +767,7 @@ do_getattr(fuse_req_t req,
static
void
do_setattr(fuse_req_t req_,
do_setattr(fuse_req_t *req_,
struct fuse_in_header *hdr_)
{
req_->f->op.setattr(req_,hdr_);
@ -775,7 +775,7 @@ do_setattr(fuse_req_t req_,
static
void
do_access(fuse_req_t req,
do_access(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.access(req,hdr_);
@ -783,7 +783,7 @@ do_access(fuse_req_t req,
static
void
do_readlink(fuse_req_t req,
do_readlink(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.readlink(req,hdr_);
@ -791,7 +791,7 @@ do_readlink(fuse_req_t req,
static
void
do_mknod(fuse_req_t req,
do_mknod(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.mknod(req,hdr_);
@ -799,7 +799,7 @@ do_mknod(fuse_req_t req,
static
void
do_mkdir(fuse_req_t req,
do_mkdir(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.mkdir(req,hdr_);
@ -807,7 +807,7 @@ do_mkdir(fuse_req_t req,
static
void
do_unlink(fuse_req_t req,
do_unlink(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.unlink(req,hdr_);
@ -815,7 +815,7 @@ do_unlink(fuse_req_t req,
static
void
do_rmdir(fuse_req_t req,
do_rmdir(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.rmdir(req,hdr_);
@ -823,7 +823,7 @@ do_rmdir(fuse_req_t req,
static
void
do_symlink(fuse_req_t req,
do_symlink(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.symlink(req,hdr_);
@ -831,7 +831,7 @@ do_symlink(fuse_req_t req,
static
void
do_rename(fuse_req_t req,
do_rename(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.rename(req,hdr_);
@ -839,7 +839,7 @@ do_rename(fuse_req_t req,
static
void
do_link(fuse_req_t req,
do_link(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.link(req,hdr_);
@ -847,7 +847,7 @@ do_link(fuse_req_t req,
static
void
do_create(fuse_req_t req,
do_create(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.create(req,hdr_);
@ -855,7 +855,7 @@ do_create(fuse_req_t req,
static
void
do_open(fuse_req_t req,
do_open(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.open(req,hdr_);
@ -863,7 +863,7 @@ do_open(fuse_req_t req,
static
void
do_read(fuse_req_t req,
do_read(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.read(req,hdr_);
@ -871,7 +871,7 @@ do_read(fuse_req_t req,
static
void
do_write(fuse_req_t req,
do_write(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.write(req,hdr_);
@ -879,7 +879,7 @@ do_write(fuse_req_t req,
static
void
do_flush(fuse_req_t req,
do_flush(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.flush(req,hdr_);
@ -887,7 +887,7 @@ do_flush(fuse_req_t req,
static
void
do_release(fuse_req_t req,
do_release(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.release(req,hdr_);
@ -895,7 +895,7 @@ do_release(fuse_req_t req,
static
void
do_fsync(fuse_req_t req,
do_fsync(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.fsync(req,hdr_);
@ -903,7 +903,7 @@ do_fsync(fuse_req_t req,
static
void
do_opendir(fuse_req_t req,
do_opendir(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.opendir(req,hdr_);
@ -911,7 +911,7 @@ do_opendir(fuse_req_t req,
static
void
do_readdir(fuse_req_t req,
do_readdir(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.readdir(req,hdr_);
@ -919,7 +919,7 @@ do_readdir(fuse_req_t req,
static
void
do_readdirplus(fuse_req_t req_,
do_readdirplus(fuse_req_t *req_,
struct fuse_in_header *hdr_)
{
req_->f->op.readdir_plus(req_,hdr_);
@ -927,7 +927,7 @@ do_readdirplus(fuse_req_t req_,
static
void
do_releasedir(fuse_req_t req,
do_releasedir(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.releasedir(req,hdr_);
@ -935,7 +935,7 @@ do_releasedir(fuse_req_t req,
static
void
do_fsyncdir(fuse_req_t req,
do_fsyncdir(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.fsyncdir(req,hdr_);
@ -943,7 +943,7 @@ do_fsyncdir(fuse_req_t req,
static
void
do_statfs(fuse_req_t req,
do_statfs(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.statfs(req,hdr_);
@ -951,7 +951,7 @@ do_statfs(fuse_req_t req,
static
void
do_setxattr(fuse_req_t req,
do_setxattr(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.setxattr(req,hdr_);
@ -959,7 +959,7 @@ do_setxattr(fuse_req_t req,
static
void
do_getxattr(fuse_req_t req,
do_getxattr(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.getxattr(req,hdr_);
@ -967,7 +967,7 @@ do_getxattr(fuse_req_t req,
static
void
do_listxattr(fuse_req_t req,
do_listxattr(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.listxattr(req,hdr_);
@ -975,7 +975,7 @@ do_listxattr(fuse_req_t req,
static
void
do_removexattr(fuse_req_t req,
do_removexattr(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.removexattr(req,hdr_);
@ -999,7 +999,7 @@ convert_fuse_file_lock(struct fuse_file_lock *fl,
static
void
do_getlk(fuse_req_t req,
do_getlk(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.getlk(req,hdr_);
@ -1007,7 +1007,7 @@ do_getlk(fuse_req_t req,
static
void
do_setlk_common(fuse_req_t req,
do_setlk_common(fuse_req_t *req,
uint64_t nodeid,
const void *inarg,
int sleep)
@ -1051,7 +1051,7 @@ do_setlk_common(fuse_req_t req,
static
void
do_setlk(fuse_req_t req,
do_setlk(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
do_setlk_common(req, hdr_->nodeid, &hdr_[1], 0);
@ -1059,7 +1059,7 @@ do_setlk(fuse_req_t req,
static
void
do_setlkw(fuse_req_t req,
do_setlkw(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
do_setlk_common(req, hdr_->nodeid, &hdr_[1], 1);
@ -1067,7 +1067,7 @@ do_setlkw(fuse_req_t req,
static
void
do_interrupt(fuse_req_t req,
do_interrupt(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
destroy_req(req);
@ -1075,7 +1075,7 @@ do_interrupt(fuse_req_t req,
static
void
do_bmap(fuse_req_t req,
do_bmap(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.bmap(req,hdr_);
@ -1083,7 +1083,7 @@ do_bmap(fuse_req_t req,
static
void
do_ioctl(fuse_req_t req,
do_ioctl(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.ioctl(req, hdr_);
@ -1097,7 +1097,7 @@ fuse_pollhandle_destroy(fuse_pollhandle_t *ph)
static
void
do_poll(fuse_req_t req,
do_poll(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.poll(req,hdr_);
@ -1105,7 +1105,7 @@ do_poll(fuse_req_t req,
static
void
do_fallocate(fuse_req_t req,
do_fallocate(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
req->f->op.fallocate(req,hdr_);
@ -1113,7 +1113,7 @@ do_fallocate(fuse_req_t req,
static
void
do_init(fuse_req_t req,
do_init(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
struct fuse_init_out outarg = {0};
@ -1334,7 +1334,7 @@ do_init(fuse_req_t req,
static
void
do_destroy(fuse_req_t req,
do_destroy(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
struct fuse_ll *f = req->f;
@ -1377,7 +1377,7 @@ list_init_nreq(struct fuse_notify_req *nreq)
static
void
do_notify_reply(fuse_req_t req,
do_notify_reply(fuse_req_t *req,
struct fuse_in_header *hdr_)
{
struct fuse_ll *f = req->f;
@ -1388,7 +1388,7 @@ do_notify_reply(fuse_req_t req,
head = &f->notify_list;
for(nreq = head->next; nreq != head; nreq = nreq->next)
{
if(nreq->unique == req->unique)
if(nreq->unique == req->ctx.unique)
{
list_del_nreq(nreq);
break;
@ -1402,7 +1402,7 @@ do_notify_reply(fuse_req_t req,
static
void
do_copy_file_range(fuse_req_t req_,
do_copy_file_range(fuse_req_t *req_,
struct fuse_in_header *hdr_)
{
req_->f->op.copy_file_range(req_,hdr_);
@ -1410,7 +1410,7 @@ do_copy_file_range(fuse_req_t req_,
static
void
do_setupmapping(fuse_req_t req_,
do_setupmapping(fuse_req_t *req_,
struct fuse_in_header *hdr_)
{
req_->f->op.setupmapping(req_,hdr_);
@ -1418,7 +1418,7 @@ do_setupmapping(fuse_req_t req_,
static
void
do_removemapping(fuse_req_t req_,
do_removemapping(fuse_req_t *req_,
struct fuse_in_header *hdr_)
{
req_->f->op.removemapping(req_,hdr_);
@ -1426,7 +1426,7 @@ do_removemapping(fuse_req_t req_,
static
void
do_syncfs(fuse_req_t req_,
do_syncfs(fuse_req_t *req_,
struct fuse_in_header *hdr_)
{
req_->f->op.syncfs(req_,hdr_);
@ -1434,7 +1434,7 @@ do_syncfs(fuse_req_t req_,
static
void
do_tmpfile(fuse_req_t req_,
do_tmpfile(fuse_req_t *req_,
struct fuse_in_header *hdr_)
{
req_->f->op.tmpfile(req_,hdr_);
@ -1442,7 +1442,7 @@ do_tmpfile(fuse_req_t req_,
static
void
do_statx(fuse_req_t req_,
do_statx(fuse_req_t *req_,
struct fuse_in_header *hdr_)
{
req_->f->op.statx(req_,hdr_);
@ -1450,7 +1450,7 @@ do_statx(fuse_req_t req_,
static
void
do_rename2(fuse_req_t req_,
do_rename2(fuse_req_t *req_,
struct fuse_in_header *hdr_)
{
req_->f->op.rename2(req_,hdr_);
@ -1458,7 +1458,7 @@ do_rename2(fuse_req_t req_,
static
void
do_lseek(fuse_req_t req_,
do_lseek(fuse_req_t *req_,
struct fuse_in_header *hdr_)
{
req_->f->op.lseek(req_,hdr_);
@ -1650,7 +1650,7 @@ struct fuse_retrieve_req
static
void
fuse_ll_retrieve_reply(struct fuse_notify_req *nreq,
fuse_req_t req,
fuse_req_t *req,
uint64_t ino,
const void *inarg)
{
@ -1716,22 +1716,9 @@ fuse_lowlevel_notify_retrieve(struct fuse_chan *ch,
return err;
}
void *
fuse_req_userdata(fuse_req_t req)
{
return req->f->userdata;
}
const
struct fuse_ctx *
fuse_req_ctx(fuse_req_t req)
{
return &req->ctx;
}
#define FUSE_OPCODE_LEN (FUSE_STATX + 1)
typedef void (*fuse_ll_func)(fuse_req_t, struct fuse_in_header *);
typedef void (*fuse_ll_func)(fuse_req_t*, struct fuse_in_header *);
const
fuse_ll_func
fuse_ll_funcs[FUSE_OPCODE_LEN] =
@ -1966,7 +1953,7 @@ fuse_ll_buf_process_read(struct fuse_session *se_,
const fuse_msgbuf_t *msgbuf_)
{
int err;
struct fuse_req *req;
struct fuse_req_t *req;
struct fuse_in_header *in;
in = (struct fuse_in_header*)msgbuf_->mem;
@ -1978,13 +1965,14 @@ fuse_ll_buf_process_read(struct fuse_session *se_,
if(req == NULL)
return fuse_send_enomem(se_->f,se_->ch,in->unique);
req->unique = in->unique;
req->ctx.len = in->len;
req->ctx.opcode = in->opcode;
req->ctx.unique = in->unique;
req->ctx.nodeid = in->nodeid;
req->ctx.uid = in->uid;
req->ctx.gid = in->gid;
req->ctx.pid = in->pid;
req->ctx.umask = 0;
req->ch = se_->ch;
err = ENOSYS;
@ -2008,7 +1996,7 @@ fuse_ll_buf_process_read_init(struct fuse_session *se_,
const fuse_msgbuf_t *msgbuf_)
{
int err;
struct fuse_req *req;
fuse_req_t *req;
struct fuse_in_header *in;
in = (struct fuse_in_header*)msgbuf_->mem;
@ -2017,13 +2005,14 @@ fuse_ll_buf_process_read_init(struct fuse_session *se_,
if(req == NULL)
return fuse_send_enomem(se_->f,se_->ch,in->unique);
req->unique = in->unique;
req->ctx.len = in->len;
req->ctx.opcode = in->opcode;
req->ctx.unique = in->unique;
req->ctx.nodeid = in->nodeid;
req->ctx.uid = in->uid;
req->ctx.gid = in->gid;
req->ctx.pid = in->pid;
req->ctx.umask = 0;
req->ch = se_->ch;
err = EIO;

57
libfuse/lib/helper.c

@ -285,7 +285,6 @@ struct fuse *
fuse_setup_common(int argc,
char *argv[],
const struct fuse_operations *op,
size_t op_size,
char **mountpoint,
int *fd)
{
@ -305,7 +304,7 @@ fuse_setup_common(int argc,
goto err_free;
}
fuse = fuse_new_common(ch, &args, op, op_size);
fuse = fuse_new(ch, &args, op);
fuse_opt_free_args(&args);
if (fuse == NULL)
goto err_unmount;
@ -325,44 +324,49 @@ fuse_setup_common(int argc,
err_unmount:
fuse_unmount_common(*mountpoint, ch);
if (fuse)
fuse_destroy(fuse);
err_free:
free(*mountpoint);
return NULL;
}
struct fuse *fuse_setup(int argc, char *argv[],
const struct fuse_operations *op, size_t op_size,
struct fuse *fuse_setup(int argc,
char *argv[],
const struct fuse_operations *op,
char **mountpoint)
{
return fuse_setup_common(argc, argv, op, op_size, mountpoint,
return fuse_setup_common(argc,
argv,
op,
mountpoint,
NULL);
}
static void fuse_teardown_common(struct fuse *fuse, char *mountpoint)
static void fuse_teardown_common(char *mountpoint)
{
struct fuse_session *se = fuse_get_session(fuse);
struct fuse_session *se = fuse_get_session();
struct fuse_chan *ch = se->ch;
fuse_remove_signal_handlers(se);
fuse_unmount_common(mountpoint, ch);
fuse_destroy(fuse);
free(mountpoint);
}
void fuse_teardown(struct fuse *fuse, char *mountpoint)
void fuse_teardown(char *mountpoint)
{
fuse_teardown_common(fuse, mountpoint);
fuse_teardown_common(mountpoint);
}
static int fuse_main_common(int argc, char *argv[],
const struct fuse_operations *op, size_t op_size)
int
fuse_main(int argc,
char *argv[],
const struct fuse_operations *op)
{
struct fuse *fuse;
char *mountpoint;
int res;
fuse = fuse_setup_common(argc, argv, op, op_size,
fuse = fuse_setup_common(argc,
argv,
op,
&mountpoint,
NULL);
if(fuse == NULL)
@ -370,30 +374,9 @@ static int fuse_main_common(int argc, char *argv[],
res = fuse_loop_mt(fuse);
fuse_teardown_common(fuse, mountpoint);
fuse_teardown_common(mountpoint);
if(res == -1)
return 1;
return 0;
}
int fuse_main_real(int argc,
char *argv[],
const struct fuse_operations *op,
size_t op_size)
{
return fuse_main_common(argc, argv, op, op_size);
}
#undef fuse_main
int fuse_main(void);
int fuse_main(void)
{
fprintf(stderr, "fuse_main(): This function does not exist\n");
return -1;
}
int fuse_version(void)
{
return FUSE_VERSION;
}

6
src/fuse_access.cpp

@ -50,12 +50,12 @@ _access(const Policy::Search &searchFunc_,
}
int
FUSE::access(const char *fusepath_,
FUSE::access(const fuse_req_ctx_t *ctx_,
const char *fusepath_,
int mask_)
{
const fs::path fusepath{fusepath_};
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
const ugid::Set ugid(ctx_->uid,ctx_->gid);
return ::_access(cfg.func.access.policy,
cfg.branches,

4
src/fuse_access.hpp

@ -16,10 +16,12 @@
#pragma once
#include "fuse_req_ctx.h"
namespace FUSE
{
int
access(const char *fusepath,
access(const fuse_req_ctx_t *ctx,
const char *fusepath,
int mask);
}

8
src/fuse_bmap.cpp

@ -20,16 +20,14 @@
#include "errno.hpp"
#include <cstdint>
#include <stddef.h>
int
FUSE::bmap(const char *fusepath_,
FUSE::bmap(const fuse_req_ctx_t *ctx_,
const char *fusepath_,
size_t blocksize_,
uint64_t *idx_)
{
(void)ctx_;
(void)fusepath_;
(void)blocksize_;
(void)idx_;

9
src/fuse_bmap.hpp

@ -18,12 +18,17 @@
#pragma once
#include "fuse.h"
#include "fuse_req_ctx.h"
#include <cstddef>
#include <cstdint>
namespace FUSE
{
int
bmap(const char *fusepath,
bmap(const fuse_req_ctx_t *ctx,
const char *fusepath,
size_t blocksize,
uint64_t *idx);
}

6
src/fuse_chmod.cpp

@ -94,8 +94,6 @@ int
_chmod(const fs::path &fusepath_,
const mode_t mode_)
{
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
return ::_chmod(cfg.func.chmod.policy,
cfg.func.getattr.policy,
@ -105,10 +103,12 @@ _chmod(const fs::path &fusepath_,
}
int
FUSE::chmod(const char *fusepath_,
FUSE::chmod(const fuse_req_ctx_t *ctx_,
const char *fusepath_,
mode_t mode_)
{
const fs::path fusepath{fusepath_};
const ugid::Set ugid(ctx_->uid,ctx_->gid);
return ::_chmod(fusepath,mode_);
}

5
src/fuse_chmod.hpp

@ -16,12 +16,15 @@
#pragma once
#include "fuse_req_ctx.h"
#include <sys/stat.h>
namespace FUSE
{
int
chmod(const char *fusepath,
chmod(const fuse_req_ctx_t *ctx,
const char *fusepath,
mode_t mode);
}

6
src/fuse_chown.cpp

@ -94,13 +94,13 @@ _chown(const Policy::Action &actionFunc_,
}
int
FUSE::chown(const char *fusepath_,
FUSE::chown(const fuse_req_ctx_t *ctx_,
const char *fusepath_,
uid_t uid_,
gid_t gid_)
{
const fs::path fusepath{fusepath_};
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
const ugid::Set ugid(ctx_->uid,ctx_->gid);
return ::_chown(cfg.func.chown.policy,
cfg.func.getattr.policy,

5
src/fuse_chown.hpp

@ -16,13 +16,16 @@
#pragma once
#include "fuse_req_ctx.h"
#include <unistd.h>
namespace FUSE
{
int
chown(const char *fusepath,
chown(const fuse_req_ctx_t *ctx,
const char *fusepath,
uid_t uid,
gid_t gid);
}

3
src/fuse_copy_file_range.cpp

@ -47,7 +47,8 @@ _copy_file_range(const int src_fd_,
}
ssize_t
FUSE::copy_file_range(const fuse_file_info_t *src_ffi_,
FUSE::copy_file_range(const fuse_req_ctx_t *ctx_,
const fuse_file_info_t *src_ffi_,
off_t src_off_,
const fuse_file_info_t *dst_ffi_,
off_t dst_off_,

3
src/fuse_copy_file_range.hpp

@ -32,7 +32,8 @@
namespace FUSE
{
ssize_t
copy_file_range(const fuse_file_info_t *ffi_in,
copy_file_range(const fuse_req_ctx_t *ctx_,
const fuse_file_info_t *ffi_in,
off_t offset_in,
const fuse_file_info_t *ffi_out,
off_t offset_out,

30
src/fuse_create.cpp

@ -223,7 +223,7 @@ _(const PassthroughEnum e_,
static
int
_create_for_insert_lambda(const fuse_context *fc_,
_create_for_insert_lambda(const fuse_req_ctx_t *ctx_,
const fs::path &fusepath_,
const mode_t mode_,
fuse_file_info_t *ffi_,
@ -231,9 +231,9 @@ _create_for_insert_lambda(const fuse_context *fc_,
{
int rv;
FileInfo *fi;
const ugid::Set ugid(fc_->uid,fc_->gid);
const ugid::Set ugid(ctx_->uid,ctx_->gid);
::_config_to_ffi_flags(cfg,fc_->pid,ffi_);
::_config_to_ffi_flags(cfg,ctx_->pid,ffi_);
if(cfg.writeback_cache)
::_tweak_flags_writeback_cache(&ffi_->flags);
ffi_->noflush = !::_calculate_flush(cfg.flushonclose,
@ -245,7 +245,7 @@ _create_for_insert_lambda(const fuse_context *fc_,
fusepath_,
ffi_,
mode_,
fc_->umask);
ctx_->umask);
if(rv == -EROFS)
{
cfg.branches.find_and_set_mode_ro();
@ -255,7 +255,7 @@ _create_for_insert_lambda(const fuse_context *fc_,
fusepath_,
ffi_,
mode_,
fc_->umask);
ctx_->umask);
}
if(rv < 0)
@ -278,7 +278,7 @@ _create_for_insert_lambda(const fuse_context *fc_,
return 0;
}
of_->backing_id = FUSE::passthrough_open(fc_,fi->fd);
of_->backing_id = FUSE::passthrough_open(fi->fd);
if(of_->backing_id < 0)
return 0;
@ -292,7 +292,7 @@ _create_for_insert_lambda(const fuse_context *fc_,
static
inline
auto
_create_insert_lambda(const fuse_context *fc_,
_create_insert_lambda(const fuse_req_ctx_t *ctx_,
const fs::path &fusepath_,
const mode_t mode_,
fuse_file_info_t *ffi_,
@ -301,7 +301,7 @@ _create_insert_lambda(const fuse_context *fc_,
return
[=](auto &val_)
{
*_rv_ = ::_create_for_insert_lambda(fc_,
*_rv_ = ::_create_for_insert_lambda(ctx_,
fusepath_,
mode_,
ffi_,
@ -326,7 +326,7 @@ _create_update_lambda()
static
int
_create(const fuse_context *fc_,
_create(const fuse_req_ctx_t *ctx_,
const fs::path &fusepath_,
mode_t mode_,
fuse_file_info_t *ffi_)
@ -335,15 +335,15 @@ _create(const fuse_context *fc_,
auto &of = state.open_files;
rv = -EINVAL;
of.try_emplace_and_visit(fc_->nodeid,
::_create_insert_lambda(fc_,fusepath_,mode_,ffi_,&rv),
of.try_emplace_and_visit(ctx_->nodeid,
::_create_insert_lambda(ctx_,fusepath_,mode_,ffi_,&rv),
::_create_update_lambda());
// Can't abort an emplace_and_visit and can't assume another thread
// hasn't created an entry since this failure so erase only if
// ref_count is default (0).
if(rv < 0)
of.erase_if(fc_->nodeid,
of.erase_if(ctx_->nodeid,
[](const auto &val_)
{
return (val_.second.ref_count <= 0);
@ -353,12 +353,12 @@ _create(const fuse_context *fc_,
}
int
FUSE::create(const char *fusepath_,
FUSE::create(const fuse_req_ctx_t *ctx_,
const char *fusepath_,
mode_t mode_,
fuse_file_info_t *ffi_)
{
const fs::path fusepath{fusepath_};
const fuse_context *fc = fuse_get_context();
return ::_create(fc,fusepath,mode_,ffi_);
return ::_create(ctx_,fusepath,mode_,ffi_);
}

3
src/fuse_create.hpp

@ -24,7 +24,8 @@
namespace FUSE
{
int
create(const char *fusepath,
create(const fuse_req_ctx_t *ctx,
const char *fusepath,
mode_t mode,
fuse_file_info_t *ffi);
}

6
src/fuse_fallocate.cpp

@ -40,18 +40,18 @@ _fallocate(const int fd_,
}
int
FUSE::fallocate(const uint64_t fh_,
FUSE::fallocate(const fuse_req_ctx_t *ctx_,
const uint64_t fh_,
int mode_,
off_t offset_,
off_t len_)
{
uint64_t fh;
const fuse_context *fc = fuse_get_context();
fh = fh_;
if(fh == 0)
{
state.open_files.cvisit(fc->nodeid,
state.open_files.cvisit(ctx_->nodeid,
[&](auto &val_)
{
fh = val_.second.fi->to_fh();

3
src/fuse_fallocate.hpp

@ -22,7 +22,8 @@
namespace FUSE
{
int
fallocate(const uint64_t fh,
fallocate(const fuse_req_ctx_t *ctx,
const uint64_t fh,
int mode,
off_t offset,
off_t len);

6
src/fuse_fchmod.cpp

@ -37,16 +37,16 @@ _fchmod(const int fd_,
}
int
FUSE::fchmod(const uint64_t fh_,
FUSE::fchmod(const fuse_req_ctx_t *ctx_,
const uint64_t fh_,
const mode_t mode_)
{
uint64_t fh;
const fuse_context *fc = fuse_get_context();
fh = fh_;
if(fh == 0)
{
state.open_files.cvisit(fc->nodeid,
state.open_files.cvisit(ctx_->nodeid,
[&](auto &val_)
{
fh = val_.second.fi->to_fh();

5
src/fuse_fchmod.hpp

@ -18,12 +18,15 @@
#include "fuse.h"
#include "fuse_req_ctx.h"
#include <sys/stat.h>
namespace FUSE
{
int
fchmod(const uint64_t fh,
fchmod(const fuse_req_ctx_t *ctx,
const uint64_t fh,
const mode_t mode);
}

6
src/fuse_fchown.cpp

@ -40,17 +40,17 @@ _fchown(const int fd_,
}
int
FUSE::fchown(const uint64_t fh_,
FUSE::fchown(const fuse_req_ctx_t *ctx_,
const uint64_t fh_,
const uid_t uid_,
const gid_t gid_)
{
uint64_t fh;
const fuse_context *fc = fuse_get_context();
fh = fh_;
if(fh == 0)
{
state.open_files.cvisit(fc->nodeid,
state.open_files.cvisit(ctx_->nodeid,
[&](auto &val_)
{
fh = val_.second.fi->to_fh();

3
src/fuse_fchown.hpp

@ -22,7 +22,8 @@
namespace FUSE
{
int
fchown(const uint64_t fh,
fchown(const fuse_req_ctx_t *ctx,
const uint64_t fh,
uid_t uid,
gid_t gid);
}

6
src/fuse_fgetattr.cpp

@ -46,18 +46,18 @@ _fgetattr(const FileInfo *fi_,
int
FUSE::fgetattr(const uint64_t fh_,
FUSE::fgetattr(const fuse_req_ctx_t *ctx_,
const uint64_t fh_,
struct stat *st_,
fuse_timeouts_t *timeout_)
{
int rv;
uint64_t fh;
const fuse_context *fc = fuse_get_context();
fh = fh_;
if(fh == 0)
{
state.open_files.cvisit(fc->nodeid,
state.open_files.cvisit(ctx_->nodeid,
[&](const auto &val_)
{
fh = val_.second.fi->to_fh();

3
src/fuse_fgetattr.hpp

@ -26,7 +26,8 @@
namespace FUSE
{
int
fgetattr(const uint64_t fh,
fgetattr(const fuse_req_ctx_t *ctx,
const uint64_t fh,
struct stat *st,
fuse_timeouts_t *timeout);
}

6
src/fuse_flock.cpp

@ -37,16 +37,16 @@ _flock(const int fd_,
}
int
FUSE::flock(const fuse_file_info_t *ffi_,
FUSE::flock(const fuse_req_ctx_t *ctx_,
const fuse_file_info_t *ffi_,
int op_)
{
uint64_t fh;
const fuse_context *fc = fuse_get_context();
fh = ffi_->fh;
if(fh == 0)
{
state.open_files.cvisit(fc->nodeid,
state.open_files.cvisit(ctx_->nodeid,
[&](const auto &val_)
{
fh = val_.second.fi->to_fh();

3
src/fuse_flock.hpp

@ -22,6 +22,7 @@
namespace FUSE
{
int
flock(const fuse_file_info_t *ffi,
flock(const fuse_req_ctx_t *ctx,
const fuse_file_info_t *ffi,
int op);
}

3
src/fuse_flush.cpp

@ -38,7 +38,8 @@ _flush(const int fd_)
}
int
FUSE::flush(const fuse_file_info_t *ffi_)
FUSE::flush(const fuse_req_ctx_t *ctx_,
const fuse_file_info_t *ffi_)
{
FileInfo *fi = FileInfo::from_fh(ffi_->fh);

3
src/fuse_flush.hpp

@ -22,5 +22,6 @@
namespace FUSE
{
int
flush(const fuse_file_info_t *ffi);
flush(const fuse_req_ctx_t *ctx,
const fuse_file_info_t *ffi);
}

3
src/fuse_fsync.cpp

@ -43,7 +43,8 @@ _fsync(const int fd_,
}
int
FUSE::fsync(const uint64_t fh_,
FUSE::fsync(const fuse_req_ctx_t *ctx_,
const uint64_t fh_,
int isdatasync_)
{
FileInfo *fi = FileInfo::from_fh(fh_);

3
src/fuse_fsync.hpp

@ -22,7 +22,8 @@
namespace FUSE
{
int
fsync(const uint64_t fh,
fsync(const fuse_req_ctx_t *ctx,
const uint64_t fh,
int isdatasync);
}

3
src/fuse_fsyncdir.cpp

@ -35,7 +35,8 @@ _fsyncdir(const DirInfo *di_,
}
int
FUSE::fsyncdir(const fuse_file_info_t *ffi_,
FUSE::fsyncdir(const fuse_req_ctx_t *ctx_,
const fuse_file_info_t *ffi_,
int isdatasync_)
{
DirInfo *di = DirInfo::from_fh(ffi_->fh);

3
src/fuse_fsyncdir.hpp

@ -22,6 +22,7 @@
namespace FUSE
{
int
fsyncdir(const fuse_file_info_t *ffi,
fsyncdir(const fuse_req_ctx_t *ctx,
const fuse_file_info_t *ffi,
int isdatasync);
}

6
src/fuse_ftruncate.cpp

@ -37,16 +37,16 @@ _ftruncate(const int fd_,
}
int
FUSE::ftruncate(const uint64_t fh_,
FUSE::ftruncate(const fuse_req_ctx_t *ctx_,
const uint64_t fh_,
off_t size_)
{
uint64_t fh;
const fuse_context *fc = fuse_get_context();
fh = fh_;
if(fh == 0)
{
state.open_files.cvisit(fc->nodeid,
state.open_files.cvisit(ctx_->nodeid,
[&](auto &val_)
{
fh = val_.second.fi->to_fh();

3
src/fuse_ftruncate.hpp

@ -25,6 +25,7 @@
namespace FUSE
{
int
ftruncate(const uint64_t fh,
ftruncate(const fuse_req_ctx_t *ctx,
const uint64_t fh,
off_t size);
}

6
src/fuse_futimens.cpp

@ -39,16 +39,16 @@ _futimens(const int fd_,
}
int
FUSE::futimens(const uint64_t fh_,
FUSE::futimens(const fuse_req_ctx_t *ctx_,
const uint64_t fh_,
const struct timespec ts_[2])
{
uint64_t fh;
const fuse_context *fc = fuse_get_context();
fh = fh_;
if(fh == 0)
{
state.open_files.cvisit(fc->nodeid,
state.open_files.cvisit(ctx_->nodeid,
[&](const auto &val_)
{
fh = val_.second.fi->to_fh();

3
src/fuse_futimens.hpp

@ -24,6 +24,7 @@
namespace FUSE
{
int
futimens(const uint64_t fh,
futimens(const fuse_req_ctx_t *ctx,
const uint64_t fh,
const timespec ts[2]);
}

18
src/fuse_getattr.cpp

@ -177,8 +177,6 @@ _getattr(const fs::path &fusepath_,
fuse_timeouts_t *timeout_)
{
int rv;
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
rv = ::_getattr(cfg.func.getattr.policy,
cfg.branches,
@ -199,13 +197,25 @@ _getattr(const fs::path &fusepath_,
}
int
FUSE::getattr(const char *fusepath_,
FUSE::getattr(const fuse_req_ctx_t *ctx_,
const char *fusepath_,
struct stat *st_,
fuse_timeouts_t *timeout_)
{
const fs::path fusepath{fusepath_};
return FUSE::getattr(fusepath,st_,timeout_);
return FUSE::getattr(ctx_,fusepath,st_,timeout_);
}
int
FUSE::getattr(const fuse_req_ctx_t *ctx_,
const fs::path &fusepath_,
struct stat *st_,
fuse_timeouts_t *timeout_)
{
const ugid::Set ugid(ctx_);
return FUSE::getattr(fusepath_,st_,timeout_);
}
int

9
src/fuse_getattr.hpp

@ -28,7 +28,14 @@
namespace FUSE
{
int
getattr(const char *fusepath,
getattr(const fuse_req_ctx_t *ctx,
const char *fusepath,
struct stat *buf,
fuse_timeouts_t *timeout);
int
getattr(const fuse_req_ctx_t *ctx,
const fs::path &fusepath,
struct stat *buf,
fuse_timeouts_t *timeout);

6
src/fuse_getxattr.cpp

@ -172,7 +172,8 @@ _getxattr(const Policy::Search &searchFunc_,
}
int
FUSE::getxattr(const char *fusepath_,
FUSE::getxattr(const fuse_req_ctx_t *ctx_,
const char *fusepath_,
const char *attrname_,
char *attrvalue_,
size_t attrvalue_size_)
@ -192,8 +193,7 @@ FUSE::getxattr(const char *fusepath_,
if(cfg.xattr.to_int())
return -cfg.xattr.to_int();
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
const ugid::Set ugid(ctx_->uid,ctx_->gid);
return ::_getxattr(cfg.func.getxattr.policy,
cfg.branches,

5
src/fuse_getxattr.hpp

@ -16,13 +16,16 @@
#pragma once
#include "fuse_req_ctx.h"
#include <cstddef>
namespace FUSE
{
int
getxattr(const char *fusepath,
getxattr(const fuse_req_ctx_t *ctx,
const char *fusepath,
const char *attrname,
char *attrvalue,
size_t attrvalue_size);

19
src/fuse_ioctl.cpp

@ -107,14 +107,14 @@ _ioctl(const int fd_,
static
int
_ioctl_file(const fuse_file_info_t *ffi_,
_ioctl_file(const fuse_req_ctx_t *ctx_,
const fuse_file_info_t *ffi_,
const uint32_t cmd_,
void *data_,
uint32_t *out_bufsz_)
{
FileInfo *fi = FileInfo::from_fh(ffi_->fh);
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
const ugid::Set ugid(ctx_);
return ::_ioctl(fi->fd,cmd_,data_,out_bufsz_);
}
@ -156,14 +156,14 @@ _ioctl_dir_base(const Policy::Search &searchFunc_,
static
int
_ioctl_dir(const fuse_file_info_t *ffi_,
_ioctl_dir(const fuse_req_ctx_t *ctx_,
const fuse_file_info_t *ffi_,
const uint32_t cmd_,
void *data_,
uint32_t *out_bufsz_)
{
DirInfo *di = DirInfo::from_fh(ffi_->fh);
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
const ugid::Set ugid(ctx_);
return ::_ioctl_dir_base(cfg.func.open.policy,
cfg.branches,
@ -181,7 +181,8 @@ _is_btrfs_ioctl_cmd(const unsigned long cmd_)
}
int
FUSE::ioctl(const fuse_file_info_t *ffi_,
FUSE::ioctl(const fuse_req_ctx_t *ctx_,
const fuse_file_info_t *ffi_,
unsigned long cmd_,
void *arg_,
unsigned int flags_,
@ -192,7 +193,7 @@ FUSE::ioctl(const fuse_file_info_t *ffi_,
return -ENOTTY;
if(flags_ & FUSE_IOCTL_DIR)
return ::_ioctl_dir(ffi_,cmd_,data_,out_bufsz_);
return ::_ioctl_dir(ctx_,ffi_,cmd_,data_,out_bufsz_);
return ::_ioctl_file(ffi_,cmd_,data_,out_bufsz_);
return ::_ioctl_file(ctx_,ffi_,cmd_,data_,out_bufsz_);
}

3
src/fuse_ioctl.hpp

@ -24,7 +24,8 @@
namespace FUSE
{
int
ioctl(const fuse_file_info_t *ffi,
ioctl(const fuse_req_ctx_t *ctx,
const fuse_file_info_t *ffi,
unsigned long cmd,
void *arg,
unsigned int flags,

65
src/fuse_link.cpp

@ -165,28 +165,27 @@ _link_preserve_path(const Policy::Action &actionFunc_,
static
int
_link(Config &cfg_,
const fs::path &oldpath_,
_link(const fs::path &oldpath_,
const fs::path &newpath_,
struct stat *st_)
{
if(cfg_.func.create.policy.path_preserving() && !cfg_.ignorepponrename)
return ::_link_preserve_path(cfg_.func.link.policy,
cfg_.branches,
if(cfg.func.create.policy.path_preserving() && !cfg.ignorepponrename)
return ::_link_preserve_path(cfg.func.link.policy,
cfg.branches,
oldpath_,
newpath_,
st_);
return ::_link_create_path(cfg_.func.getattr.policy,
cfg_.func.link.policy,
cfg_.branches,
return ::_link_create_path(cfg.func.getattr.policy,
cfg.func.link.policy,
cfg.branches,
oldpath_,
newpath_);
}
static
int
_link(Config &cfg_,
_link(const fuse_req_ctx_t *ctx_,
const fs::path &oldpath_,
const fs::path &newpath_,
struct stat *st_,
@ -194,7 +193,7 @@ _link(Config &cfg_,
{
int rv;
rv = ::_link(cfg_,oldpath_,newpath_,st_);
rv = ::_link(oldpath_,newpath_,st_);
if(rv < 0)
return rv;
@ -203,7 +202,8 @@ _link(Config &cfg_,
static
int
_link_exdev_rel_symlink(const fs::path &oldpath_,
_link_exdev_rel_symlink(const fuse_req_ctx_t *ctx_,
const fs::path &oldpath_,
const fs::path &newpath_,
struct stat *st_,
fuse_timeouts_t *timeouts_)
@ -214,9 +214,9 @@ _link_exdev_rel_symlink(const fs::path &oldpath_,
target = target.lexically_relative(linkpath.parent_path());
rv = FUSE::symlink(target.c_str(),linkpath);
rv = FUSE::symlink(ctx_,target.c_str(),linkpath);
if(rv == 0)
rv = FUSE::getattr(oldpath_,st_,timeouts_);
rv = FUSE::getattr(ctx_,oldpath_,st_,timeouts_);
// Disable caching since we created a symlink but should be a regular.
timeouts_->attr = 0;
@ -227,7 +227,8 @@ _link_exdev_rel_symlink(const fs::path &oldpath_,
static
int
_link_exdev_abs_base_symlink(const Policy::Search &openPolicy_,
_link_exdev_abs_base_symlink(const fuse_req_ctx_t *ctx_,
const Policy::Search &openPolicy_,
const Branches::Ptr &ibranches_,
const fs::path &oldpath_,
const fs::path &newpath_,
@ -244,9 +245,9 @@ _link_exdev_abs_base_symlink(const Policy::Search &openPolicy_,
target = obranches[0]->path / oldpath_;
rv = FUSE::symlink(target.c_str(),newpath_);
rv = FUSE::symlink(ctx_,target.c_str(),newpath_);
if(rv == 0)
rv = FUSE::getattr(oldpath_,st_,timeouts_);
rv = FUSE::getattr(ctx_,oldpath_,st_,timeouts_);
// Disable caching since we created a symlink but should be a regular.
timeouts_->attr = 0;
@ -257,7 +258,8 @@ _link_exdev_abs_base_symlink(const Policy::Search &openPolicy_,
static
int
_link_exdev_abs_pool_symlink(const fs::path &mount_,
_link_exdev_abs_pool_symlink(const fuse_req_ctx_t *ctx_,
const fs::path &mount_,
const fs::path &oldpath_,
const fs::path &newpath_,
struct stat *st_,
@ -269,9 +271,9 @@ _link_exdev_abs_pool_symlink(const fs::path &mount_,
target = mount_ / oldpath_;
rv = FUSE::symlink(target.c_str(),newpath_);
rv = FUSE::symlink(ctx_,target.c_str(),newpath_);
if(rv == 0)
rv = FUSE::getattr(oldpath_,st_,timeouts_);
rv = FUSE::getattr(ctx_,oldpath_,st_,timeouts_);
// Disable caching since we created a symlink but should be a regular.
timeouts_->attr = 0;
@ -282,30 +284,33 @@ _link_exdev_abs_pool_symlink(const fs::path &mount_,
static
int
_link_exdev(Config &cfg_,
_link_exdev(const fuse_req_ctx_t *ctx_,
const fs::path &oldpath_,
const fs::path &newpath_,
struct stat *st_,
fuse_timeouts_t *timeouts_)
{
switch(cfg_.link_exdev)
switch(cfg.link_exdev)
{
case LinkEXDEV::ENUM::PASSTHROUGH:
return -EXDEV;
case LinkEXDEV::ENUM::REL_SYMLINK:
return ::_link_exdev_rel_symlink(oldpath_,
return ::_link_exdev_rel_symlink(ctx_,
oldpath_,
newpath_,
st_,
timeouts_);
case LinkEXDEV::ENUM::ABS_BASE_SYMLINK:
return ::_link_exdev_abs_base_symlink(cfg_.func.open.policy,
cfg_.branches,
return ::_link_exdev_abs_base_symlink(ctx_,
cfg.func.open.policy,
cfg.branches,
oldpath_,
newpath_,
st_,
timeouts_);
case LinkEXDEV::ENUM::ABS_POOL_SYMLINK:
return ::_link_exdev_abs_pool_symlink(cfg_.mountpoint,
return ::_link_exdev_abs_pool_symlink(ctx_,
cfg.mountpoint,
oldpath_,
newpath_,
st_,
@ -316,7 +321,8 @@ _link_exdev(Config &cfg_,
}
int
FUSE::link(const char *oldpath_,
FUSE::link(const fuse_req_ctx_t *ctx_,
const char *oldpath_,
const char *newpath_,
struct stat *st_,
fuse_timeouts_t *timeouts_)
@ -324,12 +330,11 @@ FUSE::link(const char *oldpath_,
int rv;
const fs::path oldpath{oldpath_};
const fs::path newpath{newpath_};
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
const ugid::Set ugid(ctx_);
rv = ::_link(cfg,oldpath,newpath,st_,timeouts_);
rv = ::_link(ctx_,oldpath,newpath,st_,timeouts_);
if(rv == -EXDEV)
rv = ::_link_exdev(cfg,oldpath,newpath,st_,timeouts_);
rv = ::_link_exdev(ctx_,oldpath,newpath,st_,timeouts_);
return rv;
}

3
src/fuse_link.hpp

@ -22,7 +22,8 @@
namespace FUSE
{
int
link(const char *oldpath,
link(const fuse_req_ctx_t *ctx,
const char *oldpath,
const char *newpath,
struct stat *st,
fuse_timeouts_t *timeouts);

6
src/fuse_listxattr.cpp

@ -123,7 +123,8 @@ _listxattr(const Policy::Search &searchFunc_,
}
int
FUSE::listxattr(const char *fusepath_,
FUSE::listxattr(const fuse_req_ctx_t *ctx_,
const char *fusepath_,
char *list_,
size_t size_)
{
@ -142,8 +143,7 @@ FUSE::listxattr(const char *fusepath_,
return -ENOSYS;
}
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
const ugid::Set ugid(ctx_);
return ::_listxattr(cfg.func.listxattr.policy,
cfg.branches,

5
src/fuse_listxattr.hpp

@ -16,12 +16,15 @@
#pragma once
#include "fuse_req_ctx.h"
#include <cstddef>
namespace FUSE
{
int
listxattr(const char *fusepath,
listxattr(const fuse_req_ctx_t *ctx,
const char *fusepath,
char *buf,
size_t count);
}

3
src/fuse_lock.cpp

@ -24,7 +24,8 @@
int
FUSE::lock(const fuse_file_info_t *ffi,
FUSE::lock(const fuse_req_ctx_t *ctx,
const fuse_file_info_t *ffi,
int cmd,
struct flock *flock)
{

3
src/fuse_lock.hpp

@ -23,7 +23,8 @@
namespace FUSE
{
int
lock(const fuse_file_info_t *ffi,
lock(const fuse_req_ctx_t *ctx,
const fuse_file_info_t *ffi,
int cmd,
struct flock *flock);
}

10
src/fuse_mkdir.cpp

@ -125,20 +125,20 @@ _mkdir(const Policy::Search &getattrPolicy_,
}
int
FUSE::mkdir(const char *fusepath_,
FUSE::mkdir(const fuse_req_ctx_t *ctx_,
const char *fusepath_,
mode_t mode_)
{
int rv;
const fs::path fusepath{fusepath_};
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
const ugid::Set ugid(ctx_);
rv = ::_mkdir(cfg.func.getattr.policy,
cfg.func.mkdir.policy,
cfg.branches,
fusepath,
mode_,
fc->umask);
ctx_->umask);
if(rv == -EROFS)
{
cfg.branches.find_and_set_mode_ro();
@ -147,7 +147,7 @@ FUSE::mkdir(const char *fusepath_,
cfg.branches,
fusepath,
mode_,
fc->umask);
ctx_->umask);
}
return rv;

5
src/fuse_mkdir.hpp

@ -16,12 +16,15 @@
#pragma once
#include "fuse_req_ctx.h"
#include <sys/stat.h>
namespace FUSE
{
int
mkdir(const char *fusepath,
mkdir(const fuse_req_ctx_t *ctx,
const char *fusepath,
mode_t mode);
}

10
src/fuse_mknod.cpp

@ -132,21 +132,21 @@ _mknod(const Policy::Search &searchFunc_,
}
int
FUSE::mknod(const char *fusepath_,
FUSE::mknod(const fuse_req_ctx_t *ctx_,
const char *fusepath_,
mode_t mode_,
dev_t rdev_)
{
int rv;
const fs::path fusepath{fusepath_};
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
const ugid::Set ugid(ctx_);
rv = ::_mknod(cfg.func.getattr.policy,
cfg.func.mknod.policy,
cfg.branches,
fusepath,
mode_,
fc->umask,
ctx_->umask,
rdev_);
if(rv == -EROFS)
{
@ -156,7 +156,7 @@ FUSE::mknod(const char *fusepath_,
cfg.branches,
fusepath,
mode_,
fc->umask,
ctx_->umask,
rdev_);
}

5
src/fuse_mknod.hpp

@ -17,13 +17,16 @@
#pragma once
#include "fuse_req_ctx.h"
#include <sys/stat.h>
namespace FUSE
{
int
mknod(const char *fusepath,
mknod(const fuse_req_ctx_t *ctx,
const char *fusepath,
mode_t mode,
dev_t rdev);
}

40
src/fuse_open.cpp

@ -280,16 +280,16 @@ _(const PassthroughEnum e_,
static
int
_open_for_insert_lambda(const fuse_context *fc_,
_open_for_insert_lambda(const fuse_req_ctx_t *ctx_,
const fs::path &fusepath_,
fuse_file_info_t *ffi_,
State::OpenFile *of_)
{
int rv;
FileInfo *fi;
const ugid::Set ugid(fc_->uid,fc_->gid);
const ugid::Set ugid(ctx_);
::_config_to_ffi_flags(cfg,fc_->pid,ffi_);
::_config_to_ffi_flags(cfg,ctx_->pid,ffi_);
if(cfg.writeback_cache)
::_tweak_flags_writeback_cache(&ffi_->flags);
@ -324,7 +324,7 @@ _open_for_insert_lambda(const fuse_context *fc_,
return 0;
}
of_->backing_id = FUSE::passthrough_open(fc_,fi->fd);
of_->backing_id = FUSE::passthrough_open(fi->fd);
if(of_->backing_id <= 0)
return 0;
@ -337,15 +337,15 @@ _open_for_insert_lambda(const fuse_context *fc_,
static
int
_open_for_update_lambda(const fuse_context *fc_,
_open_for_update_lambda(const fuse_req_ctx_t *ctx_,
const fs::path &fusepath_,
fuse_file_info_t *ffi_,
State::OpenFile *of_)
{
int rv;
const ugid::Set ugid(fc_->uid,fc_->gid);
const ugid::Set ugid(ctx_);
::_config_to_ffi_flags(cfg,fc_->pid,ffi_);
::_config_to_ffi_flags(cfg,ctx_->pid,ffi_);
if(cfg.writeback_cache)
::_tweak_flags_writeback_cache(&ffi_->flags);
@ -375,7 +375,7 @@ _open_for_update_lambda(const fuse_context *fc_,
static
inline
auto
_open_insert_lambda(const fuse_context *fc_,
_open_insert_lambda(const fuse_req_ctx_t *ctx_,
const fs::path &fusepath_,
fuse_file_info_t *ffi_,
int *rv_)
@ -383,7 +383,7 @@ _open_insert_lambda(const fuse_context *fc_,
return
[=](auto &val_)
{
*rv_ = ::_open_for_insert_lambda(fc_,
*rv_ = ::_open_for_insert_lambda(ctx_,
fusepath_,
ffi_,
&val_.second);
@ -393,7 +393,7 @@ _open_insert_lambda(const fuse_context *fc_,
static
inline
auto
_open_update_lambda(const fuse_context *fc_,
_open_update_lambda(const fuse_req_ctx_t *ctx_,
const fs::path &fusepath_,
fuse_file_info_t *ffi_,
int *rv_)
@ -406,14 +406,14 @@ _open_update_lambda(const fuse_context *fc_,
// to abort an insert.
if(val_.second.ref_count <= 0)
{
*rv_ = ::_open_for_insert_lambda(fc_,
*rv_ = ::_open_for_insert_lambda(ctx_,
fusepath_,
ffi_,
&val_.second);
return;
}
*rv_ = ::_open_for_update_lambda(fc_,
*rv_ = ::_open_for_update_lambda(ctx_,
fusepath_,
ffi_,
&val_.second);
@ -422,7 +422,7 @@ _open_update_lambda(const fuse_context *fc_,
static
int
_open(const fuse_context *fc_,
_open(const fuse_req_ctx_t *ctx_,
const fs::path &fusepath_,
fuse_file_info_t *ffi_)
{
@ -430,15 +430,15 @@ _open(const fuse_context *fc_,
auto &of = state.open_files;
rv = -EINVAL;
of.try_emplace_and_visit(fc_->nodeid,
::_open_insert_lambda(fc_,fusepath_,ffi_,&rv),
::_open_update_lambda(fc_,fusepath_,ffi_,&rv));
of.try_emplace_and_visit(ctx_->nodeid,
::_open_insert_lambda(ctx_,fusepath_,ffi_,&rv),
::_open_update_lambda(ctx_,fusepath_,ffi_,&rv));
// Can't abort an emplace_and_visit and can't assume another thread
// hasn't created an entry since this failure so erase only if
// ref_count is default (0).
if(rv < 0)
of.erase_if(fc_->nodeid,
of.erase_if(ctx_->nodeid,
[](auto &val_)
{
return (val_.second.ref_count <= 0);
@ -449,11 +449,11 @@ _open(const fuse_context *fc_,
int
FUSE::open(const char *fusepath_,
FUSE::open(const fuse_req_ctx_t *ctx_,
const char *fusepath_,
fuse_file_info_t *ffi_)
{
const fs::path fusepath{fusepath_};
const fuse_context *fc = fuse_get_context();
return ::_open(fc,fusepath,ffi_);
return ::_open(ctx_,fusepath,ffi_);
}

3
src/fuse_open.hpp

@ -22,6 +22,7 @@
namespace FUSE
{
int
open(const char *fusepath,
open(const fuse_req_ctx_t *ctx,
const char *fusepath,
fuse_file_info_t *ffi);
}

3
src/fuse_opendir.cpp

@ -23,7 +23,8 @@
int
FUSE::opendir(const char *fusepath_,
FUSE::opendir(const fuse_req_ctx_t *ctx_,
const char *fusepath_,
fuse_file_info_t *ffi_)
{
DirInfo *di;

3
src/fuse_opendir.hpp

@ -22,6 +22,7 @@
namespace FUSE
{
int
opendir(const char *fusepath,
opendir(const fuse_req_ctx_t *ctx,
const char *fusepath,
fuse_file_info_t *ffi);
}

13
src/fuse_passthrough.hpp

@ -4,27 +4,28 @@
#include "fuse.h"
// Becoming root is required due to current security policies within
// the kernel. This may be able to be changed in the future.
namespace FUSE
{
static
inline
int
passthrough_open(const fuse_context *fc_,
const int fd_)
passthrough_open(const int fd_)
{
const ugid::SetRootGuard _;
return fuse_passthrough_open(fc_,fd_);
return fuse_passthrough_open(fd_);
}
static
inline
int
passthrough_close(const fuse_context *fc_,
const int backing_id_)
passthrough_close(const int backing_id_)
{
const ugid::SetRootGuard _;
return fuse_passthrough_close(fc_,backing_id_);
return fuse_passthrough_close(backing_id_);
}
}

4
src/fuse_poll.cpp

@ -24,10 +24,12 @@
int
FUSE::poll(const fuse_file_info_t *ffi_,
FUSE::poll(const fuse_req_ctx_t *ctx_,
const fuse_file_info_t *ffi_,
fuse_pollhandle_t *ph_,
unsigned *reventsp_)
{
(void)ctx_;
(void)ffi_;
(void)ph_;
(void)reventsp_;

3
src/fuse_poll.hpp

@ -24,7 +24,8 @@
namespace FUSE
{
int
poll(const fuse_file_info_t *ffi,
poll(const fuse_req_ctx_t *ctx,
const fuse_file_info_t *ffi,
fuse_pollhandle_t *ph,
unsigned *reventsp);
}

8
src/fuse_read.cpp

@ -56,12 +56,13 @@ _read_cached(const int fd_,
}
int
FUSE::read(const fuse_file_info_t *ffi_,
FUSE::read(const fuse_req_ctx_t *ctx_,
const fuse_file_info_t *ffi_,
char *buf_,
size_t size_,
off_t offset_)
{
ioprio::SetFrom iop(fuse_get_context()->pid);
ioprio::SetFrom iop(ctx_->pid);
FileInfo *fi = FileInfo::from_fh(ffi_->fh);
if(fi->direct_io)
@ -71,7 +72,8 @@ FUSE::read(const fuse_file_info_t *ffi_,
}
int
FUSE::read_null(const fuse_file_info_t *ffi_,
FUSE::read_null(const fuse_req_ctx_t *ctx_,
const fuse_file_info_t *ffi_,
char *buf_,
size_t size_,
off_t offset_)

6
src/fuse_read.hpp

@ -24,13 +24,15 @@
namespace FUSE
{
int
read(const fuse_file_info_t *ffi,
read(const fuse_req_ctx_t *ctx,
const fuse_file_info_t *ffi,
char *buf,
size_t size,
off_t offset);
int
read_null(const fuse_file_info_t *ffi,
read_null(const fuse_req_ctx_t *ctx,
const fuse_file_info_t *ffi,
char *buf,
size_t size,
off_t offset);

10
src/fuse_readdir.cpp

@ -31,10 +31,11 @@
int
FUSE::readdir(const fuse_file_info_t *ffi_,
FUSE::readdir(const fuse_req_ctx_t *ctx_,
const fuse_file_info_t *ffi_,
fuse_dirents_t *buf_)
{
return cfg.readdir(ffi_,buf_);
return cfg.readdir(ctx_,ffi_,buf_);
}
FUSE::ReadDir::ReadDir(const std::string_view s_)
@ -99,7 +100,8 @@ _handle_ENOENT(const fuse_file_info_t *ffi_,
}
int
FUSE::ReadDir::operator()(const fuse_file_info_t *ffi_,
FUSE::ReadDir::operator()(const fuse_req_ctx_t *ctx_,
const fuse_file_info_t *ffi_,
fuse_dirents_t *buf_)
{
int rv;
@ -108,7 +110,7 @@ FUSE::ReadDir::operator()(const fuse_file_info_t *ffi_,
readdir = std::atomic_load(&_impl);
assert(readdir);
rv = (*readdir)(ffi_,buf_);
rv = (*readdir)(ctx_,ffi_,buf_);
if(rv == -ENOENT)
return ::_handle_ENOENT(ffi_,buf_);

6
src/fuse_readdir.hpp

@ -28,7 +28,8 @@
namespace FUSE
{
int readdir(fuse_file_info_t const *ffi,
int readdir(const fuse_req_ctx_t *ctx,
fuse_file_info_t const *ffi,
fuse_dirents_t *buf);
}
@ -49,7 +50,8 @@ namespace FUSE
int from_string(const std::string_view);
public:
int operator()(fuse_file_info_t const *ffi,
int operator()(const fuse_req_ctx_t *ctx,
fuse_file_info_t const *ffi,
fuse_dirents_t *buf);
public:

3
src/fuse_readdir_base.hpp

@ -30,7 +30,8 @@ namespace FUSE
virtual ~ReadDirBase() {};
public:
virtual int operator()(const fuse_file_info_t *ffi,
virtual int operator()(const fuse_req_ctx_t *ctx,
const fuse_file_info_t *ffi,
fuse_dirents_t *buf) = 0;
};
}

8
src/fuse_readdir_cor.cpp

@ -86,16 +86,16 @@ _concurrent_readdir(ThreadPool &tp_,
}
int
FUSE::ReadDirCOR::operator()(const fuse_file_info_t *ffi_,
FUSE::ReadDirCOR::operator()(const fuse_req_ctx_t *ctx_,
const fuse_file_info_t *ffi_,
fuse_dirents_t *dirents_)
{
DirInfo *di = DirInfo::from_fh(ffi_->fh);
const fuse_context *fc = fuse_get_context();
return ::_concurrent_readdir(_tp,
cfg.branches,
di->fusepath,
dirents_,
fc->uid,
fc->gid);
ctx_->uid,
ctx_->gid);
}

3
src/fuse_readdir_cor.hpp

@ -33,7 +33,8 @@ namespace FUSE
unsigned max_queue_depth);
~ReadDirCOR();
int operator()(const fuse_file_info_t *ffi,
int operator()(const fuse_req_ctx_t *ctx,
const fuse_file_info_t *ffi,
fuse_dirents_t *buf);
private:

8
src/fuse_readdir_cosr.cpp

@ -61,16 +61,16 @@ _readdir(ThreadPool &tp_,
}
int
FUSE::ReadDirCOSR::operator()(fuse_file_info_t const *ffi_,
FUSE::ReadDirCOSR::operator()(const fuse_req_ctx_t *ctx_,
fuse_file_info_t const *ffi_,
fuse_dirents_t *dirents_)
{
DirInfo *di = DirInfo::from_fh(ffi_->fh);
const fuse_context *fc = fuse_get_context();
return ::_readdir(_tp,
cfg.branches,
di->fusepath,
dirents_,
fc->uid,
fc->gid);
ctx_->uid,
ctx_->gid);
}

3
src/fuse_readdir_cosr.hpp

@ -32,7 +32,8 @@ namespace FUSE
unsigned max_queue_depth);
~ReadDirCOSR();
int operator()(fuse_file_info_t const *ffi,
int operator()(const fuse_req_ctx_t *ctx,
fuse_file_info_t const *ffi,
fuse_dirents_t *buf);
private:

3
src/fuse_readdir_plus.cpp

@ -22,7 +22,8 @@
int
FUSE::readdir_plus(const fuse_file_info_t *ffi_,
FUSE::readdir_plus(const fuse_req_ctx_t *ctx_,
const fuse_file_info_t *ffi_,
fuse_dirents_t *buf_)
{
return -ENOTSUP;

3
src/fuse_readdir_plus.hpp

@ -21,6 +21,7 @@
namespace FUSE
{
int readdir_plus(fuse_file_info_t const *ffi,
int readdir_plus(const fuse_req_ctx_t *ctx,
const fuse_file_info_t *ffi,
fuse_dirents_t *buf);
}

6
src/fuse_readdir_seq.cpp

@ -29,12 +29,12 @@
#endif
int
FUSE::ReadDirSeq::operator()(fuse_file_info_t const *ffi_,
FUSE::ReadDirSeq::operator()(const fuse_req_ctx_t *ctx_,
const fuse_file_info_t *ffi_,
fuse_dirents_t *dirents_)
{
DirInfo *di = DirInfo::from_fh(ffi_->fh);
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
const ugid::Set ugid(ctx_);
return ::_readdir(cfg.branches,
di->fusepath,

3
src/fuse_readdir_seq.hpp

@ -29,7 +29,8 @@ namespace FUSE
ReadDirSeq() {}
~ReadDirSeq() {}
int operator()(fuse_file_info_t const *ffi,
int operator()(const fuse_req_ctx_t *ctx,
const fuse_file_info_t *ffi,
fuse_dirents_t *buf);
};
}

6
src/fuse_readlink.cpp

@ -115,13 +115,13 @@ _readlink(const Policy::Search &searchFunc_,
}
int
FUSE::readlink(const char *fusepath_,
FUSE::readlink(const fuse_req_ctx_t *ctx_,
const char *fusepath_,
char *buf_,
size_t size_)
{
const fs::path fusepath{fusepath_};
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
const ugid::Set ugid(ctx_);
return ::_readlink(cfg.func.readlink.policy,
cfg.branches,

5
src/fuse_readlink.hpp

@ -16,13 +16,16 @@
#pragma once
#include "fuse_req_ctx.h"
#include <unistd.h>
namespace FUSE
{
int
readlink(const char *fusepath,
readlink(const fuse_req_ctx_t *ctx,
const char *fusepath,
char *buf,
size_t size);
}

22
src/fuse_release.cpp

@ -29,8 +29,7 @@
static
constexpr
auto
_erase_if_lambda(const fuse_context *fc_,
FileInfo *fi_,
_erase_if_lambda(FileInfo *fi_,
bool *existed_in_map_)
{
return
@ -49,7 +48,7 @@ _erase_if_lambda(const fuse_context *fc_,
return false;
if(val_.second.backing_id > 0)
FUSE::passthrough_close(fc_,val_.second.backing_id);
FUSE::passthrough_close(val_.second.backing_id);
fs::close(val_.second.fi->fd);
delete val_.second.fi;
@ -59,7 +58,7 @@ _erase_if_lambda(const fuse_context *fc_,
static
int
_release(const fuse_context *fc_,
_release(const fuse_req_ctx_t *ctx_,
FileInfo *fi_,
const bool dropcacheonclose_)
{
@ -77,8 +76,8 @@ _release(const fuse_context *fc_,
// existed. Just how many it erased and in this case I only want to
// erase if there are no more open files.
existed_in_map = false;
state.open_files.erase_if(fc_->nodeid,
::_erase_if_lambda(fc_,fi_,&existed_in_map));
state.open_files.erase_if(ctx_->nodeid,
::_erase_if_lambda(fi_,&existed_in_map));
if(existed_in_map)
return 0;
@ -90,18 +89,17 @@ _release(const fuse_context *fc_,
static
int
_release(const fuse_context *fc_,
_release(const fuse_req_ctx_t *ctx_,
const fuse_file_info_t *ffi_)
{
FileInfo *fi = FileInfo::from_fh(ffi_->fh);
return ::_release(fc_,fi,cfg.dropcacheonclose);
return ::_release(ctx_,fi,cfg.dropcacheonclose);
}
int
FUSE::release(const fuse_file_info_t *ffi_)
FUSE::release(const fuse_req_ctx_t *ctx_,
const fuse_file_info_t *ffi_)
{
const fuse_context *fc = fuse_get_context();
return ::_release(fc,ffi_);
return ::_release(ctx_,ffi_);
}

3
src/fuse_release.hpp

@ -22,5 +22,6 @@
namespace FUSE
{
int
release(const fuse_file_info_t *ffi);
release(const fuse_req_ctx_t *ctx_,
const fuse_file_info_t *ffi);
}

3
src/fuse_releasedir.cpp

@ -32,7 +32,8 @@ _releasedir(DirInfo *di_)
}
int
FUSE::releasedir(const fuse_file_info_t *ffi_)
FUSE::releasedir(const fuse_req_ctx_t *ctx_,
const fuse_file_info_t *ffi_)
{
DirInfo *di = DirInfo::from_fh(ffi_->fh);

3
src/fuse_releasedir.hpp

@ -22,5 +22,6 @@
namespace FUSE
{
int
releasedir(const fuse_file_info_t *ffi);
releasedir(const fuse_req_ctx_t *ctx,
const fuse_file_info_t *ffi);
}

2
src/fuse_removemapping.cpp

@ -22,7 +22,7 @@
int
FUSE::removemapping()
FUSE::removemapping(const fuse_req_ctx_t *ctx)
{
return -ENOSYS;
}

2
src/fuse_removemapping.hpp

@ -23,5 +23,5 @@
namespace FUSE
{
int removemapping();
int removemapping(const fuse_req_ctx_t *ctx);
}

6
src/fuse_removexattr.cpp

@ -89,7 +89,8 @@ _removexattr(const Policy::Action &actionFunc_,
}
int
FUSE::removexattr(const char *fusepath_,
FUSE::removexattr(const fuse_req_ctx_t *ctx_,
const char *fusepath_,
const char *attrname_)
{
const fs::path fusepath{fusepath_};
@ -100,8 +101,7 @@ FUSE::removexattr(const char *fusepath_,
if(cfg.xattr.to_int())
return -cfg.xattr.to_int();
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
const ugid::Set ugid(ctx_);
return ::_removexattr(cfg.func.removexattr.policy,
cfg.func.getxattr.policy,

5
src/fuse_removexattr.hpp

@ -16,10 +16,13 @@
#pragma once
#include "fuse_req_ctx.h"
namespace FUSE
{
int
removexattr(const char *fusepath,
removexattr(const fuse_req_ctx_t *ctx,
const char *fusepath,
const char *attrname);
}

51
src/fuse_rename.cpp

@ -244,7 +244,8 @@ _rename_exdev_rename_target(const Policy::Action &actionPolicy_,
static
int
_rename_exdev_rel_symlink(const Policy::Action &actionPolicy_,
_rename_exdev_rel_symlink(const fuse_req_ctx_t *ctx_,
const Policy::Action &actionPolicy_,
const Branches::Ptr &branches_,
const fs::path &oldfusepath_,
const fs::path &newfusepath_)
@ -263,7 +264,7 @@ _rename_exdev_rel_symlink(const Policy::Action &actionPolicy_,
target /= oldfusepath_;
target = target.lexically_relative(linkpath.parent_path());
rv = FUSE::symlink(target.c_str(),linkpath);
rv = FUSE::symlink(ctx_,target.c_str(),linkpath);
if(rv < 0)
::_rename_exdev_rename_back(branches,oldfusepath_);
@ -272,7 +273,8 @@ _rename_exdev_rel_symlink(const Policy::Action &actionPolicy_,
static
int
_rename_exdev_abs_symlink(const Policy::Action &actionPolicy_,
_rename_exdev_abs_symlink(const fuse_req_ctx_t *ctx_,
const Policy::Action &actionPolicy_,
const Branches::Ptr &branches_,
const fs::path &mount_,
const fs::path &oldfusepath_,
@ -292,7 +294,7 @@ _rename_exdev_abs_symlink(const Policy::Action &actionPolicy_,
target /= ".mergerfs_rename_exdev";
target /= oldfusepath_;
rv = FUSE::symlink(target.c_str(),linkpath);
rv = FUSE::symlink(ctx_,target.c_str(),linkpath);
if(rv < 0)
::_rename_exdev_rename_back(branches,oldfusepath_);
@ -301,23 +303,25 @@ _rename_exdev_abs_symlink(const Policy::Action &actionPolicy_,
static
int
_rename_exdev(Config &cfg_,
_rename_exdev(const fuse_req_ctx_t *ctx_,
const fs::path &oldfusepath_,
const fs::path &newfusepath_)
{
switch(cfg_.rename_exdev)
switch(cfg.rename_exdev)
{
case RenameEXDEV::ENUM::PASSTHROUGH:
return -EXDEV;
case RenameEXDEV::ENUM::REL_SYMLINK:
return ::_rename_exdev_rel_symlink(cfg_.func.rename.policy,
cfg_.branches,
return ::_rename_exdev_rel_symlink(ctx_,
cfg.func.rename.policy,
cfg.branches,
oldfusepath_,
newfusepath_);
case RenameEXDEV::ENUM::ABS_SYMLINK:
return ::_rename_exdev_abs_symlink(cfg_.func.rename.policy,
cfg_.branches,
cfg_.mountpoint,
return ::_rename_exdev_abs_symlink(ctx_,
cfg.func.rename.policy,
cfg.branches,
cfg.mountpoint,
oldfusepath_,
newfusepath_);
}
@ -327,36 +331,35 @@ _rename_exdev(Config &cfg_,
static
int
_rename(Config &cfg_,
const fs::path &oldpath_,
_rename(const fs::path &oldpath_,
const fs::path &newpath_)
{
if(cfg_.func.create.policy.path_preserving() && !cfg_.ignorepponrename)
return ::_rename_preserve_path(cfg_.func.rename.policy,
cfg_.branches,
if(cfg.func.create.policy.path_preserving() && !cfg.ignorepponrename)
return ::_rename_preserve_path(cfg.func.rename.policy,
cfg.branches,
oldpath_,
newpath_);
return ::_rename_create_path(cfg_.func.getattr.policy,
cfg_.func.rename.policy,
cfg_.branches,
return ::_rename_create_path(cfg.func.getattr.policy,
cfg.func.rename.policy,
cfg.branches,
oldpath_,
newpath_);
}
int
FUSE::rename(const char *oldfusepath_,
FUSE::rename(const fuse_req_ctx_t *ctx_,
const char *oldfusepath_,
const char *newfusepath_)
{
int rv;
const fs::path oldfusepath{oldfusepath_};
const fs::path newfusepath{newfusepath_};
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
const ugid::Set ugid(ctx_);
rv = ::_rename(cfg,oldfusepath,newfusepath);
rv = ::_rename(oldfusepath,newfusepath);
if(rv == -EXDEV)
return ::_rename_exdev(cfg,oldfusepath,newfusepath);
return ::_rename_exdev(ctx_,oldfusepath,newfusepath);
return rv;
}

5
src/fuse_rename.hpp

@ -16,10 +16,13 @@
#pragma once
#include "fuse_req_ctx.h"
namespace FUSE
{
int
rename(const char *from,
rename(const fuse_req_ctx_t *ctx,
const char *from,
const char *to);
}

6
src/fuse_rmdir.cpp

@ -92,11 +92,11 @@ _rmdir(const Policy::Action &actionFunc_,
}
int
FUSE::rmdir(const char *fusepath_)
FUSE::rmdir(const fuse_req_ctx_t *ctx_,
const char *fusepath_)
{
const fs::path fusepath{fusepath_};
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
const ugid::Set ugid(ctx_);
return ::_rmdir(cfg.func.rmdir.policy,
cfg.branches,

5
src/fuse_rmdir.hpp

@ -16,9 +16,12 @@
#pragma once
#include "fuse_req_ctx.h"
namespace FUSE
{
int
rmdir(const char *fusepath);
rmdir(const fuse_req_ctx_t *ctx,
const char *fusepath);
}

3
src/fuse_setupmapping.cpp

@ -25,7 +25,8 @@
ssize_t
FUSE::setupmapping(uint64_t *fh_,
FUSE::setupmapping(const fuse_req_ctx_t *ctx_,
uint64_t *fh_,
uint64_t foffset_,
uint64_t len_,
uint64_t flags_,

3
src/fuse_setupmapping.hpp

@ -23,7 +23,8 @@
namespace FUSE
{
ssize_t setupmapping(uint64_t *fh_,
ssize_t setupmapping(const fuse_req_ctx_t *ctx,
uint64_t *fh_,
uint64_t foffset_,
uint64_t len_,
uint64_t flags_,

16
src/fuse_setxattr.cpp

@ -180,7 +180,8 @@ _setxattr(const Policy::Action &setxattrPolicy_,
static
int
_setxattr(const fs::path &fusepath_,
_setxattr(const fuse_req_ctx_t *ctx_,
const fs::path &fusepath_,
const char *attrname_,
const char *attrval_,
size_t attrvalsize_,
@ -193,8 +194,7 @@ _setxattr(const fs::path &fusepath_,
if(cfg.xattr.to_int())
return -cfg.xattr.to_int();
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
const ugid::Set ugid(ctx_);
return ::_setxattr(cfg.func.setxattr.policy,
cfg.func.getxattr.policy,
@ -208,7 +208,8 @@ _setxattr(const fs::path &fusepath_,
int
FUSE::setxattr(const char *fusepath_,
FUSE::setxattr(const fuse_req_ctx_t *ctx_,
const char *fusepath_,
const char *attrname_,
const char *attrval_,
size_t attrvalsize_,
@ -222,5 +223,10 @@ FUSE::setxattr(const char *fusepath_,
attrvalsize_,
flags_);
return ::_setxattr(fusepath,attrname_,attrval_,attrvalsize_,flags_);
return ::_setxattr(ctx_,
fusepath,
attrname_,
attrval_,
attrvalsize_,
flags_);
}

5
src/fuse_setxattr.hpp

@ -18,11 +18,14 @@
#include <cstddef>
#include "fuse_req_ctx.h"
namespace FUSE
{
int
setxattr(const char *fusepath,
setxattr(const fuse_req_ctx_t *ctx,
const char *fusepath,
const char *attrname,
const char *attrval,
size_t attrvalize,

6
src/fuse_statfs.cpp

@ -142,12 +142,12 @@ _statfs(const Branches::Ptr &branches_,
}
int
FUSE::statfs(const char *fusepath_,
FUSE::statfs(const fuse_req_ctx_t *ctx_,
const char *fusepath_,
struct statvfs *st_)
{
const fs::path fusepath{fusepath_};
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
const ugid::Set ugid(ctx_);
return ::_statfs(cfg.branches,
fusepath,

5
src/fuse_statfs.hpp

@ -16,12 +16,15 @@
#pragma once
#include "fuse_req_ctx.h"
#include <sys/statvfs.h>
namespace FUSE
{
int
statfs(const char *fusepath,
statfs(const fuse_req_ctx_t *ctx,
const char *fusepath,
struct statvfs *fsstat);
}

6
src/fuse_statx.hpp

@ -25,12 +25,14 @@
namespace FUSE
{
int statx(const char *fusepath,
int statx(const fuse_req_ctx_t *ctx,
const char *fusepath,
const uint32_t flags,
const uint32_t mask,
struct fuse_statx *st,
fuse_timeouts_t *timeout);
int statx_fh(const uint64_t fh,
int statx_fh(const fuse_req_ctx_t *ctx,
const uint64_t fh,
const uint32_t flags,
const uint32_t mask,
struct fuse_statx *st,

15
src/fuse_statx_supported.icpp

@ -179,8 +179,6 @@ _statx(const fs::path &fusepath_,
fuse_timeouts_t *timeout_)
{
int rv;
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
rv = ::_statx(cfg.func.getattr.policy,
cfg.branches,
@ -203,7 +201,8 @@ _statx(const fs::path &fusepath_,
}
int
FUSE::statx(const char *fusepath_,
FUSE::statx(const fuse_req_ctx_t *ctx_,
const char *fusepath_,
const uint32_t flags_,
const uint32_t mask_,
struct fuse_statx *st_,
@ -214,6 +213,8 @@ FUSE::statx(const char *fusepath_,
if(Config::is_ctrl_file(fusepath))
return ::_statx_controlfile(st_);
const ugid::Set ugid(ctx_);
return ::_statx(fusepath,
flags_|AT_STATX_DONT_SYNC,
mask_,
@ -222,19 +223,19 @@ FUSE::statx(const char *fusepath_,
}
int
FUSE::statx_fh(const uint64_t fh_,
FUSE::statx_fh(const fuse_req_ctx_t *ctx_,
const uint64_t fh_,
const uint32_t flags_,
const uint32_t mask_,
struct fuse_statx *st_,
fuse_timeouts_t *timeout_)
{
uint64_t fh;
const fuse_context *fc = fuse_get_context();
fh = fh_;
if(fh == 0)
{
state.open_files.cvisit(fc->nodeid,
state.open_files.cvisit(ctx_->nodeid,
[&](auto &val_)
{
fh = val_.second.fi->to_fh();
@ -246,6 +247,8 @@ FUSE::statx_fh(const uint64_t fh_,
FileInfo *fi = FileInfo::from_fh(fh);
const ugid::Set ugid(ctx_);
return ::_statx(fi->fusepath,
flags_|AT_STATX_DONT_SYNC,
mask_,

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save