Skip to content

Commit 9b467e6

Browse files
fweisbectorvalds
authored andcommitted
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 <[email protected]> Signed-off-by: Frederic Weisbecker <[email protected]> Cc: Al Viro <[email protected]> Cc: Christoph Hellwig <[email protected]> Cc: Jeff Mahoney <[email protected]> Cc: Jan Kara <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 37c69b9 commit 9b467e6

File tree

1 file changed

+13
-15
lines changed

1 file changed

+13
-15
lines changed

fs/reiserfs/super.c

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1519,9 +1519,7 @@ static int read_super_block(struct super_block *s, int offset)
15191519
static int reread_meta_blocks(struct super_block *s)
15201520
{
15211521
ll_rw_block(READ, 1, &(SB_BUFFER_WITH_SB(s)));
1522-
reiserfs_write_unlock(s);
15231522
wait_on_buffer(SB_BUFFER_WITH_SB(s));
1524-
reiserfs_write_lock(s);
15251523
if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) {
15261524
reiserfs_warning(s, "reiserfs-2504", "error reading the super");
15271525
return 1;
@@ -1837,24 +1835,14 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
18371835
*/
18381836
}
18391837

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-
18501838
if (reread_meta_blocks(s)) {
18511839
SWARN(silent, s, "jmacd-9",
18521840
"unable to reread meta blocks after journal init");
1853-
goto error;
1841+
goto error_unlocked;
18541842
}
18551843

18561844
if (replay_only(s))
1857-
goto error;
1845+
goto error_unlocked;
18581846

18591847
if (bdev_read_only(s->s_bdev) && !(s->s_flags & MS_RDONLY)) {
18601848
SWARN(silent, s, "clm-7000",
@@ -1868,9 +1856,19 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
18681856
reiserfs_init_locked_inode, (void *)(&args));
18691857
if (!root_inode) {
18701858
SWARN(silent, s, "jmacd-10", "get root inode failed");
1871-
goto error;
1859+
goto error_unlocked;
18721860
}
18731861

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+
18741872
if (root_inode->i_state & I_NEW) {
18751873
reiserfs_read_locked_inode(root_inode, &args);
18761874
unlock_new_inode(root_inode);

0 commit comments

Comments
 (0)