SCSI fixes on 20210402

Single fix to iscsi for a rare race condition which can cause a kernel
 panic.
 
 Signed-off-by: James E.J. Bottomley <jejb@linux.ibm.com>
 -----BEGIN PGP SIGNATURE-----
 
 iJwEABMIAEQWIQTnYEDbdso9F2cI+arnQslM7pishQUCYGe3ZCYcamFtZXMuYm90
 dG9tbGV5QGhhbnNlbnBhcnRuZXJzaGlwLmNvbQAKCRDnQslM7pishaxZAQDt/zcv
 xvK+2qWNsqVse32hknc3RpdMWUh4JE1pKfSvgwD/X7c3goqQ8dEyEK0cpXLNpw9D
 kOOQxTVVCxFImwActdg=
 =VlUo
 -----END PGP SIGNATURE-----

Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

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
This commit is contained in:
Linus Torvalds 2021-04-03 09:07:35 -07:00
commit 57fbdb15ec
2 changed files with 14 additions and 1 deletions

View File

@ -2475,6 +2475,7 @@ static void iscsi_if_stop_conn(struct iscsi_cls_conn *conn, int flag)
*/ */
mutex_lock(&conn_mutex); mutex_lock(&conn_mutex);
conn->transport->stop_conn(conn, flag); conn->transport->stop_conn(conn, flag);
conn->state = ISCSI_CONN_DOWN;
mutex_unlock(&conn_mutex); mutex_unlock(&conn_mutex);
} }
@ -2901,6 +2902,13 @@ iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev)
default: default:
err = transport->set_param(conn, ev->u.set_param.param, err = transport->set_param(conn, ev->u.set_param.param,
data, ev->u.set_param.len); data, ev->u.set_param.len);
if ((conn->state == ISCSI_CONN_BOUND) ||
(conn->state == ISCSI_CONN_UP)) {
err = transport->set_param(conn, ev->u.set_param.param,
data, ev->u.set_param.len);
} else {
return -ENOTCONN;
}
} }
return err; return err;
@ -2960,6 +2968,7 @@ static int iscsi_if_ep_disconnect(struct iscsi_transport *transport,
mutex_lock(&conn->ep_mutex); mutex_lock(&conn->ep_mutex);
conn->ep = NULL; conn->ep = NULL;
mutex_unlock(&conn->ep_mutex); mutex_unlock(&conn->ep_mutex);
conn->state = ISCSI_CONN_DOWN;
} }
transport->ep_disconnect(ep); transport->ep_disconnect(ep);
@ -3727,6 +3736,8 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
ev->r.retcode = transport->bind_conn(session, conn, ev->r.retcode = transport->bind_conn(session, conn,
ev->u.b_conn.transport_eph, ev->u.b_conn.transport_eph,
ev->u.b_conn.is_leading); ev->u.b_conn.is_leading);
if (!ev->r.retcode)
conn->state = ISCSI_CONN_BOUND;
mutex_unlock(&conn_mutex); mutex_unlock(&conn_mutex);
if (ev->r.retcode || !transport->ep_connect) if (ev->r.retcode || !transport->ep_connect)
@ -3966,7 +3977,8 @@ iscsi_conn_attr(local_ipaddr, ISCSI_PARAM_LOCAL_IPADDR);
static const char *const connection_state_names[] = { static const char *const connection_state_names[] = {
[ISCSI_CONN_UP] = "up", [ISCSI_CONN_UP] = "up",
[ISCSI_CONN_DOWN] = "down", [ISCSI_CONN_DOWN] = "down",
[ISCSI_CONN_FAILED] = "failed" [ISCSI_CONN_FAILED] = "failed",
[ISCSI_CONN_BOUND] = "bound"
}; };
static ssize_t show_conn_state(struct device *dev, static ssize_t show_conn_state(struct device *dev,

View File

@ -193,6 +193,7 @@ enum iscsi_connection_state {
ISCSI_CONN_UP = 0, ISCSI_CONN_UP = 0,
ISCSI_CONN_DOWN, ISCSI_CONN_DOWN,
ISCSI_CONN_FAILED, ISCSI_CONN_FAILED,
ISCSI_CONN_BOUND,
}; };
struct iscsi_cls_conn { struct iscsi_cls_conn {