linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / fs / coda / file.c
index 768b2a1..30b4630 100644 (file)
 
 /* if CODA_STORE fails with EOPNOTSUPP, venus clearly doesn't support
  * CODA_STORE/CODA_RELEASE and we fall back on using the CODA_CLOSE upcall */
-int use_coda_close;
+static int use_coda_close;
 
 static ssize_t
-coda_file_read(struct file *coda_file, char *buf, size_t count, loff_t *ppos)
+coda_file_read(struct file *coda_file, char __user *buf, size_t count, loff_t *ppos)
 {
        struct coda_file_info *cfi;
        struct file *host_file;
@@ -45,7 +45,24 @@ coda_file_read(struct file *coda_file, char *buf, size_t count, loff_t *ppos)
 }
 
 static ssize_t
-coda_file_write(struct file *coda_file, const char *buf, size_t count, loff_t *ppos)
+coda_file_sendfile(struct file *coda_file, loff_t *ppos, size_t count,
+                  read_actor_t actor, void *target)
+{
+       struct coda_file_info *cfi;
+       struct file *host_file;
+
+       cfi = CODA_FTOC(coda_file);
+       BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
+       host_file = cfi->cfi_container;
+
+       if (!host_file->f_op || !host_file->f_op->sendfile)
+               return -EINVAL;
+
+       return host_file->f_op->sendfile(host_file, ppos, count, actor, target);
+}
+
+static ssize_t
+coda_file_write(struct file *coda_file, const char __user *buf, size_t count, loff_t *ppos)
 {
        struct inode *host_inode, *coda_inode = coda_file->f_dentry->d_inode;
        struct coda_file_info *cfi;
@@ -60,14 +77,14 @@ coda_file_write(struct file *coda_file, const char *buf, size_t count, loff_t *p
                return -EINVAL;
 
        host_inode = host_file->f_dentry->d_inode;
-       down(&coda_inode->i_sem);
+       mutex_lock(&coda_inode->i_mutex);
 
        ret = host_file->f_op->write(host_file, buf, count, ppos);
 
        coda_inode->i_size = host_inode->i_size;
        coda_inode->i_blocks = (coda_inode->i_size + 511) >> 9;
-       coda_inode->i_mtime = coda_inode->i_ctime = CURRENT_TIME;
-       up(&coda_inode->i_sem);
+       coda_inode->i_mtime = coda_inode->i_ctime = CURRENT_TIME_SEC;
+       mutex_unlock(&coda_inode->i_mutex);
 
        return ret;
 }
@@ -255,9 +272,9 @@ int coda_fsync(struct file *coda_file, struct dentry *coda_dentry, int datasync)
        if (host_file->f_op && host_file->f_op->fsync) {
                host_dentry = host_file->f_dentry;
                host_inode = host_dentry->d_inode;
-               down(&host_inode->i_sem);
+               mutex_lock(&host_inode->i_mutex);
                err = host_file->f_op->fsync(host_file, host_dentry, datasync);
-               up(&host_inode->i_sem);
+               mutex_unlock(&host_inode->i_mutex);
        }
 
        if ( !err && !datasync ) {
@@ -278,5 +295,6 @@ struct file_operations coda_file_operations = {
        .flush          = coda_flush,
        .release        = coda_release,
        .fsync          = coda_fsync,
+       .sendfile       = coda_file_sendfile,
 };