diff options
author | Yoshihisa Abe <yoshiabe@cs.cmu.edu> | 2010-10-25 02:03:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-25 11:02:40 -0400 |
commit | f7cc02b8715618e179242ba9cc10bdc5146ae565 (patch) | |
tree | 80c1bcf6923c9982a52fbe510cb7d396fb9866fc | |
parent | b5ce1d83a62fc109d8e815b1fc71dcdb0d26bc49 (diff) |
Coda: push BKL regions into coda_upcall()
Now that shared inode state is locked using the cii->c_lock, the BKL is
only used to protect the upcall queues used to communicate with the
userspace cache manager. The remaining state is all local and we can
push the lock further down into coda_upcall().
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>
-rw-r--r-- | fs/coda/dir.c | 149 | ||||
-rw-r--r-- | fs/coda/file.c | 19 | ||||
-rw-r--r-- | fs/coda/inode.c | 46 | ||||
-rw-r--r-- | fs/coda/pioctl.c | 22 | ||||
-rw-r--r-- | fs/coda/psdev.c | 13 | ||||
-rw-r--r-- | fs/coda/symlink.c | 3 | ||||
-rw-r--r-- | fs/coda/upcall.c | 32 | ||||
-rw-r--r-- | include/linux/coda_psdev.h | 2 |
8 files changed, 96 insertions, 190 deletions
diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 69fbbea75f1b..96fbeab77f2f 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/stat.h> | 17 | #include <linux/stat.h> |
18 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
19 | #include <linux/string.h> | 19 | #include <linux/string.h> |
20 | #include <linux/smp_lock.h> | ||
21 | #include <linux/spinlock.h> | 20 | #include <linux/spinlock.h> |
22 | 21 | ||
23 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
@@ -117,15 +116,11 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struc | |||
117 | goto exit; | 116 | goto exit; |
118 | } | 117 | } |
119 | 118 | ||
120 | lock_kernel(); | ||
121 | |||
122 | error = venus_lookup(dir->i_sb, coda_i2f(dir), name, length, | 119 | error = venus_lookup(dir->i_sb, coda_i2f(dir), name, length, |
123 | &type, &resfid); | 120 | &type, &resfid); |
124 | if (!error) | 121 | if (!error) |
125 | error = coda_cnode_make(&inode, &resfid, dir->i_sb); | 122 | error = coda_cnode_make(&inode, &resfid, dir->i_sb); |
126 | 123 | ||
127 | unlock_kernel(); | ||
128 | |||
129 | if (error && error != -ENOENT) | 124 | if (error && error != -ENOENT) |
130 | return ERR_PTR(error); | 125 | return ERR_PTR(error); |
131 | 126 | ||
@@ -141,28 +136,24 @@ exit: | |||
141 | 136 | ||
142 | int coda_permission(struct inode *inode, int mask) | 137 | int coda_permission(struct inode *inode, int mask) |
143 | { | 138 | { |
144 | int error = 0; | 139 | int error; |
145 | 140 | ||
146 | mask &= MAY_READ | MAY_WRITE | MAY_EXEC; | 141 | mask &= MAY_READ | MAY_WRITE | MAY_EXEC; |
147 | 142 | ||
148 | if (!mask) | 143 | if (!mask) |
149 | return 0; | 144 | return 0; |
150 | 145 | ||
151 | if ((mask & MAY_EXEC) && !execute_ok(inode)) | 146 | if ((mask & MAY_EXEC) && !execute_ok(inode)) |
152 | return -EACCES; | 147 | return -EACCES; |
153 | 148 | ||
154 | lock_kernel(); | ||
155 | |||
156 | if (coda_cache_check(inode, mask)) | 149 | if (coda_cache_check(inode, mask)) |
157 | goto out; | 150 | return 0; |
158 | 151 | ||
159 | error = venus_access(inode->i_sb, coda_i2f(inode), mask); | 152 | error = venus_access(inode->i_sb, coda_i2f(inode), mask); |
160 | 153 | ||
161 | if (!error) | 154 | if (!error) |
162 | coda_cache_enter(inode, mask); | 155 | coda_cache_enter(inode, mask); |
163 | 156 | ||
164 | out: | ||
165 | unlock_kernel(); | ||
166 | return error; | 157 | return error; |
167 | } | 158 | } |
168 | 159 | ||
@@ -201,41 +192,34 @@ static inline void coda_dir_drop_nlink(struct inode *dir) | |||
201 | /* creation routines: create, mknod, mkdir, link, symlink */ | 192 | /* creation routines: create, mknod, mkdir, link, symlink */ |
202 | static int coda_create(struct inode *dir, struct dentry *de, int mode, struct nameidata *nd) | 193 | static int coda_create(struct inode *dir, struct dentry *de, int mode, struct nameidata *nd) |
203 | { | 194 | { |
204 | int error=0; | 195 | int error; |
205 | const char *name=de->d_name.name; | 196 | const char *name=de->d_name.name; |
206 | int length=de->d_name.len; | 197 | int length=de->d_name.len; |
207 | struct inode *inode; | 198 | struct inode *inode; |
208 | struct CodaFid newfid; | 199 | struct CodaFid newfid; |
209 | struct coda_vattr attrs; | 200 | struct coda_vattr attrs; |
210 | 201 | ||
211 | lock_kernel(); | 202 | if (coda_isroot(dir) && coda_iscontrol(name, length)) |
212 | |||
213 | if (coda_isroot(dir) && coda_iscontrol(name, length)) { | ||
214 | unlock_kernel(); | ||
215 | return -EPERM; | 203 | return -EPERM; |
216 | } | ||
217 | 204 | ||
218 | error = venus_create(dir->i_sb, coda_i2f(dir), name, length, | 205 | error = venus_create(dir->i_sb, coda_i2f(dir), name, length, |
219 | 0, mode, &newfid, &attrs); | 206 | 0, mode, &newfid, &attrs); |
220 | 207 | if (error) | |
221 | if ( error ) { | 208 | goto err_out; |
222 | unlock_kernel(); | ||
223 | d_drop(de); | ||
224 | return error; | ||
225 | } | ||
226 | 209 | ||
227 | inode = coda_iget(dir->i_sb, &newfid, &attrs); | 210 | inode = coda_iget(dir->i_sb, &newfid, &attrs); |
228 | if ( IS_ERR(inode) ) { | 211 | if (IS_ERR(inode)) { |
229 | unlock_kernel(); | 212 | error = PTR_ERR(inode); |
230 | d_drop(de); | 213 | goto err_out; |
231 | return PTR_ERR(inode); | ||
232 | } | 214 | } |
233 | 215 | ||
234 | /* invalidate the directory cnode's attributes */ | 216 | /* invalidate the directory cnode's attributes */ |
235 | coda_dir_update_mtime(dir); | 217 | coda_dir_update_mtime(dir); |
236 | unlock_kernel(); | ||
237 | d_instantiate(de, inode); | 218 | d_instantiate(de, inode); |
238 | return 0; | 219 | return 0; |
220 | err_out: | ||
221 | d_drop(de); | ||
222 | return error; | ||
239 | } | 223 | } |
240 | 224 | ||
241 | static int coda_mkdir(struct inode *dir, struct dentry *de, int mode) | 225 | static int coda_mkdir(struct inode *dir, struct dentry *de, int mode) |
@@ -247,36 +231,29 @@ static int coda_mkdir(struct inode *dir, struct dentry *de, int mode) | |||
247 | int error; | 231 | int error; |
248 | struct CodaFid newfid; | 232 | struct CodaFid newfid; |
249 | 233 | ||
250 | lock_kernel(); | 234 | if (coda_isroot(dir) && coda_iscontrol(name, len)) |
251 | |||
252 | if (coda_isroot(dir) && coda_iscontrol(name, len)) { | ||
253 | unlock_kernel(); | ||
254 | return -EPERM; | 235 | return -EPERM; |
255 | } | ||
256 | 236 | ||
257 | attrs.va_mode = mode; | 237 | attrs.va_mode = mode; |
258 | error = venus_mkdir(dir->i_sb, coda_i2f(dir), | 238 | error = venus_mkdir(dir->i_sb, coda_i2f(dir), |
259 | name, len, &newfid, &attrs); | 239 | name, len, &newfid, &attrs); |
260 | 240 | if (error) | |
261 | if ( error ) { | 241 | goto err_out; |
262 | unlock_kernel(); | ||
263 | d_drop(de); | ||
264 | return error; | ||
265 | } | ||
266 | 242 | ||
267 | inode = coda_iget(dir->i_sb, &newfid, &attrs); | 243 | inode = coda_iget(dir->i_sb, &newfid, &attrs); |
268 | if ( IS_ERR(inode) ) { | 244 | if (IS_ERR(inode)) { |
269 | unlock_kernel(); | 245 | error = PTR_ERR(inode); |
270 | d_drop(de); | 246 | goto err_out; |
271 | return PTR_ERR(inode); | ||
272 | } | 247 | } |
273 | 248 | ||
274 | /* invalidate the directory cnode's attributes */ | 249 | /* invalidate the directory cnode's attributes */ |
275 | coda_dir_inc_nlink(dir); | 250 | coda_dir_inc_nlink(dir); |
276 | coda_dir_update_mtime(dir); | 251 | coda_dir_update_mtime(dir); |
277 | unlock_kernel(); | ||
278 | d_instantiate(de, inode); | 252 | d_instantiate(de, inode); |
279 | return 0; | 253 | return 0; |
254 | err_out: | ||
255 | d_drop(de); | ||
256 | return error; | ||
280 | } | 257 | } |
281 | 258 | ||
282 | /* try to make de an entry in dir_inodde linked to source_de */ | 259 | /* try to make de an entry in dir_inodde linked to source_de */ |
@@ -288,52 +265,38 @@ static int coda_link(struct dentry *source_de, struct inode *dir_inode, | |||
288 | int len = de->d_name.len; | 265 | int len = de->d_name.len; |
289 | int error; | 266 | int error; |
290 | 267 | ||
291 | lock_kernel(); | 268 | if (coda_isroot(dir_inode) && coda_iscontrol(name, len)) |
292 | |||
293 | if (coda_isroot(dir_inode) && coda_iscontrol(name, len)) { | ||
294 | unlock_kernel(); | ||
295 | return -EPERM; | 269 | return -EPERM; |
296 | } | ||
297 | 270 | ||
298 | error = venus_link(dir_inode->i_sb, coda_i2f(inode), | 271 | error = venus_link(dir_inode->i_sb, coda_i2f(inode), |
299 | coda_i2f(dir_inode), (const char *)name, len); | 272 | coda_i2f(dir_inode), (const char *)name, len); |
300 | |||
301 | if (error) { | 273 | if (error) { |
302 | d_drop(de); | 274 | d_drop(de); |
303 | goto out; | 275 | return error; |
304 | } | 276 | } |
305 | 277 | ||
306 | coda_dir_update_mtime(dir_inode); | 278 | coda_dir_update_mtime(dir_inode); |
307 | atomic_inc(&inode->i_count); | 279 | atomic_inc(&inode->i_count); |
308 | d_instantiate(de, inode); | 280 | d_instantiate(de, inode); |
309 | inc_nlink(inode); | 281 | inc_nlink(inode); |
310 | 282 | return 0; | |
311 | out: | ||
312 | unlock_kernel(); | ||
313 | return(error); | ||
314 | } | 283 | } |
315 | 284 | ||
316 | 285 | ||
317 | static int coda_symlink(struct inode *dir_inode, struct dentry *de, | 286 | static int coda_symlink(struct inode *dir_inode, struct dentry *de, |
318 | const char *symname) | 287 | const char *symname) |
319 | { | 288 | { |
320 | const char *name = de->d_name.name; | 289 | const char *name = de->d_name.name; |
321 | int len = de->d_name.len; | 290 | int len = de->d_name.len; |
322 | int symlen; | 291 | int symlen; |
323 | int error = 0; | 292 | int error; |
324 | |||
325 | lock_kernel(); | ||
326 | 293 | ||
327 | if (coda_isroot(dir_inode) && coda_iscontrol(name, len)) { | 294 | if (coda_isroot(dir_inode) && coda_iscontrol(name, len)) |
328 | unlock_kernel(); | ||
329 | return -EPERM; | 295 | return -EPERM; |
330 | } | ||
331 | 296 | ||
332 | symlen = strlen(symname); | 297 | symlen = strlen(symname); |
333 | if ( symlen > CODA_MAXPATHLEN ) { | 298 | if (symlen > CODA_MAXPATHLEN) |
334 | unlock_kernel(); | ||
335 | return -ENAMETOOLONG; | 299 | return -ENAMETOOLONG; |
336 | } | ||
337 | 300 | ||
338 | /* | 301 | /* |
339 | * This entry is now negative. Since we do not create | 302 | * This entry is now negative. Since we do not create |
@@ -344,10 +307,9 @@ static int coda_symlink(struct inode *dir_inode, struct dentry *de, | |||
344 | symname, symlen); | 307 | symname, symlen); |
345 | 308 | ||
346 | /* mtime is no good anymore */ | 309 | /* mtime is no good anymore */ |
347 | if ( !error ) | 310 | if (!error) |
348 | coda_dir_update_mtime(dir_inode); | 311 | coda_dir_update_mtime(dir_inode); |
349 | 312 | ||
350 | unlock_kernel(); | ||
351 | return error; | 313 | return error; |
352 | } | 314 | } |
353 | 315 | ||
@@ -358,17 +320,12 @@ static int coda_unlink(struct inode *dir, struct dentry *de) | |||
358 | const char *name = de->d_name.name; | 320 | const char *name = de->d_name.name; |
359 | int len = de->d_name.len; | 321 | int len = de->d_name.len; |
360 | 322 | ||
361 | lock_kernel(); | ||
362 | |||
363 | error = venus_remove(dir->i_sb, coda_i2f(dir), name, len); | 323 | error = venus_remove(dir->i_sb, coda_i2f(dir), name, len); |
364 | if ( error ) { | 324 | if (error) |
365 | unlock_kernel(); | ||
366 | return error; | 325 | return error; |
367 | } | ||
368 | 326 | ||
369 | coda_dir_update_mtime(dir); | 327 | coda_dir_update_mtime(dir); |
370 | drop_nlink(de->d_inode); | 328 | drop_nlink(de->d_inode); |
371 | unlock_kernel(); | ||
372 | return 0; | 329 | return 0; |
373 | } | 330 | } |
374 | 331 | ||
@@ -378,8 +335,6 @@ static int coda_rmdir(struct inode *dir, struct dentry *de) | |||
378 | int len = de->d_name.len; | 335 | int len = de->d_name.len; |
379 | int error; | 336 | int error; |
380 | 337 | ||
381 | lock_kernel(); | ||
382 | |||
383 | error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len); | 338 | error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len); |
384 | if (!error) { | 339 | if (!error) { |
385 | /* VFS may delete the child */ | 340 | /* VFS may delete the child */ |
@@ -390,7 +345,6 @@ static int coda_rmdir(struct inode *dir, struct dentry *de) | |||
390 | coda_dir_drop_nlink(dir); | 345 | coda_dir_drop_nlink(dir); |
391 | coda_dir_update_mtime(dir); | 346 | coda_dir_update_mtime(dir); |
392 | } | 347 | } |
393 | unlock_kernel(); | ||
394 | return error; | 348 | return error; |
395 | } | 349 | } |
396 | 350 | ||
@@ -404,15 +358,12 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
404 | int new_length = new_dentry->d_name.len; | 358 | int new_length = new_dentry->d_name.len; |
405 | int error; | 359 | int error; |
406 | 360 | ||
407 | lock_kernel(); | ||
408 | |||
409 | error = venus_rename(old_dir->i_sb, coda_i2f(old_dir), | 361 | error = venus_rename(old_dir->i_sb, coda_i2f(old_dir), |
410 | coda_i2f(new_dir), old_length, new_length, | 362 | coda_i2f(new_dir), old_length, new_length, |
411 | (const char *) old_name, (const char *)new_name); | 363 | (const char *) old_name, (const char *)new_name); |
412 | 364 | if (!error) { | |
413 | if ( !error ) { | 365 | if (new_dentry->d_inode) { |
414 | if ( new_dentry->d_inode ) { | 366 | if (S_ISDIR(new_dentry->d_inode->i_mode)) { |
415 | if ( S_ISDIR(new_dentry->d_inode->i_mode) ) { | ||
416 | coda_dir_drop_nlink(old_dir); | 367 | coda_dir_drop_nlink(old_dir); |
417 | coda_dir_inc_nlink(new_dir); | 368 | coda_dir_inc_nlink(new_dir); |
418 | } | 369 | } |
@@ -424,8 +375,6 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
424 | coda_flag_inode(new_dir, C_VATTR); | 375 | coda_flag_inode(new_dir, C_VATTR); |
425 | } | 376 | } |
426 | } | 377 | } |
427 | unlock_kernel(); | ||
428 | |||
429 | return error; | 378 | return error; |
430 | } | 379 | } |
431 | 380 | ||
@@ -595,10 +544,7 @@ static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd) | |||
595 | struct inode *inode = de->d_inode; | 544 | struct inode *inode = de->d_inode; |
596 | struct coda_inode_info *cii; | 545 | struct coda_inode_info *cii; |
597 | 546 | ||
598 | if (!inode) | 547 | if (!inode || coda_isroot(inode)) |
599 | return 1; | ||
600 | lock_kernel(); | ||
601 | if (coda_isroot(inode)) | ||
602 | goto out; | 548 | goto out; |
603 | if (is_bad_inode(inode)) | 549 | if (is_bad_inode(inode)) |
604 | goto bad; | 550 | goto bad; |
@@ -621,12 +567,9 @@ static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd) | |||
621 | spin_lock(&cii->c_lock); | 567 | spin_lock(&cii->c_lock); |
622 | cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH); | 568 | cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH); |
623 | spin_unlock(&cii->c_lock); | 569 | spin_unlock(&cii->c_lock); |
624 | |||
625 | bad: | 570 | bad: |
626 | unlock_kernel(); | ||
627 | return 0; | 571 | return 0; |
628 | out: | 572 | out: |
629 | unlock_kernel(); | ||
630 | return 1; | 573 | return 1; |
631 | } | 574 | } |
632 | 575 | ||
@@ -659,20 +602,19 @@ static int coda_dentry_delete(struct dentry * dentry) | |||
659 | int coda_revalidate_inode(struct dentry *dentry) | 602 | int coda_revalidate_inode(struct dentry *dentry) |
660 | { | 603 | { |
661 | struct coda_vattr attr; | 604 | struct coda_vattr attr; |
662 | int error = 0; | 605 | int error; |
663 | int old_mode; | 606 | int old_mode; |
664 | ino_t old_ino; | 607 | ino_t old_ino; |
665 | struct inode *inode = dentry->d_inode; | 608 | struct inode *inode = dentry->d_inode; |
666 | struct coda_inode_info *cii = ITOC(inode); | 609 | struct coda_inode_info *cii = ITOC(inode); |
667 | 610 | ||
668 | lock_kernel(); | 611 | if (!cii->c_flags) |
669 | if ( !cii->c_flags ) | 612 | return 0; |
670 | goto ok; | ||
671 | 613 | ||
672 | if (cii->c_flags & (C_VATTR | C_PURGE | C_FLUSH)) { | 614 | if (cii->c_flags & (C_VATTR | C_PURGE | C_FLUSH)) { |
673 | error = venus_getattr(inode->i_sb, &(cii->c_fid), &attr); | 615 | error = venus_getattr(inode->i_sb, &(cii->c_fid), &attr); |
674 | if ( error ) | 616 | if (error) |
675 | goto return_bad; | 617 | return -EIO; |
676 | 618 | ||
677 | /* this inode may be lost if: | 619 | /* this inode may be lost if: |
678 | - it's ino changed | 620 | - it's ino changed |
@@ -691,7 +633,7 @@ int coda_revalidate_inode(struct dentry *dentry) | |||
691 | /* the following can happen when a local fid is replaced | 633 | /* the following can happen when a local fid is replaced |
692 | with a global one, here we lose and declare the inode bad */ | 634 | with a global one, here we lose and declare the inode bad */ |
693 | if (inode->i_ino != old_ino) | 635 | if (inode->i_ino != old_ino) |
694 | goto return_bad; | 636 | return -EIO; |
695 | 637 | ||
696 | coda_flag_inode_children(inode, C_FLUSH); | 638 | coda_flag_inode_children(inode, C_FLUSH); |
697 | 639 | ||
@@ -699,12 +641,5 @@ int coda_revalidate_inode(struct dentry *dentry) | |||
699 | cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH); | 641 | cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH); |
700 | spin_unlock(&cii->c_lock); | 642 | spin_unlock(&cii->c_lock); |
701 | } | 643 | } |
702 | |||
703 | ok: | ||
704 | unlock_kernel(); | ||
705 | return 0; | 644 | return 0; |
706 | |||
707 | return_bad: | ||
708 | unlock_kernel(); | ||
709 | return -EIO; | ||
710 | } | 645 | } |
diff --git a/fs/coda/file.c b/fs/coda/file.c index c4e395781d41..c8b50ba4366a 100644 --- a/fs/coda/file.c +++ b/fs/coda/file.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/stat.h> | 15 | #include <linux/stat.h> |
16 | #include <linux/cred.h> | 16 | #include <linux/cred.h> |
17 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
18 | #include <linux/smp_lock.h> | ||
19 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
20 | #include <linux/string.h> | 19 | #include <linux/string.h> |
21 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
@@ -144,8 +143,6 @@ int coda_open(struct inode *coda_inode, struct file *coda_file) | |||
144 | if (!cfi) | 143 | if (!cfi) |
145 | return -ENOMEM; | 144 | return -ENOMEM; |
146 | 145 | ||
147 | lock_kernel(); | ||
148 | |||
149 | error = venus_open(coda_inode->i_sb, coda_i2f(coda_inode), coda_flags, | 146 | error = venus_open(coda_inode->i_sb, coda_i2f(coda_inode), coda_flags, |
150 | &host_file); | 147 | &host_file); |
151 | if (!host_file) | 148 | if (!host_file) |
@@ -153,7 +150,6 @@ int coda_open(struct inode *coda_inode, struct file *coda_file) | |||
153 | 150 | ||
154 | if (error) { | 151 | if (error) { |
155 | kfree(cfi); | 152 | kfree(cfi); |
156 | unlock_kernel(); | ||
157 | return error; | 153 | return error; |
158 | } | 154 | } |
159 | 155 | ||
@@ -165,8 +161,6 @@ int coda_open(struct inode *coda_inode, struct file *coda_file) | |||
165 | 161 | ||
166 | BUG_ON(coda_file->private_data != NULL); | 162 | BUG_ON(coda_file->private_data != NULL); |
167 | coda_file->private_data = cfi; | 163 | coda_file->private_data = cfi; |
168 | |||
169 | unlock_kernel(); | ||
170 | return 0; | 164 | return 0; |
171 | } | 165 | } |
172 | 166 | ||
@@ -177,9 +171,7 @@ int coda_release(struct inode *coda_inode, struct file *coda_file) | |||
177 | struct coda_file_info *cfi; | 171 | struct coda_file_info *cfi; |
178 | struct coda_inode_info *cii; | 172 | struct coda_inode_info *cii; |
179 | struct inode *host_inode; | 173 | struct inode *host_inode; |
180 | int err = 0; | 174 | int err; |
181 | |||
182 | lock_kernel(); | ||
183 | 175 | ||
184 | cfi = CODA_FTOC(coda_file); | 176 | cfi = CODA_FTOC(coda_file); |
185 | BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); | 177 | BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); |
@@ -203,8 +195,6 @@ int coda_release(struct inode *coda_inode, struct file *coda_file) | |||
203 | kfree(coda_file->private_data); | 195 | kfree(coda_file->private_data); |
204 | coda_file->private_data = NULL; | 196 | coda_file->private_data = NULL; |
205 | 197 | ||
206 | unlock_kernel(); | ||
207 | |||
208 | /* VFS fput ignores the return value from file_operations->release, so | 198 | /* VFS fput ignores the return value from file_operations->release, so |
209 | * there is no use returning an error here */ | 199 | * there is no use returning an error here */ |
210 | return 0; | 200 | return 0; |
@@ -215,7 +205,7 @@ int coda_fsync(struct file *coda_file, int datasync) | |||
215 | struct file *host_file; | 205 | struct file *host_file; |
216 | struct inode *coda_inode = coda_file->f_path.dentry->d_inode; | 206 | struct inode *coda_inode = coda_file->f_path.dentry->d_inode; |
217 | struct coda_file_info *cfi; | 207 | struct coda_file_info *cfi; |
218 | int err = 0; | 208 | int err; |
219 | 209 | ||
220 | if (!(S_ISREG(coda_inode->i_mode) || S_ISDIR(coda_inode->i_mode) || | 210 | if (!(S_ISREG(coda_inode->i_mode) || S_ISDIR(coda_inode->i_mode) || |
221 | S_ISLNK(coda_inode->i_mode))) | 211 | S_ISLNK(coda_inode->i_mode))) |
@@ -226,11 +216,8 @@ int coda_fsync(struct file *coda_file, int datasync) | |||
226 | host_file = cfi->cfi_container; | 216 | host_file = cfi->cfi_container; |
227 | 217 | ||
228 | err = vfs_fsync(host_file, datasync); | 218 | err = vfs_fsync(host_file, datasync); |
229 | if ( !err && !datasync ) { | 219 | if (!err && !datasync) |
230 | lock_kernel(); | ||
231 | err = venus_fsync(coda_inode->i_sb, coda_i2f(coda_inode)); | 220 | err = venus_fsync(coda_inode->i_sb, coda_i2f(coda_inode)); |
232 | unlock_kernel(); | ||
233 | } | ||
234 | 221 | ||
235 | return err; | 222 | return err; |
236 | } | 223 | } |
diff --git a/fs/coda/inode.c b/fs/coda/inode.c index 0553f3bd7b1b..b7fa3e3d772f 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c | |||
@@ -150,8 +150,6 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent) | |||
150 | int error; | 150 | int error; |
151 | int idx; | 151 | int idx; |
152 | 152 | ||
153 | lock_kernel(); | ||
154 | |||
155 | idx = get_device_index((struct coda_mount_data *) data); | 153 | idx = get_device_index((struct coda_mount_data *) data); |
156 | 154 | ||
157 | /* Ignore errors in data, for backward compatibility */ | 155 | /* Ignore errors in data, for backward compatibility */ |
@@ -161,23 +159,26 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent) | |||
161 | printk(KERN_INFO "coda_read_super: device index: %i\n", idx); | 159 | printk(KERN_INFO "coda_read_super: device index: %i\n", idx); |
162 | 160 | ||
163 | vc = &coda_comms[idx]; | 161 | vc = &coda_comms[idx]; |
162 | lock_kernel(); | ||
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"); |
166 | unlock_kernel(); | 166 | error = -EINVAL; |
167 | return -EINVAL; | 167 | goto unlock_out; |
168 | } | 168 | } |
169 | 169 | ||
170 | if ( vc->vc_sb ) { | 170 | if (vc->vc_sb) { |
171 | printk("coda_read_super: Device already mounted\n"); | 171 | printk("coda_read_super: Device already mounted\n"); |
172 | unlock_kernel(); | 172 | error = -EBUSY; |
173 | return -EBUSY; | 173 | goto unlock_out; |
174 | } | 174 | } |
175 | 175 | ||
176 | error = bdi_setup_and_register(&vc->bdi, "coda", BDI_CAP_MAP_COPY); | 176 | error = bdi_setup_and_register(&vc->bdi, "coda", BDI_CAP_MAP_COPY); |
177 | if (error) | 177 | if (error) |
178 | goto bdi_err; | 178 | goto unlock_out; |
179 | 179 | ||
180 | vc->vc_sb = sb; | 180 | vc->vc_sb = sb; |
181 | unlock_kernel(); | ||
181 | 182 | ||
182 | sb->s_fs_info = vc; | 183 | sb->s_fs_info = vc; |
183 | sb->s_flags |= MS_NOATIME; | 184 | sb->s_flags |= MS_NOATIME; |
@@ -206,21 +207,23 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent) | |||
206 | printk("coda_read_super: rootinode is %ld dev %s\n", | 207 | printk("coda_read_super: rootinode is %ld dev %s\n", |
207 | root->i_ino, root->i_sb->s_id); | 208 | root->i_ino, root->i_sb->s_id); |
208 | sb->s_root = d_alloc_root(root); | 209 | sb->s_root = d_alloc_root(root); |
209 | if (!sb->s_root) | 210 | if (!sb->s_root) { |
211 | error = -EINVAL; | ||
210 | goto error; | 212 | goto error; |
211 | unlock_kernel(); | 213 | } |
212 | return 0; | 214 | return 0; |
213 | 215 | ||
214 | error: | 216 | error: |
215 | bdi_destroy(&vc->bdi); | ||
216 | bdi_err: | ||
217 | if (root) | 217 | if (root) |
218 | iput(root); | 218 | iput(root); |
219 | if (vc) | ||
220 | vc->vc_sb = NULL; | ||
221 | 219 | ||
220 | lock_kernel(); | ||
221 | bdi_destroy(&vc->bdi); | ||
222 | vc->vc_sb = NULL; | ||
223 | sb->s_fs_info = NULL; | ||
224 | unlock_out: | ||
222 | unlock_kernel(); | 225 | unlock_kernel(); |
223 | return -EINVAL; | 226 | return error; |
224 | } | 227 | } |
225 | 228 | ||
226 | static void coda_put_super(struct super_block *sb) | 229 | static void coda_put_super(struct super_block *sb) |
@@ -253,8 +256,6 @@ int coda_setattr(struct dentry *de, struct iattr *iattr) | |||
253 | struct coda_vattr vattr; | 256 | struct coda_vattr vattr; |
254 | int error; | 257 | int error; |
255 | 258 | ||
256 | lock_kernel(); | ||
257 | |||
258 | memset(&vattr, 0, sizeof(vattr)); | 259 | memset(&vattr, 0, sizeof(vattr)); |
259 | 260 | ||
260 | inode->i_ctime = CURRENT_TIME_SEC; | 261 | inode->i_ctime = CURRENT_TIME_SEC; |
@@ -264,13 +265,10 @@ int coda_setattr(struct dentry *de, struct iattr *iattr) | |||
264 | /* Venus is responsible for truncating the container-file!!! */ | 265 | /* Venus is responsible for truncating the container-file!!! */ |
265 | error = venus_setattr(inode->i_sb, coda_i2f(inode), &vattr); | 266 | error = venus_setattr(inode->i_sb, coda_i2f(inode), &vattr); |
266 | 267 | ||
267 | if ( !error ) { | 268 | if (!error) { |
268 | coda_vattr_to_iattr(inode, &vattr); | 269 | coda_vattr_to_iattr(inode, &vattr); |
269 | coda_cache_clear_inode(inode); | 270 | coda_cache_clear_inode(inode); |
270 | } | 271 | } |
271 | |||
272 | unlock_kernel(); | ||
273 | |||
274 | return error; | 272 | return error; |
275 | } | 273 | } |
276 | 274 | ||
@@ -284,12 +282,8 @@ static int coda_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
284 | { | 282 | { |
285 | int error; | 283 | int error; |
286 | 284 | ||
287 | lock_kernel(); | ||
288 | |||
289 | error = venus_statfs(dentry, buf); | 285 | error = venus_statfs(dentry, buf); |
290 | 286 | ||
291 | unlock_kernel(); | ||
292 | |||
293 | if (error) { | 287 | if (error) { |
294 | /* fake something like AFS does */ | 288 | /* fake something like AFS does */ |
295 | buf->f_blocks = 9000000; | 289 | buf->f_blocks = 9000000; |
diff --git a/fs/coda/pioctl.c b/fs/coda/pioctl.c index 028a9a0f588b..2fd89b5c5c7b 100644 --- a/fs/coda/pioctl.c +++ b/fs/coda/pioctl.c | |||
@@ -23,8 +23,6 @@ | |||
23 | #include <linux/coda_fs_i.h> | 23 | #include <linux/coda_fs_i.h> |
24 | #include <linux/coda_psdev.h> | 24 | #include <linux/coda_psdev.h> |
25 | 25 | ||
26 | #include <linux/smp_lock.h> | ||
27 | |||
28 | /* pioctl ops */ | 26 | /* pioctl ops */ |
29 | static int coda_ioctl_permission(struct inode *inode, int mask); | 27 | static int coda_ioctl_permission(struct inode *inode, int mask); |
30 | static long coda_pioctl(struct file *filp, unsigned int cmd, | 28 | static long coda_pioctl(struct file *filp, unsigned int cmd, |
@@ -58,13 +56,9 @@ static long coda_pioctl(struct file *filp, unsigned int cmd, | |||
58 | struct inode *target_inode = NULL; | 56 | struct inode *target_inode = NULL; |
59 | struct coda_inode_info *cnp; | 57 | struct coda_inode_info *cnp; |
60 | 58 | ||
61 | lock_kernel(); | ||
62 | |||
63 | /* get the Pioctl data arguments from user space */ | 59 | /* get the Pioctl data arguments from user space */ |
64 | if (copy_from_user(&data, (void __user *)user_data, sizeof(data))) { | 60 | if (copy_from_user(&data, (void __user *)user_data, sizeof(data))) |
65 | error = -EINVAL; | 61 | return -EINVAL; |
66 | goto out; | ||
67 | } | ||
68 | 62 | ||
69 | /* | 63 | /* |
70 | * Look up the pathname. Note that the pathname is in | 64 | * Look up the pathname. Note that the pathname is in |
@@ -76,13 +70,12 @@ static long coda_pioctl(struct file *filp, unsigned int cmd, | |||
76 | error = user_lpath(data.path, &path); | 70 | error = user_lpath(data.path, &path); |
77 | 71 | ||
78 | if (error) | 72 | if (error) |
79 | goto out; | 73 | return error; |
80 | else | 74 | |
81 | target_inode = path.dentry->d_inode; | 75 | target_inode = path.dentry->d_inode; |
82 | 76 | ||
83 | /* return if it is not a Coda inode */ | 77 | /* return if it is not a Coda inode */ |
84 | if (target_inode->i_sb != inode->i_sb) { | 78 | if (target_inode->i_sb != inode->i_sb) { |
85 | path_put(&path); | ||
86 | error = -EINVAL; | 79 | error = -EINVAL; |
87 | goto out; | 80 | goto out; |
88 | } | 81 | } |
@@ -91,10 +84,7 @@ static long coda_pioctl(struct file *filp, unsigned int cmd, | |||
91 | cnp = ITOC(target_inode); | 84 | cnp = ITOC(target_inode); |
92 | 85 | ||
93 | error = venus_pioctl(inode->i_sb, &(cnp->c_fid), cmd, &data); | 86 | error = venus_pioctl(inode->i_sb, &(cnp->c_fid), cmd, &data); |
94 | |||
95 | path_put(&path); | ||
96 | |||
97 | out: | 87 | out: |
98 | unlock_kernel(); | 88 | path_put(&path); |
99 | return error; | 89 | return error; |
100 | } | 90 | } |
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c index fdc2f3ef7ecd..9a9248e632c6 100644 --- a/fs/coda/psdev.c +++ b/fs/coda/psdev.c | |||
@@ -108,16 +108,9 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf, | |||
108 | return -EFAULT; | 108 | return -EFAULT; |
109 | 109 | ||
110 | if (DOWNCALL(hdr.opcode)) { | 110 | if (DOWNCALL(hdr.opcode)) { |
111 | struct super_block *sb = NULL; | 111 | union outputArgs *dcbuf; |
112 | union outputArgs *dcbuf; | ||
113 | int size = sizeof(*dcbuf); | 112 | int size = sizeof(*dcbuf); |
114 | 113 | ||
115 | sb = vcp->vc_sb; | ||
116 | if ( !sb ) { | ||
117 | count = nbytes; | ||
118 | goto out; | ||
119 | } | ||
120 | |||
121 | if ( nbytes < sizeof(struct coda_out_hdr) ) { | 114 | if ( nbytes < sizeof(struct coda_out_hdr) ) { |
122 | printk("coda_downcall opc %d uniq %d, not enough!\n", | 115 | printk("coda_downcall opc %d uniq %d, not enough!\n", |
123 | hdr.opcode, hdr.unique); | 116 | hdr.opcode, hdr.unique); |
@@ -137,9 +130,7 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf, | |||
137 | } | 130 | } |
138 | 131 | ||
139 | /* what downcall errors does Venus handle ? */ | 132 | /* what downcall errors does Venus handle ? */ |
140 | lock_kernel(); | 133 | error = coda_downcall(vcp, hdr.opcode, dcbuf); |
141 | error = coda_downcall(hdr.opcode, dcbuf, sb); | ||
142 | unlock_kernel(); | ||
143 | 134 | ||
144 | CODA_FREE(dcbuf, nbytes); | 135 | CODA_FREE(dcbuf, nbytes); |
145 | if (error) { | 136 | if (error) { |
diff --git a/fs/coda/symlink.c b/fs/coda/symlink.c index 4513b7258458..af78f007a2b0 100644 --- a/fs/coda/symlink.c +++ b/fs/coda/symlink.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/stat.h> | 14 | #include <linux/stat.h> |
15 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
16 | #include <linux/pagemap.h> | 16 | #include <linux/pagemap.h> |
17 | #include <linux/smp_lock.h> | ||
18 | 17 | ||
19 | #include <linux/coda.h> | 18 | #include <linux/coda.h> |
20 | #include <linux/coda_linux.h> | 19 | #include <linux/coda_linux.h> |
@@ -29,11 +28,9 @@ static int coda_symlink_filler(struct file *file, struct page *page) | |||
29 | unsigned int len = PAGE_SIZE; | 28 | unsigned int len = PAGE_SIZE; |
30 | char *p = kmap(page); | 29 | char *p = kmap(page); |
31 | 30 | ||
32 | lock_kernel(); | ||
33 | cii = ITOC(inode); | 31 | cii = ITOC(inode); |
34 | 32 | ||
35 | error = venus_readlink(inode->i_sb, &cii->c_fid, p, &len); | 33 | error = venus_readlink(inode->i_sb, &cii->c_fid, p, &len); |
36 | unlock_kernel(); | ||
37 | if (error) | 34 | if (error) |
38 | goto fail; | 35 | goto fail; |
39 | SetPageUptodate(page); | 36 | SetPageUptodate(page); |
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 | ||
diff --git a/include/linux/coda_psdev.h b/include/linux/coda_psdev.h index 284b520934a0..1e60c5a41a5b 100644 --- a/include/linux/coda_psdev.h +++ b/include/linux/coda_psdev.h | |||
@@ -63,7 +63,7 @@ int venus_symlink(struct super_block *sb, struct CodaFid *fid, | |||
63 | int venus_access(struct super_block *sb, struct CodaFid *fid, int mask); | 63 | int venus_access(struct super_block *sb, struct CodaFid *fid, int mask); |
64 | int venus_pioctl(struct super_block *sb, struct CodaFid *fid, | 64 | int venus_pioctl(struct super_block *sb, struct CodaFid *fid, |
65 | unsigned int cmd, struct PioctlData *data); | 65 | unsigned int cmd, struct PioctlData *data); |
66 | int coda_downcall(int opcode, union outputArgs *out, struct super_block *sb); | 66 | int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out); |
67 | int venus_fsync(struct super_block *sb, struct CodaFid *fid); | 67 | int venus_fsync(struct super_block *sb, struct CodaFid *fid); |
68 | int venus_statfs(struct dentry *dentry, struct kstatfs *sfs); | 68 | int venus_statfs(struct dentry *dentry, struct kstatfs *sfs); |
69 | 69 | ||