A bunch of pending changes:
[mirror/scst/.git] / iscsi-scst / kernel / iscsi.h
1 /*
2  *  Copyright (C) 2002-2003 Ardis Technolgies <roman@ardistech.com>
3  *  Copyright (C) 2007 Vladislav Bolkhovitin
4  *  Copyright (C) 2007 CMS Distribution Limited
5  * 
6  *  This program is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU General Public License
8  *  as published by the Free Software Foundation, version 2
9  *  of the License.
10  * 
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  *  GNU General Public License for more details.
15  */
16
17 #ifndef __ISCSI_H__
18 #define __ISCSI_H__
19
20 #include <linux/pagemap.h>
21 #include <linux/seq_file.h>
22 #include <linux/mm.h>
23 #include <linux/net.h>
24 #include <net/sock.h>
25
26 #include <scsi_tgt.h>
27
28 #include "iscsi_hdr.h"
29 #include "iscsi_u.h"
30
31 #include "iscsi_dbg.h"
32
33 #define iscsi_sense_crc_error           ABORTED_COMMAND, 0x47, 0x5
34
35 struct iscsi_sess_param {
36         int initial_r2t;
37         int immediate_data;
38         int max_connections;
39         int max_recv_data_length;
40         int max_xmit_data_length;
41         int max_burst_length;
42         int first_burst_length;
43         int default_wait_time;
44         int default_retain_time;
45         int max_outstanding_r2t;
46         int data_pdu_inorder;
47         int data_sequence_inorder;
48         int error_recovery_level;
49         int header_digest;
50         int data_digest;
51         int ofmarker;
52         int ifmarker;
53         int ofmarkint;
54         int ifmarkint;
55 };
56
57 struct iscsi_trgt_param {
58         int queued_cmnds;
59 };
60
61 struct network_thread_info {
62         struct task_struct *task;
63         unsigned int ready;
64 };
65
66 struct iscsi_cmnd;
67
68 struct iscsi_target {
69         struct scst_tgt *scst_tgt;
70
71         struct mutex target_mutex;
72
73         struct list_head session_list; /* protected by target_mutex */
74
75         /* Both protected by target_mutex */
76         struct iscsi_sess_param trgt_sess_param;
77         struct iscsi_trgt_param trgt_param;
78
79         struct list_head target_list_entry;
80         u32 tid;
81         char name[ISCSI_NAME_LEN];
82 };
83
84 #define ISCSI_HASH_ORDER        8
85 #define cmnd_hashfn(itt)        hash_long((itt), ISCSI_HASH_ORDER)
86
87 struct iscsi_session {
88         struct iscsi_target *target;
89         struct scst_session *scst_sess;
90
91         /* Both unprotected, since accessed only from a single read thread */
92         struct list_head pending_list;
93         u32 next_ttt;
94
95         u32 max_queued_cmnds; /* unprotected, since read-only */
96         atomic_t active_cmds;
97
98         spinlock_t sn_lock;
99         u32 exp_cmd_sn; /* protected by sn_lock */
100
101         /* All 3 protected by sn_lock */
102         unsigned int tm_active:1;
103         unsigned int shutting_down:1; /* Let's save some cache footprint by putting it here */
104         u32 tm_sn;
105         struct iscsi_cmnd *tm_rsp;
106
107         /* Read only, if there are connection(s) */
108         struct iscsi_sess_param sess_param;
109
110         spinlock_t cmnd_hash_lock;
111         struct list_head cmnd_hash[1 << ISCSI_HASH_ORDER];
112
113         struct list_head conn_list; /* protected by target_mutex */
114
115         struct list_head session_list_entry;
116
117         struct completion unreg_compl;
118
119         /* Both don't need any protection */
120         char *initiator_name;
121         u64 sid;
122 };
123
124 #define ISCSI_CONN_IOV_MAX                      (PAGE_SIZE/sizeof(struct iovec))
125
126 #define ISCSI_CONN_RD_STATE_IDLE                0
127 #define ISCSI_CONN_RD_STATE_IN_LIST             1               
128 #define ISCSI_CONN_RD_STATE_PROCESSING          2
129
130 #define ISCSI_CONN_WR_STATE_IDLE                0
131 #define ISCSI_CONN_WR_STATE_IN_LIST             1
132 #define ISCSI_CONN_WR_STATE_SPACE_WAIT          2
133 #define ISCSI_CONN_WR_STATE_PROCESSING          3
134
135 struct iscsi_conn {
136         struct iscsi_session *session; /* owning session */
137
138         /* Both protected by session->sn_lock */
139         u32 stat_sn;
140         u32 exp_stat_sn;        
141
142         spinlock_t cmd_list_lock; /* BH lock */
143
144         /* Protected by cmd_list_lock */
145         struct list_head cmd_list; /* in/outcoming pdus */
146
147         atomic_t conn_ref_cnt;
148
149         spinlock_t write_list_lock;
150         /* List of data pdus to be sent, protected by write_list_lock */
151         struct list_head write_list;
152         /* List of data pdus being sent, protected by write_list_lock */
153         struct list_head written_list;
154
155         struct timer_list rsp_timer;
156
157         /* All 2 protected by iscsi_wr_lock */
158         unsigned short wr_state;
159         unsigned short wr_space_ready:1;
160
161         struct list_head wr_list_entry;
162
163 #ifdef EXTRACHECKS
164         struct task_struct *wr_task;
165 #endif
166
167         /* All are unprotected, since accessed only from a single write thread */
168         struct iscsi_cmnd *write_cmnd;
169         struct iovec *write_iop;
170         int write_iop_used;
171         struct iovec write_iov[2];
172         u32 write_size;
173         u32 write_offset;
174         int write_state;
175
176         /* Both don't need any protection */
177         struct file *file;
178         struct socket *sock;
179
180         void (*old_state_change)(struct sock *);
181         void (*old_data_ready)(struct sock *, int);
182         void (*old_write_space)(struct sock *);
183
184         /* Both read only */
185         int hdigest_type;
186         int ddigest_type;
187
188         /* All 4 protected by iscsi_rd_lock */
189         unsigned short rd_state;
190         unsigned short rd_data_ready:1;
191         unsigned short closing:1; /* Let's save some cache footprint by putting it here */
192         unsigned short force_close:1; /* Let's save some cache footprint by putting it here */
193
194         struct list_head rd_list_entry;
195
196 #ifdef EXTRACHECKS
197         struct task_struct *rd_task;
198 #endif
199
200         /* All are unprotected, since accessed only from a single read thread */
201         struct iscsi_cmnd *read_cmnd;
202         struct msghdr read_msg;
203         u32 read_size;
204         int read_state;
205         struct iovec *read_iov;
206
207         struct iscsi_target *target;
208
209         struct list_head conn_list_entry;       /* list entry in session conn_list */
210
211         /* Doesn't need any protection */
212         u16 cid;
213 };
214
215 struct iscsi_pdu {
216         struct iscsi_hdr bhs;
217         void *ahs;
218         unsigned int ahssize;
219         unsigned int datasize;
220 };
221
222 typedef void (iscsi_show_info_t)(struct seq_file *seq, struct iscsi_target *target);
223
224 /* Command's states */
225 #define ISCSI_CMD_STATE_NEW               0     /* New command and SCST processes it */
226 #define ISCSI_CMD_STATE_RX_CMD            1     /* SCST processes cmd after scst_rx_cmd() */
227 #define ISCSI_CMD_STATE_AFTER_PREPROC     2     /* The command returned from preprocessing_done() */
228 #define ISCSI_CMD_STATE_RESTARTED         3     /* scst_restart_cmd() called and SCST processing it */
229 #define ISCSI_CMD_STATE_PROCESSED         4     /* SCST done processing */
230
231 /* 
232  * Most of the fields don't need any protection, since accessed from only a
233  * single thread, except where noted.
234  */
235 struct iscsi_cmnd {
236         struct iscsi_conn *conn;
237
238         /* Some flags protected by conn->write_list_lock */
239         unsigned int hashed:1;
240         unsigned int should_close_conn:1;
241         unsigned int pending:1;
242         unsigned int own_sg:1;
243         unsigned int on_write_list:1;
244         unsigned int write_processing_started:1;
245         unsigned int data_waiting:1;
246         unsigned int force_cleanup_done:1;
247         unsigned int dec_active_cmnds:1;
248         unsigned int ddigest_checked:1;
249         unsigned int on_written_list:1;
250 #ifdef EXTRACHECKS
251         unsigned int on_rx_digest_list:1;
252         unsigned int release_called:1;
253 #endif
254
255         unsigned long tmfabort; /* it's async. with the above flags */
256
257         struct list_head hash_list_entry;
258
259         spinlock_t rsp_cmd_lock; /* BH lock */
260
261         /* Unions are for readability and grepability */
262
263         union {
264                 /* Protected by rsp_cmd_lock */
265                 struct list_head rsp_cmd_list;
266                 struct list_head rsp_cmd_list_entry;
267         };
268
269         union {
270                 struct list_head pending_list_entry;
271                 struct list_head write_list_entry;
272         };
273
274         unsigned long write_timeout;
275
276         /*
277          * Unprotected, since could be accessed from only a single 
278          * thread at time
279          */
280         struct list_head rx_ddigest_cmd_list;
281         struct list_head rx_ddigest_cmd_list_entry;
282
283         struct iscsi_cmnd *parent_req;
284         struct iscsi_cmnd *cmd_req;
285
286         struct iscsi_target *target;
287
288         wait_queue_head_t scst_waitQ;
289         int scst_state;
290         struct scst_cmd *scst_cmd;
291         atomic_t ref_cnt;
292 #ifdef NET_PAGE_CALLBACKS_DEFINED
293         atomic_t net_ref_cnt;
294 #endif
295
296         struct iscsi_pdu pdu;
297
298         struct scatterlist *sg;
299         int bufflen;
300         u32 r2t_sn;
301         u32 r2t_length;
302         u32 is_unsolicited_data;
303         u32 target_task_tag;
304         u32 outstanding_r2t;
305
306         u32 hdigest;
307         u32 ddigest;
308
309         int sg_cnt; /* valid only if own_sg is 1 */
310         struct list_head cmd_list_entry;
311 };
312
313 #define ISCSI_OP_SCSI_REJECT    ISCSI_OP_VENDOR1_CMD
314 #define ISCSI_OP_PDU_REJECT     ISCSI_OP_VENDOR2_CMD
315 #define ISCSI_OP_DATA_REJECT    ISCSI_OP_VENDOR3_CMD
316
317 /* Flags for req_cmnd_release_force() */
318 #define ISCSI_FORCE_RELEASE_WRITE       1
319
320 #define ISCSI_RSP_TIMEOUT       (7*HZ)
321
322 extern struct mutex target_mgmt_mutex;
323
324 extern struct file_operations ctr_fops;
325
326 extern spinlock_t iscsi_rd_lock;
327 extern struct list_head iscsi_rd_list;
328 extern wait_queue_head_t iscsi_rd_waitQ;
329
330 extern spinlock_t iscsi_wr_lock;
331 extern struct list_head iscsi_wr_list;
332 extern wait_queue_head_t iscsi_wr_waitQ;
333
334 /* iscsi.c */
335 extern struct iscsi_cmnd *cmnd_alloc(struct iscsi_conn *,
336         struct iscsi_cmnd *parent);
337 extern int cmnd_rx_start(struct iscsi_cmnd *);
338 extern void cmnd_rx_end(struct iscsi_cmnd *);
339 extern void cmnd_tx_start(struct iscsi_cmnd *);
340 extern void cmnd_tx_end(struct iscsi_cmnd *);
341 extern void req_cmnd_release(struct iscsi_cmnd *req);
342 extern void req_cmnd_release_force(struct iscsi_cmnd *req, int flags);
343 extern void rsp_cmnd_release(struct iscsi_cmnd *);
344 extern void cmnd_done(struct iscsi_cmnd *cmnd);
345 extern void conn_abort(struct iscsi_conn *conn);
346
347 /* conn.c */
348 extern struct iscsi_conn *conn_lookup(struct iscsi_session *, u16);
349 extern int conn_add(struct iscsi_session *, struct conn_info *);
350 extern int conn_del(struct iscsi_session *, struct conn_info *);
351 extern int conn_free(struct iscsi_conn *);
352 extern void __mark_conn_closed(struct iscsi_conn *, bool);
353 extern void mark_conn_closed(struct iscsi_conn *);
354 extern void iscsi_make_conn_wr_active(struct iscsi_conn *);
355 extern void conn_info_show(struct seq_file *, struct iscsi_session *);
356
357 /* nthread.c */
358 extern int iscsi_send(struct iscsi_conn *conn);
359 #ifdef NET_PAGE_CALLBACKS_DEFINED
360 extern void iscsi_get_page_callback(struct page *page);
361 extern void iscsi_put_page_callback(struct page *page);
362 #endif
363 extern int istrd(void *arg);
364 extern int istwr(void *arg);
365
366 /* target.c */
367 struct iscsi_target *target_lookup_by_id(u32);
368 extern int target_add(struct target_info *);
369 extern int target_del(u32 id);
370 extern void target_del_all(void);
371
372 /* config.c */
373 extern int iscsi_procfs_init(void);
374 extern void iscsi_procfs_exit(void);
375 extern int iscsi_info_show(struct seq_file *, iscsi_show_info_t *);
376
377 /* session.c */
378 extern struct file_operations session_seq_fops;
379 extern struct iscsi_session *session_lookup(struct iscsi_target *, u64);
380 extern int session_add(struct iscsi_target *, struct session_info *);
381 extern int session_del(struct iscsi_target *, u64);
382 extern int session_free(struct iscsi_session *session);
383
384 /* params.c */
385 extern int iscsi_param_set(struct iscsi_target *, struct iscsi_param_info *, int);
386
387 /* event.c */
388 extern int event_send(u32, u64, u32, u32, int);
389 extern int event_init(void);
390 extern void event_exit(void);
391
392 #define get_pgcnt(size, offset) ((((size) + ((offset) & ~PAGE_MASK)) + PAGE_SIZE - 1) >> PAGE_SHIFT)
393
394 static inline void iscsi_cmnd_get_length(struct iscsi_pdu *pdu)
395 {
396 #if defined(__BIG_ENDIAN)
397         pdu->ahssize = pdu->bhs.length.ahslength * 4;
398         pdu->datasize = pdu->bhs.length.datalength;
399 #elif defined(__LITTLE_ENDIAN)
400         pdu->ahssize = (pdu->bhs.length & 0xff) * 4;
401         pdu->datasize = be32_to_cpu(pdu->bhs.length & ~0xff);
402 #else
403 #error
404 #endif
405 }
406
407 static inline void iscsi_cmnd_set_length(struct iscsi_pdu *pdu)
408 {
409 #if defined(__BIG_ENDIAN)
410         pdu->bhs.length.ahslength = pdu->ahssize / 4;
411         pdu->bhs.length.datalength = pdu->datasize;
412 #elif defined(__LITTLE_ENDIAN)
413         pdu->bhs.length = cpu_to_be32(pdu->datasize) | (pdu->ahssize / 4);
414 #else
415 #error
416 #endif
417 }
418
419 extern struct scst_tgt_template iscsi_template;
420
421 /*
422  * Skip this command if result is not 0. Must be called under
423  * corresponding lock.
424  */
425 static inline bool cmnd_get_check(struct iscsi_cmnd *cmnd)
426 {
427         int r = atomic_inc_return(&cmnd->ref_cnt);
428         int res;
429         if (unlikely(r == 1)) {
430                 TRACE_DBG("cmnd %p is being destroyed", cmnd);
431                 atomic_dec(&cmnd->ref_cnt);
432                 res = 1;
433                 /* Necessary code is serialized by locks in cmnd_done() */
434         } else {
435                 TRACE_DBG("cmnd %p, new ref_cnt %d", cmnd,
436                         atomic_read(&cmnd->ref_cnt));
437                 res = 0;
438         }
439         return res;
440 }
441
442 static inline void cmnd_get(struct iscsi_cmnd *cmnd)
443 {
444         atomic_inc(&cmnd->ref_cnt);
445         TRACE_DBG("cmnd %p, new cmnd->ref_cnt %d", cmnd,
446                 atomic_read(&cmnd->ref_cnt));
447 }
448
449 static inline void cmnd_get_ordered(struct iscsi_cmnd *cmnd)
450 {
451         cmnd_get(cmnd);
452         smp_mb__after_atomic_inc();
453 }
454
455 static inline void cmnd_put(struct iscsi_cmnd *cmnd)
456 {
457         TRACE_DBG("cmnd %p, new ref_cnt %d", cmnd,
458                 atomic_read(&cmnd->ref_cnt)-1);
459         sBUG_ON(atomic_read(&cmnd->ref_cnt) == 0);
460         if (atomic_dec_and_test(&cmnd->ref_cnt))
461                 cmnd_done(cmnd);
462 }
463
464 /* conn->write_list_lock supposed to be locked and BHs off */
465 static inline void cmd_add_on_write_list(struct iscsi_conn *conn,
466         struct iscsi_cmnd *cmnd)
467 {
468         TRACE_DBG("%p", cmnd);
469         list_add_tail(&cmnd->write_list_entry, &conn->write_list);
470         cmnd->on_write_list = 1;
471 }
472
473 /* conn->write_list_lock supposed to be locked and BHs off */
474 static inline void cmd_del_from_write_list(struct iscsi_cmnd *cmnd)
475 {
476         TRACE_DBG("%p", cmnd);
477         list_del(&cmnd->write_list_entry);
478         cmnd->on_write_list = 0;
479 }
480
481 static inline void cmd_add_on_rx_ddigest_list(struct iscsi_cmnd *req,
482         struct iscsi_cmnd *cmnd)
483 {
484         TRACE_DBG("Adding RX ddigest cmd %p to digest list "
485                         "of req %p", cmnd, req);
486         list_add_tail(&cmnd->rx_ddigest_cmd_list_entry,
487                         &req->rx_ddigest_cmd_list);
488 #ifdef EXTRACHECKS
489         cmnd->on_rx_digest_list = 1;
490 #endif
491 }
492
493 static inline void cmd_del_from_rx_ddigest_list(struct iscsi_cmnd *cmnd)
494 {
495         TRACE_DBG("Deleting RX digest cmd %p from digest list", cmnd);
496         list_del(&cmnd->rx_ddigest_cmd_list_entry);
497 #ifdef EXTRACHECKS
498         cmnd->on_rx_digest_list = 0;
499 #endif
500 }
501
502 static inline int test_write_ready(struct iscsi_conn *conn)
503 {
504         /*
505          * No need for write_list protection, in the worst case we will be
506          * restarted again.
507          */
508         return (!list_empty(&conn->write_list) || conn->write_cmnd);
509 }
510
511 static inline void conn_get(struct iscsi_conn *conn)
512 {
513         atomic_inc(&conn->conn_ref_cnt);
514         TRACE_DBG("conn %p, new conn_ref_cnt %d", conn,
515                 atomic_read(&conn->conn_ref_cnt));
516 }
517
518 static inline void conn_get_ordered(struct iscsi_conn *conn)
519 {
520         conn_get(conn);
521         smp_mb__after_atomic_inc();
522 }
523
524 static inline void conn_put(struct iscsi_conn *conn)
525 {
526         TRACE_DBG("conn %p, new conn_ref_cnt %d", conn,
527                 atomic_read(&conn->conn_ref_cnt)-1);
528         sBUG_ON(atomic_read(&conn->conn_ref_cnt) == 0);
529
530         /* 
531          * It always ordered to protect from undesired side effects like
532          * accessing just destroyed object because of this *_dec() reordering.
533          */
534         smp_mb__before_atomic_dec();
535         atomic_dec(&conn->conn_ref_cnt);
536 }
537
538 #ifdef EXTRACHECKS
539 extern void iscsi_extracheck_is_rd_thread(struct iscsi_conn *conn);
540 extern void iscsi_extracheck_is_wr_thread(struct iscsi_conn *conn);
541 #else
542 static inline void iscsi_extracheck_is_rd_thread(struct iscsi_conn *conn) {}
543 static inline void iscsi_extracheck_is_wr_thread(struct iscsi_conn *conn) {}
544 #endif
545
546 #endif  /* __ISCSI_H__ */