aboutsummaryrefslogtreecommitdiffstats
path: root/fs/vfat/namei.c
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/vfat/namei.c
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/vfat/namei.c')
-rw-r--r--fs/vfat/namei.c35
1 files changed, 19 insertions, 16 deletions
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