diff options
author | Arnd Bergmann <arnd@arndb.de> | 2011-01-24 12:14:12 +0300 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2011-03-03 00:27:48 +0300 |
commit | 788257d6101d986ac8f2741aaa35974af47f574c (patch) | |
tree | 332d877e09d8b5de6a4bdfba8111dd04e84a722b /fs/ufs/ufs.h | |
parent | 9a311b96c3065f362e3348cb5d7af1a57ca6bff9 (diff) | |
download | linux-788257d6101d986ac8f2741aaa35974af47f574c.tar.xz |
ufs: remove the BKL
This introduces a new per-superblock mutex in UFS to replace
the big kernel lock. I have been careful to avoid nested
calls to lock_ufs and to get the lock order right with
respect to other mutexes, in particular lock_super.
I did not make any attempt to prove that the big kernel
lock is not needed in a particular place in the code,
which is very possible.
The mutex has a significant performance impact, so it is only
used on SMP or PREEMPT configurations.
As Nick Piggin noticed, any allocation inside of the lock
may end up deadlocking when we get to ufs_getfrag_block
in the reclaim task, so we now use GFP_NOFS.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Tested-by: Nick Bowler <nbowler@elliptictech.com>
Cc: Evgeniy Dushistov <dushistov@mail.ru>
Cc: Nick Piggin <npiggin@gmail.com>
Diffstat (limited to 'fs/ufs/ufs.h')
-rw-r--r-- | fs/ufs/ufs.h | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h index c08782e1b48a..5be2755dd715 100644 --- a/fs/ufs/ufs.h +++ b/fs/ufs/ufs.h @@ -18,6 +18,8 @@ struct ufs_sb_info { unsigned s_cgno[UFS_MAX_GROUP_LOADED]; unsigned short s_cg_loaded; unsigned s_mount_opt; + struct mutex mutex; + struct task_struct *mutex_owner; }; struct ufs_inode_info { @@ -109,7 +111,6 @@ extern struct inode *ufs_iget(struct super_block *, unsigned long); extern int ufs_write_inode (struct inode *, struct writeback_control *); extern int ufs_sync_inode (struct inode *); extern void ufs_evict_inode (struct inode *); -extern struct buffer_head * ufs_bread (struct inode *, unsigned, int, int *); extern int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create); /* namei.c */ @@ -154,4 +155,7 @@ static inline u32 ufs_dtogd(struct ufs_sb_private_info * uspi, u64 b) return do_div(b, uspi->s_fpg); } +extern void lock_ufs(struct super_block *sb); +extern void unlock_ufs(struct super_block *sb); + #endif /* _UFS_UFS_H */ |