summaryrefslogtreecommitdiffstats
path: root/fs/coda/upcall.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/coda/upcall.c')
-rw-r--r--fs/coda/upcall.c71
1 files changed, 40 insertions, 31 deletions
diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c
index 4c258cb5266..c3563cab975 100644
--- a/fs/coda/upcall.c
+++ b/fs/coda/upcall.c
@@ -27,7 +27,7 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <asm/uaccess.h>
#include <linux/vmalloc.h>
#include <linux/vfs.h>
@@ -607,7 +607,8 @@ static void coda_unblock_signals(sigset_t *old)
(r)->uc_opcode != CODA_RELEASE) || \
(r)->uc_flags & CODA_REQ_READ))
-static inline void coda_waitfor_upcall(struct upc_req *req)
+static inline void coda_waitfor_upcall(struct venus_comm *vcp,
+ struct upc_req *req)
{
DECLARE_WAITQUEUE(wait, current);
unsigned long timeout = jiffies + coda_timeout * HZ;
@@ -640,10 +641,12 @@ static inline void coda_waitfor_upcall(struct upc_req *req)
break;
}
+ mutex_unlock(&vcp->vc_mutex);
if (blocked)
schedule_timeout(HZ);
else
schedule();
+ mutex_lock(&vcp->vc_mutex);
}
if (blocked)
coda_unblock_signals(&old);
@@ -671,7 +674,7 @@ static int coda_upcall(struct venus_comm *vcp,
struct upc_req *req = NULL, *sig_req;
int error;
- lock_kernel();
+ mutex_lock(&vcp->vc_mutex);
if (!vcp->vc_inuse) {
printk(KERN_NOTICE "coda: Venus dead, not sending upcall\n");
@@ -711,7 +714,7 @@ static int coda_upcall(struct venus_comm *vcp,
* ENODEV. */
/* Go to sleep. Wake up on signals only after the timeout. */
- coda_waitfor_upcall(req);
+ coda_waitfor_upcall(vcp, req);
/* Op went through, interrupt or not... */
if (req->uc_flags & CODA_REQ_WRITE) {
@@ -765,7 +768,7 @@ static int coda_upcall(struct venus_comm *vcp,
exit:
kfree(req);
- unlock_kernel();
+ mutex_unlock(&vcp->vc_mutex);
return error;
}
@@ -806,11 +809,11 @@ exit:
int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out)
{
struct inode *inode = NULL;
- struct CodaFid *fid, *newfid;
+ struct CodaFid *fid = NULL, *newfid;
struct super_block *sb;
/* Handle invalidation requests. */
- lock_kernel();
+ mutex_lock(&vcp->vc_mutex);
sb = vcp->vc_sb;
if (!sb || !sb->s_root)
goto unlock_out;
@@ -829,47 +832,53 @@ int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out)
case CODA_ZAPDIR:
fid = &out->coda_zapdir.CodaFid;
- inode = coda_fid_to_inode(fid, sb);
- if (inode) {
- coda_flag_inode_children(inode, C_PURGE);
- coda_flag_inode(inode, C_VATTR);
- }
break;
case CODA_ZAPFILE:
fid = &out->coda_zapfile.CodaFid;
- inode = coda_fid_to_inode(fid, sb);
- if (inode)
- coda_flag_inode(inode, C_VATTR);
break;
case CODA_PURGEFID:
fid = &out->coda_purgefid.CodaFid;
- inode = coda_fid_to_inode(fid, sb);
- if (inode) {
- coda_flag_inode_children(inode, C_PURGE);
-
- /* catch the dentries later if some are still busy */
- coda_flag_inode(inode, C_PURGE);
- d_prune_aliases(inode);
-
- }
break;
case CODA_REPLACE:
fid = &out->coda_replace.OldFid;
- newfid = &out->coda_replace.NewFid;
- inode = coda_fid_to_inode(fid, sb);
- if (inode)
- coda_replace_fid(inode, fid, newfid);
break;
}
+ if (fid)
+ inode = coda_fid_to_inode(fid, sb);
unlock_out:
- unlock_kernel();
+ mutex_unlock(&vcp->vc_mutex);
+
+ if (!inode)
+ return 0;
+
+ switch (opcode) {
+ case CODA_ZAPDIR:
+ coda_flag_inode_children(inode, C_PURGE);
+ coda_flag_inode(inode, C_VATTR);
+ break;
+
+ case CODA_ZAPFILE:
+ coda_flag_inode(inode, C_VATTR);
+ break;
+
+ case CODA_PURGEFID:
+ coda_flag_inode_children(inode, C_PURGE);
- if (inode)
- iput(inode);
+ /* catch the dentries later if some are still busy */
+ coda_flag_inode(inode, C_PURGE);
+ d_prune_aliases(inode);
+ break;
+
+ case CODA_REPLACE:
+ newfid = &out->coda_replace.NewFid;
+ coda_replace_fid(inode, fid, newfid);
+ break;
+ }
+ iput(inode);
return 0;
}