mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
e2690695ce
commit
05ba1f0823
|
@ -2171,6 +2171,37 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
|
|||
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 = {
|
||||
.llseek = fuse_file_llseek,
|
||||
.read = do_sync_read,
|
||||
|
@ -2188,6 +2219,7 @@ static const struct file_operations fuse_file_operations = {
|
|||
.unlocked_ioctl = fuse_file_ioctl,
|
||||
.compat_ioctl = fuse_file_compat_ioctl,
|
||||
.poll = fuse_file_poll,
|
||||
.fallocate = fuse_file_fallocate,
|
||||
};
|
||||
|
||||
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,
|
||||
.compat_ioctl = fuse_file_compat_ioctl,
|
||||
.poll = fuse_file_poll,
|
||||
.fallocate = fuse_file_fallocate,
|
||||
/* no splice_read */
|
||||
};
|
||||
|
||||
|
|
|
@ -54,6 +54,9 @@
|
|||
* 7.18
|
||||
* - add FUSE_IOCTL_DIR flag
|
||||
* - add FUSE_NOTIFY_DELETE
|
||||
*
|
||||
* 7.19
|
||||
* - add FUSE_FALLOCATE
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_FUSE_H
|
||||
|
@ -85,7 +88,7 @@
|
|||
#define FUSE_KERNEL_VERSION 7
|
||||
|
||||
/** 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 */
|
||||
#define FUSE_ROOT_ID 1
|
||||
|
@ -278,6 +281,7 @@ enum fuse_opcode {
|
|||
FUSE_POLL = 40,
|
||||
FUSE_NOTIFY_REPLY = 41,
|
||||
FUSE_BATCH_FORGET = 42,
|
||||
FUSE_FALLOCATE = 43,
|
||||
|
||||
/* CUSE specific operations */
|
||||
CUSE_INIT = 4096,
|
||||
|
@ -571,6 +575,14 @@ struct fuse_notify_poll_wakeup_out {
|
|||
__u64 kh;
|
||||
};
|
||||
|
||||
struct fuse_fallocate_in {
|
||||
__u64 fh;
|
||||
__u64 offset;
|
||||
__u64 length;
|
||||
__u32 mode;
|
||||
__u32 padding;
|
||||
};
|
||||
|
||||
struct fuse_in_header {
|
||||
__u32 len;
|
||||
__u32 opcode;
|
||||
|
|
Loading…
Reference in New Issue