Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp87263pxj; Mon, 17 May 2021 21:44:09 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz86gV7ni2yydWi8B9zZ+PIcN0149TERHrfVwQD8j1UzJoCtYzHWhflPP0OzXYZ9eL7OwvB X-Received: by 2002:a05:6602:18:: with SMTP id b24mr2773197ioa.1.1621313049453; Mon, 17 May 2021 21:44:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621313049; cv=none; d=google.com; s=arc-20160816; b=Lo0/r2t3YArJBtavCmqviG641gvdsDdwpua93866lDnAbiJzFZAXRbx1h1J5YdbXYX zLAnqu8sEWIRjLZYCXSYDilRQbA9vtIqpFbe6BZRfKEKsNzh6i5bq+niyvkEXaKBKcpX 95f9ERQg5WjJiXdCzFfXQ9d+6MlTYvtLZJMtrZLqjeBbOuh0SC2nIsy9KQ6JCRtBN5ml fGpvOO6C7poQvpUmGQkkGXw88SiyivJpXO2ehDff83jM//1q80jz54a48NPyGNEyJSVC Jdxms3Br6YrVB+MCv+lTof74W0+2vf/LC2aGH5cHv7P9FsLmqutDevSqDmPMt0+av1/F BySg== 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=NzlLlNiAxlbiqSr5hYsfMmJFuLjcSS/ej4kfB/WI9mI=; b=qkcM9WWdrjc2IaYQaNMPri5Ye+EfhmJlCIvavwXdgmAnbxaSUnP2fSdeMuJ3CLbHxj 7q3WQ8TIiD0HDHZy6mZS6KC7IoExJgxkxmgyEVBaZZqJguStnXfAHsiXq9GREXMGNdzp J1ILezB9MH6WVtJat+PBYwdIUcFivNRil0+cJ4HpSoPzDHsbg4RtJ8rc18VgganGqBlO fY1+AOyVqrNI6zrdOvC3/5HLo5Gx3JLc3bPrYGGQ3Z8PfC8G4APbRn+B9kt2eFVCEBNC BMlH3vJjm/xbzvtWhMVm77TbwODTeq7uUcwwBkE1Ii37W/O1xj0yG2H56OreX6LqzMvZ bfNw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=kjayehsf; 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 n15si20583608ili.65.2021.05.17.21.43.45; Mon, 17 May 2021 21:44:09 -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=kjayehsf; 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 S240463AbhEQOmu (ORCPT + 99 others); Mon, 17 May 2021 10:42:50 -0400 Received: from mail.kernel.org ([198.145.29.99]:34064 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240132AbhEQOhV (ORCPT ); Mon, 17 May 2021 10:37:21 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id CE3436141F; Mon, 17 May 2021 14:17:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1621261067; bh=5h3uOEcfMp7BGV5MOwf5UPhumR6hzpKO+nL0flWIL98=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kjayehsfrY0czatQeA5/46iQUJVnKFI135w5KeWIrBuTusNmuGn6envHxzqXg8uXs GFzArAzyqz2ufDGcCT+z7Ux/l16cpS/n8aq71bxyLDwpj+L3ZjJInI2SOEL6pdGACj djWT98IG1UGv4tZSE98VvZG+fscQ0MizEScWXtNw= 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.12 301/363] f2fs: compress: fix race condition of overwrite vs truncate Date: Mon, 17 May 2021 16:02:47 +0200 Message-Id: <20210517140312.778463974@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210517140302.508966430@linuxfoundation.org> References: <20210517140302.508966430@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 146a8eb3891b..b7ab3bdf2259 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) { @@ -1048,7 +1035,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); } @@ -1058,32 +1045,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; } @@ -1115,10 +1104,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