Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753496AbeAKC0D (ORCPT + 1 other); Wed, 10 Jan 2018 21:26:03 -0500 Received: from mailout2.samsung.com ([203.254.224.25]:21456 "EHLO mailout2.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753314AbeAKC0B (ORCPT ); Wed, 10 Jan 2018 21:26:01 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.samsung.com 20180111022559epoutp02f21232e47e1883e6f36735035816c453~IoFSgv16d2864028640epoutp02k X-AuditID: b6c32a46-9adff700000010ee-74-5a56cb37dc0e From: Daeho Jeong To: linux-kernel@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net Cc: Daeho Jeong , Youngjin Gil Subject: [PATCH] f2fs: prevent newly created inode from being dirtied incorrectly Date: Thu, 11 Jan 2018 11:26:19 +0900 Message-id: <1515637579-8360-1-git-send-email-daeho.jeong@samsung.com> X-Mailer: git-send-email 1.9.1 X-Brightmail-Tracker: H4sIAAAAAAAAAzWSa0hTYRjHfT1n21GaHKbm60yx0wVaubbTbl5JFB0ktDIkFrJO+rKZu7kz RfskeFsSkqgkJaHObgtTx/DSzMCJFaGBQgiBfcgMwwi1EJtFc0e//Z/n+f15/jw8BCZq4ImJ CqsTOayMmeJH46OBU6o09fsSvez5K0ozufmCr1noL9Qsvuzha7pffxWcx7X+3q1IbZvPA7Rb 3hQdpkdZJsSUI0cqspbZyiusxmzqQrEhz6BUyeRp8nSNmkq1MhaUTeUX6dIKKsyhZVRqDWOu DrV0DMtSZ3OyHLZqJ0o12VhnNnVNLqelcplaStO0VKEuzaCVIeQ6MvX8WxTYA7G1S0suvB64 yFYQRUBSAf39vbxWEE2IyHEAn95ZFnDFNoDbvo/4ATU/dBvnBn4AfwXXAFfsANjz+IFgj+KT p+G9J/fDOo7UQveHYNiNkVfgzGcv1goIIpYshp1jpr02Tp6AgeUAb08LyQK4/mUD45alwHez HeFIkJzjwbW2dsAN8uHuWGAfioXf3/gEnE6Cq54RwBk8AAYX5vbdjQB2zPbxOeoc3NzaAlyi GOgK/BXsJYKkELqaRRyihYP9nyI5nQvbmzzhdCKyFAYbF/G7ILEXRHjAYWRnLUbE0nZayjIW ttpqlJbZLF4QfgBJwTgYmC+aBiQBqEPCq/ElehGPqWHrLNMAEhgVJ3RfCrWE5UzdLeSwGRzV ZsROA2XoIO2YOL7MFnonq9MgV6TLFCqVXE0rZWoqQdiky9eLSCPjRJUI2ZHjwBdJRInrge14 +uiKnyyOgr5h70L0n9KWiaEN9/KgMe53YaEkyf5wSfyoT7x5sblz98jA8I+WMyPFU11VvBtt AqlrJvfn5tSxrhhV8luHFttdH8X4GbKE4ZPP3ObEyqNUrd8X4dmZnAhkrnzruVkewHiy1YWc yobM7jV+3nqyMF1SJb5M4ayJkUswB8v8B7bCUFYWAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrJJMWRmVeSWpSXmKPExsVy+t9jAV3z02FRBr9nCVjs+bSOzeLSIneL y7vmsFnM2P+U3YHFY/eCz0wefVtWMXp83iQXwBzFZZOSmpNZllqkb5fAlTHn32X2gsPCFTdu dLA0MHYIdDFyckgImEicW9/J0sXIxSEksJNRYkbzMmYI5yejxKEVc5hBqtgEtCWmL5/FDmKL CHhILD7/mwXEZhYIkVg4aw+QzcEhLBAsMWV7BkiYRUBV4vC9w6wgNq+Am8Sbxx+ZIZbJSZw8 Npl1AiPXAkaGVYySqQXFuem5xUYFRnmp5XrFibnFpXnpesn5uZsYgR7edlirfwfj4yXxhxgF OBiVeHgjRMOihFgTy4orcw8xSnAwK4nwLg4ECvGmJFZWpRblxxeV5qQWH2KU5mBREuflzz8W KSSQnliSmp2aWpBaBJNl4uCUamBcd7fY4I2yhl/xqzn/bhZtKPg8af6aT9PVG7xc3VSum61g C/tk1nBK64LWiiXGymL+ir0Km8v5qtzZM3LVhPjeWfZ9LJv7XO0L+1axpznb9nKK77NZrPaz 5fGs+9d5lcyW1xUL6R+etftnsMHNJRWPn6oxzouK5VbfdPnIfP7ZibscBZ+VRggpsRRnJBpq MRcVJwIADO7BKOwBAAA= X-CMS-MailID: 20180111022559epcas2p4b188916d6259160ed9648c9265ce2c8a X-Msg-Generator: CA CMS-TYPE: 102P DLP-Filter: Pass X-CFilter-Loop: Reflected X-CMS-RootMailID: 20180111022559epcas2p4b188916d6259160ed9648c9265ce2c8a X-RootMTR: 20180111022559epcas2p4b188916d6259160ed9648c9265ce2c8a References: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Return-Path: Now, we invoke f2fs_mark_inode_dirty_sync() to make an inode dirty in advance of creating a new node page for the inode. By this, some inodes whose node page is not created yet can be linked into the global dirty list. If the checkpoint is executed at this moment, the inode will be written back by writeback_single_inode() and finally update_inode_page() will fail to detach the inode from the global dirty list because the inode doesn't have a node page. The problem is that the inode's state in VFS layer will become clean after execution of writeback_single_inode() and it's still linked in the global dirty list of f2fs and this will cause a kernel panic. So, we will prevent the newly created inode from being dirtied during the FI_NEW_INODE flag of the inode is set. We will make it dirty right after the flag is cleared. Signed-off-by: Daeho Jeong Signed-off-by: Youngjin Gil Tested-by: Hobin Woo --- fs/f2fs/f2fs.h | 1 + fs/f2fs/inode.c | 3 +++ fs/f2fs/namei.c | 4 ++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index f4e094e..546c7d6 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -2116,6 +2116,7 @@ static inline void __mark_inode_dirty_flag(struct inode *inode, case FI_INLINE_XATTR: case FI_INLINE_DATA: case FI_INLINE_DENTRY: + case FI_NEW_INODE: if (set) return; case FI_DATA_EXIST: diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index b4c4f2b..67dfa16 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -22,6 +22,9 @@ void f2fs_mark_inode_dirty_sync(struct inode *inode, bool sync) { + if (is_inode_flag_set(inode, FI_NEW_INODE)) + return; + if (f2fs_inode_dirtied(inode, sync)) return; diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 28bdf88..bedf225 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -74,12 +74,12 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode) if (err) goto fail_drop; + set_inode_flag(inode, FI_NEW_INODE); + /* If the directory encrypted, then we should encrypt the inode. */ if (f2fs_encrypted_inode(dir) && f2fs_may_encrypt(inode)) f2fs_set_encrypted_inode(inode); - set_inode_flag(inode, FI_NEW_INODE); - if (f2fs_sb_has_extra_attr(sbi->sb)) { set_inode_flag(inode, FI_EXTRA_ATTR); F2FS_I(inode)->i_extra_isize = F2FS_TOTAL_EXTRA_ATTR_SIZE; -- 1.9.1