From 8f5934278d1d86590244c2791b28f77d67466007 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 19 May 2008 19:53:01 -0700 Subject: 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 Cc: OGAWA Hirofumi Signed-off-by: Jonathan Corbet --- fs/fat/file.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'fs/fat/file.c') 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) void fat_truncate(struct inode *inode) { - struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); + struct super_block *sb = inode->i_sb; + struct msdos_sb_info *sbi = MSDOS_SB(sb); const unsigned int cluster_size = sbi->cluster_size; int nr_clusters; @@ -242,9 +243,9 @@ void fat_truncate(struct inode *inode) nr_clusters = (inode->i_size + (cluster_size - 1)) >> sbi->cluster_bits; - lock_kernel(); + lock_super(sb); fat_free(inode, nr_clusters); - unlock_kernel(); + unlock_super(sb); fat_flush_inodes(inode->i_sb, inode, NULL); } @@ -297,12 +298,13 @@ static int fat_allow_set_time(struct msdos_sb_info *sbi, struct inode *inode) int fat_setattr(struct dentry *dentry, struct iattr *attr) { + struct super_block *sb = dentry->d_sb; struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb); struct inode *inode = dentry->d_inode; int mask, error = 0; unsigned int ia_valid; - lock_kernel(); + lock_super(sb); /* * Expand the file. Since inode_setattr() updates ->i_size @@ -356,7 +358,7 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) mask = sbi->options.fs_fmask; inode->i_mode &= S_IFMT | (S_IRWXUGO & ~mask); out: - unlock_kernel(); + unlock_super(sb); return error; } EXPORT_SYMBOL_GPL(fat_setattr); -- cgit From 9c20616c385ebeaa30257ef5d35e8f346db4ee32 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 29 May 2008 17:14:05 -0600 Subject: Make FAT users happier by not deadlocking The FAT BKL removal patch can cause deadlocks. It turns out that the new lock_super() calls are unneeded, remove them (as directed by Linus). Reported-by: "Tony Luck" Signed-off-by: Jonathan Corbet --- fs/fat/file.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'fs/fat/file.c') diff --git a/fs/fat/file.c b/fs/fat/file.c index 7059928fb351..bdf91e97397d 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -229,8 +228,7 @@ static int fat_free(struct inode *inode, int skip) void fat_truncate(struct inode *inode) { - struct super_block *sb = inode->i_sb; - struct msdos_sb_info *sbi = MSDOS_SB(sb); + struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); const unsigned int cluster_size = sbi->cluster_size; int nr_clusters; @@ -243,9 +241,7 @@ void fat_truncate(struct inode *inode) nr_clusters = (inode->i_size + (cluster_size - 1)) >> sbi->cluster_bits; - lock_super(sb); fat_free(inode, nr_clusters); - unlock_super(sb); fat_flush_inodes(inode->i_sb, inode, NULL); } @@ -298,14 +294,11 @@ static int fat_allow_set_time(struct msdos_sb_info *sbi, struct inode *inode) int fat_setattr(struct dentry *dentry, struct iattr *attr) { - struct super_block *sb = dentry->d_sb; struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb); struct inode *inode = dentry->d_inode; int mask, error = 0; unsigned int ia_valid; - lock_super(sb); - /* * Expand the file. Since inode_setattr() updates ->i_size * before calling the ->truncate(), but FAT needs to fill the @@ -358,7 +351,6 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) mask = sbi->options.fs_fmask; inode->i_mode &= S_IFMT | (S_IRWXUGO & ~mask); out: - unlock_super(sb); return error; } EXPORT_SYMBOL_GPL(fat_setattr); -- cgit