From: Jens Axboe <axboe@suse.de>
To: Markus Plail <linux-kernel@gitteundmarkus.de>,
Linux Kernel <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] SG_IO readcd and various bugs
Date: Fri, 30 May 2003 16:58:45 +0200 [thread overview]
Message-ID: <20030530145845.GI813@suse.de> (raw)
In-Reply-To: <874r3cpmmv.fsf@gitteundmarkus.de>
On Fri, May 30 2003, Markus Plail wrote:
> On Fri, 30 May 2003, Markus Plail wrote:
>
> > The patch makes readcd work just fine here :-) Many thanks!
>
> Just realized that C2 scans don't yet work.
Updated patch, please give that a shot. These sense_len wasn't being set
correctly.
===== drivers/block/ioctl.c 1.54 vs edited =====
--- 1.54/drivers/block/ioctl.c Sat Apr 26 00:16:28 2003
+++ edited/drivers/block/ioctl.c Fri May 30 10:25:55 2003
@@ -207,11 +207,8 @@
set_device_ro(bdev, n);
return 0;
default:
- if (disk->fops->ioctl) {
- ret = disk->fops->ioctl(inode, file, cmd, arg);
- if (ret != -EINVAL)
- return ret;
- }
+ if (disk->fops->ioctl)
+ return disk->fops->ioctl(inode, file, cmd, arg);
}
return -ENOTTY;
}
===== drivers/block/scsi_ioctl.c 1.27 vs edited =====
--- 1.27/drivers/block/scsi_ioctl.c Sat May 17 12:05:21 2003
+++ edited/drivers/block/scsi_ioctl.c Fri May 30 16:57:36 2003
@@ -68,7 +68,6 @@
rq->flags |= REQ_NOMERGE;
rq->waiting = &wait;
- drive_stat_acct(rq, rq->nr_sectors, 1);
elv_add_request(q, rq, 1, 1);
generic_unplug_device(q);
wait_for_completion(&wait);
@@ -99,7 +98,7 @@
static int sg_get_timeout(request_queue_t *q)
{
- return q->sg_timeout;
+ return q->sg_timeout / (HZ / USER_HZ);
}
static int sg_set_timeout(request_queue_t *q, int *p)
@@ -107,7 +106,7 @@
int timeout, err = get_user(timeout, p);
if (!err)
- q->sg_timeout = timeout;
+ q->sg_timeout = timeout * (HZ / USER_HZ);
return err;
}
@@ -121,10 +120,14 @@
{
int size, err = get_user(size, p);
- if (!err)
- q->sg_reserved_size = size;
+ if (err)
+ return err;
- return err;
+ if (size > (q->max_sectors << 9))
+ return -EINVAL;
+
+ q->sg_reserved_size = size;
+ return 0;
}
/*
@@ -139,16 +142,14 @@
static int sg_io(request_queue_t *q, struct block_device *bdev,
struct sg_io_hdr *uptr)
{
- unsigned long uaddr, start_time;
- int reading, writing, nr_sectors;
+ unsigned long start_time;
+ int reading, writing;
struct sg_io_hdr hdr;
struct request *rq;
struct bio *bio;
char sense[SCSI_SENSE_BUFFERSIZE];
void *buffer;
- if (!access_ok(VERIFY_WRITE, uptr, sizeof(*uptr)))
- return -EFAULT;
if (copy_from_user(&hdr, uptr, sizeof(*uptr)))
return -EFAULT;
@@ -156,11 +157,6 @@
return -EINVAL;
if (hdr.cmd_len > sizeof(rq->cmd))
return -EINVAL;
- if (!access_ok(VERIFY_READ, hdr.cmdp, hdr.cmd_len))
- return -EFAULT;
-
- if (hdr.dxfer_len > 65536)
- return -EINVAL;
/*
* we'll do that later
@@ -168,7 +164,9 @@
if (hdr.iovec_count)
return -EOPNOTSUPP;
- nr_sectors = 0;
+ if (hdr.dxfer_len > (q->max_sectors << 9))
+ return -EIO;
+
reading = writing = 0;
buffer = NULL;
bio = NULL;
@@ -189,19 +187,12 @@
break;
}
- uaddr = (unsigned long) hdr.dxferp;
- /* writing to device -> reading from vm */
- if (writing && !access_ok(VERIFY_READ, uaddr, bytes))
- return -EFAULT;
- /* reading from device -> writing to vm */
- else if (reading && !access_ok(VERIFY_WRITE, uaddr, bytes))
- return -EFAULT;
-
/*
* first try to map it into a bio. reading from device will
* be a write to vm.
*/
- bio = bio_map_user(bdev, uaddr, hdr.dxfer_len, reading);
+ bio = bio_map_user(bdev, (unsigned long) hdr.dxferp,
+ hdr.dxfer_len, reading);
/*
* if bio setup failed, fall back to slow approach
@@ -211,10 +202,11 @@
if (!buffer)
return -ENOMEM;
- nr_sectors = bytes >> 9;
- if (writing)
- copy_from_user(buffer,hdr.dxferp,hdr.dxfer_len);
- else
+ if (writing) {
+ if (copy_from_user(buffer, hdr.dxferp,
+ hdr.dxfer_len))
+ goto out_buffer;
+ } else
memset(buffer, 0, hdr.dxfer_len);
}
}
@@ -225,7 +217,8 @@
* fill in request structure
*/
rq->cmd_len = hdr.cmd_len;
- copy_from_user(rq->cmd, hdr.cmdp, hdr.cmd_len);
+ if (copy_from_user(rq->cmd, hdr.cmdp, hdr.cmd_len))
+ goto out_request;
if (sizeof(rq->cmd) != hdr.cmd_len)
memset(rq->cmd + hdr.cmd_len, 0, sizeof(rq->cmd) - hdr.cmd_len);
@@ -235,18 +228,15 @@
rq->flags |= REQ_BLOCK_PC;
- rq->hard_nr_sectors = rq->nr_sectors = nr_sectors;
- rq->hard_cur_sectors = rq->current_nr_sectors = nr_sectors;
-
- rq->bio = rq->biotail = bio;
+ rq->bio = rq->biotail = NULL;
if (bio)
blk_rq_bio_prep(q, rq, bio);
- rq->data_len = hdr.dxfer_len;
rq->data = buffer;
+ rq->data_len = hdr.dxfer_len;
- rq->timeout = hdr.timeout;
+ rq->timeout = (hdr.timeout * HZ) / 1000;
if (!rq->timeout)
rq->timeout = q->sg_timeout;
if (!rq->timeout)
@@ -273,12 +263,11 @@
if (hdr.masked_status || hdr.host_status || hdr.driver_status)
hdr.info |= SG_INFO_CHECK;
hdr.resid = rq->data_len;
- hdr.duration = (jiffies - start_time) * (1000 / HZ);
+ hdr.duration = ((jiffies - start_time) * 1000) / HZ;
hdr.sb_len_wr = 0;
if (rq->sense_len && hdr.sbp) {
- int len = (hdr.mx_sb_len < rq->sense_len) ?
- hdr.mx_sb_len : rq->sense_len;
+ int len = min((unsigned int) hdr.mx_sb_len, rq->sense_len);
if (!copy_to_user(hdr.sbp, rq->sense, len))
hdr.sb_len_wr = len;
@@ -286,17 +275,25 @@
blk_put_request(rq);
- copy_to_user(uptr, &hdr, sizeof(*uptr));
+ if (copy_to_user(uptr, &hdr, sizeof(*uptr)))
+ goto out_buffer;
if (buffer) {
if (reading)
- copy_to_user(hdr.dxferp, buffer, hdr.dxfer_len);
+ if (copy_to_user(hdr.dxferp, buffer, hdr.dxfer_len))
+ goto out_buffer;
kfree(buffer);
}
+
/* may not have succeeded, but output values written to control
* structure (struct sg_io_hdr). */
return 0;
+out_request:
+ blk_put_request(rq);
+out_buffer:
+ kfree(buffer);
+ return -EFAULT;
}
#define FORMAT_UNIT_TIMEOUT (2 * 60 * 60 * HZ)
===== drivers/ide/ide-cd.c 1.46 vs edited =====
--- 1.46/drivers/ide/ide-cd.c Thu May 8 10:39:34 2003
+++ edited/drivers/ide/ide-cd.c Fri May 30 16:54:11 2003
@@ -666,8 +666,10 @@
struct cdrom_info *info = drive->driver_data;
void *sense = &info->sense_data;
- if (failed && failed->sense)
+ if (failed && failed->sense) {
sense = failed->sense;
+ failed->sense_len = rq->sense_len;
+ }
cdrom_analyze_sense_data(drive, failed, sense);
}
@@ -723,7 +725,7 @@
* scsi status byte
*/
if ((rq->flags & REQ_BLOCK_PC) && !rq->errors)
- rq->errors = CHECK_CONDITION;
+ rq->errors = SAM_STAT_CHECK_CONDITION;
/* Check for tray open. */
if (sense_key == NOT_READY) {
@@ -1471,8 +1476,9 @@
/* Keep count of how much data we've moved. */
rq->data += thislen;
rq->data_len -= thislen;
- if (rq->cmd[0] == GPCMD_REQUEST_SENSE)
- rq->sense_len++;
+
+ if (rq->flags & REQ_SENSE)
+ rq->sense_len += thislen;
} else {
confused:
printk ("%s: cdrom_pc_intr: The drive "
@@ -1609,10 +1615,18 @@
static void post_transform_command(struct request *req)
{
- char *ibuf = req->buffer;
u8 *c = req->cmd;
+ char *ibuf;
if (!blk_pc_request(req))
+ return;
+
+ if (req->bio)
+ ibuf = bio_data(req->bio);
+ else
+ ibuf = req->data;
+
+ if (!ibuf)
return;
/*
===== fs/bio.c 1.45 vs edited =====
--- 1.45/fs/bio.c Tue May 27 03:53:39 2003
+++ edited/fs/bio.c Fri May 30 14:32:56 2003
@@ -538,12 +538,6 @@
bio = __bio_map_user(bdev, uaddr, len, write_to_vm);
if (bio) {
- if (bio->bi_size < len) {
- bio_endio(bio, bio->bi_size, 0);
- bio_unmap_user(bio, 0);
- return NULL;
- }
-
/*
* subtle -- if __bio_map_user() ended up bouncing a bio,
* it would normally disappear when its bi_end_io is run.
@@ -551,6 +545,12 @@
* reference to it
*/
bio_get(bio);
+
+ if (bio->bi_size < len) {
+ bio_endio(bio, bio->bi_size, 0);
+ bio_unmap_user(bio, 0);
+ return NULL;
+ }
}
return bio;
--
Jens Axboe
next prev parent reply other threads:[~2003-05-30 14:45 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-05-30 13:02 [PATCH] SG_IO readcd and various bugs Jens Axboe
2003-05-30 13:47 ` Markus Plail
2003-05-30 13:52 ` Markus Plail
2003-05-30 14:58 ` Jens Axboe [this message]
2003-05-30 16:57 ` Markus Plail
2003-06-01 7:50 ` uaca
2003-06-01 9:18 ` Markus Plail
2003-06-01 10:19 ` uaca
-- strict thread matches above, loose matches on Subject: below --
2003-05-31 8:23 Douglas Gilbert
2003-05-31 10:57 ` Jens Axboe
2003-06-01 7:39 ` Douglas Gilbert
2003-06-02 7:27 ` Jens Axboe
2003-06-03 5:23 ` Douglas Gilbert
2003-06-03 5:39 ` Nick Piggin
2003-06-03 8:29 ` Jens Axboe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20030530145845.GI813@suse.de \
--to=axboe@suse.de \
--cc=linux-kernel@gitteundmarkus.de \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.