diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-19 22:53:01 -0400 |
---|---|---|
committer | Jonathan Corbet <corbet@lwn.net> | 2008-06-20 16:05:54 -0400 |
commit | 8f5934278d1d86590244c2791b28f77d67466007 (patch) | |
tree | 7db64d90ad2b1bd9d0c2e13b3b679a5a7d17f969 /fs/msdos/namei.c | |
parent | 5ca6a93d802a9d110127556e5d3ed032fd273e03 (diff) |
Replace BKL with superblock lock in fat/msdos/vfat
This replaces the use of the BKL in the FAT family of filesystems with the
existing superblock lock instead.
The code already appears to do mostly proper locking with its own private
spinlocks (and mutexes), but while the BKL could possibly have been
dropped entirely, converting it to use the superblock lock (which is just
a regular mutex) is the conservative thing to do.
As a per-filesystem mutex, it not only won't have any of the possible
latency issues related to the BKL, but the lock is obviously private to
the particular filesystem instance and will thus not cause problems for
entirely unrelated users like the BKL can.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Diffstat (limited to 'fs/msdos/namei.c')
-rw-r--r-- | fs/msdos/namei.c | 35 |
1 files changed, 19 insertions, 16 deletions
diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c index 05ff4f1d7026..1f7f2956412a 100644 --- a/fs/msdos/namei.c +++ b/fs/msdos/namei.c | |||
@@ -214,7 +214,7 @@ static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry, | |||
214 | 214 | ||
215 | dentry->d_op = &msdos_dentry_operations; | 215 | dentry->d_op = &msdos_dentry_operations; |
216 | 216 | ||
217 | lock_kernel(); | 217 | lock_super(sb); |
218 | res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo); | 218 | res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo); |
219 | if (res == -ENOENT) | 219 | if (res == -ENOENT) |
220 | goto add; | 220 | goto add; |
@@ -232,7 +232,7 @@ add: | |||
232 | if (dentry) | 232 | if (dentry) |
233 | dentry->d_op = &msdos_dentry_operations; | 233 | dentry->d_op = &msdos_dentry_operations; |
234 | out: | 234 | out: |
235 | unlock_kernel(); | 235 | unlock_super(sb); |
236 | if (!res) | 236 | if (!res) |
237 | return dentry; | 237 | return dentry; |
238 | return ERR_PTR(res); | 238 | return ERR_PTR(res); |
@@ -286,7 +286,7 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, int mode, | |||
286 | unsigned char msdos_name[MSDOS_NAME]; | 286 | unsigned char msdos_name[MSDOS_NAME]; |
287 | int err, is_hid; | 287 | int err, is_hid; |
288 | 288 | ||
289 | lock_kernel(); | 289 | lock_super(sb); |
290 | 290 | ||
291 | err = msdos_format_name(dentry->d_name.name, dentry->d_name.len, | 291 | err = msdos_format_name(dentry->d_name.name, dentry->d_name.len, |
292 | msdos_name, &MSDOS_SB(sb)->options); | 292 | msdos_name, &MSDOS_SB(sb)->options); |
@@ -315,7 +315,7 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, int mode, | |||
315 | 315 | ||
316 | d_instantiate(dentry, inode); | 316 | d_instantiate(dentry, inode); |
317 | out: | 317 | out: |
318 | unlock_kernel(); | 318 | unlock_super(sb); |
319 | if (!err) | 319 | if (!err) |
320 | err = fat_flush_inodes(sb, dir, inode); | 320 | err = fat_flush_inodes(sb, dir, inode); |
321 | return err; | 321 | return err; |
@@ -324,11 +324,12 @@ out: | |||
324 | /***** Remove a directory */ | 324 | /***** Remove a directory */ |
325 | static int msdos_rmdir(struct inode *dir, struct dentry *dentry) | 325 | static int msdos_rmdir(struct inode *dir, struct dentry *dentry) |
326 | { | 326 | { |
327 | struct super_block *sb = dir->i_sb; | ||
327 | struct inode *inode = dentry->d_inode; | 328 | struct inode *inode = dentry->d_inode; |
328 | struct fat_slot_info sinfo; | 329 | struct fat_slot_info sinfo; |
329 | int err; | 330 | int err; |
330 | 331 | ||
331 | lock_kernel(); | 332 | lock_super(sb); |
332 | /* | 333 | /* |
333 | * Check whether the directory is not in use, then check | 334 | * Check whether the directory is not in use, then check |
334 | * whether it is empty. | 335 | * whether it is empty. |
@@ -349,9 +350,9 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry) | |||
349 | inode->i_ctime = CURRENT_TIME_SEC; | 350 | inode->i_ctime = CURRENT_TIME_SEC; |
350 | fat_detach(inode); | 351 | fat_detach(inode); |
351 | out: | 352 | out: |
352 | unlock_kernel(); | 353 | unlock_super(sb); |
353 | if (!err) | 354 | if (!err) |
354 | err = fat_flush_inodes(inode->i_sb, dir, inode); | 355 | err = fat_flush_inodes(sb, dir, inode); |
355 | 356 | ||
356 | return err; | 357 | return err; |
357 | } | 358 | } |
@@ -366,7 +367,7 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
366 | struct timespec ts; | 367 | struct timespec ts; |
367 | int err, is_hid, cluster; | 368 | int err, is_hid, cluster; |
368 | 369 | ||
369 | lock_kernel(); | 370 | lock_super(sb); |
370 | 371 | ||
371 | err = msdos_format_name(dentry->d_name.name, dentry->d_name.len, | 372 | err = msdos_format_name(dentry->d_name.name, dentry->d_name.len, |
372 | msdos_name, &MSDOS_SB(sb)->options); | 373 | msdos_name, &MSDOS_SB(sb)->options); |
@@ -404,14 +405,14 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
404 | 405 | ||
405 | d_instantiate(dentry, inode); | 406 | d_instantiate(dentry, inode); |
406 | 407 | ||
407 | unlock_kernel(); | 408 | unlock_super(sb); |
408 | fat_flush_inodes(sb, dir, inode); | 409 | fat_flush_inodes(sb, dir, inode); |
409 | return 0; | 410 | return 0; |
410 | 411 | ||
411 | out_free: | 412 | out_free: |
412 | fat_free_clusters(dir, cluster); | 413 | fat_free_clusters(dir, cluster); |
413 | out: | 414 | out: |
414 | unlock_kernel(); | 415 | unlock_super(sb); |
415 | return err; | 416 | return err; |
416 | } | 417 | } |
417 | 418 | ||
@@ -419,10 +420,11 @@ out: | |||
419 | static int msdos_unlink(struct inode *dir, struct dentry *dentry) | 420 | static int msdos_unlink(struct inode *dir, struct dentry *dentry) |
420 | { | 421 | { |
421 | struct inode *inode = dentry->d_inode; | 422 | struct inode *inode = dentry->d_inode; |
423 | struct super_block *sb= inode->i_sb; | ||
422 | struct fat_slot_info sinfo; | 424 | struct fat_slot_info sinfo; |
423 | int err; | 425 | int err; |
424 | 426 | ||
425 | lock_kernel(); | 427 | lock_super(sb); |
426 | err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo); | 428 | err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo); |
427 | if (err) | 429 | if (err) |
428 | goto out; | 430 | goto out; |
@@ -434,9 +436,9 @@ static int msdos_unlink(struct inode *dir, struct dentry *dentry) | |||
434 | inode->i_ctime = CURRENT_TIME_SEC; | 436 | inode->i_ctime = CURRENT_TIME_SEC; |
435 | fat_detach(inode); | 437 | fat_detach(inode); |
436 | out: | 438 | out: |
437 | unlock_kernel(); | 439 | unlock_super(sb); |
438 | if (!err) | 440 | if (!err) |
439 | err = fat_flush_inodes(inode->i_sb, dir, inode); | 441 | err = fat_flush_inodes(sb, dir, inode); |
440 | 442 | ||
441 | return err; | 443 | return err; |
442 | } | 444 | } |
@@ -618,10 +620,11 @@ error_inode: | |||
618 | static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry, | 620 | static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry, |
619 | struct inode *new_dir, struct dentry *new_dentry) | 621 | struct inode *new_dir, struct dentry *new_dentry) |
620 | { | 622 | { |
623 | struct super_block *sb = old_dir->i_sb; | ||
621 | unsigned char old_msdos_name[MSDOS_NAME], new_msdos_name[MSDOS_NAME]; | 624 | unsigned char old_msdos_name[MSDOS_NAME], new_msdos_name[MSDOS_NAME]; |
622 | int err, is_hid; | 625 | int err, is_hid; |
623 | 626 | ||
624 | lock_kernel(); | 627 | lock_super(sb); |
625 | 628 | ||
626 | err = msdos_format_name(old_dentry->d_name.name, | 629 | err = msdos_format_name(old_dentry->d_name.name, |
627 | old_dentry->d_name.len, old_msdos_name, | 630 | old_dentry->d_name.len, old_msdos_name, |
@@ -640,9 +643,9 @@ static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
640 | err = do_msdos_rename(old_dir, old_msdos_name, old_dentry, | 643 | err = do_msdos_rename(old_dir, old_msdos_name, old_dentry, |
641 | new_dir, new_msdos_name, new_dentry, is_hid); | 644 | new_dir, new_msdos_name, new_dentry, is_hid); |
642 | out: | 645 | out: |
643 | unlock_kernel(); | 646 | unlock_super(sb); |
644 | if (!err) | 647 | if (!err) |
645 | err = fat_flush_inodes(old_dir->i_sb, old_dir, new_dir); | 648 | err = fat_flush_inodes(sb, old_dir, new_dir); |
646 | return err; | 649 | return err; |
647 | } | 650 | } |
648 | 651 | ||