All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dongsu Park <dongsu.park@profitbricks.com>
To: Ming Lin <mlin@minggr.net>
Cc: Kent Overstreet <kmo@daterainc.com>,
	linux-fsdevel@vger.kernel.org,
	lkml <linux-kernel@vger.kernel.org>, Jens Axboe <axboe@kernel.dk>,
	Christoph Hellwig <hch@infradead.org>
Subject: Re: Block layer projects that I haven't had time for
Date: Fri, 12 Dec 2014 13:40:08 +0100	[thread overview]
Message-ID: <20141212124008.GA3365@gmail.com> (raw)
In-Reply-To: <548A8BFF.9020801@minggr.net>

On 11.12.2014 22:32, Ming Lin wrote:
> On 12/11/2014 02:07 AM, Dongsu Park wrote:
> > On 10.12.2014 23:11, Ming Lin wrote:
> >> Just tried to edit a btrfs file.
> >>
> >> [   45.216351] BTRFS error (device sdb1): partial page write in btrfs with
> >> offset 0 and length 8192
> >> [   45.217522] BTRFS critical (device sdb1): bad ordered accounting left 0
> >> size 4096
> > 
> > @ming: I guess you managed to see this error as you're testing with a
> > SCSI device, not virtio-blk device like me.
> > Are you seeing it without any back traces?
> > Does the attached patch fix your issue?
> > (This is already included in the branch block-mpage-bvecs-for-next.)
> 
> How about below fix?
> "bvec.bv_len != PAGE_CACHE_SIZE" should be not valid any more, because now bio
> handles arbitrary size, right?

Thanks for figuring it out. :-)
I applied the change not only in _writepage(), but also in _readpage(),
also with some minor changes. See the attached patch.

I've just tested it under btrfs on a SCSI device via scsi_debug.
No such errors any more. Hope it works also for you.
Probably there will be a lot of places where a single page is assumed.

Cheers,
Dongsu

----
>From db3abe857f8c0f722c5ade450389e78e79ee7d17 Mon Sep 17 00:00:00 2001
From: Ming Lin <mlin@minggr.net>
Date: Thu, 11 Dec 2014 22:32:31 -0800
Subject: [PATCH] btrfs: allow read-/writing an extent to handle arbitrarily
 sized bios

Fix bugs in end_bio_extent_{read,write}page(), upon reading or writing
biovec that has length of multiple pages. The condition "bvec.bv_len
!= PAGE_CACHE_SIZE" would not be always valid any more, because now
biovec is able to handle arbitrary size of bio. Without this patch,
read/write IO stalls with the following log:

  BTRFS error (device sdb1): partial page write in btrfs with offset 0 and length 8192
  BTRFS critical (device sdb1): bad ordered accounting left 0 size 4096

Signed-off-by: Ming Lin <mlin@minggr.net>
Signed-off-by: Dongsu Park <dongsu.park@profitbricks.com>
---
 fs/btrfs/extent_io.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 2ac08e2..790a83b 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2468,7 +2468,7 @@ static void end_bio_extent_writepage(struct bio *bio, int err)
 		 * advance bv_offset and adjust bv_len to compensate.
 		 * Print a warning for nonzero offsets, and an error
 		 * if they don't add up to a full page.  */
-		if (bvec.bv_offset || bvec.bv_len != PAGE_CACHE_SIZE) {
+		if (bvec.bv_offset) {
 			if (bvec.bv_offset + bvec.bv_len != PAGE_CACHE_SIZE)
 				btrfs_err(BTRFS_I(page->mapping->host)->root->fs_info,
 				   "partial page write in btrfs with offset %u and length %u",
@@ -2481,7 +2481,8 @@ static void end_bio_extent_writepage(struct bio *bio, int err)
 		}
 
 		start = page_offset(page);
-		end = start + bvec.bv_offset + bvec.bv_len - 1;
+		end = start + bvec.bv_offset
+			+ min_t(unsigned int, bvec.bv_len, PAGE_CACHE_SIZE) - 1;
 
 		if (end_extent_writepage(page, err, start, end))
 			continue;
@@ -2548,7 +2549,7 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
 		 * advance bv_offset and adjust bv_len to compensate.
 		 * Print a warning for nonzero offsets, and an error
 		 * if they don't add up to a full page.  */
-		if (bvec.bv_offset || bvec.bv_len != PAGE_CACHE_SIZE) {
+		if (bvec.bv_offset) {
 			if (bvec.bv_offset + bvec.bv_len != PAGE_CACHE_SIZE)
 				btrfs_err(BTRFS_I(page->mapping->host)->root->fs_info,
 				   "partial page read in btrfs with offset %u and length %u",
@@ -2561,7 +2562,8 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
 		}
 
 		start = page_offset(page);
-		end = start + bvec.bv_offset + bvec.bv_len - 1;
+		end = start + bvec.bv_offset
+			+ min_t(unsigned int, bvec.bv_len, PAGE_CACHE_SIZE) - 1;
 		len = bvec.bv_len;
 
 		mirror = io_bio->mirror_num;
-- 
2.1.0


  reply	other threads:[~2014-12-12 12:40 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-24  4:16 Block layer projects that I haven't had time for Kent Overstreet
2014-12-04 11:00 ` Dongsu Park
2014-12-06  3:02   ` Kent Overstreet
2014-12-08 11:48     ` Dongsu Park
2014-12-10 22:42       ` Ming Lin
2014-12-10 22:57         ` Kent Overstreet
2014-12-10 23:11           ` Ming Lin
2014-12-11 10:07             ` Dongsu Park
2014-12-11 10:14               ` Kent Overstreet
2014-12-11 19:16               ` Ming Lin
2014-12-12  6:32               ` Ming Lin
2014-12-12 12:40                 ` Dongsu Park [this message]
2014-12-10 22:49       ` Kent Overstreet
2014-12-11 10:21         ` Dongsu Park

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=20141212124008.GA3365@gmail.com \
    --to=dongsu.park@profitbricks.com \
    --cc=axboe@kernel.dk \
    --cc=hch@infradead.org \
    --cc=kmo@daterainc.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mlin@minggr.net \
    /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.