summaryrefslogtreecommitdiff
path: root/sound/core/pcm_native.c
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2017-06-11 23:56:12 +0900
committerTakashi Iwai <tiwai@suse.de>2017-06-11 19:05:24 +0200
commitf74ae15fe3da7905b78e986ad906a333587cf160 (patch)
tree960056cd5a387f1db64ae507538fffcc1c9c7068 /sound/core/pcm_native.c
parent6baca010c71176f406299ea1949e721ab995ff01 (diff)
ALSA: pcm: return error immediately for parameters handling
When refining mask/interval parameters, helper functions can return error code. This error is not handled immediately. This seems to return parameters to userspace applications in its meddle of processing. However, in general, when receiving error from system calls, the application might not handle argument buffer. It's reasonable to judge the above design as superfluity. This commit handles the error immediately. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/core/pcm_native.c')
-rw-r--r--sound/core/pcm_native.c66
1 files changed, 38 insertions, 28 deletions
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 076187ae8859..425f54827e78 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -276,14 +276,14 @@ static int constrain_mask_params(struct snd_pcm_substream *substream,
old_mask = *m;
changed = snd_mask_refine(m, constrs_mask(constrs, k));
+ if (changed < 0)
+ return changed;
trace_hw_mask_param(substream, k, 0, &old_mask, m);
/* Set corresponding flag so that the caller gets it. */
if (changed)
params->cmask |= 1 << k;
- if (changed < 0)
- return changed;
}
return 0;
@@ -312,14 +312,14 @@ static int constrain_interval_params(struct snd_pcm_substream *substream,
old_interval = *i;
changed = snd_interval_refine(i, constrs_interval(constrs, k));
+ if (changed < 0)
+ return changed;
trace_hw_interval_param(substream, k, 0, &old_interval, i);
/* Set corresponding flag so that the caller gets it. */
if (changed)
params->cmask |= 1 << k;
- if (changed < 0)
- return changed;
}
return 0;
@@ -406,6 +406,8 @@ retry:
}
changed = r->func(params, r);
+ if (changed < 0)
+ return changed;
if (hw_is_mask(r->var)) {
trace_hw_mask_param(substream, r->var, k + 1,
@@ -428,8 +430,7 @@ retry:
vstamps[r->var] = stamp;
again = true;
}
- if (changed < 0)
- return changed;
+
stamp++;
}
@@ -527,13 +528,16 @@ static int snd_pcm_hw_refine_user(struct snd_pcm_substream *substream,
return PTR_ERR(params);
err = snd_pcm_hw_refine(substream, params);
- if (err >= 0)
- err = fixup_unreferenced_params(substream, params);
- if (copy_to_user(_params, params, sizeof(*params))) {
- if (!err)
- err = -EFAULT;
- }
+ if (err < 0)
+ goto end;
+ err = fixup_unreferenced_params(substream, params);
+ if (err < 0)
+ goto end;
+
+ if (copy_to_user(_params, params, sizeof(*params)))
+ err = -EFAULT;
+end:
kfree(params);
return err;
}
@@ -749,11 +753,12 @@ static int snd_pcm_hw_params_user(struct snd_pcm_substream *substream,
return PTR_ERR(params);
err = snd_pcm_hw_params(substream, params);
- if (copy_to_user(_params, params, sizeof(*params))) {
- if (!err)
- err = -EFAULT;
- }
+ if (err < 0)
+ goto end;
+ if (copy_to_user(_params, params, sizeof(*params)))
+ err = -EFAULT;
+end:
kfree(params);
return err;
}
@@ -3699,14 +3704,17 @@ static int snd_pcm_hw_refine_old_user(struct snd_pcm_substream *substream,
}
snd_pcm_hw_convert_from_old_params(params, oparams);
err = snd_pcm_hw_refine(substream, params);
- if (err >= 0)
- err = fixup_unreferenced_params(substream, params);
- snd_pcm_hw_convert_to_old_params(oparams, params);
- if (copy_to_user(_oparams, oparams, sizeof(*oparams))) {
- if (!err)
- err = -EFAULT;
- }
+ if (err < 0)
+ goto out_old;
+
+ err = fixup_unreferenced_params(substream, params);
+ if (err < 0)
+ goto out_old;
+ snd_pcm_hw_convert_to_old_params(oparams, params);
+ if (copy_to_user(_oparams, oparams, sizeof(*oparams)))
+ err = -EFAULT;
+out_old:
kfree(oparams);
out:
kfree(params);
@@ -3729,14 +3737,16 @@ static int snd_pcm_hw_params_old_user(struct snd_pcm_substream *substream,
err = PTR_ERR(oparams);
goto out;
}
+
snd_pcm_hw_convert_from_old_params(params, oparams);
err = snd_pcm_hw_params(substream, params);
- snd_pcm_hw_convert_to_old_params(oparams, params);
- if (copy_to_user(_oparams, oparams, sizeof(*oparams))) {
- if (!err)
- err = -EFAULT;
- }
+ if (err < 0)
+ goto out_old;
+ snd_pcm_hw_convert_to_old_params(oparams, params);
+ if (copy_to_user(_oparams, oparams, sizeof(*oparams)))
+ err = -EFAULT;
+out_old:
kfree(oparams);
out:
kfree(params);