block: restore the meaning of rq->data_len to the true data length
The meaning of rq->data_len was changed to the length of an allocated
buffer from the true data length. It breaks SG_IO friends and
bsg. This patch restores the meaning of rq->data_len to the true data
length and adds rq->extra_len to store an extended length (due to
drain buffer and padding).
This patch also removes the code to update bio in blk_rq_map_user
introduced by the commit 40b01b9bbd
.
The commit adjusts bio according to memory alignment
(queue_dma_alignment). However, memory alignment is NOT padding
alignment. This adjustment also breaks SG_IO friends and bsg. Padding
alignment needs to be fixed in a proper way (by a separate patch).
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Jens Axboe <axboe@carl.home.kernel.dk>
This commit is contained in:
parent
89b6e74378
commit
7a85f8896f
|
@ -127,7 +127,6 @@ void rq_init(struct request_queue *q, struct request *rq)
|
|||
rq->nr_hw_segments = 0;
|
||||
rq->ioprio = 0;
|
||||
rq->special = NULL;
|
||||
rq->raw_data_len = 0;
|
||||
rq->buffer = NULL;
|
||||
rq->tag = -1;
|
||||
rq->errors = 0;
|
||||
|
@ -135,6 +134,7 @@ void rq_init(struct request_queue *q, struct request *rq)
|
|||
rq->cmd_len = 0;
|
||||
memset(rq->cmd, 0, sizeof(rq->cmd));
|
||||
rq->data_len = 0;
|
||||
rq->extra_len = 0;
|
||||
rq->sense_len = 0;
|
||||
rq->data = NULL;
|
||||
rq->sense = NULL;
|
||||
|
@ -2018,7 +2018,6 @@ void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
|
|||
rq->hard_cur_sectors = rq->current_nr_sectors;
|
||||
rq->hard_nr_sectors = rq->nr_sectors = bio_sectors(bio);
|
||||
rq->buffer = bio_data(bio);
|
||||
rq->raw_data_len = bio->bi_size;
|
||||
rq->data_len = bio->bi_size;
|
||||
|
||||
rq->bio = rq->biotail = bio;
|
||||
|
|
|
@ -19,7 +19,6 @@ int blk_rq_append_bio(struct request_queue *q, struct request *rq,
|
|||
rq->biotail->bi_next = bio;
|
||||
rq->biotail = bio;
|
||||
|
||||
rq->raw_data_len += bio->bi_size;
|
||||
rq->data_len += bio->bi_size;
|
||||
}
|
||||
return 0;
|
||||
|
@ -151,11 +150,8 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq,
|
|||
*/
|
||||
if (len & queue_dma_alignment(q)) {
|
||||
unsigned int pad_len = (queue_dma_alignment(q) & ~len) + 1;
|
||||
struct bio *bio = rq->biotail;
|
||||
|
||||
bio->bi_io_vec[bio->bi_vcnt - 1].bv_len += pad_len;
|
||||
bio->bi_size += pad_len;
|
||||
rq->data_len += pad_len;
|
||||
rq->extra_len += pad_len;
|
||||
}
|
||||
|
||||
rq->buffer = rq->data = NULL;
|
||||
|
|
|
@ -231,7 +231,7 @@ new_segment:
|
|||
((unsigned long)q->dma_drain_buffer) &
|
||||
(PAGE_SIZE - 1));
|
||||
nsegs++;
|
||||
rq->data_len += q->dma_drain_size;
|
||||
rq->extra_len += q->dma_drain_size;
|
||||
}
|
||||
|
||||
if (sg)
|
||||
|
|
|
@ -437,14 +437,14 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
|
|||
}
|
||||
|
||||
if (rq->next_rq) {
|
||||
hdr->dout_resid = rq->raw_data_len;
|
||||
hdr->din_resid = rq->next_rq->raw_data_len;
|
||||
hdr->dout_resid = rq->data_len;
|
||||
hdr->din_resid = rq->next_rq->data_len;
|
||||
blk_rq_unmap_user(bidi_bio);
|
||||
blk_put_request(rq->next_rq);
|
||||
} else if (rq_data_dir(rq) == READ)
|
||||
hdr->din_resid = rq->raw_data_len;
|
||||
hdr->din_resid = rq->data_len;
|
||||
else
|
||||
hdr->dout_resid = rq->raw_data_len;
|
||||
hdr->dout_resid = rq->data_len;
|
||||
|
||||
/*
|
||||
* If the request generated a negative error number, return it
|
||||
|
|
|
@ -266,7 +266,7 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
|
|||
hdr->info = 0;
|
||||
if (hdr->masked_status || hdr->host_status || hdr->driver_status)
|
||||
hdr->info |= SG_INFO_CHECK;
|
||||
hdr->resid = rq->raw_data_len;
|
||||
hdr->resid = rq->data_len;
|
||||
hdr->sb_len_wr = 0;
|
||||
|
||||
if (rq->sense_len && hdr->sbp) {
|
||||
|
@ -528,8 +528,8 @@ static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk,
|
|||
rq = blk_get_request(q, WRITE, __GFP_WAIT);
|
||||
rq->cmd_type = REQ_TYPE_BLOCK_PC;
|
||||
rq->data = NULL;
|
||||
rq->raw_data_len = 0;
|
||||
rq->data_len = 0;
|
||||
rq->extra_len = 0;
|
||||
rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
|
||||
memset(rq->cmd, 0, sizeof(rq->cmd));
|
||||
rq->cmd[0] = cmd;
|
||||
|
|
|
@ -2538,7 +2538,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
|
|||
}
|
||||
|
||||
qc->tf.command = ATA_CMD_PACKET;
|
||||
qc->nbytes = scsi_bufflen(scmd);
|
||||
qc->nbytes = scsi_bufflen(scmd) + scmd->request->extra_len;
|
||||
|
||||
/* check whether ATAPI DMA is safe */
|
||||
if (!using_pio && ata_check_atapi_dma(qc))
|
||||
|
@ -2549,7 +2549,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
|
|||
* want to set it properly, and for DMA where it is
|
||||
* effectively meaningless.
|
||||
*/
|
||||
nbytes = min(scmd->request->raw_data_len, (unsigned int)63 * 1024);
|
||||
nbytes = min(scmd->request->data_len, (unsigned int)63 * 1024);
|
||||
|
||||
/* Most ATAPI devices which honor transfer chunk size don't
|
||||
* behave according to the spec when odd chunk size which
|
||||
|
@ -2875,7 +2875,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
|
|||
* TODO: find out if we need to do more here to
|
||||
* cover scatter/gather case.
|
||||
*/
|
||||
qc->nbytes = scsi_bufflen(scmd);
|
||||
qc->nbytes = scsi_bufflen(scmd) + scmd->request->extra_len;
|
||||
|
||||
/* request result TF and be quiet about device error */
|
||||
qc->flags |= ATA_QCFLAG_RESULT_TF | ATA_QCFLAG_QUIET;
|
||||
|
|
|
@ -216,8 +216,8 @@ struct request {
|
|||
unsigned int cmd_len;
|
||||
unsigned char cmd[BLK_MAX_CDB];
|
||||
|
||||
unsigned int raw_data_len;
|
||||
unsigned int data_len;
|
||||
unsigned int extra_len; /* length of alignment and padding */
|
||||
unsigned int sense_len;
|
||||
void *data;
|
||||
void *sense;
|
||||
|
|
Loading…
Reference in New Issue