aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2/the_nilfs.h
diff options
context:
space:
mode:
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2009-08-02 09:45:33 -0400
committerRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2009-09-14 05:27:13 -0400
commit027d6404eb4327878454db72a006adfcb8001bb8 (patch)
tree671c0d84ee5fd19ef85a3ff15d99a3519c1ed8bf /fs/nilfs2/the_nilfs.h
parentb5696e5e0dbfb6323277d51d67d230317c18aba9 (diff)
nilfs2: use semaphore to protect pointer to a writable FS-instance
will get rid of nilfs_get_writer() and nilfs_put_writer() pair used to retain a writable FS-instance for a period. The pair functions were making up some kind of recursive lock with a mutex, but they became overkill since the commit 201913ed746c7724a40d33ee5a0b6a1fd2ef3193. Furthermore, they caused the following lockdep warning because the mutex can be released by a task which didn't lock it: ===================================== [ BUG: bad unlock balance detected! ] ------------------------------------- kswapd0/422 is trying to release lock (&nilfs->ns_writer_mutex) at: [<c1359ff5>] mutex_unlock+0x8/0xa but there are no more locks to release! other info that might help us debug this: no locks held by kswapd0/422. stack backtrace: Pid: 422, comm: kswapd0 Not tainted 2.6.31-rc4-nilfs #51 Call Trace: [<c1358f97>] ? printk+0xf/0x18 [<c104fea7>] print_unlock_inbalance_bug+0xcc/0xd7 [<c11578de>] ? prop_put_global+0x3/0x35 [<c1050195>] lock_release+0xed/0x1dc [<c1359ff5>] ? mutex_unlock+0x8/0xa [<c1359f83>] __mutex_unlock_slowpath+0xaf/0x119 [<c1359ff5>] mutex_unlock+0x8/0xa [<d1284add>] nilfs_mdt_write_page+0xd8/0xe1 [nilfs2] [<c1092653>] shrink_page_list+0x379/0x68d [<c109171b>] ? isolate_pages_global+0xb4/0x18c [<c1092bd2>] shrink_list+0x26b/0x54b [<c10930be>] shrink_zone+0x20c/0x2a2 [<c10936b7>] kswapd+0x407/0x591 [<c1091667>] ? isolate_pages_global+0x0/0x18c [<c1040603>] ? autoremove_wake_function+0x0/0x33 [<c10932b0>] ? kswapd+0x0/0x591 [<c104033b>] kthread+0x69/0x6e [<c10402d2>] ? kthread+0x0/0x6e [<c1003e33>] kernel_thread_helper+0x7/0x1a This patch uses a reader/writer semaphore instead of the own lock and kills this warning. Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Diffstat (limited to 'fs/nilfs2/the_nilfs.h')
-rw-r--r--fs/nilfs2/the_nilfs.h27
1 files changed, 6 insertions, 21 deletions
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h
index 1b9caafb8662..fa3a1dfe4053 100644
--- a/fs/nilfs2/the_nilfs.h
+++ b/fs/nilfs2/the_nilfs.h
@@ -50,8 +50,7 @@ enum {
50 * @ns_sem: semaphore for shared states 50 * @ns_sem: semaphore for shared states
51 * @ns_super_sem: semaphore for global operations across super block instances 51 * @ns_super_sem: semaphore for global operations across super block instances
52 * @ns_mount_mutex: mutex protecting mount process of nilfs 52 * @ns_mount_mutex: mutex protecting mount process of nilfs
53 * @ns_writer_mutex: mutex protecting ns_writer attach/detach 53 * @ns_writer_sem: semaphore protecting ns_writer attach/detach
54 * @ns_writer_refcount: number of referrers on ns_writer
55 * @ns_current: back pointer to current mount 54 * @ns_current: back pointer to current mount
56 * @ns_sbh: buffer heads of on-disk super blocks 55 * @ns_sbh: buffer heads of on-disk super blocks
57 * @ns_sbp: pointers to super block data 56 * @ns_sbp: pointers to super block data
@@ -100,8 +99,7 @@ struct the_nilfs {
100 struct rw_semaphore ns_sem; 99 struct rw_semaphore ns_sem;
101 struct rw_semaphore ns_super_sem; 100 struct rw_semaphore ns_super_sem;
102 struct mutex ns_mount_mutex; 101 struct mutex ns_mount_mutex;
103 struct mutex ns_writer_mutex; 102 struct rw_semaphore ns_writer_sem;
104 atomic_t ns_writer_refcount;
105 103
106 /* 104 /*
107 * components protected by ns_super_sem 105 * components protected by ns_super_sem
@@ -221,34 +219,21 @@ static inline void get_nilfs(struct the_nilfs *nilfs)
221 atomic_inc(&nilfs->ns_count); 219 atomic_inc(&nilfs->ns_count);
222} 220}
223 221
224static inline struct nilfs_sb_info *nilfs_get_writer(struct the_nilfs *nilfs)
225{
226 if (atomic_inc_and_test(&nilfs->ns_writer_refcount))
227 mutex_lock(&nilfs->ns_writer_mutex);
228 return nilfs->ns_writer;
229}
230
231static inline void nilfs_put_writer(struct the_nilfs *nilfs)
232{
233 if (atomic_add_negative(-1, &nilfs->ns_writer_refcount))
234 mutex_unlock(&nilfs->ns_writer_mutex);
235}
236
237static inline void 222static inline void
238nilfs_attach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) 223nilfs_attach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
239{ 224{
240 mutex_lock(&nilfs->ns_writer_mutex); 225 down_write(&nilfs->ns_writer_sem);
241 nilfs->ns_writer = sbi; 226 nilfs->ns_writer = sbi;
242 mutex_unlock(&nilfs->ns_writer_mutex); 227 up_write(&nilfs->ns_writer_sem);
243} 228}
244 229
245static inline void 230static inline void
246nilfs_detach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) 231nilfs_detach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
247{ 232{
248 mutex_lock(&nilfs->ns_writer_mutex); 233 down_write(&nilfs->ns_writer_sem);
249 if (sbi == nilfs->ns_writer) 234 if (sbi == nilfs->ns_writer)
250 nilfs->ns_writer = NULL; 235 nilfs->ns_writer = NULL;
251 mutex_unlock(&nilfs->ns_writer_mutex); 236 up_write(&nilfs->ns_writer_sem);
252} 237}
253 238
254static inline void nilfs_put_sbinfo(struct nilfs_sb_info *sbi) 239static inline void nilfs_put_sbinfo(struct nilfs_sb_info *sbi)