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