Commit c3a4d78c580de4edc9ef0f7c59812fb02ceb037f
Committed by
Jens Axboe
1 parent
9720aef253
Exists in
master
and in
20 other branches
block: add rq->resid_len
rq->data_len served two purposes - the length of data buffer on issue and the residual count on completion. This duality creates some headaches. First of all, block layer and low level drivers can't really determine what rq->data_len contains while a request is executing. It could be the total request length or it coulde be anything else one of the lower layers is using to keep track of residual count. This complicates things because blk_rq_bytes() and thus [__]blk_end_request_all() relies on rq->data_len for PC commands. Drivers which want to report residual count should first cache the total request length, update rq->data_len and then complete the request with the cached data length. Secondly, it makes requests default to reporting full residual count, ie. reporting that no data transfer occurred. The residual count is an exception not the norm; however, the driver should clear rq->data_len to zero to signify the normal cases while leaving it alone means no data transfer occurred at all. This reverse default behavior complicates code unnecessarily and renders block PC on some drivers (ide-tape/floppy) unuseable. This patch adds rq->resid_len which is used only for residual count. While at it, remove now unnecessasry blk_rq_bytes() caching in ide_pc_intr() as rq->data_len is not changed anymore. Boaz : spotted missing conversion in osd Sergei : spotted too early conversion to blk_rq_bytes() in ide-tape [ Impact: cleanup residual count handling, report 0 resid by default ] Signed-off-by: Tejun Heo <tj@kernel.org> Cc: James Bottomley <James.Bottomley@HansenPartnership.com> Cc: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> Cc: Borislav Petkov <petkovbb@googlemail.com> Cc: Sergei Shtylyov <sshtylyov@ru.mvista.com> Cc: Mike Miller <mike.miller@hp.com> Cc: Eric Moore <Eric.Moore@lsi.com> Cc: Alan Stern <stern@rowland.harvard.edu> Cc: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Cc: Doug Gilbert <dgilbert@interlog.com> Cc: Mike Miller <mike.miller@hp.com> Cc: Eric Moore <Eric.Moore@lsi.com> Cc: Darrick J. Wong <djwong@us.ibm.com> Cc: Pete Zaitcev <zaitcev@redhat.com> Cc: Boaz Harrosh <bharrosh@panasas.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Showing 16 changed files with 59 additions and 80 deletions Side-by-side Diff
- block/bsg.c
- block/scsi_ioctl.c
- drivers/block/cciss.c
- drivers/block/ub.c
- drivers/ide/ide-atapi.c
- drivers/ide/ide-cd.c
- drivers/ide/ide-tape.c
- drivers/message/fusion/mptsas.c
- drivers/scsi/libsas/sas_expander.c
- drivers/scsi/libsas/sas_host_smp.c
- drivers/scsi/mpt2sas/mpt2sas_transport.c
- drivers/scsi/scsi_lib.c
- drivers/scsi/sg.c
- drivers/scsi/st.c
- fs/exofs/osd.c
- include/linux/blkdev.h
block/bsg.c
... | ... | @@ -445,14 +445,14 @@ |
445 | 445 | } |
446 | 446 | |
447 | 447 | if (rq->next_rq) { |
448 | - hdr->dout_resid = rq->data_len; | |
449 | - hdr->din_resid = rq->next_rq->data_len; | |
448 | + hdr->dout_resid = rq->resid_len; | |
449 | + hdr->din_resid = rq->next_rq->resid_len; | |
450 | 450 | blk_rq_unmap_user(bidi_bio); |
451 | 451 | blk_put_request(rq->next_rq); |
452 | 452 | } else if (rq_data_dir(rq) == READ) |
453 | - hdr->din_resid = rq->data_len; | |
453 | + hdr->din_resid = rq->resid_len; | |
454 | 454 | else |
455 | - hdr->dout_resid = rq->data_len; | |
455 | + hdr->dout_resid = rq->resid_len; | |
456 | 456 | |
457 | 457 | /* |
458 | 458 | * If the request generated a negative error number, return it |
block/scsi_ioctl.c
... | ... | @@ -230,7 +230,7 @@ |
230 | 230 | hdr->info = 0; |
231 | 231 | if (hdr->masked_status || hdr->host_status || hdr->driver_status) |
232 | 232 | hdr->info |= SG_INFO_CHECK; |
233 | - hdr->resid = rq->data_len; | |
233 | + hdr->resid = rq->resid_len; | |
234 | 234 | hdr->sb_len_wr = 0; |
235 | 235 | |
236 | 236 | if (rq->sense_len && hdr->sbp) { |
drivers/block/cciss.c
... | ... | @@ -1299,7 +1299,6 @@ |
1299 | 1299 | { |
1300 | 1300 | CommandList_struct *cmd = rq->completion_data; |
1301 | 1301 | ctlr_info_t *h = hba[cmd->ctlr]; |
1302 | - unsigned int nr_bytes; | |
1303 | 1302 | unsigned long flags; |
1304 | 1303 | u64bit temp64; |
1305 | 1304 | int i, ddir; |
1306 | 1305 | |
1307 | 1306 | |
... | ... | @@ -1321,15 +1320,11 @@ |
1321 | 1320 | printk("Done with %p\n", rq); |
1322 | 1321 | #endif /* CCISS_DEBUG */ |
1323 | 1322 | |
1324 | - /* | |
1325 | - * Store the full size and set the residual count for pc requests | |
1326 | - */ | |
1327 | - nr_bytes = blk_rq_bytes(rq); | |
1323 | + /* set the residual count for pc requests */ | |
1328 | 1324 | if (blk_pc_request(rq)) |
1329 | - rq->data_len = cmd->err_info->ResidualCnt; | |
1325 | + rq->resid_len = cmd->err_info->ResidualCnt; | |
1330 | 1326 | |
1331 | - if (blk_end_request(rq, (rq->errors == 0) ? 0 : -EIO, nr_bytes)) | |
1332 | - BUG(); | |
1327 | + blk_end_request_all(rq, (rq->errors == 0) ? 0 : -EIO); | |
1333 | 1328 | |
1334 | 1329 | spin_lock_irqsave(&h->lock, flags); |
1335 | 1330 | cmd_free(h, cmd, 1); |
... | ... | @@ -2691,7 +2686,7 @@ |
2691 | 2686 | printk(KERN_WARNING "cciss: cmd %p has" |
2692 | 2687 | " completed with data underrun " |
2693 | 2688 | "reported\n", cmd); |
2694 | - cmd->rq->data_len = cmd->err_info->ResidualCnt; | |
2689 | + cmd->rq->resid_len = cmd->err_info->ResidualCnt; | |
2695 | 2690 | } |
2696 | 2691 | break; |
2697 | 2692 | case CMD_DATA_OVERRUN: |
drivers/block/ub.c
... | ... | @@ -783,10 +783,8 @@ |
783 | 783 | |
784 | 784 | if (cmd->error == 0) { |
785 | 785 | if (blk_pc_request(rq)) { |
786 | - if (cmd->act_len >= rq->data_len) | |
787 | - rq->data_len = 0; | |
788 | - else | |
789 | - rq->data_len -= cmd->act_len; | |
786 | + if (cmd->act_len < rq->data_len) | |
787 | + rq->resid_len = rq->data_len - cmd->act_len; | |
790 | 788 | scsi_status = 0; |
791 | 789 | } else { |
792 | 790 | if (cmd->act_len != cmd->len) { |
drivers/ide/ide-atapi.c
... | ... | @@ -367,7 +367,6 @@ |
367 | 367 | /* No more interrupts */ |
368 | 368 | if ((stat & ATA_DRQ) == 0) { |
369 | 369 | int uptodate, error; |
370 | - unsigned int done; | |
371 | 370 | |
372 | 371 | debug_log("Packet command completed, %d bytes transferred\n", |
373 | 372 | pc->xferred); |
... | ... | @@ -406,12 +405,6 @@ |
406 | 405 | if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0) |
407 | 406 | dsc = 1; |
408 | 407 | |
409 | - /* | |
410 | - * ->pc_callback() might change rq->data_len for | |
411 | - * residual count, cache total length. | |
412 | - */ | |
413 | - done = blk_rq_bytes(rq); | |
414 | - | |
415 | 408 | /* Command finished - Call the callback function */ |
416 | 409 | uptodate = drive->pc_callback(drive, dsc); |
417 | 410 | |
... | ... | @@ -431,7 +424,7 @@ |
431 | 424 | error = uptodate ? 0 : -EIO; |
432 | 425 | } |
433 | 426 | |
434 | - ide_complete_rq(drive, error, done); | |
427 | + ide_complete_rq(drive, error, blk_rq_bytes(rq)); | |
435 | 428 | return ide_stopped; |
436 | 429 | } |
437 | 430 |
drivers/ide/ide-cd.c
... | ... | @@ -519,7 +519,7 @@ |
519 | 519 | error = blk_execute_rq(drive->queue, info->disk, rq, 0); |
520 | 520 | |
521 | 521 | if (buffer) |
522 | - *bufflen = rq->data_len; | |
522 | + *bufflen = rq->resid_len; | |
523 | 523 | |
524 | 524 | flags = rq->cmd_flags; |
525 | 525 | blk_put_request(rq); |
... | ... | @@ -707,11 +707,7 @@ |
707 | 707 | |
708 | 708 | out_end: |
709 | 709 | if (blk_pc_request(rq) && rc == 0) { |
710 | - unsigned int dlen = rq->data_len; | |
711 | - | |
712 | - rq->data_len = 0; | |
713 | - | |
714 | - if (blk_end_request(rq, 0, dlen)) | |
710 | + if (blk_end_request(rq, 0, rq->data_len)) | |
715 | 711 | BUG(); |
716 | 712 | |
717 | 713 | hwif->rq = NULL; |
718 | 714 | |
... | ... | @@ -740,9 +736,10 @@ |
740 | 736 | nsectors = 1; |
741 | 737 | |
742 | 738 | if (blk_fs_request(rq) == 0) { |
743 | - rq->data_len -= (cmd->nbytes - cmd->nleft); | |
739 | + rq->resid_len = rq->data_len - | |
740 | + (cmd->nbytes - cmd->nleft); | |
744 | 741 | if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE)) |
745 | - rq->data_len += cmd->last_xfer_len; | |
742 | + rq->resid_len += cmd->last_xfer_len; | |
746 | 743 | } |
747 | 744 | |
748 | 745 | ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9); |
drivers/ide/ide-tape.c
... | ... | @@ -380,7 +380,7 @@ |
380 | 380 | } |
381 | 381 | |
382 | 382 | tape->first_frame += blocks; |
383 | - rq->data_len -= blocks * tape->blk_size; | |
383 | + rq->resid_len = rq->data_len - blocks * tape->blk_size; | |
384 | 384 | |
385 | 385 | if (pc->error) { |
386 | 386 | uptodate = 0; |
... | ... | @@ -903,7 +903,7 @@ |
903 | 903 | blk_execute_rq(drive->queue, tape->disk, rq, 0); |
904 | 904 | |
905 | 905 | /* calculate the number of transferred bytes and update buffer state */ |
906 | - size -= rq->data_len; | |
906 | + size -= rq->resid_len; | |
907 | 907 | tape->cur = tape->buf; |
908 | 908 | if (cmd == REQ_IDETAPE_READ) |
909 | 909 | tape->valid = size; |
drivers/message/fusion/mptsas.c
... | ... | @@ -1357,8 +1357,7 @@ |
1357 | 1357 | smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply; |
1358 | 1358 | memcpy(req->sense, smprep, sizeof(*smprep)); |
1359 | 1359 | req->sense_len = sizeof(*smprep); |
1360 | - req->data_len = 0; | |
1361 | - rsp->data_len -= smprep->ResponseDataLength; | |
1360 | + rsp->resid_len = rsp->data_len - smprep->ResponseDataLength; | |
1362 | 1361 | } else { |
1363 | 1362 | printk(MYIOC_s_ERR_FMT "%s: smp passthru reply failed to be returned\n", |
1364 | 1363 | ioc->name, __func__); |
drivers/scsi/libsas/sas_expander.c
... | ... | @@ -1936,12 +1936,8 @@ |
1936 | 1936 | bio_data(rsp->bio), rsp->data_len); |
1937 | 1937 | if (ret > 0) { |
1938 | 1938 | /* positive number is the untransferred residual */ |
1939 | - rsp->data_len = ret; | |
1940 | - req->data_len = 0; | |
1939 | + rsp->resid_len = ret; | |
1941 | 1940 | ret = 0; |
1942 | - } else if (ret == 0) { | |
1943 | - rsp->data_len = 0; | |
1944 | - req->data_len = 0; | |
1945 | 1941 | } |
1946 | 1942 | |
1947 | 1943 | return ret; |
drivers/scsi/libsas/sas_host_smp.c
... | ... | @@ -134,7 +134,7 @@ |
134 | 134 | { |
135 | 135 | u8 *req_data = NULL, *resp_data = NULL, *buf; |
136 | 136 | struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost); |
137 | - int error = -EINVAL, resp_data_len = rsp->data_len; | |
137 | + int error = -EINVAL; | |
138 | 138 | |
139 | 139 | /* eight is the minimum size for request and response frames */ |
140 | 140 | if (req->data_len < 8 || rsp->data_len < 8) |
141 | 141 | |
142 | 142 | |
... | ... | @@ -176,17 +176,20 @@ |
176 | 176 | resp_data[1] = req_data[1]; |
177 | 177 | resp_data[2] = SMP_RESP_FUNC_UNK; |
178 | 178 | |
179 | + req->resid_len = req->data_len; | |
180 | + rsp->resid_len = rsp->data_len; | |
181 | + | |
179 | 182 | switch (req_data[1]) { |
180 | 183 | case SMP_REPORT_GENERAL: |
181 | - req->data_len -= 8; | |
182 | - resp_data_len -= 32; | |
184 | + req->resid_len -= 8; | |
185 | + rsp->resid_len -= 32; | |
183 | 186 | resp_data[2] = SMP_RESP_FUNC_ACC; |
184 | 187 | resp_data[9] = sas_ha->num_phys; |
185 | 188 | break; |
186 | 189 | |
187 | 190 | case SMP_REPORT_MANUF_INFO: |
188 | - req->data_len -= 8; | |
189 | - resp_data_len -= 64; | |
191 | + req->resid_len -= 8; | |
192 | + rsp->resid_len -= 64; | |
190 | 193 | resp_data[2] = SMP_RESP_FUNC_ACC; |
191 | 194 | memcpy(resp_data + 12, shost->hostt->name, |
192 | 195 | SAS_EXPANDER_VENDOR_ID_LEN); |
193 | 196 | |
... | ... | @@ -199,13 +202,13 @@ |
199 | 202 | break; |
200 | 203 | |
201 | 204 | case SMP_DISCOVER: |
202 | - req->data_len -= 16; | |
203 | - if ((int)req->data_len < 0) { | |
204 | - req->data_len = 0; | |
205 | + req->resid_len -= 16; | |
206 | + if ((int)req->resid_len < 0) { | |
207 | + req->resid_len = 0; | |
205 | 208 | error = -EINVAL; |
206 | 209 | goto out; |
207 | 210 | } |
208 | - resp_data_len -= 56; | |
211 | + rsp->resid_len -= 56; | |
209 | 212 | sas_host_smp_discover(sas_ha, resp_data, req_data[9]); |
210 | 213 | break; |
211 | 214 | |
212 | 215 | |
... | ... | @@ -215,13 +218,13 @@ |
215 | 218 | break; |
216 | 219 | |
217 | 220 | case SMP_REPORT_PHY_SATA: |
218 | - req->data_len -= 16; | |
219 | - if ((int)req->data_len < 0) { | |
220 | - req->data_len = 0; | |
221 | + req->resid_len -= 16; | |
222 | + if ((int)req->resid_len < 0) { | |
223 | + req->resid_len = 0; | |
221 | 224 | error = -EINVAL; |
222 | 225 | goto out; |
223 | 226 | } |
224 | - resp_data_len -= 60; | |
227 | + rsp->resid_len -= 60; | |
225 | 228 | sas_report_phy_sata(sas_ha, resp_data, req_data[9]); |
226 | 229 | break; |
227 | 230 | |
228 | 231 | |
... | ... | @@ -238,13 +241,13 @@ |
238 | 241 | break; |
239 | 242 | |
240 | 243 | case SMP_PHY_CONTROL: |
241 | - req->data_len -= 44; | |
242 | - if ((int)req->data_len < 0) { | |
243 | - req->data_len = 0; | |
244 | + req->resid_len -= 44; | |
245 | + if ((int)req->resid_len < 0) { | |
246 | + req->resid_len = 0; | |
244 | 247 | error = -EINVAL; |
245 | 248 | goto out; |
246 | 249 | } |
247 | - resp_data_len -= 8; | |
250 | + rsp->resid_len -= 8; | |
248 | 251 | sas_phy_control(sas_ha, req_data[9], req_data[10], |
249 | 252 | req_data[32] >> 4, req_data[33] >> 4, |
250 | 253 | resp_data); |
... | ... | @@ -265,7 +268,6 @@ |
265 | 268 | flush_kernel_dcache_page(bio_page(rsp->bio)); |
266 | 269 | kunmap_atomic(buf - bio_offset(rsp->bio), KM_USER0); |
267 | 270 | local_irq_enable(); |
268 | - rsp->data_len = resp_data_len; | |
269 | 271 | |
270 | 272 | out: |
271 | 273 | kfree(req_data); |
drivers/scsi/mpt2sas/mpt2sas_transport.c
... | ... | @@ -1170,9 +1170,7 @@ |
1170 | 1170 | |
1171 | 1171 | memcpy(req->sense, mpi_reply, sizeof(*mpi_reply)); |
1172 | 1172 | req->sense_len = sizeof(*mpi_reply); |
1173 | - req->data_len = 0; | |
1174 | - rsp->data_len -= mpi_reply->ResponseDataLength; | |
1175 | - | |
1173 | + rsp->resid_len = rsp->data_len - mpi_reply->ResponseDataLength; | |
1176 | 1174 | } else { |
1177 | 1175 | dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT |
1178 | 1176 | "%s - no reply\n", ioc->name, __func__)); |
drivers/scsi/scsi_lib.c
... | ... | @@ -240,11 +240,11 @@ |
240 | 240 | * is invalid. Prevent the garbage from being misinterpreted |
241 | 241 | * and prevent security leaks by zeroing out the excess data. |
242 | 242 | */ |
243 | - if (unlikely(req->data_len > 0 && req->data_len <= bufflen)) | |
244 | - memset(buffer + (bufflen - req->data_len), 0, req->data_len); | |
243 | + if (unlikely(req->resid_len > 0 && req->resid_len <= bufflen)) | |
244 | + memset(buffer + (bufflen - req->resid_len), 0, req->resid_len); | |
245 | 245 | |
246 | 246 | if (resid) |
247 | - *resid = req->data_len; | |
247 | + *resid = req->resid_len; | |
248 | 248 | ret = req->errors; |
249 | 249 | out: |
250 | 250 | blk_put_request(req); |
... | ... | @@ -549,7 +549,7 @@ |
549 | 549 | int leftover = (req->hard_nr_sectors << 9); |
550 | 550 | |
551 | 551 | if (blk_pc_request(req)) |
552 | - leftover = req->data_len; | |
552 | + leftover = req->resid_len; | |
553 | 553 | |
554 | 554 | /* kill remainder if no retrys */ |
555 | 555 | if (error && scsi_noretry_cmd(cmd)) |
... | ... | @@ -673,11 +673,11 @@ |
673 | 673 | EXPORT_SYMBOL(scsi_release_buffers); |
674 | 674 | |
675 | 675 | /* |
676 | - * Bidi commands Must be complete as a whole, both sides at once. | |
677 | - * If part of the bytes were written and lld returned | |
678 | - * scsi_in()->resid and/or scsi_out()->resid this information will be left | |
679 | - * in req->data_len and req->next_rq->data_len. The upper-layer driver can | |
680 | - * decide what to do with this information. | |
676 | + * Bidi commands Must be complete as a whole, both sides at once. If | |
677 | + * part of the bytes were written and lld returned scsi_in()->resid | |
678 | + * and/or scsi_out()->resid this information will be left in | |
679 | + * req->resid_len and req->next_rq->resid_len. The upper-layer driver | |
680 | + * can decide what to do with this information. | |
681 | 681 | */ |
682 | 682 | static void scsi_end_bidi_request(struct scsi_cmnd *cmd) |
683 | 683 | { |
... | ... | @@ -685,8 +685,8 @@ |
685 | 685 | unsigned int dlen = req->data_len; |
686 | 686 | unsigned int next_dlen = req->next_rq->data_len; |
687 | 687 | |
688 | - req->data_len = scsi_out(cmd)->resid; | |
689 | - req->next_rq->data_len = scsi_in(cmd)->resid; | |
688 | + req->resid_len = scsi_out(cmd)->resid; | |
689 | + req->next_rq->resid_len = scsi_in(cmd)->resid; | |
690 | 690 | |
691 | 691 | /* The req and req->next_rq have not been completed */ |
692 | 692 | BUG_ON(blk_end_bidi_request(req, 0, dlen, next_dlen)); |
... | ... | @@ -778,7 +778,7 @@ |
778 | 778 | scsi_end_bidi_request(cmd); |
779 | 779 | return; |
780 | 780 | } |
781 | - req->data_len = scsi_get_resid(cmd); | |
781 | + req->resid_len = scsi_get_resid(cmd); | |
782 | 782 | } |
783 | 783 | |
784 | 784 | BUG_ON(blk_bidi_rq(req)); /* bidi not support for !blk_pc_request yet */ |
drivers/scsi/sg.c
... | ... | @@ -1260,7 +1260,7 @@ |
1260 | 1260 | |
1261 | 1261 | sense = rq->sense; |
1262 | 1262 | result = rq->errors; |
1263 | - resid = rq->data_len; | |
1263 | + resid = rq->resid_len; | |
1264 | 1264 | |
1265 | 1265 | SCSI_LOG_TIMEOUT(4, printk("sg_cmd_done: %s, pack_id=%d, res=0x%x\n", |
1266 | 1266 | sdp->disk->disk_name, srp->header.pack_id, result)); |
drivers/scsi/st.c
... | ... | @@ -463,7 +463,7 @@ |
463 | 463 | struct scsi_tape *STp = SRpnt->stp; |
464 | 464 | |
465 | 465 | STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors; |
466 | - STp->buffer->cmdstat.residual = req->data_len; | |
466 | + STp->buffer->cmdstat.residual = req->resid_len; | |
467 | 467 | |
468 | 468 | if (SRpnt->waiting) |
469 | 469 | complete(SRpnt->waiting); |
fs/exofs/osd.c
... | ... | @@ -50,10 +50,10 @@ |
50 | 50 | |
51 | 51 | /* FIXME: should be include in osd_sense_info */ |
52 | 52 | if (in_resid) |
53 | - *in_resid = or->in.req ? or->in.req->data_len : 0; | |
53 | + *in_resid = or->in.req ? or->in.req->resid_len : 0; | |
54 | 54 | |
55 | 55 | if (out_resid) |
56 | - *out_resid = or->out.req ? or->out.req->data_len : 0; | |
56 | + *out_resid = or->out.req ? or->out.req->resid_len : 0; | |
57 | 57 | |
58 | 58 | return ret; |
59 | 59 | } |
include/linux/blkdev.h