Commit 05ba1f0823004e947748523782e9c2f07f3bff0d

Authored by Anatol Pomozov
Committed by Miklos Szeredi
1 parent e2690695ce

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>

Showing 2 changed files with 46 additions and 1 deletions Side-by-side Diff

... ... @@ -2171,6 +2171,37 @@
2171 2171 return ret;
2172 2172 }
2173 2173  
  2174 +long 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 +}
  2203 +EXPORT_SYMBOL_GPL(fuse_file_fallocate);
  2204 +
2174 2205 static const struct file_operations fuse_file_operations = {
2175 2206 .llseek = fuse_file_llseek,
2176 2207 .read = do_sync_read,
... ... @@ -2188,6 +2219,7 @@
2188 2219 .unlocked_ioctl = fuse_file_ioctl,
2189 2220 .compat_ioctl = fuse_file_compat_ioctl,
2190 2221 .poll = fuse_file_poll,
  2222 + .fallocate = fuse_file_fallocate,
2191 2223 };
2192 2224  
2193 2225 static const struct file_operations fuse_direct_io_file_operations = {
... ... @@ -2204,6 +2236,7 @@
2204 2236 .unlocked_ioctl = fuse_file_ioctl,
2205 2237 .compat_ioctl = fuse_file_compat_ioctl,
2206 2238 .poll = fuse_file_poll,
  2239 + .fallocate = fuse_file_fallocate,
2207 2240 /* no splice_read */
2208 2241 };
2209 2242  
include/linux/fuse.h
... ... @@ -54,6 +54,9 @@
54 54 * 7.18
55 55 * - add FUSE_IOCTL_DIR flag
56 56 * - add FUSE_NOTIFY_DELETE
  57 + *
  58 + * 7.19
  59 + * - add FUSE_FALLOCATE
57 60 */
58 61  
59 62 #ifndef _LINUX_FUSE_H
... ... @@ -85,7 +88,7 @@
85 88 #define FUSE_KERNEL_VERSION 7
86 89  
87 90 /** Minor version number of this interface */
88   -#define FUSE_KERNEL_MINOR_VERSION 18
  91 +#define FUSE_KERNEL_MINOR_VERSION 19
89 92  
90 93 /** The node ID of the root inode */
91 94 #define FUSE_ROOT_ID 1
... ... @@ -278,6 +281,7 @@
278 281 FUSE_POLL = 40,
279 282 FUSE_NOTIFY_REPLY = 41,
280 283 FUSE_BATCH_FORGET = 42,
  284 + FUSE_FALLOCATE = 43,
281 285  
282 286 /* CUSE specific operations */
283 287 CUSE_INIT = 4096,
... ... @@ -569,6 +573,14 @@
569 573  
570 574 struct fuse_notify_poll_wakeup_out {
571 575 __u64 kh;
  576 +};
  577 +
  578 +struct fuse_fallocate_in {
  579 + __u64 fh;
  580 + __u64 offset;
  581 + __u64 length;
  582 + __u32 mode;
  583 + __u32 padding;
572 584 };
573 585  
574 586 struct fuse_in_header {