Commit 55752a3a authored by Miklos Szeredi's avatar Miklos Szeredi
Browse files

fuse: multiplex cached/direct_io file operations



This is cleanup, as well as allowing switching between I/O modes while the
file is open in the future.

Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent d4136d60
Loading
Loading
Loading
Loading
+34 −37
Original line number Original line Diff line number Diff line
@@ -19,8 +19,6 @@
#include <linux/falloc.h>
#include <linux/falloc.h>
#include <linux/uio.h>
#include <linux/uio.h>


static const struct file_operations fuse_direct_io_file_operations;

static int fuse_send_open(struct fuse_conn *fc, u64 nodeid, struct file *file,
static int fuse_send_open(struct fuse_conn *fc, u64 nodeid, struct file *file,
			  int opcode, struct fuse_open_out *outargp)
			  int opcode, struct fuse_open_out *outargp)
{
{
@@ -174,8 +172,6 @@ void fuse_finish_open(struct inode *inode, struct file *file)
	struct fuse_file *ff = file->private_data;
	struct fuse_file *ff = file->private_data;
	struct fuse_conn *fc = get_fuse_conn(inode);
	struct fuse_conn *fc = get_fuse_conn(inode);


	if (ff->open_flags & FOPEN_DIRECT_IO)
		file->f_op = &fuse_direct_io_file_operations;
	if (!(ff->open_flags & FOPEN_KEEP_CACHE))
	if (!(ff->open_flags & FOPEN_KEEP_CACHE))
		invalidate_inode_pages2(inode->i_mapping);
		invalidate_inode_pages2(inode->i_mapping);
	if (ff->open_flags & FOPEN_NONSEEKABLE)
	if (ff->open_flags & FOPEN_NONSEEKABLE)
@@ -929,7 +925,7 @@ out:
	return err;
	return err;
}
}


static ssize_t fuse_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
static ssize_t fuse_cache_read_iter(struct kiocb *iocb, struct iov_iter *to)
{
{
	struct inode *inode = iocb->ki_filp->f_mapping->host;
	struct inode *inode = iocb->ki_filp->f_mapping->host;
	struct fuse_conn *fc = get_fuse_conn(inode);
	struct fuse_conn *fc = get_fuse_conn(inode);
@@ -1183,7 +1179,7 @@ static ssize_t fuse_perform_write(struct kiocb *iocb,
	return res > 0 ? res : err;
	return res > 0 ? res : err;
}
}


static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
static ssize_t fuse_cache_write_iter(struct kiocb *iocb, struct iov_iter *from)
{
{
	struct file *file = iocb->ki_filp;
	struct file *file = iocb->ki_filp;
	struct address_space *mapping = file->f_mapping;
	struct address_space *mapping = file->f_mapping;
@@ -1486,6 +1482,26 @@ static ssize_t fuse_direct_write_iter(struct kiocb *iocb, struct iov_iter *from)
	return res;
	return res;
}
}


static ssize_t fuse_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
{
	struct fuse_file *ff = iocb->ki_filp->private_data;

	if (!(ff->open_flags & FOPEN_DIRECT_IO))
		return fuse_cache_read_iter(iocb, to);
	else
		return fuse_direct_read_iter(iocb, to);
}

static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
{
	struct fuse_file *ff = iocb->ki_filp->private_data;

	if (!(ff->open_flags & FOPEN_DIRECT_IO))
		return fuse_cache_write_iter(iocb, from);
	else
		return fuse_direct_write_iter(iocb, from);
}

static void fuse_writepage_free(struct fuse_conn *fc, struct fuse_req *req)
static void fuse_writepage_free(struct fuse_conn *fc, struct fuse_req *req)
{
{
	int i;
	int i;
@@ -2129,16 +2145,9 @@ static const struct vm_operations_struct fuse_file_vm_ops = {


static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma)
static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma)
{
{
	if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE))
	struct fuse_file *ff = file->private_data;
		fuse_link_write_file(file);

	file_accessed(file);
	vma->vm_ops = &fuse_file_vm_ops;
	return 0;
}


static int fuse_direct_mmap(struct file *file, struct vm_area_struct *vma)
	if (ff->open_flags & FOPEN_DIRECT_IO) {
{
		/* Can't provide the coherency needed for MAP_SHARED */
		/* Can't provide the coherency needed for MAP_SHARED */
		if (vma->vm_flags & VM_MAYSHARE)
		if (vma->vm_flags & VM_MAYSHARE)
			return -ENODEV;
			return -ENODEV;
@@ -2148,6 +2157,14 @@ static int fuse_direct_mmap(struct file *file, struct vm_area_struct *vma)
		return generic_file_mmap(file, vma);
		return generic_file_mmap(file, vma);
	}
	}


	if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE))
		fuse_link_write_file(file);

	file_accessed(file);
	vma->vm_ops = &fuse_file_vm_ops;
	return 0;
}

static int convert_fuse_file_lock(struct fuse_conn *fc,
static int convert_fuse_file_lock(struct fuse_conn *fc,
				  const struct fuse_file_lock *ffl,
				  const struct fuse_file_lock *ffl,
				  struct file_lock *fl)
				  struct file_lock *fl)
@@ -3164,26 +3181,6 @@ static const struct file_operations fuse_file_operations = {
	.copy_file_range = fuse_copy_file_range,
	.copy_file_range = fuse_copy_file_range,
};
};


static const struct file_operations fuse_direct_io_file_operations = {
	.llseek		= fuse_file_llseek,
	.read_iter	= fuse_direct_read_iter,
	.write_iter	= fuse_direct_write_iter,
	.mmap		= fuse_direct_mmap,
	.open		= fuse_open,
	.flush		= fuse_flush,
	.release	= fuse_release,
	.fsync		= fuse_fsync,
	.lock		= fuse_file_lock,
	.flock		= fuse_file_flock,
	.splice_read	= generic_file_splice_read,
	.splice_write	= iter_file_splice_write,
	.unlocked_ioctl	= fuse_file_ioctl,
	.compat_ioctl	= fuse_file_compat_ioctl,
	.poll		= fuse_file_poll,
	.fallocate	= fuse_file_fallocate,
	.copy_file_range = fuse_copy_file_range,
};

static const struct address_space_operations fuse_file_aops  = {
static const struct address_space_operations fuse_file_aops  = {
	.readpage	= fuse_readpage,
	.readpage	= fuse_readpage,
	.writepage	= fuse_writepage,
	.writepage	= fuse_writepage,