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 <[email protected]>
Cc: Jaroslav Kysela <[email protected]>
Cc: Takashi Iwai <[email protected]>
Cc: [email protected]
---
 sound/oss/vwsnd.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c
index 4bbcc0f..a077e9c 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)
        vwsnd_dev_t *devc;
        int minor = iminor(inode);
        int sw_samplefmt;
+       DEFINE_WAIT(wait);
 
        DBGE("(inode=0x%p, file=0x%p)\n", inode, file);
 
@@ -2937,21 +2938,26 @@ static int vwsnd_audio_open(struct inode *inode, struct 
file *file)
        }
 
        mutex_lock(&devc->open_mutex);
-       while (devc->open_mode & file->f_mode) {
+       while (1) {
+               prepare_to_wait(&devc->open_wait, &wait, TASK_INTERRUPTIBLE);
+               if (!(devc->open_mode & file->f_mode))
+                       break;
+
                mutex_unlock(&devc->open_mutex);
+               mutex_unlock(&vwsnd_mutex);
                if (file->f_flags & O_NONBLOCK) {
                        DEC_USE_COUNT;
-                       mutex_unlock(&vwsnd_mutex);
                        return -EBUSY;
                }
-               interruptible_sleep_on(&devc->open_wait);
+               schedule();
                if (signal_pending(current)) {
                        DEC_USE_COUNT;
-                       mutex_unlock(&vwsnd_mutex);
                        return -ERESTARTSYS;
                }
+               mutex_lock(&vwsnd_mutex);
                mutex_lock(&devc->open_mutex);
        }
+       finish_wait(&devc->open_wait, &wait);
        devc->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
        mutex_unlock(&devc->open_mutex);
 
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to