Skip to content

Commit 458b76e

Browse files
author
Kent Overstreet
committed
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: Kent Overstreet <[email protected]> Cc: Jens Axboe <[email protected]> Cc: Neil Brown <[email protected]> Cc: Nagalakshmi Nandigama <[email protected]> Cc: Sreekanth Reddy <[email protected]> Cc: "James E.J. Bottomley" <[email protected]>
1 parent d57a5f7 commit 458b76e

File tree

10 files changed

+94
-87
lines changed

10 files changed

+94
-87
lines changed

drivers/block/ps3disk.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,9 @@ static void ps3disk_scatter_gather(struct ps3_storage_device *dev,
101101

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

109108
size = bvec.bv_len;
110109
buf = bvec_kmap_irq(&bvec, &flags);

drivers/md/bcache/io.c

Lines changed: 23 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,16 @@ static void bch_generic_make_request_hack(struct bio *bio)
2424
if (bio->bi_iter.bi_idx) {
2525
struct bio_vec bv;
2626
struct bvec_iter iter;
27-
struct bio *clone = bio_alloc(GFP_NOIO, bio_segments(bio));
27+
unsigned segs = bio_segments(bio);
28+
struct bio *clone = bio_alloc(GFP_NOIO, segs);
2829

2930
bio_for_each_segment(bv, bio, iter)
3031
clone->bi_io_vec[clone->bi_vcnt++] = bv;
3132

3233
clone->bi_iter.bi_sector = bio->bi_iter.bi_sector;
3334
clone->bi_bdev = bio->bi_bdev;
3435
clone->bi_rw = bio->bi_rw;
35-
clone->bi_vcnt = bio_segments(bio);
36+
clone->bi_vcnt = segs;
3637
clone->bi_iter.bi_size = bio->bi_iter.bi_size;
3738

3839
clone->bi_private = bio;
@@ -133,40 +134,32 @@ struct bio *bch_bio_split(struct bio *bio, int sectors,
133134

134135
static unsigned bch_bio_max_sectors(struct bio *bio)
135136
{
136-
unsigned ret = bio_sectors(bio);
137137
struct request_queue *q = bdev_get_queue(bio->bi_bdev);
138-
unsigned max_segments = min_t(unsigned, BIO_MAX_PAGES,
139-
queue_max_segments(q));
138+
struct bio_vec bv;
139+
struct bvec_iter iter;
140+
unsigned ret = 0, seg = 0;
140141

141142
if (bio->bi_rw & REQ_DISCARD)
142-
return min(ret, q->limits.max_discard_sectors);
143-
144-
if (bio_segments(bio) > max_segments ||
145-
q->merge_bvec_fn) {
146-
struct bio_vec bv;
147-
struct bvec_iter iter;
148-
unsigned seg = 0;
149-
150-
ret = 0;
143+
return min(bio_sectors(bio), q->limits.max_discard_sectors);
151144

152-
bio_for_each_segment(bv, bio, iter) {
153-
struct bvec_merge_data bvm = {
154-
.bi_bdev = bio->bi_bdev,
155-
.bi_sector = bio->bi_iter.bi_sector,
156-
.bi_size = ret << 9,
157-
.bi_rw = bio->bi_rw,
158-
};
159-
160-
if (seg == max_segments)
161-
break;
145+
bio_for_each_segment(bv, bio, iter) {
146+
struct bvec_merge_data bvm = {
147+
.bi_bdev = bio->bi_bdev,
148+
.bi_sector = bio->bi_iter.bi_sector,
149+
.bi_size = ret << 9,
150+
.bi_rw = bio->bi_rw,
151+
};
152+
153+
if (seg == min_t(unsigned, BIO_MAX_PAGES,
154+
queue_max_segments(q)))
155+
break;
162156

163-
if (q->merge_bvec_fn &&
164-
q->merge_bvec_fn(q, &bvm, &bv) < (int) bv.bv_len)
165-
break;
157+
if (q->merge_bvec_fn &&
158+
q->merge_bvec_fn(q, &bvm, &bv) < (int) bv.bv_len)
159+
break;
166160

167-
seg++;
168-
ret += bv.bv_len >> 9;
169-
}
161+
seg++;
162+
ret += bv.bv_len >> 9;
170163
}
171164

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

drivers/md/raid0.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ static void raid0_make_request(struct mddev *mddev, struct bio *bio)
528528
sector_t sector = bio->bi_iter.bi_sector;
529529
struct bio_pair *bp;
530530
/* Sanity check -- queue functions should prevent this happening */
531-
if (bio_segments(bio) > 1)
531+
if (bio_multiple_segments(bio))
532532
goto bad_map;
533533
/* This is a one page bio that upper layers
534534
* refuse to split for us, so we need to split it.

drivers/md/raid10.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1188,7 +1188,7 @@ static void make_request(struct mddev *mddev, struct bio * bio)
11881188
|| conf->prev.near_copies < conf->prev.raid_disks))) {
11891189
struct bio_pair *bp;
11901190
/* Sanity check -- queue functions should prevent this happening */
1191-
if (bio_segments(bio) > 1)
1191+
if (bio_multiple_segments(bio))
11921192
goto bad_map;
11931193
/* This is a one page bio that upper layers
11941194
* refuse to split for us, so we need to split it.

drivers/message/fusion/mptsas.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2235,10 +2235,10 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
22352235
}
22362236

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

drivers/scsi/libsas/sas_expander.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2163,10 +2163,10 @@ int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
21632163
}
21642164

21652165
/* do we need to support multiple segments? */
2166-
if (bio_segments(req->bio) > 1 || bio_segments(rsp->bio) > 1) {
2167-
printk("%s: multiple segments req %u %u, rsp %u %u\n",
2168-
__func__, bio_segments(req->bio), blk_rq_bytes(req),
2169-
bio_segments(rsp->bio), blk_rq_bytes(rsp));
2166+
if (bio_multiple_segments(req->bio) ||
2167+
bio_multiple_segments(rsp->bio)) {
2168+
printk("%s: multiple segments req %u, rsp %u\n",
2169+
__func__, blk_rq_bytes(req), blk_rq_bytes(rsp));
21702170
return -EINVAL;
21712171
}
21722172

drivers/scsi/mpt2sas/mpt2sas_transport.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1943,7 +1943,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
19431943
ioc->transport_cmds.status = MPT2_CMD_PENDING;
19441944

19451945
/* Check if the request is split across multiple segments */
1946-
if (bio_segments(req->bio) > 1) {
1946+
if (bio_multiple_segments(req->bio)) {
19471947
u32 offset = 0;
19481948

19491949
/* Allocate memory and copy the request */
@@ -1975,7 +1975,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
19751975

19761976
/* Check if the response needs to be populated across
19771977
* multiple segments */
1978-
if (bio_segments(rsp->bio) > 1) {
1978+
if (bio_multiple_segments(rsp->bio)) {
19791979
pci_addr_in = pci_alloc_consistent(ioc->pdev, blk_rq_bytes(rsp),
19801980
&pci_dma_in);
19811981
if (!pci_addr_in) {
@@ -2042,7 +2042,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
20422042
sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
20432043
MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
20442044
sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
2045-
if (bio_segments(req->bio) > 1) {
2045+
if (bio_multiple_segments(req->bio)) {
20462046
ioc->base_add_sg_single(psge, sgl_flags |
20472047
(blk_rq_bytes(req) - 4), pci_dma_out);
20482048
} else {
@@ -2058,7 +2058,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
20582058
MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
20592059
MPI2_SGE_FLAGS_END_OF_LIST);
20602060
sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
2061-
if (bio_segments(rsp->bio) > 1) {
2061+
if (bio_multiple_segments(rsp->bio)) {
20622062
ioc->base_add_sg_single(psge, sgl_flags |
20632063
(blk_rq_bytes(rsp) + 4), pci_dma_in);
20642064
} else {
@@ -2103,7 +2103,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
21032103
le16_to_cpu(mpi_reply->ResponseDataLength);
21042104
/* check if the resp needs to be copied from the allocated
21052105
* pci mem */
2106-
if (bio_segments(rsp->bio) > 1) {
2106+
if (bio_multiple_segments(rsp->bio)) {
21072107
u32 offset = 0;
21082108
u32 bytes_to_copy =
21092109
le16_to_cpu(mpi_reply->ResponseDataLength);

drivers/scsi/mpt3sas/mpt3sas_transport.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,7 +1926,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
19261926
ioc->transport_cmds.status = MPT3_CMD_PENDING;
19271927

19281928
/* Check if the request is split across multiple segments */
1929-
if (req->bio->bi_vcnt > 1) {
1929+
if (bio_multiple_segments(req->bio)) {
19301930
u32 offset = 0;
19311931

19321932
/* Allocate memory and copy the request */
@@ -1958,7 +1958,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
19581958

19591959
/* Check if the response needs to be populated across
19601960
* multiple segments */
1961-
if (rsp->bio->bi_vcnt > 1) {
1961+
if (bio_multiple_segments(rsp->bio)) {
19621962
pci_addr_in = pci_alloc_consistent(ioc->pdev, blk_rq_bytes(rsp),
19631963
&pci_dma_in);
19641964
if (!pci_addr_in) {
@@ -2019,7 +2019,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
20192019
mpi_request->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4);
20202020
psge = &mpi_request->SGL;
20212021

2022-
if (req->bio->bi_vcnt > 1)
2022+
if (bio_multiple_segments(req->bio))
20232023
ioc->build_sg(ioc, psge, pci_dma_out, (blk_rq_bytes(req) - 4),
20242024
pci_dma_in, (blk_rq_bytes(rsp) + 4));
20252025
else
@@ -2064,7 +2064,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
20642064

20652065
/* check if the resp needs to be copied from the allocated
20662066
* pci mem */
2067-
if (rsp->bio->bi_vcnt > 1) {
2067+
if (bio_multiple_segments(rsp->bio)) {
20682068
u32 offset = 0;
20692069
u32 bytes_to_copy =
20702070
le16_to_cpu(mpi_reply->ResponseDataLength);

fs/bio.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1733,7 +1733,7 @@ struct bio_pair *bio_split(struct bio *bi, int first_sectors)
17331733
trace_block_split(bdev_get_queue(bi->bi_bdev), bi,
17341734
bi->bi_iter.bi_sector + first_sectors);
17351735

1736-
BUG_ON(bio_segments(bi) > 1);
1736+
BUG_ON(bio_multiple_segments(bi));
17371737
atomic_set(&bp->cnt, 3);
17381738
bp->error = 0;
17391739
bp->bio1 = *bi;

include/linux/bio.h

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -97,21 +97,54 @@
9797
#define bio_offset(bio) bio_iter_offset((bio), (bio)->bi_iter)
9898
#define bio_iovec(bio) bio_iter_iovec((bio), (bio)->bi_iter)
9999

100-
#define bio_segments(bio) ((bio)->bi_vcnt - (bio)->bi_iter.bi_idx)
100+
#define bio_multiple_segments(bio) \
101+
((bio)->bi_iter.bi_size != bio_iovec(bio).bv_len)
101102
#define bio_sectors(bio) ((bio)->bi_iter.bi_size >> 9)
102103
#define bio_end_sector(bio) ((bio)->bi_iter.bi_sector + bio_sectors((bio)))
103104

105+
/*
106+
* Check whether this bio carries any data or not. A NULL bio is allowed.
107+
*/
108+
static inline bool bio_has_data(struct bio *bio)
109+
{
110+
if (bio &&
111+
bio->bi_iter.bi_size &&
112+
!(bio->bi_rw & REQ_DISCARD))
113+
return true;
114+
115+
return false;
116+
}
117+
118+
static inline bool bio_is_rw(struct bio *bio)
119+
{
120+
if (!bio_has_data(bio))
121+
return false;
122+
123+
if (bio->bi_rw & BIO_NO_ADVANCE_ITER_MASK)
124+
return false;
125+
126+
return true;
127+
}
128+
129+
static inline bool bio_mergeable(struct bio *bio)
130+
{
131+
if (bio->bi_rw & REQ_NOMERGE_FLAGS)
132+
return false;
133+
134+
return true;
135+
}
136+
104137
static inline unsigned int bio_cur_bytes(struct bio *bio)
105138
{
106-
if (bio->bi_vcnt)
139+
if (bio_has_data(bio))
107140
return bio_iovec(bio).bv_len;
108141
else /* dataless requests such as discard */
109142
return bio->bi_iter.bi_size;
110143
}
111144

112145
static inline void *bio_data(struct bio *bio)
113146
{
114-
if (bio->bi_vcnt)
147+
if (bio_has_data(bio))
115148
return page_address(bio_page(bio)) + bio_offset(bio);
116149

117150
return NULL;
@@ -221,6 +254,18 @@ static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter,
221254

222255
#define bio_iter_last(bvec, iter) ((iter).bi_size == (bvec).bv_len)
223256

257+
static inline unsigned bio_segments(struct bio *bio)
258+
{
259+
unsigned segs = 0;
260+
struct bio_vec bv;
261+
struct bvec_iter iter;
262+
263+
bio_for_each_segment(bv, bio, iter)
264+
segs++;
265+
266+
return segs;
267+
}
268+
224269
/*
225270
* get a reference to a bio, so it won't disappear. the intended use is
226271
* something like:
@@ -434,36 +479,6 @@ static inline char *__bio_kmap_irq(struct bio *bio, unsigned short idx,
434479
__bio_kmap_irq((bio), (bio)->bi_iter.bi_idx, (flags))
435480
#define bio_kunmap_irq(buf,flags) __bio_kunmap_irq(buf, flags)
436481

437-
/*
438-
* Check whether this bio carries any data or not. A NULL bio is allowed.
439-
*/
440-
static inline bool bio_has_data(struct bio *bio)
441-
{
442-
if (bio && bio->bi_vcnt)
443-
return true;
444-
445-
return false;
446-
}
447-
448-
static inline bool bio_is_rw(struct bio *bio)
449-
{
450-
if (!bio_has_data(bio))
451-
return false;
452-
453-
if (bio->bi_rw & REQ_WRITE_SAME)
454-
return false;
455-
456-
return true;
457-
}
458-
459-
static inline bool bio_mergeable(struct bio *bio)
460-
{
461-
if (bio->bi_rw & REQ_NOMERGE_FLAGS)
462-
return false;
463-
464-
return true;
465-
}
466-
467482
/*
468483
* BIO list management for use by remapping drivers (e.g. DM or MD) and loop.
469484
*

0 commit comments

Comments
 (0)