2
* Copyright (C) 2002-2003 Ardis Technolgies <roman@ardistech.com>
4
* Released under the terms of the GNU GPL v2.0.
10
struct iscsi_session *session_lookup(struct iscsi_target *target, u64 sid)
12
struct iscsi_session *session;
14
list_for_each_entry(session, &target->session_list, list) {
15
if (session->sid == sid)
21
static struct iscsi_session *
22
iet_session_alloc(struct iscsi_target *target, struct session_info *info)
25
struct iscsi_session *session;
26
struct iet_volume *vol;
28
dprintk(D_SETUP, "%p %u %#Lx\n", target, target->tid,
29
(unsigned long long) info->sid);
31
session = kzalloc(sizeof(*session), GFP_KERNEL);
35
session->target = target;
36
session->sid = info->sid;
37
memcpy(&session->param, &target->sess_param, sizeof(session->param));
38
session->max_queued_cmnds = target->trgt_param.queued_cmnds;
40
session->exp_cmd_sn = info->exp_cmd_sn;
41
session->max_cmd_sn = info->max_cmd_sn;
43
session->initiator = kstrdup(info->initiator_name, GFP_KERNEL);
44
if (!session->initiator) {
49
INIT_LIST_HEAD(&session->conn_list);
50
INIT_LIST_HEAD(&session->pending_list);
52
spin_lock_init(&session->cmnd_hash_lock);
53
for (i = 0; i < ARRAY_SIZE(session->cmnd_hash); i++)
54
INIT_LIST_HEAD(&session->cmnd_hash[i]);
56
spin_lock_init(&session->ua_hash_lock);
57
for (i = 0; i < ARRAY_SIZE(session->ua_hash); i++)
58
INIT_LIST_HEAD(&session->ua_hash[i]);
60
list_for_each_entry(vol, &target->volumes, list)
61
/* power-on, reset, or bus device reset occurred */
62
ua_establish_for_session(session, vol->lun, 0x29, 0x0);
64
session->next_ttt = 1;
66
spin_lock(&target->session_list_lock);
67
list_add(&session->list, &target->session_list);
68
spin_unlock(&target->session_list_lock);
73
static int session_free(struct iscsi_session *session)
76
struct ua_entry *ua, *tmp;
78
struct iscsi_target *target = session->target;
80
dprintk(D_SETUP, "%#Lx\n", (unsigned long long) session->sid);
82
spin_lock(&target->session_list_lock);
84
assert(list_empty(&session->conn_list));
86
for (i = 0; i < ARRAY_SIZE(session->cmnd_hash); i++) {
87
if (!list_empty(&session->cmnd_hash[i]))
91
for (i = 0; i < ARRAY_SIZE(session->ua_hash); i++) {
92
l = &session->ua_hash[i];
93
list_for_each_entry_safe(ua, tmp, l, entry) {
94
list_del_init(&ua->entry);
99
list_del(&session->list);
101
kfree(session->initiator);
104
spin_unlock(&target->session_list_lock);
109
int session_add(struct iscsi_target *target, struct session_info *info)
111
struct iscsi_session *session;
113
session = session_lookup(target, info->sid);
117
session = iet_session_alloc(target, info);
124
int session_del(struct iscsi_target *target, u64 sid)
126
struct iscsi_session *session;
128
session = session_lookup(target, sid);
132
if (!list_empty(&session->conn_list)) {
133
eprintk("%llu still have connections\n", (unsigned long long) session->sid);
137
return session_free(session);
140
void session_del_all(struct iscsi_target *target)
142
DECLARE_COMPLETION_ONSTACK(done);
143
struct iscsi_session *sess;
145
while (!list_empty(&target->session_list)) {
146
init_completion(&done);
147
target_lock(target, 0);
148
sess = list_entry(target->session_list.next, struct
149
iscsi_session, list);
152
target_unlock(target);
153
wait_for_completion(&done);
154
target_lock(target, 0);
156
target_unlock(target);
160
complete(target->done);
163
static void iet_session_info_show(struct seq_file *seq, struct iscsi_target *target)
165
struct iscsi_session *session;
167
list_for_each_entry(session, &target->session_list, list) {
168
seq_printf(seq, "\tsid:%llu initiator:%s\n",
169
(unsigned long long) session->sid, session->initiator);
170
conn_info_show(seq, session);
174
static int iet_session_seq_open(struct inode *inode, struct file *file)
177
res = seq_open(file, &iet_seq_op);
179
((struct seq_file *)file->private_data)->private =
180
iet_session_info_show;
184
struct file_operations session_seq_fops = {
185
.owner = THIS_MODULE,
186
.open = iet_session_seq_open,
189
.release = seq_release,