|
|
@ -23,6 +23,7 @@ |
|
|
|
#define FUSE_USE_VERSION 24 |
|
|
|
#endif |
|
|
|
|
|
|
|
#include "extern_c.h" |
|
|
|
#include "fuse_common.h" |
|
|
|
|
|
|
|
#include <fcntl.h> |
|
|
@ -33,51 +34,49 @@ |
|
|
|
#include <sys/uio.h> |
|
|
|
#include <utime.h> |
|
|
|
|
|
|
|
#ifdef __cplusplus |
|
|
|
extern "C" { |
|
|
|
#endif |
|
|
|
EXTERN_C_BEGIN |
|
|
|
|
|
|
|
/* ----------------------------------------------------------- * |
|
|
|
/* ----------------------------------------------------------- * |
|
|
|
* Miscellaneous definitions * |
|
|
|
* ----------------------------------------------------------- */ |
|
|
|
|
|
|
|
/** The node ID of the root inode */ |
|
|
|
/** The node ID of the root inode */ |
|
|
|
#define FUSE_ROOT_ID 1 |
|
|
|
|
|
|
|
/** Inode number type */ |
|
|
|
typedef uint64_t fuse_ino_t; |
|
|
|
/** Inode number type */ |
|
|
|
typedef uint64_t fuse_ino_t; |
|
|
|
|
|
|
|
/** Request pointer type */ |
|
|
|
typedef struct fuse_req *fuse_req_t; |
|
|
|
/** Request pointer type */ |
|
|
|
typedef struct fuse_req *fuse_req_t; |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Session |
|
|
|
* |
|
|
|
* This provides hooks for processing requests, and exiting |
|
|
|
*/ |
|
|
|
struct fuse_session; |
|
|
|
struct fuse_session; |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Channel |
|
|
|
* |
|
|
|
* A communication channel, providing hooks for sending and receiving |
|
|
|
* messages |
|
|
|
*/ |
|
|
|
struct fuse_chan; |
|
|
|
struct fuse_chan; |
|
|
|
|
|
|
|
/** Directory entry parameters supplied to fuse_reply_entry() */ |
|
|
|
struct fuse_entry_param |
|
|
|
{ |
|
|
|
/** Unique inode number |
|
|
|
/** Directory entry parameters supplied to fuse_reply_entry() */ |
|
|
|
struct fuse_entry_param |
|
|
|
{ |
|
|
|
/** Unique inode number |
|
|
|
* |
|
|
|
* In lookup, zero means negative entry (from version 2.5) |
|
|
|
* Returning ENOENT also means negative entry, but by setting zero |
|
|
|
* ino the kernel may cache negative entries for entry_timeout |
|
|
|
* seconds. |
|
|
|
*/ |
|
|
|
fuse_ino_t ino; |
|
|
|
fuse_ino_t ino; |
|
|
|
|
|
|
|
/** Generation number for this entry. |
|
|
|
/** Generation number for this entry. |
|
|
|
* |
|
|
|
* If the file system will be exported over NFS, the |
|
|
|
* ino/generation pairs need to be unique over the file |
|
|
@ -90,48 +89,48 @@ extern "C" { |
|
|
|
* it as an error. |
|
|
|
* |
|
|
|
*/ |
|
|
|
uint64_t generation; |
|
|
|
uint64_t generation; |
|
|
|
|
|
|
|
|
|
|
|
/** Inode attributes. |
|
|
|
/** Inode attributes. |
|
|
|
* |
|
|
|
* Even if attr_timeout == 0, attr must be correct. For example, |
|
|
|
* for open(), FUSE uses attr.st_size from lookup() to determine |
|
|
|
* how many bytes to request. If this value is not correct, |
|
|
|
* incorrect data will be returned. |
|
|
|
*/ |
|
|
|
struct stat attr; |
|
|
|
struct stat attr; |
|
|
|
|
|
|
|
fuse_timeouts_t timeout; |
|
|
|
}; |
|
|
|
fuse_timeouts_t timeout; |
|
|
|
}; |
|
|
|
|
|
|
|
/** Additional context associated with requests */ |
|
|
|
struct fuse_ctx |
|
|
|
{ |
|
|
|
/** User ID of the calling process */ |
|
|
|
uid_t uid; |
|
|
|
/** Additional context associated with requests */ |
|
|
|
struct fuse_ctx |
|
|
|
{ |
|
|
|
/** User ID of the calling process */ |
|
|
|
uid_t uid; |
|
|
|
|
|
|
|
/** Group ID of the calling process */ |
|
|
|
gid_t gid; |
|
|
|
/** Group ID of the calling process */ |
|
|
|
gid_t gid; |
|
|
|
|
|
|
|
/** Thread ID of the calling process */ |
|
|
|
pid_t pid; |
|
|
|
/** Thread ID of the calling process */ |
|
|
|
pid_t pid; |
|
|
|
|
|
|
|
/** Umask of the calling process (introduced in version 2.8) */ |
|
|
|
mode_t umask; |
|
|
|
}; |
|
|
|
/** Umask of the calling process (introduced in version 2.8) */ |
|
|
|
mode_t umask; |
|
|
|
}; |
|
|
|
|
|
|
|
struct fuse_forget_data |
|
|
|
{ |
|
|
|
fuse_ino_t ino; |
|
|
|
uint64_t nlookup; |
|
|
|
}; |
|
|
|
struct fuse_forget_data |
|
|
|
{ |
|
|
|
fuse_ino_t ino; |
|
|
|
uint64_t nlookup; |
|
|
|
}; |
|
|
|
|
|
|
|
/* ----------------------------------------------------------- * |
|
|
|
/* ----------------------------------------------------------- * |
|
|
|
* Request methods and replies * |
|
|
|
* ----------------------------------------------------------- */ |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Low level filesystem operations |
|
|
|
* |
|
|
|
* Most of the methods (with the exception of init and destroy) |
|
|
@ -152,9 +151,9 @@ extern "C" { |
|
|
|
* fuse_reply_open() return -ENOENT means, that the release method for |
|
|
|
* this file will not be called. |
|
|
|
*/ |
|
|
|
struct fuse_lowlevel_ops |
|
|
|
{ |
|
|
|
/** |
|
|
|
struct fuse_lowlevel_ops |
|
|
|
{ |
|
|
|
/** |
|
|
|
* Initialize filesystem |
|
|
|
* |
|
|
|
* Called before any other filesystem method |
|
|
@ -163,9 +162,9 @@ extern "C" { |
|
|
|
* |
|
|
|
* @param userdata the user data passed to fuse_lowlevel_new() |
|
|
|
*/ |
|
|
|
void (*init) (void *userdata, struct fuse_conn_info *conn); |
|
|
|
void (*init) (void *userdata, struct fuse_conn_info *conn); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Clean up filesystem |
|
|
|
* |
|
|
|
* Called on filesystem exit |
|
|
@ -174,9 +173,9 @@ extern "C" { |
|
|
|
* |
|
|
|
* @param userdata the user data passed to fuse_lowlevel_new() |
|
|
|
*/ |
|
|
|
void (*destroy) (void *userdata); |
|
|
|
void (*destroy) (void *userdata); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Look up a directory entry by name and get its attributes. |
|
|
|
* |
|
|
|
* Valid replies: |
|
|
@ -187,9 +186,9 @@ extern "C" { |
|
|
|
* @param parent inode number of the parent directory |
|
|
|
* @param name the name to look up |
|
|
|
*/ |
|
|
|
void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name); |
|
|
|
void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Forget about an inode |
|
|
|
* |
|
|
|
* This function is called when the kernel removes an inode |
|
|
@ -1063,9 +1062,9 @@ extern "C" { |
|
|
|
struct fuse_file_info *fi_out, |
|
|
|
size_t len, |
|
|
|
int flags); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reply with an error code or success |
|
|
|
* |
|
|
|
* Possible requests: |
|
|
@ -1078,9 +1077,9 @@ extern "C" { |
|
|
|
* @param err the positive error value, or zero for success |
|
|
|
* @return zero for success, -errno for failure to send reply |
|
|
|
*/ |
|
|
|
int fuse_reply_err(fuse_req_t req, int err); |
|
|
|
int fuse_reply_err(fuse_req_t req, int err); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Don't send reply |
|
|
|
* |
|
|
|
* Possible requests: |
|
|
@ -1088,9 +1087,9 @@ extern "C" { |
|
|
|
* |
|
|
|
* @param req request handle |
|
|
|
*/ |
|
|
|
void fuse_reply_none(fuse_req_t req); |
|
|
|
void fuse_reply_none(fuse_req_t req); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reply with a directory entry |
|
|
|
* |
|
|
|
* Possible requests: |
|
|
@ -1103,9 +1102,9 @@ extern "C" { |
|
|
|
* @param e the entry parameters |
|
|
|
* @return zero for success, -errno for failure to send reply |
|
|
|
*/ |
|
|
|
int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e); |
|
|
|
int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reply with a directory entry and open parameters |
|
|
|
* |
|
|
|
* currently the following members of 'fi' are used: |
|
|
@ -1122,10 +1121,10 @@ extern "C" { |
|
|
|
* @param fi file information |
|
|
|
* @return zero for success, -errno for failure to send reply |
|
|
|
*/ |
|
|
|
int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e, |
|
|
|
int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e, |
|
|
|
const struct fuse_file_info *fi); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reply with attributes |
|
|
|
* |
|
|
|
* Possible requests: |
|
|
@ -1136,11 +1135,11 @@ extern "C" { |
|
|
|
* @param attr_timeout validity timeout (in seconds) for the attributes |
|
|
|
* @return zero for success, -errno for failure to send reply |
|
|
|
*/ |
|
|
|
int fuse_reply_attr(fuse_req_t req, |
|
|
|
int fuse_reply_attr(fuse_req_t req, |
|
|
|
const struct stat *attr, |
|
|
|
const uint64_t timeout); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reply with the contents of a symbolic link |
|
|
|
* |
|
|
|
* Possible requests: |
|
|
@ -1150,9 +1149,9 @@ extern "C" { |
|
|
|
* @param link symbolic link contents |
|
|
|
* @return zero for success, -errno for failure to send reply |
|
|
|
*/ |
|
|
|
int fuse_reply_readlink(fuse_req_t req, const char *link); |
|
|
|
int fuse_reply_readlink(fuse_req_t req, const char *link); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reply with open parameters |
|
|
|
* |
|
|
|
* currently the following members of 'fi' are used: |
|
|
@ -1165,9 +1164,9 @@ extern "C" { |
|
|
|
* @param fi file information |
|
|
|
* @return zero for success, -errno for failure to send reply |
|
|
|
*/ |
|
|
|
int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *fi); |
|
|
|
int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *fi); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reply with number of bytes written |
|
|
|
* |
|
|
|
* Possible requests: |
|
|
@ -1177,9 +1176,9 @@ extern "C" { |
|
|
|
* @param count the number of bytes written |
|
|
|
* @return zero for success, -errno for failure to send reply |
|
|
|
*/ |
|
|
|
int fuse_reply_write(fuse_req_t req, size_t count); |
|
|
|
int fuse_reply_write(fuse_req_t req, size_t count); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reply with data |
|
|
|
* |
|
|
|
* Possible requests: |
|
|
@ -1190,9 +1189,9 @@ extern "C" { |
|
|
|
* @param size the size of data in bytes |
|
|
|
* @return zero for success, -errno for failure to send reply |
|
|
|
*/ |
|
|
|
int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size); |
|
|
|
int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reply with data copied/moved from buffer(s) |
|
|
|
* |
|
|
|
* Possible requests: |
|
|
@ -1203,10 +1202,10 @@ extern "C" { |
|
|
|
* @param flags flags controlling the copy |
|
|
|
* @return zero for success, -errno for failure to send reply |
|
|
|
*/ |
|
|
|
int fuse_reply_data(fuse_req_t req, struct fuse_bufvec *bufv, |
|
|
|
int fuse_reply_data(fuse_req_t req, struct fuse_bufvec *bufv, |
|
|
|
enum fuse_buf_copy_flags flags); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reply with data vector |
|
|
|
* |
|
|
|
* Possible requests: |
|
|
@ -1217,9 +1216,9 @@ extern "C" { |
|
|
|
* @param count the size of vector |
|
|
|
* @return zero for success, -errno for failure to send reply |
|
|
|
*/ |
|
|
|
int fuse_reply_iov(fuse_req_t req, const struct iovec *iov, int count); |
|
|
|
int fuse_reply_iov(fuse_req_t req, const struct iovec *iov, int count); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reply with filesystem statistics |
|
|
|
* |
|
|
|
* Possible requests: |
|
|
@ -1229,9 +1228,9 @@ extern "C" { |
|
|
|
* @param stbuf filesystem statistics |
|
|
|
* @return zero for success, -errno for failure to send reply |
|
|
|
*/ |
|
|
|
int fuse_reply_statfs(fuse_req_t req, const struct statvfs *stbuf); |
|
|
|
int fuse_reply_statfs(fuse_req_t req, const struct statvfs *stbuf); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reply with needed buffer size |
|
|
|
* |
|
|
|
* Possible requests: |
|
|
@ -1241,9 +1240,9 @@ extern "C" { |
|
|
|
* @param count the buffer size needed in bytes |
|
|
|
* @return zero for success, -errno for failure to send reply |
|
|
|
*/ |
|
|
|
int fuse_reply_xattr(fuse_req_t req, size_t count); |
|
|
|
int fuse_reply_xattr(fuse_req_t req, size_t count); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reply with file lock information |
|
|
|
* |
|
|
|
* Possible requests: |
|
|
@ -1253,9 +1252,9 @@ extern "C" { |
|
|
|
* @param lock the lock information |
|
|
|
* @return zero for success, -errno for failure to send reply |
|
|
|
*/ |
|
|
|
int fuse_reply_lock(fuse_req_t req, const struct flock *lock); |
|
|
|
int fuse_reply_lock(fuse_req_t req, const struct flock *lock); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reply with block index |
|
|
|
* |
|
|
|
* Possible requests: |
|
|
@ -1265,9 +1264,9 @@ extern "C" { |
|
|
|
* @param idx block index within device |
|
|
|
* @return zero for success, -errno for failure to send reply |
|
|
|
*/ |
|
|
|
int fuse_reply_bmap(fuse_req_t req, uint64_t idx); |
|
|
|
int fuse_reply_bmap(fuse_req_t req, uint64_t idx); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reply to ask for data fetch and output buffer preparation. ioctl |
|
|
|
* will be retried with the specified input data fetched and output |
|
|
|
* buffer prepared. |
|
|
@ -1282,11 +1281,11 @@ extern "C" { |
|
|
|
* @param out_count number of entries in out_iov |
|
|
|
* @return zero for success, -errno for failure to send reply |
|
|
|
*/ |
|
|
|
int fuse_reply_ioctl_retry(fuse_req_t req, |
|
|
|
int fuse_reply_ioctl_retry(fuse_req_t req, |
|
|
|
const struct iovec *in_iov, size_t in_count, |
|
|
|
const struct iovec *out_iov, size_t out_count); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reply to finish ioctl |
|
|
|
* |
|
|
|
* Possible requests: |
|
|
@ -1297,9 +1296,9 @@ extern "C" { |
|
|
|
* @param buf buffer containing output data |
|
|
|
* @param size length of output data |
|
|
|
*/ |
|
|
|
int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, uint32_t size); |
|
|
|
int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, uint32_t size); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reply to finish ioctl with iov buffer |
|
|
|
* |
|
|
|
* Possible requests: |
|
|
@ -1310,31 +1309,31 @@ extern "C" { |
|
|
|
* @param iov the vector containing the data |
|
|
|
* @param count the size of vector |
|
|
|
*/ |
|
|
|
int fuse_reply_ioctl_iov(fuse_req_t req, int result, const struct iovec *iov, |
|
|
|
int fuse_reply_ioctl_iov(fuse_req_t req, int result, const struct iovec *iov, |
|
|
|
int count); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reply with poll result event mask |
|
|
|
* |
|
|
|
* @param req request handle |
|
|
|
* @param revents poll result event mask |
|
|
|
*/ |
|
|
|
int fuse_reply_poll(fuse_req_t req, unsigned revents); |
|
|
|
int fuse_reply_poll(fuse_req_t req, unsigned revents); |
|
|
|
|
|
|
|
/* ----------------------------------------------------------- * |
|
|
|
/* ----------------------------------------------------------- * |
|
|
|
* Notification * |
|
|
|
* ----------------------------------------------------------- */ |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Notify IO readiness event |
|
|
|
* |
|
|
|
* For more information, please read comment for poll operation. |
|
|
|
* |
|
|
|
* @param ph poll handle to notify IO readiness event for |
|
|
|
*/ |
|
|
|
int fuse_lowlevel_notify_poll(struct fuse_pollhandle *ph); |
|
|
|
int fuse_lowlevel_notify_poll(struct fuse_pollhandle *ph); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Notify to invalidate cache for an inode |
|
|
|
* |
|
|
|
* @param ch the channel through which to send the invalidation |
|
|
@ -1344,10 +1343,10 @@ extern "C" { |
|
|
|
* @param len the amount of cache to invalidate or 0 for all |
|
|
|
* @return zero for success, -errno for failure |
|
|
|
*/ |
|
|
|
int fuse_lowlevel_notify_inval_inode(struct fuse_chan *ch, fuse_ino_t ino, |
|
|
|
int fuse_lowlevel_notify_inval_inode(struct fuse_chan *ch, fuse_ino_t ino, |
|
|
|
off_t off, off_t len); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Notify to invalidate parent attributes and the dentry matching |
|
|
|
* parent/name |
|
|
|
* |
|
|
@ -1361,10 +1360,10 @@ extern "C" { |
|
|
|
* @param namelen strlen() of file name |
|
|
|
* @return zero for success, -errno for failure |
|
|
|
*/ |
|
|
|
int fuse_lowlevel_notify_inval_entry(struct fuse_chan *ch, fuse_ino_t parent, |
|
|
|
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 delete the dentry matching |
|
|
|
* parent/name if the dentry's inode number matches child (otherwise it |
|
|
|
* will invalidate the matching dentry). |
|
|
@ -1380,11 +1379,11 @@ extern "C" { |
|
|
|
* @param namelen strlen() of file name |
|
|
|
* @return zero for success, -errno for failure |
|
|
|
*/ |
|
|
|
int fuse_lowlevel_notify_delete(struct fuse_chan *ch, |
|
|
|
int fuse_lowlevel_notify_delete(struct fuse_chan *ch, |
|
|
|
fuse_ino_t parent, fuse_ino_t child, |
|
|
|
const char *name, size_t namelen); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Store data to the kernel buffers |
|
|
|
* |
|
|
|
* Synchronously store data in the kernel buffers belonging to the |
|
|
@ -1405,10 +1404,10 @@ extern "C" { |
|
|
|
* @param flags flags controlling the copy |
|
|
|
* @return zero for success, -errno for failure |
|
|
|
*/ |
|
|
|
int fuse_lowlevel_notify_store(struct fuse_chan *ch, fuse_ino_t ino, |
|
|
|
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); |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Retrieve data from the kernel buffers |
|
|
|
* |
|
|
|
* Retrieve data in the kernel buffers belonging to the given inode. |
|
|
@ -1433,23 +1432,23 @@ extern "C" { |
|
|
|
* @param cookie user data to supply to the reply callback |
|
|
|
* @return zero for success, -errno for failure |
|
|
|
*/ |
|
|
|
int fuse_lowlevel_notify_retrieve(struct fuse_chan *ch, fuse_ino_t ino, |
|
|
|
int fuse_lowlevel_notify_retrieve(struct fuse_chan *ch, fuse_ino_t ino, |
|
|
|
size_t size, off_t offset, void *cookie); |
|
|
|
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------- * |
|
|
|
/* ----------------------------------------------------------- * |
|
|
|
* Utility functions * |
|
|
|
* ----------------------------------------------------------- */ |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Get the userdata from the request |
|
|
|
* |
|
|
|
* @param req request handle |
|
|
|
* @return the user data passed to fuse_lowlevel_new() |
|
|
|
*/ |
|
|
|
void *fuse_req_userdata(fuse_req_t req); |
|
|
|
void *fuse_req_userdata(fuse_req_t req); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Get the context from the request |
|
|
|
* |
|
|
|
* The pointer returned by this function will only be valid for the |
|
|
@ -1458,9 +1457,9 @@ extern "C" { |
|
|
|
* @param req request handle |
|
|
|
* @return the context structure |
|
|
|
*/ |
|
|
|
const struct fuse_ctx *fuse_req_ctx(fuse_req_t req); |
|
|
|
const struct fuse_ctx *fuse_req_ctx(fuse_req_t req); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Get the current supplementary group IDs for the specified request |
|
|
|
* |
|
|
|
* Similar to the getgroups(2) system call, except the return value is |
|
|
@ -1479,17 +1478,17 @@ extern "C" { |
|
|
|
* @param list array of group IDs to be filled in |
|
|
|
* @return the total number of supplementary group IDs or -errno on failure |
|
|
|
*/ |
|
|
|
int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[]); |
|
|
|
int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[]); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Callback function for an interrupt |
|
|
|
* |
|
|
|
* @param req interrupted request |
|
|
|
* @param data user data |
|
|
|
*/ |
|
|
|
typedef void (*fuse_interrupt_func_t)(fuse_req_t req, void *data); |
|
|
|
typedef void (*fuse_interrupt_func_t)(fuse_req_t req, void *data); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Register/unregister callback for an interrupt |
|
|
|
* |
|
|
|
* If an interrupt has already happened, then the callback function is |
|
|
@ -1500,25 +1499,25 @@ extern "C" { |
|
|
|
* @param func the callback function or NULL for unregister |
|
|
|
* @param data user data passed to the callback function |
|
|
|
*/ |
|
|
|
void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func, |
|
|
|
void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func, |
|
|
|
void *data); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Check if a request has already been interrupted |
|
|
|
* |
|
|
|
* @param req request handle |
|
|
|
* @return 1 if the request has been interrupted, 0 otherwise |
|
|
|
*/ |
|
|
|
int fuse_req_interrupted(fuse_req_t req); |
|
|
|
int fuse_req_interrupted(fuse_req_t req); |
|
|
|
|
|
|
|
/* ----------------------------------------------------------- * |
|
|
|
/* ----------------------------------------------------------- * |
|
|
|
* Filesystem setup * |
|
|
|
* ----------------------------------------------------------- */ |
|
|
|
|
|
|
|
/* Deprecated, don't use */ |
|
|
|
int fuse_lowlevel_is_lib_option(const char *opt); |
|
|
|
/* Deprecated, don't use */ |
|
|
|
int fuse_lowlevel_is_lib_option(const char *opt); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Create a low level session |
|
|
|
* |
|
|
|
* @param args argument vector |
|
|
@ -1527,21 +1526,21 @@ extern "C" { |
|
|
|
* @param userdata user data |
|
|
|
* @return the created session object, or NULL on failure |
|
|
|
*/ |
|
|
|
struct fuse_session *fuse_lowlevel_new(struct fuse_args *args, |
|
|
|
struct fuse_session *fuse_lowlevel_new(struct fuse_args *args, |
|
|
|
const struct fuse_lowlevel_ops *op, |
|
|
|
size_t op_size, void *userdata); |
|
|
|
|
|
|
|
/* ----------------------------------------------------------- * |
|
|
|
/* ----------------------------------------------------------- * |
|
|
|
* Session interface * |
|
|
|
* ----------------------------------------------------------- */ |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Session operations |
|
|
|
* |
|
|
|
* This is used in session creation |
|
|
|
*/ |
|
|
|
struct fuse_session_ops |
|
|
|
{ |
|
|
|
struct fuse_session_ops |
|
|
|
{ |
|
|
|
/** |
|
|
|
* Hook to process a request (mandatory) |
|
|
|
* |
|
|
@ -1575,18 +1574,18 @@ extern "C" { |
|
|
|
* @param data user data passed to fuse_session_new() |
|
|
|
*/ |
|
|
|
void (*destroy) (void *data); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Create a new session |
|
|
|
* |
|
|
|
* @param op session operations |
|
|
|
* @param data user data |
|
|
|
* @return new session object, or NULL on failure |
|
|
|
*/ |
|
|
|
struct fuse_session *fuse_session_new(struct fuse_session_ops *op, void *data); |
|
|
|
struct fuse_session *fuse_session_new(struct fuse_session_ops *op, void *data); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Assign a channel to a session |
|
|
|
* |
|
|
|
* Note: currently only a single channel may be assigned. This may |
|
|
@ -1597,18 +1596,18 @@ extern "C" { |
|
|
|
* @param se the session |
|
|
|
* @param ch the channel |
|
|
|
*/ |
|
|
|
void fuse_session_add_chan(struct fuse_session *se, struct fuse_chan *ch); |
|
|
|
void fuse_session_add_chan(struct fuse_session *se, 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 |
|
|
|
* |
|
|
|
* @param ch the channel to remove |
|
|
|
*/ |
|
|
|
void fuse_session_remove_chan(struct fuse_chan *ch); |
|
|
|
void fuse_session_remove_chan(struct fuse_chan *ch); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Iterate over the channels assigned to a session |
|
|
|
* |
|
|
|
* The iterating function needs to start with a NULL channel, and |
|
|
@ -1619,10 +1618,10 @@ extern "C" { |
|
|
|
* @param ch the previous channel, or NULL |
|
|
|
* @return the next channel, or NULL if no more channels exist |
|
|
|
*/ |
|
|
|
struct fuse_chan *fuse_session_next_chan(struct fuse_session *se, |
|
|
|
struct fuse_chan *fuse_session_next_chan(struct fuse_session *se, |
|
|
|
struct fuse_chan *ch); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Process a raw request |
|
|
|
* |
|
|
|
* @param se the session |
|
|
@ -1630,10 +1629,10 @@ extern "C" { |
|
|
|
* @param len request length |
|
|
|
* @param ch channel on which the request was received |
|
|
|
*/ |
|
|
|
void fuse_session_process(struct fuse_session *se, const char *buf, size_t len, |
|
|
|
void fuse_session_process(struct fuse_session *se, const char *buf, size_t len, |
|
|
|
struct fuse_chan *ch); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Process a raw request supplied in a generic buffer |
|
|
|
* |
|
|
|
* This is a more generic version of fuse_session_process(). The |
|
|
@ -1643,10 +1642,10 @@ extern "C" { |
|
|
|
* @param buf the fuse_buf containing the request |
|
|
|
* @param ch channel on which the request was received |
|
|
|
*/ |
|
|
|
void fuse_session_process_buf(struct fuse_session *se, |
|
|
|
void fuse_session_process_buf(struct fuse_session *se, |
|
|
|
const struct fuse_buf *buf, struct fuse_chan *ch); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Receive a raw request supplied in a generic buffer |
|
|
|
* |
|
|
|
* This is a more generic version of fuse_chan_recv(). The fuse_buf |
|
|
@ -1658,65 +1657,65 @@ extern "C" { |
|
|
|
* @param chp pointer to the channel |
|
|
|
* @return the actual size of the raw request, or -errno on error |
|
|
|
*/ |
|
|
|
int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf, |
|
|
|
int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf, |
|
|
|
struct fuse_chan **chp); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Destroy a session |
|
|
|
* |
|
|
|
* @param se the session |
|
|
|
*/ |
|
|
|
void fuse_session_destroy(struct fuse_session *se); |
|
|
|
void fuse_session_destroy(struct fuse_session *se); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Exit a session |
|
|
|
* |
|
|
|
* @param se the session |
|
|
|
*/ |
|
|
|
void fuse_session_exit(struct fuse_session *se); |
|
|
|
void fuse_session_exit(struct fuse_session *se); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reset the exited status of a session |
|
|
|
* |
|
|
|
* @param se the session |
|
|
|
*/ |
|
|
|
void fuse_session_reset(struct fuse_session *se); |
|
|
|
void fuse_session_reset(struct fuse_session *se); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Query the exited status of a session |
|
|
|
* |
|
|
|
* @param se the session |
|
|
|
* @return 1 if exited, 0 if not exited |
|
|
|
*/ |
|
|
|
int fuse_session_exited(struct fuse_session *se); |
|
|
|
int fuse_session_exited(struct fuse_session *se); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Get the user data provided to the session |
|
|
|
* |
|
|
|
* @param se the session |
|
|
|
* @return the user data |
|
|
|
*/ |
|
|
|
void *fuse_session_data(struct fuse_session *se); |
|
|
|
void *fuse_session_data(struct fuse_session *se); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Enter a multi-threaded event loop |
|
|
|
* |
|
|
|
* @param se the session |
|
|
|
* @return 0 on success, -1 on error |
|
|
|
*/ |
|
|
|
int fuse_session_loop_mt(struct fuse_session *se, const int threads); |
|
|
|
int fuse_session_loop_mt(struct fuse_session *se, const int threads); |
|
|
|
|
|
|
|
/* ----------------------------------------------------------- * |
|
|
|
/* ----------------------------------------------------------- * |
|
|
|
* Channel interface * |
|
|
|
* ----------------------------------------------------------- */ |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Channel operations |
|
|
|
* |
|
|
|
* This is used in channel creation |
|
|
|
*/ |
|
|
|
struct fuse_chan_ops |
|
|
|
{ |
|
|
|
struct fuse_chan_ops |
|
|
|
{ |
|
|
|
/** |
|
|
|
* Hook for receiving a raw request |
|
|
|
* |
|
|
@ -1747,9 +1746,9 @@ extern "C" { |
|
|
|
* @param ch the channel |
|
|
|
*/ |
|
|
|
void (*destroy)(struct fuse_chan *ch); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Create a new channel |
|
|
|
* |
|
|
|
* @param op channel operations |
|
|
@ -1758,42 +1757,42 @@ extern "C" { |
|
|
|
* @param data user data |
|
|
|
* @return the new channel object, or NULL on failure |
|
|
|
*/ |
|
|
|
struct fuse_chan *fuse_chan_new(struct fuse_chan_ops *op, int fd, |
|
|
|
struct fuse_chan *fuse_chan_new(struct fuse_chan_ops *op, int fd, |
|
|
|
size_t bufsize, void *data); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Query the file descriptor of the channel |
|
|
|
* |
|
|
|
* @param ch the channel |
|
|
|
* @return the file descriptor passed to fuse_chan_new() |
|
|
|
*/ |
|
|
|
int fuse_chan_fd(struct fuse_chan *ch); |
|
|
|
int fuse_chan_fd(struct fuse_chan *ch); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Query the minimal receive buffer size |
|
|
|
* |
|
|
|
* @param ch the channel |
|
|
|
* @return the buffer size passed to fuse_chan_new() |
|
|
|
*/ |
|
|
|
size_t fuse_chan_bufsize(struct fuse_chan *ch); |
|
|
|
size_t fuse_chan_bufsize(struct fuse_chan *ch); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Query the user data |
|
|
|
* |
|
|
|
* @param ch the channel |
|
|
|
* @return the user data passed to fuse_chan_new() |
|
|
|
*/ |
|
|
|
void *fuse_chan_data(struct fuse_chan *ch); |
|
|
|
void *fuse_chan_data(struct fuse_chan *ch); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Query the session to which this channel is assigned |
|
|
|
* |
|
|
|
* @param ch the channel |
|
|
|
* @return the session, or NULL if the channel is not assigned |
|
|
|
*/ |
|
|
|
struct fuse_session *fuse_chan_session(struct fuse_chan *ch); |
|
|
|
struct fuse_session *fuse_chan_session(struct fuse_chan *ch); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Receive a raw request |
|
|
|
* |
|
|
|
* A return value of -ENODEV means, that the filesystem was unmounted |
|
|
@ -1803,9 +1802,9 @@ extern "C" { |
|
|
|
* @param size the size of the buffer |
|
|
|
* @return the actual size of the raw request, or -errno on error |
|
|
|
*/ |
|
|
|
int fuse_chan_recv(struct fuse_chan **ch, char *buf, size_t size); |
|
|
|
int fuse_chan_recv(struct fuse_chan **ch, char *buf, size_t size); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Send a raw reply |
|
|
|
* |
|
|
|
* A return value of -ENOENT means, that the request was |
|
|
@ -1816,18 +1815,16 @@ extern "C" { |
|
|
|
* @param count the number of blocks in vector |
|
|
|
* @return zero on success, -errno on failure |
|
|
|
*/ |
|
|
|
int fuse_chan_send(struct fuse_chan *ch, const struct iovec iov[], |
|
|
|
int fuse_chan_send(struct fuse_chan *ch, const struct iovec iov[], |
|
|
|
size_t count); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Destroy a channel |
|
|
|
* |
|
|
|
* @param ch the channel |
|
|
|
*/ |
|
|
|
void fuse_chan_destroy(struct fuse_chan *ch); |
|
|
|
void fuse_chan_destroy(struct fuse_chan *ch); |
|
|
|
|
|
|
|
#ifdef __cplusplus |
|
|
|
} |
|
|
|
#endif |
|
|
|
EXTERN_C_END |
|
|
|
|
|
|
|
#endif /* _FUSE_LOWLEVEL_H_ */ |