summaryrefslogtreecommitdiff
path: root/fs/coda/upcall.c
diff options
context:
space:
mode:
authorYoshihisa Abe <yoshiabe@cs.cmu.edu>2010-10-25 10:03:45 +0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-25 19:02:40 +0400
commitf7cc02b8715618e179242ba9cc10bdc5146ae565 (patch)
tree80c1bcf6923c9982a52fbe510cb7d396fb9866fc /fs/coda/upcall.c
parentb5ce1d83a62fc109d8e815b1fc71dcdb0d26bc49 (diff)
downloadlinux-f7cc02b8715618e179242ba9cc10bdc5146ae565.tar.xz
Coda: push BKL regions into coda_upcall()
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 <yoshiabe@cs.cmu.edu> Signed-off-by: Jan Harkes <jaharkes@cs.cmu.edu> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/coda/upcall.c')
-rw-r--r--fs/coda/upcall.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c
index b8893ab6f9e6..4c258cb5266d 100644
--- a/fs/coda/upcall.c
+++ b/fs/coda/upcall.c
@@ -27,6 +27,7 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <linux/vmalloc.h>
#include <linux/vfs.h>
@@ -667,18 +668,23 @@ static int coda_upcall(struct venus_comm *vcp,
{
union outputArgs *out;
union inputArgs *sig_inputArgs;
- struct upc_req *req, *sig_req;
- int error = 0;
+ struct upc_req *req = NULL, *sig_req;
+ int error;
+
+ lock_kernel();
if (!vcp->vc_inuse) {
printk(KERN_NOTICE "coda: Venus dead, not sending upcall\n");
- return -ENXIO;
+ error = -ENXIO;
+ goto exit;
}
/* Format the request message. */
req = kmalloc(sizeof(struct upc_req), GFP_KERNEL);
- if (!req)
- return -ENOMEM;
+ if (!req) {
+ error = -ENOMEM;
+ goto exit;
+ }
req->uc_data = (void *)buffer;
req->uc_flags = 0;
@@ -759,6 +765,7 @@ static int coda_upcall(struct venus_comm *vcp,
exit:
kfree(req);
+ unlock_kernel();
return error;
}
@@ -796,21 +803,24 @@ exit:
*
* CODA_REPLACE -- replace one CodaFid with another throughout the name cache */
-int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb)
+int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out)
{
struct inode *inode = NULL;
struct CodaFid *fid, *newfid;
+ struct super_block *sb;
/* Handle invalidation requests. */
- if ( !sb || !sb->s_root)
- return 0;
+ lock_kernel();
+ sb = vcp->vc_sb;
+ if (!sb || !sb->s_root)
+ goto unlock_out;
switch (opcode) {
case CODA_FLUSH:
coda_cache_clear_all(sb);
shrink_dcache_sb(sb);
if (sb->s_root->d_inode)
- coda_flag_inode(sb->s_root->d_inode, C_FLUSH);
+ coda_flag_inode(sb->s_root->d_inode, C_FLUSH);
break;
case CODA_PURGEUSER:
@@ -855,9 +865,11 @@ int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb)
break;
}
+unlock_out:
+ unlock_kernel();
+
if (inode)
iput(inode);
-
return 0;
}