Skip to content

Commit

Permalink
Coda: push BKL regions into coda_upcall()
Browse files Browse the repository at this point in the history
Now that shared inode state is locked using the cii->c_lock, the BKL is
only used to protect the upcall queues used to communicate with the
userspace cache manager. The remaining state is all local and we can
push the lock further down into coda_upcall().

Signed-off-by: Yoshihisa Abe <[email protected]>
Signed-off-by: Jan Harkes <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Yoshihisa Abe authored and torvalds committed Oct 25, 2010
1 parent b5ce1d8 commit f7cc02b
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 190 deletions.
149 changes: 42 additions & 107 deletions fs/coda/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#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>
Expand Down Expand Up @@ -117,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);

Expand All @@ -141,28 +136,24 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struc

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;
}

Expand Down Expand Up @@ -201,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)
Expand All @@ -247,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 */
Expand All @@ -288,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
Expand All @@ -344,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;
}

Expand All @@ -358,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;
}

Expand All @@ -378,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 */
Expand All @@ -390,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;
}

Expand All @@ -404,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);
}
Expand All @@ -424,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;
}

Expand Down Expand Up @@ -595,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;
Expand All @@ -621,12 +567,9 @@ static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd)
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;
}

Expand Down Expand Up @@ -659,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
Expand All @@ -691,20 +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;
}
Loading

0 comments on commit f7cc02b

Please sign in to comment.