From b4ce1bb1b46accb1619dc07164ef6945feded9db Mon Sep 17 00:00:00 2001 From: chengchao Date: Mon, 28 Jan 2019 11:19:15 +0800 Subject: [PATCH] Fix race yaffs_flush_inodes against iput needs inode->i_sb->s_inode_list_lock protects inode->i_sb->s_inodes, inode->i_sb_list Signed-off-by: chengchao --- yaffs_vfs_single.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/yaffs_vfs_single.c b/yaffs_vfs_single.c index 0ac24bc..1abbfd8 100644 --- a/yaffs_vfs_single.c +++ b/yaffs_vfs_single.c @@ -1489,15 +1489,34 @@ static void yaffs_flush_inodes(struct super_block *sb) { struct inode *iptr; struct yaffs_obj *obj; + struct yaffs_dev *dev = yaffs_super_to_dev(sb); + spin_lock(&sb->s_inode_list_lock); list_for_each_entry(iptr, &sb->s_inodes, i_sb_list) { + spin_lock(&inode->i_lock); + if (iptr->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) { + spin_unlock(&inode->i_lock); + continue; + } + + __iget(iptr); + spin_unlock(&inode->i_lock); + spin_unlock(&sb->s_inode_list_lock); + obj = yaffs_inode_to_obj(iptr); if (obj) { yaffs_trace(YAFFS_TRACE_OS, "flushing obj %d", obj->obj_id); yaffs_flush_file(obj, 1, 0, 0); } + + yaffs_gross_unlock(dev); + iput(iptr); + yaffs_gross_lock(dev); + + spin_lock(&sb->s_inode_list_lock); } + spin_unlock(&sb->s_inode_list_lock); } static void yaffs_flush_super(struct super_block *sb, int do_checkpoint) -- 2.30.2