diff options
Diffstat (limited to 'drivers/block/scsi_ioctl.c')
-rw-r--r-- | drivers/block/scsi_ioctl.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/drivers/block/scsi_ioctl.c b/drivers/block/scsi_ioctl.c index 681871ca5d60..93c4ca874be3 100644 --- a/drivers/block/scsi_ioctl.c +++ b/drivers/block/scsi_ioctl.c | |||
@@ -216,7 +216,7 @@ static int sg_io(struct file *file, request_queue_t *q, | |||
216 | struct gendisk *bd_disk, struct sg_io_hdr *hdr) | 216 | struct gendisk *bd_disk, struct sg_io_hdr *hdr) |
217 | { | 217 | { |
218 | unsigned long start_time; | 218 | unsigned long start_time; |
219 | int reading, writing; | 219 | int reading, writing, ret; |
220 | struct request *rq; | 220 | struct request *rq; |
221 | struct bio *bio; | 221 | struct bio *bio; |
222 | char sense[SCSI_SENSE_BUFFERSIZE]; | 222 | char sense[SCSI_SENSE_BUFFERSIZE]; |
@@ -255,14 +255,17 @@ static int sg_io(struct file *file, request_queue_t *q, | |||
255 | reading = 1; | 255 | reading = 1; |
256 | break; | 256 | break; |
257 | } | 257 | } |
258 | } | ||
258 | 259 | ||
259 | rq = blk_rq_map_user(q, writing ? WRITE : READ, hdr->dxferp, | 260 | rq = blk_get_request(q, writing ? WRITE : READ, GFP_KERNEL); |
260 | hdr->dxfer_len); | 261 | if (!rq) |
262 | return -ENOMEM; | ||
261 | 263 | ||
262 | if (IS_ERR(rq)) | 264 | if (reading || writing) { |
263 | return PTR_ERR(rq); | 265 | ret = blk_rq_map_user(q, rq, hdr->dxferp, hdr->dxfer_len); |
264 | } else | 266 | if (ret) |
265 | rq = blk_get_request(q, READ, __GFP_WAIT); | 267 | goto out; |
268 | } | ||
266 | 269 | ||
267 | /* | 270 | /* |
268 | * fill in request structure | 271 | * fill in request structure |
@@ -321,11 +324,13 @@ static int sg_io(struct file *file, request_queue_t *q, | |||
321 | } | 324 | } |
322 | 325 | ||
323 | if (blk_rq_unmap_user(rq, bio, hdr->dxfer_len)) | 326 | if (blk_rq_unmap_user(rq, bio, hdr->dxfer_len)) |
324 | return -EFAULT; | 327 | ret = -EFAULT; |
325 | 328 | ||
326 | /* may not have succeeded, but output values written to control | 329 | /* may not have succeeded, but output values written to control |
327 | * structure (struct sg_io_hdr). */ | 330 | * structure (struct sg_io_hdr). */ |
328 | return 0; | 331 | out: |
332 | blk_put_request(rq); | ||
333 | return ret; | ||
329 | } | 334 | } |
330 | 335 | ||
331 | #define OMAX_SB_LEN 16 /* For backward compatibility */ | 336 | #define OMAX_SB_LEN 16 /* For backward compatibility */ |