All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alex Elder <elder@inktank.com>
To: ceph-devel@vger.kernel.org
Subject: [PATCH 3/4] rbd: simplify rbd_merge_bvec()
Date: Mon, 22 Oct 2012 11:51:43 -0500	[thread overview]
Message-ID: <5085799F.6090405@inktank.com> (raw)
In-Reply-To: <5085791C.9010205@inktank.com>

The aim of this patch is to make what's going on rbd_merge_bvec() a
bit more obvious than it was before.  This was an issue when a
recent btrfs bug led us to question whether the merge function was
working correctly.

Use "seg" rather than "chunk" to indicate the units whose boundaries
we care about we call "segments."

Signed-off-by: Alex Elder <elder@inktank.com>
---
 drivers/block/rbd.c |   51
+++++++++++++++++++++++++++++++++++----------------
 1 file changed, 35 insertions(+), 16 deletions(-)

diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 4858d92..4ccce4d 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -1566,22 +1566,41 @@ static int rbd_merge_bvec(struct request_queue
*q, struct bvec_merge_data *bmd,
 			  struct bio_vec *bvec)
 {
 	struct rbd_device *rbd_dev = q->queuedata;
-	unsigned int chunk_sectors;
-	sector_t sector;
-	unsigned int bio_sectors;
-	int max;
-
-	chunk_sectors = 1 << (rbd_dev->header.obj_order - SECTOR_SHIFT);
-	sector = bmd->bi_sector + get_start_sect(bmd->bi_bdev);
-	bio_sectors = bmd->bi_size >> SECTOR_SHIFT;
-
-	max =  (chunk_sectors - ((sector & (chunk_sectors - 1))
-				 + bio_sectors)) << SECTOR_SHIFT;
-	if (max < 0)
-		max = 0; /* bio_add cannot handle a negative return */
-	if (max <= bvec->bv_len && bio_sectors == 0)
-		return bvec->bv_len;
-	return max;
+	sector_t sector_offset;
+	sector_t sectors_per_seg;
+	sector_t seg_sector_offset;
+	int ret;
+
+	/*
+	 * Find how far into its rbd segment the partition-relative
+	 * bio start sector is to offset relative to the enclosing
+	 * device.
+	 */
+	sector_offset = get_start_sect(bmd->bi_bdev) + bmd->bi_sector;
+	sectors_per_seg = 1 << (rbd_dev->header.obj_order - SECTOR_SHIFT);
+	seg_sector_offset = sector_offset & (sectors_per_seg - 1);
+
+	/*
+	 * Compute the number of bytes from that offset to the end
+	 * of the segment.  Account for what's already used by the bio.
+	 */
+	ret = (int) (sectors_per_seg - seg_sector_offset) << SECTOR_SHIFT;
+	if (ret >= bmd->bi_size)
+		ret -= bmd->bi_size;
+	else
+		ret = 0;
+
+	/*
+	 * Don't send back more than was asked for.  And if the bio
+	 * was empty, let the whole thing through because:  "Note
+	 * that a block device *must* allow a single page to be
+	 * added to an empty bio."
+	 */
+	rbd_assert(bvec->bv_len <= PAGE_SIZE);
+	if (ret > (int) bvec->bv_len || !bmd->bi_size)
+		ret = (int) bvec->bv_len;
+
+	return ret;
 }

 static void rbd_free_disk(struct rbd_device *rbd_dev)
-- 
1.7.9.5


  parent reply	other threads:[~2012-10-22 16:51 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-10-22 16:49 [PATCH 0/4] rbd: four minor changes Alex Elder
2012-10-22 16:51 ` [PATCH 1/4] rbd: verify rbd image order value Alex Elder
2012-10-22 22:43   ` Dan Mick
2012-10-24 18:02   ` Josh Durgin
2012-10-26 22:06     ` Alex Elder
2012-10-22 16:51 ` [PATCH 2/4] rbd: increase maximum snapshot name length Alex Elder
2012-10-24 19:01   ` Josh Durgin
2012-10-24 21:05   ` Dan Mick
2012-10-22 16:51 ` Alex Elder [this message]
2012-10-24 22:23   ` [PATCH 3/4] rbd: simplify rbd_merge_bvec() Dan Mick
2012-10-24 22:31     ` Josh Durgin
2012-10-22 16:51 ` [PATCH 4/4] rbd: kill rbd_device->rbd_opts Alex Elder
2012-10-24 22:30   ` Josh Durgin
2012-10-24 22:37   ` Dan Mick

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=5085799F.6090405@inktank.com \
    --to=elder@inktank.com \
    --cc=ceph-devel@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.