aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-03 12:10:19 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-03 12:10:19 -0400
commit790eac5640abf7a57fa3a644386df330e18c11b0 (patch)
tree08de20bde44f59e51b91ff473a71047c2957e8c9 /sound
parent0b0585c3e192967cb2ef0ac0816eb8a8c8d99840 (diff)
parent48bde8d3620f5f3c6ae9ff599eb404055ae51664 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull second set of VFS changes from Al Viro: "Assorted f_pos race fixes, making do_splice_direct() safe to call with i_mutex on parent, O_TMPFILE support, Jeff's locks.c series, ->d_hash/->d_compare calling conventions changes from Linus, misc stuff all over the place." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (63 commits) Document ->tmpfile() ext4: ->tmpfile() support vfs: export lseek_execute() to modules lseek_execute() doesn't need an inode passed to it block_dev: switch to fixed_size_llseek() cpqphp_sysfs: switch to fixed_size_llseek() tile-srom: switch to fixed_size_llseek() proc_powerpc: switch to fixed_size_llseek() ubi/cdev: switch to fixed_size_llseek() pci/proc: switch to fixed_size_llseek() isapnp: switch to fixed_size_llseek() lpfc: switch to fixed_size_llseek() locks: give the blocked_hash its own spinlock locks: add a new "lm_owner_key" lock operation locks: turn the blocked_list into a hashtable locks: convert fl_link to a hlist_node locks: avoid taking global lock if possible when waking up blocked waiters locks: protect most of the file_lock handling with i_lock locks: encapsulate the fl_link list handling locks: make "added" in __posix_lock_file a bool ...
Diffstat (limited to 'sound')
-rw-r--r--sound/core/pcm_native.c40
1 files changed, 15 insertions, 25 deletions
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index f92818155958..a68d4c6d702c 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1589,29 +1589,16 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream)
1589} 1589}
1590 1590
1591 1591
1592/* WARNING: Don't forget to fput back the file */ 1592static bool is_pcm_file(struct file *file)
1593static struct file *snd_pcm_file_fd(int fd, int *fput_needed)
1594{ 1593{
1595 struct file *file; 1594 struct inode *inode = file_inode(file);
1596 struct inode *inode;
1597 unsigned int minor; 1595 unsigned int minor;
1598 1596
1599 file = fget_light(fd, fput_needed); 1597 if (!S_ISCHR(inode->i_mode) || imajor(inode) != snd_major)
1600 if (!file) 1598 return false;
1601 return NULL;
1602 inode = file_inode(file);
1603 if (!S_ISCHR(inode->i_mode) ||
1604 imajor(inode) != snd_major) {
1605 fput_light(file, *fput_needed);
1606 return NULL;
1607 }
1608 minor = iminor(inode); 1599 minor = iminor(inode);
1609 if (!snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_PLAYBACK) && 1600 return snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_PLAYBACK) ||
1610 !snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_CAPTURE)) { 1601 snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_CAPTURE);
1611 fput_light(file, *fput_needed);
1612 return NULL;
1613 }
1614 return file;
1615} 1602}
1616 1603
1617/* 1604/*
@@ -1620,16 +1607,18 @@ static struct file *snd_pcm_file_fd(int fd, int *fput_needed)
1620static int snd_pcm_link(struct snd_pcm_substream *substream, int fd) 1607static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
1621{ 1608{
1622 int res = 0; 1609 int res = 0;
1623 struct file *file;
1624 struct snd_pcm_file *pcm_file; 1610 struct snd_pcm_file *pcm_file;
1625 struct snd_pcm_substream *substream1; 1611 struct snd_pcm_substream *substream1;
1626 struct snd_pcm_group *group; 1612 struct snd_pcm_group *group;
1627 int fput_needed; 1613 struct fd f = fdget(fd);
1628 1614
1629 file = snd_pcm_file_fd(fd, &fput_needed); 1615 if (!f.file)
1630 if (!file)
1631 return -EBADFD; 1616 return -EBADFD;
1632 pcm_file = file->private_data; 1617 if (!is_pcm_file(f.file)) {
1618 res = -EBADFD;
1619 goto _badf;
1620 }
1621 pcm_file = f.file->private_data;
1633 substream1 = pcm_file->substream; 1622 substream1 = pcm_file->substream;
1634 group = kmalloc(sizeof(*group), GFP_KERNEL); 1623 group = kmalloc(sizeof(*group), GFP_KERNEL);
1635 if (!group) { 1624 if (!group) {
@@ -1663,8 +1652,9 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
1663 up_write(&snd_pcm_link_rwsem); 1652 up_write(&snd_pcm_link_rwsem);
1664 _nolock: 1653 _nolock:
1665 snd_card_unref(substream1->pcm->card); 1654 snd_card_unref(substream1->pcm->card);
1666 fput_light(file, fput_needed);
1667 kfree(group); 1655 kfree(group);
1656 _badf:
1657 fdput(f);
1668 return res; 1658 return res;
1669} 1659}
1670 1660