aboutsummaryrefslogtreecommitdiffstats
path: root/fs/reiserfs/super.c
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2012-01-10 18:11:11 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-10 19:30:54 -0500
commit9b467e6ebebbe75288aeb7e816ffbb5d35d6eaa3 (patch)
treec4ef186bd143aaa47b5745235452e9e2345d8f20 /fs/reiserfs/super.c
parent37c69b98d0dca54d9eb72226bbf2e211aaaf126e (diff)
reiserfs: don't lock root inode searching
Nothing requires that we lock the filesystem until the root inode is provided. Also iget5_locked() triggers a warning because we are holding the filesystem lock while allocating the inode, which result in a lockdep suspicion that we have a lock inversion against the reclaim path: [ 1986.896979] ================================= [ 1986.896990] [ INFO: inconsistent lock state ] [ 1986.896997] 3.1.1-main #8 [ 1986.897001] --------------------------------- [ 1986.897007] inconsistent {RECLAIM_FS-ON-W} -> {IN-RECLAIM_FS-W} usage. [ 1986.897016] kswapd0/16 [HC0[0]:SC0[0]:HE1:SE1] takes: [ 1986.897023] (&REISERFS_SB(s)->lock){+.+.?.}, at: [<c01f8bd4>] reiserfs_write_lock+0x20/0x2a [ 1986.897044] {RECLAIM_FS-ON-W} state was registered at: [ 1986.897050] [<c014a5b9>] mark_held_locks+0xae/0xd0 [ 1986.897060] [<c014aab3>] lockdep_trace_alloc+0x7d/0x91 [ 1986.897068] [<c0190ee0>] kmem_cache_alloc+0x1a/0x93 [ 1986.897078] [<c01e7728>] reiserfs_alloc_inode+0x13/0x3d [ 1986.897088] [<c01a5b06>] alloc_inode+0x14/0x5f [ 1986.897097] [<c01a5cb9>] iget5_locked+0x62/0x13a [ 1986.897106] [<c01e99e0>] reiserfs_fill_super+0x410/0x8b9 [ 1986.897114] [<c01953da>] mount_bdev+0x10b/0x159 [ 1986.897123] [<c01e764d>] get_super_block+0x10/0x12 [ 1986.897131] [<c0195b38>] mount_fs+0x59/0x12d [ 1986.897138] [<c01a80d1>] vfs_kern_mount+0x45/0x7a [ 1986.897147] [<c01a83e3>] do_kern_mount+0x2f/0xb0 [ 1986.897155] [<c01a987a>] do_mount+0x5c2/0x612 [ 1986.897163] [<c01a9a72>] sys_mount+0x61/0x8f [ 1986.897170] [<c044060c>] sysenter_do_call+0x12/0x32 [ 1986.897181] irq event stamp: 7509691 [ 1986.897186] hardirqs last enabled at (7509691): [<c0190f34>] kmem_cache_alloc+0x6e/0x93 [ 1986.897197] hardirqs last disabled at (7509690): [<c0190eea>] kmem_cache_alloc+0x24/0x93 [ 1986.897209] softirqs last enabled at (7508896): [<c01294bd>] __do_softirq+0xee/0xfd [ 1986.897222] softirqs last disabled at (7508859): [<c01030ed>] do_softirq+0x50/0x9d [ 1986.897234] [ 1986.897235] other info that might help us debug this: [ 1986.897242] Possible unsafe locking scenario: [ 1986.897244] [ 1986.897250] CPU0 [ 1986.897254] ---- [ 1986.897257] lock(&REISERFS_SB(s)->lock); [ 1986.897265] <Interrupt> [ 1986.897269] lock(&REISERFS_SB(s)->lock); [ 1986.897276] [ 1986.897277] *** DEADLOCK *** [ 1986.897278] [ 1986.897286] no locks held by kswapd0/16. [ 1986.897291] [ 1986.897292] stack backtrace: [ 1986.897299] Pid: 16, comm: kswapd0 Not tainted 3.1.1-main #8 [ 1986.897306] Call Trace: [ 1986.897314] [<c0439e76>] ? printk+0xf/0x11 [ 1986.897324] [<c01482d1>] print_usage_bug+0x20e/0x21a [ 1986.897332] [<c01479b8>] ? print_irq_inversion_bug+0x172/0x172 [ 1986.897341] [<c014855c>] mark_lock+0x27f/0x483 [ 1986.897349] [<c0148d88>] __lock_acquire+0x628/0x1472 [ 1986.897358] [<c0149fae>] lock_acquire+0x47/0x5e [ 1986.897366] [<c01f8bd4>] ? reiserfs_write_lock+0x20/0x2a [ 1986.897384] [<c01f8bd4>] ? reiserfs_write_lock+0x20/0x2a [ 1986.897397] [<c043b5ef>] mutex_lock_nested+0x35/0x26f [ 1986.897409] [<c01f8bd4>] ? reiserfs_write_lock+0x20/0x2a [ 1986.897421] [<c01f8bd4>] reiserfs_write_lock+0x20/0x2a [ 1986.897433] [<c01e2edd>] map_block_for_writepage+0xc9/0x590 [ 1986.897448] [<c01b1706>] ? create_empty_buffers+0x33/0x8f [ 1986.897461] [<c0121124>] ? get_parent_ip+0xb/0x31 [ 1986.897472] [<c043ef7f>] ? sub_preempt_count+0x81/0x8e [ 1986.897485] [<c043cae0>] ? _raw_spin_unlock+0x27/0x3d [ 1986.897496] [<c0121124>] ? get_parent_ip+0xb/0x31 [ 1986.897508] [<c01e355d>] reiserfs_writepage+0x1b9/0x3e7 [ 1986.897521] [<c0173b40>] ? clear_page_dirty_for_io+0xcb/0xde [ 1986.897533] [<c014a6e3>] ? trace_hardirqs_on_caller+0x108/0x138 [ 1986.897546] [<c014a71e>] ? trace_hardirqs_on+0xb/0xd [ 1986.897559] [<c0177b38>] shrink_page_list+0x34f/0x5e2 [ 1986.897572] [<c01780a7>] shrink_inactive_list+0x172/0x22c [ 1986.897585] [<c0178464>] shrink_zone+0x303/0x3b1 [ 1986.897597] [<c043cae0>] ? _raw_spin_unlock+0x27/0x3d [ 1986.897611] [<c01788c9>] kswapd+0x3b7/0x5f2 The deadlock shouldn't happen since we are doing that allocation in the mount path, the filesystem is not available for any reclaim. Still the warning is annoying. To solve this, acquire the lock later only where we need it, right before calling reiserfs_read_locked_inode() that wants to lock to walk the tree. Reported-by: Knut Petersen <Knut_Petersen@t-online.de> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Christoph Hellwig <hch@lst.de> Cc: Jeff Mahoney <jeffm@suse.com> Cc: Jan Kara <jack@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/reiserfs/super.c')
-rw-r--r--fs/reiserfs/super.c28
1 files changed, 13 insertions, 15 deletions
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 61b60380d2c..e12d8b97cd4 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -1519,9 +1519,7 @@ static int read_super_block(struct super_block *s, int offset)
1519static int reread_meta_blocks(struct super_block *s) 1519static int reread_meta_blocks(struct super_block *s)
1520{ 1520{
1521 ll_rw_block(READ, 1, &(SB_BUFFER_WITH_SB(s))); 1521 ll_rw_block(READ, 1, &(SB_BUFFER_WITH_SB(s)));
1522 reiserfs_write_unlock(s);
1523 wait_on_buffer(SB_BUFFER_WITH_SB(s)); 1522 wait_on_buffer(SB_BUFFER_WITH_SB(s));
1524 reiserfs_write_lock(s);
1525 if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) { 1523 if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) {
1526 reiserfs_warning(s, "reiserfs-2504", "error reading the super"); 1524 reiserfs_warning(s, "reiserfs-2504", "error reading the super");
1527 return 1; 1525 return 1;
@@ -1837,24 +1835,14 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
1837 */ 1835 */
1838 } 1836 }
1839 1837
1840 /*
1841 * This path assumed to be called with the BKL in the old times.
1842 * Now we have inherited the big reiserfs lock from it and many
1843 * reiserfs helpers called in the mount path and elsewhere require
1844 * this lock to be held even if it's not always necessary. Let's be
1845 * conservative and hold it early. The window can be reduced after
1846 * careful review of the code.
1847 */
1848 reiserfs_write_lock(s);
1849
1850 if (reread_meta_blocks(s)) { 1838 if (reread_meta_blocks(s)) {
1851 SWARN(silent, s, "jmacd-9", 1839 SWARN(silent, s, "jmacd-9",
1852 "unable to reread meta blocks after journal init"); 1840 "unable to reread meta blocks after journal init");
1853 goto error; 1841 goto error_unlocked;
1854 } 1842 }
1855 1843
1856 if (replay_only(s)) 1844 if (replay_only(s))
1857 goto error; 1845 goto error_unlocked;
1858 1846
1859 if (bdev_read_only(s->s_bdev) && !(s->s_flags & MS_RDONLY)) { 1847 if (bdev_read_only(s->s_bdev) && !(s->s_flags & MS_RDONLY)) {
1860 SWARN(silent, s, "clm-7000", 1848 SWARN(silent, s, "clm-7000",
@@ -1868,9 +1856,19 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
1868 reiserfs_init_locked_inode, (void *)(&args)); 1856 reiserfs_init_locked_inode, (void *)(&args));
1869 if (!root_inode) { 1857 if (!root_inode) {
1870 SWARN(silent, s, "jmacd-10", "get root inode failed"); 1858 SWARN(silent, s, "jmacd-10", "get root inode failed");
1871 goto error; 1859 goto error_unlocked;
1872 } 1860 }
1873 1861
1862 /*
1863 * This path assumed to be called with the BKL in the old times.
1864 * Now we have inherited the big reiserfs lock from it and many
1865 * reiserfs helpers called in the mount path and elsewhere require
1866 * this lock to be held even if it's not always necessary. Let's be
1867 * conservative and hold it early. The window can be reduced after
1868 * careful review of the code.
1869 */
1870 reiserfs_write_lock(s);
1871
1874 if (root_inode->i_state & I_NEW) { 1872 if (root_inode->i_state & I_NEW) {
1875 reiserfs_read_locked_inode(root_inode, &args); 1873 reiserfs_read_locked_inode(root_inode, &args);
1876 unlock_new_inode(root_inode); 1874 unlock_new_inode(root_inode);