From db71922217a214e5c9268448e537b54fc1f301ea Mon Sep 17 00:00:00 2001 From: Jan Blunck Date: Sun, 15 Aug 2010 22:51:10 +0200 Subject: BKL: Explicitly add BKL around get_sb/fill_super This patch is a preparation necessary to remove the BKL from do_new_mount(). It explicitly adds calls to lock_kernel()/unlock_kernel() around get_sb/fill_super operations for filesystems that still uses the BKL. I've read through all the code formerly covered by the BKL inside do_kern_mount() and have satisfied myself that it doesn't need the BKL any more. do_kern_mount() is already called without the BKL when mounting the rootfs and in nfsctl. do_kern_mount() calls vfs_kern_mount(), which is called from various places without BKL: simple_pin_fs(), nfs_do_clone_mount() through nfs_follow_mountpoint(), afs_mntpt_do_automount() through afs_mntpt_follow_link(). Both later functions are actually the filesystems follow_link inode operation. vfs_kern_mount() is calling the specified get_sb function and lets the filesystem do its job by calling the given fill_super function. Therefore I think it is safe to push down the BKL from the VFS to the low-level filesystems get_sb/fill_super operation. [arnd: do not add the BKL to those file systems that already don't use it elsewhere] Signed-off-by: Jan Blunck Signed-off-by: Arnd Bergmann Cc: Matthew Wilcox Cc: Christoph Hellwig --- fs/afs/super.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'fs/afs') diff --git a/fs/afs/super.c b/fs/afs/super.c index 77e1e5a..6c2fef4 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -302,12 +302,15 @@ static int afs_fill_super(struct super_block *sb, void *data) struct inode *inode = NULL; int ret; + lock_kernel(); + _enter(""); /* allocate a superblock info record */ as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL); if (!as) { _leave(" = -ENOMEM"); + unlock_kernel(); return -ENOMEM; } @@ -341,6 +344,7 @@ static int afs_fill_super(struct super_block *sb, void *data) sb->s_root = root; _leave(" = 0"); + unlock_kernel(); return 0; error_inode: @@ -354,6 +358,7 @@ error: sb->s_fs_info = NULL; _leave(" = %d", ret); + unlock_kernel(); return ret; } -- cgit v1.1 From 77f2fe036cd51300c80d1aca76bcf23a09977f13 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 16 Sep 2010 15:35:54 +0200 Subject: BKL: Remove BKL from afs The BKL is only used in put_super and fill_super, which are both protected by the superblocks s_umount rw_semaphore. Therefore it is safe to remove the BKL entirely. Signed-off-by: Arnd Bergmann Cc: linux-afs@lists.infradead.org Cc: David Howells --- fs/afs/super.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'fs/afs') diff --git a/fs/afs/super.c b/fs/afs/super.c index 6c2fef4..eacf76d 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -302,15 +301,12 @@ static int afs_fill_super(struct super_block *sb, void *data) struct inode *inode = NULL; int ret; - lock_kernel(); - _enter(""); /* allocate a superblock info record */ as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL); if (!as) { _leave(" = -ENOMEM"); - unlock_kernel(); return -ENOMEM; } @@ -344,7 +340,6 @@ static int afs_fill_super(struct super_block *sb, void *data) sb->s_root = root; _leave(" = 0"); - unlock_kernel(); return 0; error_inode: @@ -358,7 +353,6 @@ error: sb->s_fs_info = NULL; _leave(" = %d", ret); - unlock_kernel(); return ret; } @@ -458,12 +452,8 @@ static void afs_put_super(struct super_block *sb) _enter(""); - lock_kernel(); - afs_put_volume(as->volume); - unlock_kernel(); - _leave(""); } -- cgit v1.1 From b89f432133851a01c0d28822f11cbdcc15781a75 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sat, 18 Sep 2010 15:09:31 +0200 Subject: fs/locks.c: prepare for BKL removal This prepares the removal of the big kernel lock from the file locking code. We still use the BKL as long as fs/lockd uses it and ceph might sleep, but we can flip the definition to a private spinlock as soon as that's done. All users outside of fs/lockd get converted to use lock_flocks() instead of lock_kernel() where appropriate. Based on an earlier patch to use a spinlock from Matthew Wilcox, who has attempted this a few times before, the earliest patch from over 10 years ago turned it into a semaphore, which ended up being slower than the BKL and was subsequently reverted. Someone should do some serious performance testing when this becomes a spinlock, since this has caused problems before. Using a spinlock should be at least as good as the BKL in theory, but who knows... Signed-off-by: Arnd Bergmann Acked-by: Matthew Wilcox Cc: Christoph Hellwig Cc: Trond Myklebust Cc: "J. Bruce Fields" Cc: Andrew Morton Cc: Miklos Szeredi Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: John Kacur Cc: Sage Weil Cc: linux-kernel@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org --- fs/afs/flock.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'fs/afs') diff --git a/fs/afs/flock.c b/fs/afs/flock.c index 0931bc1..757d6645 100644 --- a/fs/afs/flock.c +++ b/fs/afs/flock.c @@ -9,7 +9,6 @@ * 2 of the License, or (at your option) any later version. */ -#include #include "internal.h" #define AFS_LOCK_GRANTED 0 @@ -274,7 +273,7 @@ static int afs_do_setlk(struct file *file, struct file_lock *fl) type = (fl->fl_type == F_RDLCK) ? AFS_LOCK_READ : AFS_LOCK_WRITE; - lock_kernel(); + lock_flocks(); /* make sure we've got a callback on this file and that our view of the * data version is up to date */ @@ -421,7 +420,7 @@ given_lock: afs_vnode_fetch_status(vnode, NULL, key); error: - unlock_kernel(); + unlock_flocks(); _leave(" = %d", ret); return ret; -- cgit v1.1