Pull SCSI fix from James Bottomley: "A single fix to iscsi for a rare race condition which can cause a kernel panic" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: iscsi: Fix race condition between login and sync thread
Unified · Split
| @@ -2475,6 +2475,7 @@ static void iscsi_if_stop_conn(struct iscsi_cls_conn *conn, int flag) · 2474 unmodified lines | |||
| 2475 | */ | 2475 | */ |
| 2476 | mutex_lock(&conn_mutex); | 2476 | mutex_lock(&conn_mutex); |
| 2477 | conn->transport->stop_conn(conn, flag); | 2477 | conn->transport->stop_conn(conn, flag); |
| 2478 | conn->state = ISCSI_CONN_DOWN; | ||
| 2478 | mutex_unlock(&conn_mutex); | 2479 | mutex_unlock(&conn_mutex); |
| 2479 | 2480 | ||
| 2480 | } | 2481 | } |
| @@ -2901,6 +2902,13 @@ iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev) · 420 unmodified lines | |||
| 2901 | default: | 2902 | default: |
| 2902 | err = transport->set_param(conn, ev->u.set_param.param, | 2903 | err = transport->set_param(conn, ev->u.set_param.param, |
| 2903 | data, ev->u.set_param.len); | 2904 | data, ev->u.set_param.len); |
| 2905 | if ((conn->state == ISCSI_CONN_BOUND) || | ||
| 2906 | (conn->state == ISCSI_CONN_UP)) { | ||
| 2907 | err = transport->set_param(conn, ev->u.set_param.param, | ||
| 2908 | data, ev->u.set_param.len); | ||
| 2909 | } else { | ||
| 2910 | return -ENOTCONN; | ||
| 2911 | } | ||
| 2904 | } | 2912 | } |
| 2905 | 2913 | ||
| 2906 | return err; | 2914 | return err; |
| @@ -2960,6 +2968,7 @@ static int iscsi_if_ep_disconnect(struct iscsi_transport *transport, · 53 unmodified lines | |||
| 2960 | mutex_lock(&conn->ep_mutex); | 2968 | mutex_lock(&conn->ep_mutex); |
| 2961 | conn->ep = NULL; | 2969 | conn->ep = NULL; |
| 2962 | mutex_unlock(&conn->ep_mutex); | 2970 | mutex_unlock(&conn->ep_mutex); |
| 2971 | conn->state = ISCSI_CONN_DOWN; | ||
| 2963 | } | 2972 | } |
| 2964 | 2973 | ||
| 2965 | transport->ep_disconnect(ep); | 2974 | transport->ep_disconnect(ep); |
| @@ -3727,6 +3736,8 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group) · 761 unmodified lines | |||
| 3727 | ev->r.retcode = transport->bind_conn(session, conn, | 3736 | ev->r.retcode = transport->bind_conn(session, conn, |
| 3728 | ev->u.b_conn.transport_eph, | 3737 | ev->u.b_conn.transport_eph, |
| 3729 | ev->u.b_conn.is_leading); | 3738 | ev->u.b_conn.is_leading); |
| 3739 | if (!ev->r.retcode) | ||
| 3740 | conn->state = ISCSI_CONN_BOUND; | ||
| 3730 | mutex_unlock(&conn_mutex); | 3741 | mutex_unlock(&conn_mutex); |
| 3731 | 3742 | ||
| 3732 | if (ev->r.retcode || !transport->ep_connect) | 3743 | if (ev->r.retcode || !transport->ep_connect) |
| @@ -3966,7 +3977,8 @@ iscsi_conn_attr(local_ipaddr, ISCSI_PARAM_LOCAL_IPADDR); · 233 unmodified lines | |||
| 3966 | static const char *const connection_state_names[] = { | 3977 | static const char *const connection_state_names[] = { |
| 3967 | [ISCSI_CONN_UP] = "up", | 3978 | [ISCSI_CONN_UP] = "up", |
| 3968 | [ISCSI_CONN_DOWN] = "down", | 3979 | [ISCSI_CONN_DOWN] = "down", |
| 3969 | [ISCSI_CONN_FAILED] = "failed" | 3980 | [ISCSI_CONN_FAILED] = "failed", |
| 3981 | [ISCSI_CONN_BOUND] = "bound" | ||
| 3970 | }; | 3982 | }; |
| 3971 | 3983 | ||
| 3972 | static ssize_t show_conn_state(struct device *dev, | 3984 | static ssize_t show_conn_state(struct device *dev, |
| @@ -193,6 +193,7 @@ enum iscsi_connection_state { · 192 unmodified lines | |||
| 193 | ISCSI_CONN_UP = 0, | 193 | ISCSI_CONN_UP = 0, |
| 194 | ISCSI_CONN_DOWN, | 194 | ISCSI_CONN_DOWN, |
| 195 | ISCSI_CONN_FAILED, | 195 | ISCSI_CONN_FAILED, |
| 196 | ISCSI_CONN_BOUND, | ||
| 196 | }; | 197 | }; |
| 197 | 198 | ||
| 198 | struct iscsi_cls_conn { | 199 | struct iscsi_cls_conn { |