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: Neil Brown <neilb@suse.de> Various compile fixes by me... Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
This commit is contained in:
@@ -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,14 +664,14 @@ 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
|
||||||
that traverse bio chains on completion need to keep that in mind. Drivers
|
that traverse bio chains on completion need to keep that in mind. Drivers
|
||||||
|
@@ -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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
* 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 @@ new_segment:
|
|||||||
nsegs++;
|
nsegs++;
|
||||||
}
|
}
|
||||||
bvprv = bvec;
|
bvprv = bvec;
|
||||||
} /* segments in bio */
|
} /* segments in rq */
|
||||||
} /* bios in rq */
|
|
||||||
|
|
||||||
return nsegs;
|
return nsegs;
|
||||||
}
|
}
|
||||||
|
@@ -2437,22 +2437,19 @@ 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 !=
|
break;
|
||||||
base + size)
|
|
||||||
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)
|
|||||||
{
|
{
|
||||||
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,43 +2511,41 @@ 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;
|
|
||||||
|
|
||||||
size = bv->bv_len;
|
size = bv->bv_len;
|
||||||
SUPBOUND(size, remaining);
|
SUPBOUND(size, remaining);
|
||||||
|
|
||||||
buffer = page_address(bv->bv_page) + bv->bv_offset;
|
buffer = page_address(bv->bv_page) + bv->bv_offset;
|
||||||
#ifdef FLOPPY_SANITY_CHECK
|
#ifdef FLOPPY_SANITY_CHECK
|
||||||
if (dma_buffer + size >
|
if (dma_buffer + size >
|
||||||
floppy_track_buffer + (max_buffer_sectors << 10) ||
|
floppy_track_buffer + (max_buffer_sectors << 10) ||
|
||||||
dma_buffer < floppy_track_buffer) {
|
dma_buffer < floppy_track_buffer) {
|
||||||
DPRINT("buffer overrun in copy buffer %d\n",
|
DPRINT("buffer overrun in copy buffer %d\n",
|
||||||
(int)((floppy_track_buffer -
|
(int)((floppy_track_buffer -
|
||||||
dma_buffer) >> 9));
|
dma_buffer) >> 9));
|
||||||
printk("fsector_t=%d buffer_min=%d\n",
|
printk("fsector_t=%d buffer_min=%d\n",
|
||||||
fsector_t, buffer_min);
|
fsector_t, buffer_min);
|
||||||
printk("current_count_sectors=%ld\n",
|
printk("current_count_sectors=%ld\n",
|
||||||
current_count_sectors);
|
current_count_sectors);
|
||||||
if (CT(COMMAND) == FD_READ)
|
|
||||||
printk("read\n");
|
|
||||||
if (CT(COMMAND) == FD_WRITE)
|
|
||||||
printk("write\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (((unsigned long)buffer) % 512)
|
|
||||||
DPRINT("%p buffer not aligned\n", buffer);
|
|
||||||
#endif
|
|
||||||
if (CT(COMMAND) == FD_READ)
|
if (CT(COMMAND) == FD_READ)
|
||||||
memcpy(buffer, dma_buffer, size);
|
printk("read\n");
|
||||||
else
|
if (CT(COMMAND) == FD_WRITE)
|
||||||
memcpy(dma_buffer, buffer, size);
|
printk("write\n");
|
||||||
|
break;
|
||||||
remaining -= size;
|
|
||||||
dma_buffer += size;
|
|
||||||
}
|
}
|
||||||
|
if (((unsigned long)buffer) % 512)
|
||||||
|
DPRINT("%p buffer not aligned\n", buffer);
|
||||||
|
#endif
|
||||||
|
if (CT(COMMAND) == FD_READ)
|
||||||
|
memcpy(buffer, dma_buffer, size);
|
||||||
|
else
|
||||||
|
memcpy(dma_buffer, buffer, size);
|
||||||
|
|
||||||
|
remaining -= size;
|
||||||
|
dma_buffer += size;
|
||||||
}
|
}
|
||||||
#ifdef FLOPPY_SANITY_CHECK
|
#ifdef FLOPPY_SANITY_CHECK
|
||||||
if (remaining) {
|
if (remaining) {
|
||||||
|
@@ -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;
|
||||||
|
struct bio_vec *bvec;
|
||||||
|
|
||||||
rq_for_each_bio(bio, req) {
|
rq_for_each_segment(bvec, req, iter) {
|
||||||
struct bio_vec *bvec;
|
|
||||||
bio_for_each_segment(bvec, bio, idx) {
|
|
||||||
/* 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
|
||||||
@@ -160,7 +159,6 @@ static unsigned int req_to_dma(struct request *req, struct lguest_dma *dma)
|
|||||||
dma->len[i] = bvec->bv_len;
|
dma->len[i] = bvec->bv_len;
|
||||||
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)
|
||||||
|
@@ -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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
@@ -226,7 +225,6 @@ static int nbd_send_req(struct nbd_device *lo, struct request *req)
|
|||||||
result);
|
result);
|
||||||
goto error_out;
|
goto error_out;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -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;
|
struct bio_vec *bvec;
|
||||||
rq_for_each_bio(bio, req) {
|
|
||||||
struct bio_vec *bvec;
|
rq_for_each_segment(bvec, req, iter) {
|
||||||
bio_for_each_segment(bvec, bio, i) {
|
|
||||||
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",
|
||||||
@@ -336,7 +333,6 @@ static struct request *nbd_read_stat(struct nbd_device *lo)
|
|||||||
}
|
}
|
||||||
dprintk(DBG_RX, "%s: request %p: got %d bytes data\n",
|
dprintk(DBG_RX, "%s: request %p: got %d bytes data\n",
|
||||||
lo->disk->disk_name, req, bvec->bv_len);
|
lo->disk->disk_name, req, bvec->bv_len);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return req;
|
return req;
|
||||||
|
@@ -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,
|
|||||||
|
|
||||||
#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)
|
|||||||
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)
|
|||||||
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));
|
||||||
@@ -213,7 +211,6 @@ static int blkif_queue_request(struct request *req)
|
|||||||
.last_sect = lsect };
|
.last_sect = lsect };
|
||||||
|
|
||||||
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
|
|||||||
{
|
{
|
||||||
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;
|
||||||
|
|
||||||
@@ -625,7 +624,6 @@ static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, uns
|
|||||||
bcount -= count;
|
bcount -= count;
|
||||||
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
|
|||||||
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;
|
||||||
|
|
||||||
@@ -659,7 +656,6 @@ static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, un
|
|||||||
bcount -= count;
|
bcount -= count;
|
||||||
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)
|
|||||||
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,13 +492,11 @@ 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)
|
||||||
@@ -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));
|
||||||
@@ -528,7 +524,6 @@ dasd_diag_build_cp(struct dasd_device * device, struct request *req)
|
|||||||
dst += blksize;
|
dst += blksize;
|
||||||
recid++;
|
recid++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
cqr->retries = DIAG_MAX_RETRIES;
|
cqr->retries = DIAG_MAX_RETRIES;
|
||||||
cqr->buildclk = get_clock();
|
cqr->buildclk = get_clock();
|
||||||
|
@@ -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)
|
|||||||
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)
|
|||||||
/* 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);
|
||||||
@@ -1217,7 +1215,6 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req)
|
|||||||
bv->bv_len))
|
bv->bv_len))
|
||||||
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)
|
||||||
@@ -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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
/* 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);
|
||||||
@@ -268,7 +266,6 @@ dasd_fba_build_cp(struct dasd_device * device, struct request *req)
|
|||||||
bv->bv_len))
|
bv->bv_len))
|
||||||
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)
|
||||||
@@ -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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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) {
|
||||||
@@ -1187,7 +1183,6 @@ tape_34xx_bread(struct tape_device *device, struct request *req)
|
|||||||
ccw++;
|
ccw++;
|
||||||
dst += TAPEBLOCK_HSEC_SIZE;
|
dst += TAPEBLOCK_HSEC_SIZE;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ccw = tape_ccw_end(ccw, NOP, 0, NULL);
|
ccw = tape_ccw_end(ccw, NOP, 0, NULL);
|
||||||
|
@@ -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)
|
|||||||
*/
|
*/
|
||||||
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) {
|
||||||
@@ -667,7 +664,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");
|
||||||
|
@@ -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);
|
||||||
|
Reference in New Issue
Block a user