Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 458b76ed authored by Kent Overstreet's avatar Kent Overstreet
Browse files

block: Kill bio_segments()/bi_vcnt usage



When we start sharing biovecs, keeping bi_vcnt accurate for splits is
going to be error prone - and unnecessary, if we refactor some code.

So bio_segments() has to go - but most of the existing users just needed
to know if the bio had multiple segments, which is easier - add a
bio_multiple_segments() for them.

(Two of the current uses of bio_segments() are going to go away in a
couple patches, but the current implementation of bio_segments() is
unsafe as soon as we start doing driver conversions for immutable
biovecs - so implement a dumb version for bisectability, it'll go away
in a couple patches)

Signed-off-by: default avatarKent Overstreet <kmo@daterainc.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Neil Brown <neilb@suse.de>
Cc: Nagalakshmi Nandigama <Nagalakshmi.Nandigama@lsi.com>
Cc: Sreekanth Reddy <Sreekanth.Reddy@lsi.com>
Cc: "James E.J. Bottomley" <JBottomley@parallels.com>
parent d57a5f7c
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -101,10 +101,9 @@ static void ps3disk_scatter_gather(struct ps3_storage_device *dev,

	rq_for_each_segment(bvec, req, iter) {
		unsigned long flags;
		dev_dbg(&dev->sbd.core,
			"%s:%u: bio %u: %u segs %u sectors from %lu\n",
			__func__, __LINE__, i, bio_segments(iter.bio),
			bio_sectors(iter.bio), iter.bio->bi_iter.bi_sector);
		dev_dbg(&dev->sbd.core, "%s:%u: bio %u: %u sectors from %lu\n",
			__func__, __LINE__, i, bio_sectors(iter.bio),
			iter.bio->bi_iter.bi_sector);

		size = bvec.bv_len;
		buf = bvec_kmap_irq(&bvec, &flags);
+23 −30
Original line number Diff line number Diff line
@@ -24,7 +24,8 @@ static void bch_generic_make_request_hack(struct bio *bio)
	if (bio->bi_iter.bi_idx) {
		struct bio_vec bv;
		struct bvec_iter iter;
		struct bio *clone = bio_alloc(GFP_NOIO, bio_segments(bio));
		unsigned segs = bio_segments(bio);
		struct bio *clone = bio_alloc(GFP_NOIO, segs);

		bio_for_each_segment(bv, bio, iter)
			clone->bi_io_vec[clone->bi_vcnt++] = bv;
@@ -32,7 +33,7 @@ static void bch_generic_make_request_hack(struct bio *bio)
		clone->bi_iter.bi_sector = bio->bi_iter.bi_sector;
		clone->bi_bdev		= bio->bi_bdev;
		clone->bi_rw		= bio->bi_rw;
		clone->bi_vcnt		= bio_segments(bio);
		clone->bi_vcnt		= segs;
		clone->bi_iter.bi_size	= bio->bi_iter.bi_size;

		clone->bi_private	= bio;
@@ -133,21 +134,13 @@ struct bio *bch_bio_split(struct bio *bio, int sectors,

static unsigned bch_bio_max_sectors(struct bio *bio)
{
	unsigned ret = bio_sectors(bio);
	struct request_queue *q = bdev_get_queue(bio->bi_bdev);
	unsigned max_segments = min_t(unsigned, BIO_MAX_PAGES,
				      queue_max_segments(q));

	if (bio->bi_rw & REQ_DISCARD)
		return min(ret, q->limits.max_discard_sectors);

	if (bio_segments(bio) > max_segments ||
	    q->merge_bvec_fn) {
	struct bio_vec bv;
	struct bvec_iter iter;
		unsigned seg = 0;
	unsigned ret = 0, seg = 0;

		ret = 0;
	if (bio->bi_rw & REQ_DISCARD)
		return min(bio_sectors(bio), q->limits.max_discard_sectors);

	bio_for_each_segment(bv, bio, iter) {
		struct bvec_merge_data bvm = {
@@ -157,7 +150,8 @@ static unsigned bch_bio_max_sectors(struct bio *bio)
			.bi_rw		= bio->bi_rw,
		};

			if (seg == max_segments)
		if (seg == min_t(unsigned, BIO_MAX_PAGES,
				 queue_max_segments(q)))
			break;

		if (q->merge_bvec_fn &&
@@ -167,7 +161,6 @@ static unsigned bch_bio_max_sectors(struct bio *bio)
		seg++;
		ret += bv.bv_len >> 9;
	}
	}

	ret = min(ret, queue_max_sectors(q));

+1 −1
Original line number Diff line number Diff line
@@ -528,7 +528,7 @@ static void raid0_make_request(struct mddev *mddev, struct bio *bio)
		sector_t sector = bio->bi_iter.bi_sector;
		struct bio_pair *bp;
		/* Sanity check -- queue functions should prevent this happening */
		if (bio_segments(bio) > 1)
		if (bio_multiple_segments(bio))
			goto bad_map;
		/* This is a one page bio that upper layers
		 * refuse to split for us, so we need to split it.
+1 −1
Original line number Diff line number Diff line
@@ -1188,7 +1188,7 @@ static void make_request(struct mddev *mddev, struct bio * bio)
			 || conf->prev.near_copies < conf->prev.raid_disks))) {
		struct bio_pair *bp;
		/* Sanity check -- queue functions should prevent this happening */
		if (bio_segments(bio) > 1)
		if (bio_multiple_segments(bio))
			goto bad_map;
		/* This is a one page bio that upper layers
		 * refuse to split for us, so we need to split it.
+4 −4
Original line number Diff line number Diff line
@@ -2235,10 +2235,10 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
	}

	/* do we need to support multiple segments? */
	if (bio_segments(req->bio) > 1 || bio_segments(rsp->bio) > 1) {
		printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n",
		    ioc->name, __func__, bio_segments(req->bio), blk_rq_bytes(req),
		    bio_segments(rsp->bio), blk_rq_bytes(rsp));
	if (bio_multiple_segments(req->bio) ||
	    bio_multiple_segments(rsp->bio)) {
		printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u, rsp %u\n",
		    ioc->name, __func__, blk_rq_bytes(req), blk_rq_bytes(rsp));
		return -EINVAL;
	}

Loading