diff options
Diffstat (limited to 'fs/coda/upcall.c')
-rw-r--r-- | fs/coda/upcall.c | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c index b8893ab6f9e6..4c258cb5266d 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/smp_lock.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> |
@@ -667,18 +668,23 @@ static int coda_upcall(struct venus_comm *vcp, | |||
667 | { | 668 | { |
668 | union outputArgs *out; | 669 | union outputArgs *out; |
669 | union inputArgs *sig_inputArgs; | 670 | union inputArgs *sig_inputArgs; |
670 | struct upc_req *req, *sig_req; | 671 | struct upc_req *req = NULL, *sig_req; |
671 | int error = 0; | 672 | int error; |
673 | |||
674 | lock_kernel(); | ||
672 | 675 | ||
673 | if (!vcp->vc_inuse) { | 676 | if (!vcp->vc_inuse) { |
674 | printk(KERN_NOTICE "coda: Venus dead, not sending upcall\n"); | 677 | printk(KERN_NOTICE "coda: Venus dead, not sending upcall\n"); |
675 | return -ENXIO; | 678 | error = -ENXIO; |
679 | goto exit; | ||
676 | } | 680 | } |
677 | 681 | ||
678 | /* Format the request message. */ | 682 | /* Format the request message. */ |
679 | req = kmalloc(sizeof(struct upc_req), GFP_KERNEL); | 683 | req = kmalloc(sizeof(struct upc_req), GFP_KERNEL); |
680 | if (!req) | 684 | if (!req) { |
681 | return -ENOMEM; | 685 | error = -ENOMEM; |
686 | goto exit; | ||
687 | } | ||
682 | 688 | ||
683 | req->uc_data = (void *)buffer; | 689 | req->uc_data = (void *)buffer; |
684 | req->uc_flags = 0; | 690 | req->uc_flags = 0; |
@@ -759,6 +765,7 @@ static int coda_upcall(struct venus_comm *vcp, | |||
759 | 765 | ||
760 | exit: | 766 | exit: |
761 | kfree(req); | 767 | kfree(req); |
768 | unlock_kernel(); | ||
762 | return error; | 769 | return error; |
763 | } | 770 | } |
764 | 771 | ||
@@ -796,21 +803,24 @@ exit: | |||
796 | * | 803 | * |
797 | * CODA_REPLACE -- replace one CodaFid with another throughout the name cache */ | 804 | * CODA_REPLACE -- replace one CodaFid with another throughout the name cache */ |
798 | 805 | ||
799 | int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb) | 806 | int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out) |
800 | { | 807 | { |
801 | struct inode *inode = NULL; | 808 | struct inode *inode = NULL; |
802 | struct CodaFid *fid, *newfid; | 809 | struct CodaFid *fid, *newfid; |
810 | struct super_block *sb; | ||
803 | 811 | ||
804 | /* Handle invalidation requests. */ | 812 | /* Handle invalidation requests. */ |
805 | if ( !sb || !sb->s_root) | 813 | lock_kernel(); |
806 | return 0; | 814 | sb = vcp->vc_sb; |
815 | if (!sb || !sb->s_root) | ||
816 | goto unlock_out; | ||
807 | 817 | ||
808 | switch (opcode) { | 818 | switch (opcode) { |
809 | case CODA_FLUSH: | 819 | case CODA_FLUSH: |
810 | coda_cache_clear_all(sb); | 820 | coda_cache_clear_all(sb); |
811 | shrink_dcache_sb(sb); | 821 | shrink_dcache_sb(sb); |
812 | if (sb->s_root->d_inode) | 822 | if (sb->s_root->d_inode) |
813 | coda_flag_inode(sb->s_root->d_inode, C_FLUSH); | 823 | coda_flag_inode(sb->s_root->d_inode, C_FLUSH); |
814 | break; | 824 | break; |
815 | 825 | ||
816 | case CODA_PURGEUSER: | 826 | case CODA_PURGEUSER: |
@@ -855,9 +865,11 @@ int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb) | |||
855 | break; | 865 | break; |
856 | } | 866 | } |
857 | 867 | ||
868 | unlock_out: | ||
869 | unlock_kernel(); | ||
870 | |||
858 | if (inode) | 871 | if (inode) |
859 | iput(inode); | 872 | iput(inode); |
860 | |||
861 | return 0; | 873 | return 0; |
862 | } | 874 | } |
863 | 875 | ||