diff options
author | Tejun Heo <tj@kernel.org> | 2008-11-26 06:03:55 -0500 |
---|---|---|
committer | Miklos Szeredi <miklos@szeredi.hu> | 2008-11-26 06:03:55 -0500 |
commit | 59efec7b903987dcb60b9ebc85c7acd4443a11a1 (patch) | |
tree | 1287e817201fcb4008917b2bffd378c36540622b /include | |
parent | e9bb09dd6c5b8ec6a971ed6251df5eba3a4c8d3c (diff) |
fuse: implement ioctl support
Generic ioctl support is tricky to implement because only the ioctl
implementation itself knows which memory regions need to be read
and/or written. To support this, fuse client can request retry of
ioctl specifying memory regions to read and write. Deep copying
(nested pointers) can be implemented by retrying multiple times
resolving one depth of dereference at a time.
For security and cleanliness considerations, ioctl implementation has
restricted mode where the kernel determines data transfer directions
and sizes using the _IOC_*() macros on the ioctl command. In this
mode, retry is not allowed.
For all FUSE servers, restricted mode is enforced. Unrestricted ioctl
will be used by CUSE.
Plese read the comment on top of fs/fuse/file.c::fuse_file_do_ioctl()
for more information.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/fuse.h | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/include/linux/fuse.h b/include/linux/fuse.h index 7caa473306e4..608e300ae883 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h | |||
@@ -148,6 +148,21 @@ struct fuse_file_lock { | |||
148 | */ | 148 | */ |
149 | #define FUSE_READ_LOCKOWNER (1 << 1) | 149 | #define FUSE_READ_LOCKOWNER (1 << 1) |
150 | 150 | ||
151 | /** | ||
152 | * Ioctl flags | ||
153 | * | ||
154 | * FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine | ||
155 | * FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed | ||
156 | * FUSE_IOCTL_RETRY: retry with new iovecs | ||
157 | * | ||
158 | * FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs | ||
159 | */ | ||
160 | #define FUSE_IOCTL_COMPAT (1 << 0) | ||
161 | #define FUSE_IOCTL_UNRESTRICTED (1 << 1) | ||
162 | #define FUSE_IOCTL_RETRY (1 << 2) | ||
163 | |||
164 | #define FUSE_IOCTL_MAX_IOV 256 | ||
165 | |||
151 | enum fuse_opcode { | 166 | enum fuse_opcode { |
152 | FUSE_LOOKUP = 1, | 167 | FUSE_LOOKUP = 1, |
153 | FUSE_FORGET = 2, /* no reply */ | 168 | FUSE_FORGET = 2, /* no reply */ |
@@ -185,6 +200,7 @@ enum fuse_opcode { | |||
185 | FUSE_INTERRUPT = 36, | 200 | FUSE_INTERRUPT = 36, |
186 | FUSE_BMAP = 37, | 201 | FUSE_BMAP = 37, |
187 | FUSE_DESTROY = 38, | 202 | FUSE_DESTROY = 38, |
203 | FUSE_IOCTL = 39, | ||
188 | }; | 204 | }; |
189 | 205 | ||
190 | /* The read buffer is required to be at least 8k, but may be much larger */ | 206 | /* The read buffer is required to be at least 8k, but may be much larger */ |
@@ -385,6 +401,22 @@ struct fuse_bmap_out { | |||
385 | __u64 block; | 401 | __u64 block; |
386 | }; | 402 | }; |
387 | 403 | ||
404 | struct fuse_ioctl_in { | ||
405 | __u64 fh; | ||
406 | __u32 flags; | ||
407 | __u32 cmd; | ||
408 | __u64 arg; | ||
409 | __u32 in_size; | ||
410 | __u32 out_size; | ||
411 | }; | ||
412 | |||
413 | struct fuse_ioctl_out { | ||
414 | __s32 result; | ||
415 | __u32 flags; | ||
416 | __u32 in_iovs; | ||
417 | __u32 out_iovs; | ||
418 | }; | ||
419 | |||
388 | struct fuse_in_header { | 420 | struct fuse_in_header { |
389 | __u32 len; | 421 | __u32 len; |
390 | __u32 opcode; | 422 | __u32 opcode; |