aboutsummaryrefslogtreecommitdiffstats
path: root/fs/coda/upcall.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/coda/upcall.c')
-rw-r--r--fs/coda/upcall.c94
1 files changed, 57 insertions, 37 deletions
diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c
index b8893ab6f9e6..9727e0c52579 100644
--- a/fs/coda/upcall.c
+++ b/fs/coda/upcall.c
@@ -27,15 +27,15 @@
27#include <linux/errno.h> 27#include <linux/errno.h>
28#include <linux/string.h> 28#include <linux/string.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/mutex.h>
30#include <asm/uaccess.h> 31#include <asm/uaccess.h>
31#include <linux/vmalloc.h> 32#include <linux/vmalloc.h>
32#include <linux/vfs.h> 33#include <linux/vfs.h>
33 34
34#include <linux/coda.h> 35#include <linux/coda.h>
35#include <linux/coda_linux.h>
36#include <linux/coda_psdev.h> 36#include <linux/coda_psdev.h>
37#include <linux/coda_fs_i.h> 37#include "coda_linux.h"
38#include <linux/coda_cache.h> 38#include "coda_cache.h"
39 39
40#include "coda_int.h" 40#include "coda_int.h"
41 41
@@ -606,7 +606,8 @@ static void coda_unblock_signals(sigset_t *old)
606 (r)->uc_opcode != CODA_RELEASE) || \ 606 (r)->uc_opcode != CODA_RELEASE) || \
607 (r)->uc_flags & CODA_REQ_READ)) 607 (r)->uc_flags & CODA_REQ_READ))
608 608
609static inline void coda_waitfor_upcall(struct upc_req *req) 609static inline void coda_waitfor_upcall(struct venus_comm *vcp,
610 struct upc_req *req)
610{ 611{
611 DECLARE_WAITQUEUE(wait, current); 612 DECLARE_WAITQUEUE(wait, current);
612 unsigned long timeout = jiffies + coda_timeout * HZ; 613 unsigned long timeout = jiffies + coda_timeout * HZ;
@@ -639,10 +640,12 @@ static inline void coda_waitfor_upcall(struct upc_req *req)
639 break; 640 break;
640 } 641 }
641 642
643 mutex_unlock(&vcp->vc_mutex);
642 if (blocked) 644 if (blocked)
643 schedule_timeout(HZ); 645 schedule_timeout(HZ);
644 else 646 else
645 schedule(); 647 schedule();
648 mutex_lock(&vcp->vc_mutex);
646 } 649 }
647 if (blocked) 650 if (blocked)
648 coda_unblock_signals(&old); 651 coda_unblock_signals(&old);
@@ -667,18 +670,23 @@ static int coda_upcall(struct venus_comm *vcp,
667{ 670{
668 union outputArgs *out; 671 union outputArgs *out;
669 union inputArgs *sig_inputArgs; 672 union inputArgs *sig_inputArgs;
670 struct upc_req *req, *sig_req; 673 struct upc_req *req = NULL, *sig_req;
671 int error = 0; 674 int error;
675
676 mutex_lock(&vcp->vc_mutex);
672 677
673 if (!vcp->vc_inuse) { 678 if (!vcp->vc_inuse) {
674 printk(KERN_NOTICE "coda: Venus dead, not sending upcall\n"); 679 printk(KERN_NOTICE "coda: Venus dead, not sending upcall\n");
675 return -ENXIO; 680 error = -ENXIO;
681 goto exit;
676 } 682 }
677 683
678 /* Format the request message. */ 684 /* Format the request message. */
679 req = kmalloc(sizeof(struct upc_req), GFP_KERNEL); 685 req = kmalloc(sizeof(struct upc_req), GFP_KERNEL);
680 if (!req) 686 if (!req) {
681 return -ENOMEM; 687 error = -ENOMEM;
688 goto exit;
689 }
682 690
683 req->uc_data = (void *)buffer; 691 req->uc_data = (void *)buffer;
684 req->uc_flags = 0; 692 req->uc_flags = 0;
@@ -705,7 +713,7 @@ static int coda_upcall(struct venus_comm *vcp,
705 * ENODEV. */ 713 * ENODEV. */
706 714
707 /* Go to sleep. Wake up on signals only after the timeout. */ 715 /* Go to sleep. Wake up on signals only after the timeout. */
708 coda_waitfor_upcall(req); 716 coda_waitfor_upcall(vcp, req);
709 717
710 /* Op went through, interrupt or not... */ 718 /* Op went through, interrupt or not... */
711 if (req->uc_flags & CODA_REQ_WRITE) { 719 if (req->uc_flags & CODA_REQ_WRITE) {
@@ -759,6 +767,7 @@ static int coda_upcall(struct venus_comm *vcp,
759 767
760exit: 768exit:
761 kfree(req); 769 kfree(req);
770 mutex_unlock(&vcp->vc_mutex);
762 return error; 771 return error;
763} 772}
764 773
@@ -796,21 +805,24 @@ exit:
796 * 805 *
797 * CODA_REPLACE -- replace one CodaFid with another throughout the name cache */ 806 * CODA_REPLACE -- replace one CodaFid with another throughout the name cache */
798 807
799int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb) 808int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out)
800{ 809{
801 struct inode *inode = NULL; 810 struct inode *inode = NULL;
802 struct CodaFid *fid, *newfid; 811 struct CodaFid *fid = NULL, *newfid;
812 struct super_block *sb;
803 813
804 /* Handle invalidation requests. */ 814 /* Handle invalidation requests. */
805 if ( !sb || !sb->s_root) 815 mutex_lock(&vcp->vc_mutex);
806 return 0; 816 sb = vcp->vc_sb;
817 if (!sb || !sb->s_root)
818 goto unlock_out;
807 819
808 switch (opcode) { 820 switch (opcode) {
809 case CODA_FLUSH: 821 case CODA_FLUSH:
810 coda_cache_clear_all(sb); 822 coda_cache_clear_all(sb);
811 shrink_dcache_sb(sb); 823 shrink_dcache_sb(sb);
812 if (sb->s_root->d_inode) 824 if (sb->s_root->d_inode)
813 coda_flag_inode(sb->s_root->d_inode, C_FLUSH); 825 coda_flag_inode(sb->s_root->d_inode, C_FLUSH);
814 break; 826 break;
815 827
816 case CODA_PURGEUSER: 828 case CODA_PURGEUSER:
@@ -819,45 +831,53 @@ int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb)
819 831
820 case CODA_ZAPDIR: 832 case CODA_ZAPDIR:
821 fid = &out->coda_zapdir.CodaFid; 833 fid = &out->coda_zapdir.CodaFid;
822 inode = coda_fid_to_inode(fid, sb);
823 if (inode) {
824 coda_flag_inode_children(inode, C_PURGE);
825 coda_flag_inode(inode, C_VATTR);
826 }
827 break; 834 break;
828 835
829 case CODA_ZAPFILE: 836 case CODA_ZAPFILE:
830 fid = &out->coda_zapfile.CodaFid; 837 fid = &out->coda_zapfile.CodaFid;
831 inode = coda_fid_to_inode(fid, sb);
832 if (inode)
833 coda_flag_inode(inode, C_VATTR);
834 break; 838 break;
835 839
836 case CODA_PURGEFID: 840 case CODA_PURGEFID:
837 fid = &out->coda_purgefid.CodaFid; 841 fid = &out->coda_purgefid.CodaFid;
842 break;
843
844 case CODA_REPLACE:
845 fid = &out->coda_replace.OldFid;
846 break;
847 }
848 if (fid)
838 inode = coda_fid_to_inode(fid, sb); 849 inode = coda_fid_to_inode(fid, sb);
839 if (inode) {
840 coda_flag_inode_children(inode, C_PURGE);
841 850
842 /* catch the dentries later if some are still busy */ 851unlock_out:
843 coda_flag_inode(inode, C_PURGE); 852 mutex_unlock(&vcp->vc_mutex);
844 d_prune_aliases(inode);
845 853
846 } 854 if (!inode)
855 return 0;
856
857 switch (opcode) {
858 case CODA_ZAPDIR:
859 coda_flag_inode_children(inode, C_PURGE);
860 coda_flag_inode(inode, C_VATTR);
861 break;
862
863 case CODA_ZAPFILE:
864 coda_flag_inode(inode, C_VATTR);
865 break;
866
867 case CODA_PURGEFID:
868 coda_flag_inode_children(inode, C_PURGE);
869
870 /* catch the dentries later if some are still busy */
871 coda_flag_inode(inode, C_PURGE);
872 d_prune_aliases(inode);
847 break; 873 break;
848 874
849 case CODA_REPLACE: 875 case CODA_REPLACE:
850 fid = &out->coda_replace.OldFid;
851 newfid = &out->coda_replace.NewFid; 876 newfid = &out->coda_replace.NewFid;
852 inode = coda_fid_to_inode(fid, sb); 877 coda_replace_fid(inode, fid, newfid);
853 if (inode)
854 coda_replace_fid(inode, fid, newfid);
855 break; 878 break;
856 } 879 }
857 880 iput(inode);
858 if (inode)
859 iput(inode);
860
861 return 0; 881 return 0;
862} 882}
863 883