út 15. 11. 2022 v 13:56 odesílatel Maurizio Lombardi <mlombard@xxxxxxxxxx> napsal: > > > +/** > + * RETURN VALUE: > + * > + * 1 = Login successful > + * -1 = Login failed > + * 0 = More PDU exchanges required > + */ > static int iscsi_target_do_login(struct iscsit_conn *conn, struct iscsi_login *login) > { > int pdu_count = 0; > @@ -1363,12 +1370,13 @@ int iscsi_target_start_negotiation( > ret = -1; > > if (ret < 0) { > - cancel_delayed_work_sync(&conn->login_work); > iscsi_target_restore_sock_callbacks(conn); > iscsi_remove_failed_auth_entry(conn); > } > - if (ret != 0) > + if (ret != 0) { > + cancel_delayed_work_sync(&conn->login_work); > iscsi_target_nego_release(conn); > + } > > return ret; > } > If ret == 1 the login was successful, the socket callbacks have been restored by iscsi_target_do_login() so we just have to call cancel_delayed_work_sync() against login_work to fix the race condition. if ret == -1 the login was unsuccessful, I moved the cancel_delayed_work_sync() call from the (ret < 0) block to the (ret != 0) to close a potential race condition (we must restore the socket callbacks first). if ret == 0 then iscsi_target_do_login() clears LOGIN_FLAGS_INITIAL_PDU and passes the control to login_work. With this version of the patch, nothing has been changed in the login_work context so it should work exactly as before. iscsi_target_start_negotiation() is executed only in the login_thread context. Maurizio