[alsa-devel] [PATCH 16/24] ALSA: ctl: add replace helper function to allocate own buffer

Takashi Sakamoto o-takashi at sakamocchi.jp
Sat Nov 25 10:19:58 CET 2017


In current implementation, an execution path of ELEM_REPLACE request
joins in an execution path of ELEM_ADD in the last. An advance preparation
of the replacement can be split from processing of the addition. This
separation might be a good granularity of helper functions.

For a preparation to it, this commit adds an unique helper function for
the replacement. In this time, the execution path still joins in the one
of the addition.

Signed-off-by: Takashi Sakamoto <o-takashi at sakamocchi.jp>
---
 sound/core/control.c | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/sound/core/control.c b/sound/core/control.c
index a321576a6308..9e23f84d284d 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1406,7 +1406,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
 }
 
 static int snd_ctl_elem_add_user(struct snd_ctl_file *ctl_file,
-				 void __user *arg, int replace)
+				 void __user *arg)
 {
 	struct snd_ctl_elem_info *info;
 	int err;
@@ -1415,7 +1415,29 @@ static int snd_ctl_elem_add_user(struct snd_ctl_file *ctl_file,
 	if (IS_ERR(info))
 		return PTR_ERR(info);
 
-	err = snd_ctl_elem_add(ctl_file, info, replace);
+	err = snd_ctl_elem_add(ctl_file, info, 0);
+	if (err >= 0) {
+		if (copy_to_user(arg, info, sizeof(*info))) {
+			snd_ctl_remove_user_ctl(ctl_file, &info->id);
+			err = -EFAULT;
+		}
+	}
+
+	kfree(info);
+	return err;
+}
+
+static int snd_ctl_elem_replace_user(struct snd_ctl_file *ctl_file,
+				     void __user *arg)
+{
+	struct snd_ctl_elem_info *info;
+	int err;
+
+	info = memdup_user(arg, sizeof(*info));
+	if (IS_ERR(info))
+		return PTR_ERR(info);
+
+	err = snd_ctl_elem_add(ctl_file, info, 1);
 	if (err >= 0) {
 		if (copy_to_user(arg, info, sizeof(*info))) {
 			snd_ctl_remove_user_ctl(ctl_file, &info->id);
@@ -1592,9 +1614,9 @@ static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg
 	case SNDRV_CTL_IOCTL_ELEM_UNLOCK:
 		return snd_ctl_elem_unlock(ctl, argp);
 	case SNDRV_CTL_IOCTL_ELEM_ADD:
-		return snd_ctl_elem_add_user(ctl, argp, 0);
+		return snd_ctl_elem_add_user(ctl, argp);
 	case SNDRV_CTL_IOCTL_ELEM_REPLACE:
-		return snd_ctl_elem_add_user(ctl, argp, 1);
+		return snd_ctl_elem_replace_user(ctl, argp);
 	case SNDRV_CTL_IOCTL_ELEM_REMOVE:
 		return snd_ctl_elem_remove(ctl, argp);
 	case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS:
-- 
2.14.1



More information about the Alsa-devel mailing list