X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=block%2Fscsi_ioctl.c;h=e83f1dbf7c29a12563d18da1ae355929dcdde06e;hb=9d399cc7feac3faf66768566e04e16c750aad25f;hp=e55a756214375577ffa942dbc239fe79e87985fe;hpb=097b8457dafe7efc22201b4062e2d1e82e494067;p=safe%2Fjmp%2Flinux-2.6 diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index e55a756..e83f1db 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -78,7 +78,9 @@ static int sg_set_timeout(request_queue_t *q, int __user *p) static int sg_get_reserved_size(request_queue_t *q, int __user *p) { - return put_user(q->sg_reserved_size, p); + unsigned val = min(q->sg_reserved_size, q->max_sectors << 9); + + return put_user(val, p); } static int sg_set_reserved_size(request_queue_t *q, int __user *p) @@ -223,12 +225,12 @@ static int verify_command(struct file *file, unsigned char *cmd) static int sg_io(struct file *file, request_queue_t *q, struct gendisk *bd_disk, struct sg_io_hdr *hdr) { - unsigned long start_time; + unsigned long start_time, timeout; int writing = 0, ret = 0; struct request *rq; - struct bio *bio; char sense[SCSI_SENSE_BUFFERSIZE]; unsigned char cmd[BLK_MAX_CDB]; + struct bio *bio; if (hdr->interface_id != 'S') return -EINVAL; @@ -258,6 +260,26 @@ static int sg_io(struct file *file, request_queue_t *q, if (!rq) return -ENOMEM; + /* + * fill in request structure + */ + rq->cmd_len = hdr->cmd_len; + memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */ + memcpy(rq->cmd, cmd, hdr->cmd_len); + + memset(sense, 0, sizeof(sense)); + rq->sense = sense; + rq->sense_len = 0; + + rq->cmd_type = REQ_TYPE_BLOCK_PC; + + timeout = msecs_to_jiffies(hdr->timeout); + rq->timeout = (timeout < INT_MAX) ? timeout : INT_MAX; + if (!rq->timeout) + rq->timeout = q->sg_timeout; + if (!rq->timeout) + rq->timeout = BLK_DEFAULT_TIMEOUT; + if (hdr->iovec_count) { const int size = sizeof(struct sg_iovec) * hdr->iovec_count; struct sg_iovec *iov; @@ -274,7 +296,8 @@ static int sg_io(struct file *file, request_queue_t *q, goto out; } - ret = blk_rq_map_user_iov(q, rq, iov, hdr->iovec_count); + ret = blk_rq_map_user_iov(q, rq, iov, hdr->iovec_count, + hdr->dxfer_len); kfree(iov); } else if (hdr->dxfer_len) ret = blk_rq_map_user(q, rq, hdr->dxferp, hdr->dxfer_len); @@ -282,33 +305,7 @@ static int sg_io(struct file *file, request_queue_t *q, if (ret) goto out; - /* - * fill in request structure - */ - rq->cmd_len = hdr->cmd_len; - memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */ - memcpy(rq->cmd, cmd, hdr->cmd_len); - - memset(sense, 0, sizeof(sense)); - rq->sense = sense; - rq->sense_len = 0; - - rq->cmd_type = REQ_TYPE_BLOCK_PC; bio = rq->bio; - - /* - * bounce this after holding a reference to the original bio, it's - * needed for proper unmapping - */ - if (rq->bio) - blk_queue_bounce(q, &rq->bio); - - rq->timeout = (hdr->timeout * HZ) / 1000; - if (!rq->timeout) - rq->timeout = q->sg_timeout; - if (!rq->timeout) - rq->timeout = BLK_DEFAULT_TIMEOUT; - rq->retries = 0; start_time = jiffies; @@ -339,7 +336,7 @@ static int sg_io(struct file *file, request_queue_t *q, hdr->sb_len_wr = len; } - if (blk_rq_unmap_user(bio, hdr->dxfer_len)) + if (blk_rq_unmap_user(bio)) ret = -EFAULT; /* may not have succeeded, but output values written to control