]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - fs/coda/dir.c
Merge branch 'for-next' of git://android.git.kernel.org/kernel/tegra
[net-next-2.6.git] / fs / coda / dir.c
index ccd98b0f2b0b9c3d37f10b101a86b36572054240..96fbeab77f2f42476683cd41ead808f519a14a1e 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/stat.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/smp_lock.h>
+#include <linux/spinlock.h>
 
 #include <asm/uaccess.h>
 
@@ -116,15 +116,11 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struc
                goto exit;
        }
 
-       lock_kernel();
-
        error = venus_lookup(dir->i_sb, coda_i2f(dir), name, length,
                             &type, &resfid);
        if (!error)
                error = coda_cnode_make(&inode, &resfid, dir->i_sb);
 
-       unlock_kernel();
-
        if (error && error != -ENOENT)
                return ERR_PTR(error);
 
@@ -140,28 +136,24 @@ exit:
 
 int coda_permission(struct inode *inode, int mask)
 {
-        int error = 0;
+       int error;
 
        mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
  
        if (!mask)
-               return 0; 
+               return 0;
 
        if ((mask & MAY_EXEC) && !execute_ok(inode))
                return -EACCES;
 
-       lock_kernel();
-
        if (coda_cache_check(inode, mask))
-               goto out; 
+               return 0;
 
-        error = venus_access(inode->i_sb, coda_i2f(inode), mask);
+       error = venus_access(inode->i_sb, coda_i2f(inode), mask);
     
        if (!error)
                coda_cache_enter(inode, mask);
 
- out:
-       unlock_kernel();
        return error;
 }
 
@@ -200,41 +192,34 @@ static inline void coda_dir_drop_nlink(struct inode *dir)
 /* creation routines: create, mknod, mkdir, link, symlink */
 static int coda_create(struct inode *dir, struct dentry *de, int mode, struct nameidata *nd)
 {
-        int error=0;
+       int error;
        const char *name=de->d_name.name;
        int length=de->d_name.len;
        struct inode *inode;
        struct CodaFid newfid;
        struct coda_vattr attrs;
 
-       lock_kernel();
-
-       if (coda_isroot(dir) && coda_iscontrol(name, length)) {
-               unlock_kernel();
+       if (coda_isroot(dir) && coda_iscontrol(name, length))
                return -EPERM;
-       }
 
        error = venus_create(dir->i_sb, coda_i2f(dir), name, length, 
                                0, mode, &newfid, &attrs);
-
-        if ( error ) {
-               unlock_kernel();
-               d_drop(de);
-               return error;
-       }
+       if (error)
+               goto err_out;
 
        inode = coda_iget(dir->i_sb, &newfid, &attrs);
-       if ( IS_ERR(inode) ) {
-               unlock_kernel();
-               d_drop(de);
-               return PTR_ERR(inode);
+       if (IS_ERR(inode)) {
+               error = PTR_ERR(inode);
+               goto err_out;
        }
 
        /* invalidate the directory cnode's attributes */
        coda_dir_update_mtime(dir);
-       unlock_kernel();
        d_instantiate(de, inode);
        return 0;
+err_out:
+       d_drop(de);
+       return error;
 }
 
 static int coda_mkdir(struct inode *dir, struct dentry *de, int mode)
@@ -246,36 +231,29 @@ static int coda_mkdir(struct inode *dir, struct dentry *de, int mode)
        int error;
        struct CodaFid newfid;
 
-       lock_kernel();
-
-       if (coda_isroot(dir) && coda_iscontrol(name, len)) {
-               unlock_kernel();
+       if (coda_isroot(dir) && coda_iscontrol(name, len))
                return -EPERM;
-       }
 
        attrs.va_mode = mode;
        error = venus_mkdir(dir->i_sb, coda_i2f(dir), 
                               name, len, &newfid, &attrs);
-        
-        if ( error ) {
-               unlock_kernel();
-               d_drop(de);
-               return error;
-        }
+       if (error)
+               goto err_out;
          
        inode = coda_iget(dir->i_sb, &newfid, &attrs);
-       if ( IS_ERR(inode) ) {
-               unlock_kernel();
-               d_drop(de);
-               return PTR_ERR(inode);
+       if (IS_ERR(inode)) {
+               error = PTR_ERR(inode);
+               goto err_out;
        }
 
        /* invalidate the directory cnode's attributes */
        coda_dir_inc_nlink(dir);
        coda_dir_update_mtime(dir);
-       unlock_kernel();
        d_instantiate(de, inode);
        return 0;
+err_out:
+       d_drop(de);
+       return error;
 }
 
 /* try to make de an entry in dir_inodde linked to source_de */ 
@@ -287,52 +265,38 @@ static int coda_link(struct dentry *source_de, struct inode *dir_inode,
        int len = de->d_name.len;
        int error;
 
-       lock_kernel();
-
-       if (coda_isroot(dir_inode) && coda_iscontrol(name, len)) {
-               unlock_kernel();
+       if (coda_isroot(dir_inode) && coda_iscontrol(name, len))
                return -EPERM;
-       }
 
        error = venus_link(dir_inode->i_sb, coda_i2f(inode),
                           coda_i2f(dir_inode), (const char *)name, len);
-
        if (error) {
                d_drop(de);
-               goto out;
+               return error;
        }
 
        coda_dir_update_mtime(dir_inode);
        atomic_inc(&inode->i_count);
        d_instantiate(de, inode);
        inc_nlink(inode);
-
-out:
-       unlock_kernel();
-       return(error);
+       return 0;
 }
 
 
 static int coda_symlink(struct inode *dir_inode, struct dentry *de,
                        const char *symname)
 {
-        const char *name = de->d_name.name;
+       const char *name = de->d_name.name;
        int len = de->d_name.len;
        int symlen;
-       int error = 0;
-
-       lock_kernel();
+       int error;
 
-       if (coda_isroot(dir_inode) && coda_iscontrol(name, len)) {
-               unlock_kernel();
+       if (coda_isroot(dir_inode) && coda_iscontrol(name, len))
                return -EPERM;
-       }
 
        symlen = strlen(symname);
-       if ( symlen > CODA_MAXPATHLEN ) {
-               unlock_kernel();
+       if (symlen > CODA_MAXPATHLEN)
                return -ENAMETOOLONG;
-       }
 
        /*
         * This entry is now negative. Since we do not create
@@ -343,10 +307,9 @@ static int coda_symlink(struct inode *dir_inode, struct dentry *de,
                              symname, symlen);
 
        /* mtime is no good anymore */
-       if ( !error )
+       if (!error)
                coda_dir_update_mtime(dir_inode);
 
-       unlock_kernel();
        return error;
 }
 
@@ -357,17 +320,12 @@ static int coda_unlink(struct inode *dir, struct dentry *de)
        const char *name = de->d_name.name;
        int len = de->d_name.len;
 
-       lock_kernel();
-
        error = venus_remove(dir->i_sb, coda_i2f(dir), name, len);
-       if ( error ) {
-               unlock_kernel();
+       if (error)
                return error;
-       }
 
        coda_dir_update_mtime(dir);
        drop_nlink(de->d_inode);
-       unlock_kernel();
        return 0;
 }
 
