xref: /spdk/test/unit/lib/iscsi/conn.c/conn_ut.c (revision 1e3d25b901a6b9d2dce4999e2ecbc02f98d79f05)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2018 Intel Corporation.
3  *   All rights reserved.
4  *   Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
5  */
6 
7 #include "spdk/stdinc.h"
8 
9 #include "common/lib/test_env.c"
10 #include "spdk_internal/cunit.h"
11 
12 #include "iscsi/conn.c"
13 
14 #include "spdk_internal/mock.h"
15 
16 #include "unit/lib/json_mock.c"
17 
18 SPDK_LOG_REGISTER_COMPONENT(iscsi)
19 
20 DEFINE_STUB(iscsi_get_pdu, struct spdk_iscsi_pdu *,
21 	    (struct spdk_iscsi_conn *conn), NULL);
22 DEFINE_STUB(iscsi_param_eq_val, int,
23 	    (struct iscsi_param *params, const char *key, const char *val), 0);
24 DEFINE_STUB(iscsi_pdu_calc_data_digest, uint32_t, (struct spdk_iscsi_pdu *pdu), 0);
25 DEFINE_STUB_V(spdk_sock_writev_async,
26 	      (struct spdk_sock *sock, struct spdk_sock_request *req));
27 
28 struct spdk_scsi_lun {
29 	uint8_t reserved;
30 };
31 
32 struct spdk_iscsi_globals g_iscsi = {
33 	.MaxLargeDataInPerConnection = DEFAULT_MAX_LARGE_DATAIN_PER_CONNECTION,
34 };
35 
36 static TAILQ_HEAD(read_tasks_head, spdk_iscsi_task) g_ut_read_tasks =
37 	TAILQ_HEAD_INITIALIZER(g_ut_read_tasks);
38 static struct spdk_iscsi_task *g_new_task = NULL;
39 static ssize_t g_sock_writev_bytes = 0;
40 
41 DEFINE_STUB(spdk_app_get_shm_id, int, (void), 0);
42 
43 DEFINE_STUB(spdk_sock_getaddr, int,
44 	    (struct spdk_sock *sock, char *saddr, int slen, uint16_t *sport,
45 	     char *caddr, int clen, uint16_t *cport),
46 	    0);
47 
48 int
49 spdk_sock_close(struct spdk_sock **sock)
50 {
51 	*sock = NULL;
52 	return 0;
53 }
54 
55 DEFINE_STUB(spdk_sock_recv, ssize_t,
56 	    (struct spdk_sock *sock, void *buf, size_t len), 0);
57 
58 DEFINE_STUB(spdk_sock_readv, ssize_t,
59 	    (struct spdk_sock *sock, struct iovec *iov, int iovcnt), 0);
60 
61 ssize_t
62 spdk_sock_writev(struct spdk_sock *sock, struct iovec *iov, int iovcnt)
63 {
64 	return g_sock_writev_bytes;
65 }
66 
67 DEFINE_STUB(spdk_sock_set_recvlowat, int, (struct spdk_sock *s, int nbytes), 0);
68 
69 DEFINE_STUB(spdk_sock_set_recvbuf, int, (struct spdk_sock *sock, int sz), 0);
70 
71 DEFINE_STUB(spdk_sock_set_sendbuf, int, (struct spdk_sock *sock, int sz), 0);
72 
73 DEFINE_STUB(spdk_sock_group_add_sock, int,
74 	    (struct spdk_sock_group *group, struct spdk_sock *sock,
75 	     spdk_sock_cb cb_fn, void *cb_arg),
76 	    0);
77 
78 DEFINE_STUB(spdk_sock_group_remove_sock, int,
79 	    (struct spdk_sock_group *group, struct spdk_sock *sock), 0);
80 
81 struct spdk_iscsi_task *
82 iscsi_task_get(struct spdk_iscsi_conn *conn,
83 	       struct spdk_iscsi_task *parent,
84 	       spdk_scsi_task_cpl cpl_fn)
85 {
86 	struct spdk_iscsi_task *task;
87 
88 	task = g_new_task;
89 	if (task == NULL) {
90 		return NULL;
91 	}
92 	memset(task, 0, sizeof(*task));
93 
94 	task->scsi.ref = 1;
95 	task->conn = conn;
96 	task->scsi.cpl_fn = cpl_fn;
97 	if (parent) {
98 		parent->scsi.ref++;
99 		task->parent = parent;
100 		task->scsi.dxfer_dir = parent->scsi.dxfer_dir;
101 		task->scsi.transfer_len = parent->scsi.transfer_len;
102 		task->scsi.lun = parent->scsi.lun;
103 		if (conn && (task->scsi.dxfer_dir == SPDK_SCSI_DIR_FROM_DEV)) {
104 			conn->data_in_cnt++;
105 		}
106 	}
107 
108 	return task;
109 }
110 
111 void
112 spdk_scsi_task_put(struct spdk_scsi_task *scsi_task)
113 {
114 	struct spdk_iscsi_task *task;
115 
116 	CU_ASSERT(scsi_task->ref > 0);
117 	scsi_task->ref--;
118 
119 	task = iscsi_task_from_scsi_task(scsi_task);
120 	if (task->parent) {
121 		spdk_scsi_task_put(&task->parent->scsi);
122 	}
123 }
124 
125 DEFINE_STUB(spdk_scsi_dev_get_lun, struct spdk_scsi_lun *,
126 	    (struct spdk_scsi_dev *dev, int lun_id), NULL);
127 
128 DEFINE_STUB(spdk_scsi_dev_get_first_lun, struct spdk_scsi_lun *,
129 	    (struct spdk_scsi_dev *dev), NULL);
130 
131 DEFINE_STUB(spdk_scsi_dev_get_next_lun, struct spdk_scsi_lun *,
132 	    (struct spdk_scsi_lun *prev_lun), NULL);
133 
134 DEFINE_STUB(spdk_scsi_dev_has_pending_tasks, bool,
135 	    (const struct spdk_scsi_dev *dev, const struct spdk_scsi_port *initiator_port),
136 	    true);
137 
138 DEFINE_STUB(spdk_scsi_lun_open, int,
139 	    (struct spdk_scsi_lun *lun, spdk_scsi_lun_remove_cb_t hotremove_cb,
140 	     void *hotremove_ctx, struct spdk_scsi_lun_desc **desc),
141 	    0);
142 
143 DEFINE_STUB_V(spdk_scsi_lun_close, (struct spdk_scsi_lun_desc *desc));
144 
145 DEFINE_STUB(spdk_scsi_lun_allocate_io_channel, int,
146 	    (struct spdk_scsi_lun_desc *desc), 0);
147 
148 DEFINE_STUB_V(spdk_scsi_lun_free_io_channel, (struct spdk_scsi_lun_desc *desc));
149 
150 DEFINE_STUB(spdk_scsi_lun_get_id, int, (const struct spdk_scsi_lun *lun), 0);
151 
152 DEFINE_STUB(spdk_scsi_port_get_name, const char *,
153 	    (const struct spdk_scsi_port *port), NULL);
154 
155 void
156 spdk_scsi_task_copy_status(struct spdk_scsi_task *dst,
157 			   struct spdk_scsi_task *src)
158 {
159 	dst->status = src->status;
160 }
161 
162 DEFINE_STUB_V(spdk_scsi_task_set_data, (struct spdk_scsi_task *task, void *data, uint32_t len));
163 
164 DEFINE_STUB_V(spdk_scsi_task_process_null_lun, (struct spdk_scsi_task *task));
165 
166 DEFINE_STUB_V(spdk_scsi_task_process_abort, (struct spdk_scsi_task *task));
167 
168 DEFINE_STUB_V(iscsi_put_pdu, (struct spdk_iscsi_pdu *pdu));
169 
170 DEFINE_STUB_V(iscsi_param_free, (struct iscsi_param *params));
171 
172 DEFINE_STUB(iscsi_conn_params_init, int, (struct iscsi_param **params), 0);
173 
174 DEFINE_STUB_V(iscsi_clear_all_transfer_task,
175 	      (struct spdk_iscsi_conn *conn, struct spdk_scsi_lun *lun,
176 	       struct spdk_iscsi_pdu *pdu));
177 
178 DEFINE_STUB(iscsi_build_iovs, int,
179 	    (struct spdk_iscsi_conn *conn, struct iovec *iov, int num_iovs,
180 	     struct spdk_iscsi_pdu *pdu, uint32_t *mapped_length),
181 	    0);
182 
183 DEFINE_STUB_V(iscsi_queue_task,
184 	      (struct spdk_iscsi_conn *conn, struct spdk_iscsi_task *task));
185 
186 DEFINE_STUB_V(iscsi_task_response,
187 	      (struct spdk_iscsi_conn *conn, struct spdk_iscsi_task *task));
188 
189 DEFINE_STUB_V(iscsi_task_mgmt_response,
190 	      (struct spdk_iscsi_conn *conn, struct spdk_iscsi_task *task));
191 
192 bool
193 iscsi_del_transfer_task(struct spdk_iscsi_conn *conn, uint32_t task_tag)
194 {
195 	struct spdk_iscsi_task *task;
196 
197 	task = TAILQ_FIRST(&conn->active_r2t_tasks);
198 	if (task == NULL || task->tag != task_tag) {
199 		return false;
200 	}
201 
202 	TAILQ_REMOVE(&conn->active_r2t_tasks, task, link);
203 	task->is_r2t_active = false;
204 	iscsi_task_put(task);
205 
206 	return true;
207 }
208 
209 DEFINE_STUB(iscsi_handle_incoming_pdus, int, (struct spdk_iscsi_conn *conn), 0);
210 
211 DEFINE_STUB_V(iscsi_free_sess, (struct spdk_iscsi_sess *sess));
212 
213 DEFINE_STUB(iscsi_tgt_node_cleanup_luns, int,
214 	    (struct spdk_iscsi_conn *conn, struct spdk_iscsi_tgt_node *target),
215 	    0);
216 
217 DEFINE_STUB(iscsi_pdu_calc_header_digest, uint32_t,
218 	    (struct spdk_iscsi_pdu *pdu), 0);
219 
220 DEFINE_STUB_V(shutdown_iscsi_conns_done, (void));
221 
222 static struct spdk_iscsi_task *
223 ut_conn_task_get(struct spdk_iscsi_task *parent)
224 {
225 	struct spdk_iscsi_task *task;
226 
227 	task = calloc(1, sizeof(*task));
228 	SPDK_CU_ASSERT_FATAL(task != NULL);
229 
230 	task->scsi.ref = 1;
231 
232 	if (parent) {
233 		task->parent = parent;
234 		parent->scsi.ref++;
235 	}
236 	return task;
237 }
238 
239 static void
240 ut_conn_create_read_tasks(struct spdk_iscsi_task *primary)
241 {
242 	struct spdk_iscsi_task *subtask;
243 	uint32_t remaining_size = 0;
244 
245 	while (1) {
246 		if (primary->current_data_offset < primary->scsi.transfer_len) {
247 			remaining_size = primary->scsi.transfer_len - primary->current_data_offset;
248 
249 			subtask = ut_conn_task_get(primary);
250 
251 			subtask->scsi.offset = primary->current_data_offset;
252 			subtask->scsi.length = spdk_min(SPDK_BDEV_LARGE_BUF_MAX_SIZE, remaining_size);
253 			subtask->scsi.status = SPDK_SCSI_STATUS_GOOD;
254 
255 			primary->current_data_offset += subtask->scsi.length;
256 
257 			TAILQ_INSERT_TAIL(&g_ut_read_tasks, subtask, link);
258 		}
259 
260 		if (primary->current_data_offset == primary->scsi.transfer_len) {
261 			break;
262 		}
263 	}
264 }
265 
266 static void
267 read_task_split_in_order_case(void)
268 {
269 	struct spdk_iscsi_task primary = {};
270 	struct spdk_iscsi_task *task, *tmp;
271 	struct spdk_iscsi_conn conn = {};
272 	struct spdk_iscsi_sess sess = {};
273 
274 	conn.sess = &sess;
275 	conn.sess->DataSequenceInOrder = true;
276 
277 	primary.scsi.transfer_len = SPDK_BDEV_LARGE_BUF_MAX_SIZE * 8;
278 	TAILQ_INIT(&primary.subtask_list);
279 	primary.current_data_offset = 0;
280 	primary.bytes_completed = 0;
281 	primary.scsi.ref = 1;
282 
283 	ut_conn_create_read_tasks(&primary);
284 	SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_ut_read_tasks));
285 
286 	TAILQ_FOREACH(task, &g_ut_read_tasks, link) {
287 		CU_ASSERT(&primary == iscsi_task_get_primary(task));
288 		process_read_task_completion(&conn, task, &primary);
289 	}
290 
291 	CU_ASSERT(primary.bytes_completed == primary.scsi.transfer_len);
292 	CU_ASSERT(primary.scsi.ref == 0);
293 
294 	TAILQ_FOREACH_SAFE(task, &g_ut_read_tasks, link, tmp) {
295 		CU_ASSERT(task->scsi.ref == 0);
296 		TAILQ_REMOVE(&g_ut_read_tasks, task, link);
297 		free(task);
298 	}
299 
300 }
301 
302 static void
303 read_task_split_reverse_order_case(void)
304 {
305 	struct spdk_iscsi_task primary = {};
306 	struct spdk_iscsi_task *task, *tmp;
307 	struct spdk_iscsi_conn conn = {};
308 	struct spdk_iscsi_sess sess = {};
309 
310 	conn.sess = &sess;
311 	conn.sess->DataSequenceInOrder = true;
312 
313 	primary.scsi.transfer_len = SPDK_BDEV_LARGE_BUF_MAX_SIZE * 8;
314 	TAILQ_INIT(&primary.subtask_list);
315 	primary.current_data_offset = 0;
316 	primary.bytes_completed = 0;
317 	primary.scsi.ref = 1;
318 
319 	ut_conn_create_read_tasks(&primary);
320 	SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_ut_read_tasks));
321 
322 	TAILQ_FOREACH_REVERSE(task, &g_ut_read_tasks, read_tasks_head, link) {
323 		CU_ASSERT(&primary == iscsi_task_get_primary(task));
324 		process_read_task_completion(&conn, task, &primary);
325 	}
326 
327 	CU_ASSERT(primary.bytes_completed == primary.scsi.transfer_len);
328 	CU_ASSERT(primary.scsi.ref == 0);
329 
330 	TAILQ_FOREACH_SAFE(task, &g_ut_read_tasks, link, tmp) {
331 		CU_ASSERT(task->scsi.ref == 0);
332 		TAILQ_REMOVE(&g_ut_read_tasks, task, link);
333 		free(task);
334 	}
335 }
336 
337 static void
338 propagate_scsi_error_status_for_split_read_tasks(void)
339 {
340 	struct spdk_iscsi_task primary = {};
341 	struct spdk_iscsi_task task1 = {}, task2 = {}, task3 = {}, task4 = {}, task5 = {}, task6 = {};
342 
343 	struct spdk_iscsi_conn conn = {};
344 	struct spdk_iscsi_sess sess = {};
345 
346 	conn.sess = &sess;
347 	conn.sess->DataSequenceInOrder = true;
348 
349 	primary.scsi.transfer_len = 512 * 6;
350 	primary.scsi.status = SPDK_SCSI_STATUS_GOOD;
351 	TAILQ_INIT(&primary.subtask_list);
352 	primary.scsi.ref = 7;
353 
354 	task1.scsi.offset = 0;
355 	task1.scsi.length = 512;
356 	task1.scsi.status = SPDK_SCSI_STATUS_GOOD;
357 	task1.scsi.ref = 1;
358 	task1.parent = &primary;
359 
360 	task2.scsi.offset = 512;
361 	task2.scsi.length = 512;
362 	task2.scsi.status = SPDK_SCSI_STATUS_CHECK_CONDITION;
363 	task2.scsi.ref = 1;
364 	task2.parent = &primary;
365 
366 	task3.scsi.offset = 512 * 2;
367 	task3.scsi.length = 512;
368 	task3.scsi.status = SPDK_SCSI_STATUS_GOOD;
369 	task3.scsi.ref = 1;
370 	task3.parent = &primary;
371 
372 	task4.scsi.offset = 512 * 3;
373 	task4.scsi.length = 512;
374 	task4.scsi.status = SPDK_SCSI_STATUS_GOOD;
375 	task4.scsi.ref = 1;
376 	task4.parent = &primary;
377 
378 	task5.scsi.offset = 512 * 4;
379 	task5.scsi.length = 512;
380 	task5.scsi.status = SPDK_SCSI_STATUS_GOOD;
381 	task5.scsi.ref = 1;
382 	task5.parent = &primary;
383 
384 	task6.scsi.offset = 512 * 5;
385 	task6.scsi.length = 512;
386 	task6.scsi.status = SPDK_SCSI_STATUS_GOOD;
387 	task6.scsi.ref = 1;
388 	task6.parent = &primary;
389 
390 	/* task2 has check condition status, and verify if the check condition
391 	 * status is propagated to remaining tasks correctly when these tasks complete
392 	 * by the following order, task4, task3, task2, task1, primary, task5, and task6.
393 	 */
394 	process_read_task_completion(&conn, &task4, &primary);
395 	process_read_task_completion(&conn, &task3, &primary);
396 	process_read_task_completion(&conn, &task2, &primary);
397 	process_read_task_completion(&conn, &task1, &primary);
398 	process_read_task_completion(&conn, &task5, &primary);
399 	process_read_task_completion(&conn, &task6, &primary);
400 
401 	CU_ASSERT(primary.scsi.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
402 	CU_ASSERT(task1.scsi.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
403 	CU_ASSERT(task2.scsi.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
404 	CU_ASSERT(task3.scsi.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
405 	CU_ASSERT(task4.scsi.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
406 	CU_ASSERT(task5.scsi.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
407 	CU_ASSERT(task6.scsi.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
408 	CU_ASSERT(primary.bytes_completed == primary.scsi.transfer_len);
409 	CU_ASSERT(TAILQ_EMPTY(&primary.subtask_list));
410 	CU_ASSERT(primary.scsi.ref == 0);
411 	CU_ASSERT(task1.scsi.ref == 0);
412 	CU_ASSERT(task2.scsi.ref == 0);
413 	CU_ASSERT(task3.scsi.ref == 0);
414 	CU_ASSERT(task4.scsi.ref == 0);
415 	CU_ASSERT(task5.scsi.ref == 0);
416 	CU_ASSERT(task6.scsi.ref == 0);
417 }
418 
419 static void
420 process_non_read_task_completion_test(void)
421 {
422 	struct spdk_iscsi_conn conn = {};
423 	struct spdk_iscsi_task primary = {};
424 	struct spdk_iscsi_task task = {};
425 
426 	TAILQ_INIT(&conn.active_r2t_tasks);
427 
428 	primary.bytes_completed = 0;
429 	primary.scsi.transfer_len = 4096 * 3;
430 	primary.scsi.status = SPDK_SCSI_STATUS_GOOD;
431 	primary.scsi.ref = 1;
432 	TAILQ_INSERT_TAIL(&conn.active_r2t_tasks, &primary, link);
433 	primary.is_r2t_active = true;
434 	primary.tag = 1;
435 
436 	/* First subtask which failed. */
437 	task.scsi.length = 4096;
438 	task.scsi.data_transferred = 4096;
439 	task.scsi.status = SPDK_SCSI_STATUS_CHECK_CONDITION;
440 	task.scsi.ref = 1;
441 	task.parent = &primary;
442 	primary.scsi.ref++;
443 
444 	process_non_read_task_completion(&conn, &task, &primary);
445 	CU_ASSERT(!TAILQ_EMPTY(&conn.active_r2t_tasks));
446 	CU_ASSERT(primary.bytes_completed == 4096);
447 	CU_ASSERT(primary.scsi.data_transferred == 0);
448 	CU_ASSERT(primary.scsi.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
449 	CU_ASSERT(task.scsi.ref == 0);
450 	CU_ASSERT(primary.scsi.ref == 1);
451 
452 	/* Second subtask which succeeded. */
453 	task.scsi.length = 4096;
454 	task.scsi.data_transferred = 4096;
455 	task.scsi.status = SPDK_SCSI_STATUS_GOOD;
456 	task.scsi.ref = 1;
457 	task.parent = &primary;
458 	primary.scsi.ref++;
459 
460 	process_non_read_task_completion(&conn, &task, &primary);
461 	CU_ASSERT(!TAILQ_EMPTY(&conn.active_r2t_tasks));
462 	CU_ASSERT(primary.bytes_completed == 4096 * 2);
463 	CU_ASSERT(primary.scsi.data_transferred == 4096);
464 	CU_ASSERT(primary.scsi.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
465 	CU_ASSERT(task.scsi.ref == 0);
466 	CU_ASSERT(primary.scsi.ref == 1);
467 
468 	/* Third and final subtask which succeeded. */
469 	task.scsi.length = 4096;
470 	task.scsi.data_transferred = 4096;
471 	task.scsi.status = SPDK_SCSI_STATUS_GOOD;
472 	task.scsi.ref = 1;
473 	task.parent = &primary;
474 	primary.scsi.ref++;
475 
476 	process_non_read_task_completion(&conn, &task, &primary);
477 	CU_ASSERT(TAILQ_EMPTY(&conn.active_r2t_tasks));
478 	CU_ASSERT(primary.bytes_completed == 4096 * 3);
479 	CU_ASSERT(primary.scsi.data_transferred == 4096 * 2);
480 	CU_ASSERT(primary.scsi.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
481 	CU_ASSERT(task.scsi.ref == 0);
482 	CU_ASSERT(primary.scsi.ref == 0);
483 
484 	/* A tricky case that the R2T was already terminated when the last task completed. */
485 	primary.scsi.ref = 0;
486 	primary.bytes_completed = 4096 * 2;
487 	primary.scsi.data_transferred = 4096 * 2;
488 	primary.scsi.transfer_len = 4096 * 3;
489 	primary.scsi.status = SPDK_SCSI_STATUS_CHECK_CONDITION;
490 	primary.is_r2t_active = false;
491 	task.scsi.length = 4096;
492 	task.scsi.data_transferred = 4096;
493 	task.scsi.status = SPDK_SCSI_STATUS_GOOD;
494 	task.scsi.ref = 1;
495 	task.parent = &primary;
496 	primary.scsi.ref++;
497 
498 	process_non_read_task_completion(&conn, &task, &primary);
499 	CU_ASSERT(primary.bytes_completed == 4096 * 3);
500 	CU_ASSERT(primary.scsi.data_transferred == 4096 * 3);
501 	CU_ASSERT(primary.scsi.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
502 	CU_ASSERT(primary.scsi.ref == 0);
503 }
504 
505 static bool
506 dequeue_pdu(void *_head, struct spdk_iscsi_pdu *pdu)
507 {
508 	TAILQ_HEAD(queued_pdus, spdk_iscsi_pdu) *head = _head;
509 	struct spdk_iscsi_pdu *tmp;
510 
511 	TAILQ_FOREACH(tmp, head, tailq) {
512 		if (tmp == pdu) {
513 			TAILQ_REMOVE(head, tmp, tailq);
514 			return true;
515 		}
516 	}
517 	return false;
518 }
519 
520 static bool
521 dequeue_task(void *_head, struct spdk_iscsi_task *task)
522 {
523 	TAILQ_HEAD(queued_tasks, spdk_iscsi_task) *head = _head;
524 	struct spdk_iscsi_task *tmp;
525 
526 	TAILQ_FOREACH(tmp, head, link) {
527 		if (tmp == task) {
528 			TAILQ_REMOVE(head, tmp, link);
529 			return true;
530 		}
531 	}
532 	return false;
533 }
534 
535 static void
536 iscsi_conn_pdu_dummy_complete(void *arg)
537 {
538 }
539 
540 static void
541 free_tasks_on_connection(void)
542 {
543 	struct spdk_iscsi_conn conn = {};
544 	struct spdk_iscsi_pdu pdu1 = {}, pdu2 = {}, pdu3 = {}, pdu4 = {};
545 	struct spdk_iscsi_task task1 = {}, task2 = {}, task3 = {};
546 	struct spdk_scsi_lun lun1 = {}, lun2 = {};
547 
548 	TAILQ_INIT(&conn.write_pdu_list);
549 	TAILQ_INIT(&conn.snack_pdu_list);
550 	TAILQ_INIT(&conn.queued_datain_tasks);
551 	conn.data_in_cnt = g_iscsi.MaxLargeDataInPerConnection;
552 
553 	pdu1.task = &task1;
554 	pdu2.task = &task2;
555 	pdu3.task = &task3;
556 
557 	pdu1.cb_fn = iscsi_conn_pdu_dummy_complete;
558 	pdu2.cb_fn = iscsi_conn_pdu_dummy_complete;
559 	pdu3.cb_fn = iscsi_conn_pdu_dummy_complete;
560 	pdu4.cb_fn = iscsi_conn_pdu_dummy_complete;
561 
562 	task1.scsi.lun = &lun1;
563 	task2.scsi.lun = &lun2;
564 
565 	task1.is_queued = false;
566 	task2.is_queued = false;
567 	task3.is_queued = true;
568 
569 	/* Test conn->write_pdu_list. */
570 
571 	task1.scsi.ref = 1;
572 	task2.scsi.ref = 1;
573 	task3.scsi.ref = 1;
574 	TAILQ_INSERT_TAIL(&conn.write_pdu_list, &pdu1, tailq);
575 	TAILQ_INSERT_TAIL(&conn.write_pdu_list, &pdu2, tailq);
576 	TAILQ_INSERT_TAIL(&conn.write_pdu_list, &pdu3, tailq);
577 	TAILQ_INSERT_TAIL(&conn.write_pdu_list, &pdu4, tailq);
578 
579 	/* Free all PDUs when exiting connection. */
580 	iscsi_conn_free_tasks(&conn);
581 
582 	CU_ASSERT(TAILQ_EMPTY(&conn.write_pdu_list));
583 	CU_ASSERT(task1.scsi.ref == 0);
584 	CU_ASSERT(task2.scsi.ref == 0);
585 	CU_ASSERT(task3.scsi.ref == 0);
586 
587 	/* Test conn->snack_pdu_list */
588 
589 	task1.scsi.ref = 1;
590 	task2.scsi.ref = 1;
591 	task3.scsi.ref = 1;
592 	pdu1.cb_fn = iscsi_conn_pdu_dummy_complete;
593 	pdu2.cb_fn = iscsi_conn_pdu_dummy_complete;
594 	pdu3.cb_fn = iscsi_conn_pdu_dummy_complete;
595 	TAILQ_INSERT_TAIL(&conn.snack_pdu_list, &pdu1, tailq);
596 	TAILQ_INSERT_TAIL(&conn.snack_pdu_list, &pdu2, tailq);
597 	TAILQ_INSERT_TAIL(&conn.snack_pdu_list, &pdu3, tailq);
598 
599 	/* Free all PDUs and associated tasks when exiting connection. */
600 	iscsi_conn_free_tasks(&conn);
601 
602 	CU_ASSERT(!dequeue_pdu(&conn.snack_pdu_list, &pdu1));
603 	CU_ASSERT(!dequeue_pdu(&conn.snack_pdu_list, &pdu2));
604 	CU_ASSERT(!dequeue_pdu(&conn.snack_pdu_list, &pdu3));
605 	CU_ASSERT(task1.scsi.ref == 0);
606 	CU_ASSERT(task2.scsi.ref == 0);
607 	CU_ASSERT(task3.scsi.ref == 0);
608 
609 	/* Test conn->queued_datain_tasks */
610 
611 	task1.scsi.ref = 1;
612 	task2.scsi.ref = 1;
613 	task3.scsi.ref = 1;
614 	TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task1, link);
615 	TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task2, link);
616 	TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task3, link);
617 
618 	/* Free all tasks which is not queued when exiting connection. */
619 	iscsi_conn_free_tasks(&conn);
620 
621 	CU_ASSERT(!dequeue_task(&conn.queued_datain_tasks, &task1));
622 	CU_ASSERT(!dequeue_task(&conn.queued_datain_tasks, &task2));
623 	CU_ASSERT(dequeue_task(&conn.queued_datain_tasks, &task3));
624 	CU_ASSERT(task1.scsi.ref == 0);
625 	CU_ASSERT(task2.scsi.ref == 0);
626 	CU_ASSERT(task3.scsi.ref == 1);
627 }
628 
629 static void
630 free_tasks_with_queued_datain(void)
631 {
632 	struct spdk_iscsi_conn conn = {};
633 	struct spdk_iscsi_pdu pdu1 = {}, pdu2 = {}, pdu3 = {}, pdu4 = {}, pdu5 = {}, pdu6 = {};
634 	struct spdk_iscsi_task task1 = {}, task2 = {}, task3 = {}, task4 = {}, task5 = {}, task6 = {};
635 
636 	TAILQ_INIT(&conn.write_pdu_list);
637 	TAILQ_INIT(&conn.snack_pdu_list);
638 	TAILQ_INIT(&conn.queued_datain_tasks);
639 
640 	pdu1.task = &task1;
641 	pdu2.task = &task2;
642 	pdu3.task = &task3;
643 	pdu1.cb_fn = iscsi_conn_pdu_dummy_complete;
644 	pdu2.cb_fn = iscsi_conn_pdu_dummy_complete;
645 	pdu3.cb_fn = iscsi_conn_pdu_dummy_complete;
646 
647 	task1.scsi.ref = 1;
648 	task2.scsi.ref = 1;
649 	task3.scsi.ref = 1;
650 
651 	pdu3.bhs.opcode = ISCSI_OP_SCSI_DATAIN;
652 	task3.scsi.offset = 1;
653 	conn.data_in_cnt = 1;
654 
655 	TAILQ_INSERT_TAIL(&conn.write_pdu_list, &pdu1, tailq);
656 	TAILQ_INSERT_TAIL(&conn.write_pdu_list, &pdu2, tailq);
657 	TAILQ_INSERT_TAIL(&conn.write_pdu_list, &pdu3, tailq);
658 
659 	task4.scsi.ref = 1;
660 	task5.scsi.ref = 1;
661 	task6.scsi.ref = 1;
662 
663 	task4.pdu = &pdu4;
664 	task5.pdu = &pdu5;
665 	task6.pdu = &pdu6;
666 	pdu4.cb_fn = iscsi_conn_pdu_dummy_complete;
667 	pdu5.cb_fn = iscsi_conn_pdu_dummy_complete;
668 	pdu6.cb_fn = iscsi_conn_pdu_dummy_complete;
669 
670 	TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task4, link);
671 	TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task5, link);
672 	TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task6, link);
673 
674 	iscsi_conn_free_tasks(&conn);
675 
676 	CU_ASSERT(TAILQ_EMPTY(&conn.write_pdu_list));
677 	CU_ASSERT(TAILQ_EMPTY(&conn.queued_datain_tasks));
678 }
679 
680 static void
681 abort_queued_datain_task_test(void)
682 {
683 	struct spdk_iscsi_conn conn = {};
684 	struct spdk_iscsi_task task = {}, subtask = {};
685 	struct spdk_iscsi_pdu pdu = {};
686 	struct iscsi_bhs_scsi_req *scsi_req;
687 	int rc;
688 
689 	struct spdk_iscsi_sess sess = {};
690 
691 	conn.sess = &sess;
692 	conn.sess->DataSequenceInOrder = true;
693 
694 	TAILQ_INIT(&conn.queued_datain_tasks);
695 	task.scsi.ref = 1;
696 	task.scsi.dxfer_dir = SPDK_SCSI_DIR_FROM_DEV;
697 	task.pdu = &pdu;
698 	TAILQ_INIT(&task.subtask_list);
699 	scsi_req = (struct iscsi_bhs_scsi_req *)&pdu.bhs;
700 	scsi_req->read_bit = 1;
701 
702 	g_new_task = &subtask;
703 
704 	/* Case1: Queue one task, and this task is not executed */
705 	task.scsi.transfer_len = SPDK_BDEV_LARGE_BUF_MAX_SIZE * 3;
706 	task.scsi.offset = 0;
707 	TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task, link);
708 
709 	/* No slots for sub read tasks */
710 	conn.data_in_cnt = g_iscsi.MaxLargeDataInPerConnection;
711 	rc = _iscsi_conn_abort_queued_datain_task(&conn, &task);
712 	CU_ASSERT(rc != 0);
713 	CU_ASSERT(!TAILQ_EMPTY(&conn.queued_datain_tasks));
714 
715 	/* Have slots for sub read tasks */
716 	conn.data_in_cnt = 0;
717 	rc = _iscsi_conn_abort_queued_datain_task(&conn, &task);
718 	CU_ASSERT(rc == 0);
719 	CU_ASSERT(TAILQ_EMPTY(&conn.queued_datain_tasks));
720 	CU_ASSERT(task.current_data_offset == SPDK_BDEV_LARGE_BUF_MAX_SIZE * 3);
721 	CU_ASSERT(task.scsi.ref == 0);
722 	CU_ASSERT(subtask.scsi.offset == 0);
723 	CU_ASSERT(subtask.scsi.length == SPDK_BDEV_LARGE_BUF_MAX_SIZE * 3);
724 	CU_ASSERT(subtask.scsi.ref == 0);
725 
726 	/* Case2: Queue one task, and this task is partially executed */
727 	task.scsi.ref = 1;
728 	task.scsi.transfer_len = SPDK_BDEV_LARGE_BUF_MAX_SIZE * 3;
729 	task.current_data_offset = SPDK_BDEV_LARGE_BUF_MAX_SIZE;
730 	TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task, link);
731 
732 	/* No slots for sub read tasks */
733 	conn.data_in_cnt = g_iscsi.MaxLargeDataInPerConnection;
734 	rc = _iscsi_conn_abort_queued_datain_task(&conn, &task);
735 	CU_ASSERT(rc != 0);
736 	CU_ASSERT(!TAILQ_EMPTY(&conn.queued_datain_tasks));
737 
738 	/* have slots for sub read tasks */
739 	conn.data_in_cnt = 0;
740 	rc = _iscsi_conn_abort_queued_datain_task(&conn, &task);
741 	CU_ASSERT(rc == 0);
742 	CU_ASSERT(task.current_data_offset == SPDK_BDEV_LARGE_BUF_MAX_SIZE * 3);
743 	CU_ASSERT(task.scsi.ref == 2);
744 	CU_ASSERT(TAILQ_FIRST(&task.subtask_list) == &subtask);
745 	CU_ASSERT(subtask.scsi.offset == SPDK_BDEV_LARGE_BUF_MAX_SIZE);
746 	CU_ASSERT(subtask.scsi.length == SPDK_BDEV_LARGE_BUF_MAX_SIZE * 2);
747 	CU_ASSERT(subtask.scsi.ref == 1);
748 
749 	g_new_task = NULL;
750 }
751 
752 static bool
753 datain_task_is_queued(struct spdk_iscsi_conn *conn,
754 		      struct spdk_iscsi_task *task)
755 {
756 	struct spdk_iscsi_task *tmp;
757 
758 	TAILQ_FOREACH(tmp, &conn->queued_datain_tasks, link) {
759 		if (tmp == task) {
760 			return true;
761 		}
762 	}
763 	return false;
764 }
765 static void
766 abort_queued_datain_tasks_test(void)
767 {
768 	struct spdk_iscsi_conn conn = {};
769 	struct spdk_iscsi_task task1 = {}, task2 = {}, task3 = {}, task4 = {}, task5 = {}, task6 = {};
770 	struct spdk_iscsi_task subtask = {};
771 	struct spdk_iscsi_pdu pdu1 = {}, pdu2 = {}, pdu3 = {}, pdu4 = {}, pdu5 = {}, pdu6 = {};
772 	struct spdk_iscsi_pdu mgmt_pdu1 = {}, mgmt_pdu2 = {};
773 	struct spdk_scsi_lun lun1 = {}, lun2 = {};
774 	uint32_t alloc_cmd_sn;
775 	struct iscsi_bhs_scsi_req *scsi_req;
776 	int rc;
777 	struct spdk_iscsi_sess sess = {};
778 
779 	TAILQ_INIT(&conn.queued_datain_tasks);
780 	conn.data_in_cnt = 0;
781 
782 	conn.sess = &sess;
783 	conn.sess->DataSequenceInOrder = true;
784 
785 	g_new_task = &subtask;
786 
787 	alloc_cmd_sn = 88;
788 
789 	pdu1.cmd_sn = alloc_cmd_sn;
790 	alloc_cmd_sn++;
791 	scsi_req = (struct iscsi_bhs_scsi_req *)&pdu1.bhs;
792 	scsi_req->read_bit = 1;
793 	task1.scsi.ref = 1;
794 	task1.current_data_offset = 0;
795 	task1.scsi.transfer_len = 512;
796 	task1.scsi.lun = &lun1;
797 	iscsi_task_set_pdu(&task1, &pdu1);
798 	TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task1, link);
799 
800 	pdu2.cmd_sn = alloc_cmd_sn;
801 	alloc_cmd_sn++;
802 	scsi_req = (struct iscsi_bhs_scsi_req *)&pdu2.bhs;
803 	scsi_req->read_bit = 1;
804 	task2.scsi.ref = 1;
805 	task2.current_data_offset = 0;
806 	task2.scsi.transfer_len = 512;
807 	task2.scsi.lun = &lun2;
808 	iscsi_task_set_pdu(&task2, &pdu2);
809 	TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task2, link);
810 
811 	mgmt_pdu1.cmd_sn = alloc_cmd_sn;
812 	alloc_cmd_sn++;
813 
814 	pdu3.cmd_sn = alloc_cmd_sn;
815 	alloc_cmd_sn++;
816 	scsi_req = (struct iscsi_bhs_scsi_req *)&pdu3.bhs;
817 	scsi_req->read_bit = 1;
818 	task3.scsi.ref = 1;
819 	task3.current_data_offset = 0;
820 	task3.scsi.transfer_len = 512;
821 	task3.scsi.lun = &lun1;
822 	iscsi_task_set_pdu(&task3, &pdu3);
823 	TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task3, link);
824 
825 	pdu4.cmd_sn = alloc_cmd_sn;
826 	alloc_cmd_sn++;
827 	scsi_req = (struct iscsi_bhs_scsi_req *)&pdu4.bhs;
828 	scsi_req->read_bit = 1;
829 	task4.scsi.ref = 1;
830 	task4.current_data_offset = 0;
831 	task4.scsi.transfer_len = 512;
832 	task4.scsi.lun = &lun2;
833 	iscsi_task_set_pdu(&task4, &pdu4);
834 	TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task4, link);
835 
836 	pdu5.cmd_sn = alloc_cmd_sn;
837 	alloc_cmd_sn++;
838 	scsi_req = (struct iscsi_bhs_scsi_req *)&pdu5.bhs;
839 	scsi_req->read_bit = 1;
840 	task5.scsi.ref = 1;
841 	task5.current_data_offset = 0;
842 	task5.scsi.transfer_len = 512;
843 	task5.scsi.lun = &lun1;
844 	iscsi_task_set_pdu(&task5, &pdu5);
845 	TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task5, link);
846 
847 	mgmt_pdu2.cmd_sn = alloc_cmd_sn;
848 	alloc_cmd_sn++;
849 
850 	pdu6.cmd_sn = alloc_cmd_sn;
851 	alloc_cmd_sn++;
852 	scsi_req = (struct iscsi_bhs_scsi_req *)&pdu6.bhs;
853 	scsi_req->read_bit = 1;
854 	task6.scsi.ref = 1;
855 	task6.current_data_offset = 0;
856 	task6.scsi.transfer_len = 512;
857 	task6.scsi.lun = &lun2;
858 	iscsi_task_set_pdu(&task6, &pdu6);
859 	TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task6, link);
860 
861 	rc = iscsi_conn_abort_queued_datain_tasks(&conn, &lun1, &mgmt_pdu1);
862 	CU_ASSERT(rc == 0);
863 	CU_ASSERT(!datain_task_is_queued(&conn, &task1));
864 	CU_ASSERT(datain_task_is_queued(&conn, &task2));
865 	CU_ASSERT(datain_task_is_queued(&conn, &task3));
866 	CU_ASSERT(datain_task_is_queued(&conn, &task4));
867 	CU_ASSERT(datain_task_is_queued(&conn, &task5));
868 	CU_ASSERT(datain_task_is_queued(&conn, &task6));
869 
870 	rc = iscsi_conn_abort_queued_datain_tasks(&conn, &lun2, &mgmt_pdu2);
871 	CU_ASSERT(rc == 0);
872 	CU_ASSERT(!datain_task_is_queued(&conn, &task2));
873 	CU_ASSERT(datain_task_is_queued(&conn, &task3));
874 	CU_ASSERT(!datain_task_is_queued(&conn, &task4));
875 	CU_ASSERT(datain_task_is_queued(&conn, &task5));
876 	CU_ASSERT(datain_task_is_queued(&conn, &task6));
877 
878 	CU_ASSERT(task1.scsi.ref == 0);
879 	CU_ASSERT(task2.scsi.ref == 0);
880 	CU_ASSERT(task3.scsi.ref == 1);
881 	CU_ASSERT(task4.scsi.ref == 0);
882 	CU_ASSERT(task5.scsi.ref == 1);
883 	CU_ASSERT(task6.scsi.ref == 1);
884 	CU_ASSERT(subtask.scsi.ref == 0);
885 
886 	g_new_task = NULL;
887 }
888 
889 int
890 main(int argc, char **argv)
891 {
892 	CU_pSuite	suite = NULL;
893 	unsigned int	num_failures;
894 
895 	CU_initialize_registry();
896 
897 	suite = CU_add_suite("conn_suite", NULL, NULL);
898 
899 	CU_ADD_TEST(suite, read_task_split_in_order_case);
900 	CU_ADD_TEST(suite, read_task_split_reverse_order_case);
901 	CU_ADD_TEST(suite, propagate_scsi_error_status_for_split_read_tasks);
902 	CU_ADD_TEST(suite, process_non_read_task_completion_test);
903 	CU_ADD_TEST(suite, free_tasks_on_connection);
904 	CU_ADD_TEST(suite, free_tasks_with_queued_datain);
905 	CU_ADD_TEST(suite, abort_queued_datain_task_test);
906 	CU_ADD_TEST(suite, abort_queued_datain_tasks_test);
907 
908 	num_failures = spdk_ut_run_tests(argc, argv, NULL);
909 	CU_cleanup_registry();
910 	return num_failures;
911 }
912