Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp547035pxj; Tue, 18 May 2021 09:01:20 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyNtR+imrxep/LlOjNDneJYIO1lyw6S3OxzwnPhLnQWSUP7HudDXRl9kUZLWREP1Ymo1YgC X-Received: by 2002:aa7:c684:: with SMTP id n4mr558114edq.357.1621353680681; Tue, 18 May 2021 09:01:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621353680; cv=none; d=google.com; s=arc-20160816; b=sJm2bmessxHcbC3OJeKId7wnBOu4Liei3LBZdNYffyltQ/1PbtNkklQVVh1Z7n0qQw 5COaClvwN0Wo7a4iuRiCOg/KmffMxIb61oWJAQFBUAS6sz445JgMofTpRUnG6kPZS7JK /RgEE0ClaqJuuk2NE6J1RyarE83zGYKyzcqSTzp4gGM0m8w07j0KAen3eDjqaybbWXNx qU5U3bSdCAs9LcVZHZmf6+aW2NtHN6rl+XhdUETMglPv/Rn1OCxdgEFsPllgbUXyBTFq wDCGxm106I5zmewN9o1MYbuWG4ysbBI6xzwgCYeW+CafnIllofSy+N6uqcNlfF4JBdJn UVAw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=LrX/ybDNUIV2QwClhXmdEV9S8imk7IMBZguw3Tki+8E=; b=ZQlbFF0GRaRvnW4ZTX759OOGKjQlTIveq+DCQL+PF027Jx+3CGNCYGCwcBS/nMxbrI /3nHFBHz0asCdgEaQByqHntZPDpkRrp09963pPLGumiWifJA92B30IHQw8N3hGHNjRS8 ywP6BukRIKE8R1GvwAnUMkUGxla6BLfG3Ej0nW8eKiDpPy+JzAavdacjXW9HwUTD7i8v nNvqQNpVCJwRGXomUn/Z78rBKvTbT1/q4Xcsx9aJ4ElGhuYqeuh1a8TFh+MOm7hbb3Fu 80hOvzdZVaAAmMYlLjv2bU2aEf986gh3q5k6x+JnuLS9A9AmoBeuVcbGJXCknYdqKo5W ADVQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=PiF0IEY7; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id l3si20654962ejd.203.2021.05.18.09.00.48; Tue, 18 May 2021 09:01:20 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=PiF0IEY7; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344356AbhEQP7R (ORCPT + 99 others); Mon, 17 May 2021 11:59:17 -0400 Received: from mail.kernel.org ([198.145.29.99]:51450 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343528AbhEQPjj (ORCPT ); Mon, 17 May 2021 11:39:39 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id C095661CFF; Mon, 17 May 2021 14:41:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1621262488; bh=WunRfjUgmSekC9nRkUs4dFH3ggSHfyxtdwAgmpGxhu8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PiF0IEY7Pzo+6a3DgdbrFx4Md5pkBgSfvMw/f5CpsjmYCQwu4dFbpSTw/En/Nylam I1Fbb2NsaPtf7npitc/vH7zH0W7LUXrULeKjxJFQdB7EGbd/sUvoH0voprRWf5cKWU CkKLuXmV/a3gYt06h56DiebP9A7ZNCNqwlHRbFRs= 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 5.11 276/329] f2fs: compress: fix race condition of overwrite vs truncate Date: Mon, 17 May 2021 16:03:07 +0200 Message-Id: <20210517140311.444802455@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210517140302.043055203@linuxfoundation.org> References: <20210517140302.043055203@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Chao Yu [ Upstream commit a949dc5f2c5cfe0c910b664650f45371254c0744 ] pos_fsstress testcase complains a panic as belew: ------------[ cut here ]------------ kernel BUG at fs/f2fs/compress.c:1082! invalid opcode: 0000 [#1] SMP PTI CPU: 4 PID: 2753477 Comm: kworker/u16:2 Tainted: G OE 5.12.0-rc1-custom #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 Workqueue: writeback wb_workfn (flush-252:16) RIP: 0010:prepare_compress_overwrite+0x4c0/0x760 [f2fs] Call Trace: f2fs_prepare_compress_overwrite+0x5f/0x80 [f2fs] f2fs_write_cache_pages+0x468/0x8a0 [f2fs] f2fs_write_data_pages+0x2a4/0x2f0 [f2fs] do_writepages+0x38/0xc0 __writeback_single_inode+0x44/0x2a0 writeback_sb_inodes+0x223/0x4d0 __writeback_inodes_wb+0x56/0xf0 wb_writeback+0x1dd/0x290 wb_workfn+0x309/0x500 process_one_work+0x220/0x3c0 worker_thread+0x53/0x420 kthread+0x12f/0x150 ret_from_fork+0x22/0x30 The root cause is truncate() may race with overwrite as below, so that one reference count left in page can not guarantee the page attaching in mapping tree all the time, after truncation, later find_lock_page() may return NULL pointer. - prepare_compress_overwrite - f2fs_pagecache_get_page - unlock_page - f2fs_setattr - truncate_setsize - truncate_inode_page - delete_from_page_cache - find_lock_page Fix this by avoiding referencing updated page. Fixes: 4c8ff7095bef ("f2fs: support data compression") Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin --- fs/f2fs/compress.c | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index ac12adc17f5e..8093d06116b4 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -123,19 +123,6 @@ static void f2fs_unlock_rpages(struct compress_ctx *cc, int len) f2fs_drop_rpages(cc, len, true); } -static void f2fs_put_rpages_mapping(struct address_space *mapping, - pgoff_t start, int len) -{ - int i; - - for (i = 0; i < len; i++) { - struct page *page = find_get_page(mapping, start + i); - - put_page(page); - put_page(page); - } -} - static void f2fs_put_rpages_wbc(struct compress_ctx *cc, struct writeback_control *wbc, bool redirty, int unlock) { @@ -1008,7 +995,7 @@ static int prepare_compress_overwrite(struct compress_ctx *cc, } if (PageUptodate(page)) - unlock_page(page); + f2fs_put_page(page, 1); else f2fs_compress_ctx_add_page(cc, page); } @@ -1018,32 +1005,34 @@ static int prepare_compress_overwrite(struct compress_ctx *cc, ret = f2fs_read_multi_pages(cc, &bio, cc->cluster_size, &last_block_in_bio, false, true); + f2fs_put_rpages(cc); f2fs_destroy_compress_ctx(cc); if (ret) - goto release_pages; + goto out; if (bio) f2fs_submit_bio(sbi, bio, DATA); ret = f2fs_init_compress_ctx(cc); if (ret) - goto release_pages; + goto out; } for (i = 0; i < cc->cluster_size; i++) { f2fs_bug_on(sbi, cc->rpages[i]); page = find_lock_page(mapping, start_idx + i); - f2fs_bug_on(sbi, !page); + if (!page) { + /* page can be truncated */ + goto release_and_retry; + } f2fs_wait_on_page_writeback(page, DATA, true, true); - f2fs_compress_ctx_add_page(cc, page); - f2fs_put_page(page, 0); if (!PageUptodate(page)) { +release_and_retry: + f2fs_put_rpages(cc); f2fs_unlock_rpages(cc, i + 1); - f2fs_put_rpages_mapping(mapping, start_idx, - cc->cluster_size); f2fs_destroy_compress_ctx(cc); goto retry; } @@ -1075,10 +1064,10 @@ static int prepare_compress_overwrite(struct compress_ctx *cc, } unlock_pages: + f2fs_put_rpages(cc); f2fs_unlock_rpages(cc, i); -release_pages: - f2fs_put_rpages_mapping(mapping, start_idx, i); f2fs_destroy_compress_ctx(cc); +out: return ret; } -- 2.30.2