@@ -377,8 +335,6 @@ static int coda_rmdir(struct inode *dir, struct dentry *de)
        int len = de->d_name.len;
        int error;
 
-       lock_kernel();
-
        error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len);
        if (!error) {
                /* VFS may delete the child */
@@ -389,7 +345,6 @@ static int coda_rmdir(struct inode *dir, struct dentry *de)
                coda_dir_drop_nlink(dir);
                coda_dir_update_mtime(dir);
        }
-       unlock_kernel();
        return error;
 }
 
@@ -403,15 +358,12 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry,
        int new_length = new_dentry->d_name.len;
        int error;
 
-       lock_kernel();
-
        error = venus_rename(old_dir->i_sb, coda_i2f(old_dir),
                             coda_i2f(new_dir), old_length, new_length,
                             (const char *) old_name, (const char *)new_name);
-
-       if ( !error ) {
-               if ( new_dentry->d_inode ) {
-                       if ( S_ISDIR(new_dentry->d_inode->i_mode) ) {
+       if (!error) {
+               if (new_dentry->d_inode) {
+                       if (S_ISDIR(new_dentry->d_inode->i_mode)) {
                                coda_dir_drop_nlink(old_dir);
                                coda_dir_inc_nlink(new_dir);
                        }
@@ -423,8 +375,6 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry,
                        coda_flag_inode(new_dir, C_VATTR);
                }
        }
-       unlock_kernel();
-
        return error;
 }
 
@@ -594,10 +544,7 @@ static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd)
        struct inode *inode = de->d_inode;
        struct coda_inode_info *cii;
 
-       if (!inode)
-               return 1;
-       lock_kernel();
-       if (coda_isroot(inode))
+       if (!inode || coda_isroot(inode))
                goto out;
        if (is_bad_inode(inode))
                goto bad;
@@ -617,13 +564,12 @@ static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd)
                goto out;
 
        /* clear the flags. */
+       spin_lock(&cii->c_lock);
        cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
-
+       spin_unlock(&cii->c_lock);
 bad:
-       unlock_kernel();
        return 0;
 out:
-       unlock_kernel();
        return 1;
 }
 
@@ -656,20 +602,19 @@ static int coda_dentry_delete(struct dentry * dentry)
 int coda_revalidate_inode(struct dentry *dentry)
 {
        struct coda_vattr attr;
-       int error = 0;
+       int error;
        int old_mode;
        ino_t old_ino;
        struct inode *inode = dentry->d_inode;
        struct coda_inode_info *cii = ITOC(inode);
 
-       lock_kernel();
-       if ( !cii->c_flags )
-               goto ok;
+       if (!cii->c_flags)
+               return 0;
 
        if (cii->c_flags & (C_VATTR | C_PURGE | C_FLUSH)) {
                error = venus_getattr(inode->i_sb, &(cii->c_fid), &attr);
-               if ( error )
-                       goto return_bad;
+               if (error)
+                       return -EIO;
 
                /* this inode may be lost if:
                   - it's ino changed 
@@ -688,17 +633,13 @@ int coda_revalidate_inode(struct dentry *dentry)
                /* the following can happen when a local fid is replaced 
                   with a global one, here we lose and declare the inode bad */
                if (inode->i_ino != old_ino)
-                       goto return_bad;
+                       return -EIO;
                
                coda_flag_inode_children(inode, C_FLUSH);
+
+               spin_lock(&cii->c_lock);
                cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
+               spin_unlock(&cii->c_lock);
        }
-
-ok:
-       unlock_kernel();
        return 0;
-
-return_bad:
-       unlock_kernel();
-       return -EIO;
 }