In former commit, actual operations of each ioctl command get argument in kernel space. Copying from/to user space is performed outside of the function.
This commit optimizes to the new design.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/core/seq/seq_clientmgr.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-)
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index 8681f90..9f4bcf2 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c @@ -1466,34 +1466,36 @@ static int seq_ioctl_subscribe_port(struct snd_seq_client *client, void *arg) /* * remove from port's subscription list */ -static int seq_ioctl_unsubscribe_port(struct snd_seq_client *client, - void __user *arg) +static int seq_ioctl_unsubscribe_port(struct snd_seq_client *client, void *arg) { + struct snd_seq_port_subscribe *subs = arg; int result = -ENXIO; struct snd_seq_client *receiver = NULL, *sender = NULL; struct snd_seq_client_port *sport = NULL, *dport = NULL; - struct snd_seq_port_subscribe subs; - - if (copy_from_user(&subs, arg, sizeof(subs))) - return -EFAULT;
- if ((receiver = snd_seq_client_use_ptr(subs.dest.client)) == NULL) + receiver = snd_seq_client_use_ptr(subs->dest.client); + if (receiver == NULL) goto __end; - if ((sender = snd_seq_client_use_ptr(subs.sender.client)) == NULL) + sender = snd_seq_client_use_ptr(subs->sender.client); + if (receiver == NULL) goto __end; - if ((sport = snd_seq_port_use_ptr(sender, subs.sender.port)) == NULL) + sport = snd_seq_port_use_ptr(sender, subs->sender.port); + if (sport == NULL) goto __end; - if ((dport = snd_seq_port_use_ptr(receiver, subs.dest.port)) == NULL) + dport = snd_seq_port_use_ptr(receiver, subs->dest.port); + if (dport == NULL) goto __end;
- result = check_subscription_permission(client, sport, dport, &subs); + result = check_subscription_permission(client, sport, dport, subs); if (result < 0) goto __end;
- result = snd_seq_port_disconnect(client, sender, sport, receiver, dport, &subs); - if (! result) /* broadcast announce */ - snd_seq_client_notify_subscription(SNDRV_SEQ_ADDRESS_SUBSCRIBERS, 0, - &subs, SNDRV_SEQ_EVENT_PORT_UNSUBSCRIBED); + result = snd_seq_port_disconnect(client, sender, sport, receiver, dport, + subs); + if (!result) /* broadcast announce */ + snd_seq_client_notify_subscription( + SNDRV_SEQ_ADDRESS_SUBSCRIBERS, 0, subs, + SNDRV_SEQ_EVENT_PORT_UNSUBSCRIBED); __end: if (sport) snd_seq_port_unlock(sport);