diff options
author | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2009-08-02 09:45:33 -0400 |
---|---|---|
committer | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2009-09-14 05:27:13 -0400 |
commit | 027d6404eb4327878454db72a006adfcb8001bb8 (patch) | |
tree | 671c0d84ee5fd19ef85a3ff15d99a3519c1ed8bf /fs/nilfs2/mdt.c | |
parent | b5696e5e0dbfb6323277d51d67d230317c18aba9 (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/mdt.c')
-rw-r--r-- | fs/nilfs2/mdt.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c index 2dfd47714ae5..a5cd80162dc5 100644 --- a/fs/nilfs2/mdt.c +++ b/fs/nilfs2/mdt.c | |||
@@ -402,6 +402,7 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc) | |||
402 | struct inode *inode = container_of(page->mapping, | 402 | struct inode *inode = container_of(page->mapping, |
403 | struct inode, i_data); | 403 | struct inode, i_data); |
404 | struct super_block *sb = inode->i_sb; | 404 | struct super_block *sb = inode->i_sb; |
405 | struct the_nilfs *nilfs = NILFS_MDT(inode)->mi_nilfs; | ||
405 | struct nilfs_sb_info *writer = NULL; | 406 | struct nilfs_sb_info *writer = NULL; |
406 | int err = 0; | 407 | int err = 0; |
407 | 408 | ||
@@ -411,9 +412,10 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc) | |||
411 | if (page->mapping->assoc_mapping) | 412 | if (page->mapping->assoc_mapping) |
412 | return 0; /* Do not request flush for shadow page cache */ | 413 | return 0; /* Do not request flush for shadow page cache */ |
413 | if (!sb) { | 414 | if (!sb) { |
414 | writer = nilfs_get_writer(NILFS_MDT(inode)->mi_nilfs); | 415 | down_read(&nilfs->ns_writer_sem); |
416 | writer = nilfs->ns_writer; | ||
415 | if (!writer) { | 417 | if (!writer) { |
416 | nilfs_put_writer(NILFS_MDT(inode)->mi_nilfs); | 418 | up_read(&nilfs->ns_writer_sem); |
417 | return -EROFS; | 419 | return -EROFS; |
418 | } | 420 | } |
419 | sb = writer->s_super; | 421 | sb = writer->s_super; |
@@ -425,7 +427,7 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc) | |||
425 | nilfs_flush_segment(sb, inode->i_ino); | 427 | nilfs_flush_segment(sb, inode->i_ino); |
426 | 428 | ||
427 | if (writer) | 429 | if (writer) |
428 | nilfs_put_writer(NILFS_MDT(inode)->mi_nilfs); | 430 | up_read(&nilfs->ns_writer_sem); |
429 | return err; | 431 | return err; |
430 | } | 432 | } |
431 | 433 | ||