mirror of
https://github.com/trapexit/mergerfs.git
synced 2025-02-20 17:52:45 +08:00
Send invalidate node request outside lock
This commit is contained in:
commit
0197984db3
@ -71,6 +71,8 @@ CFLAGS := \
|
||||
-Wall \
|
||||
-pipe \
|
||||
-MMD
|
||||
CXXFLAGS ?= \
|
||||
$(OPT_FLAGS)
|
||||
CXXFLAGS := \
|
||||
${CXXFLAGS} \
|
||||
$(LTO_FLAGS) \
|
||||
|
@ -442,7 +442,7 @@ struct fuse_file_lock {
|
||||
#define FUSE_HANDLE_KILLPRIV_V2 (1 << 28)
|
||||
#define FUSE_SETXATTR_EXT (1 << 29)
|
||||
#define FUSE_INIT_EXT (1 << 30)
|
||||
#define FUSE_INIT_RESERVED (1 << 31)
|
||||
#define FUSE_INIT_RESERVED (1ULL << 31)
|
||||
/* bits 32..63 get shifted down 32 bits into the flags2 field */
|
||||
#define FUSE_SECURITY_CTX (1ULL << 32)
|
||||
#define FUSE_HAS_INODE_DAX (1ULL << 33)
|
||||
|
@ -131,891 +131,55 @@ struct fuse_ctx
|
||||
*/
|
||||
struct fuse_lowlevel_ops
|
||||
{
|
||||
/**
|
||||
* Initialize filesystem
|
||||
*
|
||||
* Called before any other filesystem method
|
||||
*
|
||||
* There's no reply to this function
|
||||
*
|
||||
* @param userdata the user data passed to fuse_lowlevel_new()
|
||||
*/
|
||||
void (*init)(void *userdata, struct fuse_conn_info *conn);
|
||||
|
||||
/**
|
||||
* Clean up filesystem
|
||||
*
|
||||
* Called on filesystem exit
|
||||
*
|
||||
* There's no reply to this function
|
||||
*
|
||||
* @param userdata the user data passed to fuse_lowlevel_new()
|
||||
*/
|
||||
void (*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);
|
||||
|
||||
/**
|
||||
* Look up a directory entry by name and get its attributes.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_entry
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param parent inode number of the parent directory
|
||||
* @param name the name to look up
|
||||
*/
|
||||
void (*lookup)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Forget about an inode
|
||||
*
|
||||
* This function is called when the kernel removes an inode
|
||||
* from its internal caches.
|
||||
*
|
||||
* The inode's lookup count increases by one for every call to
|
||||
* fuse_reply_entry and fuse_reply_create. The nlookup parameter
|
||||
* indicates by how much the lookup count should be decreased.
|
||||
*
|
||||
* Inodes with a non-zero lookup count may receive request from
|
||||
* the kernel even after calls to unlink, rmdir or (when
|
||||
* overwriting an existing file) rename. Filesystems must handle
|
||||
* such requests properly and it is recommended to defer removal
|
||||
* of the inode until the lookup count reaches zero. Calls to
|
||||
* unlink, remdir or rename will be followed closely by forget
|
||||
* unless the file or directory is open, in which case the
|
||||
* kernel issues forget only after the release or releasedir
|
||||
* calls.
|
||||
*
|
||||
* Note that if a file system will be exported over NFS the
|
||||
* inodes lifetime must extend even beyond forget. See the
|
||||
* generation field in struct fuse_entry_param above.
|
||||
*
|
||||
* On unmount the lookup count for all inodes implicitly drops
|
||||
* to zero. It is not guaranteed that the file system will
|
||||
* receive corresponding forget messages for the affected
|
||||
* inodes.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_none
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param nlookup the number of lookups to forget
|
||||
*/
|
||||
void (*forget)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Get file attributes
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_attr
|
||||
* fuse_reply_err
|
||||
*/
|
||||
void (*getattr)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Set file attributes
|
||||
*
|
||||
* In the 'attr' argument only members indicated by the 'to_set'
|
||||
* bitmask contain valid values. Other members contain undefined
|
||||
* values.
|
||||
*
|
||||
* If the setattr was invoked from the ftruncate() system call
|
||||
* under Linux kernel versions 2.6.15 or later, the fi->fh will
|
||||
* contain the value set by the open method or will be undefined
|
||||
* if the open method didn't set any value. Otherwise (not
|
||||
* ftruncate call, or kernel version earlier than 2.6.15) the fi
|
||||
* parameter will be NULL.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_attr
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param attr the attributes
|
||||
* @param to_set bit mask of attributes which should be set
|
||||
* @param fi file information, or NULL
|
||||
*
|
||||
* Changed in version 2.5:
|
||||
* file information filled in for ftruncate
|
||||
*/
|
||||
void (*setattr)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Read symbolic link
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_readlink
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
*/
|
||||
void (*readlink)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Create file node
|
||||
*
|
||||
* Create a regular file, character device, block device, fifo or
|
||||
* socket node.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_entry
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param parent inode number of the parent directory
|
||||
* @param name to create
|
||||
* @param mode file type and mode with which to create the new file
|
||||
* @param rdev the device number (only valid if created file is a device)
|
||||
*/
|
||||
void (*mknod)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Create a directory
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_entry
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param parent inode number of the parent directory
|
||||
* @param name to create
|
||||
* @param mode with which to create the new file
|
||||
*/
|
||||
void (*mkdir)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Remove a file
|
||||
*
|
||||
* If the file's inode's lookup count is non-zero, the file
|
||||
* system is expected to postpone any removal of the inode
|
||||
* until the lookup count reaches zero (see description of the
|
||||
* forget function).
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param parent inode number of the parent directory
|
||||
* @param name to remove
|
||||
*/
|
||||
void (*unlink)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Remove a directory
|
||||
*
|
||||
* If the directory's inode's lookup count is non-zero, the
|
||||
* file system is expected to postpone any removal of the
|
||||
* inode until the lookup count reaches zero (see description
|
||||
* of the forget function).
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param parent inode number of the parent directory
|
||||
* @param name to remove
|
||||
*/
|
||||
void (*rmdir)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Create a symbolic link
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_entry
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param link the contents of the symbolic link
|
||||
* @param parent inode number of the parent directory
|
||||
* @param name to create
|
||||
*/
|
||||
void (*symlink)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/** Rename a file
|
||||
*
|
||||
* If the target exists it should be atomically replaced. If
|
||||
* the target's inode's lookup count is non-zero, the file
|
||||
* system is expected to postpone any removal of the inode
|
||||
* until the lookup count reaches zero (see description of the
|
||||
* forget function).
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param parent inode number of the old parent directory
|
||||
* @param name old name
|
||||
* @param newparent inode number of the new parent directory
|
||||
* @param newname new name
|
||||
*/
|
||||
void (*rename)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Create a hard link
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_entry
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the old inode number
|
||||
* @param newparent inode number of the new parent directory
|
||||
* @param newname new name to create
|
||||
*/
|
||||
void (*link)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Open a file
|
||||
*
|
||||
* Open flags (with the exception of O_CREAT, O_EXCL, O_NOCTTY and
|
||||
* O_TRUNC) are available in fi->flags.
|
||||
*
|
||||
* Filesystem may store an arbitrary file handle (pointer, index,
|
||||
* etc) in fi->fh, and use this in other all other file operations
|
||||
* (read, write, flush, release, fsync).
|
||||
*
|
||||
* Filesystem may also implement stateless file I/O and not store
|
||||
* anything in fi->fh.
|
||||
*
|
||||
* There are also some flags (direct_io, keep_cache) which the
|
||||
* filesystem may set in fi, to change the way the file is opened.
|
||||
* See fuse_file_info structure in <fuse_common.h> for more details.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_open
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param fi file information
|
||||
*/
|
||||
void (*open)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Read data
|
||||
*
|
||||
* Read should send exactly the number of bytes requested except
|
||||
* on EOF or error, otherwise the rest of the data will be
|
||||
* substituted with zeroes. An exception to this is when the file
|
||||
* has been opened in 'direct_io' mode, in which case the return
|
||||
* value of the read system call will reflect the return value of
|
||||
* this operation.
|
||||
*
|
||||
* fi->fh will contain the value set by the open method, or will
|
||||
* be undefined if the open method didn't set any value.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_buf
|
||||
* fuse_reply_iov
|
||||
* fuse_reply_data
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param size number of bytes to read
|
||||
* @param off offset to read from
|
||||
* @param fi file information
|
||||
*/
|
||||
void (*read)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Write data
|
||||
*
|
||||
* Write should return exactly the number of bytes requested
|
||||
* except on error. An exception to this is when the file has
|
||||
* been opened in 'direct_io' mode, in which case the return value
|
||||
* of the write system call will reflect the return value of this
|
||||
* operation.
|
||||
*
|
||||
* fi->fh will contain the value set by the open method, or will
|
||||
* be undefined if the open method didn't set any value.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_write
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param buf data to write
|
||||
* @param size number of bytes to write
|
||||
* @param off offset to write to
|
||||
* @param fi file information
|
||||
*/
|
||||
void (*write)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Flush method
|
||||
*
|
||||
* This is called on each close() of the opened file.
|
||||
*
|
||||
* Since file descriptors can be duplicated (dup, dup2, fork), for
|
||||
* one open call there may be many flush calls.
|
||||
*
|
||||
* Filesystems shouldn't assume that flush will always be called
|
||||
* after some writes, or that if will be called at all.
|
||||
*
|
||||
* fi->fh will contain the value set by the open method, or will
|
||||
* be undefined if the open method didn't set any value.
|
||||
*
|
||||
* NOTE: the name of the method is misleading, since (unlike
|
||||
* fsync) the filesystem is not forced to flush pending writes.
|
||||
* One reason to flush data, is if the filesystem wants to return
|
||||
* write errors.
|
||||
*
|
||||
* If the filesystem supports file locking operations (setlk,
|
||||
* getlk) it should remove all locks belonging to 'fi->owner'.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param fi file information
|
||||
*/
|
||||
void (*flush)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Release an open file
|
||||
*
|
||||
* Release is called when there are no more references to an open
|
||||
* file: all file descriptors are closed and all memory mappings
|
||||
* are unmapped.
|
||||
*
|
||||
* For every open call there will be exactly one release call.
|
||||
*
|
||||
* The filesystem may reply with an error, but error values are
|
||||
* not returned to close() or munmap() which triggered the
|
||||
* release.
|
||||
*
|
||||
* fi->fh will contain the value set by the open method, or will
|
||||
* be undefined if the open method didn't set any value.
|
||||
* fi->flags will contain the same flags as for open.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param fi file information
|
||||
*/
|
||||
void (*release)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Synchronize file contents
|
||||
*
|
||||
* If the datasync parameter is non-zero, then only the user data
|
||||
* should be flushed, not the meta data.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param datasync flag indicating if only data should be flushed
|
||||
* @param fi file information
|
||||
*/
|
||||
void (*fsync)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Open a directory
|
||||
*
|
||||
* Filesystem may store an arbitrary file handle (pointer, index,
|
||||
* etc) in fi->fh, and use this in other all other directory
|
||||
* stream operations (readdir, releasedir, fsyncdir).
|
||||
*
|
||||
* Filesystem may also implement stateless directory I/O and not
|
||||
* store anything in fi->fh, though that makes it impossible to
|
||||
* implement standard conforming directory stream operations in
|
||||
* case the contents of the directory can change between opendir
|
||||
* and releasedir.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_open
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param fi file information
|
||||
*/
|
||||
void (*opendir)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Read directory
|
||||
*
|
||||
* Send a buffer filled using fuse_add_direntry(), with size not
|
||||
* exceeding the requested size. Send an empty buffer on end of
|
||||
* stream.
|
||||
*
|
||||
* fi->fh will contain the value set by the opendir method, or
|
||||
* will be undefined if the opendir method didn't set any value.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_buf
|
||||
* fuse_reply_data
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param size maximum number of bytes to send
|
||||
* @param off offset to continue reading the directory stream
|
||||
* @param fi file information
|
||||
*/
|
||||
void (*readdir)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
void (*readdir_plus)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Release an open directory
|
||||
*
|
||||
* For every opendir call there will be exactly one releasedir
|
||||
* call.
|
||||
*
|
||||
* fi->fh will contain the value set by the opendir method, or
|
||||
* will be undefined if the opendir method didn't set any value.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param fi file information
|
||||
*/
|
||||
void (*releasedir)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Synchronize directory contents
|
||||
*
|
||||
* If the datasync parameter is non-zero, then only the directory
|
||||
* contents should be flushed, not the meta data.
|
||||
*
|
||||
* fi->fh will contain the value set by the opendir method, or
|
||||
* will be undefined if the opendir method didn't set any value.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param datasync flag indicating if only data should be flushed
|
||||
* @param fi file information
|
||||
*/
|
||||
void (*fsyncdir)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Get file system statistics
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_statfs
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number, zero means "undefined"
|
||||
*/
|
||||
void (*statfs)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Set an extended attribute
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_err
|
||||
*/
|
||||
void (*setxattr)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Get an extended attribute
|
||||
*
|
||||
* If size is zero, the size of the value should be sent with
|
||||
* fuse_reply_xattr.
|
||||
*
|
||||
* If the size is non-zero, and the value fits in the buffer, the
|
||||
* value should be sent with fuse_reply_buf.
|
||||
*
|
||||
* If the size is too small for the value, the ERANGE error should
|
||||
* be sent.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_buf
|
||||
* fuse_reply_data
|
||||
* fuse_reply_xattr
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param name of the extended attribute
|
||||
* @param size maximum size of the value to send
|
||||
*/
|
||||
void (*getxattr)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* List extended attribute names
|
||||
*
|
||||
* If size is zero, the total size of the attribute list should be
|
||||
* sent with fuse_reply_xattr.
|
||||
*
|
||||
* If the size is non-zero, and the null character separated
|
||||
* attribute list fits in the buffer, the list should be sent with
|
||||
* fuse_reply_buf.
|
||||
*
|
||||
* If the size is too small for the list, the ERANGE error should
|
||||
* be sent.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_buf
|
||||
* fuse_reply_data
|
||||
* fuse_reply_xattr
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param size maximum size of the list to send
|
||||
*/
|
||||
void (*listxattr)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Remove an extended attribute
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param name of the extended attribute
|
||||
*/
|
||||
void (*removexattr)(fuse_req_t req,
|
||||
const struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Check file access permissions
|
||||
*
|
||||
* This will be called for the access() system call. If the
|
||||
* 'default_permissions' mount option is given, this method is not
|
||||
* called.
|
||||
*
|
||||
* This method is not called under Linux kernel versions 2.4.x
|
||||
*
|
||||
* Introduced in version 2.5
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param mask requested access mode
|
||||
*/
|
||||
void (*access)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Create and open a file
|
||||
*
|
||||
* If the file does not exist, first create it with the specified
|
||||
* mode, and then open it.
|
||||
*
|
||||
* Open flags (with the exception of O_NOCTTY) are available in
|
||||
* fi->flags.
|
||||
*
|
||||
* Filesystem may store an arbitrary file handle (pointer, index,
|
||||
* etc) in fi->fh, and use this in other all other file operations
|
||||
* (read, write, flush, release, fsync).
|
||||
*
|
||||
* There are also some flags (direct_io, keep_cache) which the
|
||||
* filesystem may set in fi, to change the way the file is opened.
|
||||
* See fuse_file_info structure in <fuse_common.h> for more details.
|
||||
*
|
||||
* If this method is not implemented or under Linux kernel
|
||||
* versions earlier than 2.6.15, the mknod() and open() methods
|
||||
* will be called instead.
|
||||
*
|
||||
* Introduced in version 2.5
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_create
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param parent inode number of the parent directory
|
||||
* @param name to create
|
||||
* @param mode file type and mode with which to create the new file
|
||||
* @param fi file information
|
||||
*/
|
||||
void (*create)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Test for a POSIX file lock
|
||||
*
|
||||
* Introduced in version 2.6
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_lock
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param fi file information
|
||||
* @param lock the region/type to test
|
||||
*/
|
||||
void (*getlk)(fuse_req_t req,
|
||||
const struct fuse_in_header *hdr);
|
||||
/**
|
||||
* Acquire, modify or release a POSIX file lock
|
||||
*
|
||||
* For POSIX threads (NPTL) there's a 1-1 relation between pid and
|
||||
* owner, but otherwise this is not always the case. For checking
|
||||
* lock ownership, 'fi->owner' must be used. The l_pid field in
|
||||
* 'struct flock' should only be used to fill in this field in
|
||||
* getlk().
|
||||
*
|
||||
* Note: if the locking methods are not implemented, the kernel
|
||||
* will still allow file locking to work locally. Hence these are
|
||||
* only interesting for network filesystems and similar.
|
||||
*
|
||||
* Introduced in version 2.6
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param fi file information
|
||||
* @param lock the region/type to set
|
||||
* @param sleep locking operation may sleep
|
||||
*/
|
||||
void (*setlk)(fuse_req_t req, uint64_t ino,
|
||||
fuse_file_info_t *fi,
|
||||
struct flock *lock, int sleep);
|
||||
|
||||
/**
|
||||
* Map block index within file to block index within device
|
||||
*
|
||||
* Note: This makes sense only for block device backed filesystems
|
||||
* mounted with the 'blkdev' option
|
||||
*
|
||||
* Introduced in version 2.6
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_bmap
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param blocksize unit of block index
|
||||
* @param idx block index within file
|
||||
*/
|
||||
void (*bmap)(fuse_req_t req,
|
||||
const struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Ioctl
|
||||
*
|
||||
* Note: For unrestricted ioctls (not allowed for FUSE
|
||||
* servers), data in and out areas can be discovered by giving
|
||||
* iovs and setting FUSE_IOCTL_RETRY in @flags. For
|
||||
* restricted ioctls, kernel prepares in/out data area
|
||||
* according to the information encoded in cmd.
|
||||
*
|
||||
* Introduced in version 2.8
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_ioctl_retry
|
||||
* fuse_reply_ioctl
|
||||
* fuse_reply_ioctl_iov
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param cmd ioctl command
|
||||
* @param arg ioctl argument
|
||||
* @param fi file information
|
||||
* @param flags for FUSE_IOCTL_* flags
|
||||
* @param in_buf data fetched from the caller
|
||||
* @param in_bufsz number of fetched bytes
|
||||
* @param out_bufsz maximum size of output data
|
||||
*/
|
||||
void (*ioctl)(fuse_req_t req,
|
||||
const struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Poll for IO readiness
|
||||
*
|
||||
* Introduced in version 2.8
|
||||
*
|
||||
* Note: If ph is non-NULL, the client should notify
|
||||
* when IO readiness events occur by calling
|
||||
* fuse_lowelevel_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.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_poll
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param fi file information
|
||||
* @param ph poll handle to be used for notification
|
||||
*/
|
||||
void (*poll)(fuse_req_t req,
|
||||
const struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Callback function for the retrieve request
|
||||
*
|
||||
* Introduced in version 2.9
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_none
|
||||
*
|
||||
* @param req request handle
|
||||
* @param cookie user data supplied to fuse_lowlevel_notify_retrieve()
|
||||
* @param ino the inode number supplied to fuse_lowlevel_notify_retrieve()
|
||||
* @param offset the offset supplied to fuse_lowlevel_notify_retrieve()
|
||||
* @param bufv the buffer containing the returned data
|
||||
*/
|
||||
void (*retrieve_reply)(fuse_req_t req,
|
||||
void *cookie,
|
||||
uint64_t ino,
|
||||
off_t offset);
|
||||
|
||||
/**
|
||||
* Forget about multiple inodes
|
||||
*
|
||||
* See description of the forget function for more
|
||||
* information.
|
||||
*
|
||||
* Introduced in version 2.9
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_none
|
||||
*
|
||||
* @param req request handle
|
||||
*/
|
||||
void (*forget_multi)(fuse_req_t req,
|
||||
struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* Acquire, modify or release a BSD file lock
|
||||
*
|
||||
* Note: if the locking methods are not implemented, the kernel
|
||||
* will still allow file locking to work locally. Hence these are
|
||||
* only interesting for network filesystems and similar.
|
||||
*
|
||||
* Introduced in version 2.9
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param fi file information
|
||||
* @param op the locking operation, see flock(2)
|
||||
*/
|
||||
void (*flock)(fuse_req_t req, uint64_t ino,
|
||||
fuse_file_info_t *fi, int op);
|
||||
|
||||
/**
|
||||
* Allocate requested space. If this function returns success then
|
||||
* subsequent writes to the specified range shall not fail due to the lack
|
||||
* of free space on the file system storage media.
|
||||
*
|
||||
* Introduced in version 2.9
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param offset starting point for allocated region
|
||||
* @param length size of allocated region
|
||||
* @param mode determines the operation to be performed on the given range,
|
||||
* see fallocate(2)
|
||||
*/
|
||||
void (*fallocate)(fuse_req_t req,
|
||||
const struct fuse_in_header *hdr);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* If this request is answered with an error code of ENOSYS, this is
|
||||
* treated as a permanent failure with error code EOPNOTSUPP,
|
||||
* i.e. all
|
||||
* future copy_file_range() requests will fail with EOPNOTSUPP
|
||||
* without
|
||||
* being send to the filesystem process.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_write
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino_in the inode number of the source file
|
||||
* @param off_in starting point from were the data should be read
|
||||
* @param fi_in file information of the source file
|
||||
* @param ino_out the inode number of the destination file
|
||||
* @param off_out starting point where the data should be written
|
||||
* @param fi_out file information of the destination file
|
||||
* @param len maximum size of the data to copy
|
||||
* @param flags passed along with the copy_file_range() syscall
|
||||
*/
|
||||
void (*copy_file_range)(fuse_req_t req,
|
||||
const struct fuse_in_header *hdr);
|
||||
|
||||
void (*setupmapping)(fuse_req_t req,
|
||||
const struct fuse_in_header *hdr);
|
||||
void (*removemapping)(fuse_req_t req,
|
||||
const 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 (*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);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -19,6 +19,11 @@
|
||||
#ifndef CRC32B_H_INCLUDED
|
||||
#define CRC32B_H_INCLUDED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef unsigned int crc32b_t;
|
||||
|
||||
crc32b_t crc32b_start(void);
|
||||
@ -29,4 +34,8 @@ crc32b_t crc32b_finish(const crc32b_t crc);
|
||||
|
||||
crc32b_t crc32b(const void *buf, crc32b_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -16,7 +16,9 @@
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include "fuse_kernel.h"
|
||||
|
||||
@ -211,7 +213,7 @@ void
|
||||
debug_open_flags(const uint32_t flags_)
|
||||
{
|
||||
fprintf(stderr,"%s, ",open_accmode_to_str(flags_));
|
||||
for(int i = 0; i < (sizeof(flags_) * 8); i++)
|
||||
for(size_t i = 0; i < (sizeof(flags_) * 8); i++)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
@ -252,11 +254,11 @@ debug_fuse_open_out(const struct fuse_open_out *arg_)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"fuse_open_out:"
|
||||
" fh=0x%"PRIx64";"
|
||||
" fh=0x%" PRIx64 ";"
|
||||
" open_flags=0x%X (",
|
||||
arg_->fh,
|
||||
arg_->open_flags);
|
||||
for(int i = 0; i < (sizeof(arg_->open_flags) * 8); i++)
|
||||
for(size_t i = 0; i < (sizeof(arg_->open_flags) * 8); i++)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
@ -276,7 +278,7 @@ static
|
||||
void
|
||||
debug_fuse_lookup(const void *arg_)
|
||||
{
|
||||
const char *name = arg_;
|
||||
const char *name = (const char*)arg_;
|
||||
|
||||
fprintf(g_OUTPUT,
|
||||
"fuse_lookup:"
|
||||
@ -290,12 +292,12 @@ static
|
||||
void
|
||||
debug_fuse_getattr_in(const void *arg_)
|
||||
{
|
||||
const struct fuse_getattr_in *arg = arg_;
|
||||
const struct fuse_getattr_in *arg = (const fuse_getattr_in*)arg_;
|
||||
|
||||
fprintf(g_OUTPUT,
|
||||
"fuse_getattr_in:"
|
||||
" getattr_flags=0x%08X;"
|
||||
" fh=0x%"PRIx64";\n",
|
||||
" fh=0x%" PRIx64 ";\n",
|
||||
arg->getattr_flags,
|
||||
arg->fh);
|
||||
}
|
||||
@ -304,12 +306,12 @@ static
|
||||
void
|
||||
debug_fuse_setattr_in(const void *arg_)
|
||||
{
|
||||
const struct fuse_setattr_in *arg = arg_;
|
||||
const struct fuse_setattr_in *arg = (const fuse_setattr_in*)arg_;
|
||||
|
||||
fprintf(g_OUTPUT,
|
||||
"fuse_setattr_in:"
|
||||
" valid=%u;"
|
||||
" fh=0x%"PRIx64";"
|
||||
" fh=0x%" PRIx64 ";"
|
||||
" size=%zu;"
|
||||
" lock_owner=%zu;"
|
||||
" atime=%zu;"
|
||||
@ -342,7 +344,7 @@ static
|
||||
void
|
||||
debug_fuse_access_in(const void *arg_)
|
||||
{
|
||||
const struct fuse_access_in *arg = arg_;
|
||||
const struct fuse_access_in *arg = (const fuse_access_in*)arg_;
|
||||
|
||||
fprintf(g_OUTPUT,
|
||||
"fuse_access_in:"
|
||||
@ -356,7 +358,7 @@ static
|
||||
void
|
||||
debug_fuse_mknod_in(const void *arg_)
|
||||
{
|
||||
const struct fuse_mknod_in *arg = arg_;
|
||||
const struct fuse_mknod_in *arg = (const fuse_mknod_in*)arg_;
|
||||
|
||||
fprintf(g_OUTPUT,
|
||||
"fuse_mknod_in:"
|
||||
@ -374,7 +376,7 @@ static
|
||||
void
|
||||
debug_fuse_mkdir_in(const void *arg_)
|
||||
{
|
||||
const struct fuse_mkdir_in *arg = arg_;
|
||||
const struct fuse_mkdir_in *arg = (const fuse_mkdir_in*)arg_;
|
||||
|
||||
fprintf(g_OUTPUT,
|
||||
"fuse_mkdir_in:"
|
||||
@ -392,7 +394,7 @@ static
|
||||
void
|
||||
debug_fuse_unlink(const void *arg_)
|
||||
{
|
||||
const char *name = arg_;
|
||||
const char *name = (const char*)arg_;
|
||||
|
||||
fprintf(g_OUTPUT,
|
||||
"fuse_unlink:"
|
||||
@ -406,7 +408,7 @@ static
|
||||
void
|
||||
debug_fuse_rmdir(const void *arg_)
|
||||
{
|
||||
const char *name = arg_;
|
||||
const char *name = (const char*)arg_;
|
||||
|
||||
fprintf(g_OUTPUT,
|
||||
"fuse_mkdir:"
|
||||
@ -423,7 +425,7 @@ debug_fuse_symlink(const void *arg_)
|
||||
const char *name;
|
||||
const char *linkname;
|
||||
|
||||
name = arg_;
|
||||
name = (const char*)arg_;
|
||||
linkname = (name + (strlen(name) + 1));
|
||||
|
||||
fprintf(g_OUTPUT,
|
||||
@ -442,7 +444,7 @@ debug_fuse_rename_in(const void *arg_)
|
||||
{
|
||||
const char *oldname;
|
||||
const char *newname;
|
||||
const struct fuse_rename_in *arg = arg_;
|
||||
const struct fuse_rename_in *arg = (const fuse_rename_in*)arg_;
|
||||
|
||||
oldname = PARAM(arg);
|
||||
newname = (oldname + strlen(oldname) + 1);
|
||||
@ -464,7 +466,7 @@ void
|
||||
debug_fuse_link_in(const void *arg_)
|
||||
{
|
||||
const char *name;
|
||||
const struct fuse_link_in *arg = arg_;
|
||||
const struct fuse_link_in *arg = (const fuse_link_in*)arg_;
|
||||
|
||||
name = PARAM(arg);
|
||||
|
||||
@ -483,7 +485,7 @@ void
|
||||
debug_fuse_create_in(const void *arg_)
|
||||
{
|
||||
const char *name;
|
||||
const struct fuse_create_in *arg = arg_;
|
||||
const struct fuse_create_in *arg = (const fuse_create_in*)arg_;
|
||||
|
||||
name = PARAM(arg);
|
||||
|
||||
@ -505,7 +507,7 @@ static
|
||||
void
|
||||
debug_fuse_open_in(const void *arg_)
|
||||
{
|
||||
const struct fuse_open_in *arg = arg_;
|
||||
const struct fuse_open_in *arg = (const fuse_open_in*)arg_;
|
||||
|
||||
fprintf(g_OUTPUT,
|
||||
"fuse_open_in:"
|
||||
@ -519,15 +521,15 @@ static
|
||||
void
|
||||
debug_fuse_read_in(const void *arg_)
|
||||
{
|
||||
const struct fuse_read_in *arg = arg_;
|
||||
const struct fuse_read_in *arg = (const fuse_read_in*)arg_;
|
||||
|
||||
fprintf(g_OUTPUT,
|
||||
"fuse_read_in:"
|
||||
" fh=0x%"PRIx64";"
|
||||
" fh=0x%" PRIx64 ";"
|
||||
" offset=%zu;"
|
||||
" size=%u;"
|
||||
" read_flags=%X;"
|
||||
" lock_owner=0x%"PRIx64";"
|
||||
" lock_owner=0x%" PRIx64 ";"
|
||||
" flags=0x%X ("
|
||||
,
|
||||
arg->fh,
|
||||
@ -544,14 +546,14 @@ static
|
||||
void
|
||||
debug_fuse_write_in(const void *arg_)
|
||||
{
|
||||
const struct fuse_write_in *arg = arg_;
|
||||
const struct fuse_write_in *arg = (const fuse_write_in*)arg_;
|
||||
|
||||
fprintf(g_OUTPUT,
|
||||
"fuse_write_in:"
|
||||
" fh=0x%"PRIx64";"
|
||||
" fh=0x%" PRIx64 ";"
|
||||
" offset=%zu;"
|
||||
" size=%u;"
|
||||
" lock_owner=0x%"PRIx64";"
|
||||
" lock_owner=0x%" PRIx64 ";"
|
||||
" flags=0x%X ("
|
||||
,
|
||||
arg->fh,
|
||||
@ -563,7 +565,7 @@ debug_fuse_write_in(const void *arg_)
|
||||
fprintf(g_OUTPUT,
|
||||
"); write_flags=0x%X (",
|
||||
arg->write_flags);
|
||||
for(int i = 0; i < (sizeof(arg->write_flags) * 8); i++)
|
||||
for(size_t i = 0; i < (sizeof(arg->write_flags) * 8); i++)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
@ -583,12 +585,12 @@ static
|
||||
void
|
||||
debug_fuse_flush_in(const void *arg_)
|
||||
{
|
||||
const struct fuse_flush_in *arg = arg_;
|
||||
const struct fuse_flush_in *arg = (const fuse_flush_in*)arg_;
|
||||
|
||||
fprintf(g_OUTPUT,
|
||||
"fuse_flush_in:"
|
||||
" fh=0x%"PRIx64";"
|
||||
" lock_owner=0x%"PRIx64";"
|
||||
" fh=0x%" PRIx64 ";"
|
||||
" lock_owner=0x%" PRIx64 ";"
|
||||
"\n"
|
||||
,
|
||||
arg->fh,
|
||||
@ -599,13 +601,13 @@ static
|
||||
void
|
||||
debug_fuse_release_in(const void *arg_)
|
||||
{
|
||||
const struct fuse_release_in *arg = arg_;
|
||||
const struct fuse_release_in *arg = (const fuse_release_in*)arg_;
|
||||
|
||||
fprintf(g_OUTPUT,
|
||||
"fuse_release_in:"
|
||||
" fh=0x%"PRIx64";"
|
||||
" fh=0x%" PRIx64 ";"
|
||||
" release_flags=0x%X;"
|
||||
" lock_owner=0x%"PRIx64";"
|
||||
" lock_owner=0x%" PRIx64 ";"
|
||||
" flags=0x%X ("
|
||||
,
|
||||
arg->fh,
|
||||
@ -620,11 +622,11 @@ static
|
||||
void
|
||||
debug_fuse_fsync_in(const void *arg_)
|
||||
{
|
||||
const struct fuse_fsync_in *arg = arg_;
|
||||
const struct fuse_fsync_in *arg = (const fuse_fsync_in*)arg_;
|
||||
|
||||
fprintf(g_OUTPUT,
|
||||
"fuse_fsync_in:"
|
||||
" fh=0x%"PRIx64";"
|
||||
" fh=0x%" PRIx64 ";"
|
||||
" fsync_flags=0x%X;"
|
||||
"\n"
|
||||
,
|
||||
@ -638,7 +640,7 @@ debug_fuse_setxattr_in(const void *arg_)
|
||||
{
|
||||
const char *name;
|
||||
const char *value;
|
||||
const struct fuse_setxattr_in *arg = arg_;
|
||||
const struct fuse_setxattr_in *arg = (const fuse_setxattr_in*)arg_;
|
||||
|
||||
name = PARAM(arg);
|
||||
value = (name + strlen(name) + 1);
|
||||
@ -662,7 +664,7 @@ void
|
||||
debug_fuse_getxattr_in(const void *arg_)
|
||||
{
|
||||
const char *name;
|
||||
const struct fuse_getxattr_in *arg = arg_;
|
||||
const struct fuse_getxattr_in *arg = (const fuse_getxattr_in*)arg_;
|
||||
|
||||
name = PARAM(arg);
|
||||
|
||||
@ -680,7 +682,7 @@ static
|
||||
void
|
||||
debug_fuse_listxattr(const void *arg_)
|
||||
{
|
||||
const struct fuse_getxattr_in *arg = arg_;
|
||||
const struct fuse_getxattr_in *arg = (const fuse_getxattr_in*)arg_;
|
||||
|
||||
fprintf(g_OUTPUT,
|
||||
"fuse_listxattr:"
|
||||
@ -694,7 +696,7 @@ static
|
||||
void
|
||||
debug_fuse_removexattr(const void *arg_)
|
||||
{
|
||||
const char *name = arg_;
|
||||
const char *name = (const char*)arg_;
|
||||
|
||||
fprintf(g_OUTPUT,
|
||||
"fuse_removexattr:"
|
||||
@ -708,11 +710,11 @@ static
|
||||
void
|
||||
debug_fuse_fallocate_in(const void *arg_)
|
||||
{
|
||||
const struct fuse_fallocate_in *arg = arg_;
|
||||
const struct fuse_fallocate_in *arg = (const fuse_fallocate_in*)arg_;
|
||||
|
||||
fprintf(g_OUTPUT,
|
||||
"fuse_fallocate_in:"
|
||||
" fh=0x%"PRIx64";"
|
||||
" fh=0x%" PRIx64 ";"
|
||||
" offset=%zu;"
|
||||
" length=%zu;"
|
||||
" mode=%o;"
|
||||
@ -766,10 +768,10 @@ debug_fuse_init_out(const uint64_t unique_,
|
||||
|
||||
flags = (((uint64_t)arg->flags) | ((uint64_t)arg->flags2) << 32);
|
||||
fprintf(g_OUTPUT,
|
||||
/* "unique=0x%016"PRIx64";" */
|
||||
/* "unique=0x%016" PRIx64 ";" */
|
||||
/* " opcode=RESPONSE;" */
|
||||
/* " error=0 (Success);" */
|
||||
/* " len=%"PRIu64"; || " */
|
||||
/* " len=%" PRIu64 "; || " */
|
||||
"FUSE_INIT_OUT:"
|
||||
" major=%u;"
|
||||
" minor=%u;"
|
||||
@ -819,14 +821,14 @@ debug_fuse_attr(const struct fuse_attr *attr_)
|
||||
{
|
||||
fprintf(g_OUTPUT,
|
||||
"attr:"
|
||||
" ino=0x%016"PRIx64";"
|
||||
" size=%"PRIu64";"
|
||||
" blocks=%"PRIu64";"
|
||||
" atime=%"PRIu64";"
|
||||
" ino=0x%016" PRIx64 ";"
|
||||
" size=%" PRIu64 ";"
|
||||
" blocks=%" PRIu64 ";"
|
||||
" atime=%" PRIu64 ";"
|
||||
" atimensec=%u;"
|
||||
" mtime=%"PRIu64";"
|
||||
" mtime=%" PRIu64 ";"
|
||||
" mtimensec=%u;"
|
||||
" ctime=%"PRIu64";"
|
||||
" ctime=%" PRIu64 ";"
|
||||
" ctimesec=%u;"
|
||||
" mode=%o;"
|
||||
" nlink=%u;"
|
||||
@ -858,11 +860,11 @@ debug_fuse_entry(const struct fuse_entry_out *entry_)
|
||||
{
|
||||
fprintf(g_OUTPUT,
|
||||
" fuse_entry_out:"
|
||||
" nodeid=0x%016"PRIx64";"
|
||||
" generation=0x%016"PRIx64";"
|
||||
" entry_valid=%"PRIu64";"
|
||||
" nodeid=0x%016" PRIx64 ";"
|
||||
" generation=0x%016" PRIx64 ";"
|
||||
" entry_valid=%" PRIu64 ";"
|
||||
" entry_valid_nsec=%u;"
|
||||
" attr_valid=%"PRIu64";"
|
||||
" attr_valid=%" PRIu64 ";"
|
||||
" attr_valid_nsec=%u;"
|
||||
" ",
|
||||
entry_->nodeid,
|
||||
@ -880,10 +882,10 @@ debug_fuse_entry_out(const uint64_t unique_,
|
||||
const uint64_t argsize_)
|
||||
{
|
||||
fprintf(g_OUTPUT,
|
||||
"unique=0x%016"PRIx64";"
|
||||
"unique=0x%016" PRIx64 ";"
|
||||
" opcode=RESPONSE;"
|
||||
" error=0 (Success);"
|
||||
" len=%"PRIu64"; || "
|
||||
" len=%" PRIu64 "; || "
|
||||
,
|
||||
unique_,
|
||||
sizeof(struct fuse_out_header) + argsize_);
|
||||
@ -897,10 +899,10 @@ debug_fuse_attr_out(const uint64_t unique_,
|
||||
const uint64_t argsize_)
|
||||
{
|
||||
fprintf(g_OUTPUT,
|
||||
"unique=0x%016"PRIx64";"
|
||||
"unique=0x%016" PRIx64 ";"
|
||||
" opcode=RESPONSE;"
|
||||
" error=0 (Success);"
|
||||
" len=%"PRIu64"; || "
|
||||
" len=%" PRIu64 "; || "
|
||||
"fuse_attr_out:"
|
||||
" attr_valid=%zu;"
|
||||
" attr_valid_nsec=%u;"
|
||||
@ -945,11 +947,11 @@ static
|
||||
void
|
||||
debug_fuse_interrupt_in(const void *arg_)
|
||||
{
|
||||
const struct fuse_interrupt_in *arg = arg_;
|
||||
const struct fuse_interrupt_in *arg = (const fuse_interrupt_in*)arg_;
|
||||
|
||||
fprintf(g_OUTPUT,
|
||||
"fuse_interrupt_in:"
|
||||
" unique=0x%016"PRIx64";"
|
||||
" unique=0x%016" PRIx64 ";"
|
||||
"\n"
|
||||
,
|
||||
arg->unique);
|
||||
@ -962,53 +964,54 @@ opcode_name(enum fuse_opcode op_)
|
||||
{
|
||||
static const char *names[] =
|
||||
{
|
||||
[FUSE_LOOKUP] = "LOOKUP",
|
||||
[FUSE_FORGET] = "FORGET",
|
||||
[FUSE_GETATTR] = "GETATTR",
|
||||
[FUSE_SETATTR] = "SETATTR",
|
||||
[FUSE_READLINK] = "READLINK",
|
||||
[FUSE_SYMLINK] = "SYMLINK",
|
||||
[FUSE_MKNOD] = "MKNOD",
|
||||
[FUSE_MKDIR] = "MKDIR",
|
||||
[FUSE_UNLINK] = "UNLINK",
|
||||
[FUSE_RMDIR] = "RMDIR",
|
||||
[FUSE_RENAME] = "RENAME",
|
||||
[FUSE_LINK] = "LINK",
|
||||
[FUSE_OPEN] = "OPEN",
|
||||
[FUSE_READ] = "READ",
|
||||
[FUSE_WRITE] = "WRITE",
|
||||
[FUSE_STATFS] = "STATFS",
|
||||
[FUSE_RELEASE] = "RELEASE",
|
||||
[FUSE_FSYNC] = "FSYNC",
|
||||
[FUSE_SETXATTR] = "SETXATTR",
|
||||
[FUSE_GETXATTR] = "GETXATTR",
|
||||
[FUSE_LISTXATTR] = "LISTXATTR",
|
||||
[FUSE_REMOVEXATTR] = "REMOVEXATTR",
|
||||
[FUSE_FLUSH] = "FLUSH",
|
||||
[FUSE_INIT] = "INIT",
|
||||
[FUSE_OPENDIR] = "OPENDIR",
|
||||
[FUSE_READDIR] = "READDIR",
|
||||
[FUSE_RELEASEDIR] = "RELEASEDIR",
|
||||
[FUSE_FSYNCDIR] = "FSYNCDIR",
|
||||
[FUSE_GETLK] = "GETLK",
|
||||
[FUSE_SETLK] = "SETLK",
|
||||
[FUSE_SETLKW] = "SETLKW",
|
||||
[FUSE_ACCESS] = "ACCESS",
|
||||
[FUSE_CREATE] = "CREATE",
|
||||
[FUSE_INTERRUPT] = "INTERRUPT",
|
||||
[FUSE_BMAP] = "BMAP",
|
||||
[FUSE_DESTROY] = "DESTROY",
|
||||
[FUSE_IOCTL] = "IOCTL",
|
||||
[FUSE_POLL] = "POLL",
|
||||
[FUSE_NOTIFY_REPLY] = "NOTIFY_REPLY",
|
||||
[FUSE_BATCH_FORGET] = "BATCH_FORGET",
|
||||
[FUSE_FALLOCATE] = "FALLOCATE",
|
||||
[FUSE_READDIRPLUS] = "READDIRPLUS",
|
||||
[FUSE_RENAME2] = "RENAME2",
|
||||
[FUSE_LSEEK] = "LSEEK",
|
||||
[FUSE_COPY_FILE_RANGE] = "COPY_FILE_RANGE",
|
||||
[FUSE_SETUPMAPPING] = "SETUPMAPPING",
|
||||
[FUSE_REMOVEMAPPING] = "REMOVEMAPPING"
|
||||
"INVALID",
|
||||
"LOOKUP",
|
||||
"FORGET",
|
||||
"GETATTR",
|
||||
"SETATTR",
|
||||
"READLINK",
|
||||
"SYMLINK",
|
||||
"MKNOD",
|
||||
"MKDIR",
|
||||
"UNLINK",
|
||||
"RMDIR",
|
||||
"RENAME",
|
||||
"LINK",
|
||||
"OPEN",
|
||||
"READ",
|
||||
"WRITE",
|
||||
"STATFS",
|
||||
"RELEASE",
|
||||
"FSYNC",
|
||||
"SETXATTR",
|
||||
"GETXATTR",
|
||||
"LISTXATTR",
|
||||
"REMOVEXATTR",
|
||||
"FLUSH",
|
||||
"INIT",
|
||||
"OPENDIR",
|
||||
"READDIR",
|
||||
"RELEASEDIR",
|
||||
"FSYNCDIR",
|
||||
"GETLK",
|
||||
"SETLK",
|
||||
"SETLKW",
|
||||
"ACCESS",
|
||||
"CREATE",
|
||||
"INTERRUPT",
|
||||
"BMAP",
|
||||
"DESTROY",
|
||||
"IOCTL",
|
||||
"POLL",
|
||||
"NOTIFY_REPLY",
|
||||
"BATCH_FORGET",
|
||||
"FALLOCATE",
|
||||
"READDIRPLUS",
|
||||
"RENAME2",
|
||||
"LSEEK",
|
||||
"COPY_FILE_RANGE",
|
||||
"SETUPMAPPING",
|
||||
"REMOVEMAPPING"
|
||||
};
|
||||
|
||||
if(op_ >= (sizeof(names) / sizeof(names[0])))
|
||||
@ -1023,14 +1026,14 @@ debug_fuse_in_header(const struct fuse_in_header *hdr_)
|
||||
const void *arg = &hdr_[1];
|
||||
|
||||
fprintf(stderr,
|
||||
"unique=0x%016"PRIx64";"
|
||||
"unique=0x%016" PRIx64 ";"
|
||||
" opcode=%s (%u);"
|
||||
" nodeid=%zu;"
|
||||
" uid=%u;"
|
||||
" gid=%u;"
|
||||
" pid=%u; || ",
|
||||
hdr_->unique,
|
||||
opcode_name(hdr_->opcode),
|
||||
opcode_name((fuse_opcode)hdr_->opcode),
|
||||
hdr_->opcode,
|
||||
hdr_->nodeid,
|
||||
hdr_->uid,
|
||||
@ -1043,7 +1046,7 @@ debug_fuse_in_header(const struct fuse_in_header *hdr_)
|
||||
debug_fuse_lookup(arg);
|
||||
break;
|
||||
case FUSE_INIT:
|
||||
debug_fuse_init_in(arg);
|
||||
debug_fuse_init_in((const fuse_init_in*)arg);
|
||||
break;
|
||||
case FUSE_GETATTR:
|
||||
debug_fuse_getattr_in(arg);
|
||||
@ -1136,10 +1139,10 @@ void
|
||||
debug_fuse_out_header(const struct fuse_out_header *hdr_)
|
||||
{
|
||||
fprintf(g_OUTPUT,
|
||||
"unique=0x%016"PRIx64";"
|
||||
"unique=0x%016" PRIx64 ";"
|
||||
" opcode=RESPONSE;"
|
||||
" error=%d (%s);"
|
||||
" len=%"PRIu64";"
|
||||
" len=%" PRIu64 ";"
|
||||
,
|
||||
hdr_->unique,
|
||||
hdr_->error,
|
||||
@ -1153,10 +1156,10 @@ debug_fuse_entry_open_out(const uint64_t unique_,
|
||||
const struct fuse_open_out *open_)
|
||||
{
|
||||
fprintf(g_OUTPUT,
|
||||
"unique=0x%016"PRIx64";"
|
||||
"unique=0x%016" PRIx64 ";"
|
||||
" opcode=RESPONSE;"
|
||||
" error=0 (Success);"
|
||||
" len=%"PRIu64"; || "
|
||||
" len=%" PRIu64 "; || "
|
||||
,
|
||||
unique_,
|
||||
sizeof(struct fuse_entry_out) + sizeof(struct fuse_open_out));
|
||||
@ -1169,10 +1172,10 @@ debug_fuse_readlink(const uint64_t unique_,
|
||||
const char *linkname_)
|
||||
{
|
||||
fprintf(g_OUTPUT,
|
||||
"unique=0x%016"PRIx64";"
|
||||
"unique=0x%016" PRIx64 ";"
|
||||
" opcode=RESPONSE;"
|
||||
" error=0 (Success);"
|
||||
" len=%"PRIu64"; || "
|
||||
" len=%" PRIu64 "; || "
|
||||
"readlink: linkname=%s"
|
||||
"\n"
|
||||
,
|
||||
@ -1186,10 +1189,10 @@ debug_fuse_write_out(const uint64_t unique_,
|
||||
const struct fuse_write_out *arg_)
|
||||
{
|
||||
fprintf(g_OUTPUT,
|
||||
"unique=0x%016"PRIx64";"
|
||||
"unique=0x%016" PRIx64 ";"
|
||||
" opcode=RESPONSE;"
|
||||
" error=0 (Success);"
|
||||
" len=%"PRIu64"; || "
|
||||
" len=%" PRIu64 "; || "
|
||||
" fuse_write_out:"
|
||||
" size=%u"
|
||||
"\n"
|
||||
@ -1204,16 +1207,16 @@ debug_fuse_statfs_out(const uint64_t unique_,
|
||||
const struct fuse_statfs_out *arg_)
|
||||
{
|
||||
fprintf(g_OUTPUT,
|
||||
"unique=0x%016"PRIx64";"
|
||||
"unique=0x%016" PRIx64 ";"
|
||||
" opcode=RESPONSE;"
|
||||
" error=0 (Success);"
|
||||
" len=%"PRIu64"; || "
|
||||
" len=%" PRIu64 "; || "
|
||||
" fuse_statfs_out:"
|
||||
" blocks=%"PRIu64";"
|
||||
" bfree=%"PRIu64";"
|
||||
" bavail=%"PRIu64";"
|
||||
" files=%"PRIu64";"
|
||||
" ffree=%"PRIu64";"
|
||||
" blocks=%" PRIu64 ";"
|
||||
" bfree=%" PRIu64 ";"
|
||||
" bavail=%" PRIu64 ";"
|
||||
" files=%" PRIu64 ";"
|
||||
" ffree=%" PRIu64 ";"
|
||||
" bsize=%u;"
|
||||
" namelen=%u;"
|
||||
" frsize=%u;"
|
||||
@ -1236,10 +1239,10 @@ debug_fuse_getxattr_out(const uint64_t unique_,
|
||||
const struct fuse_getxattr_out *arg_)
|
||||
{
|
||||
fprintf(g_OUTPUT,
|
||||
"unique=0x%016"PRIx64";"
|
||||
"unique=0x%016" PRIx64 ";"
|
||||
" opcode=RESPONSE;"
|
||||
" error=0 (Success);"
|
||||
" len=%"PRIu64"; || "
|
||||
" len=%" PRIu64 "; || "
|
||||
" fuse_getxattr_out:"
|
||||
" size=%u;"
|
||||
"\n"
|
||||
@ -1255,13 +1258,13 @@ debug_fuse_lk_out(const uint64_t unique_,
|
||||
const struct fuse_lk_out *arg_)
|
||||
{
|
||||
fprintf(g_OUTPUT,
|
||||
"unique=0x%016"PRIx64";"
|
||||
"unique=0x%016" PRIx64 ";"
|
||||
" opcode=RESPONSE;"
|
||||
" error=0 (Success);"
|
||||
" len=%"PRIu64"; || "
|
||||
" len=%" PRIu64 "; || "
|
||||
" fuse_file_lock:"
|
||||
" start=%"PRIu64";"
|
||||
" end=%"PRIu64";"
|
||||
" start=%" PRIu64 ";"
|
||||
" end=%" PRIu64 ";"
|
||||
" type=%u;"
|
||||
" pid=%u;"
|
||||
"\n"
|
||||
@ -1279,12 +1282,12 @@ debug_fuse_bmap_out(const uint64_t unique_,
|
||||
const struct fuse_bmap_out *arg_)
|
||||
{
|
||||
fprintf(g_OUTPUT,
|
||||
"unique=0x%016"PRIx64";"
|
||||
"unique=0x%016" PRIx64 ";"
|
||||
" opcode=RESPONSE;"
|
||||
" error=0 (Success);"
|
||||
" len=%"PRIu64"; || "
|
||||
" len=%" PRIu64 "; || "
|
||||
" fuse_bmap_out:"
|
||||
" block=%"PRIu64";"
|
||||
" block=%" PRIu64 ";"
|
||||
"\n"
|
||||
,
|
||||
unique_,
|
@ -328,7 +328,7 @@ fmp_gc_slab(fmp_t *fmp_,
|
||||
|
||||
slab_idx_ = (slab_idx_ % kv_size(fmp_->slabs));
|
||||
|
||||
slab = kv_A(fmp_->slabs,slab_idx_);
|
||||
slab = (char*)kv_A(fmp_->slabs,slab_idx_);
|
||||
|
||||
objs_per_slab = fmp_objs_per_slab(fmp_);
|
||||
objs_in_slab = fmp_objs_in_slab(fmp_,slab);
|
||||
|
@ -7,7 +7,9 @@
|
||||
*/
|
||||
|
||||
/* For pthread_rwlock_t */
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include "crc32b.h"
|
||||
#include "fuse_node.h"
|
||||
@ -25,6 +27,9 @@
|
||||
#include "fuse_pollhandle.h"
|
||||
#include "fuse_msgbuf.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <assert.h>
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
@ -104,13 +109,6 @@ struct node_table
|
||||
size_t split;
|
||||
};
|
||||
|
||||
#define container_of(ptr,type,member) ({ \
|
||||
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||
(type *)( (char *)__mptr - offsetof(type,member) );})
|
||||
|
||||
#define list_entry(ptr,type,member) \
|
||||
container_of(ptr,type,member)
|
||||
|
||||
struct list_head
|
||||
{
|
||||
struct list_head *next;
|
||||
@ -218,32 +216,32 @@ fuse_hdr_arg(const struct fuse_in_header *hdr_)
|
||||
|
||||
static
|
||||
void
|
||||
list_add(struct list_head *new,
|
||||
struct list_head *prev,
|
||||
struct list_head *next)
|
||||
list_add(struct list_head *new_,
|
||||
struct list_head *prev_,
|
||||
struct list_head *next_)
|
||||
{
|
||||
next->prev = new;
|
||||
new->next = next;
|
||||
new->prev = prev;
|
||||
prev->next = new;
|
||||
next_->prev = new_;
|
||||
new_->next = next_;
|
||||
new_->prev = prev_;
|
||||
prev_->next = new_;
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
void
|
||||
list_add_head(struct list_head *new,
|
||||
struct list_head *head)
|
||||
list_add_head(struct list_head *new_,
|
||||
struct list_head *head_)
|
||||
{
|
||||
list_add(new,head,head->next);
|
||||
list_add(new_,head_,head_->next);
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
void
|
||||
list_add_tail(struct list_head *new,
|
||||
struct list_head *head)
|
||||
list_add_tail(struct list_head *new_,
|
||||
struct list_head *head_)
|
||||
{
|
||||
list_add(new,head->prev,head);
|
||||
list_add(new_,head_->prev,head_);
|
||||
}
|
||||
|
||||
static
|
||||
@ -384,7 +382,7 @@ node_table_reduce(struct node_table *t)
|
||||
|
||||
newarray = realloc(t->array,sizeof(node_t*) * newsize);
|
||||
if(newarray != NULL)
|
||||
t->array = newarray;
|
||||
t->array = (node_t**)newarray;
|
||||
|
||||
t->size = newsize;
|
||||
t->split = t->size / 2;
|
||||
@ -450,7 +448,7 @@ node_table_resize(struct node_table *t)
|
||||
if(newarray == NULL)
|
||||
return -1;
|
||||
|
||||
t->array = newarray;
|
||||
t->array = (node_t**)newarray;
|
||||
memset(t->array + t->size,0,t->size * sizeof(node_t*));
|
||||
t->size = newsize;
|
||||
t->split = 0;
|
||||
@ -795,7 +793,7 @@ add_name(char **buf,
|
||||
newbufsize *= 2;
|
||||
}
|
||||
|
||||
newbuf = realloc(*buf,newbufsize);
|
||||
newbuf = (char*)realloc(*buf,newbufsize);
|
||||
if(newbuf == NULL)
|
||||
return NULL;
|
||||
|
||||
@ -857,7 +855,7 @@ try_get_path(struct fuse *f,
|
||||
*path = NULL;
|
||||
|
||||
err = -ENOMEM;
|
||||
buf = malloc(bufsize);
|
||||
buf = (char*)malloc(bufsize);
|
||||
if(buf == NULL)
|
||||
goto out_err;
|
||||
|
||||
@ -1562,7 +1560,7 @@ fuse_lib_lookup(fuse_req_t req,
|
||||
node_t *dot = NULL;
|
||||
struct fuse_entry_param e = {0};
|
||||
|
||||
name = fuse_hdr_arg(hdr_);
|
||||
name = (const char*)fuse_hdr_arg(hdr_);
|
||||
nodeid = hdr_->nodeid;
|
||||
f = req_fuse_prepare(req);
|
||||
|
||||
@ -1628,7 +1626,7 @@ fuse_lib_forget(fuse_req_t req,
|
||||
struct fuse_forget_in *arg;
|
||||
|
||||
f = req_fuse(req);
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
arg = (fuse_forget_in*)fuse_hdr_arg(hdr_);
|
||||
|
||||
forget_node(f,hdr_->nodeid,arg->nlookup);
|
||||
|
||||
@ -1645,8 +1643,8 @@ fuse_lib_forget_multi(fuse_req_t req,
|
||||
struct fuse_forget_one *entry;
|
||||
|
||||
f = req_fuse(req);
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
entry = PARAM(arg);
|
||||
arg = (fuse_batch_forget_in*)fuse_hdr_arg(hdr_);
|
||||
entry = (fuse_forget_one*)PARAM(arg);
|
||||
|
||||
for(uint32_t i = 0; i < arg->count; i++)
|
||||
{
|
||||
@ -1673,7 +1671,7 @@ fuse_lib_getattr(fuse_req_t req,
|
||||
fuse_file_info_t ffi = {0};
|
||||
const struct fuse_getattr_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
arg = (fuse_getattr_in*)fuse_hdr_arg(hdr_);
|
||||
f = req_fuse_prepare(req);
|
||||
|
||||
if(arg->getattr_flags & FUSE_GETATTR_FH)
|
||||
@ -1735,7 +1733,7 @@ fuse_lib_setattr(fuse_req_t req,
|
||||
fuse_file_info_t ffi = {0};
|
||||
struct fuse_setattr_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
arg = (fuse_setattr_in*)fuse_hdr_arg(hdr_);
|
||||
|
||||
fi = NULL;
|
||||
if(arg->valid & FATTR_FH)
|
||||
@ -1796,12 +1794,12 @@ fuse_lib_setattr(fuse_req_t req,
|
||||
if(arg->valid & FATTR_ATIME_NOW)
|
||||
tv[0].tv_nsec = UTIME_NOW;
|
||||
else if(arg->valid & FATTR_ATIME)
|
||||
tv[0] = (struct timespec){ arg->atime, arg->atimensec };
|
||||
tv[0] = (struct timespec){ static_cast<time_t>(arg->atime), arg->atimensec };
|
||||
|
||||
if(arg->valid & FATTR_MTIME_NOW)
|
||||
tv[1].tv_nsec = UTIME_NOW;
|
||||
else if(arg->valid & FATTR_MTIME)
|
||||
tv[1] = (struct timespec){ arg->mtime, arg->mtimensec };
|
||||
tv[1] = (struct timespec){ static_cast<time_t>(arg->mtime), arg->mtimensec };
|
||||
|
||||
err = ((fi == NULL) ?
|
||||
f->fs->op.utimens(path,tv) :
|
||||
@ -1853,7 +1851,7 @@ fuse_lib_access(fuse_req_t req,
|
||||
struct fuse *f;
|
||||
struct fuse_access_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
arg = (fuse_access_in*)fuse_hdr_arg(hdr_);
|
||||
|
||||
f = req_fuse_prepare(req);
|
||||
|
||||
@ -1909,8 +1907,8 @@ fuse_lib_mknod(fuse_req_t req,
|
||||
struct fuse_entry_param e;
|
||||
struct fuse_mknod_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
name = PARAM(arg);
|
||||
arg = (fuse_mknod_in*)fuse_hdr_arg(hdr_);
|
||||
name = (const char*)PARAM(arg);
|
||||
if(req->f->conn.proto_minor >= 12)
|
||||
req->ctx.umask = arg->umask;
|
||||
else
|
||||
@ -1961,8 +1959,8 @@ fuse_lib_mkdir(fuse_req_t req,
|
||||
struct fuse_entry_param e;
|
||||
struct fuse_mkdir_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
name = PARAM(arg);
|
||||
arg = (fuse_mkdir_in*)fuse_hdr_arg(hdr_);
|
||||
name = (const char*)PARAM(arg);
|
||||
if(req->f->conn.proto_minor >= 12)
|
||||
req->ctx.umask = arg->umask;
|
||||
|
||||
@ -1991,7 +1989,7 @@ fuse_lib_unlink(fuse_req_t req,
|
||||
const char *name;
|
||||
node_t *wnode;
|
||||
|
||||
name = PARAM(hdr_);
|
||||
name = (const char*)PARAM(hdr_);
|
||||
|
||||
f = req_fuse_prepare(req);
|
||||
err = get_path_wrlock(f,hdr_->nodeid,name,&path,&wnode);
|
||||
@ -2024,7 +2022,7 @@ fuse_lib_rmdir(fuse_req_t req,
|
||||
const char *name;
|
||||
node_t *wnode;
|
||||
|
||||
name = PARAM(hdr_);
|
||||
name = (const char*)PARAM(hdr_);
|
||||
|
||||
f = req_fuse_prepare(req);
|
||||
|
||||
@ -2052,7 +2050,7 @@ fuse_lib_symlink(fuse_req_t req_,
|
||||
const char *linkname;
|
||||
struct fuse_entry_param e = {0};
|
||||
|
||||
name = fuse_hdr_arg(hdr_);
|
||||
name = (const char*)fuse_hdr_arg(hdr_);
|
||||
linkname = (name + strlen(name) + 1);
|
||||
|
||||
f = req_fuse_prepare(req_);
|
||||
@ -2084,8 +2082,8 @@ fuse_lib_rename(fuse_req_t req,
|
||||
node_t *wnode2;
|
||||
struct fuse_rename_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
oldname = PARAM(arg);
|
||||
arg = (fuse_rename_in*)fuse_hdr_arg(hdr_);
|
||||
oldname = (const char*)PARAM(arg);
|
||||
newname = (oldname + strlen(oldname) + 1);
|
||||
|
||||
f = req_fuse_prepare(req);
|
||||
@ -2122,8 +2120,8 @@ fuse_lib_link(fuse_req_t req,
|
||||
struct fuse_link_in *arg;
|
||||
struct fuse_entry_param e = {0};
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
newname = PARAM(arg);
|
||||
arg = (fuse_link_in*)fuse_hdr_arg(hdr_);
|
||||
newname = (const char*)PARAM(arg);
|
||||
|
||||
f = req_fuse_prepare(req);
|
||||
|
||||
@ -2186,8 +2184,8 @@ fuse_lib_create(fuse_req_t req,
|
||||
struct fuse_entry_param e;
|
||||
struct fuse_create_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
name = PARAM(arg);
|
||||
arg = (fuse_create_in*)fuse_hdr_arg(hdr_);
|
||||
name = (const char*)PARAM(arg);
|
||||
|
||||
ffi.flags = arg->flags;
|
||||
|
||||
@ -2287,7 +2285,7 @@ fuse_lib_open(fuse_req_t req,
|
||||
fuse_file_info_t ffi = {0};
|
||||
struct fuse_open_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
arg = (fuse_open_in*)fuse_hdr_arg(hdr_);
|
||||
|
||||
ffi.flags = arg->flags;
|
||||
|
||||
@ -2332,7 +2330,7 @@ fuse_lib_read(fuse_req_t req,
|
||||
struct fuse_read_in *arg;
|
||||
fuse_msgbuf_t *msgbuf;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
arg = (fuse_read_in*)fuse_hdr_arg(hdr_);
|
||||
ffi.fh = arg->fh;
|
||||
if(req->f->conn.proto_minor >= 9)
|
||||
{
|
||||
@ -2365,7 +2363,7 @@ fuse_lib_write(fuse_req_t req,
|
||||
fuse_file_info_t ffi = {0};
|
||||
struct fuse_write_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
arg = (fuse_write_in*)fuse_hdr_arg(hdr_);
|
||||
ffi.fh = arg->fh;
|
||||
ffi.writepage = !!(arg->write_flags & 1);
|
||||
if(req->f->conn.proto_minor < 9)
|
||||
@ -2376,7 +2374,7 @@ fuse_lib_write(fuse_req_t req,
|
||||
{
|
||||
ffi.flags = arg->flags;
|
||||
ffi.lock_owner = arg->lock_owner;
|
||||
data = PARAM(arg);
|
||||
data = (char*)PARAM(arg);
|
||||
}
|
||||
|
||||
f = req_fuse_prepare(req);
|
||||
@ -2400,7 +2398,7 @@ fuse_lib_fsync(fuse_req_t req,
|
||||
struct fuse_fsync_in *arg;
|
||||
fuse_file_info_t ffi = {0};
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
arg = (fuse_fsync_in*)fuse_hdr_arg(hdr_);
|
||||
ffi.fh = arg->fh;
|
||||
|
||||
f = req_fuse_prepare(req);
|
||||
@ -2435,7 +2433,7 @@ fuse_lib_opendir(fuse_req_t req,
|
||||
struct fuse *f;
|
||||
struct fuse_open_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
arg = (fuse_open_in*)fuse_hdr_arg(hdr_);
|
||||
llffi.flags = arg->flags;
|
||||
|
||||
f = req_fuse_prepare(req);
|
||||
@ -2522,7 +2520,7 @@ fuse_lib_readdir(fuse_req_t req_,
|
||||
fuse_file_info_t llffi = {0};
|
||||
struct fuse_read_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
arg = (fuse_read_in*)fuse_hdr_arg(hdr_);
|
||||
size = arg->size;
|
||||
llffi.fh = arg->fh;
|
||||
|
||||
@ -2566,7 +2564,7 @@ fuse_lib_readdir_plus(fuse_req_t req_,
|
||||
fuse_file_info_t llffi = {0};
|
||||
struct fuse_read_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
arg = (fuse_read_in*)fuse_hdr_arg(hdr_);
|
||||
size = arg->size;
|
||||
llffi.fh = arg->fh;
|
||||
|
||||
@ -2607,7 +2605,7 @@ fuse_lib_releasedir(fuse_req_t req_,
|
||||
fuse_file_info_t llffi = {0};
|
||||
struct fuse_release_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
arg = (fuse_release_in*)fuse_hdr_arg(hdr_);
|
||||
llffi.fh = arg->fh;
|
||||
llffi.flags = arg->flags;
|
||||
|
||||
@ -2636,7 +2634,7 @@ fuse_lib_fsyncdir(fuse_req_t req,
|
||||
fuse_file_info_t llffi = {0};
|
||||
struct fuse_fsync_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
arg = (fuse_fsync_in*)fuse_hdr_arg(hdr_);
|
||||
llffi.fh = arg->fh;
|
||||
|
||||
f = req_fuse_prepare(req);
|
||||
@ -2688,9 +2686,9 @@ fuse_lib_setxattr(fuse_req_t req,
|
||||
struct fuse *f;
|
||||
struct fuse_setxattr_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
arg = (fuse_setxattr_in*)fuse_hdr_arg(hdr_);
|
||||
if((req->f->conn.capable & FUSE_SETXATTR_EXT) && (req->f->conn.want & FUSE_SETXATTR_EXT))
|
||||
name = PARAM(arg);
|
||||
name = (const char*)PARAM(arg);
|
||||
else
|
||||
name = (((char*)arg) + FUSE_COMPAT_SETXATTR_IN_SIZE);
|
||||
|
||||
@ -2741,8 +2739,8 @@ fuse_lib_getxattr(fuse_req_t req,
|
||||
const char* name;
|
||||
struct fuse_getxattr_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
name = PARAM(arg);
|
||||
arg = (fuse_getxattr_in*)fuse_hdr_arg(hdr_);
|
||||
name = (const char*)PARAM(arg);
|
||||
|
||||
f = req_fuse_prepare(req);
|
||||
|
||||
@ -2802,7 +2800,7 @@ fuse_lib_listxattr(fuse_req_t req,
|
||||
struct fuse *f;
|
||||
struct fuse_getxattr_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
arg = (fuse_getxattr_in*)fuse_hdr_arg(hdr_);
|
||||
|
||||
f = req_fuse_prepare(req);
|
||||
|
||||
@ -2842,7 +2840,7 @@ fuse_lib_removexattr(fuse_req_t req,
|
||||
const char *name;
|
||||
struct fuse *f;
|
||||
|
||||
name = fuse_hdr_arg(hdr_);
|
||||
name = (const char*)fuse_hdr_arg(hdr_);
|
||||
|
||||
f = req_fuse_prepare(req);
|
||||
|
||||
@ -2867,7 +2865,7 @@ fuse_lib_copy_file_range(fuse_req_t req_,
|
||||
fuse_file_info_t ffi_out = {0};
|
||||
const struct fuse_copy_file_range_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
arg = (fuse_copy_file_range_in*)fuse_hdr_arg(hdr_);
|
||||
ffi_in.fh = arg->fh_in;
|
||||
ffi_out.fh = arg->fh_out;
|
||||
|
||||
@ -2927,8 +2925,8 @@ fuse_lib_tmpfile(fuse_req_t req_,
|
||||
struct fuse_entry_param e;
|
||||
struct fuse_create_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
name = PARAM(arg);
|
||||
arg = (fuse_create_in*)fuse_hdr_arg(hdr_);
|
||||
name = (const char*)PARAM(arg);
|
||||
|
||||
ffi.flags = arg->flags;
|
||||
|
||||
@ -3026,8 +3024,8 @@ locks_insert(node_t *node,
|
||||
|
||||
if(lock->type != F_UNLCK || lock->start != 0 || lock->end != OFFSET_MAX)
|
||||
{
|
||||
newl1 = malloc(sizeof(lock_t));
|
||||
newl2 = malloc(sizeof(lock_t));
|
||||
newl1 = (lock_t*)malloc(sizeof(lock_t));
|
||||
newl2 = (lock_t*)malloc(sizeof(lock_t));
|
||||
|
||||
if(!newl1 || !newl2)
|
||||
{
|
||||
@ -3055,7 +3053,7 @@ locks_insert(node_t *node,
|
||||
lock->start = l->start;
|
||||
if(lock->end < l->end)
|
||||
lock->end = l->end;
|
||||
goto delete;
|
||||
goto delete_lock;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3064,7 +3062,7 @@ locks_insert(node_t *node,
|
||||
if(lock->end < l->start)
|
||||
break;
|
||||
if(lock->start <= l->start && l->end <= lock->end)
|
||||
goto delete;
|
||||
goto delete_lock;
|
||||
if(l->end <= lock->end)
|
||||
{
|
||||
l->end = lock->start - 1;
|
||||
@ -3085,7 +3083,7 @@ locks_insert(node_t *node,
|
||||
lp = &l->next;
|
||||
continue;
|
||||
|
||||
delete:
|
||||
delete_lock:
|
||||
delete_lock(lp);
|
||||
}
|
||||
if(lock->type != F_UNLCK)
|
||||
@ -3168,7 +3166,7 @@ fuse_lib_release(fuse_req_t req,
|
||||
fuse_file_info_t ffi = {0};
|
||||
struct fuse_release_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
arg = (fuse_release_in*)fuse_hdr_arg(hdr_);
|
||||
ffi.fh = arg->fh;
|
||||
ffi.flags = arg->flags;
|
||||
if(req->f->conn.proto_minor >= 8)
|
||||
@ -3206,7 +3204,7 @@ fuse_lib_flush(fuse_req_t req,
|
||||
fuse_file_info_t ffi = {0};
|
||||
struct fuse_flush_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
arg = (fuse_flush_in*)fuse_hdr_arg(hdr_);
|
||||
|
||||
ffi.fh = arg->fh;
|
||||
ffi.flush = 1;
|
||||
@ -3265,7 +3263,7 @@ fuse_lib_getlk(fuse_req_t req,
|
||||
fuse_file_info_t ffi = {0};
|
||||
const struct fuse_lk_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
arg = (fuse_lk_in*)fuse_hdr_arg(hdr_);
|
||||
ffi.fh = arg->fh;
|
||||
ffi.lock_owner = arg->owner;
|
||||
|
||||
@ -3341,7 +3339,7 @@ fuse_lib_bmap(fuse_req_t req,
|
||||
uint64_t block;
|
||||
const struct fuse_bmap_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
arg = (fuse_bmap_in*)fuse_hdr_arg(hdr_);
|
||||
block = arg->block;
|
||||
|
||||
f = req_fuse_prepare(req);
|
||||
@ -3373,7 +3371,7 @@ fuse_lib_ioctl(fuse_req_t req,
|
||||
uint32_t out_size;
|
||||
const struct fuse_ioctl_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
arg = (fuse_ioctl_in*)fuse_hdr_arg(hdr_);
|
||||
if((arg->flags & FUSE_IOCTL_DIR) && !(req->f->conn.want & FUSE_CAP_IOCTL_DIR))
|
||||
{
|
||||
fuse_reply_err(req,ENOTTY);
|
||||
@ -3403,7 +3401,7 @@ fuse_lib_ioctl(fuse_req_t req,
|
||||
if(out_size)
|
||||
{
|
||||
err = -ENOMEM;
|
||||
out_buf = malloc(out_size);
|
||||
out_buf = (char*)malloc(out_size);
|
||||
if(!out_buf)
|
||||
goto err;
|
||||
}
|
||||
@ -3441,7 +3439,7 @@ fuse_lib_poll(fuse_req_t req,
|
||||
fuse_pollhandle_t *ph = NULL;
|
||||
const struct fuse_poll_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
arg = (fuse_poll_in*)fuse_hdr_arg(hdr_);
|
||||
ffi.fh = arg->fh;
|
||||
|
||||
if(arg->flags & FUSE_POLL_SCHEDULE_NOTIFY)
|
||||
@ -3476,7 +3474,7 @@ fuse_lib_fallocate(fuse_req_t req,
|
||||
fuse_file_info_t ffi = {0};
|
||||
const struct fuse_fallocate_in *arg;
|
||||
|
||||
arg = fuse_hdr_arg(hdr_);
|
||||
arg = (fuse_fallocate_in*)fuse_hdr_arg(hdr_);
|
||||
ffi.fh = arg->fh;
|
||||
|
||||
f = req_fuse_prepare(req);
|
||||
@ -3494,8 +3492,8 @@ int
|
||||
remembered_node_cmp(const void *a_,
|
||||
const void *b_)
|
||||
{
|
||||
const remembered_node_t *a = a_;
|
||||
const remembered_node_t *b = b_;
|
||||
const remembered_node_t *a = (const remembered_node_t*)a_;
|
||||
const remembered_node_t *b = (const remembered_node_t*)b_;
|
||||
|
||||
return (a->time - b->time);
|
||||
}
|
||||
@ -3830,21 +3828,21 @@ metrics_log_nodes_info(struct fuse *f_,
|
||||
|
||||
snprintf(buf,sizeof(buf),
|
||||
"time: %s\n"
|
||||
"sizeof(node): %"PRIu64"\n"
|
||||
"node id_table size: %"PRIu64"\n"
|
||||
"node id_table usage: %"PRIu64"\n"
|
||||
"node id_table total allocated memory: %"PRIu64"\n"
|
||||
"node name_table size: %"PRIu64"\n"
|
||||
"node name_table usage: %"PRIu64"\n"
|
||||
"node name_table total allocated memory: %"PRIu64"\n"
|
||||
"node memory pool slab count: %"PRIu64"\n"
|
||||
"sizeof(node): %" PRIu64 "\n"
|
||||
"node id_table size: %" PRIu64 "\n"
|
||||
"node id_table usage: %" PRIu64 "\n"
|
||||
"node id_table total allocated memory: %" PRIu64 "\n"
|
||||
"node name_table size: %" PRIu64 "\n"
|
||||
"node name_table usage: %" PRIu64 "\n"
|
||||
"node name_table total allocated memory: %" PRIu64 "\n"
|
||||
"node memory pool slab count: %" PRIu64 "\n"
|
||||
"node memory pool usage ratio: %f\n"
|
||||
"node memory pool avail objs: %"PRIu64"\n"
|
||||
"node memory pool total allocated memory: %"PRIu64"\n"
|
||||
"msgbuf bufsize: %"PRIu64"\n"
|
||||
"msgbuf allocation count: %"PRIu64"\n"
|
||||
"msgbuf available count: %"PRIu64"\n"
|
||||
"msgbuf total allocated memory: %"PRIu64"\n"
|
||||
"node memory pool avail objs: %" PRIu64 "\n"
|
||||
"node memory pool total allocated memory: %" PRIu64 "\n"
|
||||
"msgbuf bufsize: %" PRIu64 "\n"
|
||||
"msgbuf allocation count: %" PRIu64 "\n"
|
||||
"msgbuf available count: %" PRIu64 "\n"
|
||||
"msgbuf total allocated memory: %" PRIu64 "\n"
|
||||
"\n"
|
||||
,
|
||||
time_str,
|
||||
@ -3907,11 +3905,10 @@ void
|
||||
fuse_invalidate_all_nodes()
|
||||
{
|
||||
struct fuse *f = fuse_get_fuse_obj();
|
||||
|
||||
syslog(LOG_INFO,"invalidating file entries");
|
||||
std::vector<std::string> names;
|
||||
|
||||
pthread_mutex_lock(&f->lock);
|
||||
for(int i = 0; i < f->id_table.size; i++)
|
||||
for(size_t i = 0; i < f->id_table.size; i++)
|
||||
{
|
||||
node_t *node;
|
||||
|
||||
@ -3919,16 +3916,28 @@ fuse_invalidate_all_nodes()
|
||||
{
|
||||
if(node->nodeid == FUSE_ROOT_ID)
|
||||
continue;
|
||||
if(node->name == NULL)
|
||||
continue;
|
||||
if(node->parent == NULL)
|
||||
continue;
|
||||
if(node->parent->nodeid != FUSE_ROOT_ID)
|
||||
continue;
|
||||
|
||||
fuse_lowlevel_notify_inval_entry(f->se->ch,
|
||||
node->parent->nodeid,
|
||||
node->name,
|
||||
strlen(node->name));
|
||||
names.emplace_back(node->name);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&f->lock);
|
||||
|
||||
syslog(LOG_INFO,
|
||||
"invalidating %ld file entries",
|
||||
names.size());
|
||||
for(auto &name : names)
|
||||
{
|
||||
fuse_lowlevel_notify_inval_entry(f->se->ch,
|
||||
FUSE_ROOT_ID,
|
||||
name.c_str(),
|
||||
name.size());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
@ -6,12 +6,14 @@
|
||||
See the file COPYING.LIB
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include "lfmp.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "debug.hpp"
|
||||
#include "fuse_i.h"
|
||||
#include "fuse_kernel.h"
|
||||
#include "fuse_opt.h"
|
||||
@ -41,7 +43,7 @@
|
||||
#define OFFSET_MAX 0x7fffffffffffffffLL
|
||||
|
||||
#define container_of(ptr, type, member) ({ \
|
||||
const typeof( ((type*)0)->member ) *__mptr = (ptr); \
|
||||
const decltype( ((type*)0)->member ) *__mptr = (ptr); \
|
||||
(type *)( (char*)__mptr - offsetof(type,member) );})
|
||||
|
||||
static size_t pagesize;
|
||||
@ -135,7 +137,7 @@ fuse_send_msg(struct fuse_ll *f,
|
||||
int count)
|
||||
{
|
||||
int rv;
|
||||
struct fuse_out_header *out = iov[0].iov_base;
|
||||
struct fuse_out_header *out = (fuse_out_header*)iov[0].iov_base;
|
||||
|
||||
out->len = iov_length(iov, count);
|
||||
|
||||
@ -410,7 +412,7 @@ fuse_send_data_iov_fallback(struct fuse_ll *f,
|
||||
return -ENOMEM;
|
||||
|
||||
mem_buf.buf[0].mem = msgbuf->mem;
|
||||
res = fuse_buf_copy(&mem_buf, buf, 0);
|
||||
res = fuse_buf_copy(&mem_buf, buf, (fuse_buf_copy_flags)0);
|
||||
if(res < 0)
|
||||
{
|
||||
msgbuf_free(msgbuf);
|
||||
@ -550,7 +552,7 @@ fuse_ioctl_iovec_copy(const struct iovec *iov,
|
||||
struct fuse_ioctl_iovec *fiov;
|
||||
size_t i;
|
||||
|
||||
fiov = malloc(sizeof(fiov[0]) * count);
|
||||
fiov = (fuse_ioctl_iovec*)malloc(sizeof(fiov[0]) * count);
|
||||
if(!fiov)
|
||||
return NULL;
|
||||
|
||||
@ -683,7 +685,7 @@ fuse_reply_ioctl_iov(fuse_req_t req,
|
||||
struct fuse_ioctl_out arg = {0};
|
||||
int res;
|
||||
|
||||
padded_iov = malloc((count + 2) * sizeof(struct iovec));
|
||||
padded_iov = (iovec*)malloc((count + 2) * sizeof(struct iovec));
|
||||
if(padded_iov == NULL)
|
||||
return fuse_reply_err(req, ENOMEM);
|
||||
|
||||
@ -896,8 +898,8 @@ do_readdir(fuse_req_t req,
|
||||
|
||||
static
|
||||
void
|
||||
do_readdir_plus(fuse_req_t req_,
|
||||
struct fuse_in_header *hdr_)
|
||||
do_readdirplus(fuse_req_t req_,
|
||||
struct fuse_in_header *hdr_)
|
||||
{
|
||||
req_->f->op.readdir_plus(req_,hdr_);
|
||||
}
|
||||
@ -1372,7 +1374,6 @@ void
|
||||
do_setupmapping(fuse_req_t req_,
|
||||
struct fuse_in_header *hdr_)
|
||||
{
|
||||
printf("setupmapping\n");
|
||||
req_->f->op.setupmapping(req_,hdr_);
|
||||
}
|
||||
|
||||
@ -1381,7 +1382,6 @@ void
|
||||
do_removemapping(fuse_req_t req_,
|
||||
struct fuse_in_header *hdr_)
|
||||
{
|
||||
printf("removemapping\n");
|
||||
req_->f->op.removemapping(req_,hdr_);
|
||||
}
|
||||
|
||||
@ -1390,7 +1390,6 @@ void
|
||||
do_syncfs(fuse_req_t req_,
|
||||
struct fuse_in_header *hdr_)
|
||||
{
|
||||
printf("syncfs\n");
|
||||
req_->f->op.syncfs(req_,hdr_);
|
||||
}
|
||||
|
||||
@ -1399,10 +1398,33 @@ void
|
||||
do_tmpfile(fuse_req_t req_,
|
||||
struct fuse_in_header *hdr_)
|
||||
{
|
||||
printf("tmpfile\n");
|
||||
req_->f->op.tmpfile(req_,hdr_);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
do_statx(fuse_req_t req_,
|
||||
struct fuse_in_header *hdr_)
|
||||
{
|
||||
req_->f->op.statx(req_,hdr_);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
do_rename2(fuse_req_t req_,
|
||||
struct fuse_in_header *hdr_)
|
||||
{
|
||||
req_->f->op.rename2(req_,hdr_);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
do_lseek(fuse_req_t req_,
|
||||
struct fuse_in_header *hdr_)
|
||||
{
|
||||
req_->f->op.lseek(req_,hdr_);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
send_notify_iov(struct fuse_ll *f,
|
||||
@ -1624,7 +1646,7 @@ fuse_lowlevel_notify_retrieve(struct fuse_chan *ch,
|
||||
if(f->conn.proto_minor < 15)
|
||||
return -ENOSYS;
|
||||
|
||||
rreq = malloc(sizeof(*rreq));
|
||||
rreq = (fuse_retrieve_req*)malloc(sizeof(*rreq));
|
||||
if(rreq == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1668,61 +1690,69 @@ fuse_req_ctx(fuse_req_t req)
|
||||
return &req->ctx;
|
||||
}
|
||||
|
||||
static struct {
|
||||
void (*func)(fuse_req_t, struct fuse_in_header *);
|
||||
const char *name;
|
||||
} fuse_ll_ops[] =
|
||||
#define FUSE_OPCODE_LEN (FUSE_STATX + 1)
|
||||
|
||||
typedef void (*fuse_ll_func)(fuse_req_t, struct fuse_in_header *);
|
||||
const
|
||||
fuse_ll_func
|
||||
fuse_ll_funcs[FUSE_OPCODE_LEN] =
|
||||
{
|
||||
[FUSE_LOOKUP] = { do_lookup, "LOOKUP" },
|
||||
[FUSE_FORGET] = { do_forget, "FORGET" },
|
||||
[FUSE_GETATTR] = { do_getattr, "GETATTR" },
|
||||
[FUSE_SETATTR] = { do_setattr, "SETATTR" },
|
||||
[FUSE_READLINK] = { do_readlink, "READLINK" },
|
||||
[FUSE_SYMLINK] = { do_symlink, "SYMLINK" },
|
||||
[FUSE_MKNOD] = { do_mknod, "MKNOD" },
|
||||
[FUSE_MKDIR] = { do_mkdir, "MKDIR" },
|
||||
[FUSE_UNLINK] = { do_unlink, "UNLINK" },
|
||||
[FUSE_RMDIR] = { do_rmdir, "RMDIR" },
|
||||
[FUSE_RENAME] = { do_rename, "RENAME" },
|
||||
[FUSE_LINK] = { do_link, "LINK" },
|
||||
[FUSE_OPEN] = { do_open, "OPEN" },
|
||||
[FUSE_READ] = { do_read, "READ" },
|
||||
[FUSE_WRITE] = { do_write, "WRITE" },
|
||||
[FUSE_STATFS] = { do_statfs, "STATFS" },
|
||||
[FUSE_RELEASE] = { do_release, "RELEASE" },
|
||||
[FUSE_FSYNC] = { do_fsync, "FSYNC" },
|
||||
[FUSE_SETXATTR] = { do_setxattr, "SETXATTR" },
|
||||
[FUSE_GETXATTR] = { do_getxattr, "GETXATTR" },
|
||||
[FUSE_LISTXATTR] = { do_listxattr, "LISTXATTR" },
|
||||
[FUSE_REMOVEXATTR] = { do_removexattr, "REMOVEXATTR" },
|
||||
[FUSE_FLUSH] = { do_flush, "FLUSH" },
|
||||
[FUSE_INIT] = { do_init, "INIT" },
|
||||
[FUSE_OPENDIR] = { do_opendir, "OPENDIR" },
|
||||
[FUSE_READDIR] = { do_readdir, "READDIR" },
|
||||
[FUSE_READDIRPLUS] = { do_readdir_plus, "READDIR_PLUS" },
|
||||
[FUSE_RELEASEDIR] = { do_releasedir, "RELEASEDIR" },
|
||||
[FUSE_FSYNCDIR] = { do_fsyncdir, "FSYNCDIR" },
|
||||
[FUSE_GETLK] = { do_getlk, "GETLK" },
|
||||
[FUSE_SETLK] = { do_setlk, "SETLK" },
|
||||
[FUSE_SETLKW] = { do_setlkw, "SETLKW" },
|
||||
[FUSE_ACCESS] = { do_access, "ACCESS" },
|
||||
[FUSE_CREATE] = { do_create, "CREATE" },
|
||||
[FUSE_INTERRUPT] = { do_interrupt, "INTERRUPT" },
|
||||
[FUSE_BMAP] = { do_bmap, "BMAP" },
|
||||
[FUSE_IOCTL] = { do_ioctl, "IOCTL" },
|
||||
[FUSE_POLL] = { do_poll, "POLL" },
|
||||
[FUSE_FALLOCATE] = { do_fallocate, "FALLOCATE" },
|
||||
[FUSE_DESTROY] = { do_destroy, "DESTROY" },
|
||||
[FUSE_NOTIFY_REPLY] = { do_notify_reply, "NOTIFY_REPLY" },
|
||||
[FUSE_BATCH_FORGET] = { do_batch_forget, "BATCH_FORGET" },
|
||||
[FUSE_COPY_FILE_RANGE] = { do_copy_file_range, "COPY_FILE_RANGE" },
|
||||
[FUSE_SETUPMAPPING] = { do_setupmapping, "SETUPMAPPING" },
|
||||
[FUSE_REMOVEMAPPING] = { do_removemapping, "REMOVEMAPPING" },
|
||||
[FUSE_SYNCFS] = { do_syncfs, "SYNCFS" },
|
||||
[FUSE_TMPFILE] = { do_tmpfile, "TMPFILE" }
|
||||
NULL,
|
||||
do_lookup,
|
||||
do_forget,
|
||||
do_getattr,
|
||||
do_setattr,
|
||||
do_readlink,
|
||||
do_symlink,
|
||||
NULL,
|
||||
do_mknod,
|
||||
do_mkdir,
|
||||
do_unlink,
|
||||
do_rmdir,
|
||||
do_rename,
|
||||
do_link,
|
||||
do_open,
|
||||
do_read,
|
||||
do_write,
|
||||
do_statfs,
|
||||
do_release,
|
||||
NULL,
|
||||
do_fsync,
|
||||
do_setxattr,
|
||||
do_getxattr,
|
||||
do_listxattr,
|
||||
do_removexattr,
|
||||
do_flush,
|
||||
do_init,
|
||||
do_opendir,
|
||||
do_readdir,
|
||||
do_releasedir,
|
||||
do_fsyncdir,
|
||||
do_getlk,
|
||||
do_setlk,
|
||||
do_setlkw,
|
||||
do_access,
|
||||
do_create,
|
||||
do_interrupt,
|
||||
do_bmap,
|
||||
do_destroy,
|
||||
do_ioctl,
|
||||
do_poll,
|
||||
do_notify_reply,
|
||||
do_batch_forget,
|
||||
do_fallocate,
|
||||
do_readdirplus,
|
||||
do_rename2,
|
||||
do_lseek,
|
||||
do_copy_file_range,
|
||||
do_setupmapping,
|
||||
do_removemapping,
|
||||
do_syncfs,
|
||||
do_tmpfile,
|
||||
do_statx
|
||||
};
|
||||
|
||||
#define FUSE_MAXOP (sizeof(fuse_ll_ops) / sizeof(fuse_ll_ops[0]))
|
||||
#define FUSE_MAXOPS (sizeof(fuse_ll_funcs) / sizeof(fuse_ll_funcs[0]))
|
||||
|
||||
enum {
|
||||
KEY_HELP,
|
||||
@ -1816,7 +1846,7 @@ fuse_ll_destroy(void *data)
|
||||
f->op.destroy(f->userdata);
|
||||
}
|
||||
|
||||
llp = pthread_getspecific(f->pipe_key);
|
||||
llp = (fuse_ll_pipe*)pthread_getspecific(f->pipe_key);
|
||||
if(llp != NULL)
|
||||
fuse_ll_pipe_free(llp);
|
||||
pthread_key_delete(f->pipe_key);
|
||||
@ -1830,7 +1860,7 @@ static
|
||||
void
|
||||
fuse_ll_pipe_destructor(void *data)
|
||||
{
|
||||
struct fuse_ll_pipe *llp = data;
|
||||
struct fuse_ll_pipe *llp = (fuse_ll_pipe*)data;
|
||||
fuse_ll_pipe_free(llp);
|
||||
}
|
||||
|
||||
@ -1872,7 +1902,7 @@ fuse_ll_buf_receive_read(struct fuse_session *se_,
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
if(rv < sizeof(struct fuse_in_header))
|
||||
if(rv < (int)sizeof(struct fuse_in_header))
|
||||
{
|
||||
fprintf(stderr, "short read from fuse device\n");
|
||||
return -EIO;
|
||||
@ -1892,8 +1922,6 @@ fuse_ll_buf_process_read(struct fuse_session *se_,
|
||||
|
||||
in = (struct fuse_in_header*)msgbuf_->mem;
|
||||
|
||||
// printf("%d\n",in->opcode);
|
||||
|
||||
req = fuse_ll_alloc_req(se_->f);
|
||||
if(req == NULL)
|
||||
return fuse_send_enomem(se_->f,se_->ch,in->unique);
|
||||
@ -1905,12 +1933,12 @@ fuse_ll_buf_process_read(struct fuse_session *se_,
|
||||
req->ch = se_->ch;
|
||||
|
||||
err = ENOSYS;
|
||||
if(in->opcode >= FUSE_MAXOP)
|
||||
if(in->opcode >= FUSE_MAXOPS)
|
||||
goto reply_err;
|
||||
if(fuse_ll_ops[in->opcode].func == NULL)
|
||||
if(fuse_ll_funcs[in->opcode] == NULL)
|
||||
goto reply_err;
|
||||
|
||||
fuse_ll_ops[in->opcode].func(req, in);
|
||||
fuse_ll_funcs[in->opcode](req, in);
|
||||
|
||||
return;
|
||||
|
||||
@ -1943,12 +1971,12 @@ fuse_ll_buf_process_read_init(struct fuse_session *se_,
|
||||
err = EIO;
|
||||
if(in->opcode != FUSE_INIT)
|
||||
goto reply_err;
|
||||
if(fuse_ll_ops[in->opcode].func == NULL)
|
||||
if(fuse_ll_funcs[FUSE_INIT] == NULL)
|
||||
goto reply_err;
|
||||
|
||||
se_->process_buf = fuse_ll_buf_process_read;
|
||||
|
||||
fuse_ll_ops[in->opcode].func(req, in);
|
||||
fuse_ll_funcs[in->opcode](req,in);
|
||||
|
||||
return;
|
||||
|
||||
@ -2007,9 +2035,9 @@ fuse_lowlevel_new_common(struct fuse_args *args,
|
||||
f->userdata = userdata;
|
||||
|
||||
se = fuse_session_new(f,
|
||||
fuse_ll_buf_receive_read,
|
||||
fuse_ll_buf_process_read_init,
|
||||
fuse_ll_destroy);
|
||||
(void*)fuse_ll_buf_receive_read,
|
||||
(void*)fuse_ll_buf_process_read_init,
|
||||
(void*)fuse_ll_destroy);
|
||||
|
||||
if(!se)
|
||||
goto out_key_destroy;
|
@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "lock.h"
|
||||
#include "lfmp.h"
|
||||
|
||||
@ -23,8 +25,18 @@ struct node_s
|
||||
uint8_t is_stat_cache_valid:1;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
node_t *node_alloc();
|
||||
void node_free(node_t*);
|
||||
int node_gc1();
|
||||
void node_gc();
|
||||
lfmp_t *node_lfmp();
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user