All of lore.kernel.org
 help / color / mirror / Atom feed
From: Liu Bo <bo.li.liu@oracle.com>
To: dsterba@suse.cz, linux-btrfs@vger.kernel.org
Subject: Re: [PATCH 5/7] Btrfs: replace BUG_ON with WARN in merge_bio
Date: Tue, 17 May 2016 10:30:47 -0700	[thread overview]
Message-ID: <20160517173047.GA8522@localhost.localdomain> (raw)
In-Reply-To: <20160517095519.GI511@twin.jikos.cz>

On Tue, May 17, 2016 at 11:55:19AM +0200, David Sterba wrote:
> On Mon, May 16, 2016 at 10:24:01AM -0700, Liu Bo wrote:
> > On Mon, May 16, 2016 at 10:44:38AM +0200, David Sterba wrote:
> > > On Fri, May 13, 2016 at 05:07:00PM -0700, Liu Bo wrote:
> > > > We have two BUG_ON in merge_bio, but since it can gracefully return errors
> > > > to callers, use WARN_ONCE to give error information and don't leave a
> > > > possible panic.
> > > > 
> > > > Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
> > > > ---
> > > >  fs/btrfs/extent_io.c | 1 -
> > > >  fs/btrfs/inode.c     | 6 ++++--
> > > >  2 files changed, 4 insertions(+), 3 deletions(-)
> > > > 
> > > > diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
> > > > index e601e0f..99286d1 100644
> > > > --- a/fs/btrfs/extent_io.c
> > > > +++ b/fs/btrfs/extent_io.c
> > > > @@ -2746,7 +2746,6 @@ static int merge_bio(int rw, struct extent_io_tree *tree, struct page *page,
> > > >  	if (tree->ops && tree->ops->merge_bio_hook)
> > > >  		ret = tree->ops->merge_bio_hook(rw, page, offset, size, bio,
> > > >  						bio_flags);
> > > > -	BUG_ON(ret < 0);
> > > >  	return ret;
> > > >  
> > > >  }
> > > > diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
> > > > index 5874562..3a989e3 100644
> > > > --- a/fs/btrfs/inode.c
> > > > +++ b/fs/btrfs/inode.c
> > > > @@ -1827,8 +1827,10 @@ int btrfs_merge_bio_hook(int rw, struct page *page, unsigned long offset,
> > > >  	map_length = length;
> > > >  	ret = btrfs_map_block(root->fs_info, rw, logical,
> > > >  			      &map_length, NULL, 0);
> > > > -	/* Will always return 0 with map_multi == NULL */
> > > > -	BUG_ON(ret < 0);
> > > > +	if (ret < 0) {
> > > > +		WARN_ONCE(ret < 0, KERN_ERR "ret = %d\n", ret);
> > > 
> > > btrfs_map_block is quite verbose about the errors so it's not needed to
> > > print it here.
> > 
> > OK.
> > 
> > > 
> > > Otherwise I'm not sure if all paths that go through the merge hook
> > > handle errors, eg. in btrfs_submit_compressed_read or _write. Some code
> > > is skipped if merge hook returns nonzero. But, the code expects either 0
> > > or 1, and when the BUG_ON(ret < 0) is removed suddenly the 'ret < 0' can
> > > be returned. Unexpected.
> > 
> > Right now btrfs_merge_bio_hook() only returns 1 or 0 and marks (ret < 0) as
> >  BUG_ON.
> 
> IOW, "ret < 0" never leaves btrfs_merge_bio_hook in current code.

OK.

> 
> > But compress code is ready to handle the error,
> > 
> > btrfs_submit_compressed_read/write() {
> > 	...
> > 	ret = merge_bio_hook()
> > 	if (ret || bio_add_page()) {
> 
> This code expects 0 or 1, < 0 is not expected here and has to be
> considered after the change in merge_bio_hook.

OK.

> 
> > 		ret = btrfs_map_bio();
> > 		BUG_ON(ret);
> > 		...
> > 	}
> > 	...
> > }
> > 
> > So ret < 0 is handled, if there's any errors from merge_bio_hook(), it submits
> >  the current bio, so the way is sane to me.
> 
> Well, that's what I don't call 'handled'. 'ret < 0' will get to the 'if'
> but the question is whether the code really expects to see < 0 there and
> if it does the right thing then.

OK.

> 
> > The other consumer of merge_bio is submit_extent_page(), where it's OK
> > to return errors and callers are ready to handle them.
> 
> Same argument.
> 
> 'if (... || merge_bio() || ...)'
> 
> returns 1 "we can merge, continue with submit_bio" 

return 1 means "we _cannot_ merge" ;-)

> returns <0 "there was an error, we cannot continue" ... yet will still
> try to do submit_bio.
> 
> > > It's IMO better to push up the BUG_ON error handling only one caller at
> > > a time. That way it's easier to review the callgraph and call paths.
> > 
> > merge_bio() is a wrapper for tree->ops->merge_bio_hook(), which is the
> > same thing with btrfs_merge_bio_hook().  It makes no sense if we just
> > look at BUG_ON in btrfs_merge_bio_hook but keep BUG_ON() in merge_bio().
> 
> So, looking at the code again: the BUG_ON in btrfs_merge_bio_hook can be
> replaced by return ret (no warning needed IMO).

OK.

> 
> If merge_bio gets rid of the BUG_ON, the calles must explicitly handle
> 'ret < 0' unless it's provably not a problem.

If merge_bio() returns < 0, then it must be __btrfs_map_block() returns < 0,
so even if we continue with submiting this bio, it'd fail at
__btrfs_map_block() again because merge_bio and submit_bio are using the
same bio.  Because of that we don't bother to submit it, instead we can
just return in case of (ret < 0), this applies to both
submit_extent_page() and btrfs_submit_compressed_read/write().

What do you think?

Thanks,

-liubo

  reply	other threads:[~2016-05-17 17:29 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-14  0:06 [PATCH 1/7] Btrfs: replace BUG() with WARN_ONCE in raid56 Liu Bo
2016-05-14  0:06 ` [PATCH 2/7] Btrfs: replace BUG_ON with WARN_ONCE in cow_file_range Liu Bo
2016-05-14  0:06 ` [PATCH 3/7] Btrfs: check if extent buffer is aligned to sectorsize Liu Bo
2016-05-14 10:30   ` Qu Wenruo
2016-05-16 18:01     ` Liu Bo
2016-05-17  9:39       ` David Sterba
2016-05-17 17:38         ` Liu Bo
2016-05-14  0:06 ` [PATCH 4/7] Btrfs: free sys_array eb as soon as possible Liu Bo
2016-05-16  8:45   ` David Sterba
2016-05-14  0:07 ` [PATCH 5/7] Btrfs: replace BUG_ON with WARN in merge_bio Liu Bo
2016-05-16  8:44   ` David Sterba
2016-05-16 17:24     ` Liu Bo
2016-05-17  9:55       ` David Sterba
2016-05-17 17:30         ` Liu Bo [this message]
2016-05-18 13:54           ` David Sterba
2016-05-14  0:07 ` [PATCH 6/7] Btrfs: fix eb memory leak due to readpage failure Liu Bo
2016-05-18 19:38   ` Josef Bacik
2016-05-14  0:07 ` [PATCH 7/7] Btrfs: fix memory leak due to invalid btree height Liu Bo
2016-09-06 16:50   ` David Sterba
2016-09-06 22:04     ` Liu Bo
2016-05-14 10:42 ` [PATCH 1/7] Btrfs: replace BUG() with WARN_ONCE in raid56 Qu Wenruo
2016-05-15 14:19 ` Holger Hoffstätte
2016-05-16  8:32   ` David Sterba
2016-10-12 15:06     ` David Sterba
2016-10-12 19:14       ` Liu Bo
2016-06-30  0:57 ` [PATCH v2] Btrfs: remove BUG() " Liu Bo
2016-07-26 16:58   ` David Sterba
2016-07-27  5:11     ` Liu Bo
2016-07-27 18:56   ` [PATCH v3] " Liu Bo
2016-07-29 16:53     ` David Sterba
2016-07-29 17:57     ` [PATCH v4] " Liu Bo
2016-08-24 12:11       ` David Sterba

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=20160517173047.GA8522@localhost.localdomain \
    --to=bo.li.liu@oracle.com \
    --cc=dsterba@suse.cz \
    --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 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.