From patchwork Fri Oct 9 09:02:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "yebin (H)" X-Patchwork-Id: 1379077 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=huawei.com Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4C71zK6yV1z9sTq for ; Fri, 9 Oct 2020 19:52:13 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732953AbgJIIwK (ORCPT ); Fri, 9 Oct 2020 04:52:10 -0400 Received: from szxga06-in.huawei.com ([45.249.212.32]:57148 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1732496AbgJIIwK (ORCPT ); Fri, 9 Oct 2020 04:52:10 -0400 Received: from DGGEMS408-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id 59A21BE4E6B029381D37; Fri, 9 Oct 2020 16:52:08 +0800 (CST) Received: from huawei.com (10.90.53.225) by DGGEMS408-HUB.china.huawei.com (10.3.19.208) with Microsoft SMTP Server id 14.3.487.0; Fri, 9 Oct 2020 16:51:58 +0800 From: Ye Bin To: , , , CC: Ye Bin Subject: [PATCH] ext4: Fix WARN_ON_ONCE in __ext4_handle_dirty_metadata() Date: Fri, 9 Oct 2020 17:02:44 +0800 Message-ID: <20201009090244.111352-1-yebin10@huawei.com> X-Mailer: git-send-email 2.16.2.dirty MIME-Version: 1.0 X-Originating-IP: [10.90.53.225] X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org When run fsstress with disk offline/online, I got follow warning: [ 47.395783] ------------[ cut here ]------------ [ 47.400554] sd 1:0:0:0: rejecting I/O to offline device [ 47.403327] WARNING: CPU: 3 PID: 2420 at fs/buffer.c:1117 mark_buffer_dirty+0xcd/0xe0 [ 47.406093] Modules linked in: [ 47.407322] CPU: 3 PID: 2420 Comm: fsstress Not tainted 3.10.0-862.14.0.6.x86_64 #136 [ 47.409702] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996),BIOS ? -20190727_073836-buildvm-ppc64le-16.ppc.fedoraproject.org-3.fc3104/01/2014 [ 47.413142] Call Trace: [ 47.413473] sd 1:0:0:0: rejecting I/O to offline device [ 47.414805] [] dump_stack+0x19/0x1b [ 47.415866] [] __warn+0xd8/0x100 [ 47.416970] [] warn_slowpath_null+0x1d/0x20 [ 47.418115] [] mark_buffer_dirty+0xcd/0xe0 [ 47.419247] [] __ext4_handle_dirty_metadata+0x1a8/0x220 [ 47.420408] [] ? __ext4_journal_get_write_access+0x53/0x110 [ 47.421430] [] __ext4_new_inode+0x921/0x1350 [ 47.422276] [] ext4_create+0xd9/0x1a0 [ 47.423071] [] vfs_create+0xd3/0x140 [ 47.423820] [] do_last+0x10f0/0x12c0 [ 47.424627] [] ? selinux_file_alloc_security+0x3c/0x60 [ 47.425571] [] path_openat+0xd7/0x640 [ 47.426389] [] ? system_call_fastpath+0x22/0x27 [ 47.428099] [] ? create_object+0x234/0x310 [ 47.428922] [] do_filp_open+0x4d/0xb0 [ 47.429724] [] ? files_cgroup_alloc_fd+0x39/0x60 [ 47.430623] [] ? __alloc_fd+0xe5/0x180 [ 47.431361] [] do_sys_open+0x137/0x240 [ 47.432275] [] ? system_call_after_swapgs+0xa2/0x146 [ 47.433214] [] SyS_open+0x1e/0x20 [ 47.433959] [] SyS_creat+0x16/0x20 [ 47.434675] [] system_call_fastpath+0x22/0x27 [ 47.435555] [] ? system_call_after_swapgs+0xae/0x146 [ 47.436468] ---[ end trace f8ed64a9adfa868b ]--- In fact, I got a lot of call trace. All call trace trigger warning when call __ext4_handle_dirty_metadate. If there are racing calls to __ext4_handle_dirty_metadate. It's possible for another writeback result in the buffer being marked with an error after we check if the buffer is marked as having a write error and the buffer up-to-date flag is cleared. If that happens mark_buffer_dirty() can end up throwing a WARN_ON_ONCE. To Fix this warning, lock buffer when call mark_buffer_dirty in function __ext4_handle_dirty_metadate. Signed-off-by: Ye Bin --- fs/ext4/ext4_jbd2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c index 760b9ee49dc0..306ede92ee40 100644 --- a/fs/ext4/ext4_jbd2.c +++ b/fs/ext4/ext4_jbd2.c @@ -355,11 +355,13 @@ int __ext4_handle_dirty_metadata(const char *where, unsigned int line, err); } } else { + lock_buffer(bh); set_buffer_uptodate(bh); if (inode) mark_buffer_dirty_inode(bh, inode); else mark_buffer_dirty(bh); + unlock_buffer(bh); if (inode && inode_needs_sync(inode)) { sync_dirty_buffer(bh); if (buffer_req(bh) && !buffer_uptodate(bh)) {