Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932284AbeAKXFo (ORCPT + 1 other); Thu, 11 Jan 2018 18:05:44 -0500 Received: from mailout1.samsung.com ([203.254.224.24]:22393 "EHLO mailout1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932152AbeAKXFm (ORCPT ); Thu, 11 Jan 2018 18:05:42 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.samsung.com 20180111230540epoutp017fad22dc1789bb90fde282ede09fa2cc~I4-rCmLLe2146721467epoutp01_ X-AuditID: b6c32a37-413ff70000001041-37-5a57edc4e788 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: Fri, 12 Jan 2018 08:06:00 +0900 Message-id: <1515711960-10781-1-git-send-email-daeho.jeong@samsung.com> X-Mailer: git-send-email 1.9.1 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpgleLIzCtJLcpLzFFi42LZdlhTX/fI2/Aogy9X5Sz2fFrHZnFpkbvF 5V1z2Cxm7H/K7sDisXvBZyaPvi2rGD0+b5ILYI5KtclITUxJLVJIzUvOT8nMS7dV8g6Od443 NTMw1DW0tDBXUshLzE21VXLxCdB1y8wBWqakUJaYUwoUCkgsLlbSt7Mpyi8tSVXIyC8usVWK NjQ00jM0MNczMjLSMzGPtTIyBSpJSM1ofNjHVPBOuOLY489MDYzrBLoYOTkkBEwk+p+dZgax hQR2MEp8uVLXxcgFZH9nlHh38SQTTNHNhY1sEEUbGCVmdTpCFP1klNj95jMrSIJNQFti+vJZ 7CC2iICHxOLzv1lAbGaBEIkj9zcBbeDgEBYIlpiyPQMkzCKgKvH16BOw+bwC7hK3OicxQuyS kzh5bDIryHwJgbOsEtevnYRKuEjcvXGCDcIWlnh1fAs7yEwJAWmJS0dtIepXMUr8vnQWqrmF UWLysYVQDcYSnz5/ZoQ4iE/i3dceVohmXomONiGIEg+JqwdmsEPYjhJnF7UzQTwcK/Hw6zz2 CYySCxgZVjGKpRYU56anFhsWGOsVJ+YWl+al6yXn525iBMe+lvkOxg3nfA4xCnAwKvHwPsgN jxJiTSwrrsw9xCjBwawkwlvTDRTiTUmsrEotyo8vKs1JLT7EaAoMj4nMUqLJ+cC0lFcSb2hi aWBiZmRqamhgYaIkzhsQ4BIlJJCeWJKanZpakFoE08fEwSnVwMhyn+vXbpn0mRx5orHi8nHP L/dtt9bY6/fC+M1mey2/HVvDPgnnPXVdpythcj3EeNGkCSWSKcfm1DyqPmIhJ77Z7/lr9l9n 5k7eejV2+7Q4ptKPkSt3Tf8YZbhFy2g6J1vh3CbVqce+n+kLLDD67567f3N6G8fC42Lvo7lm sZ6aLFA4ubrBdK4SS3FGoqEWc1FxIgDG7rISEwMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrBJMWRmVeSWpSXmKPExsVy+t9jQd0jb8OjDHo/CFjs+bSOzeLSIneL y7vmsFnM2P+U3YHFY/eCz0wefVtWMXp83iQXwBzFZZOSmpNZllqkb5fAldH4sI+p4J1wxbHH n5kaGNcJdDFyckgImEjcXNjI1sXIxSEksI5RYu3/k0wgCSGBn4wSc98GgdhsAtoS05fPYgex RQQ8JBaf/80CYjMLhEgsnLUHyObgEBYIlpiyPQMkzCKgKvH16BOwMbwC7hK3OicxQuySkzh5 bDLrBEauBYwMqxglUwuKc9Nzi40KDPNSy/WKE3OLS/PS9ZLzczcxAv277bBW3w7G+0viDzEK cDAq8fA+yA2PEmJNLCuuzD3EKMHBrCTCW9MNFOJNSaysSi3Kjy8qzUktPsQozcGiJM57O+9Y pJBAemJJanZqakFqEUyWiYNTqoFx8QvrF/bbTKVu15Vp32w9/HjBjKwU8SVu0UfbXghv+hE7 b7lccgDHMjfRPXsWbjzEt97C9ttv427e8mlrC1kr2h7uFmWaKeG6m/VpxmQv2Y3+jf6Kyzbn rXbinetU+qTTbPl+VmarravXMaXIL2U4+HenfrW6kpfsuvdf/1zIYU/c+3PHnFtXlFiKMxIN tZiLihMBYfxZfesBAAA= X-CMS-MailID: 20180111230540epcas1p4c839d6dae432f5c1b388b43c17e0f649 X-Msg-Generator: CA CMS-TYPE: 101P DLP-Filter: Pass X-CFilter-Loop: Reflected X-CMS-RootMailID: 20180111230540epcas1p4c839d6dae432f5c1b388b43c17e0f649 X-RootMTR: 20180111230540epcas1p4c839d6dae432f5c1b388b43c17e0f649 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 Reviewed-by: Chao Yu --- 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