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