Commit 05ba1f08 authored by Anatol Pomozov's avatar Anatol Pomozov Committed by Miklos Szeredi

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: default avatarAnatol Pomozov <anatol.pomozov@gmail.com>
Signed-off-by: default avatarMiklos Szeredi <mszeredi@suse.cz>
parent e2690695
...@@ -2171,6 +2171,37 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, ...@@ -2171,6 +2171,37 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
return ret; return ret;
} }
long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
loff_t length)
{
struct fuse_file *ff = file->private_data;
struct fuse_conn *fc = ff->fc;
struct fuse_req *req;
struct fuse_fallocate_in inarg = {
.fh = ff->fh,
.offset = offset,
.length = length,
.mode = mode
};
int err;
req = fuse_get_req(fc);
if (IS_ERR(req))
return PTR_ERR(req);
req->in.h.opcode = FUSE_FALLOCATE;
req->in.h.nodeid = ff->nodeid;
req->in.numargs = 1;
req->in.args[0].size = sizeof(inarg);
req->in.args[0].value = &inarg;
fuse_request_send(fc, req);
err = req->out.h.error;
fuse_put_request(fc, req);
return err;
}
EXPORT_SYMBOL_GPL(fuse_file_fallocate);
static const struct file_operations fuse_file_operations = { static const struct file_operations fuse_file_operations = {
.llseek = fuse_file_llseek, .llseek = fuse_file_llseek,
.read = do_sync_read, .read = do_sync_read,
...@@ -2188,6 +2219,7 @@ static const struct file_operations fuse_file_operations = { ...@@ -2188,6 +2219,7 @@ static const struct file_operations fuse_file_operations = {
.unlocked_ioctl = fuse_file_ioctl, .unlocked_ioctl = fuse_file_ioctl,
.compat_ioctl = fuse_file_compat_ioctl, .compat_ioctl = fuse_file_compat_ioctl,
.poll = fuse_file_poll, .poll = fuse_file_poll,
.fallocate = fuse_file_fallocate,
}; };
static const struct file_operations fuse_direct_io_file_operations = { static const struct file_operations fuse_direct_io_file_operations = {
...@@ -2204,6 +2236,7 @@ static const struct file_operations fuse_direct_io_file_operations = { ...@@ -2204,6 +2236,7 @@ static const struct file_operations fuse_direct_io_file_operations = {
.unlocked_ioctl = fuse_file_ioctl, .unlocked_ioctl = fuse_file_ioctl,
.compat_ioctl = fuse_file_compat_ioctl, .compat_ioctl = fuse_file_compat_ioctl,
.poll = fuse_file_poll, .poll = fuse_file_poll,
.fallocate = fuse_file_fallocate,
/* no splice_read */ /* no splice_read */
}; };
......
...@@ -54,6 +54,9 @@ ...@@ -54,6 +54,9 @@
* 7.18 * 7.18
* - add FUSE_IOCTL_DIR flag * - add FUSE_IOCTL_DIR flag
* - add FUSE_NOTIFY_DELETE * - add FUSE_NOTIFY_DELETE
*
* 7.19
* - add FUSE_FALLOCATE
*/ */
#ifndef _LINUX_FUSE_H #ifndef _LINUX_FUSE_H
...@@ -85,7 +88,7 @@ ...@@ -85,7 +88,7 @@
#define FUSE_KERNEL_VERSION 7 #define FUSE_KERNEL_VERSION 7
/** Minor version number of this interface */ /** Minor version number of this interface */
#define FUSE_KERNEL_MINOR_VERSION 18 #define FUSE_KERNEL_MINOR_VERSION 19
/** The node ID of the root inode */ /** The node ID of the root inode */
#define FUSE_ROOT_ID 1 #define FUSE_ROOT_ID 1
...@@ -278,6 +281,7 @@ enum fuse_opcode { ...@@ -278,6 +281,7 @@ enum fuse_opcode {
FUSE_POLL = 40, FUSE_POLL = 40,
FUSE_NOTIFY_REPLY = 41, FUSE_NOTIFY_REPLY = 41,
FUSE_BATCH_FORGET = 42, FUSE_BATCH_FORGET = 42,
FUSE_FALLOCATE = 43,
/* CUSE specific operations */ /* CUSE specific operations */
CUSE_INIT = 4096, CUSE_INIT = 4096,
...@@ -571,6 +575,14 @@ struct fuse_notify_poll_wakeup_out { ...@@ -571,6 +575,14 @@ struct fuse_notify_poll_wakeup_out {
__u64 kh; __u64 kh;
}; };
struct fuse_fallocate_in {
__u64 fh;
__u64 offset;
__u64 length;
__u32 mode;
__u32 padding;
};
struct fuse_in_header { struct fuse_in_header {
__u32 len; __u32 len;
__u32 opcode; __u32 opcode;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment