diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2009-08-17 12:27:22 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-08-17 12:48:15 +0200 |
commit | f217ac59b6dd73105abc13da3fe656391fa6d135 (patch) | |
tree | d0ff4a0dec41b603df76baec15ec51bf62146ee6 /sound/core/control.c | |
parent | 317b80817fcaeac7ae7e062fcccef0d2aba38a78 (diff) | |
download | linux-stable-f217ac59b6dd73105abc13da3fe656391fa6d135.tar.gz linux-stable-f217ac59b6dd73105abc13da3fe656391fa6d135.tar.bz2 linux-stable-f217ac59b6dd73105abc13da3fe656391fa6d135.zip |
sound: snd_ctl_remove_unlocked_id: simplify user control counting
Move the decrementing of the user controls counter from
snd_ctl_elem_remove to snd_ctl_remove_unlocked_id; this saves the
separate locking of the controls semaphore, and therefore removes
a harmless race.
Since the purpose of the function is to operate on user controls (the
control being unlocked is just a prerequisite), rename it to
snd_ctl_remove_user_ctl.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/core/control.c')
-rw-r--r-- | sound/core/control.c | 19 |
1 files changed, 7 insertions, 12 deletions
diff --git a/sound/core/control.c b/sound/core/control.c index 9d91f77bc880..bc64b723415b 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -414,7 +414,7 @@ int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id) EXPORT_SYMBOL(snd_ctl_remove_id); /** - * snd_ctl_remove_unlocked_id - remove the unlocked control of the given id and release it + * snd_ctl_remove_user_ctl - remove and release the unlocked user control * @file: active control handle * @id: the control id to remove * @@ -423,8 +423,8 @@ EXPORT_SYMBOL(snd_ctl_remove_id); * * Returns 0 if successful, or a negative error code on failure. */ -static int snd_ctl_remove_unlocked_id(struct snd_ctl_file * file, - struct snd_ctl_elem_id *id) +static int snd_ctl_remove_user_ctl(struct snd_ctl_file * file, + struct snd_ctl_elem_id *id) { struct snd_card *card = file->card; struct snd_kcontrol *kctl; @@ -442,6 +442,9 @@ static int snd_ctl_remove_unlocked_id(struct snd_ctl_file * file, goto error; } ret = snd_ctl_remove(card, kctl); + if (ret < 0) + goto error; + card->user_ctl_count--; error: up_write(&card->controls_rwsem); return ret; @@ -1053,18 +1056,10 @@ static int snd_ctl_elem_remove(struct snd_ctl_file *file, struct snd_ctl_elem_id __user *_id) { struct snd_ctl_elem_id id; - int err; if (copy_from_user(&id, _id, sizeof(id))) return -EFAULT; - err = snd_ctl_remove_unlocked_id(file, &id); - if (! err) { - struct snd_card *card = file->card; - down_write(&card->controls_rwsem); - card->user_ctl_count--; - up_write(&card->controls_rwsem); - } - return err; + return snd_ctl_remove_user_ctl(file, &id); } static int snd_ctl_subscribe_events(struct snd_ctl_file *file, int __user *ptr) |