Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

block: set rq->resid_len to blk_rq_bytes() on issue

In commit c3a4d78c580de4edc9ef0f7c59812fb02ceb037f, while introducing
rq->resid_len, the default value of residue count was changed from
full count to zero. The conversion was done under the assumption that
when a request fails residue count wasn't defined. However, Boaz and
James pointed out that this wasn't true and the residue count should
be preserved for failed requests too.

This patchset restores the original behavior by setting rq->resid_len
to blk_rq_bytes(rq) on request start and restoring explicit clearing
in affected drivers. While at it, take advantage of the fact that
rq->resid_len is set to full count where applicable.

* ide-cd: rq->resid_len cleared on pc success

* mptsas: req->resid_len cleared on success

* sas_expander: rsp/req->resid_len cleared on success

* mpt2sas_transport: req->resid_len cleared on success

* ide-cd, ide-tape, mptsas, sas_host_smp, mpt2sas_transport, ub: take
advantage of initial full count to simplify code

Boaz Harrosh spotted bug in resid_len initialization. Fixed as
suggested.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Borislav Petkov <petkovbb@googlemail.com>
Cc: Boaz Harrosh <bharrosh@panasas.com>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
Cc: Pete Zaitcev <zaitcev@redhat.com>
Cc: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Cc: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Cc: Eric Moore <Eric.Moore@lsi.com>
Cc: Darrick J. Wong <djwong@us.ibm.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>

authored by

Tejun Heo and committed by
Jens Axboe
5f49f631 3755100d

+18 -13
+3 -2
block/blk-core.c
··· 1783 1783 blk_dequeue_request(req); 1784 1784 1785 1785 /* 1786 - * We are now handing the request to the hardware, add the 1787 - * timeout handler. 1786 + * We are now handing the request to the hardware, initialize 1787 + * resid_len to full count and add the timeout handler. 1788 1788 */ 1789 + req->resid_len = blk_rq_bytes(req); 1789 1790 blk_add_timer(req); 1790 1791 } 1791 1792 EXPORT_SYMBOL(blk_start_request);
+4 -2
drivers/block/ub.c
··· 781 781 782 782 if (cmd->error == 0) { 783 783 if (blk_pc_request(rq)) { 784 - if (cmd->act_len < blk_rq_bytes(rq)) 785 - rq->resid_len = blk_rq_bytes(rq) - cmd->act_len; 784 + if (cmd->act_len >= rq->resid_len) 785 + rq->resid_len = 0; 786 + else 787 + rq->resid_len -= cmd->act_len; 786 788 scsi_status = 0; 787 789 } else { 788 790 if (cmd->act_len != cmd->len) {
+2 -2
drivers/ide/ide-cd.c
··· 699 699 700 700 out_end: 701 701 if (blk_pc_request(rq) && rc == 0) { 702 + rq->resid_len = 0; 702 703 blk_end_request_all(rq, 0); 703 704 hwif->rq = NULL; 704 705 } else { ··· 719 718 720 719 /* make sure it's fully ended */ 721 720 if (blk_fs_request(rq) == 0) { 722 - rq->resid_len = blk_rq_bytes(rq) - 723 - (cmd->nbytes - cmd->nleft); 721 + rq->resid_len -= cmd->nbytes - cmd->nleft; 724 722 if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE)) 725 723 rq->resid_len += cmd->last_xfer_len; 726 724 }
+1 -1
drivers/ide/ide-tape.c
··· 380 380 } 381 381 382 382 tape->first_frame += blocks; 383 - rq->resid_len = blk_rq_bytes(rq) - blocks * tape->blk_size; 383 + rq->resid_len -= blocks * tape->blk_size; 384 384 385 385 if (pc->error) { 386 386 uptodate = 0;
+2 -1
drivers/message/fusion/mptsas.c
··· 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 - rsp->resid_len = blk_rq_bytes(rsp) - smprep->ResponseDataLength; 1360 + req->resid_len = 0; 1361 + rsp->resid_len -= smprep->ResponseDataLength; 1361 1362 } else { 1362 1363 printk(MYIOC_s_ERR_FMT "%s: smp passthru reply failed to be returned\n", 1363 1364 ioc->name, __func__);
+4
drivers/scsi/libsas/sas_expander.c
··· 1937 1937 if (ret > 0) { 1938 1938 /* positive number is the untransferred residual */ 1939 1939 rsp->resid_len = ret; 1940 + req->resid_len = 0; 1940 1941 ret = 0; 1942 + } else if (ret == 0) { 1943 + rsp->resid_len = 0; 1944 + req->resid_len = 0; 1941 1945 } 1942 1946 1943 1947 return ret;
-3
drivers/scsi/libsas/sas_host_smp.c
··· 176 176 resp_data[1] = req_data[1]; 177 177 resp_data[2] = SMP_RESP_FUNC_UNK; 178 178 179 - req->resid_len = blk_rq_bytes(req); 180 - rsp->resid_len = blk_rq_bytes(rsp); 181 - 182 179 switch (req_data[1]) { 183 180 case SMP_REPORT_GENERAL: 184 181 req->resid_len -= 8;
+2 -2
drivers/scsi/mpt2sas/mpt2sas_transport.c
··· 1170 1170 1171 1171 memcpy(req->sense, mpi_reply, sizeof(*mpi_reply)); 1172 1172 req->sense_len = sizeof(*mpi_reply); 1173 - rsp->resid_len = blk_rq_bytes(rsp) - 1174 - mpi_reply->ResponseDataLength; 1173 + req->resid_len = 0; 1174 + rsp->resid_len -= mpi_reply->ResponseDataLength; 1175 1175 } else { 1176 1176 dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT 1177 1177 "%s - no reply\n", ioc->name, __func__));