aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/coda/inode.c19
-rw-r--r--fs/coda/psdev.c28
-rw-r--r--fs/coda/upcall.c71
-rw-r--r--include/linux/coda_psdev.h2
4 files changed, 70 insertions, 50 deletions
diff --git a/fs/coda/inode.c b/fs/coda/inode.c
index b7fa3e3d772f..7993b96ca348 100644
--- a/fs/coda/inode.c
+++ b/fs/coda/inode.c
@@ -15,7 +15,7 @@
15#include <linux/stat.h> 15#include <linux/stat.h>
16#include <linux/errno.h> 16#include <linux/errno.h>
17#include <linux/unistd.h> 17#include <linux/unistd.h>
18#include <linux/smp_lock.h> 18#include <linux/mutex.h>
19#include <linux/spinlock.h> 19#include <linux/spinlock.h>
20#include <linux/file.h> 20#include <linux/file.h>
21#include <linux/vfs.h> 21#include <linux/vfs.h>
@@ -145,7 +145,7 @@ static int get_device_index(struct coda_mount_data *data)
145static int coda_fill_super(struct super_block *sb, void *data, int silent) 145static int coda_fill_super(struct super_block *sb, void *data, int silent)
146{ 146{
147 struct inode *root = NULL; 147 struct inode *root = NULL;
148 struct venus_comm *vc = NULL; 148 struct venus_comm *vc;
149 struct CodaFid fid; 149 struct CodaFid fid;
150 int error; 150 int error;
151 int idx; 151 int idx;
@@ -159,7 +159,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
159 printk(KERN_INFO "coda_read_super: device index: %i\n", idx); 159 printk(KERN_INFO "coda_read_super: device index: %i\n", idx);
160 160
161 vc = &coda_comms[idx]; 161 vc = &coda_comms[idx];
162 lock_kernel(); 162 mutex_lock(&vc->vc_mutex);
163 163
164 if (!vc->vc_inuse) { 164 if (!vc->vc_inuse) {
165 printk("coda_read_super: No pseudo device\n"); 165 printk("coda_read_super: No pseudo device\n");
@@ -178,7 +178,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
178 goto unlock_out; 178 goto unlock_out;
179 179
180 vc->vc_sb = sb; 180 vc->vc_sb = sb;
181 unlock_kernel(); 181 mutex_unlock(&vc->vc_mutex);
182 182
183 sb->s_fs_info = vc; 183 sb->s_fs_info = vc;
184 sb->s_flags |= MS_NOATIME; 184 sb->s_flags |= MS_NOATIME;
@@ -217,20 +217,23 @@ error:
217 if (root) 217 if (root)
218 iput(root); 218 iput(root);
219 219
220 lock_kernel(); 220 mutex_lock(&vc->vc_mutex);
221 bdi_destroy(&vc->bdi); 221 bdi_destroy(&vc->bdi);
222 vc->vc_sb = NULL; 222 vc->vc_sb = NULL;
223 sb->s_fs_info = NULL; 223 sb->s_fs_info = NULL;
224unlock_out: 224unlock_out:
225 unlock_kernel(); 225 mutex_unlock(&vc->vc_mutex);
226 return error; 226 return error;
227} 227}
228 228
229static void coda_put_super(struct super_block *sb) 229static void coda_put_super(struct super_block *sb)
230{ 230{
231 bdi_destroy(&coda_vcp(sb)->bdi); 231 struct venus_comm *vcp = coda_vcp(sb);
232 coda_vcp(sb)->vc_sb = NULL; 232 mutex_lock(&vcp->vc_mutex);
233 bdi_destroy(&vcp->bdi);
234 vcp->vc_sb = NULL;
233 sb->s_fs_info = NULL; 235 sb->s_fs_info = NULL;
236 mutex_unlock(&vcp->vc_mutex);
234 237
235 printk("Coda: Bye bye.\n"); 238 printk("Coda: Bye bye.\n");
236} 239}
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c
index 9a9248e632c6..62647a8595e4 100644
--- a/fs/coda/psdev.c
+++ b/fs/coda/psdev.c
@@ -35,7 +35,7 @@
35#include <linux/poll.h> 35#include <linux/poll.h>
36#include <linux/init.h> 36#include <linux/init.h>
37#include <linux/list.h> 37#include <linux/list.h>
38#include <linux/smp_lock.h> 38#include <linux/mutex.h>
39#include <linux/device.h> 39#include <linux/device.h>
40#include <asm/io.h> 40#include <asm/io.h>
41#include <asm/system.h> 41#include <asm/system.h>
@@ -67,8 +67,10 @@ static unsigned int coda_psdev_poll(struct file *file, poll_table * wait)
67 unsigned int mask = POLLOUT | POLLWRNORM; 67 unsigned int mask = POLLOUT | POLLWRNORM;
68 68
69 poll_wait(file, &vcp->vc_waitq, wait); 69 poll_wait(file, &vcp->vc_waitq, wait);
70 mutex_lock(&vcp->vc_mutex);
70 if (!list_empty(&vcp->vc_pending)) 71 if (!list_empty(&vcp->vc_pending))
71 mask |= POLLIN | POLLRDNORM; 72 mask |= POLLIN | POLLRDNORM;
73 mutex_unlock(&vcp->vc_mutex);
72 74
73 return mask; 75 return mask;
74} 76}
@@ -143,7 +145,7 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf,
143 } 145 }
144 146
145 /* Look for the message on the processing queue. */ 147 /* Look for the message on the processing queue. */
146 lock_kernel(); 148 mutex_lock(&vcp->vc_mutex);
147 list_for_each(lh, &vcp->vc_processing) { 149 list_for_each(lh, &vcp->vc_processing) {
148 tmp = list_entry(lh, struct upc_req , uc_chain); 150 tmp = list_entry(lh, struct upc_req , uc_chain);
149 if (tmp->uc_unique == hdr.unique) { 151 if (tmp->uc_unique == hdr.unique) {
@@ -152,7 +154,7 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf,
152 break; 154 break;
153 } 155 }
154 } 156 }
155 unlock_kernel(); 157 mutex_unlock(&vcp->vc_mutex);
156 158
157 if (!req) { 159 if (!req) {
158 printk("psdev_write: msg (%d, %d) not found\n", 160 printk("psdev_write: msg (%d, %d) not found\n",
@@ -207,7 +209,7 @@ static ssize_t coda_psdev_read(struct file * file, char __user * buf,
207 if (nbytes == 0) 209 if (nbytes == 0)
208 return 0; 210 return 0;
209 211
210 lock_kernel(); 212 mutex_lock(&vcp->vc_mutex);
211 213
212 add_wait_queue(&vcp->vc_waitq, &wait); 214 add_wait_queue(&vcp->vc_waitq, &wait);
213 set_current_state(TASK_INTERRUPTIBLE); 215 set_current_state(TASK_INTERRUPTIBLE);
@@ -221,7 +223,9 @@ static ssize_t coda_psdev_read(struct file * file, char __user * buf,
221 retval = -ERESTARTSYS; 223 retval = -ERESTARTSYS;
222 break; 224 break;
223 } 225 }
226 mutex_unlock(&vcp->vc_mutex);
224 schedule(); 227 schedule();
228 mutex_lock(&vcp->vc_mutex);
225 } 229 }
226 230
227 set_current_state(TASK_RUNNING); 231 set_current_state(TASK_RUNNING);
@@ -254,7 +258,7 @@ static ssize_t coda_psdev_read(struct file * file, char __user * buf,
254 CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr)); 258 CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr));
255 kfree(req); 259 kfree(req);
256out: 260out:
257 unlock_kernel(); 261 mutex_unlock(&vcp->vc_mutex);
258 return (count ? count : retval); 262 return (count ? count : retval);
259} 263}
260 264
@@ -267,10 +271,10 @@ static int coda_psdev_open(struct inode * inode, struct file * file)
267 if (idx < 0 || idx >= MAX_CODADEVS) 271 if (idx < 0 || idx >= MAX_CODADEVS)
268 return -ENODEV; 272 return -ENODEV;
269 273
270 lock_kernel();
271
272 err = -EBUSY; 274 err = -EBUSY;
273 vcp = &coda_comms[idx]; 275 vcp = &coda_comms[idx];
276 mutex_lock(&vcp->vc_mutex);
277
274 if (!vcp->vc_inuse) { 278 if (!vcp->vc_inuse) {
275 vcp->vc_inuse++; 279 vcp->vc_inuse++;
276 280
@@ -284,7 +288,7 @@ static int coda_psdev_open(struct inode * inode, struct file * file)
284 err = 0; 288 err = 0;
285 } 289 }
286 290
287 unlock_kernel(); 291 mutex_unlock(&vcp->vc_mutex);
288 return err; 292 return err;
289} 293}
290 294
@@ -299,7 +303,7 @@ static int coda_psdev_release(struct inode * inode, struct file * file)
299 return -1; 303 return -1;
300 } 304 }
301 305
302 lock_kernel(); 306 mutex_lock(&vcp->vc_mutex);
303 307
304 /* Wakeup clients so they can return. */ 308 /* Wakeup clients so they can return. */
305 list_for_each_entry_safe(req, tmp, &vcp->vc_pending, uc_chain) { 309 list_for_each_entry_safe(req, tmp, &vcp->vc_pending, uc_chain) {
@@ -324,7 +328,7 @@ static int coda_psdev_release(struct inode * inode, struct file * file)
324 328
325 file->private_data = NULL; 329 file->private_data = NULL;
326 vcp->vc_inuse--; 330 vcp->vc_inuse--;
327 unlock_kernel(); 331 mutex_unlock(&vcp->vc_mutex);
328 return 0; 332 return 0;
329} 333}
330 334
@@ -353,9 +357,11 @@ static int init_coda_psdev(void)
353 err = PTR_ERR(coda_psdev_class); 357 err = PTR_ERR(coda_psdev_class);
354 goto out_chrdev; 358 goto out_chrdev;
355 } 359 }
356 for (i = 0; i < MAX_CODADEVS; i++) 360 for (i = 0; i < MAX_CODADEVS; i++) {
361 mutex_init(&(&coda_comms[i])->vc_mutex);
357 device_create(coda_psdev_class, NULL, 362 device_create(coda_psdev_class, NULL,
358 MKDEV(CODA_PSDEV_MAJOR, i), NULL, "cfs%d", i); 363 MKDEV(CODA_PSDEV_MAJOR, i), NULL, "cfs%d", i);
364 }
359 coda_sysctl_init(); 365 coda_sysctl_init();
360 goto out; 366 goto out;
361 367
diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c
index 4c258cb5266d..c3563cab9758 100644
--- a/fs/coda/upcall.c
+++ b/fs/coda/upcall.c
@@ -27,7 +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 <linux/mutex.h>
31#include <asm/uaccess.h> 31#include <asm/uaccess.h>
32#include <linux/vmalloc.h> 32#include <linux/vmalloc.h>
33#include <linux/vfs.h> 33#include <linux/vfs.h>
@@ -607,7 +607,8 @@ static void coda_unblock_signals(sigset_t *old)
607 (r)->uc_opcode != CODA_RELEASE) || \ 607 (r)->uc_opcode != CODA_RELEASE) || \
608 (r)->uc_flags & CODA_REQ_READ)) 608 (r)->uc_flags & CODA_REQ_READ))
609 609
610static inline void coda_waitfor_upcall(struct upc_req *req) 610static inline void coda_waitfor_upcall(struct venus_comm *vcp,
611 struct upc_req *req)
611{ 612{
612 DECLARE_WAITQUEUE(wait, current); 613 DECLARE_WAITQUEUE(wait, current);
613 unsigned long timeout = jiffies + coda_timeout * HZ; 614 unsigned long timeout = jiffies + coda_timeout * HZ;
@@ -640,10 +641,12 @@ static inline void coda_waitfor_upcall(struct upc_req *req)
640 break; 641 break;
641 } 642 }
642 643
644 mutex_unlock(&vcp->vc_mutex);
643 if (blocked) 645 if (blocked)
644 schedule_timeout(HZ); 646 schedule_timeout(HZ);
645 else 647 else
646 schedule(); 648 schedule();
649 mutex_lock(&vcp->vc_mutex);
647 } 650 }
648 if (blocked) 651 if (blocked)
649 coda_unblock_signals(&old); 652 coda_unblock_signals(&old);
@@ -671,7 +674,7 @@ static int coda_upcall(struct venus_comm *vcp,
671 struct upc_req *req = NULL, *sig_req; 674 struct upc_req *req = NULL, *sig_req;
672 int error; 675 int error;
673 676
674 lock_kernel(); 677 mutex_lock(&vcp->vc_mutex);
675 678
676 if (!vcp->vc_inuse) { 679 if (!vcp->vc_inuse) {
677 printk(KERN_NOTICE "coda: Venus dead, not sending upcall\n"); 680 printk(KERN_NOTICE "coda: Venus dead, not sending upcall\n");
@@ -711,7 +714,7 @@ static int coda_upcall(struct venus_comm *vcp,
711 * ENODEV. */ 714 * ENODEV. */
712 715
713 /* Go to sleep. Wake up on signals only after the timeout. */ 716 /* Go to sleep. Wake up on signals only after the timeout. */
714 coda_waitfor_upcall(req); 717 coda_waitfor_upcall(vcp, req);
715 718
716 /* Op went through, interrupt or not... */ 719 /* Op went through, interrupt or not... */
717 if (req->uc_flags & CODA_REQ_WRITE) { 720 if (req->uc_flags & CODA_REQ_WRITE) {
@@ -765,7 +768,7 @@ static int coda_upcall(struct venus_comm *vcp,
765 768
766exit: 769exit:
767 kfree(req); 770 kfree(req);
768 unlock_kernel(); 771 mutex_unlock(&vcp->vc_mutex);
769 return error; 772 return error;
770} 773}
771 774
@@ -806,11 +809,11 @@ exit:
806int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out) 809int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out)
807{ 810{
808 struct inode *inode = NULL; 811 struct inode *inode = NULL;
809 struct CodaFid *fid, *newfid; 812 struct CodaFid *fid = NULL, *newfid;
810 struct super_block *sb; 813 struct super_block *sb;
811 814
812 /* Handle invalidation requests. */ 815 /* Handle invalidation requests. */
813 lock_kernel(); 816 mutex_lock(&vcp->vc_mutex);
814 sb = vcp->vc_sb; 817 sb = vcp->vc_sb;
815 if (!sb || !sb->s_root) 818 if (!sb || !sb->s_root)
816 goto unlock_out; 819 goto unlock_out;
@@ -829,47 +832,53 @@ int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out)
829 832
830 case CODA_ZAPDIR: 833 case CODA_ZAPDIR:
831 fid = &out->coda_zapdir.CodaFid; 834 fid = &out->coda_zapdir.CodaFid;
832 inode = coda_fid_to_inode(fid, sb);
833 if (inode) {
834 coda_flag_inode_children(inode, C_PURGE);
835 coda_flag_inode(inode, C_VATTR);
836 }
837 break; 835 break;
838 836
839 case CODA_ZAPFILE: 837 case CODA_ZAPFILE:
840 fid = &out->coda_zapfile.CodaFid; 838 fid = &out->coda_zapfile.CodaFid;
841 inode = coda_fid_to_inode(fid, sb);
842 if (inode)
843 coda_flag_inode(inode, C_VATTR);
844 break; 839 break;
845 840
846 case CODA_PURGEFID: 841 case CODA_PURGEFID:
847 fid = &out->coda_purgefid.CodaFid; 842 fid = &out->coda_purgefid.CodaFid;
848 inode = coda_fid_to_inode(fid, sb);
849 if (inode) {
850 coda_flag_inode_children(inode, C_PURGE);
851
852 /* catch the dentries later if some are still busy */
853 coda_flag_inode(inode, C_PURGE);
854 d_prune_aliases(inode);
855
856 }
857 break; 843 break;
858 844
859 case CODA_REPLACE: 845 case CODA_REPLACE:
860 fid = &out->coda_replace.OldFid; 846 fid = &out->coda_replace.OldFid;
861 newfid = &out->coda_replace.NewFid;
862 inode = coda_fid_to_inode(fid, sb);
863 if (inode)
864 coda_replace_fid(inode, fid, newfid);
865 break; 847 break;
866 } 848 }
849 if (fid)
850 inode = coda_fid_to_inode(fid, sb);
867 851
868unlock_out: 852unlock_out:
869 unlock_kernel(); 853 mutex_unlock(&vcp->vc_mutex);
854
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 870
871 if (inode) 871 /* catch the dentries later if some are still busy */
872 iput(inode); 872 coda_flag_inode(inode, C_PURGE);
873 d_prune_aliases(inode);
874 break;
875
876 case CODA_REPLACE:
877 newfid = &out->coda_replace.NewFid;
878 coda_replace_fid(inode, fid, newfid);
879 break;
880 }
881 iput(inode);
873 return 0; 882 return 0;
874} 883}
875 884
diff --git a/include/linux/coda_psdev.h b/include/linux/coda_psdev.h
index 1e60c5a41a5b..72f2d2f0af91 100644
--- a/include/linux/coda_psdev.h
+++ b/include/linux/coda_psdev.h
@@ -8,6 +8,7 @@
8 8
9#ifdef __KERNEL__ 9#ifdef __KERNEL__
10#include <linux/backing-dev.h> 10#include <linux/backing-dev.h>
11#include <linux/mutex.h>
11 12
12struct kstatfs; 13struct kstatfs;
13 14
@@ -20,6 +21,7 @@ struct venus_comm {
20 int vc_inuse; 21 int vc_inuse;
21 struct super_block *vc_sb; 22 struct super_block *vc_sb;
22 struct backing_dev_info bdi; 23 struct backing_dev_info bdi;
24 struct mutex vc_mutex;
23}; 25};
24 26
25 27