diff options
author | Karsten Wiese <fzu@wemgehoertderstaat.de> | 2007-01-31 09:05:30 (GMT) |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2007-02-09 08:03:24 (GMT) |
commit | 8fa58af7db56077d6a042fd7b9dd4c9515e1c37b (patch) | |
tree | 759062886223b266c4200e8abab82789a9c5ba62 | |
parent | 298a2c753a5ae2f0e230a57e94843d248f0033e2 (diff) | |
download | linux-8fa58af7db56077d6a042fd7b9dd4c9515e1c37b.tar.xz |
[ALSA] snd_hwdep_release() racefix
snd_card_file_remove() can free the snd_card.
Touch hw->* only before calling snd_card_file_remove().
Unrelated: Allow hwdep devices not to have own ops.release();
Signed-off-by: Karsten Wiese <fzu@wemgehoertderstaat.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
-rw-r--r-- | sound/core/hwdep.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c index a6a6ad0..39c03f3 100644 --- a/sound/core/hwdep.c +++ b/sound/core/hwdep.c @@ -156,15 +156,16 @@ static int snd_hwdep_release(struct inode *inode, struct file * file) int err = -ENXIO; struct snd_hwdep *hw = file->private_data; struct module *mod = hw->card->module; + mutex_lock(&hw->open_mutex); - if (hw->ops.release) { + if (hw->ops.release) err = hw->ops.release(hw, file); - wake_up(&hw->open_wait); - } if (hw->used > 0) hw->used--; - snd_card_file_remove(hw->card, file); mutex_unlock(&hw->open_mutex); + wake_up(&hw->open_wait); + + snd_card_file_remove(hw->card, file); module_put(mod); return err; } |