diff options
Diffstat (limited to 'drivers/scsi/sr.c')
-rw-r--r-- | drivers/scsi/sr.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 0a90abc7f140..ba9c3e0387ce 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/init.h> | 44 | #include <linux/init.h> |
45 | #include <linux/blkdev.h> | 45 | #include <linux/blkdev.h> |
46 | #include <linux/mutex.h> | 46 | #include <linux/mutex.h> |
47 | #include <linux/smp_lock.h> | ||
47 | #include <linux/slab.h> | 48 | #include <linux/slab.h> |
48 | #include <asm/uaccess.h> | 49 | #include <asm/uaccess.h> |
49 | 50 | ||
@@ -466,22 +467,27 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq) | |||
466 | 467 | ||
467 | static int sr_block_open(struct block_device *bdev, fmode_t mode) | 468 | static int sr_block_open(struct block_device *bdev, fmode_t mode) |
468 | { | 469 | { |
469 | struct scsi_cd *cd = scsi_cd_get(bdev->bd_disk); | 470 | struct scsi_cd *cd; |
470 | int ret = -ENXIO; | 471 | int ret = -ENXIO; |
471 | 472 | ||
473 | lock_kernel(); | ||
474 | cd = scsi_cd_get(bdev->bd_disk); | ||
472 | if (cd) { | 475 | if (cd) { |
473 | ret = cdrom_open(&cd->cdi, bdev, mode); | 476 | ret = cdrom_open(&cd->cdi, bdev, mode); |
474 | if (ret) | 477 | if (ret) |
475 | scsi_cd_put(cd); | 478 | scsi_cd_put(cd); |
476 | } | 479 | } |
480 | unlock_kernel(); | ||
477 | return ret; | 481 | return ret; |
478 | } | 482 | } |
479 | 483 | ||
480 | static int sr_block_release(struct gendisk *disk, fmode_t mode) | 484 | static int sr_block_release(struct gendisk *disk, fmode_t mode) |
481 | { | 485 | { |
482 | struct scsi_cd *cd = scsi_cd(disk); | 486 | struct scsi_cd *cd = scsi_cd(disk); |
487 | lock_kernel(); | ||
483 | cdrom_release(&cd->cdi, mode); | 488 | cdrom_release(&cd->cdi, mode); |
484 | scsi_cd_put(cd); | 489 | scsi_cd_put(cd); |
490 | unlock_kernel(); | ||
485 | return 0; | 491 | return 0; |
486 | } | 492 | } |
487 | 493 | ||
@@ -493,6 +499,8 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, | |||
493 | void __user *argp = (void __user *)arg; | 499 | void __user *argp = (void __user *)arg; |
494 | int ret; | 500 | int ret; |
495 | 501 | ||
502 | lock_kernel(); | ||
503 | |||
496 | /* | 504 | /* |
497 | * Send SCSI addressing ioctls directly to mid level, send other | 505 | * Send SCSI addressing ioctls directly to mid level, send other |
498 | * ioctls to cdrom/block level. | 506 | * ioctls to cdrom/block level. |
@@ -500,12 +508,13 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, | |||
500 | switch (cmd) { | 508 | switch (cmd) { |
501 | case SCSI_IOCTL_GET_IDLUN: | 509 | case SCSI_IOCTL_GET_IDLUN: |
502 | case SCSI_IOCTL_GET_BUS_NUMBER: | 510 | case SCSI_IOCTL_GET_BUS_NUMBER: |
503 | return scsi_ioctl(sdev, cmd, argp); | 511 | ret = scsi_ioctl(sdev, cmd, argp); |
512 | goto out; | ||
504 | } | 513 | } |
505 | 514 | ||
506 | ret = cdrom_ioctl(&cd->cdi, bdev, mode, cmd, arg); | 515 | ret = cdrom_ioctl(&cd->cdi, bdev, mode, cmd, arg); |
507 | if (ret != -ENOSYS) | 516 | if (ret != -ENOSYS) |
508 | return ret; | 517 | goto out; |
509 | 518 | ||
510 | /* | 519 | /* |
511 | * ENODEV means that we didn't recognise the ioctl, or that we | 520 | * ENODEV means that we didn't recognise the ioctl, or that we |
@@ -516,8 +525,12 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, | |||
516 | ret = scsi_nonblockable_ioctl(sdev, cmd, argp, | 525 | ret = scsi_nonblockable_ioctl(sdev, cmd, argp, |
517 | (mode & FMODE_NDELAY) != 0); | 526 | (mode & FMODE_NDELAY) != 0); |
518 | if (ret != -ENODEV) | 527 | if (ret != -ENODEV) |
519 | return ret; | 528 | goto out; |
520 | return scsi_ioctl(sdev, cmd, argp); | 529 | ret = scsi_ioctl(sdev, cmd, argp); |
530 | |||
531 | out: | ||
532 | unlock_kernel(); | ||
533 | return ret; | ||
521 | } | 534 | } |
522 | 535 | ||
523 | static int sr_block_media_changed(struct gendisk *disk) | 536 | static int sr_block_media_changed(struct gendisk *disk) |
@@ -531,7 +544,7 @@ static const struct block_device_operations sr_bdops = | |||
531 | .owner = THIS_MODULE, | 544 | .owner = THIS_MODULE, |
532 | .open = sr_block_open, | 545 | .open = sr_block_open, |
533 | .release = sr_block_release, | 546 | .release = sr_block_release, |
534 | .locked_ioctl = sr_block_ioctl, | 547 | .ioctl = sr_block_ioctl, |
535 | .media_changed = sr_block_media_changed, | 548 | .media_changed = sr_block_media_changed, |
536 | /* | 549 | /* |
537 | * No compat_ioctl for now because sr_block_ioctl never | 550 | * No compat_ioctl for now because sr_block_ioctl never |