diff options
Diffstat (limited to 'sound/core/sound.c')
-rw-r--r-- | sound/core/sound.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/sound/core/sound.c b/sound/core/sound.c index 437c25e..f002bd9 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c @@ -153,7 +153,7 @@ static int snd_open(struct inode *inode, struct file *file) { unsigned int minor = iminor(inode); struct snd_minor *mptr = NULL; - const struct file_operations *new_fops; + const struct file_operations *old_fops; int err = 0; if (minor >= ARRAY_SIZE(snd_minors)) @@ -167,14 +167,24 @@ static int snd_open(struct inode *inode, struct file *file) return -ENODEV; } } - new_fops = fops_get(mptr->f_ops); + old_fops = file->f_op; + file->f_op = fops_get(mptr->f_ops); + if (file->f_op == NULL) { + file->f_op = old_fops; + err = -ENODEV; + } mutex_unlock(&sound_mutex); - if (!new_fops) - return -ENODEV; - replace_fops(file, new_fops); + if (err < 0) + return err; - if (file->f_op->open) + if (file->f_op->open) { err = file->f_op->open(inode, file); + if (err) { + fops_put(file->f_op); + file->f_op = fops_get(old_fops); + } + } + fops_put(old_fops); return err; } |