2 * Copyright (C) 2002 - 2003 Ardis Technolgies <roman@ardistech.com>
3 * Copyright (C) 2007 - 2009 Vladislav Bolkhovitin
4 * Copyright (C) 2007 - 2009 ID7 Ltd.
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
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.
17 #include <linux/file.h>
24 static int print_conn_state(char *p, size_t size, struct iscsi_conn *conn)
29 pos += scnprintf(p, size, "%s", "closing");
33 switch (conn->rd_state) {
34 case ISCSI_CONN_RD_STATE_PROCESSING:
35 pos += scnprintf(&p[pos], size - pos, "%s", "read_processing ");
37 case ISCSI_CONN_RD_STATE_IN_LIST:
38 pos += scnprintf(&p[pos], size - pos, "%s", "in_read_list ");
42 switch (conn->wr_state) {
43 case ISCSI_CONN_WR_STATE_PROCESSING:
44 pos += scnprintf(&p[pos], size - pos, "%s", "write_processing ");
46 case ISCSI_CONN_WR_STATE_IN_LIST:
47 pos += scnprintf(&p[pos], size - pos, "%s", "in_write_list ");
49 case ISCSI_CONN_WR_STATE_SPACE_WAIT:
50 pos += scnprintf(&p[pos], size - pos, "%s", "space_waiting ");
54 if (test_bit(ISCSI_CONN_REINSTATING, &conn->conn_aflags))
55 pos += scnprintf(&p[pos], size - pos, "%s", "reinstating ");
57 pos += scnprintf(&p[pos], size - pos, "%s", "established idle ");
63 #ifdef CONFIG_SCST_PROC
65 /* target_mutex supposed to be locked */
66 void conn_info_show(struct seq_file *seq, struct iscsi_session *session)
68 struct iscsi_conn *conn;
72 list_for_each_entry(conn, &session->conn_list, conn_list_entry) {
74 switch (sk->sk_family) {
76 snprintf(buf, sizeof(buf),
77 "%u.%u.%u.%u", NIPQUAD(inet_sk(sk)->daddr));
80 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
81 snprintf(buf, sizeof(buf),
82 "[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]",
83 NIP6(inet6_sk(sk)->daddr));
85 snprintf(buf, sizeof(buf), "[%p6]",
86 &inet6_sk(sk)->daddr);
90 snprintf(buf, sizeof(buf), "Unknown family %d",
94 seq_printf(seq, "\t\tcid:%u ip:%s ", conn->cid, buf);
95 print_conn_state(buf, sizeof(buf), conn);
96 seq_printf(seq, "state:%s ", buf);
97 print_digest_state(buf, sizeof(buf), conn->hdigest_type);
98 seq_printf(seq, "hd:%s ", buf);
99 print_digest_state(buf, sizeof(buf), conn->ddigest_type);
100 seq_printf(seq, "dd:%s\n", buf);
104 #else /* CONFIG_SCST_PROC */
106 static int conn_free(struct iscsi_conn *conn);
108 static void iscsi_conn_release(struct kobject *kobj)
110 struct iscsi_conn *conn;
111 struct iscsi_target *target;
115 conn = container_of(kobj, struct iscsi_conn, iscsi_conn_kobj);
116 target = conn->target;
118 mutex_lock(&target->target_mutex);
120 mutex_unlock(&target->target_mutex);
126 static struct kobj_type iscsi_conn_ktype = {
127 .sysfs_ops = &scst_sysfs_ops,
128 .release = iscsi_conn_release,
131 static ssize_t iscsi_get_initiator_ip(struct iscsi_conn *conn,
140 switch (sk->sk_family) {
142 pos = scnprintf(buf, size,
143 "%u.%u.%u.%u", NIPQUAD(inet_sk(sk)->daddr));
146 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
147 pos = scnprintf(buf, size,
148 "[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]",
149 NIP6(inet6_sk(sk)->daddr));
151 pos = scnprintf(buf, size, "[%p6]",
152 &inet6_sk(sk)->daddr);
156 pos = scnprintf(buf, size, "Unknown family %d",
165 static ssize_t iscsi_conn_ip_show(struct kobject *kobj,
166 struct kobj_attribute *attr, char *buf)
169 struct iscsi_conn *conn;
173 conn = container_of(kobj, struct iscsi_conn, iscsi_conn_kobj);
175 pos = iscsi_get_initiator_ip(conn, buf, SCST_SYSFS_BLOCK_SIZE);
181 static struct kobj_attribute iscsi_conn_ip_attr =
182 __ATTR(ip, S_IRUGO, iscsi_conn_ip_show, NULL);
184 static ssize_t iscsi_conn_cid_show(struct kobject *kobj,
185 struct kobj_attribute *attr, char *buf)
188 struct iscsi_conn *conn;
192 conn = container_of(kobj, struct iscsi_conn, iscsi_conn_kobj);
194 pos = sprintf(buf, "%u", conn->cid);
200 static struct kobj_attribute iscsi_conn_cid_attr =
201 __ATTR(cid, S_IRUGO, iscsi_conn_cid_show, NULL);
203 static ssize_t iscsi_conn_state_show(struct kobject *kobj,
204 struct kobj_attribute *attr, char *buf)
207 struct iscsi_conn *conn;
211 conn = container_of(kobj, struct iscsi_conn, iscsi_conn_kobj);
213 pos = print_conn_state(buf, SCST_SYSFS_BLOCK_SIZE, conn);
219 static struct kobj_attribute iscsi_conn_state_attr =
220 __ATTR(state, S_IRUGO, iscsi_conn_state_show, NULL);
222 #endif /* CONFIG_SCST_PROC */
224 /* target_mutex supposed to be locked */
225 struct iscsi_conn *conn_lookup(struct iscsi_session *session, u16 cid)
227 struct iscsi_conn *conn;
230 * We need to find the latest conn to correctly handle
231 * multi-reinstatements
233 list_for_each_entry_reverse(conn, &session->conn_list,
235 if (conn->cid == cid)
241 void iscsi_make_conn_rd_active(struct iscsi_conn *conn)
245 spin_lock_bh(&iscsi_rd_lock);
247 TRACE_DBG("conn %p, rd_state %x, rd_data_ready %d", conn,
248 conn->rd_state, conn->rd_data_ready);
250 conn->rd_data_ready = 1;
252 if (conn->rd_state == ISCSI_CONN_RD_STATE_IDLE) {
253 list_add_tail(&conn->rd_list_entry, &iscsi_rd_list);
254 conn->rd_state = ISCSI_CONN_RD_STATE_IN_LIST;
255 wake_up(&iscsi_rd_waitQ);
258 spin_unlock_bh(&iscsi_rd_lock);
264 void iscsi_make_conn_wr_active(struct iscsi_conn *conn)
268 spin_lock_bh(&iscsi_wr_lock);
270 TRACE_DBG("conn %p, wr_state %x, wr_space_ready %d", conn,
271 conn->wr_state, conn->wr_space_ready);
273 if (conn->wr_state == ISCSI_CONN_WR_STATE_IDLE) {
274 list_add_tail(&conn->wr_list_entry, &iscsi_wr_list);
275 conn->wr_state = ISCSI_CONN_WR_STATE_IN_LIST;
276 wake_up(&iscsi_wr_waitQ);
279 spin_unlock_bh(&iscsi_wr_lock);
285 void __mark_conn_closed(struct iscsi_conn *conn, int flags)
287 spin_lock_bh(&iscsi_rd_lock);
289 if (flags & ISCSI_CONN_ACTIVE_CLOSE)
290 conn->active_close = 1;
291 if (flags & ISCSI_CONN_DELETING)
293 spin_unlock_bh(&iscsi_rd_lock);
295 iscsi_make_conn_rd_active(conn);
298 void mark_conn_closed(struct iscsi_conn *conn)
300 __mark_conn_closed(conn, ISCSI_CONN_ACTIVE_CLOSE);
303 static void __iscsi_state_change(struct sock *sk)
305 struct iscsi_conn *conn = sk->sk_user_data;
309 if (unlikely(sk->sk_state != TCP_ESTABLISHED)) {
310 if (!conn->closing) {
311 PRINT_ERROR("Connection with initiator %s "
312 "unexpectedly closed!",
313 conn->session->initiator_name);
314 TRACE_MGMT_DBG("conn %p, sk state %d", conn,
316 __mark_conn_closed(conn, 0);
319 iscsi_make_conn_rd_active(conn);
325 static void iscsi_state_change(struct sock *sk)
327 struct iscsi_conn *conn = sk->sk_user_data;
329 __iscsi_state_change(sk);
330 conn->old_state_change(sk);
335 static void iscsi_data_ready(struct sock *sk, int len)
337 struct iscsi_conn *conn = sk->sk_user_data;
341 iscsi_make_conn_rd_active(conn);
343 conn->old_data_ready(sk, len);
349 static void iscsi_write_space_ready(struct sock *sk)
351 struct iscsi_conn *conn = sk->sk_user_data;
355 TRACE_DBG("Write space ready for conn %p", conn);
357 spin_lock_bh(&iscsi_wr_lock);
358 conn->wr_space_ready = 1;
359 if ((conn->wr_state == ISCSI_CONN_WR_STATE_SPACE_WAIT)) {
360 list_add_tail(&conn->wr_list_entry, &iscsi_wr_list);
361 conn->wr_state = ISCSI_CONN_WR_STATE_IN_LIST;
362 wake_up(&iscsi_wr_waitQ);
364 spin_unlock_bh(&iscsi_wr_lock);
366 conn->old_write_space(sk);
372 static void conn_rsp_timer_fn(unsigned long arg)
374 struct iscsi_conn *conn = (struct iscsi_conn *)arg;
378 TRACE_DBG("Timer (conn %p)", conn);
380 spin_lock_bh(&conn->write_list_lock);
382 if (!list_empty(&conn->written_list)) {
383 struct iscsi_cmnd *wr_cmd = list_entry(conn->written_list.next,
384 struct iscsi_cmnd, written_list_entry);
386 if (unlikely(time_after_eq(jiffies, wr_cmd->write_timeout))) {
387 if (!conn->closing) {
388 PRINT_ERROR("Timeout sending data to initiator"
389 " %s (SID %llx), closing connection",
390 conn->session->initiator_name,
391 (long long unsigned int)
393 mark_conn_closed(conn);
396 TRACE_DBG("Restarting timer on %ld (conn %p)",
397 wr_cmd->write_timeout, conn);
399 * Timer might have been restarted while we were
402 mod_timer(&conn->rsp_timer, wr_cmd->write_timeout);
406 spin_unlock_bh(&conn->write_list_lock);
412 /* target_mutex supposed to be locked */
413 void conn_reinst_finished(struct iscsi_conn *conn)
415 struct iscsi_cmnd *cmnd, *t;
419 clear_bit(ISCSI_CONN_REINSTATING, &conn->conn_aflags);
421 list_for_each_entry_safe(cmnd, t, &conn->reinst_pending_cmd_list,
422 reinst_pending_cmd_list_entry) {
423 TRACE_MGMT_DBG("Restarting reinst pending cmnd %p",
425 list_del(&cmnd->reinst_pending_cmd_list_entry);
426 iscsi_restart_cmnd(cmnd);
433 static void conn_activate(struct iscsi_conn *conn)
435 TRACE_MGMT_DBG("Enabling conn %p", conn);
437 /* Catch double bind */
438 sBUG_ON(conn->sock->sk->sk_state_change == iscsi_state_change);
440 write_lock_bh(&conn->sock->sk->sk_callback_lock);
442 conn->old_state_change = conn->sock->sk->sk_state_change;
443 conn->sock->sk->sk_state_change = iscsi_state_change;
445 conn->old_data_ready = conn->sock->sk->sk_data_ready;
446 conn->sock->sk->sk_data_ready = iscsi_data_ready;
448 conn->old_write_space = conn->sock->sk->sk_write_space;
449 conn->sock->sk->sk_write_space = iscsi_write_space_ready;
451 write_unlock_bh(&conn->sock->sk->sk_callback_lock);
454 * Check, if conn was closed while we were initializing it.
455 * This function will make conn rd_active, if necessary.
457 __iscsi_state_change(conn->sock->sk);
463 * Note: the code below passes a kernel space pointer (&opt) to setsockopt()
464 * while the declaration of setsockopt specifies that it expects a user space
465 * pointer. This seems to work fine, and this approach is also used in some
466 * other parts of the Linux kernel (see e.g. fs/ocfs2/cluster/tcp.c).
468 static int conn_setup_sock(struct iscsi_conn *conn)
473 struct iscsi_session *session = conn->session;
475 TRACE_DBG("%llu", (long long unsigned int)session->sid);
477 conn->sock = SOCKET_I(conn->file->f_dentry->d_inode);
479 if (conn->sock->ops->sendpage == NULL) {
480 PRINT_ERROR("Socket for sid %llu doesn't support sendpage()",
481 (long long unsigned int)session->sid);
487 conn->sock->sk->sk_allocation = GFP_NOIO;
489 conn->sock->sk->sk_user_data = conn;
493 conn->sock->ops->setsockopt(conn->sock, SOL_TCP, TCP_NODELAY,
494 (void __force __user *)&opt, sizeof(opt));
501 /* target_mutex supposed to be locked */
502 #ifdef CONFIG_SCST_PROC
503 int conn_free(struct iscsi_conn *conn)
505 static int conn_free(struct iscsi_conn *conn)
508 struct iscsi_session *session = conn->session;
510 TRACE_MGMT_DBG("Freeing conn %p (sess=%p, %#Lx %u)", conn,
511 session, (long long unsigned int)session->sid, conn->cid);
513 del_timer_sync(&conn->rsp_timer);
515 sBUG_ON(atomic_read(&conn->conn_ref_cnt) != 0);
516 sBUG_ON(!list_empty(&conn->cmd_list));
517 sBUG_ON(!list_empty(&conn->write_list));
518 sBUG_ON(!list_empty(&conn->written_list));
519 sBUG_ON(conn->conn_reinst_successor != NULL);
520 sBUG_ON(!test_bit(ISCSI_CONN_SHUTTINGDOWN, &conn->conn_aflags));
522 /* Just in case if new conn gets freed before the old one */
523 if (test_bit(ISCSI_CONN_REINSTATING, &conn->conn_aflags)) {
524 struct iscsi_conn *c;
525 TRACE_MGMT_DBG("Freeing being reinstated conn %p", conn);
526 list_for_each_entry(c, &session->conn_list,
528 if (c->conn_reinst_successor == conn) {
529 c->conn_reinst_successor = NULL;
535 list_del(&conn->conn_list_entry);
541 free_page((unsigned long)conn->read_iov);
545 if (list_empty(&session->conn_list)) {
546 sBUG_ON(session->sess_reinst_successor != NULL);
547 session_free(session, true);
553 /* target_mutex supposed to be locked */
554 static int iscsi_conn_alloc(struct iscsi_session *session,
555 struct iscsi_kern_conn_info *info, struct iscsi_conn **new_conn)
557 struct iscsi_conn *conn;
559 #ifndef CONFIG_SCST_PROC
560 struct iscsi_conn *c;
565 conn = kzalloc(sizeof(*conn), GFP_KERNEL);
571 TRACE_MGMT_DBG("Creating connection %p for sid %#Lx, cid %u", conn,
572 (long long unsigned int)session->sid, info->cid);
574 /* Changing it, change ISCSI_CONN_IOV_MAX as well !! */
575 conn->read_iov = (struct iovec *)get_zeroed_page(GFP_KERNEL);
576 if (conn->read_iov == NULL) {
578 goto out_err_free_conn;
581 atomic_set(&conn->conn_ref_cnt, 0);
582 conn->session = session;
583 if (session->sess_reinstating)
584 __set_bit(ISCSI_CONN_REINSTATING, &conn->conn_aflags);
585 conn->cid = info->cid;
586 conn->stat_sn = info->stat_sn;
587 conn->exp_stat_sn = info->exp_stat_sn;
588 conn->rd_state = ISCSI_CONN_RD_STATE_IDLE;
589 conn->wr_state = ISCSI_CONN_WR_STATE_IDLE;
591 conn->hdigest_type = session->sess_param.header_digest;
592 conn->ddigest_type = session->sess_param.data_digest;
593 res = digest_init(conn);
597 conn->target = session->target;
598 spin_lock_init(&conn->cmd_list_lock);
599 INIT_LIST_HEAD(&conn->cmd_list);
600 spin_lock_init(&conn->write_list_lock);
601 INIT_LIST_HEAD(&conn->write_list);
602 INIT_LIST_HEAD(&conn->written_list);
603 setup_timer(&conn->rsp_timer, conn_rsp_timer_fn, (unsigned long)conn);
604 init_waitqueue_head(&conn->read_state_waitQ);
605 init_completion(&conn->ready_to_free);
606 INIT_LIST_HEAD(&conn->reinst_pending_cmd_list);
608 conn->file = fget(info->fd);
610 res = conn_setup_sock(conn);
614 #ifndef CONFIG_SCST_PROC
615 iscsi_get_initiator_ip(conn, addr, sizeof(addr));
618 list_for_each_entry(c, &session->conn_list, conn_list_entry) {
619 if (strcmp(addr, conn->iscsi_conn_kobj.name) == 0) {
622 iscsi_get_initiator_ip(conn, c_addr, sizeof(c_addr));
624 TRACE_DBG("Dublicated conn from the same initiator "
627 snprintf(addr, sizeof(addr), "%s_%d", c_addr, n);
633 res = kobject_init_and_add(&conn->iscsi_conn_kobj, &iscsi_conn_ktype,
634 scst_sysfs_get_sess_kobj(session->scst_sess), addr);
636 PRINT_ERROR("Unable create sysfs entries for conn %s",
641 TRACE_DBG("conn %p, iscsi_conn_kobj %p", conn, &conn->iscsi_conn_kobj);
643 res = sysfs_create_file(&conn->iscsi_conn_kobj,
644 &iscsi_conn_state_attr.attr);
646 PRINT_ERROR("Unable create sysfs attribute %s for conn %s",
647 iscsi_conn_state_attr.attr.name, addr);
651 res = sysfs_create_file(&conn->iscsi_conn_kobj,
652 &iscsi_conn_cid_attr.attr);
654 PRINT_ERROR("Unable create sysfs attribute %s for conn %s",
655 iscsi_conn_cid_attr.attr.name, addr);
659 res = sysfs_create_file(&conn->iscsi_conn_kobj,
660 &iscsi_conn_ip_attr.attr);
662 PRINT_ERROR("Unable create sysfs attribute %s for conn %s",
663 iscsi_conn_ip_attr.attr.name, addr);
666 #endif /* CONFIG_SCST_PROC */
668 list_add_tail(&conn->conn_list_entry, &session->conn_list);
675 #ifndef CONFIG_SCST_PROC
677 kobject_put(&conn->iscsi_conn_kobj);
685 free_page((unsigned long)conn->read_iov);
694 /* target_mutex supposed to be locked */
695 int conn_add(struct iscsi_session *session, struct iscsi_kern_conn_info *info)
697 struct iscsi_conn *conn, *new_conn = NULL;
699 bool reinstatement = false;
701 conn = conn_lookup(session, info->cid);
702 if ((conn != NULL) &&
703 !test_bit(ISCSI_CONN_SHUTTINGDOWN, &conn->conn_aflags)) {
704 /* conn reinstatement */
705 reinstatement = true;
706 } else if (!list_empty(&session->conn_list)) {
711 err = iscsi_conn_alloc(session, info, &new_conn);
716 TRACE_MGMT_DBG("Reinstating conn (old %p, new %p)", conn,
718 conn->conn_reinst_successor = new_conn;
719 __set_bit(ISCSI_CONN_REINSTATING, &new_conn->conn_aflags);
720 __mark_conn_closed(conn, 0);
723 conn_activate(new_conn);
729 /* target_mutex supposed to be locked */
730 int conn_del(struct iscsi_session *session, struct iscsi_kern_conn_info *info)
732 struct iscsi_conn *conn;
735 conn = conn_lookup(session, info->cid);
737 PRINT_ERROR("Connection %d not found", info->cid);
741 PRINT_INFO("Deleting connection with initiator %s (%p)",
742 conn->session->initiator_name, conn);
744 __mark_conn_closed(conn, ISCSI_CONN_ACTIVE_CLOSE|ISCSI_CONN_DELETING);
749 #ifdef CONFIG_SCST_EXTRACHECKS
751 void iscsi_extracheck_is_rd_thread(struct iscsi_conn *conn)
753 if (unlikely(current != conn->rd_task)) {
754 printk(KERN_EMERG "conn %p rd_task != current %p (pid %d)\n",
755 conn, current, current->pid);
758 printk(KERN_EMERG "rd_state %x\n", conn->rd_state);
759 printk(KERN_EMERG "rd_task %p\n", conn->rd_task);
760 printk(KERN_EMERG "rd_task->pid %d\n", conn->rd_task->pid);
765 void iscsi_extracheck_is_wr_thread(struct iscsi_conn *conn)
767 if (unlikely(current != conn->wr_task)) {
768 printk(KERN_EMERG "conn %p wr_task != current %p (pid %d)\n",
769 conn, current, current->pid);
772 printk(KERN_EMERG "wr_state %x\n", conn->wr_state);
773 printk(KERN_EMERG "wr_task %p\n", conn->wr_task);
774 printk(KERN_EMERG "wr_task->pid %d\n", conn->wr_task->pid);
779 #endif /* CONFIG_SCST_EXTRACHECKS */