aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/char/vmur.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/char/vmur.c')
-rw-r--r--drivers/s390/char/vmur.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c
index 7689b500a104..83ae9a852f00 100644
--- a/drivers/s390/char/vmur.c
+++ b/drivers/s390/char/vmur.c
@@ -100,7 +100,8 @@ static struct urdev *urdev_alloc(struct ccw_device *cdev)
100 urd->reclen = cdev->id.driver_info; 100 urd->reclen = cdev->id.driver_info;
101 ccw_device_get_id(cdev, &urd->dev_id); 101 ccw_device_get_id(cdev, &urd->dev_id);
102 mutex_init(&urd->io_mutex); 102 mutex_init(&urd->io_mutex);
103 mutex_init(&urd->open_mutex); 103 init_waitqueue_head(&urd->wait);
104 spin_lock_init(&urd->open_lock);
104 atomic_set(&urd->ref_count, 1); 105 atomic_set(&urd->ref_count, 1);
105 urd->cdev = cdev; 106 urd->cdev = cdev;
106 get_device(&cdev->dev); 107 get_device(&cdev->dev);
@@ -678,17 +679,21 @@ static int ur_open(struct inode *inode, struct file *file)
678 if (!urd) 679 if (!urd)
679 return -ENXIO; 680 return -ENXIO;
680 681
681 if (file->f_flags & O_NONBLOCK) { 682 spin_lock(&urd->open_lock);
682 if (!mutex_trylock(&urd->open_mutex)) { 683 while (urd->open_flag) {
684 spin_unlock(&urd->open_lock);
685 if (file->f_flags & O_NONBLOCK) {
683 rc = -EBUSY; 686 rc = -EBUSY;
684 goto fail_put; 687 goto fail_put;
685 } 688 }
686 } else { 689 if (wait_event_interruptible(urd->wait, urd->open_flag == 0)) {
687 if (mutex_lock_interruptible(&urd->open_mutex)) {
688 rc = -ERESTARTSYS; 690 rc = -ERESTARTSYS;
689 goto fail_put; 691 goto fail_put;
690 } 692 }
693 spin_lock(&urd->open_lock);
691 } 694 }
695 urd->open_flag++;
696 spin_unlock(&urd->open_lock);
692 697
693 TRACE("ur_open\n"); 698 TRACE("ur_open\n");
694 699
@@ -720,7 +725,9 @@ static int ur_open(struct inode *inode, struct file *file)
720fail_urfile_free: 725fail_urfile_free:
721 urfile_free(urf); 726 urfile_free(urf);
722fail_unlock: 727fail_unlock:
723 mutex_unlock(&urd->open_mutex); 728 spin_lock(&urd->open_lock);
729 urd->open_flag--;
730 spin_unlock(&urd->open_lock);
724fail_put: 731fail_put:
725 urdev_put(urd); 732 urdev_put(urd);
726 return rc; 733 return rc;
@@ -731,7 +738,10 @@ static int ur_release(struct inode *inode, struct file *file)
731 struct urfile *urf = file->private_data; 738 struct urfile *urf = file->private_data;
732 739
733 TRACE("ur_release\n"); 740 TRACE("ur_release\n");
734 mutex_unlock(&urf->urd->open_mutex); 741 spin_lock(&urf->urd->open_lock);
742 urf->urd->open_flag--;
743 spin_unlock(&urf->urd->open_lock);
744 wake_up_interruptible(&urf->urd->wait);
735 urdev_put(urf->urd); 745 urdev_put(urf->urd);
736 urfile_free(urf); 746 urfile_free(urf);
737 return 0; 747 return 0;