Commit 5f49f631 authored by Tejun Heo's avatar Tejun Heo Committed by Jens Axboe

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

In commit c3a4d78c, 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: default avatarTejun Heo <tj@kernel.org>
Acked-by: default avatarBorislav 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: default avatarJens Axboe <jens.axboe@oracle.com>
parent 3755100d
...@@ -1783,9 +1783,10 @@ void blk_start_request(struct request *req) ...@@ -1783,9 +1783,10 @@ void blk_start_request(struct request *req)
blk_dequeue_request(req); blk_dequeue_request(req);
/* /*
* We are now handing the request to the hardware, add the * We are now handing the request to the hardware, initialize
* timeout handler. * resid_len to full count and add the timeout handler.
*/ */
req->resid_len = blk_rq_bytes(req);
blk_add_timer(req); blk_add_timer(req);
} }
EXPORT_SYMBOL(blk_start_request); EXPORT_SYMBOL(blk_start_request);
......
...@@ -781,8 +781,10 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) ...@@ -781,8 +781,10 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
if (cmd->error == 0) { if (cmd->error == 0) {
if (blk_pc_request(rq)) { if (blk_pc_request(rq)) {
if (cmd->act_len < blk_rq_bytes(rq)) if (cmd->act_len >= rq->resid_len)
rq->resid_len = blk_rq_bytes(rq) - cmd->act_len; rq->resid_len = 0;
else
rq->resid_len -= cmd->act_len;
scsi_status = 0; scsi_status = 0;
} else { } else {
if (cmd->act_len != cmd->len) { if (cmd->act_len != cmd->len) {
......
...@@ -699,6 +699,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) ...@@ -699,6 +699,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
out_end: out_end:
if (blk_pc_request(rq) && rc == 0) { if (blk_pc_request(rq) && rc == 0) {
rq->resid_len = 0;
blk_end_request_all(rq, 0); blk_end_request_all(rq, 0);
hwif->rq = NULL; hwif->rq = NULL;
} else { } else {
...@@ -718,8 +719,7 @@ out_end: ...@@ -718,8 +719,7 @@ out_end:
/* make sure it's fully ended */ /* make sure it's fully ended */
if (blk_fs_request(rq) == 0) { if (blk_fs_request(rq) == 0) {
rq->resid_len = blk_rq_bytes(rq) - rq->resid_len -= cmd->nbytes - cmd->nleft;
(cmd->nbytes - cmd->nleft);
if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE)) if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE))
rq->resid_len += cmd->last_xfer_len; rq->resid_len += cmd->last_xfer_len;
} }
......
...@@ -380,7 +380,7 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) ...@@ -380,7 +380,7 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc)
} }
tape->first_frame += blocks; tape->first_frame += blocks;
rq->resid_len = blk_rq_bytes(rq) - blocks * tape->blk_size; rq->resid_len -= blocks * tape->blk_size;
if (pc->error) { if (pc->error) {
uptodate = 0; uptodate = 0;
......
...@@ -1357,7 +1357,8 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, ...@@ -1357,7 +1357,8 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply; smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
memcpy(req->sense, smprep, sizeof(*smprep)); memcpy(req->sense, smprep, sizeof(*smprep));
req->sense_len = sizeof(*smprep); req->sense_len = sizeof(*smprep);
rsp->resid_len = blk_rq_bytes(rsp) - smprep->ResponseDataLength; req->resid_len = 0;
rsp->resid_len -= smprep->ResponseDataLength;
} else { } else {
printk(MYIOC_s_ERR_FMT "%s: smp passthru reply failed to be returned\n", printk(MYIOC_s_ERR_FMT "%s: smp passthru reply failed to be returned\n",
ioc->name, __func__); ioc->name, __func__);
......
...@@ -1937,7 +1937,11 @@ int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, ...@@ -1937,7 +1937,11 @@ int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
if (ret > 0) { if (ret > 0) {
/* positive number is the untransferred residual */ /* positive number is the untransferred residual */
rsp->resid_len = ret; rsp->resid_len = ret;
req->resid_len = 0;
ret = 0; ret = 0;
} else if (ret == 0) {
rsp->resid_len = 0;
req->resid_len = 0;
} }
return ret; return ret;
......
...@@ -176,9 +176,6 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req, ...@@ -176,9 +176,6 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
resp_data[1] = req_data[1]; resp_data[1] = req_data[1];
resp_data[2] = SMP_RESP_FUNC_UNK; resp_data[2] = SMP_RESP_FUNC_UNK;
req->resid_len = blk_rq_bytes(req);
rsp->resid_len = blk_rq_bytes(rsp);
switch (req_data[1]) { switch (req_data[1]) {
case SMP_REPORT_GENERAL: case SMP_REPORT_GENERAL:
req->resid_len -= 8; req->resid_len -= 8;
......
...@@ -1170,8 +1170,8 @@ transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, ...@@ -1170,8 +1170,8 @@ transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
memcpy(req->sense, mpi_reply, sizeof(*mpi_reply)); memcpy(req->sense, mpi_reply, sizeof(*mpi_reply));
req->sense_len = sizeof(*mpi_reply); req->sense_len = sizeof(*mpi_reply);
rsp->resid_len = blk_rq_bytes(rsp) - req->resid_len = 0;
mpi_reply->ResponseDataLength; rsp->resid_len -= mpi_reply->ResponseDataLength;
} else { } else {
dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT
"%s - no reply\n", ioc->name, __func__)); "%s - no reply\n", ioc->name, __func__));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment