From: Josef Bacik <jbacik@fusionio.com>
To: Liu Bo <bo.li.liu@oracle.com>
Cc: <linux-btrfs@vger.kernel.org>
Subject: Re: [PATCH] Btrfs: fix crash of compressed writes
Date: Mon, 30 Sep 2013 13:02:49 -0400 [thread overview]
Message-ID: <20130930170249.GO18681@localhost.localdomain> (raw)
In-Reply-To: <1380544797-29798-1-git-send-email-bo.li.liu@oracle.com>
On Mon, Sep 30, 2013 at 08:39:57PM +0800, Liu Bo wrote:
> The crash[1] is found by xfstests/generic/208 with "-o compress",
> it's not reproduced everytime, but it does panic.
>
> The bug is quite interesting, it's actually introduced by a recent commit
> (573aecafca1cf7a974231b759197a1aebcf39c2a,
> Btrfs: actually limit the size of delalloc range).
>
> Btrfs implements delay allocation, so during writeback, we
> (1) get a page A and lock it
> (2) search the state tree for delalloc bytes and lock all pages within the range
> (3) process the delalloc range, including find disk space and create
> ordered extent and so on.
> (4) submit the page A.
>
> It runs well in normal cases, but if we're in a racy case, eg.
> buffered compressed writes and aio-dio writes,
> sometimes we may fail to lock all pages in the 'delalloc' range,
> in which case, we need to fall back to search the state tree again with
> a smaller range limit(max_bytes = PAGE_CACHE_SIZE - offset).
>
> The mentioned commit has a side effect, that is, in the fallback case,
> we can find delalloc bytes before the index of the page we already have locked,
> so we're in the case of (delalloc_end <= *start) and return with (found > 0).
>
> This ends with not locking delalloc pages but making ->writepage still
> process them, and the crash happens.
>
> This fixes it by not enforcing the 'max_bytes' limit in the special fallback
> case.
>
Great analysis, thank you for that, however I don't like the fix ;). Instead We
need to change the
if (!found || delalloc_end <= *start)
to always return 0 since we should not call fill delalloc if the delalloc range
doesn't start at our current offset. Secondly the
max_bytes = PAGE_CACHE_SIZE - offset;
is completely crap since we are talking about the entire page/sector. We should
simply set max_bytes to sectorszie or PAGE_CACHE_SIZE that way we avoid this
issue. Thanks,
Josef
next prev parent reply other threads:[~2013-09-30 17:02 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-09-30 12:39 [PATCH] Btrfs: fix crash of compressed writes Liu Bo
2013-09-30 17:02 ` Josef Bacik [this message]
2013-10-01 3:37 ` Liu Bo
2013-10-01 12:38 ` Josef Bacik
2013-10-01 15:42 ` Liu Bo
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=20130930170249.GO18681@localhost.localdomain \
--to=jbacik@fusionio.com \
--cc=bo.li.liu@oracle.com \
--cc=linux-btrfs@vger.kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).