Received: by 2002:a25:1506:0:0:0:0:0 with SMTP id 6csp1422376ybv; Thu, 6 Feb 2020 03:52:56 -0800 (PST) X-Google-Smtp-Source: APXvYqwj/DT1TTI0TPz5/5NI5/6yr8ox9LSBzZEWiTO8wEmhp93/UZmm+dj0HH34geb4dnOHMSoK X-Received: by 2002:aca:c0c5:: with SMTP id q188mr6312910oif.169.1580989975849; Thu, 06 Feb 2020 03:52:55 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1580989975; cv=none; d=google.com; s=arc-20160816; b=PVQKrN+H2KI8tBG92rKWjLXdx2nfDmzg4Or3dSxVPW5wfJuvoduuARdq38iDwrx8Zc a2HmnrK0I6j9f5rPOQ85fYH0ztaA8DGnYahMtBWla322XCsYL2tOMCDpEHr1uqZ2fdZG 8FY4hg1Wq5kjuNPKM9VF9bCBlRP7ledY0UPgR/wXp9ii4bY2nbG40Rc69WNAUaqojrnR RykJjdPFDkMkgIw6QY7xOpgzwkGyTi/svtStXLRFiJhYKE5PPXRzSZk1DHoJzvBh7L4+ SSSDGipku2PhtgpPivtkmSB3OiI9laO9eudQB5hAGfjhJqsob+x3+cSU6v6Oj/74eGTE g5Cw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date; bh=ILG+9DbHQ+koDal7SviBHD9IlJ4IoI+ZH+xpIMTVkYQ=; b=jwr2ypChOZXj6+r5h8Qe0G2QD0Hzj91FlEpZMRoUE/c0fik3SEU9mIcImE69Hlb999 hnnxWDc/WDX1mby+UC2yUHoLEm8Q8JHJ1njbI+rjHDXtrSsaevnxeB5nrArezA3knpdK PrAw2wYC5mya5qbv5IiDTDvz5Y6+WoXKI/f/KQ1OFe6VFs0qHSZLqAX/UrThZViyDNqn dKIy3fnRz85DCaw/AnG0NP8971rnUNn4AUxw2oBRmjGsZ2sS8/FkynwHiaDa9Mly4BY/ bGY2pgDSz7R0fBe6urBVqk5i4gCkS+KNrSFycwx8z3gX2vtIFQVdhVzDISWuAdGmsSHs jRHg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-ext4-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-ext4-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 h28si1907628otg.63.2020.02.06.03.52.38; Thu, 06 Feb 2020 03:52:55 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-ext4-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-ext4-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726956AbgBFLqu (ORCPT + 99 others); Thu, 6 Feb 2020 06:46:50 -0500 Received: from mx2.suse.de ([195.135.220.15]:58394 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726538AbgBFLqu (ORCPT ); Thu, 6 Feb 2020 06:46:50 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 01135AD07; Thu, 6 Feb 2020 11:46:47 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id 67F551E0E31; Thu, 6 Feb 2020 12:46:47 +0100 (CET) Date: Thu, 6 Feb 2020 12:46:47 +0100 From: Jan Kara To: "zhangyi (F)" Cc: jack@suse.cz, tytso@mit.edu, linux-ext4@vger.kernel.org, luoshijie1@huawei.com, zhangxiaoxu5@huawei.com Subject: Re: [PATCH 2/2] jbd2: do not clear the BH_Mapped flag when forgetting a metadata buffer Message-ID: <20200206114647.GB3994@quack2.suse.cz> References: <20200203140458.37397-1-yi.zhang@huawei.com> <20200203140458.37397-3-yi.zhang@huawei.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20200203140458.37397-3-yi.zhang@huawei.com> User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org On Mon 03-02-20 22:04:58, zhangyi (F) wrote: > Commit 904cdbd41d74 ("jbd2: clear dirty flag when revoking a buffer from > an older transaction") set the BH_Freed flag when forgetting a metadata > buffer which belongs to the committing transaction, it indicate the > committing process clear dirty bits when it is done with the buffer. But > it also clear the BH_Mapped flag at the same time, which may trigger > below NULL pointer oops when block_size < PAGE_SIZE. > > rmdir 1 kjournald2 mkdir 2 > jbd2_journal_commit_transaction > commit transaction N > jbd2_journal_forget > set_buffer_freed(bh1) > jbd2_journal_commit_transaction > commit transaction N+1 > ... > clear_buffer_mapped(bh1) > ext4_getblk(bh2 ummapped) > ... > grow_dev_page > init_page_buffers > bh1->b_private=NULL > bh2->b_private=NULL > jbd2_journal_put_journal_head(jh1) > __journal_remove_journal_head(hb1) > jh1 is NULL and trigger oops > > *) Dir entry block bh1 and bh2 belongs to one page, and the bh2 has > already been unmapped. > > For the metadata buffer we forgetting, clear the dirty flags is enough, > so this patch add BH_Unmap flag for the journal_unmap_buffer() case and > keep the mapped flag for the metadata buffer. > > Fixes: 904cdbd41d74 ("jbd2: clear dirty flag when revoking a buffer from an older transaction") > Signed-off-by: zhangyi (F) Good spotting! Thanks for the patch. Some comments below: > diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c > index 6396fe70085b..a649cdd1c5e5 100644 > --- a/fs/jbd2/commit.c > +++ b/fs/jbd2/commit.c > @@ -987,10 +987,13 @@ void jbd2_journal_commit_transaction(journal_t *journal) > if (buffer_freed(bh) && !jh->b_next_transaction) { > clear_buffer_freed(bh); > clear_buffer_jbddirty(bh); > - clear_buffer_mapped(bh); > - clear_buffer_new(bh); > - clear_buffer_req(bh); > - bh->b_bdev = NULL; > + if (buffer_unmap(bh)) { > + clear_buffer_unmap(bh); > + clear_buffer_mapped(bh); > + clear_buffer_new(bh); > + clear_buffer_req(bh); > + bh->b_bdev = NULL; > + } Any reason why you don't want to clear buffer_req and buffer_new flags for all buffers as well? I agree that b_bdev setting and buffer_mapped need special treatment. Also rather than introducing this new buffer_unmap bit, I'd use the fact this special treatment is needed only for buffers coming from the block device mapping. And we can check for that like: /* * We can (and need to) unmap buffer only for normal mappings. * Block device buffers need to stay mapped all the time. * We need to be careful about the check because the page * mapping can get cleared under our hands. */ mapping = READ_ONCE(bh->b_page->mapping); if (mapping && !sb_is_blkdev_sb(mapping->host->i_sb)) { ... } Longer term, we might want to rework how the handling of truncated buffers works with JDB2. There's lots of duplication between jbd2_journal_forget() and jbd2_journal_unmap_buffer(), the dirtiness is tracked in jh->b_modified as well as buffer_jbddirty() and it is further redundant with the journal list the buffer is currently on. So I suspect it could all be simplified if we took a fresh look at things. Honza -- Jan Kara SUSE Labs, CR