Commit c3a4d78c580de4edc9ef0f7c59812fb02ceb037f

Authored by Tejun Heo
Committed by Jens Axboe
1 parent 9720aef253

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

... ... @@ -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
... ... @@ -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:
... ... @@ -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 */
... ... @@ -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));
... ... @@ -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);
... ... @@ -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
... ... @@ -229,6 +229,7 @@
229 229 unsigned int data_len;
230 230 unsigned int extra_len; /* length of alignment and padding */
231 231 unsigned int sense_len;
  232 + unsigned int resid_len; /* residual count */
232 233 void *sense;
233 234  
234 235 unsigned long deadline;