Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > d18fa7374095732a0ead4cb4065710a5 > files > 7

iscsi-initiator-utils-6.2.0.871-0.12.el5_4.1.src.rpm

diff --git a/usr/actor.c b/usr/actor.c
index b487632..00f5c58 100644
--- a/usr/actor.c
+++ b/usr/actor.c
@@ -90,7 +90,7 @@ actor_delete(actor_t *thread)
 }
 
 static void
-actor_schedule_private(actor_t *thread, uint32_t ttschedule)
+actor_schedule_private(actor_t *thread, uint32_t ttschedule, int head)
 {
 	uint64_t delay_time, current_time;
 	actor_t *next_thread;
@@ -115,10 +115,20 @@ actor_schedule_private(actor_t *thread, uint32_t ttschedule)
 		if (delay_time == 0) {
 			if (poll_in_progress) {
 				thread->state = ACTOR_POLL_WAITING;
-				list_add_tail(&thread->list, &poll_list);
+				if (head)
+					list_add(&thread->list,
+						 &poll_list);
+				else
+					list_add_tail(&thread->list,
+						      &poll_list);
 			} else {
 				thread->state = ACTOR_SCHEDULED;
-				list_add_tail(&thread->list, &actor_list);
+				if (head)
+					list_add(&thread->list,
+						 &actor_list);
+				else
+					list_add_tail(&thread->list,
+						      &actor_list);
 			}
 		} else {
 			thread->state = ACTOR_WAITING;
@@ -159,9 +169,15 @@ done:
 }
 
 void
+actor_schedule_head(actor_t *thread)
+{
+	actor_schedule_private(thread, 0, 1);
+}
+
+void
 actor_schedule(actor_t *thread)
 {
-	actor_schedule_private(thread, 0);
+	actor_schedule_private(thread, 0, 0);
 }
 
 void
@@ -169,7 +185,7 @@ actor_timer(actor_t *thread, uint32_t timeout, void (*callback)(void *),
 	    void *data)
 {
 	actor_new(thread, callback, data);
-	actor_schedule_private(thread, timeout);
+	actor_schedule_private(thread, timeout, 0);
 }
 
 int
@@ -178,7 +194,7 @@ actor_timer_mod(actor_t *thread, uint32_t timeout, void *data)
 	if (thread->state == ACTOR_WAITING) {
 		list_del_init(&thread->list);
 		thread->data = data;
-		actor_schedule_private(thread, timeout);
+		actor_schedule_private(thread, timeout, 0);
 		return 1;
 	}
 	return 0;
diff --git a/usr/actor.h b/usr/actor.h
index 7a71d42..704224d 100644
--- a/usr/actor.h
+++ b/usr/actor.h
@@ -44,6 +44,7 @@ typedef struct actor {
 
 extern void actor_new(actor_t *thread, void (*callback)(void *), void * data);
 extern void actor_delete(actor_t *thread);
+extern void actor_schedule_head(actor_t *thread);
 extern void actor_schedule(actor_t *thread);
 extern void actor_timer(actor_t *thread, uint32_t timeout,
 			void (*callback)(void *), void *data);
diff --git a/usr/initiator.c b/usr/initiator.c
index d7ff50f..dc0deca 100644
--- a/usr/initiator.c
+++ b/usr/initiator.c
@@ -1981,6 +1981,8 @@ void iscsi_sched_conn_context(struct iscsi_conn_context *conn_context,
 			      struct iscsi_conn *conn, unsigned long tmo,
 			      int event)
 {
+	enum iscsi_err error;
+
 	log_debug(7, "sched conn context %p event %d, tmo %lu",
 		  &conn_context->actor, event, tmo);
 
@@ -1992,9 +1994,19 @@ void iscsi_sched_conn_context(struct iscsi_conn_context *conn_context,
 		actor_schedule(&conn_context->actor);
 		break;
 	case EV_CONN_ERROR:
+		error = *(enum iscsi_err *)conn_context->data;
+
 		actor_new(&conn_context->actor, session_conn_error,
 			  conn_context);
-		actor_schedule(&conn_context->actor);
+		/*
+		 * We handle invalid host, by killing the session.
+		 * It must go at the head of the queue, so we do not
+		 * initiate error handling or logout or some other op.
+		 */
+		if (error == ISCSI_ERR_INVALID_HOST)
+			actor_schedule_head(&conn_context->actor);
+		else
+			actor_schedule(&conn_context->actor);
 		break;
 	case EV_CONN_POLL:
 		actor_new(&conn_context->actor, session_conn_poll,