coda: add hinting support for partial file caching
[linux-2.6-microblaze.git] / fs / coda / file.c
index 0dbd13a..128d63d 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
+#include <linux/uio.h>
 
 #include <linux/coda.h>
 #include "coda_psdev.h"
@@ -37,9 +38,25 @@ static ssize_t
 coda_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
 {
        struct file *coda_file = iocb->ki_filp;
+       struct inode *coda_inode = file_inode(coda_file);
        struct coda_file_info *cfi = coda_ftoc(coda_file);
+       loff_t ki_pos = iocb->ki_pos;
+       size_t count = iov_iter_count(to);
+       ssize_t ret;
+
+       ret = venus_access_intent(coda_inode->i_sb, coda_i2f(coda_inode),
+                                 &cfi->cfi_access_intent,
+                                 count, ki_pos, CODA_ACCESS_TYPE_READ);
+       if (ret)
+               goto finish_read;
 
-       return vfs_iter_read(cfi->cfi_container, to, &iocb->ki_pos, 0);
+       ret = vfs_iter_read(cfi->cfi_container, to, &iocb->ki_pos, 0);
+
+finish_read:
+       venus_access_intent(coda_inode->i_sb, coda_i2f(coda_inode),
+                           &cfi->cfi_access_intent,
+                           count, ki_pos, CODA_ACCESS_TYPE_READ_FINISH);
+       return ret;
 }
 
 static ssize_t
@@ -48,10 +65,17 @@ coda_file_write_iter(struct kiocb *iocb, struct iov_iter *to)
        struct file *coda_file = iocb->ki_filp;
        struct inode *coda_inode = file_inode(coda_file);
        struct coda_file_info *cfi = coda_ftoc(coda_file);
-       struct file *host_file;
+       struct file *host_file = cfi->cfi_container;
+       loff_t ki_pos = iocb->ki_pos;
+       size_t count = iov_iter_count(to);
        ssize_t ret;
 
-       host_file = cfi->cfi_container;
+       ret = venus_access_intent(coda_inode->i_sb, coda_i2f(coda_inode),
+                                 &cfi->cfi_access_intent,
+                                 count, ki_pos, CODA_ACCESS_TYPE_WRITE);
+       if (ret)
+               goto finish_write;
+
        file_start_write(host_file);
        inode_lock(coda_inode);
        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)
        coda_inode->i_mtime = coda_inode->i_ctime = current_time(coda_inode);
        inode_unlock(coda_inode);
        file_end_write(host_file);
+
+finish_write:
+       venus_access_intent(coda_inode->i_sb, coda_i2f(coda_inode),
+                           &cfi->cfi_access_intent,
+                           count, ki_pos, CODA_ACCESS_TYPE_WRITE_FINISH);
        return ret;
 }
 
@@ -94,29 +123,35 @@ coda_vm_close(struct vm_area_struct *vma)
 static int
 coda_file_mmap(struct file *coda_file, struct vm_area_struct *vma)
 {
-       struct coda_file_info *cfi;
+       struct inode *coda_inode = file_inode(coda_file);
+       struct coda_file_info *cfi = coda_ftoc(coda_file);
+       struct file *host_file = cfi->cfi_container;
+       struct inode *host_inode = file_inode(host_file);
        struct coda_inode_info *cii;
-       struct file *host_file;
-       struct inode *coda_inode, *host_inode;
        struct coda_vm_ops *cvm_ops;
+       loff_t ppos;
+       size_t count;
        int ret;
 
-       cfi = coda_ftoc(coda_file);
-       host_file = cfi->cfi_container;
-
        if (!host_file->f_op->mmap)
                return -ENODEV;
 
        if (WARN_ON(coda_file != vma->vm_file))
                return -EIO;
 
+       count = vma->vm_end - vma->vm_start;
+       ppos = vma->vm_pgoff * PAGE_SIZE;
+
+       ret = venus_access_intent(coda_inode->i_sb, coda_i2f(coda_inode),
+                                 &cfi->cfi_access_intent,
+                                 count, ppos, CODA_ACCESS_TYPE_MMAP);
+       if (ret)
+               return ret;
+
        cvm_ops = kmalloc(sizeof(struct coda_vm_ops), GFP_KERNEL);
        if (!cvm_ops)
                return -ENOMEM;
 
-       coda_inode = file_inode(coda_file);
-       host_inode = file_inode(host_file);
-
        cii = ITOC(coda_inode);
        spin_lock(&cii->c_lock);
        coda_file->f_mapping = host_file->f_mapping;
@@ -188,6 +223,8 @@ int coda_open(struct inode *coda_inode, struct file *coda_file)
        cfi->cfi_magic = CODA_MAGIC;
        cfi->cfi_mapcount = 0;
        cfi->cfi_container = host_file;
+       /* assume access intents are supported unless we hear otherwise */
+       cfi->cfi_access_intent = true;
 
        BUG_ON(coda_file->private_data != NULL);
        coda_file->private_data = cfi;