Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp729582imm; Thu, 13 Sep 2018 06:57:08 -0700 (PDT) X-Google-Smtp-Source: ANB0VdaD9FLSEXSCScfegp9JjOSTK9UijHGL0LsBPKsgllSyGjBape6hmaHRz1W0v7f+ki4BnfIx X-Received: by 2002:a17:902:402:: with SMTP id 2-v6mr7350483ple.277.1536847028353; Thu, 13 Sep 2018 06:57:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1536847028; cv=none; d=google.com; s=arc-20160816; b=FsXW5pe+4I5C0FviBTap8n8p70pVeIbBuPvEt9z6dwDHV7XD6R+9Zk+qNTmowZSpI5 pZx+w0is+mfcYsgIYl45obu35ughUZguRnp75YZAyVoKd1ruRell7SD8Djpza4QSHraI 9ZkYv3s7XPTjV70/H2zRzO2O/txkzqc9bEY/xs4m7e84yySD+oFP+1KyIyinCduQOzUp fj1WR6RwyWnJ3gvNv04CezjKuxXDgPp0R4i2jQeUYvXS4+DHiFEzQ1hseKAjuXVqpAXy +aIN4NnpXCBO3D+0tCpEOabyE3ck8neI3UflMCC4VhQwr0V103ydpWeMXRrM8xs8dQjk oREg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from; bh=IAJRsvJcgsY4m4YZZlfW8stbN3mRksAE3Xo+AUGrTgg=; b=loiEOGVS3cT4N8oIFXHFvbA9ryHl2Ql/EEGRwaUa6Th35S8Cw0/GreGtv5lIdQnCnr VLGkyZQNoKWF9RCB1X6pib/hH765br+/85jJ1w+jtOrSvYcrORDFMiuoaCdbLboAtigy S26XNoVH2LCaPzrjhQpWTnkNuXOo1+zu3iMx1u1OS85jCMEWvjrOZSNK8QXdy4ekfYxs 6Z1MFKLRzHxetNmSQLlsYBOl97tVGuyKoBIBhkvLjlBfbk52Ye9jESJbIDz61CNzEG05 MReDAJRBsSViV3IOl0Ii1SdQImZTFDN18gZ4tV0JeYSUfRpx4k4Q36ou9upUx2uX/EC6 yRSA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z19-v6si4324950pgi.388.2018.09.13.06.56.53; Thu, 13 Sep 2018 06:57:08 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731394AbeIMTGK (ORCPT + 99 others); Thu, 13 Sep 2018 15:06:10 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:34180 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730563AbeIMTGK (ORCPT ); Thu, 13 Sep 2018 15:06:10 -0400 Received: from localhost (ip-213-127-77-73.ip.prioritytelecom.net [213.127.77.73]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id F18B2D10; Thu, 13 Sep 2018 13:56:32 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Chao Yu , Jaegeuk Kim , Sasha Levin Subject: [PATCH 4.18 089/197] f2fs: fix avoid race between truncate and background GC Date: Thu, 13 Sep 2018 15:30:38 +0200 Message-Id: <20180913131845.090273910@linuxfoundation.org> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180913131841.568116777@linuxfoundation.org> References: <20180913131841.568116777@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Chao Yu [ Upstream commit a33c150237a20d97a174243bc658c86502f9d370 ] Thread A Background GC - f2fs_setattr isize to 0 - truncate_setsize - gc_data_segment - f2fs_get_read_data_page page #0 - set_page_dirty - set_cold_data - f2fs_truncate - f2fs_setattr isize to 4k - read 4k <--- hit data in cached page #0 Above race condition can cause read out invalid data in a truncated page, fix it by i_gc_rwsem[WRITE] lock. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- fs/f2fs/data.c | 4 ++++ fs/f2fs/file.c | 37 +++++++++++++++++++++++-------------- 2 files changed, 27 insertions(+), 14 deletions(-) --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -2149,8 +2149,12 @@ static void f2fs_write_failed(struct add if (to > i_size) { down_write(&F2FS_I(inode)->i_mmap_sem); + down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + truncate_pagecache(inode, i_size); f2fs_truncate_blocks(inode, i_size, true); + + up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); up_write(&F2FS_I(inode)->i_mmap_sem); } } --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -782,22 +782,26 @@ int f2fs_setattr(struct dentry *dentry, } if (attr->ia_valid & ATTR_SIZE) { - if (attr->ia_size <= i_size_read(inode)) { - down_write(&F2FS_I(inode)->i_mmap_sem); - truncate_setsize(inode, attr->ia_size); + bool to_smaller = (attr->ia_size <= i_size_read(inode)); + + down_write(&F2FS_I(inode)->i_mmap_sem); + down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + + truncate_setsize(inode, attr->ia_size); + + if (to_smaller) err = f2fs_truncate(inode); - up_write(&F2FS_I(inode)->i_mmap_sem); - if (err) - return err; - } else { - /* - * do not trim all blocks after i_size if target size is - * larger than i_size. - */ - down_write(&F2FS_I(inode)->i_mmap_sem); - truncate_setsize(inode, attr->ia_size); - up_write(&F2FS_I(inode)->i_mmap_sem); + /* + * do not trim all blocks after i_size if target size is + * larger than i_size. + */ + up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + up_write(&F2FS_I(inode)->i_mmap_sem); + + if (err) + return err; + if (!to_smaller) { /* should convert inline inode here */ if (!f2fs_may_inline_data(inode)) { err = f2fs_convert_inline_inode(inode); @@ -944,13 +948,18 @@ static int punch_hole(struct inode *inod blk_start = (loff_t)pg_start << PAGE_SHIFT; blk_end = (loff_t)pg_end << PAGE_SHIFT; + down_write(&F2FS_I(inode)->i_mmap_sem); + down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + truncate_inode_pages_range(mapping, blk_start, blk_end - 1); f2fs_lock_op(sbi); ret = f2fs_truncate_hole(inode, pg_start, pg_end); f2fs_unlock_op(sbi); + + up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); up_write(&F2FS_I(inode)->i_mmap_sem); } }