Commit e5d1a1ee authored by Ying Xue's avatar Ying Xue Committed by David S. Miller
Browse files

tipc: Refactor __tipc_nl_compat_doit



As preparation for adding RTNL to make (*cmd->transcode)() and
(*cmd->transcode)() constantly protected by RTNL lock, we move out of
memory allocations existing between them as many as possible so that
the time of holding RTNL can be minimized in __tipc_nl_compat_doit().

Signed-off-by: default avatarYing Xue <ying.xue@windriver.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 361b1231
Loading
Loading
Loading
Loading
+15 −14
Original line number Diff line number Diff line
@@ -285,10 +285,6 @@ static int __tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd,
	if (!trans_buf)
		return -ENOMEM;

	err = (*cmd->transcode)(cmd, trans_buf, msg);
	if (err)
		goto trans_out;

	attrbuf = kmalloc((tipc_genl_family.maxattr + 1) *
			sizeof(struct nlattr *), GFP_KERNEL);
	if (!attrbuf) {
@@ -296,27 +292,32 @@ static int __tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd,
		goto trans_out;
	}

	err = nla_parse(attrbuf, tipc_genl_family.maxattr,
			(const struct nlattr *)trans_buf->data,
			trans_buf->len, NULL, NULL);
	if (err)
		goto parse_out;

	doit_buf = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!doit_buf) {
		err = -ENOMEM;
		goto parse_out;
		goto attrbuf_out;
	}

	doit_buf->sk = msg->dst_sk;

	memset(&info, 0, sizeof(info));
	info.attrs = attrbuf;

	err = (*cmd->transcode)(cmd, trans_buf, msg);
	if (err)
		goto doit_out;

	err = nla_parse(attrbuf, tipc_genl_family.maxattr,
			(const struct nlattr *)trans_buf->data,
			trans_buf->len, NULL, NULL);
	if (err)
		goto doit_out;

	doit_buf->sk = msg->dst_sk;

	err = (*cmd->doit)(doit_buf, &info);
doit_out:

	kfree_skb(doit_buf);
parse_out:
attrbuf_out:
	kfree(attrbuf);
trans_out:
	kfree_skb(trans_buf);