Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp5602500imm; Mon, 27 Aug 2018 00:28:33 -0700 (PDT) X-Google-Smtp-Source: ANB0VdYirByAEhIZGNfhzrI3sFZICEbDD7KMghoXsVFlRhhvv456i0WWz3VfwYXzjeDHmDj1B8dl X-Received: by 2002:a17:902:6b05:: with SMTP id o5-v6mr12101332plk.338.1535354913506; Mon, 27 Aug 2018 00:28:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1535354913; cv=none; d=google.com; s=arc-20160816; b=EhziUdXRo6RVSuAus7U9fnilyclNzV3hnF42E1ILcIs87E4QuPaRg16Hv8oISZkcty 2LrarzKb4FHO0fXB3VmMO/qdUX692tLF01fr08+lCGedy33YUkwyqz26d7B4DiTVMGu2 8XldNASmSfqGBAmtSC7AFqfIiaxi+LaM/4qIyxoNAtGIZkdXC0Au93DV/+qE/0bUGxCT KrIaXTIvbB1U03rcOANOkeHaEsAjJA52v0U9fARuScO6uzuzPYVCTdGTorHD9jfdEG6s XB/44h2JSsuRji57oAF0IyeA0PIeGYK6z53s5miaCVblFwpJMI3kHTTE1+cPIpZ2OYQF 2Dow== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :arc-authentication-results; bh=f2Htz9UGfNcjgLDmOhbqhJfG35UvnPnYgEjuSpSNhSE=; b=a0XFlULIhLOIFgdN0gJ9ImcRBFHYjrAZ5IHRDSPXcF5soYnpO2tXszvmiKUVFNKo2X 2M9TOEaIr7kxnSZXS03FvHOyJz00nB1BOUaEcn/1uJj3Z3DXiGtcuUlH4zBbamt0DzEX ZArP/a+CJ6EtVzSuoQLr+YP+FM31F0yc8V0ZGgyE2AX3m52lOZKgTWGa9IL2adUtR0LV 0P896zghWBnBwW+21kCy+fgauLWJiRBZdq0nr9aGrc+6rZayDpfLkf7WIT864xz9uQG2 5IvM2zmHTnnMYP34NNEb45h11y2XW89pUa16/XMzX+yCLNr/4hBnw+o5IQ6G+jRS1bqh ghaQ== 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 21-v6si13169672pgg.588.2018.08.27.00.28.18; Mon, 27 Aug 2018 00:28:33 -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 S1727218AbeH0LMN (ORCPT + 99 others); Mon, 27 Aug 2018 07:12:13 -0400 Received: from smtp2.provo.novell.com ([137.65.250.81]:60028 "EHLO smtp2.provo.novell.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726882AbeH0LMN (ORCPT ); Mon, 27 Aug 2018 07:12:13 -0400 Received: from Beta.suse.asia (prv-ext-foundry1int.gns.novell.com [137.65.251.240]) by smtp2.provo.novell.com with ESMTP (NOT encrypted); Mon, 27 Aug 2018 01:26:44 -0600 From: Larry Chen To: mfasheh@suse.com, jlbec@evilplan.org Cc: linux-kernel@vger.kernel.org, ocfs2-devel@oss.oracle.com, akpm@linux-foundation.org Subject: [PATCH V2] fix crash on ocfs2_duplicate_clusters_by_page Date: Mon, 27 Aug 2018 15:26:34 +0800 Message-Id: <20180827072634.23700-1-lchen@suse.com> X-Mailer: git-send-email 2.13.7 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org ocfs2_duplicate_clusters_by_page may crash if one of extent's pages is dirty. When a page has not been written back, it is still in dirty state. If ocfs2_duplicate_clusters_by_page is called against the dirty page, the crash happens. To fix this bug, we can just unlock the page and wait the page until it's not dirty. The following is the buck trace dump: kernel BUG at /root/code/ocfs2/refcounttree.c:2961! [exception RIP: ocfs2_duplicate_clusters_by_page+822] __ocfs2_move_extent+0x80/0x450 [ocfs2] ? __ocfs2_claim_clusters+0x130/0x250 [ocfs2] ocfs2_defrag_extent+0x5b8/0x5e0 [ocfs2] __ocfs2_move_extents_range+0x2a4/0x470 [ocfs2] ocfs2_move_extents+0x180/0x3b0 [ocfs2] ? ocfs2_wait_for_recovery+0x13/0x70 [ocfs2] ocfs2_ioctl_move_extents+0x133/0x2d0 [ocfs2] ocfs2_ioctl+0x253/0x640 [ocfs2] do_vfs_ioctl+0x90/0x5f0 SyS_ioctl+0x74/0x80 do_syscall_64+0x74/0x140 entry_SYSCALL_64_after_hwframe+0x3d/0xa2 Change-log: 1. Once we founce the page is dirty, we do not wait until it's clean, but rather we use write_one_page to write it back Signed-off-by: Larry Chen --- fs/ocfs2/refcounttree.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 7869622af22a..380c9ae2f467 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c @@ -2946,6 +2946,7 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle, if (map_end & (PAGE_SIZE - 1)) to = map_end & (PAGE_SIZE - 1); +retry: page = find_or_create_page(mapping, page_index, GFP_NOFS); if (!page) { ret = -ENOMEM; @@ -2957,8 +2958,15 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle, * In case PAGE_SIZE <= CLUSTER_SIZE, This page * can't be dirtied before we CoW it out. */ - if (PAGE_SIZE <= OCFS2_SB(sb)->s_clustersize) - BUG_ON(PageDirty(page)); + if (PAGE_SIZE <= OCFS2_SB(sb)->s_clustersize) { + if (PageDirty(page)) { + /* + * write_on_page will unlock the page on return + */ + ret = write_one_page(page, 1); + goto retry; + } + } if (!PageUptodate(page)) { ret = block_read_full_page(page, ocfs2_get_block); -- 2.13.7