fuse
|
#include "fuse_common.h"
#include <utime.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/uio.h>
#include "fuse_lowlevel_compat.h"
Data Structures | |
struct | fuse_entry_param |
struct | fuse_ctx |
struct | fuse_lowlevel_ops |
struct | fuse_session_ops |
struct | fuse_chan_ops |
Macros | |
#define | FUSE_ROOT_ID 1 |
Typedefs | |
typedef unsigned long | fuse_ino_t |
typedef struct fuse_req * | fuse_req_t |
typedef void(* | fuse_interrupt_func_t )(fuse_req_t req, void *data) |
Functions | |
int | fuse_reply_err (fuse_req_t req, int err) |
void | fuse_reply_none (fuse_req_t req) |
int | fuse_reply_entry (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 struct fuse_file_info *fi) |
int | fuse_reply_attr (fuse_req_t req, const struct stat *attr, double attr_timeout) |
int | fuse_reply_readlink (fuse_req_t req, const char *link) |
int | fuse_reply_open (fuse_req_t req, const struct fuse_file_info *fi) |
int | fuse_reply_write (fuse_req_t req, size_t count) |
int | fuse_reply_buf (fuse_req_t req, const char *buf, size_t size) |
int | fuse_reply_data (fuse_req_t req, struct fuse_bufvec *bufv, enum fuse_buf_copy_flags flags) |
int | fuse_reply_iov (fuse_req_t req, const struct iovec *iov, int count) |
int | fuse_reply_statfs (fuse_req_t req, const struct statvfs *stbuf) |
int | fuse_reply_xattr (fuse_req_t req, size_t count) |
int | fuse_reply_lock (fuse_req_t req, const struct flock *lock) |
int | fuse_reply_bmap (fuse_req_t req, uint64_t idx) |
size_t | fuse_add_direntry (fuse_req_t req, char *buf, size_t bufsize, const char *name, const struct stat *stbuf, off_t off) |
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) |
int | fuse_reply_ioctl (fuse_req_t req, int result, const void *buf, size_t size) |
int | fuse_reply_ioctl_iov (fuse_req_t req, int result, const struct iovec *iov, int count) |
int | fuse_reply_poll (fuse_req_t req, unsigned revents) |
int | fuse_lowlevel_notify_poll (struct fuse_pollhandle *ph) |
int | fuse_lowlevel_notify_inval_inode (struct fuse_chan *ch, fuse_ino_t ino, off_t off, off_t len) |
int | fuse_lowlevel_notify_inval_entry (struct fuse_chan *ch, fuse_ino_t parent, const char *name, size_t namelen) |
int | fuse_lowlevel_notify_delete (struct fuse_chan *ch, fuse_ino_t parent, fuse_ino_t child, const char *name, size_t namelen) |
int | fuse_lowlevel_notify_store (struct fuse_chan *ch, fuse_ino_t ino, off_t offset, struct fuse_bufvec *bufv, enum fuse_buf_copy_flags flags) |
int | fuse_lowlevel_notify_retrieve (struct fuse_chan *ch, fuse_ino_t ino, size_t size, off_t offset, void *cookie) |
void * | fuse_req_userdata (fuse_req_t req) |
const struct fuse_ctx * | fuse_req_ctx (fuse_req_t req) |
int | fuse_req_getgroups (fuse_req_t req, int size, gid_t list[]) |
void | fuse_req_interrupt_func (fuse_req_t req, fuse_interrupt_func_t func, void *data) |
int | fuse_req_interrupted (fuse_req_t req) |
struct fuse_session * | fuse_lowlevel_new (struct fuse_args *args, const struct fuse_lowlevel_ops *op, size_t op_size, void *userdata) |
struct fuse_session * | fuse_session_new (struct fuse_session_ops *op, void *data) |
void | fuse_session_add_chan (struct fuse_session *se, struct fuse_chan *ch) |
void | fuse_session_remove_chan (struct fuse_chan *ch) |
struct fuse_chan * | fuse_session_next_chan (struct fuse_session *se, struct fuse_chan *ch) |
void | fuse_session_process (struct fuse_session *se, const char *buf, size_t len, struct fuse_chan *ch) |
void | fuse_session_process_buf (struct fuse_session *se, const struct fuse_buf *buf, struct fuse_chan *ch) |
int | fuse_session_receive_buf (struct fuse_session *se, struct fuse_buf *buf, struct fuse_chan **chp) |
void | fuse_session_destroy (struct fuse_session *se) |
void | fuse_session_exit (struct fuse_session *se) |
void | fuse_session_reset (struct fuse_session *se) |
int | fuse_session_exited (struct fuse_session *se) |
void * | fuse_session_data (struct fuse_session *se) |
int | fuse_session_loop (struct fuse_session *se) |
int | fuse_session_loop_mt (struct fuse_session *se) |
struct fuse_chan * | fuse_chan_new (struct fuse_chan_ops *op, int fd, size_t bufsize, void *data) |
int | fuse_chan_fd (struct fuse_chan *ch) |
size_t | fuse_chan_bufsize (struct fuse_chan *ch) |
void * | fuse_chan_data (struct fuse_chan *ch) |
struct fuse_session * | fuse_chan_session (struct fuse_chan *ch) |
int | fuse_chan_recv (struct fuse_chan **ch, char *buf, size_t size) |
int | fuse_chan_send (struct fuse_chan *ch, const struct iovec iov[], size_t count) |
void | fuse_chan_destroy (struct fuse_chan *ch) |
Low level API
IMPORTANT: you should define FUSE_USE_VERSION before including this header. To use the newest API define it to 26 (recommended for any new application), to use the old API define it to 24 (default) or 25
#define FUSE_ROOT_ID 1 |
The node ID of the root inode
typedef unsigned long fuse_ino_t |
Inode number type
typedef void(* fuse_interrupt_func_t)(fuse_req_t req, void *data) |
Callback function for an interrupt
req | interrupted request |
data | user data |
typedef struct fuse_req* fuse_req_t |
Request pointer type
size_t fuse_add_direntry | ( | fuse_req_t | req, |
char * | buf, | ||
size_t | bufsize, | ||
const char * | name, | ||
const struct stat * | stbuf, | ||
off_t | off | ||
) |
Add a directory entry to the buffer
Buffer needs to be large enough to hold the entry. If it's not, then the entry is not filled in but the size of the entry is still returned. The caller can check this by comparing the bufsize parameter with the returned entry size. If the entry size is larger than the buffer size, the operation failed.
From the 'stbuf' argument the st_ino field and bits 12-15 of the st_mode field are used. The other fields are ignored.
Note: offsets do not necessarily represent physical offsets, and could be any marker, that enables the implementation to find a specific point in the directory stream.
req | request handle |
buf | the point where the new entry will be added to the buffer |
bufsize | remaining size of the buffer |
name | the name of the entry |
stbuf | the file attributes |
off | the offset of the next entry |
size_t fuse_chan_bufsize | ( | struct fuse_chan * | ch | ) |
Query the minimal receive buffer size
ch | the channel |
void* fuse_chan_data | ( | struct fuse_chan * | ch | ) |
void fuse_chan_destroy | ( | struct fuse_chan * | ch | ) |
Destroy a channel
ch | the channel |
int fuse_chan_fd | ( | struct fuse_chan * | ch | ) |
Query the file descriptor of the channel
ch | the channel |
struct fuse_chan* fuse_chan_new | ( | struct fuse_chan_ops * | op, |
int | fd, | ||
size_t | bufsize, | ||
void * | data | ||
) |
Create a new channel
op | channel operations |
fd | file descriptor of the channel |
bufsize | the minimal receive buffer size |
data | user data |
int fuse_chan_recv | ( | struct fuse_chan ** | ch, |
char * | buf, | ||
size_t | size | ||
) |
Receive a raw request
A return value of -ENODEV means, that the filesystem was unmounted
ch | pointer to the channel |
buf | the buffer to store the request in |
size | the size of the buffer |
int fuse_chan_send | ( | struct fuse_chan * | ch, |
const struct iovec | iov[], | ||
size_t | count | ||
) |
Send a raw reply
A return value of -ENOENT means, that the request was interrupted, and the reply was discarded
ch | the channel |
iov | vector of blocks |
count | the number of blocks in vector |
struct fuse_session* fuse_chan_session | ( | struct fuse_chan * | ch | ) |
Query the session to which this channel is assigned
ch | the channel |
struct fuse_session* fuse_lowlevel_new | ( | struct fuse_args * | args, |
const struct fuse_lowlevel_ops * | op, | ||
size_t | op_size, | ||
void * | userdata | ||
) |
Create a low level session
args | argument vector |
op | the low level filesystem operations |
op_size | sizeof(struct fuse_lowlevel_ops) |
userdata | user data |
int fuse_lowlevel_notify_delete | ( | struct fuse_chan * | ch, |
fuse_ino_t | parent, | ||
fuse_ino_t | child, | ||
const char * | name, | ||
size_t | namelen | ||
) |
Notify to invalidate parent attributes and delete the dentry matching parent/name if the dentry's inode number matches child (otherwise it will invalidate the matching dentry).
To avoid a deadlock don't call this function from a filesystem operation and don't call it with a lock held that can also be held by a filesystem operation.
ch | the channel through which to send the notification |
parent | inode number |
child | inode number |
name | file name |
namelen | strlen() of file name |
int fuse_lowlevel_notify_inval_entry | ( | struct fuse_chan * | ch, |
fuse_ino_t | parent, | ||
const char * | name, | ||
size_t | namelen | ||
) |
Notify to invalidate parent attributes and the dentry matching parent/name
To avoid a deadlock don't call this function from a filesystem operation and don't call it with a lock held that can also be held by a filesystem operation.
ch | the channel through which to send the invalidation |
parent | inode number |
name | file name |
namelen | strlen() of file name |
int fuse_lowlevel_notify_inval_inode | ( | struct fuse_chan * | ch, |
fuse_ino_t | ino, | ||
off_t | off, | ||
off_t | len | ||
) |
Notify to invalidate cache for an inode
ch | the channel through which to send the invalidation |
ino | the inode number |
off | the offset in the inode where to start invalidating or negative to invalidate attributes only |
len | the amount of cache to invalidate or 0 for all |
int fuse_lowlevel_notify_poll | ( | struct fuse_pollhandle * | ph | ) |
Notify IO readiness event
For more information, please read comment for poll operation.
ph | poll handle to notify IO readiness event for |
int fuse_lowlevel_notify_retrieve | ( | struct fuse_chan * | ch, |
fuse_ino_t | ino, | ||
size_t | size, | ||
off_t | offset, | ||
void * | cookie | ||
) |
Retrieve data from the kernel buffers
Retrieve data in the kernel buffers belonging to the given inode. If successful then the retrieve_reply() method will be called with the returned data.
Only present pages are returned in the retrieve reply. Retrieving stops when it finds a non-present page and only data prior to that is returned.
If this function returns an error, then the retrieve will not be completed and no reply will be sent.
This function doesn't change the dirty state of pages in the kernel buffer. For dirty pages the write() method will be called regardless of having been retrieved previously.
ch | the channel through which to send the invalidation |
ino | the inode number |
size | the number of bytes to retrieve |
offset | the starting offset into the file to retrieve from |
cookie | user data to supply to the reply callback |
int fuse_lowlevel_notify_store | ( | struct fuse_chan * | ch, |
fuse_ino_t | ino, | ||
off_t | offset, | ||
struct fuse_bufvec * | bufv, | ||
enum fuse_buf_copy_flags | flags | ||
) |
Store data to the kernel buffers
Synchronously store data in the kernel buffers belonging to the given inode. The stored data is marked up-to-date (no read will be performed against it, unless it's invalidated or evicted from the cache).
If the stored data overflows the current file size, then the size is extended, similarly to a write(2) on the filesystem.
If this function returns an error, then the store wasn't fully completed, but it may have been partially completed.
ch | the channel through which to send the invalidation |
ino | the inode number |
offset | the starting offset into the file to store to |
bufv | buffer vector |
flags | flags controlling the copy |
int fuse_reply_attr | ( | fuse_req_t | req, |
const struct stat * | attr, | ||
double | attr_timeout | ||
) |
Reply with attributes
Possible requests: getattr, setattr
req | request handle |
attr | the attributes |
attr_timeout | validity timeout (in seconds) for the attributes |
int fuse_reply_bmap | ( | fuse_req_t | req, |
uint64_t | idx | ||
) |
Reply with block index
Possible requests: bmap
req | request handle |
idx | block index within device |
int fuse_reply_buf | ( | fuse_req_t | req, |
const char * | buf, | ||
size_t | size | ||
) |
Reply with data
Possible requests: read, readdir, getxattr, listxattr
req | request handle |
buf | buffer containing data |
size | the size of data in bytes |
int fuse_reply_create | ( | fuse_req_t | req, |
const struct fuse_entry_param * | e, | ||
const struct fuse_file_info * | fi | ||
) |
Reply with a directory entry and open parameters
currently the following members of 'fi' are used: fh, direct_io, keep_cache
Possible requests: create
Side effects: increments the lookup count on success
req | request handle |
e | the entry parameters |
fi | file information |
int fuse_reply_data | ( | fuse_req_t | req, |
struct fuse_bufvec * | bufv, | ||
enum fuse_buf_copy_flags | flags | ||
) |
Reply with data copied/moved from buffer(s)
Possible requests: read, readdir, getxattr, listxattr
req | request handle |
bufv | buffer vector |
flags | flags controlling the copy |
int fuse_reply_entry | ( | fuse_req_t | req, |
const struct fuse_entry_param * | e | ||
) |
Reply with a directory entry
Possible requests: lookup, mknod, mkdir, symlink, link
Side effects: increments the lookup count on success
req | request handle |
e | the entry parameters |
int fuse_reply_err | ( | fuse_req_t | req, |
int | err | ||
) |
Reply with an error code or success
Possible requests: all except forget
unlink, rmdir, rename, flush, release, fsync, fsyncdir, setxattr, removexattr and setlk may send a zero code
req | request handle |
err | the positive error value, or zero for success |
int fuse_reply_ioctl | ( | fuse_req_t | req, |
int | result, | ||
const void * | buf, | ||
size_t | size | ||
) |
Reply to finish ioctl
Possible requests: ioctl
req | request handle |
result | result to be passed to the caller |
buf | buffer containing output data |
size | length of output data |
int fuse_reply_ioctl_iov | ( | fuse_req_t | req, |
int | result, | ||
const struct iovec * | iov, | ||
int | count | ||
) |
Reply to finish ioctl with iov buffer
Possible requests: ioctl
req | request handle |
result | result to be passed to the caller |
iov | the vector containing the data |
count | the size of vector |
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 | ||
) |
Reply to ask for data fetch and output buffer preparation. ioctl will be retried with the specified input data fetched and output buffer prepared.
Possible requests: ioctl
req | request handle |
in_iov | iovec specifying data to fetch from the caller |
in_count | number of entries in in_iov |
out_iov | iovec specifying addresses to write output to |
out_count | number of entries in out_iov |
int fuse_reply_iov | ( | fuse_req_t | req, |
const struct iovec * | iov, | ||
int | count | ||
) |
Reply with data vector
Possible requests: read, readdir, getxattr, listxattr
req | request handle |
iov | the vector containing the data |
count | the size of vector |
int fuse_reply_lock | ( | fuse_req_t | req, |
const struct flock * | lock | ||
) |
Reply with file lock information
Possible requests: getlk
req | request handle |
lock | the lock information |
void fuse_reply_none | ( | fuse_req_t | req | ) |
Don't send reply
Possible requests: forget
req | request handle |
int fuse_reply_open | ( | fuse_req_t | req, |
const struct fuse_file_info * | fi | ||
) |
Reply with open parameters
currently the following members of 'fi' are used: fh, direct_io, keep_cache
Possible requests: open, opendir
req | request handle |
fi | file information |
int fuse_reply_poll | ( | fuse_req_t | req, |
unsigned | revents | ||
) |
Reply with poll result event mask
req | request handle |
revents | poll result event mask |
int fuse_reply_readlink | ( | fuse_req_t | req, |
const char * | link | ||
) |
Reply with the contents of a symbolic link
Possible requests: readlink
req | request handle |
link | symbolic link contents |
int fuse_reply_statfs | ( | fuse_req_t | req, |
const struct statvfs * | stbuf | ||
) |
Reply with filesystem statistics
Possible requests: statfs
req | request handle |
stbuf | filesystem statistics |
int fuse_reply_write | ( | fuse_req_t | req, |
size_t | count | ||
) |
Reply with number of bytes written
Possible requests: write
req | request handle |
count | the number of bytes written |
int fuse_reply_xattr | ( | fuse_req_t | req, |
size_t | count | ||
) |
Reply with needed buffer size
Possible requests: getxattr, listxattr
req | request handle |
count | the buffer size needed in bytes |
const struct fuse_ctx* fuse_req_ctx | ( | 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
req | request handle |
int fuse_req_getgroups | ( | fuse_req_t | req, |
int | size, | ||
gid_t | list[] | ||
) |
Get the current supplementary group IDs for the specified request
Similar to the getgroups(2) system call, except the return value is always the total number of group IDs, even if it is larger than the specified size.
The current fuse kernel module in linux (as of 2.6.30) doesn't pass the group list to userspace, hence this function needs to parse "/proc/$TID/task/$TID/status" to get the group IDs.
This feature may not be supported on all operating systems. In such a case this function will return -ENOSYS.
req | request handle |
size | size of given array |
list | array of group IDs to be filled in |
void fuse_req_interrupt_func | ( | fuse_req_t | req, |
fuse_interrupt_func_t | func, | ||
void * | data | ||
) |
Register/unregister callback for an interrupt
If an interrupt has already happened, then the callback function is called from within this function, hence it's not possible for interrupts to be lost.
req | request handle |
func | the callback function or NULL for unregister |
data | user data passed to the callback function |
int fuse_req_interrupted | ( | fuse_req_t | req | ) |
Check if a request has already been interrupted
req | request handle |
void* fuse_req_userdata | ( | fuse_req_t | req | ) |
Get the userdata from the request
req | request handle |
void fuse_session_add_chan | ( | struct fuse_session * | se, |
struct fuse_chan * | ch | ||
) |
Assign a channel to a session
Note: currently only a single channel may be assigned. This may change in the future
If a session is destroyed, the assigned channel is also destroyed
se | the session |
ch | the channel |
void* fuse_session_data | ( | struct fuse_session * | se | ) |
Get the user data provided to the session
se | the session |
void fuse_session_destroy | ( | struct fuse_session * | se | ) |
Destroy a session
se | the session |
void fuse_session_exit | ( | struct fuse_session * | se | ) |
Exit a session
se | the session |
int fuse_session_exited | ( | struct fuse_session * | se | ) |
Query the exited status of a session
se | the session |
int fuse_session_loop | ( | struct fuse_session * | se | ) |
Enter a single threaded event loop
se | the session |
int fuse_session_loop_mt | ( | struct fuse_session * | se | ) |
Enter a multi-threaded event loop
se | the session |
struct fuse_session* fuse_session_new | ( | struct fuse_session_ops * | op, |
void * | data | ||
) |
Create a new session
op | session operations |
data | user data |
struct fuse_chan* fuse_session_next_chan | ( | struct fuse_session * | se, |
struct fuse_chan * | ch | ||
) |
Iterate over the channels assigned to a session
The iterating function needs to start with a NULL channel, and after that needs to pass the previously returned channel to the function.
se | the session |
ch | the previous channel, or NULL |
void fuse_session_process | ( | struct fuse_session * | se, |
const char * | buf, | ||
size_t | len, | ||
struct fuse_chan * | ch | ||
) |
Process a raw request
se | the session |
buf | buffer containing the raw request |
len | request length |
ch | channel on which the request was received |
void fuse_session_process_buf | ( | struct fuse_session * | se, |
const struct fuse_buf * | buf, | ||
struct fuse_chan * | ch | ||
) |
Process a raw request supplied in a generic buffer
This is a more generic version of fuse_session_process(). The fuse_buf may contain a memory buffer or a pipe file descriptor.
se | the session |
buf | the fuse_buf containing the request |
ch | channel on which the request was received |
int fuse_session_receive_buf | ( | struct fuse_session * | se, |
struct fuse_buf * | buf, | ||
struct fuse_chan ** | chp | ||
) |
Receive a raw request supplied in a generic buffer
This is a more generic version of fuse_chan_recv(). The fuse_buf supplied to this function contains a suitably allocated memory buffer. This may be overwritten with a file descriptor buffer.
se | the session |
buf | the fuse_buf to store the request in |
chp | pointer to the channel |
void fuse_session_remove_chan | ( | struct fuse_chan * | ch | ) |
Remove a channel from a session
If the channel is not assigned to a session, then this is a no-op
ch | the channel to remove |
void fuse_session_reset | ( | struct fuse_session * | se | ) |
Reset the exited status of a session
se | the session |