aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnatol Pomozov <anatol.pomozov@gmail.com>2012-04-22 21:45:24 -0400
committerMiklos Szeredi <mszeredi@suse.cz>2012-04-25 06:25:05 -0400
commit05ba1f0823004e947748523782e9c2f07f3bff0d (patch)
tree3ec44b97f0725b0b9045152c31802a66aa62aec2
parente2690695ce5085677b84fbf2e38d2ed57cad39cd (diff)
fuse: add FALLOCATE operation
fallocate filesystem operation preallocates media space for the given file. If fallocate returns success then any subsequent write to the given range never fails with 'not enough space' error. Signed-off-by: Anatol Pomozov <anatol.pomozov@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
-rw-r--r--fs/fuse/file.c33
-rw-r--r--include/linux/fuse.h14
2 files changed, 46 insertions, 1 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 504e61b7fd75..e3fee88831d4 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -2171,6 +2171,37 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
2171 return ret; 2171 return ret;
2172} 2172}
2173 2173
2174long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
2175 loff_t length)
2176{
2177 struct fuse_file *ff = file->private_data;
2178 struct fuse_conn *fc = ff->fc;
2179 struct fuse_req *req;
2180 struct fuse_fallocate_in inarg = {
2181 .fh = ff->fh,
2182 .offset = offset,
2183 .length = length,
2184 .mode = mode
2185 };
2186 int err;
2187
2188 req = fuse_get_req(fc);
2189 if (IS_ERR(req))
2190 return PTR_ERR(req);
2191
2192 req->in.h.opcode = FUSE_FALLOCATE;
2193 req->in.h.nodeid = ff->nodeid;
2194 req->in.numargs = 1;
2195 req->in.args[0].size = sizeof(inarg);
2196 req->in.args[0].value = &inarg;
2197 fuse_request_send(fc, req);
2198 err = req->out.h.error;
2199 fuse_put_request(fc, req);
2200
2201 return err;
2202}
2203EXPORT_SYMBOL_GPL(fuse_file_fallocate);
2204
2174static const struct file_operations fuse_file_operations = { 2205static const struct file_operations fuse_file_operations = {
2175 .llseek = fuse_file_llseek, 2206 .llseek = fuse_file_llseek,
2176 .read = do_sync_read, 2207 .read = do_sync_read,
@@ -2188,6 +2219,7 @@ static const struct file_operations fuse_file_operations = {
2188 .unlocked_ioctl = fuse_file_ioctl, 2219 .unlocked_ioctl = fuse_file_ioctl,
2189 .compat_ioctl = fuse_file_compat_ioctl, 2220 .compat_ioctl = fuse_file_compat_ioctl,
2190 .poll = fuse_file_poll, 2221 .poll = fuse_file_poll,
2222 .fallocate = fuse_file_fallocate,
2191}; 2223};
2192 2224
2193static const struct file_operations fuse_direct_io_file_operations = { 2225static const struct file_operations fuse_direct_io_file_operations = {
@@ -2204,6 +2236,7 @@ static const struct file_operations fuse_direct_io_file_operations = {
2204 .unlocked_ioctl = fuse_file_ioctl, 2236 .unlocked_ioctl = fuse_file_ioctl,
2205 .compat_ioctl = fuse_file_compat_ioctl, 2237 .compat_ioctl = fuse_file_compat_ioctl,
2206 .poll = fuse_file_poll, 2238 .poll = fuse_file_poll,
2239 .fallocate = fuse_file_fallocate,
2207 /* no splice_read */ 2240 /* no splice_read */
2208}; 2241};
2209 2242
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index 8f2ab8fef929..9303348965fb 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -54,6 +54,9 @@
54 * 7.18 54 * 7.18
55 * - add FUSE_IOCTL_DIR flag 55 * - add FUSE_IOCTL_DIR flag
56 * - add FUSE_NOTIFY_DELETE 56 * - add FUSE_NOTIFY_DELETE
57 *
58 * 7.19
59 * - add FUSE_FALLOCATE
57 */ 60 */
58 61
59#ifndef _LINUX_FUSE_H 62#ifndef _LINUX_FUSE_H
@@ -85,7 +88,7 @@
85#define FUSE_KERNEL_VERSION 7 88#define FUSE_KERNEL_VERSION 7
86 89
87/** Minor version number of this interface */ 90/** Minor version number of this interface */
88#define FUSE_KERNEL_MINOR_VERSION 18 91#define FUSE_KERNEL_MINOR_VERSION 19
89 92
90/** The node ID of the root inode */ 93/** The node ID of the root inode */
91#define FUSE_ROOT_ID 1 94#define FUSE_ROOT_ID 1
@@ -278,6 +281,7 @@ enum fuse_opcode {
278 FUSE_POLL = 40, 281 FUSE_POLL = 40,
279 FUSE_NOTIFY_REPLY = 41, 282 FUSE_NOTIFY_REPLY = 41,
280 FUSE_BATCH_FORGET = 42, 283 FUSE_BATCH_FORGET = 42,
284 FUSE_FALLOCATE = 43,
281 285
282 /* CUSE specific operations */ 286 /* CUSE specific operations */
283 CUSE_INIT = 4096, 287 CUSE_INIT = 4096,
@@ -571,6 +575,14 @@ struct fuse_notify_poll_wakeup_out {
571 __u64 kh; 575 __u64 kh;
572}; 576};
573 577
578struct fuse_fallocate_in {
579 __u64 fh;
580 __u64 offset;
581 __u64 length;
582 __u32 mode;
583 __u32 padding;
584};
585
574struct fuse_in_header { 586struct fuse_in_header {
575 __u32 len; 587 __u32 len;
576 __u32 opcode; 588 __u32 opcode;