Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7bd6972a authored by Arnd Bergmann's avatar Arnd Bergmann Committed by Takashi Iwai
Browse files

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: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 1a215765
Loading
Loading
Loading
Loading
+10 −4
Original line number Original line Diff line number Diff line
@@ -2921,6 +2921,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
	vwsnd_dev_t *devc;
	vwsnd_dev_t *devc;
	int minor = iminor(inode);
	int minor = iminor(inode);
	int sw_samplefmt;
	int sw_samplefmt;
	DEFINE_WAIT(wait);


	DBGE("(inode=0x%p, file=0x%p)\n", inode, file);
	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);
	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(&devc->open_mutex);
		mutex_unlock(&vwsnd_mutex);
		if (file->f_flags & O_NONBLOCK) {
		if (file->f_flags & O_NONBLOCK) {
			DEC_USE_COUNT;
			DEC_USE_COUNT;
			mutex_unlock(&vwsnd_mutex);
			return -EBUSY;
			return -EBUSY;
		}
		}
		interruptible_sleep_on(&devc->open_wait);
		schedule();
		if (signal_pending(current)) {
		if (signal_pending(current)) {
			DEC_USE_COUNT;
			DEC_USE_COUNT;
			mutex_unlock(&vwsnd_mutex);
			return -ERESTARTSYS;
			return -ERESTARTSYS;
		}
		}
		mutex_lock(&vwsnd_mutex);
		mutex_lock(&devc->open_mutex);
		mutex_lock(&devc->open_mutex);
	}
	}
	finish_wait(&devc->open_wait, &wait);
	devc->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
	devc->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
	mutex_unlock(&devc->open_mutex);
	mutex_unlock(&devc->open_mutex);