Andrew Morton <[EMAIL PROTECTED]> writes: > The __sync_single_inode() caller takes a ref on the inode to prevent things > like this from happening.
Yes. But, in this case, that inode->i_mapping is pointing the bdev's ->i_mapping by open("/dev/hda2"). open("/dev/hda2") -> blkdev_open() -> bd_acquire() inode->i_bdev = bdev; inode->i_mapping = bdev->bd_inode->i_mapping; list_add(&inode->i_devices, &bdev->bd_inodes); In this race case, the inode is not freeing, but ->i_mapping is freed. > What was the call path on the other process? The one running > destroy_inode()? unmount? close("/dev/hda2"). The _bdev's_ inode is freed by close() path after restoreing the inode->i_mapping of filesytem in bdev_clear_inode(). close("/dev/hda2") -> blkdev_close() -> [...] -> iput() -> generic_delete_inode() -> bdev_clear_inode() -> __bd_forget() /* inode is filesystem's inode, not bdev. */ list_del_init(&inode->i_devices); inode->i_bdev = NULL; inode->i_mapping = &inode->i_data; -> destroy_inode() <- is freeing the bdev's inode. And __sync_single_inode() side is updating the inode->i_atime on filesystem. >> +/* Called under inode_lock. */ >> +void wait_inode_ilock(struct inode *inode) >> +{ >> + wait_queue_head_t *wqh; >> + DEFINE_WAIT_BIT(wq, &inode->i_state, __I_LOCK); >> + >> + if (!(inode->i_state & I_LOCK)) >> + return; >> + >> + wqh = bit_waitqueue(&inode->i_state, __I_LOCK); >> + do { >> + __iget(inode); >> + spin_unlock(&inode_lock); >> + __wait_on_bit(wqh, &wq, inode_wait, TASK_UNINTERRUPTIBLE); >> + iput(inode); >> + spin_lock(&inode_lock); >> + } while (inode->i_state & I_LOCK); >> +} > > Does this differ from wait_on_inode()? This checks I_LOCK after taking the inode_lock. So, caller can set the I_LOCK after this. -- OGAWA Hirofumi <[EMAIL PROTECTED]> - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/