]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - fs/coda/file.c
Merge branch 'master' into tk71
[mv-sheeva.git] / fs / coda / file.c
index ad3cd2abeeb48e561cadf63f65f9ae8d105dd621..0433057be3305c083fc4a705dfd5fcfbd857e2c0 100644 (file)
 #include <linux/stat.h>
 #include <linux/cred.h>
 #include <linux/errno.h>
-#include <linux/smp_lock.h>
+#include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <asm/uaccess.h>
 
 #include <linux/coda.h>
-#include <linux/coda_linux.h>
-#include <linux/coda_fs_i.h>
 #include <linux/coda_psdev.h>
 
+#include "coda_linux.h"
 #include "coda_int.h"
 
 static ssize_t
@@ -109,19 +108,24 @@ coda_file_mmap(struct file *coda_file, struct vm_area_struct *vma)
 
        coda_inode = coda_file->f_path.dentry->d_inode;
        host_inode = host_file->f_path.dentry->d_inode;
+
+       cii = ITOC(coda_inode);
+       spin_lock(&cii->c_lock);
        coda_file->f_mapping = host_file->f_mapping;
        if (coda_inode->i_mapping == &coda_inode->i_data)
                coda_inode->i_mapping = host_inode->i_mapping;
 
        /* only allow additional mmaps as long as userspace isn't changing
         * the container file on us! */
-       else if (coda_inode->i_mapping != host_inode->i_mapping)
+       else if (coda_inode->i_mapping != host_inode->i_mapping) {
+               spin_unlock(&cii->c_lock);
                return -EBUSY;
+       }
 
        /* keep track of how often the coda_inode/host_file has been mmapped */
-       cii = ITOC(coda_inode);
        cii->c_mapcount++;
        cfi->cfi_mapcount++;
+       spin_unlock(&cii->c_lock);
 
        return host_file->f_op->mmap(host_file, vma);
 }
@@ -138,8 +142,6 @@ int coda_open(struct inode *coda_inode, struct file *coda_file)
        if (!cfi)
                return -ENOMEM;
 
-       lock_kernel();
-
        error = venus_open(coda_inode->i_sb, coda_i2f(coda_inode), coda_flags,
                           &host_file);
        if (!host_file)
@@ -147,7 +149,6 @@ int coda_open(struct inode *coda_inode, struct file *coda_file)
 
        if (error) {
                kfree(cfi);
-               unlock_kernel();
                return error;
        }
 
@@ -159,8 +160,6 @@ int coda_open(struct inode *coda_inode, struct file *coda_file)
 
        BUG_ON(coda_file->private_data != NULL);
        coda_file->private_data = cfi;
-
-       unlock_kernel();
        return 0;
 }
 
@@ -171,9 +170,7 @@ int coda_release(struct inode *coda_inode, struct file *coda_file)
        struct coda_file_info *cfi;
        struct coda_inode_info *cii;
        struct inode *host_inode;
-       int err = 0;
-
-       lock_kernel();
+       int err;
 
        cfi = CODA_FTOC(coda_file);
        BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
@@ -185,18 +182,18 @@ int coda_release(struct inode *coda_inode, struct file *coda_file)
        cii = ITOC(coda_inode);
 
        /* did we mmap this file? */
+       spin_lock(&cii->c_lock);
        if (coda_inode->i_mapping == &host_inode->i_data) {
                cii->c_mapcount -= cfi->cfi_mapcount;
                if (!cii->c_mapcount)
                        coda_inode->i_mapping = &coda_inode->i_data;
        }
+       spin_unlock(&cii->c_lock);
 
        fput(cfi->cfi_container);
        kfree(coda_file->private_data);
        coda_file->private_data = NULL;
 
-       unlock_kernel();
-
        /* VFS fput ignores the return value from file_operations->release, so
         * there is no use returning an error here */
        return 0;
@@ -207,7 +204,7 @@ int coda_fsync(struct file *coda_file, int datasync)
        struct file *host_file;
        struct inode *coda_inode = coda_file->f_path.dentry->d_inode;
        struct coda_file_info *cfi;
-       int err = 0;
+       int err;
 
        if (!(S_ISREG(coda_inode->i_mode) || S_ISDIR(coda_inode->i_mode) ||
              S_ISLNK(coda_inode->i_mode)))
@@ -218,11 +215,8 @@ int coda_fsync(struct file *coda_file, int datasync)
        host_file = cfi->cfi_container;
 
        err = vfs_fsync(host_file, datasync);
-       if ( !err && !datasync ) {
-               lock_kernel();
+       if (!err && !datasync)
                err = venus_fsync(coda_inode->i_sb, coda_i2f(coda_inode));
-               unlock_kernel();
-       }
 
        return err;
 }