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;
127
struct iet_volume *volume;
129
session = session_lookup(target, sid);
133
if (!list_empty(&session->conn_list)) {
134
DECLARE_COMPLETION_ONSTACK(done);
135
struct iscsi_conn *conn;
137
session->done = &done;
138
list_for_each_entry(conn, &session->conn_list, list)
141
target_unlock(target);
142
wait_for_completion(&done);
143
target_lock(target, 0);
146
list_for_each_entry(volume, &target->volumes, list){
147
volume_release(volume, sid, 0);
150
return session_free(session);
153
static void iet_session_info_show(struct seq_file *seq, struct iscsi_target *target)
155
struct iscsi_session *session;
157
list_for_each_entry(session, &target->session_list, list) {
158
seq_printf(seq, "\tsid:%llu initiator:%s\n",
159
(unsigned long long) session->sid, session->initiator);
160
conn_info_show(seq, session);
164
static int iet_session_seq_open(struct inode *inode, struct file *file)
167
res = seq_open(file, &iet_seq_op);
169
((struct seq_file *)file->private_data)->private =
170
iet_session_info_show;
174
struct file_operations session_seq_fops = {
175
.owner = THIS_MODULE,
176
.open = iet_session_seq_open,
179
.release = seq_release,