xref: /spdk/lib/iscsi/task.h (revision 8afdeef3becfe9409cc9e7372bd0bc10e8b7d46d)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>.
3  *   Copyright (C) 2016 Intel Corporation.
4  *   All rights reserved.
5  */
6 
7 #ifndef SPDK_ISCSI_TASK_H
8 #define SPDK_ISCSI_TASK_H
9 
10 #include "iscsi/iscsi.h"
11 #include "spdk/scsi.h"
12 #include "spdk/util.h"
13 
14 struct spdk_iscsi_task {
15 	struct spdk_scsi_task	scsi;
16 
17 	struct spdk_iscsi_task *parent;
18 
19 	struct spdk_iscsi_conn *conn;
20 	struct spdk_iscsi_pdu *pdu;
21 	struct spdk_mobj *mobj;
22 	uint64_t start_tsc;
23 	uint32_t outstanding_r2t;
24 
25 	uint32_t desired_data_transfer_length;
26 
27 	/* Only valid for Read/Write */
28 	uint32_t bytes_completed;
29 
30 	uint32_t data_out_cnt;
31 
32 	/*
33 	 * Tracks the current offset of large read or write io.
34 	 */
35 	uint32_t current_data_offset;
36 
37 	/*
38 	 * next_expected_r2t_offset is used when we receive
39 	 * the DataOUT PDU.
40 	 */
41 	uint32_t next_expected_r2t_offset;
42 
43 	/*
44 	 * Tracks the length of the R2T that is in progress.
45 	 * Used to check that an R2T burst does not exceed
46 	 *  MaxBurstLength.
47 	 */
48 	uint32_t current_r2t_length;
49 
50 	/*
51 	 * next_r2t_offset is used when we are sending the
52 	 * R2T packet to keep track of next offset of r2t.
53 	 */
54 	uint32_t next_r2t_offset;
55 	uint32_t R2TSN;
56 	uint32_t r2t_datasn; /* record next datasn for a r2tsn */
57 	uint32_t acked_r2tsn; /* next r2tsn to be acked */
58 	uint32_t datain_datasn;
59 	uint32_t acked_data_sn; /* next expected datain datasn */
60 	uint32_t ttt;
61 	bool is_r2t_active;
62 
63 	uint32_t tag;
64 
65 	/**
66 	 * Record the lun id just in case the lun is invalid,
67 	 * which will happen when hot removing the lun.
68 	 */
69 	int lun_id;
70 
71 	struct spdk_poller *mgmt_poller;
72 
73 	TAILQ_ENTRY(spdk_iscsi_task) link;
74 
75 	TAILQ_HEAD(subtask_list, spdk_iscsi_task) subtask_list;
76 	TAILQ_ENTRY(spdk_iscsi_task) subtask_link;
77 	bool is_queued; /* is queued in scsi layer for handling */
78 };
79 
80 static inline void
81 iscsi_task_put(struct spdk_iscsi_task *task)
82 {
83 	spdk_scsi_task_put(&task->scsi);
84 }
85 
86 static inline struct spdk_iscsi_pdu *
87 iscsi_task_get_pdu(struct spdk_iscsi_task *task)
88 {
89 	return task->pdu;
90 }
91 
92 static inline void
93 iscsi_task_set_pdu(struct spdk_iscsi_task *task, struct spdk_iscsi_pdu *pdu)
94 {
95 	task->pdu = pdu;
96 }
97 
98 static inline struct iscsi_bhs *
99 iscsi_task_get_bhs(struct spdk_iscsi_task *task)
100 {
101 	return &iscsi_task_get_pdu(task)->bhs;
102 }
103 
104 static inline void
105 iscsi_task_associate_pdu(struct spdk_iscsi_task *task, struct spdk_iscsi_pdu *pdu)
106 {
107 	iscsi_task_set_pdu(task, pdu);
108 	pdu->ref++;
109 }
110 
111 static inline void
112 iscsi_task_disassociate_pdu(struct spdk_iscsi_task *task)
113 {
114 	if (iscsi_task_get_pdu(task)) {
115 		iscsi_put_pdu(iscsi_task_get_pdu(task));
116 		iscsi_task_set_pdu(task, NULL);
117 	}
118 }
119 
120 static inline int
121 iscsi_task_is_immediate(struct spdk_iscsi_task *task)
122 {
123 	struct iscsi_bhs_scsi_req *scsi_req;
124 
125 	scsi_req = (struct iscsi_bhs_scsi_req *)iscsi_task_get_bhs(task);
126 	return (scsi_req->immediate == 1);
127 }
128 
129 static inline int
130 iscsi_task_is_read(struct spdk_iscsi_task *task)
131 {
132 	struct iscsi_bhs_scsi_req *scsi_req;
133 
134 	scsi_req = (struct iscsi_bhs_scsi_req *)iscsi_task_get_bhs(task);
135 	return (scsi_req->read_bit == 1);
136 }
137 
138 struct spdk_iscsi_task *iscsi_task_get(struct spdk_iscsi_conn *conn,
139 				       struct spdk_iscsi_task *parent,
140 				       spdk_scsi_task_cpl cpl_fn);
141 
142 static inline struct spdk_iscsi_task *
143 iscsi_task_from_scsi_task(struct spdk_scsi_task *task)
144 {
145 	return SPDK_CONTAINEROF(task, struct spdk_iscsi_task, scsi);
146 }
147 
148 static inline struct spdk_iscsi_task *
149 iscsi_task_get_primary(struct spdk_iscsi_task *task)
150 {
151 	if (task->parent) {
152 		return task->parent;
153 	} else {
154 		return task;
155 	}
156 }
157 
158 static inline void
159 iscsi_task_set_mobj(struct spdk_iscsi_task *task, struct spdk_mobj *mobj)
160 {
161 	task->mobj = mobj;
162 }
163 
164 static inline struct spdk_mobj *
165 iscsi_task_get_mobj(struct spdk_iscsi_task *task)
166 {
167 	return task->mobj;
168 }
169 
170 #endif /* SPDK_ISCSI_TASK_H */
171