Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7a85f889 authored by FUJITA Tomonori's avatar FUJITA Tomonori Committed by Jens Axboe
Browse files

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 40b01b9b.
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: default avatarFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: default avatarJens Axboe <axboe@carl.home.kernel.dk>
parent 89b6e743
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -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;
+1 −5
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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)
+4 −4
Original line number Diff line number Diff line
@@ -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
+2 −2
Original line number Diff line number Diff line
@@ -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;
Loading