From: Kent Overstreet Date: Wed, 7 Aug 2013 21:31:11 +0000 (-0700) Subject: rbd: Refactor bio cloning X-Git-Tag: v3.14-rc1~43^2~27 X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=5341a6278bc5d10dbbb2ab6031b41d95c8db7a35;p=~emulex%2Finfiniband.git rbd: Refactor bio cloning Now that we've got drivers converted to the new immutable bvec primitives, bio splitting becomes much easier - this is how the new bio_split() will work. (Someone more familiar with the ceph code could probably use bio_clone_fast() instead of bio_clone() here). Signed-off-by: Kent Overstreet Cc: Jens Axboe Cc: Yehuda Sadeh Cc: Alex Elder Cc: ceph-devel@vger.kernel.org --- diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 20e8ab35736..3624368b910 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -1173,73 +1173,13 @@ static struct bio *bio_clone_range(struct bio *bio_src, unsigned int len, gfp_t gfpmask) { - struct bio_vec bv; - struct bvec_iter iter; - struct bvec_iter end_iter; - unsigned int resid; - unsigned int voff; - unsigned short vcnt; struct bio *bio; - /* Handle the easy case for the caller */ - - if (!offset && len == bio_src->bi_iter.bi_size) - return bio_clone(bio_src, gfpmask); - - if (WARN_ON_ONCE(!len)) - return NULL; - if (WARN_ON_ONCE(len > bio_src->bi_iter.bi_size)) - return NULL; - if (WARN_ON_ONCE(offset > bio_src->bi_iter.bi_size - len)) - return NULL; - - /* Find first affected segment... */ - - resid = offset; - bio_for_each_segment(bv, bio_src, iter) { - if (resid < bv.bv_len) - break; - resid -= bv.bv_len; - } - voff = resid; - - /* ...and the last affected segment */ - - resid += len; - __bio_for_each_segment(bv, bio_src, end_iter, iter) { - if (resid <= bv.bv_len) - break; - resid -= bv.bv_len; - } - vcnt = end_iter.bi_idx = iter.bi_idx + 1; - - /* Build the clone */ - - bio = bio_alloc(gfpmask, (unsigned int) vcnt); + bio = bio_clone(bio_src, gfpmask); if (!bio) return NULL; /* ENOMEM */ - bio->bi_bdev = bio_src->bi_bdev; - bio->bi_iter.bi_sector = bio_src->bi_iter.bi_sector + - (offset >> SECTOR_SHIFT); - bio->bi_rw = bio_src->bi_rw; - bio->bi_flags |= 1 << BIO_CLONED; - - /* - * Copy over our part of the bio_vec, then update the first - * and last (or only) entries. - */ - memcpy(&bio->bi_io_vec[0], &bio_src->bi_io_vec[iter.bi_idx], - vcnt * sizeof (struct bio_vec)); - bio->bi_io_vec[0].bv_offset += voff; - if (vcnt > 1) { - bio->bi_io_vec[0].bv_len -= voff; - bio->bi_io_vec[vcnt - 1].bv_len = resid; - } else { - bio->bi_io_vec[0].bv_len = len; - } - - bio->bi_vcnt = vcnt; + bio_advance(bio, offset); bio->bi_iter.bi_size = len; return bio;