Commit 5705f702 authored by NeilBrown's avatar NeilBrown Committed by Jens Axboe

Introduce rq_for_each_segment replacing rq_for_each_bio

Every usage of rq_for_each_bio wraps a usage of
bio_for_each_segment, so these can be combined into
rq_for_each_segment.

We define "struct req_iterator" to hold the 'bio' and 'index' that
are needed for the double iteration.
Signed-off-by: default avatarNeil Brown <neilb@suse.de>

Various compile fixes by me...
Signed-off-by: default avatarJens Axboe <jens.axboe@oracle.com>
parent 9dfa5283
...@@ -477,9 +477,9 @@ With this multipage bio design: ...@@ -477,9 +477,9 @@ With this multipage bio design:
the same bi_io_vec array, but with the index and size accordingly modified) the same bi_io_vec array, but with the index and size accordingly modified)
- A linked list of bios is used as before for unrelated merges (*) - this - A linked list of bios is used as before for unrelated merges (*) - this
avoids reallocs and makes independent completions easier to handle. avoids reallocs and makes independent completions easier to handle.
- Code that traverses the req list needs to make a distinction between - Code that traverses the req list can find all the segments of a bio
segments of a request (bio_for_each_segment) and the distinct completion by using rq_for_each_segment. This handles the fact that a request
units/bios (rq_for_each_bio). has multiple bios, each of which can have multiple segments.
- Drivers which can't process a large bio in one shot can use the bi_idx - Drivers which can't process a large bio in one shot can use the bi_idx
field to keep track of the next bio_vec entry to process. field to keep track of the next bio_vec entry to process.
(e.g a 1MB bio_vec needs to be handled in max 128kB chunks for IDE) (e.g a 1MB bio_vec needs to be handled in max 128kB chunks for IDE)
...@@ -664,13 +664,13 @@ in lvm or md. ...@@ -664,13 +664,13 @@ in lvm or md.
3.2.1 Traversing segments and completion units in a request 3.2.1 Traversing segments and completion units in a request
The macros bio_for_each_segment() and rq_for_each_bio() should be used for The macro rq_for_each_segment() should be used for traversing the bios
traversing the bios in the request list (drivers should avoid directly in the request list (drivers should avoid directly trying to do it
trying to do it themselves). Using these helpers should also make it easier themselves). Using these helpers should also make it easier to cope
to cope with block changes in the future. with block changes in the future.
rq_for_each_bio(bio, rq) struct req_iterator iter;
bio_for_each_segment(bio_vec, bio, i) rq_for_each_segment(bio_vec, rq, iter)
/* bio_vec is now current segment */ /* bio_vec is now current segment */
I/O completion callbacks are per-bio rather than per-segment, so drivers I/O completion callbacks are per-bio rather than per-segment, so drivers
......
...@@ -1244,8 +1244,7 @@ static void blk_recalc_rq_segments(struct request *rq) ...@@ -1244,8 +1244,7 @@ static void blk_recalc_rq_segments(struct request *rq)
int seg_size; int seg_size;
int hw_seg_size; int hw_seg_size;
int cluster; int cluster;
struct bio *bio; struct req_iterator iter;
int i;
int high, highprv = 1; int high, highprv = 1;
struct request_queue *q = rq->q; struct request_queue *q = rq->q;
...@@ -1255,8 +1254,7 @@ static void blk_recalc_rq_segments(struct request *rq) ...@@ -1255,8 +1254,7 @@ static void blk_recalc_rq_segments(struct request *rq)
cluster = q->queue_flags & (1 << QUEUE_FLAG_CLUSTER); cluster = q->queue_flags & (1 << QUEUE_FLAG_CLUSTER);
hw_seg_size = seg_size = 0; hw_seg_size = seg_size = 0;
phys_size = hw_size = nr_phys_segs = nr_hw_segs = 0; phys_size = hw_size = nr_phys_segs = nr_hw_segs = 0;
rq_for_each_bio(bio, rq) rq_for_each_segment(bv, rq, iter) {
bio_for_each_segment(bv, bio, i) {
/* /*
* the trick here is making sure that a high page is never * the trick here is making sure that a high page is never
* considered part of another segment, since that might * considered part of another segment, since that might
...@@ -1353,8 +1351,8 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq, ...@@ -1353,8 +1351,8 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
struct scatterlist *sg) struct scatterlist *sg)
{ {
struct bio_vec *bvec, *bvprv; struct bio_vec *bvec, *bvprv;
struct bio *bio; struct req_iterator iter;
int nsegs, i, cluster; int nsegs, cluster;
nsegs = 0; nsegs = 0;
cluster = q->queue_flags & (1 << QUEUE_FLAG_CLUSTER); cluster = q->queue_flags & (1 << QUEUE_FLAG_CLUSTER);
...@@ -1363,11 +1361,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq, ...@@ -1363,11 +1361,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
* for each bio in rq * for each bio in rq
*/ */
bvprv = NULL; bvprv = NULL;
rq_for_each_bio(bio, rq) { rq_for_each_segment(bvec, rq, iter) {
/*
* for each segment in bio
*/
bio_for_each_segment(bvec, bio, i) {
int nbytes = bvec->bv_len; int nbytes = bvec->bv_len;
if (bvprv && cluster) { if (bvprv && cluster) {
...@@ -1390,8 +1384,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq, ...@@ -1390,8 +1384,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
nsegs++; nsegs++;
} }
bvprv = bvec; bvprv = bvec;
} /* segments in bio */ } /* segments in rq */
} /* bios in rq */
return nsegs; return nsegs;
} }
......
...@@ -2437,23 +2437,20 @@ static void rw_interrupt(void) ...@@ -2437,23 +2437,20 @@ static void rw_interrupt(void)
/* Compute maximal contiguous buffer size. */ /* Compute maximal contiguous buffer size. */
static int buffer_chain_size(void) static int buffer_chain_size(void)
{ {
struct bio *bio;
struct bio_vec *bv; struct bio_vec *bv;
int size, i; int size;
struct req_iterator iter;
char *base; char *base;
base = bio_data(current_req->bio); base = bio_data(current_req->bio);
size = 0; size = 0;
rq_for_each_bio(bio, current_req) { rq_for_each_segment(bv, current_req, iter) {
bio_for_each_segment(bv, bio, i) { if (page_address(bv->bv_page) + bv->bv_offset != base + size)
if (page_address(bv->bv_page) + bv->bv_offset !=
base + size)
break; break;
size += bv->bv_len; size += bv->bv_len;
} }
}
return size >> 9; return size >> 9;
} }
...@@ -2479,9 +2476,9 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2) ...@@ -2479,9 +2476,9 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
{ {
int remaining; /* number of transferred 512-byte sectors */ int remaining; /* number of transferred 512-byte sectors */
struct bio_vec *bv; struct bio_vec *bv;
struct bio *bio;
char *buffer, *dma_buffer; char *buffer, *dma_buffer;
int size, i; int size;
struct req_iterator iter;
max_sector = transfer_size(ssize, max_sector = transfer_size(ssize,
min(max_sector, max_sector_2), min(max_sector, max_sector_2),
...@@ -2514,8 +2511,7 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2) ...@@ -2514,8 +2511,7 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
size = current_req->current_nr_sectors << 9; size = current_req->current_nr_sectors << 9;
rq_for_each_bio(bio, current_req) { rq_for_each_segment(bv, current_req, iter) {
bio_for_each_segment(bv, bio, i) {
if (!remaining) if (!remaining)
break; break;
...@@ -2551,7 +2547,6 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2) ...@@ -2551,7 +2547,6 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
remaining -= size; remaining -= size;
dma_buffer += size; dma_buffer += size;
} }
}
#ifdef FLOPPY_SANITY_CHECK #ifdef FLOPPY_SANITY_CHECK
if (remaining) { if (remaining) {
if (remaining > 0) if (remaining > 0)
......
...@@ -142,12 +142,11 @@ static irqreturn_t lgb_irq(int irq, void *_bd) ...@@ -142,12 +142,11 @@ static irqreturn_t lgb_irq(int irq, void *_bd)
* return the total length. */ * return the total length. */
static unsigned int req_to_dma(struct request *req, struct lguest_dma *dma) static unsigned int req_to_dma(struct request *req, struct lguest_dma *dma)
{ {
unsigned int i = 0, idx, len = 0; unsigned int i = 0, len = 0;
struct bio *bio; struct req_iterator iter;
rq_for_each_bio(bio, req) {
struct bio_vec *bvec; struct bio_vec *bvec;
bio_for_each_segment(bvec, bio, idx) {
rq_for_each_segment(bvec, req, iter) {
/* We told the block layer not to give us too many. */ /* We told the block layer not to give us too many. */
BUG_ON(i == LGUEST_MAX_DMA_SECTIONS); BUG_ON(i == LGUEST_MAX_DMA_SECTIONS);
/* If we had a zero-length segment, it would look like /* If we had a zero-length segment, it would look like
...@@ -161,7 +160,6 @@ static unsigned int req_to_dma(struct request *req, struct lguest_dma *dma) ...@@ -161,7 +160,6 @@ static unsigned int req_to_dma(struct request *req, struct lguest_dma *dma)
len += bvec->bv_len; len += bvec->bv_len;
i++; i++;
} }
}
/* If the array isn't full, we mark the end with a 0 length */ /* If the array isn't full, we mark the end with a 0 length */
if (i < LGUEST_MAX_DMA_SECTIONS) if (i < LGUEST_MAX_DMA_SECTIONS)
dma->len[i] = 0; dma->len[i] = 0;
......
...@@ -180,7 +180,7 @@ static inline int sock_send_bvec(struct socket *sock, struct bio_vec *bvec, ...@@ -180,7 +180,7 @@ static inline int sock_send_bvec(struct socket *sock, struct bio_vec *bvec,
static int nbd_send_req(struct nbd_device *lo, struct request *req) static int nbd_send_req(struct nbd_device *lo, struct request *req)
{ {
int result, i, flags; int result, flags;
struct nbd_request request; struct nbd_request request;
unsigned long size = req->nr_sectors << 9; unsigned long size = req->nr_sectors << 9;
struct socket *sock = lo->sock; struct socket *sock = lo->sock;
...@@ -205,16 +205,15 @@ static int nbd_send_req(struct nbd_device *lo, struct request *req) ...@@ -205,16 +205,15 @@ static int nbd_send_req(struct nbd_device *lo, struct request *req)
} }
if (nbd_cmd(req) == NBD_CMD_WRITE) { if (nbd_cmd(req) == NBD_CMD_WRITE) {
struct bio *bio; struct req_iterator iter;
struct bio_vec *bvec;
/* /*
* we are really probing at internals to determine * we are really probing at internals to determine
* whether to set MSG_MORE or not... * whether to set MSG_MORE or not...
*/ */
rq_for_each_bio(bio, req) { rq_for_each_segment(bvec, req, iter) {
struct bio_vec *bvec;
bio_for_each_segment(bvec, bio, i) {
flags = 0; flags = 0;
if ((i < (bio->bi_vcnt - 1)) || bio->bi_next) if (!rq_iter_last(req, iter))
flags = MSG_MORE; flags = MSG_MORE;
dprintk(DBG_TX, "%s: request %p: sending %d bytes data\n", dprintk(DBG_TX, "%s: request %p: sending %d bytes data\n",
lo->disk->disk_name, req, lo->disk->disk_name, req,
...@@ -228,7 +227,6 @@ static int nbd_send_req(struct nbd_device *lo, struct request *req) ...@@ -228,7 +227,6 @@ static int nbd_send_req(struct nbd_device *lo, struct request *req)
} }
} }
} }
}
return 0; return 0;
error_out: error_out:
...@@ -321,11 +319,10 @@ static struct request *nbd_read_stat(struct nbd_device *lo) ...@@ -321,11 +319,10 @@ static struct request *nbd_read_stat(struct nbd_device *lo)
dprintk(DBG_RX, "%s: request %p: got reply\n", dprintk(DBG_RX, "%s: request %p: got reply\n",
lo->disk->disk_name, req); lo->disk->disk_name, req);
if (nbd_cmd(req) == NBD_CMD_READ) { if (nbd_cmd(req) == NBD_CMD_READ) {
int i; struct req_iterator iter;
struct bio *bio;
rq_for_each_bio(bio, req) {
struct bio_vec *bvec; struct bio_vec *bvec;
bio_for_each_segment(bvec, bio, i) {
rq_for_each_segment(bvec, req, iter) {
result = sock_recv_bvec(sock, bvec); result = sock_recv_bvec(sock, bvec);
if (result <= 0) { if (result <= 0) {
printk(KERN_ERR "%s: Receive data failed (result %d)\n", printk(KERN_ERR "%s: Receive data failed (result %d)\n",
...@@ -338,7 +335,6 @@ static struct request *nbd_read_stat(struct nbd_device *lo) ...@@ -338,7 +335,6 @@ static struct request *nbd_read_stat(struct nbd_device *lo)
lo->disk->disk_name, req, bvec->bv_len); lo->disk->disk_name, req, bvec->bv_len);
} }
} }
}
return req; return req;
harderror: harderror:
lo->harderror = result; lo->harderror = result;
......
...@@ -91,30 +91,30 @@ static void ps3disk_scatter_gather(struct ps3_storage_device *dev, ...@@ -91,30 +91,30 @@ static void ps3disk_scatter_gather(struct ps3_storage_device *dev,
struct request *req, int gather) struct request *req, int gather)
{ {
unsigned int offset = 0; unsigned int offset = 0;
struct bio *bio; struct req_iterator iter;
sector_t sector;
struct bio_vec *bvec; struct bio_vec *bvec;
unsigned int i = 0, j; unsigned int i = 0;
size_t size; size_t size;
void *buf; void *buf;
rq_for_each_bio(bio, req) { rq_for_each_segment(bvec, req, iter) {
sector = bio->bi_sector; unsigned long flags;
dev_dbg(&dev->sbd.core, dev_dbg(&dev->sbd.core,
"%s:%u: bio %u: %u segs %u sectors from %lu\n", "%s:%u: bio %u: %u segs %u sectors from %lu\n",
__func__, __LINE__, i, bio_segments(bio), __func__, __LINE__, i, bio_segments(iter.bio),
bio_sectors(bio), sector); bio_sectors(iter.bio),
bio_for_each_segment(bvec, bio, j) { (unsigned long)iter.bio->bi_sector);
size = bvec->bv_len; size = bvec->bv_len;
buf = __bio_kmap_atomic(bio, j, KM_IRQ0); buf = bvec_kmap_irq(bvec, &flags);
if (gather) if (gather)
memcpy(dev->bounce_buf+offset, buf, size); memcpy(dev->bounce_buf+offset, buf, size);
else else
memcpy(buf, dev->bounce_buf+offset, size); memcpy(buf, dev->bounce_buf+offset, size);
offset += size; offset += size;
flush_kernel_dcache_page(bio_iovec_idx(bio, j)->bv_page); flush_kernel_dcache_page(bvec->bv_page);
__bio_kunmap_atomic(bio, KM_IRQ0); bvec_kunmap_irq(bvec, &flags);
}
i++; i++;
} }
} }
...@@ -130,12 +130,13 @@ static int ps3disk_submit_request_sg(struct ps3_storage_device *dev, ...@@ -130,12 +130,13 @@ static int ps3disk_submit_request_sg(struct ps3_storage_device *dev,
#ifdef DEBUG #ifdef DEBUG
unsigned int n = 0; unsigned int n = 0;
struct bio *bio; struct bio_vec *bv;
struct req_iterator iter;
rq_for_each_bio(bio, req) rq_for_each_segment(bv, req, iter)
n++; n++;
dev_dbg(&dev->sbd.core, dev_dbg(&dev->sbd.core,
"%s:%u: %s req has %u bios for %lu sectors %lu hard sectors\n", "%s:%u: %s req has %u bvecs for %lu sectors %lu hard sectors\n",
__func__, __LINE__, op, n, req->nr_sectors, __func__, __LINE__, op, n, req->nr_sectors,
req->hard_nr_sectors); req->hard_nr_sectors);
#endif #endif
......
...@@ -150,9 +150,8 @@ static int blkif_queue_request(struct request *req) ...@@ -150,9 +150,8 @@ static int blkif_queue_request(struct request *req)
struct blkfront_info *info = req->rq_disk->private_data; struct blkfront_info *info = req->rq_disk->private_data;
unsigned long buffer_mfn; unsigned long buffer_mfn;
struct blkif_request *ring_req; struct blkif_request *ring_req;
struct bio *bio; struct req_iterator iter;
struct bio_vec *bvec; struct bio_vec *bvec;
int idx;
unsigned long id; unsigned long id;
unsigned int fsect, lsect; unsigned int fsect, lsect;
int ref; int ref;
...@@ -186,8 +185,7 @@ static int blkif_queue_request(struct request *req) ...@@ -186,8 +185,7 @@ static int blkif_queue_request(struct request *req)
ring_req->operation = BLKIF_OP_WRITE_BARRIER; ring_req->operation = BLKIF_OP_WRITE_BARRIER;
ring_req->nr_segments = 0; ring_req->nr_segments = 0;
rq_for_each_bio (bio, req) { rq_for_each_segment(bvec, req, iter) {
bio_for_each_segment (bvec, bio, idx) {
BUG_ON(ring_req->nr_segments BUG_ON(ring_req->nr_segments
== BLKIF_MAX_SEGMENTS_PER_REQUEST); == BLKIF_MAX_SEGMENTS_PER_REQUEST);
buffer_mfn = pfn_to_mfn(page_to_pfn(bvec->bv_page)); buffer_mfn = pfn_to_mfn(page_to_pfn(bvec->bv_page));
...@@ -214,7 +212,6 @@ static int blkif_queue_request(struct request *req) ...@@ -214,7 +212,6 @@ static int blkif_queue_request(struct request *req)
ring_req->nr_segments++; ring_req->nr_segments++;
} }
}
info->ring.req_prod_pvt++; info->ring.req_prod_pvt++;
......
...@@ -606,13 +606,12 @@ static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, uns ...@@ -606,13 +606,12 @@ static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, uns
{ {
struct request *rq = pc->rq; struct request *rq = pc->rq;
struct bio_vec *bvec; struct bio_vec *bvec;
struct bio *bio; struct req_iterator iter;
unsigned long flags; unsigned long flags;
char *data; char *data;
int count, i, done = 0; int count, done = 0;
rq_for_each_bio(bio, rq) { rq_for_each_segment(bvec, rq, iter) {
bio_for_each_segment(bvec, bio, i) {
if (!bcount) if (!bcount)
break; break;
...@@ -626,7 +625,6 @@ static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, uns ...@@ -626,7 +625,6 @@ static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, uns
pc->b_count += count; pc->b_count += count;
done += count; done += count;
} }
}
idefloppy_do_end_request(drive, 1, done >> 9); idefloppy_do_end_request(drive, 1, done >> 9);
...@@ -639,14 +637,13 @@ static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, uns ...@@ -639,14 +637,13 @@ static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, uns
static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount) static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount)
{ {
struct request *rq = pc->rq; struct request *rq = pc->rq;
struct bio *bio; struct req_iterator iter;
struct bio_vec *bvec; struct bio_vec *bvec;
unsigned long flags; unsigned long flags;
int count, i, done = 0; int count, done = 0;
char *data; char *data;
rq_for_each_bio(bio, rq) { rq_for_each_segment(bvec, rq, iter) {
bio_for_each_segment(bvec, bio, i) {
if (!bcount) if (!bcount)
break; break;
...@@ -660,7 +657,6 @@ static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, un ...@@ -660,7 +657,6 @@ static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, un
pc->b_count += count; pc->b_count += count;
done += count; done += count;
} }
}
idefloppy_do_end_request(drive, 1, done >> 9); idefloppy_do_end_request(drive, 1, done >> 9);
......
...@@ -472,14 +472,13 @@ dasd_diag_build_cp(struct dasd_device * device, struct request *req) ...@@ -472,14 +472,13 @@ dasd_diag_build_cp(struct dasd_device * device, struct request *req)
struct dasd_ccw_req *cqr; struct dasd_ccw_req *cqr;
struct dasd_diag_req *dreq; struct dasd_diag_req *dreq;
struct dasd_diag_bio *dbio; struct dasd_diag_bio *dbio;
struct bio *bio; struct req_iterator iter;
struct bio_vec *bv; struct bio_vec *bv;
char *dst; char *dst;
unsigned int count, datasize; unsigned int count, datasize;
sector_t recid, first_rec, last_rec; sector_t recid, first_rec, last_rec;
unsigned int blksize, off; unsigned int blksize, off;
unsigned char rw_cmd; unsigned char rw_cmd;
int i;
if (rq_data_dir(req) == READ) if (rq_data_dir(req) == READ)
rw_cmd = MDSK_READ_REQ; rw_cmd = MDSK_READ_REQ;
...@@ -493,14 +492,12 @@ dasd_diag_build_cp(struct dasd_device * device, struct request *req) ...@@ -493,14 +492,12 @@ dasd_diag_build_cp(struct dasd_device * device, struct request *req)
last_rec = (req->sector + req->nr_sectors - 1) >> device->s2b_shift; last_rec = (req->sector + req->nr_sectors - 1) >> device->s2b_shift;
/* Check struct bio and count the number of blocks for the request. */ /* Check struct bio and count the number of blocks for the request. */
count = 0; count = 0;
rq_for_each_bio(bio, req) { rq_for_each_segment(bv, req, iter) {
bio_for_each_segment(bv, bio, i) {
if (bv->bv_len & (blksize - 1)) if (bv->bv_len & (blksize - 1))
/* Fba can only do full blocks. */ /* Fba can only do full blocks. */
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
count += bv->bv_len >> (device->s2b_shift + 9); count += bv->bv_len >> (device->s2b_shift + 9);
} }
}
/* Paranoia. */ /* Paranoia. */
if (count != last_rec - first_rec + 1) if (count != last_rec - first_rec + 1)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
...@@ -516,8 +513,7 @@ dasd_diag_build_cp(struct dasd_device * device, struct request *req) ...@@ -516,8 +513,7 @@ dasd_diag_build_cp(struct dasd_device * device, struct request *req)
dreq->block_count = count; dreq->block_count = count;
dbio = dreq->bio; dbio = dreq->bio;
recid = first_rec; recid = first_rec;
rq_for_each_bio(bio, req) { rq_for_each_segment(bv, req, iter) {
bio_for_each_segment(bv, bio, i) {
dst = page_address(bv->bv_page) + bv->bv_offset; dst = page_address(bv->bv_page) + bv->bv_offset;
for (off = 0; off < bv->bv_len; off += blksize) { for (off = 0; off < bv->bv_len; off += blksize) {
memset(dbio, 0, sizeof (struct dasd_diag_bio)); memset(dbio, 0, sizeof (struct dasd_diag_bio));
...@@ -529,7 +525,6 @@ dasd_diag_build_cp(struct dasd_device * device, struct request *req) ...@@ -529,7 +525,6 @@ dasd_diag_build_cp(struct dasd_device * device, struct request *req)
recid++; recid++;
} }
} }
}
cqr->retries = DIAG_MAX_RETRIES; cqr->retries = DIAG_MAX_RETRIES;
cqr->buildclk = get_clock(); cqr->buildclk = get_clock();
if (req->cmd_flags & REQ_FAILFAST) if (req->cmd_flags & REQ_FAILFAST)
......
...@@ -1176,7 +1176,7 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req) ...@@ -1176,7 +1176,7 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req)
struct LO_eckd_data *LO_data; struct LO_eckd_data *LO_data;
struct dasd_ccw_req *cqr; struct dasd_ccw_req *cqr;
struct ccw1 *ccw; struct ccw1 *ccw;
struct bio *bio; struct req_iterator iter;
struct bio_vec *bv; struct bio_vec *bv;
char *dst; char *dst;
unsigned int blksize, blk_per_trk, off; unsigned int blksize, blk_per_trk, off;
...@@ -1185,7 +1185,6 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req) ...@@ -1185,7 +1185,6 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req)
sector_t first_trk, last_trk; sector_t first_trk, last_trk;
unsigned int first_offs, last_offs; unsigned int first_offs, last_offs;
unsigned char cmd, rcmd; unsigned char cmd, rcmd;
int i;
private = (struct dasd_eckd_private *) device->private; private = (struct dasd_eckd_private *) device->private;
if (rq_data_dir(req) == READ) if (rq_data_dir(req) == READ)
...@@ -1206,8 +1205,7 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req) ...@@ -1206,8 +1205,7 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req)
/* Check struct bio and count the number of blocks for the request. */ /* Check struct bio and count the number of blocks for the request. */
count = 0; count = 0;
cidaw = 0; cidaw = 0;
rq_for_each_bio(bio, req) { rq_for_each_segment(bv, req, iter) {
bio_for_each_segment(bv, bio, i) {
if (bv->bv_len & (blksize - 1)) if (bv->bv_len & (blksize - 1))
/* Eckd can only do full blocks. */ /* Eckd can only do full blocks. */
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
...@@ -1218,7 +1216,6 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req) ...@@ -1218,7 +1216,6 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req)
cidaw += bv->bv_len >> (device->s2b_shift + 9); cidaw += bv->bv_len >> (device->s2b_shift + 9);
#endif #endif
} }
}
/* Paranoia. */ /* Paranoia. */
if (count != last_rec - first_rec + 1) if (count != last_rec - first_rec + 1)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
...@@ -1257,7 +1254,7 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req) ...@@ -1257,7 +1254,7 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req)
locate_record(ccw++, LO_data++, first_trk, first_offs + 1, locate_record(ccw++, LO_data++, first_trk, first_offs + 1,
last_rec - recid + 1, cmd, device, blksize); last_rec - recid + 1, cmd, device, blksize);
} }
rq_for_each_bio(bio, req) bio_for_each_segment(bv, bio, i) { rq_for_each_segment(bv, req, iter) {
dst = page_address(bv->bv_page) + bv->bv_offset; dst = page_address(bv->bv_page) + bv->bv_offset;
if (dasd_page_cache) { if (dasd_page_cache) {
char *copy = kmem_cache_alloc(dasd_page_cache, char *copy = kmem_cache_alloc(dasd_page_cache,
...@@ -1328,12 +1325,12 @@ dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req) ...@@ -1328,12 +1325,12 @@ dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req)
{ {
struct dasd_eckd_private *private; struct dasd_eckd_private *private;
struct ccw1 *ccw; struct ccw1 *ccw;
struct bio *bio; struct req_iterator iter;
struct bio_vec *bv; struct bio_vec *bv;
char *dst, *cda; char *dst, *cda;
unsigned int blksize, blk_per_trk, off; unsigned int blksize, blk_per_trk, off;
sector_t recid; sector_t recid;
int i, status; int status;
if (!dasd_page_cache) if (!dasd_page_cache)
goto out; goto out;
...@@ -1346,7 +1343,7 @@ dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req) ...@@ -1346,7 +1343,7 @@ dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req)
ccw++; ccw++;
if (private->uses_cdl == 0 || recid > 2*blk_per_trk) if (private->uses_cdl == 0 || recid > 2*blk_per_trk)
ccw++; ccw++;
rq_for_each_bio(bio, req) bio_for_each_segment(bv, bio, i) { rq_for_each_segment(bv, req, iter) {
dst = page_address(bv->bv_page) + bv->bv_offset; dst = page_address(bv->bv_page) + bv->bv_offset;
for (off = 0; off < bv->bv_len; off += blksize) { for (off = 0; off < bv->bv_len; off += blksize) {
/* Skip locate record. */ /* Skip locate record. */
......
...@@ -234,14 +234,13 @@ dasd_fba_build_cp(struct dasd_device * device, struct request *req) ...@@ -234,14 +234,13 @@ dasd_fba_build_cp(struct dasd_device * device, struct request *req)
struct LO_fba_data *LO_data; struct LO_fba_data *LO_data;
struct dasd_ccw_req *cqr; struct dasd_ccw_req *cqr;
struct ccw1 *ccw; struct ccw1 *ccw;
struct bio *bio; struct req_iterator iter;
struct bio_vec *bv; struct bio_vec *bv;
char *dst; char *dst;
int count, cidaw, cplength, datasize; int count, cidaw, cplength, datasize;
sector_t recid, first_rec, last_rec; sector_t recid, first_rec, last_rec;
unsigned int blksize, off; unsigned int blksize, off;
unsigned char cmd; unsigned char cmd;
int i;
private = (struct dasd_fba_private *) device->private; private = (struct dasd_fba_private *) device->private;
if (rq_data_dir(req) == READ) { if (rq_data_dir(req) == READ) {
...@@ -257,8 +256,7 @@ dasd_fba_build_cp(struct dasd_device * device, struct request *req) ...@@ -257,8 +256,7 @@ dasd_fba_build_cp(struct dasd_device * device, struct request *req)
/* Check struct bio and count the number of blocks for the request. */ /* Check struct bio and count the number of blocks for the request. */
count = 0; count = 0;
cidaw = 0; cidaw = 0;
rq_for_each_bio(bio, req) { rq_for_each_segment(bv, req, iter) {
bio_for_each_segment(bv, bio, i) {
if (bv->bv_len & (blksize - 1)) if (bv->bv_len & (blksize - 1))
/* Fba can only do full blocks. */ /* Fba can only do full blocks. */
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
...@@ -269,7 +267,6 @@ dasd_fba_build_cp(struct dasd_device * device, struct request *req) ...@@ -269,7 +267,6 @@ dasd_fba_build_cp(struct dasd_device * device, struct request *req)
cidaw += bv->bv_len / blksize; cidaw += bv->bv_len / blksize;
#endif #endif
} }
}
/* Paranoia. */ /* Paranoia. */
if (count != last_rec - first_rec + 1) if (count != last_rec - first_rec + 1)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
...@@ -304,7 +301,7 @@ dasd_fba_build_cp(struct dasd_device * device, struct request *req) ...@@ -304,7 +301,7 @@ dasd_fba_build_cp(struct dasd_device * device, struct request *req)
locate_record(ccw++, LO_data++, rq_data_dir(req), 0, count); locate_record(ccw++, LO_data++, rq_data_dir(req), 0, count);
} }
recid = first_rec; recid = first_rec;
rq_for_each_bio(bio, req) bio_for_each_segment(bv, bio, i) { rq_for_each_segment(bv, req, iter) {
dst = page_address(bv->bv_page) + bv->bv_offset; dst = page_address(bv->bv_page) + bv->bv_offset;
if (dasd_page_cache) { if (dasd_page_cache) {
char *copy = kmem_cache_alloc(dasd_page_cache, char *copy = kmem_cache_alloc(dasd_page_cache,
...@@ -359,11 +356,11 @@ dasd_fba_free_cp(struct dasd_ccw_req *cqr, struct request *req) ...@@ -359,11 +356,11 @@ dasd_fba_free_cp(struct dasd_ccw_req *cqr, struct request *req)
{ {
struct dasd_fba_private *private; struct dasd_fba_private *private;
struct ccw1 *ccw; struct ccw1 *ccw;
struct bio *bio; struct req_iterator iter;
struct bio_vec *bv; struct bio_vec *bv;
char *dst, *cda; char *dst, *cda;
unsigned int blksize, off; unsigned int blksize, off;
int i, status; int status;
if (!dasd_page_cache) if (!dasd_page_cache)
goto out; goto out;
...@@ -374,7 +371,7 @@ dasd_fba_free_cp(struct dasd_ccw_req *cqr, struct request *req) ...@@ -374,7 +371,7 @@ dasd_fba_free_cp(struct dasd_ccw_req *cqr, struct request *req)
ccw++; ccw++;
if (private->rdc_data.mode.bits.data_chain != 0) if (private->rdc_data.mode.bits.data_chain != 0)
ccw++; ccw++;
rq_for_each_bio(bio, req) bio_for_each_segment(bv, bio, i) { rq_for_each_segment(bv, req, iter) {
dst = page_address(bv->bv_page) + bv->bv_offset; dst = page_address(bv->bv_page) + bv->bv_offset;
for (off = 0; off < bv->bv_len; off += blksize) { for (off = 0; off < bv->bv_len; off += blksize) {
/* Skip locate record. */ /* Skip locate record. */
......
...@@ -1134,21 +1134,18 @@ tape_34xx_bread(struct tape_device *device, struct request *req) ...@@ -1134,21 +1134,18 @@ tape_34xx_bread(struct tape_device *device, struct request *req)
{ {
struct tape_request *request; struct tape_request *request;
struct ccw1 *ccw; struct ccw1 *ccw;
int count = 0, i; int count = 0;
unsigned off; unsigned off;
char *dst; char *dst;
struct bio_vec *bv; struct bio_vec *bv;
struct bio *bio; struct req_iterator iter;
struct tape_34xx_block_id * start_block; struct tape_34xx_block_id * start_block;
DBF_EVENT(6, "xBREDid:"); DBF_EVENT(6, "xBREDid:");
/* Count the number of blocks for the request. */ /* Count the number of blocks for the request. */
rq_for_each_bio(bio, req) { rq_for_each_segment(bv, req, iter)
bio_for_each_segment(bv, bio, i) {
count += bv->bv_len >> (TAPEBLOCK_HSEC_S2B + 9); count += bv->bv_len >> (TAPEBLOCK_HSEC_S2B + 9);
}
}
/* Allocate the ccw request. */ /* Allocate the ccw request. */
request = tape_alloc_request(3+count+1, 8); request = tape_alloc_request(3+count+1, 8);
...@@ -1175,8 +1172,7 @@ tape_34xx_bread(struct tape_device *device, struct request *req) ...@@ -1175,8 +1172,7 @@ tape_34xx_bread(struct tape_device *device, struct request *req)
ccw = tape_ccw_cc(ccw, NOP, 0, NULL); ccw = tape_ccw_cc(ccw, NOP, 0, NULL);
ccw = tape_ccw_cc(ccw, NOP, 0, NULL); ccw = tape_ccw_cc(ccw, NOP, 0, NULL);
rq_for_each_bio(bio, req) { rq_for_each_segment(bv, req, iter) {
bio_for_each_segment(bv, bio, i) {
dst = kmap(bv->bv_page) + bv->bv_offset; dst = kmap(bv->bv_page) + bv->bv_offset;
for (off = 0; off < bv->bv_len; for (off = 0; off < bv->bv_len;
off += TAPEBLOCK_HSEC_SIZE) { off += TAPEBLOCK_HSEC_SIZE) {
...@@ -1188,7 +1184,6 @@ tape_34xx_bread(struct tape_device *device, struct request *req) ...@@ -1188,7 +1184,6 @@ tape_34xx_bread(struct tape_device *device, struct request *req)
dst += TAPEBLOCK_HSEC_SIZE; dst += TAPEBLOCK_HSEC_SIZE;
} }
} }
}
ccw = tape_ccw_end(ccw, NOP, 0, NULL); ccw = tape_ccw_end(ccw, NOP, 0, NULL);
DBF_EVENT(6, "xBREDccwg\n"); DBF_EVENT(6, "xBREDccwg\n");
......
...@@ -623,21 +623,19 @@ tape_3590_bread(struct tape_device *device, struct request *req) ...@@ -623,21 +623,19 @@ tape_3590_bread(struct tape_device *device, struct request *req)
{ {
struct tape_request *request; struct tape_request *request;
struct ccw1 *ccw; struct ccw1 *ccw;
int count = 0, start_block, i; int count = 0, start_block;
unsigned off; unsigned off;
char *dst; char *dst;
struct bio_vec *bv; struct bio_vec *bv;
struct bio *bio; struct req_iterator iter;
DBF_EVENT(6, "xBREDid:"); DBF_EVENT(6, "xBREDid:");
start_block = req->sector >> TAPEBLOCK_HSEC_S2B; start_block = req->sector >> TAPEBLOCK_HSEC_S2B;
DBF_EVENT(6, "start_block = %i\n", start_block); DBF_EVENT(6, "start_block = %i\n", start_block);
rq_for_each_bio(bio, req) { rq_for_each_segment(bv, req, iter)
bio_for_each_segment(bv, bio, i) {
count += bv->bv_len >> (TAPEBLOCK_HSEC_S2B + 9); count += bv->bv_len >> (TAPEBLOCK_HSEC_S2B + 9);
}
}
request = tape_alloc_request(2 + count + 1, 4); request = tape_alloc_request(2 + count + 1, 4);
if (IS_ERR(request)) if (IS_ERR(request))
return request; return request;
...@@ -653,8 +651,7 @@ tape_3590_bread(struct tape_device *device, struct request *req) ...@@ -653,8 +651,7 @@ tape_3590_bread(struct tape_device *device, struct request *req)
*/ */
ccw = tape_ccw_cc(ccw, NOP, 0, NULL); ccw = tape_ccw_cc(ccw, NOP, 0, NULL);
rq_for_each_bio(bio, req) { rq_for_each_segment(bv, req, iter) {
bio_for_each_segment(bv, bio, i) {
dst = page_address(bv->bv_page) + bv->bv_offset; dst = page_address(bv->bv_page) + bv->bv_offset;
for (off = 0; off < bv->bv_len; for (off = 0; off < bv->bv_len;
off += TAPEBLOCK_HSEC_SIZE) { off += TAPEBLOCK_HSEC_SIZE) {
...@@ -668,7 +665,6 @@ tape_3590_bread(struct tape_device *device, struct request *req) ...@@ -668,7 +665,6 @@ tape_3590_bread(struct tape_device *device, struct request *req)
if (off > bv->bv_len) if (off > bv->bv_len)
BUG(); BUG();
} }
}
ccw = tape_ccw_end(ccw, NOP, 0, NULL); ccw = tape_ccw_end(ccw, NOP, 0, NULL);
DBF_EVENT(6, "xBREDccwg\n"); DBF_EVENT(6, "xBREDccwg\n");
return request; return request;
......
...@@ -637,10 +637,23 @@ static inline void blk_queue_bounce(struct request_queue *q, struct bio **bio) ...@@ -637,10 +637,23 @@ static inline void blk_queue_bounce(struct request_queue *q, struct bio **bio)
} }
#endif /* CONFIG_MMU */ #endif /* CONFIG_MMU */
#define rq_for_each_bio(_bio, rq) \ struct req_iterator {
int i;
struct bio *bio;
};
/* This should not be used directly - use rq_for_each_segment */
#define __rq_for_each_bio(_bio, rq) \
if ((rq->bio)) \ if ((rq->bio)) \
for (_bio = (rq)->bio; _bio; _bio = _bio->bi_next) for (_bio = (rq)->bio; _bio; _bio = _bio->bi_next)
#define rq_for_each_segment(bvl, _rq, _iter) \
__rq_for_each_bio(_iter.bio, _rq) \
bio_for_each_segment(bvl, _iter.bio, _iter.i)
#define rq_iter_last(rq, _iter) \
(_iter.bio->bi_next == NULL && _iter.i == _iter.bio->bi_vcnt-1)
extern int blk_register_queue(struct gendisk *disk); extern int blk_register_queue(struct gendisk *disk);
extern void blk_unregister_queue(struct gendisk *disk); extern void blk_unregister_queue(struct gendisk *disk);
extern void register_disk(struct gendisk *dev); extern void register_disk(struct gendisk *dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment