|
@@ -27,7 +27,7 @@
|
|
#include <linux/errno.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/string.h>
|
|
#include <linux/string.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/slab.h>
|
|
-#include <linux/smp_lock.h>
|
|
|
|
|
|
+#include <linux/mutex.h>
|
|
#include <asm/uaccess.h>
|
|
#include <asm/uaccess.h>
|
|
#include <linux/vmalloc.h>
|
|
#include <linux/vmalloc.h>
|
|
#include <linux/vfs.h>
|
|
#include <linux/vfs.h>
|
|
@@ -607,7 +607,8 @@ static void coda_unblock_signals(sigset_t *old)
|
|
(r)->uc_opcode != CODA_RELEASE) || \
|
|
(r)->uc_opcode != CODA_RELEASE) || \
|
|
(r)->uc_flags & CODA_REQ_READ))
|
|
(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);
|
|
DECLARE_WAITQUEUE(wait, current);
|
|
unsigned long timeout = jiffies + coda_timeout * HZ;
|
|
unsigned long timeout = jiffies + coda_timeout * HZ;
|
|
@@ -640,10 +641,12 @@ static inline void coda_waitfor_upcall(struct upc_req *req)
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ mutex_unlock(&vcp->vc_mutex);
|
|
if (blocked)
|
|
if (blocked)
|
|
schedule_timeout(HZ);
|
|
schedule_timeout(HZ);
|
|
else
|
|
else
|
|
schedule();
|
|
schedule();
|
|
|
|
+ mutex_lock(&vcp->vc_mutex);
|
|
}
|
|
}
|
|
if (blocked)
|
|
if (blocked)
|
|
coda_unblock_signals(&old);
|
|
coda_unblock_signals(&old);
|
|
@@ -671,7 +674,7 @@ static int coda_upcall(struct venus_comm *vcp,
|
|
struct upc_req *req = NULL, *sig_req;
|
|
struct upc_req *req = NULL, *sig_req;
|
|
int error;
|
|
int error;
|
|
|
|
|
|
- lock_kernel();
|
|
|
|
|
|
+ mutex_lock(&vcp->vc_mutex);
|
|
|
|
|
|
if (!vcp->vc_inuse) {
|
|
if (!vcp->vc_inuse) {
|
|
printk(KERN_NOTICE "coda: Venus dead, not sending upcall\n");
|
|
printk(KERN_NOTICE "coda: Venus dead, not sending upcall\n");
|
|
@@ -711,7 +714,7 @@ static int coda_upcall(struct venus_comm *vcp,
|
|
* ENODEV. */
|
|
* ENODEV. */
|
|
|
|
|
|
/* Go to sleep. Wake up on signals only after the timeout. */
|
|
/* 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... */
|
|
/* Op went through, interrupt or not... */
|
|
if (req->uc_flags & CODA_REQ_WRITE) {
|
|
if (req->uc_flags & CODA_REQ_WRITE) {
|
|
@@ -765,7 +768,7 @@ static int coda_upcall(struct venus_comm *vcp,
|
|
|
|
|
|
exit:
|
|
exit:
|
|
kfree(req);
|
|
kfree(req);
|
|
- unlock_kernel();
|
|
|
|
|
|
+ mutex_unlock(&vcp->vc_mutex);
|
|
return error;
|
|
return error;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -806,11 +809,11 @@ exit:
|
|
int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out)
|
|
int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out)
|
|
{
|
|
{
|
|
struct inode *inode = NULL;
|
|
struct inode *inode = NULL;
|
|
- struct CodaFid *fid, *newfid;
|
|
|
|
|
|
+ struct CodaFid *fid = NULL, *newfid;
|
|
struct super_block *sb;
|
|
struct super_block *sb;
|
|
|
|
|
|
/* Handle invalidation requests. */
|
|
/* Handle invalidation requests. */
|
|
- lock_kernel();
|
|
|
|
|
|
+ mutex_lock(&vcp->vc_mutex);
|
|
sb = vcp->vc_sb;
|
|
sb = vcp->vc_sb;
|
|
if (!sb || !sb->s_root)
|
|
if (!sb || !sb->s_root)
|
|
goto unlock_out;
|
|
goto unlock_out;
|
|
@@ -829,47 +832,53 @@ int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out)
|
|
|
|
|
|
case CODA_ZAPDIR:
|
|
case CODA_ZAPDIR:
|
|
fid = &out->coda_zapdir.CodaFid;
|
|
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;
|
|
break;
|
|
|
|
|
|
case CODA_ZAPFILE:
|
|
case CODA_ZAPFILE:
|
|
fid = &out->coda_zapfile.CodaFid;
|
|
fid = &out->coda_zapfile.CodaFid;
|
|
- inode = coda_fid_to_inode(fid, sb);
|
|
|
|
- if (inode)
|
|
|
|
- coda_flag_inode(inode, C_VATTR);
|
|
|
|
break;
|
|
break;
|
|
|
|
|
|
case CODA_PURGEFID:
|
|
case CODA_PURGEFID:
|
|
fid = &out->coda_purgefid.CodaFid;
|
|
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;
|
|
break;
|
|
|
|
|
|
case CODA_REPLACE:
|
|
case CODA_REPLACE:
|
|
fid = &out->coda_replace.OldFid;
|
|
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;
|
|
break;
|
|
}
|
|
}
|
|
|
|
+ if (fid)
|
|
|
|
+ inode = coda_fid_to_inode(fid, sb);
|
|
|
|
|
|
unlock_out:
|
|
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;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|