Commit da47c19e5c746829042933c8f945a71e2b62d6fc
Committed by
Linus Torvalds
1 parent
f7cc02b871
Exists in
master
and in
7 other branches
Coda: replace BKL with mutex
Replace the BKL with a mutex to protect the venus_comm structure which binds the mountpoint with the character device and holds the upcall queues. Signed-off-by: Yoshihisa Abe <yoshiabe@cs.cmu.edu> Signed-off-by: Jan Harkes <jaharkes@cs.cmu.edu> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 4 changed files with 70 additions and 50 deletions Side-by-side Diff
fs/coda/inode.c
... | ... | @@ -15,7 +15,7 @@ |
15 | 15 | #include <linux/stat.h> |
16 | 16 | #include <linux/errno.h> |
17 | 17 | #include <linux/unistd.h> |
18 | -#include <linux/smp_lock.h> | |
18 | +#include <linux/mutex.h> | |
19 | 19 | #include <linux/spinlock.h> |
20 | 20 | #include <linux/file.h> |
21 | 21 | #include <linux/vfs.h> |
... | ... | @@ -145,7 +145,7 @@ |
145 | 145 | static int coda_fill_super(struct super_block *sb, void *data, int silent) |
146 | 146 | { |
147 | 147 | struct inode *root = NULL; |
148 | - struct venus_comm *vc = NULL; | |
148 | + struct venus_comm *vc; | |
149 | 149 | struct CodaFid fid; |
150 | 150 | int error; |
151 | 151 | int idx; |
... | ... | @@ -159,7 +159,7 @@ |
159 | 159 | printk(KERN_INFO "coda_read_super: device index: %i\n", idx); |
160 | 160 | |
161 | 161 | vc = &coda_comms[idx]; |
162 | - lock_kernel(); | |
162 | + mutex_lock(&vc->vc_mutex); | |
163 | 163 | |
164 | 164 | if (!vc->vc_inuse) { |
165 | 165 | printk("coda_read_super: No pseudo device\n"); |
... | ... | @@ -178,7 +178,7 @@ |
178 | 178 | goto unlock_out; |
179 | 179 | |
180 | 180 | vc->vc_sb = sb; |
181 | - unlock_kernel(); | |
181 | + mutex_unlock(&vc->vc_mutex); | |
182 | 182 | |
183 | 183 | sb->s_fs_info = vc; |
184 | 184 | sb->s_flags |= MS_NOATIME; |
185 | 185 | |
186 | 186 | |
187 | 187 | |
... | ... | @@ -217,20 +217,23 @@ |
217 | 217 | if (root) |
218 | 218 | iput(root); |
219 | 219 | |
220 | - lock_kernel(); | |
220 | + mutex_lock(&vc->vc_mutex); | |
221 | 221 | bdi_destroy(&vc->bdi); |
222 | 222 | vc->vc_sb = NULL; |
223 | 223 | sb->s_fs_info = NULL; |
224 | 224 | unlock_out: |
225 | - unlock_kernel(); | |
225 | + mutex_unlock(&vc->vc_mutex); | |
226 | 226 | return error; |
227 | 227 | } |
228 | 228 | |
229 | 229 | static void coda_put_super(struct super_block *sb) |
230 | 230 | { |
231 | - bdi_destroy(&coda_vcp(sb)->bdi); | |
232 | - coda_vcp(sb)->vc_sb = NULL; | |
231 | + struct venus_comm *vcp = coda_vcp(sb); | |
232 | + mutex_lock(&vcp->vc_mutex); | |
233 | + bdi_destroy(&vcp->bdi); | |
234 | + vcp->vc_sb = NULL; | |
233 | 235 | sb->s_fs_info = NULL; |
236 | + mutex_unlock(&vcp->vc_mutex); | |
234 | 237 | |
235 | 238 | printk("Coda: Bye bye.\n"); |
236 | 239 | } |
fs/coda/psdev.c
... | ... | @@ -35,7 +35,7 @@ |
35 | 35 | #include <linux/poll.h> |
36 | 36 | #include <linux/init.h> |
37 | 37 | #include <linux/list.h> |
38 | -#include <linux/smp_lock.h> | |
38 | +#include <linux/mutex.h> | |
39 | 39 | #include <linux/device.h> |
40 | 40 | #include <asm/io.h> |
41 | 41 | #include <asm/system.h> |
42 | 42 | |
... | ... | @@ -67,8 +67,10 @@ |
67 | 67 | unsigned int mask = POLLOUT | POLLWRNORM; |
68 | 68 | |
69 | 69 | poll_wait(file, &vcp->vc_waitq, wait); |
70 | + mutex_lock(&vcp->vc_mutex); | |
70 | 71 | if (!list_empty(&vcp->vc_pending)) |
71 | 72 | mask |= POLLIN | POLLRDNORM; |
73 | + mutex_unlock(&vcp->vc_mutex); | |
72 | 74 | |
73 | 75 | return mask; |
74 | 76 | } |
... | ... | @@ -143,7 +145,7 @@ |
143 | 145 | } |
144 | 146 | |
145 | 147 | /* Look for the message on the processing queue. */ |
146 | - lock_kernel(); | |
148 | + mutex_lock(&vcp->vc_mutex); | |
147 | 149 | list_for_each(lh, &vcp->vc_processing) { |
148 | 150 | tmp = list_entry(lh, struct upc_req , uc_chain); |
149 | 151 | if (tmp->uc_unique == hdr.unique) { |
... | ... | @@ -152,7 +154,7 @@ |
152 | 154 | break; |
153 | 155 | } |
154 | 156 | } |
155 | - unlock_kernel(); | |
157 | + mutex_unlock(&vcp->vc_mutex); | |
156 | 158 | |
157 | 159 | if (!req) { |
158 | 160 | printk("psdev_write: msg (%d, %d) not found\n", |
... | ... | @@ -207,7 +209,7 @@ |
207 | 209 | if (nbytes == 0) |
208 | 210 | return 0; |
209 | 211 | |
210 | - lock_kernel(); | |
212 | + mutex_lock(&vcp->vc_mutex); | |
211 | 213 | |
212 | 214 | add_wait_queue(&vcp->vc_waitq, &wait); |
213 | 215 | set_current_state(TASK_INTERRUPTIBLE); |
214 | 216 | |
... | ... | @@ -221,7 +223,9 @@ |
221 | 223 | retval = -ERESTARTSYS; |
222 | 224 | break; |
223 | 225 | } |
226 | + mutex_unlock(&vcp->vc_mutex); | |
224 | 227 | schedule(); |
228 | + mutex_lock(&vcp->vc_mutex); | |
225 | 229 | } |
226 | 230 | |
227 | 231 | set_current_state(TASK_RUNNING); |
... | ... | @@ -254,7 +258,7 @@ |
254 | 258 | CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr)); |
255 | 259 | kfree(req); |
256 | 260 | out: |
257 | - unlock_kernel(); | |
261 | + mutex_unlock(&vcp->vc_mutex); | |
258 | 262 | return (count ? count : retval); |
259 | 263 | } |
260 | 264 | |
261 | 265 | |
... | ... | @@ -267,10 +271,10 @@ |
267 | 271 | if (idx < 0 || idx >= MAX_CODADEVS) |
268 | 272 | return -ENODEV; |
269 | 273 | |
270 | - lock_kernel(); | |
271 | - | |
272 | 274 | err = -EBUSY; |
273 | 275 | vcp = &coda_comms[idx]; |
276 | + mutex_lock(&vcp->vc_mutex); | |
277 | + | |
274 | 278 | if (!vcp->vc_inuse) { |
275 | 279 | vcp->vc_inuse++; |
276 | 280 | |
... | ... | @@ -284,7 +288,7 @@ |
284 | 288 | err = 0; |
285 | 289 | } |
286 | 290 | |
287 | - unlock_kernel(); | |
291 | + mutex_unlock(&vcp->vc_mutex); | |
288 | 292 | return err; |
289 | 293 | } |
290 | 294 | |
... | ... | @@ -299,7 +303,7 @@ |
299 | 303 | return -1; |
300 | 304 | } |
301 | 305 | |
302 | - lock_kernel(); | |
306 | + mutex_lock(&vcp->vc_mutex); | |
303 | 307 | |
304 | 308 | /* Wakeup clients so they can return. */ |
305 | 309 | list_for_each_entry_safe(req, tmp, &vcp->vc_pending, uc_chain) { |
... | ... | @@ -324,7 +328,7 @@ |
324 | 328 | |
325 | 329 | file->private_data = NULL; |
326 | 330 | vcp->vc_inuse--; |
327 | - unlock_kernel(); | |
331 | + mutex_unlock(&vcp->vc_mutex); | |
328 | 332 | return 0; |
329 | 333 | } |
330 | 334 | |
331 | 335 | |
... | ... | @@ -353,9 +357,11 @@ |
353 | 357 | err = PTR_ERR(coda_psdev_class); |
354 | 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 | 362 | device_create(coda_psdev_class, NULL, |
358 | 363 | MKDEV(CODA_PSDEV_MAJOR, i), NULL, "cfs%d", i); |
364 | + } | |
359 | 365 | coda_sysctl_init(); |
360 | 366 | goto out; |
361 | 367 |
fs/coda/upcall.c
... | ... | @@ -27,7 +27,7 @@ |
27 | 27 | #include <linux/errno.h> |
28 | 28 | #include <linux/string.h> |
29 | 29 | #include <linux/slab.h> |
30 | -#include <linux/smp_lock.h> | |
30 | +#include <linux/mutex.h> | |
31 | 31 | #include <asm/uaccess.h> |
32 | 32 | #include <linux/vmalloc.h> |
33 | 33 | #include <linux/vfs.h> |
... | ... | @@ -607,7 +607,8 @@ |
607 | 607 | (r)->uc_opcode != CODA_RELEASE) || \ |
608 | 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 | 613 | DECLARE_WAITQUEUE(wait, current); |
613 | 614 | unsigned long timeout = jiffies + coda_timeout * HZ; |
614 | 615 | |
... | ... | @@ -640,10 +641,12 @@ |
640 | 641 | break; |
641 | 642 | } |
642 | 643 | |
644 | + mutex_unlock(&vcp->vc_mutex); | |
643 | 645 | if (blocked) |
644 | 646 | schedule_timeout(HZ); |
645 | 647 | else |
646 | 648 | schedule(); |
649 | + mutex_lock(&vcp->vc_mutex); | |
647 | 650 | } |
648 | 651 | if (blocked) |
649 | 652 | coda_unblock_signals(&old); |
... | ... | @@ -671,7 +674,7 @@ |
671 | 674 | struct upc_req *req = NULL, *sig_req; |
672 | 675 | int error; |
673 | 676 | |
674 | - lock_kernel(); | |
677 | + mutex_lock(&vcp->vc_mutex); | |
675 | 678 | |
676 | 679 | if (!vcp->vc_inuse) { |
677 | 680 | printk(KERN_NOTICE "coda: Venus dead, not sending upcall\n"); |
... | ... | @@ -711,7 +714,7 @@ |
711 | 714 | * ENODEV. */ |
712 | 715 | |
713 | 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 | 719 | /* Op went through, interrupt or not... */ |
717 | 720 | if (req->uc_flags & CODA_REQ_WRITE) { |
... | ... | @@ -765,7 +768,7 @@ |
765 | 768 | |
766 | 769 | exit: |
767 | 770 | kfree(req); |
768 | - unlock_kernel(); | |
771 | + mutex_unlock(&vcp->vc_mutex); | |
769 | 772 | return error; |
770 | 773 | } |
771 | 774 | |
772 | 775 | |
... | ... | @@ -806,11 +809,11 @@ |
806 | 809 | int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out) |
807 | 810 | { |
808 | 811 | struct inode *inode = NULL; |
809 | - struct CodaFid *fid, *newfid; | |
812 | + struct CodaFid *fid = NULL, *newfid; | |
810 | 813 | struct super_block *sb; |
811 | 814 | |
812 | 815 | /* Handle invalidation requests. */ |
813 | - lock_kernel(); | |
816 | + mutex_lock(&vcp->vc_mutex); | |
814 | 817 | sb = vcp->vc_sb; |
815 | 818 | if (!sb || !sb->s_root) |
816 | 819 | goto unlock_out; |
817 | 820 | |
818 | 821 | |
819 | 822 | |
820 | 823 | |
821 | 824 | |
822 | 825 | |
... | ... | @@ -829,47 +832,53 @@ |
829 | 832 | |
830 | 833 | case CODA_ZAPDIR: |
831 | 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 | 835 | break; |
838 | 836 | |
839 | 837 | case CODA_ZAPFILE: |
840 | 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 | 839 | break; |
845 | 840 | |
846 | 841 | case CODA_PURGEFID: |
847 | 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 | 843 | break; |
858 | 844 | |
859 | 845 | case CODA_REPLACE: |
860 | 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 | 847 | break; |
866 | 848 | } |
849 | + if (fid) | |
850 | + inode = coda_fid_to_inode(fid, sb); | |
867 | 851 | |
868 | 852 | unlock_out: |
869 | - unlock_kernel(); | |
853 | + mutex_unlock(&vcp->vc_mutex); | |
870 | 854 | |
871 | - if (inode) | |
872 | - iput(inode); | |
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); | |
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 | 882 | return 0; |
874 | 883 | } |
include/linux/coda_psdev.h
... | ... | @@ -8,6 +8,7 @@ |
8 | 8 | |
9 | 9 | #ifdef __KERNEL__ |
10 | 10 | #include <linux/backing-dev.h> |
11 | +#include <linux/mutex.h> | |
11 | 12 | |
12 | 13 | struct kstatfs; |
13 | 14 | |
... | ... | @@ -20,6 +21,7 @@ |
20 | 21 | int vc_inuse; |
21 | 22 | struct super_block *vc_sb; |
22 | 23 | struct backing_dev_info bdi; |
24 | + struct mutex vc_mutex; | |
23 | 25 | }; |
24 | 26 | |
25 | 27 |