pcm_native: switch to fdget()/fdput()
authorAl Viro <viro@zeniv.linux.org.uk>
Wed, 5 Jun 2013 18:09:55 +0000 (14:09 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Sat, 29 Jun 2013 08:57:06 +0000 (12:57 +0400)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
sound/core/pcm_native.c

index f928181..a68d4c6 100644 (file)
@@ -1589,29 +1589,16 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream)
 }
 
 
-/* WARNING: Don't forget to fput back the file */
-static struct file *snd_pcm_file_fd(int fd, int *fput_needed)
+static bool is_pcm_file(struct file *file)
 {
-       struct file *file;
-       struct inode *inode;
+       struct inode *inode = file_inode(file);
        unsigned int minor;
 
-       file = fget_light(fd, fput_needed);
-       if (!file)
-               return NULL;
-       inode = file_inode(file);
-       if (!S_ISCHR(inode->i_mode) ||
-           imajor(inode) != snd_major) {
-               fput_light(file, *fput_needed);
-               return NULL;
-       }
+       if (!S_ISCHR(inode->i_mode) || imajor(inode) != snd_major)
+               return false;
        minor = iminor(inode);
-       if (!snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_PLAYBACK) &&
-           !snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_CAPTURE)) {
-               fput_light(file, *fput_needed);
-               return NULL;
-       }
-       return file;
+       return snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_PLAYBACK) ||
+               snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_CAPTURE);
 }
 
 /*
@@ -1620,16 +1607,18 @@ static struct file *snd_pcm_file_fd(int fd, int *fput_needed)
 static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
 {
        int res = 0;
-       struct file *file;
        struct snd_pcm_file *pcm_file;
        struct snd_pcm_substream *substream1;
        struct snd_pcm_group *group;
-       int fput_needed;
+       struct fd f = fdget(fd);
 
-       file = snd_pcm_file_fd(fd, &fput_needed);
-       if (!file)
+       if (!f.file)
                return -EBADFD;
-       pcm_file = file->private_data;
+       if (!is_pcm_file(f.file)) {
+               res = -EBADFD;
+               goto _badf;
+       }
+       pcm_file = f.file->private_data;
        substream1 = pcm_file->substream;
        group = kmalloc(sizeof(*group), GFP_KERNEL);
        if (!group) {
@@ -1663,8 +1652,9 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
        up_write(&snd_pcm_link_rwsem);
  _nolock:
        snd_card_unref(substream1->pcm->card);
-       fput_light(file, fput_needed);
        kfree(group);
+ _badf:
+       fdput(f);
        return res;
 }