All of lore.kernel.org
 help / color / mirror / Atom feed
From: NeilBrown <neilb@suse.de>
To: Jens Axboe <jens.axboe@oracle.com>
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH 003 of 4] Don't decrement bi_size in bio_endio.
Date: Thu, 27 Sep 2007 17:20:18 +1000	[thread overview]
Message-ID: <1070927072018.4205@suse.de> (raw)
In-Reply-To: 20070927171111.3251.patches@notabene


The only caller of bio_endio that does not pass the full bi_size
is end_that_request_first.  Also, no ->bi_end_io method is really
interested in bi_size being decremented.

So move the decrement and related code into ll_rw_blk and merge it
with order_bio_endio to form req_bio_endio which does endio functionality
specific to request completion.

As some ->bi_end_io methods do check bi_size of 0, we set it thus for
now, but that will go in the next patch.

Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./block/ll_rw_blk.c |   42 +++++++++++++++++++++++++++---------------
 ./fs/bio.c          |   23 +++++++++++------------
 2 files changed, 38 insertions(+), 27 deletions(-)

diff .prev/block/ll_rw_blk.c ./block/ll_rw_blk.c
--- .prev/block/ll_rw_blk.c	2007-09-27 16:42:31.000000000 +1000
+++ ./block/ll_rw_blk.c	2007-09-27 16:42:50.000000000 +1000
@@ -524,22 +524,36 @@ int blk_do_ordered(struct request_queue 
 	return 1;
 }
 
-static int ordered_bio_endio(struct request *rq, struct bio *bio,
-			     unsigned int nbytes, int error)
+static void req_bio_endio(struct request *rq, struct bio *bio,
+			  unsigned int nbytes, int error)
 {
 	struct request_queue *q = rq->q;
 
-	if (&q->bar_rq != rq)
-		return 0;
+	if (&q->bar_rq != rq) {
+		if (error)
+			clear_bit(BIO_UPTODATE, &bio->bi_flags);
+		else if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
+			error = -EIO;
+
+		if (unlikely(nbytes > bio->bi_size)) {
+			printk("%s: want %u bytes done, only %u left\n",
+			       __FUNCTION__, nbytes, bio->bi_size);
+			nbytes = bio->bi_size;
+		}
 
-	/*
-	 * Okay, this is the barrier request in progress, just
-	 * record the error;
-	 */
-	if (error && !q->orderr)
-		q->orderr = error;
+		bio->bi_size -= nbytes;
+		bio->bi_sector += (nbytes >> 9);
+		if (bio->bi_size == 0)
+			bio_endio(bio, bio->bi_size, error);
+	} else {
 
-	return 1;
+		/*
+		 * Okay, this is the barrier request in progress, just
+		 * record the error;
+		 */
+		if (error && !q->orderr)
+			q->orderr = error;
+	}
 }
 
 /**
@@ -3407,8 +3421,7 @@ static int __end_that_request_first(stru
 		if (nr_bytes >= bio->bi_size) {
 			req->bio = bio->bi_next;
 			nbytes = bio->bi_size;
-			if (!ordered_bio_endio(req, bio, nbytes, error))
-				bio_endio(bio, nbytes, error);
+			req_bio_endio(req, bio, nbytes, error);
 			next_idx = 0;
 			bio_nbytes = 0;
 		} else {
@@ -3463,8 +3476,7 @@ static int __end_that_request_first(stru
 	 * if the request wasn't completed, update state
 	 */
 	if (bio_nbytes) {
-		if (!ordered_bio_endio(req, bio, bio_nbytes, error))
-			bio_endio(bio, bio_nbytes, error);
+		req_bio_endio(req, bio, bio_nbytes, error);
 		bio->bi_idx += next_idx;
 		bio_iovec(bio)->bv_offset += nr_bytes;
 		bio_iovec(bio)->bv_len -= nr_bytes;

diff .prev/fs/bio.c ./fs/bio.c
--- .prev/fs/bio.c	2007-09-27 16:39:02.000000000 +1000
+++ ./fs/bio.c	2007-09-27 16:42:50.000000000 +1000
@@ -1006,13 +1006,14 @@ void bio_check_pages_dirty(struct bio *b
  * @error:	error, if any
  *
  * Description:
- *   bio_endio() will end I/O on @bytes_done number of bytes. This may be
- *   just a partial part of the bio, or it may be the whole bio. bio_endio()
- *   is the preferred way to end I/O on a bio, it takes care of decrementing
- *   bi_size and clearing BIO_UPTODATE on error. @error is 0 on success, and
- *   and one of the established -Exxxx (-EIO, for instance) error values in
- *   case something went wrong. Noone should call bi_end_io() directly on
- *   a bio unless they own it and thus know that it has an end_io function.
+ *   bio_endio() will end I/O on @bytes_done number of bytes. This
+ *   must always be the whole (remaining) bio. bio_endio() is the
+ *   preferred way to end I/O on a bio, it takes care of clearing
+ *   BIO_UPTODATE on error. @error is 0 on success, and and one of the
+ *   established -Exxxx (-EIO, for instance) error values in case
+ *   something went wrong. Noone should call bi_end_io() directly on a
+ *   bio unless they own it and thus know that it has an end_io
+ *   function.
  **/
 void bio_endio(struct bio *bio, unsigned int bytes_done, int error)
 {
@@ -1021,16 +1022,14 @@ void bio_endio(struct bio *bio, unsigned
 	else if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
 		error = -EIO;
 
-	if (unlikely(bytes_done > bio->bi_size)) {
+	if (unlikely(bytes_done != bio->bi_size)) {
 		printk("%s: want %u bytes done, only %u left\n", __FUNCTION__,
 						bytes_done, bio->bi_size);
 		bytes_done = bio->bi_size;
 	}
 
-	bio->bi_size -= bytes_done;
-	bio->bi_sector += (bytes_done >> 9);
-
-	if (bio->bi_size && bio->bi_end_io)
+	bio->bi_size = 0; /* expected by some callees - will be removed */
+	if (bio->bi_end_io)
 		bio->bi_end_io(bio, bytes_done, error);
 }
 

  parent reply	other threads:[~2007-09-27  7:21 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-09-27  7:20 [PATCH 000 of 4] Change prototype for bi_end_io NeilBrown
2007-09-27  7:20 ` [PATCH 001 of 4] Remove flush_dry_bio_endio NeilBrown
2007-09-27  7:20 ` [PATCH 002 of 4] Only call bi_end_io once for any bio NeilBrown
2007-09-27  7:20 ` NeilBrown [this message]
2007-09-27  7:20 ` [PATCH 004 of 4] Drop 'size' argument from bio_endio and bi_end_io NeilBrown
2007-09-27 11:13 ` [PATCH 000 of 4] Change prototype for bi_end_io Jens Axboe

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=1070927072018.4205@suse.de \
    --to=neilb@suse.de \
    --cc=jens.axboe@oracle.com \
    --cc=linux-kernel@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.