Skip to content

Commit

Permalink
block: restore the meaning of rq->data_len to the true data length
Browse files Browse the repository at this point in the history
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 40b01b9.
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>
  • Loading branch information
FUJITA Tomonori authored and Jens Axboe committed Mar 4, 2008
1 parent 89b6e74 commit 7a85f88
Show file tree
Hide file tree
Showing 7 changed files with 13 additions and 18 deletions.
3 changes: 1 addition & 2 deletions block/blk-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,14 @@ 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;
rq->ref_count = 1;
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;
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 1 addition & 5 deletions block/blk-map.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion block/blk-merge.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
((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)
Expand Down
8 changes: 4 additions & 4 deletions block/bsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions block/scsi_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions drivers/ata/libata-scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion include/linux/blkdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 7a85f88

Please sign in to comment.