diff options
Diffstat (limited to 'fs/coda/upcall.c')
-rw-r--r-- | fs/coda/upcall.c | 94 |
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 | ||
609 | static inline void coda_waitfor_upcall(struct upc_req *req) | 609 | static 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 | ||
760 | exit: | 768 | exit: |
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 | ||
799 | int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb) | 808 | int 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 */ | 851 | unlock_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 | ||