aboutsummaryrefslogtreecommitdiffstats
path: root/fs/coda/file.c
diff options
context:
space:
mode:
authorPedro Cuadra <pjcuadra@gmail.com>2019-07-16 19:29:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-07-16 22:23:23 -0400
commita9fba24c6ac9b66c09dfc2a0e845ecace187e89c (patch)
treec0985325e935868b52697d0e0167e0023a0e5d9b /fs/coda/file.c
parent5bb44810f47a00b608ed2cb9f892ae7ce37b02bd (diff)
coda: add hinting support for partial file caching
This adds support for partial file caching in Coda. Every read, write and mmap informs the userspace cache manager about what part of a file is about to be accessed so that the cache manager can ensure the relevant parts are available before the operation is allowed to proceed. When a read or write operation completes, this is also reported to allow the cache manager to track when partially cached content can be released. If the cache manager does not support partial file caching, or when the entire file has been fetched into the local cache, the cache manager may return an EOPNOTSUPP error to indicate that intent upcalls are no longer necessary until the file is closed. [akpm@linux-foundation.org: little whitespace fixup] Link: http://lkml.kernel.org/r/20190618181301.6960-1-jaharkes@cs.cmu.edu Signed-off-by: Pedro Cuadra <pjcuadra@gmail.com> Signed-off-by: Jan Harkes <jaharkes@cs.cmu.edu> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/coda/file.c')
-rw-r--r--fs/coda/file.c61
1 files changed, 49 insertions, 12 deletions
diff --git a/fs/coda/file.c b/fs/coda/file.c
index 0dbd13ab72e3..128d63df5bfb 100644
--- a/fs/coda/file.c
+++ b/fs/coda/file.c
@@ -20,6 +20,7 @@
20#include <linux/string.h> 20#include <linux/string.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/uaccess.h> 22#include <linux/uaccess.h>
23#include <linux/uio.h>
23 24
24#include <linux/coda.h> 25#include <linux/coda.h>
25#include "coda_psdev.h" 26#include "coda_psdev.h"
@@ -37,9 +38,25 @@ static ssize_t
37coda_file_read_iter(struct kiocb *iocb, struct iov_iter *to) 38coda_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
38{ 39{
39 struct file *coda_file = iocb->ki_filp; 40 struct file *coda_file = iocb->ki_filp;
41 struct inode *coda_inode = file_inode(coda_file);
40 struct coda_file_info *cfi = coda_ftoc(coda_file); 42 struct coda_file_info *cfi = coda_ftoc(coda_file);
43 loff_t ki_pos = iocb->ki_pos;
44 size_t count = iov_iter_count(to);
45 ssize_t ret;
46
47 ret = venus_access_intent(coda_inode->i_sb, coda_i2f(coda_inode),
48 &cfi->cfi_access_intent,
49 count, ki_pos, CODA_ACCESS_TYPE_READ);
50 if (ret)
51 goto finish_read;
41 52
42 return vfs_iter_read(cfi->cfi_container, to, &iocb->ki_pos, 0); 53 ret = vfs_iter_read(cfi->cfi_container, to, &iocb->ki_pos, 0);
54
55finish_read:
56 venus_access_intent(coda_inode->i_sb, coda_i2f(coda_inode),
57 &cfi->cfi_access_intent,
58 count, ki_pos, CODA_ACCESS_TYPE_READ_FINISH);
59 return ret;
43} 60}
44 61
45static ssize_t 62static ssize_t
@@ -48,10 +65,17 @@ coda_file_write_iter(struct kiocb *iocb, struct iov_iter *to)
48 struct file *coda_file = iocb->ki_filp; 65 struct file *coda_file = iocb->ki_filp;
49 struct inode *coda_inode = file_inode(coda_file); 66 struct inode *coda_inode = file_inode(coda_file);
50 struct coda_file_info *cfi = coda_ftoc(coda_file); 67 struct coda_file_info *cfi = coda_ftoc(coda_file);
51 struct file *host_file; 68 struct file *host_file = cfi->cfi_container;
69 loff_t ki_pos = iocb->ki_pos;
70 size_t count = iov_iter_count(to);
52 ssize_t ret; 71 ssize_t ret;
53 72
54 host_file = cfi->cfi_container; 73 ret = venus_access_intent(coda_inode->i_sb, coda_i2f(coda_inode),
74 &cfi->cfi_access_intent,
75 count, ki_pos, CODA_ACCESS_TYPE_WRITE);
76 if (ret)
77 goto finish_write;
78
55 file_start_write(host_file); 79 file_start_write(host_file);
56 inode_lock(coda_inode); 80 inode_lock(coda_inode);
57 ret = vfs_iter_write(cfi->cfi_container, to, &iocb->ki_pos, 0); 81 ret = vfs_iter_write(cfi->cfi_container, to, &iocb->ki_pos, 0);
@@ -60,6 +84,11 @@ coda_file_write_iter(struct kiocb *iocb, struct iov_iter *to)
60 coda_inode->i_mtime = coda_inode->i_ctime = current_time(coda_inode); 84 coda_inode->i_mtime = coda_inode->i_ctime = current_time(coda_inode);
61 inode_unlock(coda_inode); 85 inode_unlock(coda_inode);
62 file_end_write(host_file); 86 file_end_write(host_file);
87
88finish_write:
89 venus_access_intent(coda_inode->i_sb, coda_i2f(coda_inode),
90 &cfi->cfi_access_intent,
91 count, ki_pos, CODA_ACCESS_TYPE_WRITE_FINISH);
63 return ret; 92 return ret;
64} 93}
65 94
@@ -94,29 +123,35 @@ coda_vm_close(struct vm_area_struct *vma)
94static int 123static int
95coda_file_mmap(struct file *coda_file, struct vm_area_struct *vma) 124coda_file_mmap(struct file *coda_file, struct vm_area_struct *vma)
96{ 125{
97 struct coda_file_info *cfi; 126 struct inode *coda_inode = file_inode(coda_file);
127 struct coda_file_info *cfi = coda_ftoc(coda_file);
128 struct file *host_file = cfi->cfi_container;
129 struct inode *host_inode = file_inode(host_file);
98 struct coda_inode_info *cii; 130 struct coda_inode_info *cii;
99 struct file *host_file;
100 struct inode *coda_inode, *host_inode;
101 struct coda_vm_ops *cvm_ops; 131 struct coda_vm_ops *cvm_ops;
132 loff_t ppos;
133 size_t count;
102 int ret; 134 int ret;
103 135
104 cfi = coda_ftoc(coda_file);
105 host_file = cfi->cfi_container;
106
107 if (!host_file->f_op->mmap) 136 if (!host_file->f_op->mmap)
108 return -ENODEV; 137 return -ENODEV;
109 138
110 if (WARN_ON(coda_file != vma->vm_file)) 139 if (WARN_ON(coda_file != vma->vm_file))
111 return -EIO; 140 return -EIO;
112 141
142 count = vma->vm_end - vma->vm_start;
143 ppos = vma->vm_pgoff * PAGE_SIZE;
144
145 ret = venus_access_intent(coda_inode->i_sb, coda_i2f(coda_inode),
146 &cfi->cfi_access_intent,
147 count, ppos, CODA_ACCESS_TYPE_MMAP);
148 if (ret)
149 return ret;
150
113 cvm_ops = kmalloc(sizeof(struct coda_vm_ops), GFP_KERNEL); 151 cvm_ops = kmalloc(sizeof(struct coda_vm_ops), GFP_KERNEL);
114 if (!cvm_ops) 152 if (!cvm_ops)
115 return -ENOMEM; 153 return -ENOMEM;
116 154
117 coda_inode = file_inode(coda_file);
118 host_inode = file_inode(host_file);
119
120 cii = ITOC(coda_inode); 155 cii = ITOC(coda_inode);
121 spin_lock(&cii->c_lock); 156 spin_lock(&cii->c_lock);
122 coda_file->f_mapping = host_file->f_mapping; 157 coda_file->f_mapping = host_file->f_mapping;
@@ -188,6 +223,8 @@ int coda_open(struct inode *coda_inode, struct file *coda_file)
188 cfi->cfi_magic = CODA_MAGIC; 223 cfi->cfi_magic = CODA_MAGIC;
189 cfi->cfi_mapcount = 0; 224 cfi->cfi_mapcount = 0;
190 cfi->cfi_container = host_file; 225 cfi->cfi_container = host_file;
226 /* assume access intents are supported unless we hear otherwise */
227 cfi->cfi_access_intent = true;
191 228
192 BUG_ON(coda_file->private_data != NULL); 229 BUG_ON(coda_file->private_data != NULL);
193 coda_file->private_data = cfi; 230 coda_file->private_data = cfi;