On Sat 06-06-09 11:07:25, Wu Fengguang wrote: > 1) I_FREEING tests should be coupled with I_CLEAR > > The two I_FREEING tests are racy because clear_inode() can set i_state to > I_CLEAR between the clear of I_SYNC and the test of I_FREEING. > > 2) skip I_WILL_FREE inodes in generic_sync_sb_inodes() to avoid possible > races with generic_forget_inode() > > generic_forget_inode() sets I_WILL_FREE call writeback on its own, so > generic_sync_sb_inodes() shall not try to step in and create possible races: > > generic_forget_inode > inode->i_state |= I_WILL_FREE; > spin_unlock(&inode_lock); > generic_sync_sb_inodes() > spin_lock(&inode_lock); > __iget(inode); > __writeback_single_inode > // see non zero i_count > may WARN here ==> WARN_ON(inode->i_state & I_WILL_FREE); > spin_unlock(&inode_lock); > may call generic_forget_inode again ==> iput(inode); > > The above race and warning didn't turn up because writeback_inodes() holds > the s_umount lock, so generic_forget_inode() finds MS_ACTIVE and returns > early. But we are not sure the UBIFS calls and future callers will guarantee > that. So skip I_WILL_FREE inodes for the sake of safety. OK, the patch looks fine. Acked-by: Jan Kara <jack@xxxxxxx> Honza > CC: Jan Kara <jack@xxxxxxx> > CC: Eric Sandeen <sandeen@xxxxxxxxxxx> > Acked-by: Jeff Layton <jlayton@xxxxxxxxxx> > CC: Masayoshi MIZUMA <m.mizuma@xxxxxxxxxxxxxx> > Signed-off-by: Wu Fengguang <fengguang.wu@xxxxxxxxx> > --- > fs/fs-writeback.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > --- linux.orig/fs/fs-writeback.c > +++ linux/fs/fs-writeback.c > @@ -316,7 +316,7 @@ __sync_single_inode(struct inode *inode, > spin_lock(&inode_lock); > WARN_ON(inode->i_state & I_NEW); > inode->i_state &= ~I_SYNC; > - if (!(inode->i_state & I_FREEING)) { > + if (!(inode->i_state & (I_FREEING | I_CLEAR))) { > if (!(inode->i_state & I_DIRTY) && > mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) { > /* > @@ -487,7 +487,7 @@ void generic_sync_sb_inodes(struct super > break; > } > > - if (inode->i_state & I_NEW) { > + if (inode->i_state & (I_NEW | I_WILL_FREE)) { > requeue_io(inode); > continue; > } > @@ -518,7 +518,7 @@ void generic_sync_sb_inodes(struct super > if (current_is_pdflush() && !writeback_acquire(bdi)) > break; > > - BUG_ON(inode->i_state & I_FREEING); > + BUG_ON(inode->i_state & (I_FREEING | I_CLEAR)); > __iget(inode); > pages_skipped = wbc->pages_skipped; > __writeback_single_inode(inode, wbc); -- Jan Kara <jack@xxxxxxx> SUSE Labs, CR -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html