diff options
Diffstat (limited to 'drivers/s390/char')
-rw-r--r-- | drivers/s390/char/tape.h | 3 | ||||
-rw-r--r-- | drivers/s390/char/tape_block.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/tape_char.c | 45 | ||||
-rw-r--r-- | drivers/s390/char/tape_core.c | 1 |
4 files changed, 29 insertions, 22 deletions
diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index fbe41e0377b..7a242f07363 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h @@ -212,6 +212,9 @@ struct tape_device { struct tape_class_device * nt; struct tape_class_device * rt; + /* Device mutex to serialize tape commands. */ + struct mutex mutex; + /* Device discipline information. */ struct tape_discipline * discipline; void * discdata; diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index c97c6aac8ed..4799cc2f73c 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c @@ -54,7 +54,7 @@ static const struct block_device_operations tapeblock_fops = { .owner = THIS_MODULE, .open = tapeblock_open, .release = tapeblock_release, - .locked_ioctl = tapeblock_ioctl, + .ioctl = tapeblock_ioctl, .media_changed = tapeblock_medium_changed, .revalidate_disk = tapeblock_revalidate_disk, }; diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c index d44e6981eea..23d773a0d11 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c @@ -33,8 +33,7 @@ static ssize_t tapechar_read(struct file *, char __user *, size_t, loff_t *); static ssize_t tapechar_write(struct file *, const char __user *, size_t, loff_t *); static int tapechar_open(struct inode *,struct file *); static int tapechar_release(struct inode *,struct file *); -static int tapechar_ioctl(struct inode *, struct file *, unsigned int, - unsigned long); +static long tapechar_ioctl(struct file *, unsigned int, unsigned long); static long tapechar_compat_ioctl(struct file *, unsigned int, unsigned long); @@ -43,7 +42,7 @@ static const struct file_operations tape_fops = .owner = THIS_MODULE, .read = tapechar_read, .write = tapechar_write, - .ioctl = tapechar_ioctl, + .unlocked_ioctl = tapechar_ioctl, .compat_ioctl = tapechar_compat_ioctl, .open = tapechar_open, .release = tapechar_release, @@ -284,26 +283,20 @@ tapechar_open (struct inode *inode, struct file *filp) if (imajor(filp->f_path.dentry->d_inode) != tapechar_major) return -ENODEV; - lock_kernel(); minor = iminor(filp->f_path.dentry->d_inode); device = tape_find_device(minor / TAPE_MINORS_PER_DEV); if (IS_ERR(device)) { DBF_EVENT(3, "TCHAR:open: tape_find_device() failed\n"); - rc = PTR_ERR(device); - goto out; + return PTR_ERR(device); } - rc = tape_open(device); if (rc == 0) { filp->private_data = device; - rc = nonseekable_open(inode, filp); - } - else + nonseekable_open(inode, filp); + } else tape_put_device(device); -out: - unlock_kernel(); return rc; } @@ -350,16 +343,11 @@ tapechar_release(struct inode *inode, struct file *filp) * Tape device io controls. */ static int -tapechar_ioctl(struct inode *inp, struct file *filp, - unsigned int no, unsigned long data) +__tapechar_ioctl(struct tape_device *device, + unsigned int no, unsigned long data) { - struct tape_device *device; int rc; - DBF_EVENT(6, "TCHAR:ioct\n"); - - device = (struct tape_device *) filp->private_data; - if (no == MTIOCTOP) { struct mtop op; @@ -452,15 +440,30 @@ tapechar_ioctl(struct inode *inp, struct file *filp, } static long +tapechar_ioctl(struct file *filp, unsigned int no, unsigned long data) +{ + struct tape_device *device; + long rc; + + DBF_EVENT(6, "TCHAR:ioct\n"); + + device = (struct tape_device *) filp->private_data; + mutex_lock(&device->mutex); + rc = __tapechar_ioctl(device, no, data); + mutex_unlock(&device->mutex); + return rc; +} + +static long tapechar_compat_ioctl(struct file *filp, unsigned int no, unsigned long data) { struct tape_device *device = filp->private_data; int rval = -ENOIOCTLCMD; if (device->discipline->ioctl_fn) { - lock_kernel(); + mutex_lock(&device->mutex); rval = device->discipline->ioctl_fn(device, no, data); - unlock_kernel(); + mutex_unlock(&device->mutex); if (rval == -EINVAL) rval = -ENOIOCTLCMD; } diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index a7b7e72c691..f5d6802dc5d 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c @@ -492,6 +492,7 @@ tape_alloc_device(void) kfree(device); return ERR_PTR(-ENOMEM); } + mutex_init(&device->mutex); INIT_LIST_HEAD(&device->req_queue); INIT_LIST_HEAD(&device->node); init_waitqueue_head(&device->state_change_wq); |