aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/sr.c')
-rw-r--r--drivers/scsi/sr.c25
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
467static int sr_block_open(struct block_device *bdev, fmode_t mode) 468static 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
480static int sr_block_release(struct gendisk *disk, fmode_t mode) 484static 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
531out:
532 unlock_kernel();
533 return ret;
521} 534}
522 535
523static int sr_block_media_changed(struct gendisk *disk) 536static 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