* BUG in writeback_inodes()?
@ 2004-09-13 16:01 Kirill Korotaev
2004-09-13 20:35 ` Chris Mason
0 siblings, 1 reply; 2+ messages in thread
From: Kirill Korotaev @ 2004-09-13 16:01 UTC (permalink / raw)
To: linux-kernel, Andrew Morton, Linus Torvalds
Hello All,
It looks like there is a small race bug in writeback_inodes()
Have a look at this 2 call chains:
writeback_inodes()
{
....
sb->s_count++;
spin_unlock(&sb_lock);
....
spin_lock(&sb_lock);
if (__put_super(sb)) <<< X
goto restart;
}
}
deactivate_super()
{
fs->kill_sb(s);
kill_block_super(sb)
generic_shutdown_super(sb)
spin_lock(&sb_lock);
list_del(&sb->s_list); <<< Y
spin_unlock(&sb_lock);
....
put_super(s);
spin_lock(&sb_lock);
__put_super(sb); <<< Z
spin_unlock(&sb_lock);
}
The problem with it is that writeback_inodes() supposes that if
__put_super() returns 0 then no super block was deleted from the list
and we can safely traverse sb list further.
But as it is obvious from the deactivate_super() it's not actually true.
because at point Y we delete super block from the list and drop the
lock. We do __put_super() very much later... So we can find sb with
poisoned sb->s_list at point X and we won't be the last sb reference
holders. The last reference will be dropped in point Z.
So in case of the following sequence of execution Y -> X -> Z we'll get
an oops after point X in writeback_inodes().
Am I correct with it?
Kirill
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: BUG in writeback_inodes()?
2004-09-13 16:01 BUG in writeback_inodes()? Kirill Korotaev
@ 2004-09-13 20:35 ` Chris Mason
0 siblings, 0 replies; 2+ messages in thread
From: Chris Mason @ 2004-09-13 20:35 UTC (permalink / raw)
To: Kirill Korotaev; +Cc: linux-kernel, Andrew Morton, Linus Torvalds
On Mon, 2004-09-13 at 12:01, Kirill Korotaev wrote:
> The problem with it is that writeback_inodes() supposes that if
> __put_super() returns 0 then no super block was deleted from the list
> and we can safely traverse sb list further.
>
> But as it is obvious from the deactivate_super() it's not actually true.
> because at point Y we delete super block from the list and drop the
> lock. We do __put_super() very much later... So we can find sb with
> poisoned sb->s_list at point X and we won't be the last sb reference
> holders. The last reference will be dropped in point Z.
>
> So in case of the following sequence of execution Y -> X -> Z we'll get
> an oops after point X in writeback_inodes().
>
> Am I correct with it?
Hmmm, sure looks that way. Seems like it should be enough to switch to
list_del_init in deactivate_super, and then check for
list_empty(sb->s_list) in writeback_inodes.
-chris
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2004-09-13 20:34 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-09-13 16:01 BUG in writeback_inodes()? Kirill Korotaev
2004-09-13 20:35 ` Chris Mason
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox