Re: [PATCH RFC] __bd_forget should wait for inodes using themapping

From: Chris Mason
Date: Fri Jun 18 2004 - 11:21:18 EST


On Fri, 2004-06-18 at 11:43, viro@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
wrote:
> On Fri, Jun 18, 2004 at 11:41:43AM -0400, Chris Mason wrote:
> > > And yes, ->i_mapping flips on "normal" bdev inodes will go away - we set
> > > ->f_mapping on open directly.
> >
> > Fair enough, I'll cook up some code to bump the inode->bdev->bd_inode
> > i_count in __sync_single_inode It won't be pretty either though, I'll
> > have to drop the inode_lock so that some function can take the bdev_lock
> > to safely use inode->i_bdev.
>
> *Ugh*
>
> You do realize that ->i_bdev is not promised to be there either? Could you
> show the actual code that steps into this mess?
>
Grin, it won't be pretty, i_bdev can't be trusted without the bdev lock,
and I'll need to check for I_FREEING on it to make sure it isn't in
clear_inode.

The sequence leading up to all of this looks something like this:

CPU 0: CPU 1:

pdflush finds umount /dev/sda1
FS inode for
/dev/sda1 in dirty list,
makes it's way down
to __sync_single_inode

mapping = inode->i_mapping
(this points bdev address
space)
kill_block_super
close_bdev_excl
blkdev_put
bdput(bdev)
iput(bdev->bd_inode)
...
clear_inode(bdev inode)
bdev_clear_inode
__bd_forget(inode for /dev/sda1)
...
destroy_inode(bdev inode)
...
do_writepages(mapping, wbc)

Since mapping on CPU0 still points to the bdev address space, and that
has been freed by the destroy inode, we run into problems.

Maybe the real bug is the FS inode should never have ended up in the
dirty list. This should all work fine if the bdev inode were the only
one to ever hit a dirty list.

-chris


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/