~ubuntu-branches/ubuntu/precise/linux-ti-omap/precise

« back to all changes in this revision

Viewing changes to ubuntu/iscsitarget/session.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Bader, Amit Kucheria
  • Date: 2010-03-23 18:05:12 UTC
  • Revision ID: james.westby@ubuntu.com-20100323180512-iavj906ocnphdubp
Tags: 2.6.33-500.3
[ Amit Kucheria ]

* [Config] Fix the debug package name to end in -dbgsym
* SAUCE: Add the ubuntu/ drivers to omap
* SAUCE: Re-export the symbols for aufs
* [Config] Enable AUFS and COMPCACHE

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2002-2003 Ardis Technolgies <roman@ardistech.com>
 
3
 *
 
4
 * Released under the terms of the GNU GPL v2.0.
 
5
 */
 
6
 
 
7
#include "iscsi.h"
 
8
#include "iscsi_dbg.h"
 
9
 
 
10
struct iscsi_session *session_lookup(struct iscsi_target *target, u64 sid)
 
11
{
 
12
        struct iscsi_session *session;
 
13
 
 
14
        list_for_each_entry(session, &target->session_list, list) {
 
15
                if (session->sid == sid)
 
16
                        return session;
 
17
        }
 
18
        return NULL;
 
19
}
 
20
 
 
21
static struct iscsi_session *
 
22
iet_session_alloc(struct iscsi_target *target, struct session_info *info)
 
23
{
 
24
        int i;
 
25
        struct iscsi_session *session;
 
26
        struct iet_volume *vol;
 
27
 
 
28
        dprintk(D_SETUP, "%p %u %#Lx\n", target, target->tid,
 
29
                (unsigned long long) info->sid);
 
30
 
 
31
        session = kzalloc(sizeof(*session), GFP_KERNEL);
 
32
        if (!session)
 
33
                return NULL;
 
34
 
 
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;
 
39
 
 
40
        session->exp_cmd_sn = info->exp_cmd_sn;
 
41
        session->max_cmd_sn = info->max_cmd_sn;
 
42
 
 
43
        session->initiator = kstrdup(info->initiator_name, GFP_KERNEL);
 
44
        if (!session->initiator) {
 
45
                kfree(session);
 
46
                return NULL;
 
47
        }
 
48
 
 
49
        INIT_LIST_HEAD(&session->conn_list);
 
50
        INIT_LIST_HEAD(&session->pending_list);
 
51
 
 
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]);
 
55
 
 
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]);
 
59
 
 
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);
 
63
 
 
64
        session->next_ttt = 1;
 
65
 
 
66
        spin_lock(&target->session_list_lock);
 
67
        list_add(&session->list, &target->session_list);
 
68
        spin_unlock(&target->session_list_lock);
 
69
 
 
70
        return session;
 
71
}
 
72
 
 
73
static int session_free(struct iscsi_session *session)
 
74
{
 
75
        int i;
 
76
        struct ua_entry *ua, *tmp;
 
77
        struct list_head *l;
 
78
        struct iscsi_target *target = session->target;
 
79
 
 
80
        dprintk(D_SETUP, "%#Lx\n", (unsigned long long) session->sid);
 
81
 
 
82
        spin_lock(&target->session_list_lock);
 
83
 
 
84
        assert(list_empty(&session->conn_list));
 
85
 
 
86
        for (i = 0; i < ARRAY_SIZE(session->cmnd_hash); i++) {
 
87
                if (!list_empty(&session->cmnd_hash[i]))
 
88
                        BUG();
 
89
        }
 
90
 
 
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);
 
95
                        ua_free(ua);
 
96
                }
 
97
        }
 
98
 
 
99
        list_del(&session->list);
 
100
 
 
101
        kfree(session->initiator);
 
102
        kfree(session);
 
103
 
 
104
        spin_unlock(&target->session_list_lock);
 
105
 
 
106
        return 0;
 
107
}
 
108
 
 
109
int session_add(struct iscsi_target *target, struct session_info *info)
 
110
{
 
111
        struct iscsi_session *session;
 
112
 
 
113
        session = session_lookup(target, info->sid);
 
114
        if (session)
 
115
                return -EEXIST;
 
116
 
 
117
        session = iet_session_alloc(target, info);
 
118
        if (!session)
 
119
                return -ENOMEM;
 
120
 
 
121
        return 0;
 
122
}
 
123
 
 
124
int session_del(struct iscsi_target *target, u64 sid)
 
125
{
 
126
        struct iscsi_session *session;
 
127
 
 
128
        session = session_lookup(target, sid);
 
129
        if (!session)
 
130
                return -ENOENT;
 
131
 
 
132
        if (!list_empty(&session->conn_list)) {
 
133
                eprintk("%llu still have connections\n", (unsigned long long) session->sid);
 
134
                return -EBUSY;
 
135
        }
 
136
 
 
137
        return session_free(session);
 
138
}
 
139
 
 
140
void session_del_all(struct iscsi_target *target)
 
141
{
 
142
        DECLARE_COMPLETION_ONSTACK(done);
 
143
        struct iscsi_session *sess;
 
144
 
 
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);
 
150
                sess->done = &done;
 
151
                conn_del_all(sess);
 
152
                target_unlock(target);
 
153
                wait_for_completion(&done);
 
154
                target_lock(target, 0);
 
155
                session_free(sess);
 
156
                target_unlock(target);
 
157
        }
 
158
 
 
159
        if (target->done)
 
160
                complete(target->done);
 
161
}
 
162
 
 
163
static void iet_session_info_show(struct seq_file *seq, struct iscsi_target *target)
 
164
{
 
165
        struct iscsi_session *session;
 
166
 
 
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);
 
171
        }
 
172
}
 
173
 
 
174
static int iet_session_seq_open(struct inode *inode, struct file *file)
 
175
{
 
176
        int res;
 
177
        res = seq_open(file, &iet_seq_op);
 
178
        if (!res)
 
179
                ((struct seq_file *)file->private_data)->private =
 
180
                        iet_session_info_show;
 
181
        return res;
 
182
}
 
183
 
 
184
struct file_operations session_seq_fops = {
 
185
        .owner          = THIS_MODULE,
 
186
        .open           = iet_session_seq_open,
 
187
        .read           = seq_read,
 
188
        .llseek         = seq_lseek,
 
189
        .release        = seq_release,
 
190
};