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