diff options
-rw-r--r-- | fs/coda/inode.c | 19 | ||||
-rw-r--r-- | fs/coda/psdev.c | 28 | ||||
-rw-r--r-- | fs/coda/upcall.c | 71 | ||||
-rw-r--r-- | include/linux/coda_psdev.h | 2 |
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) | |||
145 | static int coda_fill_super(struct super_block *sb, void *data, int silent) | 145 | static 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; |
224 | unlock_out: | 224 | unlock_out: |
225 | unlock_kernel(); | 225 | mutex_unlock(&vc->vc_mutex); |
226 | return error; | 226 | return error; |
227 | } | 227 | } |
228 | 228 | ||
229 | static void coda_put_super(struct super_block *sb) | 229 | static 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); |
256 | out: | 260 | out: |
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 | ||
610 | static inline void coda_waitfor_upcall(struct upc_req *req) | 610 | static 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 | ||
766 | exit: | 769 | exit: |
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: | |||
806 | int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out) | 809 | int 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 | ||
868 | unlock_out: | 852 | unlock_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 | ||
12 | struct kstatfs; | 13 | struct 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 | ||