aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-05-19 22:53:01 -0400
committerJonathan Corbet <corbet@lwn.net>2008-06-20 16:05:54 -0400
commit8f5934278d1d86590244c2791b28f77d67466007 (patch)
tree7db64d90ad2b1bd9d0c2e13b3b679a5a7d17f969 /fs
parent5ca6a93d802a9d110127556e5d3ed032fd273e03 (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')
-rw-r--r--fs/fat/cache.c2
-rw-r--r--fs/fat/dir.c4
-rw-r--r--fs/fat/file.c12
-rw-r--r--fs/fat/inode.c26
-rw-r--r--fs/msdos/namei.c35
-rw-r--r--fs/vfat/namei.c35
6 files changed, 64 insertions, 50 deletions
diff --git a/fs/fat/cache.c b/fs/fat/cache.c
index fda25479af26..3a9ecac8d61f 100644
--- a/fs/fat/cache.c
+++ b/fs/fat/cache.c
@@ -61,7 +61,7 @@ void fat_cache_destroy(void)
61 61
62static inline struct fat_cache *fat_cache_alloc(struct inode *inode) 62static inline struct fat_cache *fat_cache_alloc(struct inode *inode)
63{ 63{
64 return kmem_cache_alloc(fat_cache_cachep, GFP_KERNEL); 64 return kmem_cache_alloc(fat_cache_cachep, GFP_NOFS);
65} 65}
66 66
67static inline void fat_cache_free(struct fat_cache *cache) 67static inline void fat_cache_free(struct fat_cache *cache)
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index 486725ee99ae..34541d06e626 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -472,7 +472,7 @@ static int __fat_readdir(struct inode *inode, struct file *filp, void *dirent,
472 loff_t cpos; 472 loff_t cpos;
473 int ret = 0; 473 int ret = 0;
474 474
475 lock_kernel(); 475 lock_super(sb);
476 476
477 cpos = filp->f_pos; 477 cpos = filp->f_pos;
478 /* Fake . and .. for the root directory. */ 478 /* Fake . and .. for the root directory. */
@@ -654,7 +654,7 @@ FillFailed:
654 if (unicode) 654 if (unicode)
655 __putname(unicode); 655 __putname(unicode);
656out: 656out:
657 unlock_kernel(); 657 unlock_super(sb);
658 return ret; 658 return ret;
659} 659}
660 660
diff --git a/fs/fat/file.c b/fs/fat/file.c
index 27cc1164ec36..7059928fb351 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -229,7 +229,8 @@ static int fat_free(struct inode *inode, int skip)
229 229
230void fat_truncate(struct inode *inode) 230void fat_truncate(struct inode *inode)
231{ 231{
232 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); 232 struct super_block *sb = inode->i_sb;
233 struct msdos_sb_info *sbi = MSDOS_SB(sb);
233 const unsigned int cluster_size = sbi->cluster_size; 234 const unsigned int cluster_size = sbi->cluster_size;
234 int nr_clusters; 235 int nr_clusters;
235 236
@@ -242,9 +243,9 @@ void fat_truncate(struct inode *inode)
242 243
243 nr_clusters = (inode->i_size + (cluster_size - 1)) >> sbi->cluster_bits; 244 nr_clusters = (inode->i_size + (cluster_size - 1)) >> sbi->cluster_bits;
244 245
245 lock_kernel(); 246 lock_super(sb);
246 fat_free(inode, nr_clusters); 247 fat_free(inode, nr_clusters);
247 unlock_kernel(); 248 unlock_super(sb);
248 fat_flush_inodes(inode->i_sb, inode, NULL); 249 fat_flush_inodes(inode->i_sb, inode, NULL);
249} 250}
250 251
@@ -297,12 +298,13 @@ static int fat_allow_set_time(struct msdos_sb_info *sbi, struct inode *inode)
297 298
298int fat_setattr(struct dentry *dentry, struct iattr *attr) 299int fat_setattr(struct dentry *dentry, struct iattr *attr)
299{ 300{
301 struct super_block *sb = dentry->d_sb;
300 struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb); 302 struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb);
301 struct inode *inode = dentry->d_inode; 303 struct inode *inode = dentry->d_inode;
302 int mask, error = 0; 304 int mask, error = 0;
303 unsigned int ia_valid; 305 unsigned int ia_valid;
304 306
305 lock_kernel(); 307 lock_super(sb);
306 308
307 /* 309 /*
308 * Expand the file. Since inode_setattr() updates ->i_size 310 * Expand the file. Since inode_setattr() updates ->i_size
@@ -356,7 +358,7 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
356 mask = sbi->options.fs_fmask; 358 mask = sbi->options.fs_fmask;
357 inode->i_mode &= S_IFMT | (S_IRWXUGO & ~mask); 359 inode->i_mode &= S_IFMT | (S_IRWXUGO & ~mask);
358out: 360out:
359 unlock_kernel(); 361 unlock_super(sb);
360 return error; 362 return error;
361} 363}
362EXPORT_SYMBOL_GPL(fat_setattr); 364EXPORT_SYMBOL_GPL(fat_setattr);
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 4e0a3dd9d677..46a4508ffd2e 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -440,14 +440,13 @@ static void fat_delete_inode(struct inode *inode)
440 440
441static void fat_clear_inode(struct inode *inode) 441static void fat_clear_inode(struct inode *inode)
442{ 442{
443 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); 443 struct super_block *sb = inode->i_sb;
444 struct msdos_sb_info *sbi = MSDOS_SB(sb);
444 445
445 lock_kernel();
446 spin_lock(&sbi->inode_hash_lock); 446 spin_lock(&sbi->inode_hash_lock);
447 fat_cache_inval_inode(inode); 447 fat_cache_inval_inode(inode);
448 hlist_del_init(&MSDOS_I(inode)->i_fat_hash); 448 hlist_del_init(&MSDOS_I(inode)->i_fat_hash);
449 spin_unlock(&sbi->inode_hash_lock); 449 spin_unlock(&sbi->inode_hash_lock);
450 unlock_kernel();
451} 450}
452 451
453static void fat_write_super(struct super_block *sb) 452static void fat_write_super(struct super_block *sb)
@@ -485,7 +484,7 @@ static struct kmem_cache *fat_inode_cachep;
485static struct inode *fat_alloc_inode(struct super_block *sb) 484static struct inode *fat_alloc_inode(struct super_block *sb)
486{ 485{
487 struct msdos_inode_info *ei; 486 struct msdos_inode_info *ei;
488 ei = kmem_cache_alloc(fat_inode_cachep, GFP_KERNEL); 487 ei = kmem_cache_alloc(fat_inode_cachep, GFP_NOFS);
489 if (!ei) 488 if (!ei)
490 return NULL; 489 return NULL;
491 return &ei->vfs_inode; 490 return &ei->vfs_inode;
@@ -567,7 +566,7 @@ retry:
567 if (inode->i_ino == MSDOS_ROOT_INO || !i_pos) 566 if (inode->i_ino == MSDOS_ROOT_INO || !i_pos)
568 return 0; 567 return 0;
569 568
570 lock_kernel(); 569 lock_super(sb);
571 bh = sb_bread(sb, i_pos >> sbi->dir_per_block_bits); 570 bh = sb_bread(sb, i_pos >> sbi->dir_per_block_bits);
572 if (!bh) { 571 if (!bh) {
573 printk(KERN_ERR "FAT: unable to read inode block " 572 printk(KERN_ERR "FAT: unable to read inode block "
@@ -579,7 +578,7 @@ retry:
579 if (i_pos != MSDOS_I(inode)->i_pos) { 578 if (i_pos != MSDOS_I(inode)->i_pos) {
580 spin_unlock(&sbi->inode_hash_lock); 579 spin_unlock(&sbi->inode_hash_lock);
581 brelse(bh); 580 brelse(bh);
582 unlock_kernel(); 581 unlock_super(sb);
583 goto retry; 582 goto retry;
584 } 583 }
585 584
@@ -606,7 +605,7 @@ retry:
606 err = sync_dirty_buffer(bh); 605 err = sync_dirty_buffer(bh);
607 brelse(bh); 606 brelse(bh);
608out: 607out:
609 unlock_kernel(); 608 unlock_super(sb);
610 return err; 609 return err;
611} 610}
612 611
@@ -736,6 +735,7 @@ fat_encode_fh(struct dentry *de, __u32 *fh, int *lenp, int connectable)
736 735
737static struct dentry *fat_get_parent(struct dentry *child) 736static struct dentry *fat_get_parent(struct dentry *child)
738{ 737{
738 struct super_block *sb = child->d_sb;
739 struct buffer_head *bh; 739 struct buffer_head *bh;
740 struct msdos_dir_entry *de; 740 struct msdos_dir_entry *de;
741 loff_t i_pos; 741 loff_t i_pos;
@@ -743,14 +743,14 @@ static struct dentry *fat_get_parent(struct dentry *child)
743 struct inode *inode; 743 struct inode *inode;
744 int err; 744 int err;
745 745
746 lock_kernel(); 746 lock_super(sb);
747 747
748 err = fat_get_dotdot_entry(child->d_inode, &bh, &de, &i_pos); 748 err = fat_get_dotdot_entry(child->d_inode, &bh, &de, &i_pos);
749 if (err) { 749 if (err) {
750 parent = ERR_PTR(err); 750 parent = ERR_PTR(err);
751 goto out; 751 goto out;
752 } 752 }
753 inode = fat_build_inode(child->d_sb, de, i_pos); 753 inode = fat_build_inode(sb, de, i_pos);
754 brelse(bh); 754 brelse(bh);
755 if (IS_ERR(inode)) { 755 if (IS_ERR(inode)) {
756 parent = ERR_CAST(inode); 756 parent = ERR_CAST(inode);
@@ -762,7 +762,7 @@ static struct dentry *fat_get_parent(struct dentry *child)
762 parent = ERR_PTR(-ENOMEM); 762 parent = ERR_PTR(-ENOMEM);
763 } 763 }
764out: 764out:
765 unlock_kernel(); 765 unlock_super(sb);
766 766
767 return parent; 767 return parent;
768} 768}
@@ -1172,6 +1172,12 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
1172 long error; 1172 long error;
1173 char buf[50]; 1173 char buf[50];
1174 1174
1175 /*
1176 * GFP_KERNEL is ok here, because while we do hold the
1177 * supeblock lock, memory pressure can't call back into
1178 * the filesystem, since we're only just about to mount
1179 * it and have no inodes etc active!
1180 */
1175 sbi = kzalloc(sizeof(struct msdos_sb_info), GFP_KERNEL); 1181 sbi = kzalloc(sizeof(struct msdos_sb_info), GFP_KERNEL);
1176 if (!sbi) 1182 if (!sbi)
1177 return -ENOMEM; 1183 return -ENOMEM;
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;
234out: 234out:
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);
317out: 317out:
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 */
325static int msdos_rmdir(struct inode *dir, struct dentry *dentry) 325static 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);
351out: 352out:
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
411out_free: 412out_free:
412 fat_free_clusters(dir, cluster); 413 fat_free_clusters(dir, cluster);
413out: 414out:
414 unlock_kernel(); 415 unlock_super(sb);
415 return err; 416 return err;
416} 417}
417 418
@@ -419,10 +420,11 @@ out:
419static int msdos_unlink(struct inode *dir, struct dentry *dentry) 420static 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);
436out: 438out:
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:
618static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry, 620static 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);
642out: 645out:
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
diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c
index a3522727ea5b..b546ba69be82 100644
--- a/fs/vfat/namei.c
+++ b/fs/vfat/namei.c
@@ -645,7 +645,7 @@ static int vfat_add_entry(struct inode *dir, struct qstr *qname, int is_dir,
645 if (len == 0) 645 if (len == 0)
646 return -ENOENT; 646 return -ENOENT;
647 647
648 slots = kmalloc(sizeof(*slots) * MSDOS_SLOTS, GFP_KERNEL); 648 slots = kmalloc(sizeof(*slots) * MSDOS_SLOTS, GFP_NOFS);
649 if (slots == NULL) 649 if (slots == NULL)
650 return -ENOMEM; 650 return -ENOMEM;
651 651
@@ -687,7 +687,7 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
687 struct dentry *alias; 687 struct dentry *alias;
688 int err, table; 688 int err, table;
689 689
690 lock_kernel(); 690 lock_super(sb);
691 table = (MSDOS_SB(sb)->options.name_check == 's') ? 2 : 0; 691 table = (MSDOS_SB(sb)->options.name_check == 's') ? 2 : 0;
692 dentry->d_op = &vfat_dentry_ops[table]; 692 dentry->d_op = &vfat_dentry_ops[table];
693 693
@@ -699,7 +699,7 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
699 inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos); 699 inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos);
700 brelse(sinfo.bh); 700 brelse(sinfo.bh);
701 if (IS_ERR(inode)) { 701 if (IS_ERR(inode)) {
702 unlock_kernel(); 702 unlock_super(sb);
703 return ERR_CAST(inode); 703 return ERR_CAST(inode);
704 } 704 }
705 alias = d_find_alias(inode); 705 alias = d_find_alias(inode);
@@ -708,13 +708,13 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
708 dput(alias); 708 dput(alias);
709 else { 709 else {
710 iput(inode); 710 iput(inode);
711 unlock_kernel(); 711 unlock_super(sb);
712 return alias; 712 return alias;
713 } 713 }
714 714
715 } 715 }
716error: 716error:
717 unlock_kernel(); 717 unlock_super(sb);
718 dentry->d_op = &vfat_dentry_ops[table]; 718 dentry->d_op = &vfat_dentry_ops[table];
719 dentry->d_time = dentry->d_parent->d_inode->i_version; 719 dentry->d_time = dentry->d_parent->d_inode->i_version;
720 dentry = d_splice_alias(inode, dentry); 720 dentry = d_splice_alias(inode, dentry);
@@ -734,7 +734,7 @@ static int vfat_create(struct inode *dir, struct dentry *dentry, int mode,
734 struct timespec ts; 734 struct timespec ts;
735 int err; 735 int err;
736 736
737 lock_kernel(); 737 lock_super(sb);
738 738
739 ts = CURRENT_TIME_SEC; 739 ts = CURRENT_TIME_SEC;
740 err = vfat_add_entry(dir, &dentry->d_name, 0, 0, &ts, &sinfo); 740 err = vfat_add_entry(dir, &dentry->d_name, 0, 0, &ts, &sinfo);
@@ -755,17 +755,18 @@ static int vfat_create(struct inode *dir, struct dentry *dentry, int mode,
755 dentry->d_time = dentry->d_parent->d_inode->i_version; 755 dentry->d_time = dentry->d_parent->d_inode->i_version;
756 d_instantiate(dentry, inode); 756 d_instantiate(dentry, inode);
757out: 757out:
758 unlock_kernel(); 758 unlock_super(sb);
759 return err; 759 return err;
760} 760}
761 761
762static int vfat_rmdir(struct inode *dir, struct dentry *dentry) 762static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
763{ 763{
764 struct inode *inode = dentry->d_inode; 764 struct inode *inode = dentry->d_inode;
765 struct super_block *sb = dir->i_sb;
765 struct fat_slot_info sinfo; 766 struct fat_slot_info sinfo;
766 int err; 767 int err;
767 768
768 lock_kernel(); 769 lock_super(sb);
769 770
770 err = fat_dir_empty(inode); 771 err = fat_dir_empty(inode);
771 if (err) 772 if (err)
@@ -783,7 +784,7 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
783 inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC; 784 inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
784 fat_detach(inode); 785 fat_detach(inode);
785out: 786out:
786 unlock_kernel(); 787 unlock_super(sb);
787 788
788 return err; 789 return err;
789} 790}
@@ -791,10 +792,11 @@ out:
791static int vfat_unlink(struct inode *dir, struct dentry *dentry) 792static int vfat_unlink(struct inode *dir, struct dentry *dentry)
792{ 793{
793 struct inode *inode = dentry->d_inode; 794 struct inode *inode = dentry->d_inode;
795 struct super_block *sb = dir->i_sb;
794 struct fat_slot_info sinfo; 796 struct fat_slot_info sinfo;
795 int err; 797 int err;
796 798
797 lock_kernel(); 799 lock_super(sb);
798 800
799 err = vfat_find(dir, &dentry->d_name, &sinfo); 801 err = vfat_find(dir, &dentry->d_name, &sinfo);
800 if (err) 802 if (err)
@@ -807,7 +809,7 @@ static int vfat_unlink(struct inode *dir, struct dentry *dentry)
807 inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC; 809 inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
808 fat_detach(inode); 810 fat_detach(inode);
809out: 811out:
810 unlock_kernel(); 812 unlock_super(sb);
811 813
812 return err; 814 return err;
813} 815}
@@ -820,7 +822,7 @@ static int vfat_mkdir(struct inode *dir, struct dentry *dentry, int mode)
820 struct timespec ts; 822 struct timespec ts;
821 int err, cluster; 823 int err, cluster;
822 824
823 lock_kernel(); 825 lock_super(sb);
824 826
825 ts = CURRENT_TIME_SEC; 827 ts = CURRENT_TIME_SEC;
826 cluster = fat_alloc_new_dir(dir, &ts); 828 cluster = fat_alloc_new_dir(dir, &ts);
@@ -849,13 +851,13 @@ static int vfat_mkdir(struct inode *dir, struct dentry *dentry, int mode)
849 dentry->d_time = dentry->d_parent->d_inode->i_version; 851 dentry->d_time = dentry->d_parent->d_inode->i_version;
850 d_instantiate(dentry, inode); 852 d_instantiate(dentry, inode);
851 853
852 unlock_kernel(); 854 unlock_super(sb);
853 return 0; 855 return 0;
854 856
855out_free: 857out_free:
856 fat_free_clusters(dir, cluster); 858 fat_free_clusters(dir, cluster);
857out: 859out:
858 unlock_kernel(); 860 unlock_super(sb);
859 return err; 861 return err;
860} 862}
861 863
@@ -869,11 +871,12 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
869 struct timespec ts; 871 struct timespec ts;
870 loff_t dotdot_i_pos, new_i_pos; 872 loff_t dotdot_i_pos, new_i_pos;
871 int err, is_dir, update_dotdot, corrupt = 0; 873 int err, is_dir, update_dotdot, corrupt = 0;
874 struct super_block *sb = old_dir->i_sb;
872 875
873 old_sinfo.bh = sinfo.bh = dotdot_bh = NULL; 876 old_sinfo.bh = sinfo.bh = dotdot_bh = NULL;
874 old_inode = old_dentry->d_inode; 877 old_inode = old_dentry->d_inode;
875 new_inode = new_dentry->d_inode; 878 new_inode = new_dentry->d_inode;
876 lock_kernel(); 879 lock_super(sb);
877 err = vfat_find(old_dir, &old_dentry->d_name, &old_sinfo); 880 err = vfat_find(old_dir, &old_dentry->d_name, &old_sinfo);
878 if (err) 881 if (err)
879 goto out; 882 goto out;
@@ -951,7 +954,7 @@ out:
951 brelse(sinfo.bh); 954 brelse(sinfo.bh);
952 brelse(dotdot_bh); 955 brelse(dotdot_bh);
953 brelse(old_sinfo.bh); 956 brelse(old_sinfo.bh);
954 unlock_kernel(); 957 unlock_super(sb);
955 958
956 return err; 959 return err;
957 960