diff options
author | Miklos Szeredi <miklos@szeredi.hu> | 2008-12-05 10:55:36 +0000 |
---|---|---|
committer | Miklos Szeredi <miklos@szeredi.hu> | 2008-12-05 10:55:36 +0000 |
commit | ecfa5263ab5b19a58d53a7116fb079f3b956b918 (patch) | |
tree | a9f9dd2ec17e9185e4d515328b78e3b5e84938f2 /include | |
parent | cafdcb253e4c7ad6238198982425c004b487d2e6 (diff) |
* Implement ioctl support. On high level interface only
"restricted" ioctls are supported (which are defined with the
_IO(), _IOR(), _IOW() or _IOWR() macros). Unrestricted ioctls
will only be allwed to CUSE (Character Device in Userspace)
servers. Patch by Tejun Heo
Diffstat (limited to 'include')
-rw-r--r-- | include/fuse.h | 19 | ||||
-rw-r--r-- | include/fuse_common.h | 15 | ||||
-rw-r--r-- | include/fuse_kernel.h | 50 | ||||
-rw-r--r-- | include/fuse_lowlevel.h | 62 |
4 files changed, 133 insertions, 13 deletions
diff --git a/include/fuse.h b/include/fuse.h index 8d47bc5..2016ccc 100644 --- a/include/fuse.h +++ b/include/fuse.h @@ -31,6 +31,7 @@ #include <sys/types.h> #include <sys/stat.h> #include <sys/statvfs.h> +#include <sys/uio.h> #ifdef __cplusplus extern "C" { @@ -457,6 +458,22 @@ struct fuse_operations { * Reserved flags, don't set */ unsigned int flag_reserved : 31; + + /** + * Ioctl + * + * @flags will have FUSE_IOCTL_COMPAT set for 32bit ioctls in + * 64bit environment. The size and direction of @data is + * determined by _IOC_*() decoding of @cmd. For _IOC_NONE, + * @data will be NULL, for _IOC_WRITE @data is out area, for + * _IOC_READ in area and if both are set in/out area. In all + * non-NULL cases, the area is of _IOC_SIZE(@cmd) bytes. + * + * Introduced in version 2.9 + */ + int (*ioctl) (const char *, int cmd, void *arg, + struct fuse_file_info *, unsigned int flags, void *data); + }; /** Extra context that may be needed by some filesystems @@ -689,6 +706,8 @@ int fuse_fs_removexattr(struct fuse_fs *fs, const char *path, const char *name); int fuse_fs_bmap(struct fuse_fs *fs, const char *path, size_t blocksize, uint64_t *idx); +int fuse_fs_ioctl(struct fuse_fs *fs, const char *path, int cmd, void *arg, + struct fuse_file_info *fi, unsigned int flags, void *data); void fuse_fs_init(struct fuse_fs *fs, struct fuse_conn_info *conn); void fuse_fs_destroy(struct fuse_fs *fs); diff --git a/include/fuse_common.h b/include/fuse_common.h index 9bbc386..fb18b61 100644 --- a/include/fuse_common.h +++ b/include/fuse_common.h @@ -94,6 +94,21 @@ struct fuse_file_info { #define FUSE_CAP_BIG_WRITES (1 << 5) /** + * Ioctl flags + * + * FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine + * FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed + * FUSE_IOCTL_RETRY: retry with new iovecs + * + * FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs + */ +#define FUSE_IOCTL_COMPAT (1 << 0) +#define FUSE_IOCTL_UNRESTRICTED (1 << 1) +#define FUSE_IOCTL_RETRY (1 << 2) + +#define FUSE_IOCTL_MAX_IOV 256 + +/** * Connection information, passed to the ->init() method * * Some of the elements are read-write, these can be changed to diff --git a/include/fuse_kernel.h b/include/fuse_kernel.h index b37d969..eb28a35 100644 --- a/include/fuse_kernel.h +++ b/include/fuse_kernel.h @@ -1,6 +1,6 @@ /* This file defines the kernel interface of FUSE - Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> + Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> This program can be distributed under the terms of the GNU GPL. See the file COPYING. @@ -46,36 +46,28 @@ * * 7.10 * - add nonseekable open flag + * + * 7.11 + * - add IOCTL message */ #ifndef _LINUX_FUSE_H #define _LINUX_FUSE_H -#ifndef linux #include <sys/types.h> #define __u64 uint64_t #define __u32 uint32_t #define __s32 int32_t -#else -#include <asm/types.h> -#include <linux/major.h> -#endif /** Version number of this interface */ #define FUSE_KERNEL_VERSION 7 /** Minor version number of this interface */ -#define FUSE_KERNEL_MINOR_VERSION 10 +#define FUSE_KERNEL_MINOR_VERSION 11 /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 -/** The major number of the fuse character device */ -#define FUSE_MAJOR MISC_MAJOR - -/** The minor number of the fuse character device */ -#define FUSE_MINOR 229 - /* Make sure all structures are padded to 64bit boundary, so 32bit userspace works under 64bit kernels */ @@ -184,6 +176,21 @@ struct fuse_file_lock { */ #define FUSE_READ_LOCKOWNER (1 << 1) +/** + * Ioctl flags + * + * FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine + * FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed + * FUSE_IOCTL_RETRY: retry with new iovecs + * + * FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs + */ +#define FUSE_IOCTL_COMPAT (1 << 0) +#define FUSE_IOCTL_UNRESTRICTED (1 << 1) +#define FUSE_IOCTL_RETRY (1 << 2) + +#define FUSE_IOCTL_MAX_IOV 256 + enum fuse_opcode { FUSE_LOOKUP = 1, FUSE_FORGET = 2, /* no reply */ @@ -221,6 +228,7 @@ enum fuse_opcode { FUSE_INTERRUPT = 36, FUSE_BMAP = 37, FUSE_DESTROY = 38, + FUSE_IOCTL = 39, }; /* The read buffer is required to be at least 8k, but may be much larger */ @@ -421,6 +429,22 @@ struct fuse_bmap_out { __u64 block; }; +struct fuse_ioctl_in { + __u64 fh; + __u32 flags; + __u32 cmd; + __u64 arg; + __u32 in_size; + __u32 out_size; +}; + +struct fuse_ioctl_out { + __s32 result; + __u32 flags; + __u32 in_iovs; + __u32 out_iovs; +}; + struct fuse_in_header { __u32 len; __u32 opcode; diff --git a/include/fuse_lowlevel.h b/include/fuse_lowlevel.h index 9330548..e17274f 100644 --- a/include/fuse_lowlevel.h +++ b/include/fuse_lowlevel.h @@ -807,6 +807,36 @@ struct fuse_lowlevel_ops { */ void (*bmap) (fuse_req_t req, fuse_ino_t ino, size_t blocksize, uint64_t idx); + + /** + * 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 *@flagsp. For + * restricted ioctls, kernel prepares in/out data area + * according to the information encoded in @cmd. + * + * Introduced in version 2.9 + * + * Valid replies: + * fuse_reply_ioctl_retry + * fuse_reply_ioctl + * 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 flagsp io/out parameter for FUSE_IOCTL_* flags + * @param in_buf data fetched from the caller + * @param in_size number of fetched bytes + * @param out_size maximum size of output data + */ + void (*ioctl) (fuse_req_t req, fuse_ino_t ino, int cmd, void *arg, + struct fuse_file_info *fi, unsigned *flagsp, + const void *in_buf, size_t in_bufsz, size_t out_bufszp); }; /** @@ -1022,6 +1052,38 @@ size_t fuse_add_direntry(fuse_req_t req, char *buf, size_t bufsize, const char *name, const struct stat *stbuf, off_t off); +/** + * 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 + * + * @param req request handle + * @param in_iov iovec specifying data to fetch from the caller + * @param in_count number of entries in @in_iov + * @param out_iov iovec specifying addresses to write output to + * @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, + const struct iovec *in_iov, size_t in_count, + const struct iovec *out_iov, size_t out_count); + +/** + * Reply to finish ioctl + * + * Possible requests: + * ioctl + * + * @param req request handle + * @param result result to be passed to the caller + * @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, size_t size); + /* ----------------------------------------------------------- * * Utility functions * * ----------------------------------------------------------- */ |