scsi: iscsi: respond to netlink with unicast when appropriate
[ Upstream commit af17092810a887178195276255b7b31f8fbe7dbe ] Instead of always multicasting responses, send a unicast netlink message directed at the correct pid. This will be needed if we ever want to support multiple userspace processes interacting with the kernel over iSCSI netlink simultaneously. Limitations can currently be seen if you attempt to run multiple iscsistart commands in parallel. We've fixed up the userspace issues in iscsistart that prevented multiple instances from running, so now attempts to speed up booting by bringing up multiple iscsi sessions at once in the initramfs are just running into misrouted responses that this fixes. Signed-off-by: Chris Leech <cleech@redhat.com> Reviewed-by: Lee Duncan <lduncan@suse.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
3f64c0c502
commit
af2cc1d2e7
@ -2322,6 +2322,12 @@ iscsi_multicast_skb(struct sk_buff *skb, uint32_t group, gfp_t gfp)
|
||||
return nlmsg_multicast(nls, skb, 0, group, gfp);
|
||||
}
|
||||
|
||||
static int
|
||||
iscsi_unicast_skb(struct sk_buff *skb, u32 portid)
|
||||
{
|
||||
return nlmsg_unicast(nls, skb, portid);
|
||||
}
|
||||
|
||||
int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
|
||||
char *data, uint32_t data_size)
|
||||
{
|
||||
@ -2524,14 +2530,11 @@ void iscsi_ping_comp_event(uint32_t host_no, struct iscsi_transport *transport,
|
||||
EXPORT_SYMBOL_GPL(iscsi_ping_comp_event);
|
||||
|
||||
static int
|
||||
iscsi_if_send_reply(uint32_t group, int seq, int type, int done, int multi,
|
||||
void *payload, int size)
|
||||
iscsi_if_send_reply(u32 portid, int type, void *payload, int size)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct nlmsghdr *nlh;
|
||||
int len = nlmsg_total_size(size);
|
||||
int flags = multi ? NLM_F_MULTI : 0;
|
||||
int t = done ? NLMSG_DONE : type;
|
||||
|
||||
skb = alloc_skb(len, GFP_ATOMIC);
|
||||
if (!skb) {
|
||||
@ -2539,10 +2542,9 @@ iscsi_if_send_reply(uint32_t group, int seq, int type, int done, int multi,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
nlh = __nlmsg_put(skb, 0, 0, t, (len - sizeof(*nlh)), 0);
|
||||
nlh->nlmsg_flags = flags;
|
||||
nlh = __nlmsg_put(skb, 0, 0, type, (len - sizeof(*nlh)), 0);
|
||||
memcpy(nlmsg_data(nlh), payload, size);
|
||||
return iscsi_multicast_skb(skb, group, GFP_ATOMIC);
|
||||
return iscsi_unicast_skb(skb, portid);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -3470,6 +3472,7 @@ static int
|
||||
iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
|
||||
{
|
||||
int err = 0;
|
||||
u32 portid;
|
||||
struct iscsi_uevent *ev = nlmsg_data(nlh);
|
||||
struct iscsi_transport *transport = NULL;
|
||||
struct iscsi_internal *priv;
|
||||
@ -3490,10 +3493,12 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
|
||||
if (!try_module_get(transport->owner))
|
||||
return -EINVAL;
|
||||
|
||||
portid = NETLINK_CB(skb).portid;
|
||||
|
||||
switch (nlh->nlmsg_type) {
|
||||
case ISCSI_UEVENT_CREATE_SESSION:
|
||||
err = iscsi_if_create_session(priv, ep, ev,
|
||||
NETLINK_CB(skb).portid,
|
||||
portid,
|
||||
ev->u.c_session.initial_cmdsn,
|
||||
ev->u.c_session.cmds_max,
|
||||
ev->u.c_session.queue_depth);
|
||||
@ -3506,7 +3511,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
|
||||
}
|
||||
|
||||
err = iscsi_if_create_session(priv, ep, ev,
|
||||
NETLINK_CB(skb).portid,
|
||||
portid,
|
||||
ev->u.c_bound_session.initial_cmdsn,
|
||||
ev->u.c_bound_session.cmds_max,
|
||||
ev->u.c_bound_session.queue_depth);
|
||||
@ -3664,6 +3669,8 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
|
||||
static void
|
||||
iscsi_if_rx(struct sk_buff *skb)
|
||||
{
|
||||
u32 portid = NETLINK_CB(skb).portid;
|
||||
|
||||
mutex_lock(&rx_queue_mutex);
|
||||
while (skb->len >= NLMSG_HDRLEN) {
|
||||
int err;
|
||||
@ -3699,8 +3706,8 @@ iscsi_if_rx(struct sk_buff *skb)
|
||||
break;
|
||||
if (ev->type == ISCSI_UEVENT_GET_CHAP && !err)
|
||||
break;
|
||||
err = iscsi_if_send_reply(group, nlh->nlmsg_seq,
|
||||
nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
|
||||
err = iscsi_if_send_reply(portid, nlh->nlmsg_type,
|
||||
ev, sizeof(*ev));
|
||||
} while (err < 0 && err != -ECONNREFUSED && err != -ESRCH);
|
||||
skb_pull(skb, rlen);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user