aboutsummaryrefslogtreecommitdiffstats
path: root/sound/oss
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2014-01-02 07:07:49 -0500
committerTakashi Iwai <tiwai@suse.de>2014-01-14 10:01:27 -0500
commit7bd6972a921e148beea54919a00aa7b0bf046ff1 (patch)
tree37e0f74ceba884d3a2af13b8bf7e8d2a412619c9 /sound/oss
parent1a21576562507b2b10b9aa53555857868fe51c94 (diff)
sound: oss: vwsnd: avoid interruptible_sleep_on
Interruptible_sleep_on is racy and we want to remove it. This replaces the use in the vwsnd driver with an open-coded prepare_to_wait loop that fixes the race between concurrent open() and close() calls, and also drops the global mutex while waiting here, which restores the original behavior that was changed during the BKL removal. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/oss')
-rw-r--r--sound/oss/vwsnd.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c
index 4bbcc0fcd4eb..a077e9c69a5e 100644
--- a/sound/oss/vwsnd.c
+++ b/sound/oss/vwsnd.c
@@ -2921,6 +2921,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
2921 vwsnd_dev_t *devc; 2921 vwsnd_dev_t *devc;
2922 int minor = iminor(inode); 2922 int minor = iminor(inode);
2923 int sw_samplefmt; 2923 int sw_samplefmt;
2924 DEFINE_WAIT(wait);
2924 2925
2925 DBGE("(inode=0x%p, file=0x%p)\n", inode, file); 2926 DBGE("(inode=0x%p, file=0x%p)\n", inode, file);
2926 2927
@@ -2937,21 +2938,26 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
2937 } 2938 }
2938 2939
2939 mutex_lock(&devc->open_mutex); 2940 mutex_lock(&devc->open_mutex);
2940 while (devc->open_mode & file->f_mode) { 2941 while (1) {
2942 prepare_to_wait(&devc->open_wait, &wait, TASK_INTERRUPTIBLE);
2943 if (!(devc->open_mode & file->f_mode))
2944 break;
2945
2941 mutex_unlock(&devc->open_mutex); 2946 mutex_unlock(&devc->open_mutex);
2947 mutex_unlock(&vwsnd_mutex);
2942 if (file->f_flags & O_NONBLOCK) { 2948 if (file->f_flags & O_NONBLOCK) {
2943 DEC_USE_COUNT; 2949 DEC_USE_COUNT;
2944 mutex_unlock(&vwsnd_mutex);
2945 return -EBUSY; 2950 return -EBUSY;
2946 } 2951 }
2947 interruptible_sleep_on(&devc->open_wait); 2952 schedule();
2948 if (signal_pending(current)) { 2953 if (signal_pending(current)) {
2949 DEC_USE_COUNT; 2954 DEC_USE_COUNT;
2950 mutex_unlock(&vwsnd_mutex);
2951 return -ERESTARTSYS; 2955 return -ERESTARTSYS;
2952 } 2956 }
2957 mutex_lock(&vwsnd_mutex);
2953 mutex_lock(&devc->open_mutex); 2958 mutex_lock(&devc->open_mutex);
2954 } 2959 }
2960 finish_wait(&devc->open_wait, &wait);
2955 devc->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); 2961 devc->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
2956 mutex_unlock(&devc->open_mutex); 2962 mutex_unlock(&devc->open_mutex);
2957 2963