diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2007-12-29 17:59:53 +0100 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-01-12 01:29:13 +0100 |
commit | 2d507a01dac338831266b44ccbb01c69e84606ed (patch) | |
tree | ec59ce6bc1ec86e93d1683107d41b5dbce0b370a /block | |
parent | [SCSI] libsas: don't treat underrun as an error on SMP tasks (diff) | |
download | linux-2d507a01dac338831266b44ccbb01c69e84606ed.tar.xz linux-2d507a01dac338831266b44ccbb01c69e84606ed.zip |
[SCSI] libsas, bsg: pass errors through correctly
Currently in BSG, errors returned in req->errors aren't passed back to
the calling programme (either via SG_IO or via read/write). Fix this,
while preserving the SCSI convention of returning status in
req->errors.
Now update libsas to return errors correctly instead of to ignore
them.
Acked-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'block')
-rw-r--r-- | block/bsg.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/block/bsg.c b/block/bsg.c index 8e181ab3afb9..69b0a9d33306 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -445,6 +445,15 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, else hdr->dout_resid = rq->data_len; + /* + * If the request generated a negative error number, return it + * (providing we aren't already returning an error); if it's + * just a protocol response (i.e. non negative), that gets + * processed above. + */ + if (!ret && rq->errors < 0) + ret = rq->errors; + blk_rq_unmap_user(bio); blk_put_request(rq); @@ -837,6 +846,7 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct bsg_device *bd = file->private_data; int __user *uarg = (int __user *) arg; + int ret; switch (cmd) { /* @@ -889,12 +899,12 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (rq->next_rq) bidi_bio = rq->next_rq->bio; blk_execute_rq(bd->queue, NULL, rq, 0); - blk_complete_sgv4_hdr_rq(rq, &hdr, bio, bidi_bio); + ret = blk_complete_sgv4_hdr_rq(rq, &hdr, bio, bidi_bio); if (copy_to_user(uarg, &hdr, sizeof(hdr))) return -EFAULT; - return 0; + return ret; } /* * block device ioctls |