summaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2019-01-13 09:25:42 +0100
committerTakashi Iwai <tiwai@suse.de>2019-01-21 16:38:15 +0100
commitd819fb21eecc70972c4a3681f2542e1ddcc1ca13 (patch)
tree4b06164a6a2ccf304d45b88b2f728d26afeecc0e /sound/core
parentbfeffd155283772bbe78c6a05dec7c0128ee500c (diff)
downloadlinux-d819fb21eecc70972c4a3681f2542e1ddcc1ca13.tar.gz
linux-d819fb21eecc70972c4a3681f2542e1ddcc1ca13.tar.bz2
linux-d819fb21eecc70972c4a3681f2542e1ddcc1ca13.zip
ALSA: pcm: Call snd_card_unref() inside in_pcm_file()
The snd_card_unref() call in snd_pcm_link() looks suspicious through a quick glance, but it's a correct usage; this is needed just because the file descriptor check in is_pcm_file() calls the helper snd_lookup_minor_data() that keeps the card refcount. Despite of the correctness, the code still looks confusing. Basically, keeping the card ref for the whole code isn't needed as fdget() blocks the release of the opened file. Hence it's more understandable if snd_card_unref() is moved into is_pcm_file(), then the caller doesn't have to take care after the call. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/pcm_native.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 818dff1de545..c72dfd1fc1ed 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1935,13 +1935,19 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream)
static bool is_pcm_file(struct file *file)
{
struct inode *inode = file_inode(file);
+ struct snd_pcm *pcm;
unsigned int minor;
if (!S_ISCHR(inode->i_mode) || imajor(inode) != snd_major)
return false;
minor = iminor(inode);
- return snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_PLAYBACK) ||
- snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_CAPTURE);
+ pcm = snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
+ if (!pcm)
+ pcm = snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_CAPTURE);
+ if (!pcm)
+ return false;
+ snd_card_unref(pcm->card);
+ return true;
}
/*
@@ -1996,7 +2002,6 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
write_unlock_irq(&snd_pcm_link_rwlock);
up_write(&snd_pcm_link_rwsem);
_nolock:
- snd_card_unref(substream1->pcm->card);
kfree(group);
_badf:
fdput(f);