From: Jan Kara <jack@suse.cz>
To: "zhangyi (F)" <yi.zhang@huawei.com>
Cc: jack@suse.cz, tytso@mit.edu, linux-ext4@vger.kernel.org,
luoshijie1@huawei.com, zhangxiaoxu5@huawei.com
Subject: Re: [PATCH v3 2/2] jbd2: do not clear the BH_Mapped flag when forgetting a metadata buffer
Date: Mon, 17 Feb 2020 10:36:45 +0100 [thread overview]
Message-ID: <20200217093645.GC12032@quack2.suse.cz> (raw)
In-Reply-To: <20200213063821.30455-3-yi.zhang@huawei.com>
On Thu 13-02-20 14:38:21, 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, we should always keep the mapped
> flag and clear the dirty flags is enough, so this patch pick out the
> these buffers and keep their BH_Mapped flag.
>
> Fixes: 904cdbd41d74 ("jbd2: clear dirty flag when revoking a buffer from an older transaction")
> Signed-off-by: zhangyi (F) <yi.zhang@huawei.com>
> ---
> fs/jbd2/commit.c | 25 +++++++++++++++++++++----
> 1 file changed, 21 insertions(+), 4 deletions(-)
Thanks! The patch looks good. I have just some comment reformulation
suggestion below, otherwise feel free to add:
Reviewed-by: Jan Kara <jack@suse.cz>
> diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
> index 6396fe70085b..27373f5792a4 100644
> --- a/fs/jbd2/commit.c
> +++ b/fs/jbd2/commit.c
> @@ -985,12 +985,29 @@ void jbd2_journal_commit_transaction(journal_t *journal)
> * pagesize and it is attached to the last partial page.
> */
> if (buffer_freed(bh) && !jh->b_next_transaction) {
> + struct address_space *mapping;
> +
> clear_buffer_freed(bh);
> clear_buffer_jbddirty(bh);
> - clear_buffer_mapped(bh);
> - clear_buffer_new(bh);
> - clear_buffer_req(bh);
> - bh->b_bdev = NULL;
> +
> + /*
> + * Block device buffers need to stay mapped all the
> + * time, so it is enough to clear buffer_jbddirty and
> + * buffer_freed bits. For the file mapping buffers (i.e.
> + * journalled data) we need to unmap buffer and clear
> + * more bits. We also need to be careful about the check
> + * because the data page mapping can get cleared under
> + * out hands, which alse need not to clear more bits
^^^ our ^^^^ Maybe I'd rephrase this like:
... under our hands. Note that if mapping == NULL, we don't need to make
buffer unmapped because the page is already detached from the mapping and
buffers cannot get reused.
> + * because the page and buffers will be freed and can
> + * never be reused once we are done with them.
> + */
> + mapping = READ_ONCE(bh->b_page->mapping);
> + if (mapping && !sb_is_blkdev_sb(mapping->host->i_sb)) {
> + clear_buffer_mapped(bh);
> + clear_buffer_new(bh);
> + clear_buffer_req(bh);
> + bh->b_bdev = NULL;
> + }
> }
Honza
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
next prev parent reply other threads:[~2020-02-17 9:36 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-13 6:38 [PATCH v3 0/2] jbd2: fix an oops problem zhangyi (F)
2020-02-13 6:38 ` [PATCH v3 1/2] jbd2: move the clearing of b_modified flag to the journal_unmap_buffer() zhangyi (F)
2020-02-13 6:38 ` [PATCH v3 2/2] jbd2: do not clear the BH_Mapped flag when forgetting a metadata buffer zhangyi (F)
2020-02-17 9:36 ` Jan Kara [this message]
2020-02-17 10:38 ` zhangyi (F)
2020-02-18 17:04 ` Theodore Y. Ts'o
2020-02-18 5:18 ` Ritesh Harjani
2020-02-18 16:46 ` Theodore Y. Ts'o
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200217093645.GC12032@quack2.suse.cz \
--to=jack@suse.cz \
--cc=linux-ext4@vger.kernel.org \
--cc=luoshijie1@huawei.com \
--cc=tytso@mit.edu \
--cc=yi.zhang@huawei.com \
--cc=zhangxiaoxu5@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.