aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@redhat.com>2019-01-24 04:40:17 -0500
committerMiklos Szeredi <mszeredi@redhat.com>2019-02-13 07:15:15 -0500
commit55752a3aba1387887afa024a0732f8ae52fb0645 (patch)
tree2c1297d1783cfaa428d303c758e1f843050ee82b
parentd4136d60751a5f45f47f1c3a77f6e8bafa11be1f (diff)
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: Miklos Szeredi <mszeredi@redhat.com>
-rw-r--r--fs/fuse/file.c71
1 files changed, 34 insertions, 37 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index c86266d4eac3..e5dfc5e4b999 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -19,8 +19,6 @@
19#include <linux/falloc.h> 19#include <linux/falloc.h>
20#include <linux/uio.h> 20#include <linux/uio.h>
21 21
22static const struct file_operations fuse_direct_io_file_operations;
23
24static int fuse_send_open(struct fuse_conn *fc, u64 nodeid, struct file *file, 22static int fuse_send_open(struct fuse_conn *fc, u64 nodeid, struct file *file,
25 int opcode, struct fuse_open_out *outargp) 23 int opcode, struct fuse_open_out *outargp)
26{ 24{
@@ -174,8 +172,6 @@ void fuse_finish_open(struct inode *inode, struct file *file)
174 struct fuse_file *ff = file->private_data; 172 struct fuse_file *ff = file->private_data;
175 struct fuse_conn *fc = get_fuse_conn(inode); 173 struct fuse_conn *fc = get_fuse_conn(inode);
176 174
177 if (ff->open_flags & FOPEN_DIRECT_IO)
178 file->f_op = &fuse_direct_io_file_operations;
179 if (!(ff->open_flags & FOPEN_KEEP_CACHE)) 175 if (!(ff->open_flags & FOPEN_KEEP_CACHE))
180 invalidate_inode_pages2(inode->i_mapping); 176 invalidate_inode_pages2(inode->i_mapping);
181 if (ff->open_flags & FOPEN_NONSEEKABLE) 177 if (ff->open_flags & FOPEN_NONSEEKABLE)
@@ -929,7 +925,7 @@ out:
929 return err; 925 return err;
930} 926}
931 927
932static ssize_t fuse_file_read_iter(struct kiocb *iocb, struct iov_iter *to) 928static ssize_t fuse_cache_read_iter(struct kiocb *iocb, struct iov_iter *to)
933{ 929{
934 struct inode *inode = iocb->ki_filp->f_mapping->host; 930 struct inode *inode = iocb->ki_filp->f_mapping->host;
935 struct fuse_conn *fc = get_fuse_conn(inode); 931 struct fuse_conn *fc = get_fuse_conn(inode);
@@ -1183,7 +1179,7 @@ static ssize_t fuse_perform_write(struct kiocb *iocb,
1183 return res > 0 ? res : err; 1179 return res > 0 ? res : err;
1184} 1180}
1185 1181
1186static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from) 1182static ssize_t fuse_cache_write_iter(struct kiocb *iocb, struct iov_iter *from)
1187{ 1183{
1188 struct file *file = iocb->ki_filp; 1184 struct file *file = iocb->ki_filp;
1189 struct address_space *mapping = file->f_mapping; 1185 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)
1486 return res; 1482 return res;
1487} 1483}
1488 1484
1485static ssize_t fuse_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
1486{
1487 struct fuse_file *ff = iocb->ki_filp->private_data;
1488
1489 if (!(ff->open_flags & FOPEN_DIRECT_IO))
1490 return fuse_cache_read_iter(iocb, to);
1491 else
1492 return fuse_direct_read_iter(iocb, to);
1493}
1494
1495static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
1496{
1497 struct fuse_file *ff = iocb->ki_filp->private_data;
1498
1499 if (!(ff->open_flags & FOPEN_DIRECT_IO))
1500 return fuse_cache_write_iter(iocb, from);
1501 else
1502 return fuse_direct_write_iter(iocb, from);
1503}
1504
1489static void fuse_writepage_free(struct fuse_conn *fc, struct fuse_req *req) 1505static void fuse_writepage_free(struct fuse_conn *fc, struct fuse_req *req)
1490{ 1506{
1491 int i; 1507 int i;
@@ -2129,6 +2145,18 @@ static const struct vm_operations_struct fuse_file_vm_ops = {
2129 2145
2130static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma) 2146static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma)
2131{ 2147{
2148 struct fuse_file *ff = file->private_data;
2149
2150 if (ff->open_flags & FOPEN_DIRECT_IO) {
2151 /* Can't provide the coherency needed for MAP_SHARED */
2152 if (vma->vm_flags & VM_MAYSHARE)
2153 return -ENODEV;
2154
2155 invalidate_inode_pages2(file->f_mapping);
2156
2157 return generic_file_mmap(file, vma);
2158 }
2159
2132 if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) 2160 if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE))
2133 fuse_link_write_file(file); 2161 fuse_link_write_file(file);
2134 2162
@@ -2137,17 +2165,6 @@ static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma)
2137 return 0; 2165 return 0;
2138} 2166}
2139 2167
2140static int fuse_direct_mmap(struct file *file, struct vm_area_struct *vma)
2141{
2142 /* Can't provide the coherency needed for MAP_SHARED */
2143 if (vma->vm_flags & VM_MAYSHARE)
2144 return -ENODEV;
2145
2146 invalidate_inode_pages2(file->f_mapping);
2147
2148 return generic_file_mmap(file, vma);
2149}
2150
2151static int convert_fuse_file_lock(struct fuse_conn *fc, 2168static int convert_fuse_file_lock(struct fuse_conn *fc,
2152 const struct fuse_file_lock *ffl, 2169 const struct fuse_file_lock *ffl,
2153 struct file_lock *fl) 2170 struct file_lock *fl)
@@ -3164,26 +3181,6 @@ static const struct file_operations fuse_file_operations = {
3164 .copy_file_range = fuse_copy_file_range, 3181 .copy_file_range = fuse_copy_file_range,
3165}; 3182};
3166 3183
3167static const struct file_operations fuse_direct_io_file_operations = {
3168 .llseek = fuse_file_llseek,
3169 .read_iter = fuse_direct_read_iter,
3170 .write_iter = fuse_direct_write_iter,
3171 .mmap = fuse_direct_mmap,
3172 .open = fuse_open,
3173 .flush = fuse_flush,
3174 .release = fuse_release,
3175 .fsync = fuse_fsync,
3176 .lock = fuse_file_lock,
3177 .flock = fuse_file_flock,
3178 .splice_read = generic_file_splice_read,
3179 .splice_write = iter_file_splice_write,
3180 .unlocked_ioctl = fuse_file_ioctl,
3181 .compat_ioctl = fuse_file_compat_ioctl,
3182 .poll = fuse_file_poll,
3183 .fallocate = fuse_file_fallocate,
3184 .copy_file_range = fuse_copy_file_range,
3185};
3186
3187static const struct address_space_operations fuse_file_aops = { 3184static const struct address_space_operations fuse_file_aops = {
3188 .readpage = fuse_readpage, 3185 .readpage = fuse_readpage,
3189 .writepage = fuse_writepage, 3186 .writepage = fuse_writepage,