diff --git a/Makefile b/Makefile index 7263ec5d6..e5092d915 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ # # Common makefile for SCSI target mid-level and its drivers # -# Copyright (C) 2004 - 2015 Vladislav Bolkhovitin -# Copyright (C) 2007 - 2015 SanDisk Corporation +# Copyright (C) 2004 - 2016 Vladislav Bolkhovitin +# Copyright (C) 2007 - 2016 SanDisk Corporation # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License diff --git a/SVN_TAGS b/SVN_TAGS index b8fb6f4f4..0e234d912 100644 --- a/SVN_TAGS +++ b/SVN_TAGS @@ -20,3 +20,4 @@ SRPT 1.0.0 450 3.0.x branch start 5534, which is a copy of trunk r5533 3.0.0 5815 on the 3.0.x branch 3.1.x branch start 6591, which is a copy of trunk r6590 +3.1.0 6783 on the 3.1.x branch diff --git a/doc/Makefile b/doc/Makefile index c1b59b8cc..de55e58a8 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -36,9 +36,9 @@ rtf: $(RTFS) $(COMMAND)rtf $(<) clean: - mv "Using the DLM as a Distributed In-Memory Database.pdf" "Using the DLM as a Distributed In-Memory Database.pdf_" + -mv "Using-the-DLM-as-a-Distributed-In-Memory-Database.pdf" "Using-the-DLM-as-a-Distributed-In-Memory-Database.pdf_" rm -f *.txt *.html *.tex *.dvi *.ps *.pdf *.info *.lyx *.rtf - mv "Using the DLM as a Distributed In-Memory Database.pdf_" "Using the DLM as a Distributed In-Memory Database.pdf" + -mv "Using-the-DLM-as-a-Distributed-In-Memory-Database.pdf_" "Using-the-DLM-as-a-Distributed-In-Memory-Database.pdf" extraclean: clean rm -f *.orig *.rej diff --git a/doc/Using the DLM as a Distributed In-Memory Database.pdf b/doc/Using-the-DLM-as-a-Distributed-In-Memory-Database.pdf similarity index 100% rename from doc/Using the DLM as a Distributed In-Memory Database.pdf rename to doc/Using-the-DLM-as-a-Distributed-In-Memory-Database.pdf diff --git a/doc/scst_user_spec.sgml b/doc/scst_user_spec.sgml index 121e4df97..75f601928 100644 --- a/doc/scst_user_spec.sgml +++ b/doc/scst_user_spec.sgml @@ -10,7 +10,7 @@ SCST user space device handler interface description Vladislav Bolkhovitin -Version 3.0.0 +Version 3.2.0 diff --git a/fcst/Makefile b/fcst/Makefile index 6ed535a59..0c5311f71 100644 --- a/fcst/Makefile +++ b/fcst/Makefile @@ -3,7 +3,7 @@ # Based on ../mvsas_tgt/Makefile # # Copyright (C) 2006 - 2008 Jacky Feng -# Copyright (C) 2011 - 2015 Bart Van Assche +# Copyright (C) 2011 - 2016 Bart Van Assche # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License diff --git a/fcst/fcst.h b/fcst/fcst.h index 771937a3a..9e403835f 100644 --- a/fcst/fcst.h +++ b/fcst/fcst.h @@ -13,8 +13,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id$ */ #ifndef __SCSI_FCST_H__ #define __SCSI_FCST_H__ diff --git a/fcst/ft_cmd.c b/fcst/ft_cmd.c index e0b0baa2f..adc297847 100644 --- a/fcst/ft_cmd.c +++ b/fcst/ft_cmd.c @@ -330,7 +330,7 @@ int ft_send_response(struct scst_cmd *cmd) * For bi-directional comands, the bi_resid is for the read direction. */ if (dir & SCST_DATA_WRITE) - resid = (signed)scst_cmd_get_bufflen(cmd) - + resid = (signed int)scst_cmd_get_bufflen(cmd) - fcmd->write_data_len; if (dir & SCST_DATA_READ) { error = ft_send_read_data(cmd); @@ -340,12 +340,12 @@ int ft_send_response(struct scst_cmd *cmd) } if (dir == SCST_DATA_BIDI) { - bi_resid = (signed)scst_cmd_get_out_bufflen(cmd) - + bi_resid = (signed int)scst_cmd_get_out_bufflen(cmd) - scst_cmd_get_resp_data_len(cmd); if (bi_resid) len += sizeof(__be32); } else - resid = (signed)scst_cmd_get_bufflen(cmd) - + resid = (signed int)scst_cmd_get_bufflen(cmd) - scst_cmd_get_resp_data_len(cmd); } diff --git a/ibmvstgt/src/Kconfig b/ibmvstgt/src/Kconfig index f3f71155e..5c989a9ed 100644 --- a/ibmvstgt/src/Kconfig +++ b/ibmvstgt/src/Kconfig @@ -977,7 +977,7 @@ config SCSI_IBMVSCSIS The userspace component needed to initialize the driver and documentation can be found: - http://stgt.berlios.de/ + http://stgt.sourceforge.net/ To compile this driver as a module, choose M here: the module will be called ibmvstgt. diff --git a/ibmvstgt/src/orig/2.6.35/Kconfig b/ibmvstgt/src/orig/2.6.35/Kconfig index d07f508d1..a80061834 100644 --- a/ibmvstgt/src/orig/2.6.35/Kconfig +++ b/ibmvstgt/src/orig/2.6.35/Kconfig @@ -969,7 +969,7 @@ config SCSI_IBMVSCSIS The userspace component needed to initialize the driver and documentation can be found: - http://stgt.berlios.de/ + http://stgt.sourceforge.net/ To compile this driver as a module, choose M here: the module will be called ibmvstgt. diff --git a/ibmvstgt/src/orig/2.6.36/Kconfig b/ibmvstgt/src/orig/2.6.36/Kconfig index f3f71155e..5c989a9ed 100644 --- a/ibmvstgt/src/orig/2.6.36/Kconfig +++ b/ibmvstgt/src/orig/2.6.36/Kconfig @@ -977,7 +977,7 @@ config SCSI_IBMVSCSIS The userspace component needed to initialize the driver and documentation can be found: - http://stgt.berlios.de/ + http://stgt.sourceforge.net/ To compile this driver as a module, choose M here: the module will be called ibmvstgt. diff --git a/iscsi-scst/Makefile b/iscsi-scst/Makefile index 1df57d882..d1969de05 100644 --- a/iscsi-scst/Makefile +++ b/iscsi-scst/Makefile @@ -100,12 +100,15 @@ else endif endif +CREATE_CQ_FLAG = $(shell $(MAKE) -C $(KDIR) SUBDIRS=$(shell pwd)/conftest/create_cq PRE_CFLAGS="$(OFED_CFLAGS) -Werror" >/dev/null 2>&1 && echo -DIB_CREATE_CQ_HAS_INIT_ATTR) +PRE_CFLAGS=$(OFED_CFLAGS) $(CREATE_CQ_FLAG) -DOFED_FLAVOR=$(OFED_FLAVOR) + mods: Modules.symvers Module.symvers $(MAKE) -C $(KDIR) SCST_INC_DIR=$(SCST_INC_DIR) SUBDIRS=$(KMOD) modules if $(INFINIBAND_ENABLED); then \ echo " Building against $(OFED_FLAVOR) InfiniBand kernel headers."; \ $(MAKE) -C $(KDIR) SCST_INC_DIR=$(SCST_INC_DIR) SUBDIRS=$(ISERTMOD) \ - PRE_CFLAGS="$(OFED_CFLAGS) -DOFED_FLAVOR=$(OFED_FLAVOR)" \ + PRE_CFLAGS="$(PRE_CFLAGS)" \ KBUILD_EXTRA_SYMBOLS=$(ISER_SYMVERS) modules; \ fi diff --git a/iscsi-scst/conftest/create_cq/Makefile b/iscsi-scst/conftest/create_cq/Makefile new file mode 100644 index 000000000..d7ada9b0a --- /dev/null +++ b/iscsi-scst/conftest/create_cq/Makefile @@ -0,0 +1,3 @@ +LINUXINCLUDE := $(PRE_CFLAGS) $(LINUXINCLUDE) + +obj-m += create_cq.o diff --git a/iscsi-scst/conftest/create_cq/create_cq.c b/iscsi-scst/conftest/create_cq/create_cq.c new file mode 100644 index 000000000..86fce929e --- /dev/null +++ b/iscsi-scst/conftest/create_cq/create_cq.c @@ -0,0 +1,13 @@ +#include +#include + +static int modinit(void) +{ + struct ib_cq *q; + + q = ib_create_cq(NULL, NULL, NULL, NULL, NULL); + + return q != 0; +} + +module_init(modinit); diff --git a/iscsi-scst/doc/SCST_Gentoo_HOWTO.txt b/iscsi-scst/doc/SCST_Gentoo_HOWTO.txt index cca3aa443..9533ac6e8 100644 --- a/iscsi-scst/doc/SCST_Gentoo_HOWTO.txt +++ b/iscsi-scst/doc/SCST_Gentoo_HOWTO.txt @@ -85,6 +85,13 @@ work perfectly) 5. Build SCST + ! Important: SCST 3.1.x and trunk: Gentoo Hardened kernels uses + Grsec/PaX patchset. If you happen to use one of those kernels + (sys-kernel/hardened-sources) you need to change every call + "object_is_on_stack" to "object_starts_on_stack" to compile SCST + successfully. At the time of writing this there is a single such call + in scst/src/scst_lib.c + cd /root/scst make 2perf make scst scst_install diff --git a/iscsi-scst/include/iscsi_scst.h b/iscsi-scst/include/iscsi_scst.h index f64d50096..b823adbc3 100644 --- a/iscsi-scst/include/iscsi_scst.h +++ b/iscsi-scst/include/iscsi_scst.h @@ -1,6 +1,6 @@ /* - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/iscsi-scst/include/iscsi_scst_ver.h b/iscsi-scst/include/iscsi_scst_ver.h index 9c60851f5..4dc77ad01 100644 --- a/iscsi-scst/include/iscsi_scst_ver.h +++ b/iscsi-scst/include/iscsi_scst_ver.h @@ -1,6 +1,6 @@ /* - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/iscsi-scst/kernel/Makefile b/iscsi-scst/kernel/Makefile index 39c837a2b..f36ae5666 100644 --- a/iscsi-scst/kernel/Makefile +++ b/iscsi-scst/kernel/Makefile @@ -1,8 +1,8 @@ # # Makefile for the kernel part of iSCSI-SCST. # -# Copyright (C) 2007 - 2015 Vladislav Bolkhovitin -# Copyright (C) 2007 - 2015 SanDisk Corporation +# Copyright (C) 2007 - 2016 Vladislav Bolkhovitin +# Copyright (C) 2007 - 2016 SanDisk Corporation # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License diff --git a/iscsi-scst/kernel/config.c b/iscsi-scst/kernel/config.c index 2e39e2523..b4c7e842e 100644 --- a/iscsi-scst/kernel/config.c +++ b/iscsi-scst/kernel/config.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2004 - 2005 FUJITA Tomonori - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -31,13 +31,13 @@ int ctr_open_state; #define ISCSI_PROC_LOG_ENTRY_NAME "trace_level" static struct scst_trace_log iscsi_local_trace_tbl[] = { - { TRACE_D_WRITE, "d_write" }, - { TRACE_CONN_OC, "conn" }, - { TRACE_CONN_OC_DBG, "conn_dbg" }, - { TRACE_D_IOV, "iov" }, - { TRACE_D_DUMP_PDU, "pdu" }, - { TRACE_NET_PG, "net_page" }, - { 0, NULL } + { TRACE_D_WRITE, "d_write" }, + { TRACE_CONN_OC, "conn" }, + { TRACE_CONN_OC_DBG, "conn_dbg" }, + { TRACE_D_IOV, "iov" }, + { TRACE_D_DUMP_PDU, "pdu" }, + { TRACE_NET_PG, "net_page" }, + { 0, NULL } }; static int iscsi_log_info_show(struct seq_file *seq, void *v) diff --git a/iscsi-scst/kernel/conn.c b/iscsi-scst/kernel/conn.c index de76de85d..3b1de7fea 100644 --- a/iscsi-scst/kernel/conn.c +++ b/iscsi-scst/kernel/conn.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2002 - 2003 Ardis Technolgies - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -103,7 +103,7 @@ void conn_info_show(struct seq_file *seq, struct iscsi_session *session) switch (sk->sk_family) { case AF_INET: snprintf(buf, sizeof(buf), -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) "%u.%u.%u.%u", NIPQUAD(inet_sk(sk)->daddr)); #else "%pI4", &inet_sk(sk)->inet_daddr); @@ -111,7 +111,7 @@ void conn_info_show(struct seq_file *seq, struct iscsi_session *session) break; #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) case AF_INET6: -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) snprintf(buf, sizeof(buf), "[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]", NIP6(inet6_sk(sk)->daddr)); diff --git a/iscsi-scst/kernel/digest.c b/iscsi-scst/kernel/digest.c index cbfff039e..dc3a7c564 100644 --- a/iscsi-scst/kernel/digest.c +++ b/iscsi-scst/kernel/digest.c @@ -3,8 +3,8 @@ * * Copyright (C) 2004 - 2006 Xiranet Communications GmbH * - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/iscsi-scst/kernel/digest.h b/iscsi-scst/kernel/digest.h index d13289d21..4c85c6760 100644 --- a/iscsi-scst/kernel/digest.h +++ b/iscsi-scst/kernel/digest.h @@ -2,8 +2,8 @@ * iSCSI digest handling. * * Copyright (C) 2004 Xiranet Communications GmbH - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/iscsi-scst/kernel/event.c b/iscsi-scst/kernel/event.c index 4be91d429..1db71ee6f 100644 --- a/iscsi-scst/kernel/event.c +++ b/iscsi-scst/kernel/event.c @@ -2,8 +2,8 @@ * Event notification code. * * Copyright (C) 2005 FUJITA Tomonori - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/iscsi-scst/kernel/iscsi.c b/iscsi-scst/kernel/iscsi.c index d7d12c3de..f76db72ff 100644 --- a/iscsi-scst/kernel/iscsi.c +++ b/iscsi-scst/kernel/iscsi.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2002 - 2003 Ardis Technolgies - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/iscsi-scst/kernel/iscsi.h b/iscsi-scst/kernel/iscsi.h index 986f5132c..a63c5b965 100644 --- a/iscsi-scst/kernel/iscsi.h +++ b/iscsi-scst/kernel/iscsi.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2002 - 2003 Ardis Technolgies - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/iscsi-scst/kernel/iscsi_dbg.h b/iscsi-scst/kernel/iscsi_dbg.h index ebbb60a4e..4e190b7e1 100644 --- a/iscsi-scst/kernel/iscsi_dbg.h +++ b/iscsi-scst/kernel/iscsi_dbg.h @@ -1,6 +1,6 @@ /* - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/iscsi-scst/kernel/iscsi_hdr.h b/iscsi-scst/kernel/iscsi_hdr.h index 67e729697..617da3f3a 100644 --- a/iscsi-scst/kernel/iscsi_hdr.h +++ b/iscsi-scst/kernel/iscsi_hdr.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2002 - 2003 Ardis Technolgies - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/iscsi-scst/kernel/isert-scst/iser.h b/iscsi-scst/kernel/isert-scst/iser.h index 90fa056a2..eeb8040fc 100644 --- a/iscsi-scst/kernel/isert-scst/iser.h +++ b/iscsi-scst/kernel/isert-scst/iser.h @@ -98,7 +98,11 @@ struct isert_wr { struct ib_sge *sge_list; union { struct ib_recv_wr recv_wr; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) struct ib_send_wr send_wr; +#else + struct ib_rdma_wr send_wr; +#endif }; } ____cacheline_aligned; diff --git a/iscsi-scst/kernel/isert-scst/iser_buf.c b/iscsi-scst/kernel/isert-scst/iser_buf.c index daa78c72a..7bd34c9a2 100644 --- a/iscsi-scst/kernel/isert-scst/iser_buf.c +++ b/iscsi-scst/kernel/isert-scst/iser_buf.c @@ -238,9 +238,14 @@ int isert_wr_init(struct isert_wr *wr, buff_offset = -EFAULT; goto out; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) wr->send_wr.wr.rdma.remote_addr = pdu->rem_write_va + buff_offset; wr->send_wr.wr.rdma.rkey = pdu->rem_write_stag; +#else + wr->send_wr.remote_addr = pdu->rem_write_va + buff_offset; + wr->send_wr.rkey = pdu->rem_write_stag; +#endif break; case ISER_WR_RDMA_WRITE: send_wr_op = IB_WR_RDMA_WRITE; @@ -250,9 +255,14 @@ int isert_wr_init(struct isert_wr *wr, buff_offset = -EFAULT; goto out; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) wr->send_wr.wr.rdma.remote_addr = pdu->rem_read_va + buff_offset; wr->send_wr.wr.rdma.rkey = pdu->rem_read_stag; +#else + wr->send_wr.remote_addr = pdu->rem_read_va + buff_offset; + wr->send_wr.rkey = pdu->rem_read_stag; +#endif break; default: BUG(); @@ -278,12 +288,21 @@ int isert_wr_init(struct isert_wr *wr, wr->recv_wr.sg_list = wr->sge_list; wr->recv_wr.num_sge = sg_cnt; } else { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) wr->send_wr.next = NULL; wr->send_wr.wr_id = _ptr_to_u64(wr); wr->send_wr.sg_list = wr->sge_list; wr->send_wr.num_sge = sg_cnt; wr->send_wr.opcode = send_wr_op; wr->send_wr.send_flags = send_flags; +#else + wr->send_wr.wr.next = NULL; + wr->send_wr.wr.wr_id = _ptr_to_u64(wr); + wr->send_wr.wr.sg_list = wr->sge_list; + wr->send_wr.wr.num_sge = sg_cnt; + wr->send_wr.wr.opcode = send_wr_op; + wr->send_wr.wr.send_flags = send_flags; +#endif } out: diff --git a/iscsi-scst/kernel/isert-scst/iser_pdu.c b/iscsi-scst/kernel/isert-scst/iser_pdu.c index 0c6e81b32..cf30db258 100644 --- a/iscsi-scst/kernel/isert-scst/iser_pdu.c +++ b/iscsi-scst/kernel/isert-scst/iser_pdu.c @@ -214,7 +214,11 @@ out: static inline void isert_link_send_wrs(struct isert_wr *from_wr, struct isert_wr *to_wr) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) from_wr->send_wr.next = &to_wr->send_wr; +#else + from_wr->send_wr.wr.next = &to_wr->send_wr.wr; +#endif } static inline void isert_link_send_pdu_wrs(struct isert_cmnd *from_pdu, @@ -222,7 +226,11 @@ static inline void isert_link_send_pdu_wrs(struct isert_cmnd *from_pdu, int wr_cnt) { isert_link_send_wrs(&from_pdu->wr[wr_cnt - 1], &to_pdu->wr[0]); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) to_pdu->wr[0].send_wr.next = NULL; +#else + to_pdu->wr[0].send_wr.wr.next = NULL; +#endif } int isert_prepare_rdma(struct isert_cmnd *isert_pdu, @@ -281,8 +289,14 @@ int isert_prepare_rdma(struct isert_cmnd *isert_pdu, isert_link_send_wrs(&isert_pdu->wr[i - 1], &isert_pdu->wr[i]); if (op == ISER_WR_RDMA_READ) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) isert_pdu->wr[wr_cnt - 1].send_wr.send_flags = IB_SEND_SIGNALED; isert_pdu->wr[wr_cnt - 1].send_wr.next = NULL; +#else + isert_pdu->wr[wr_cnt - 1].send_wr.wr.send_flags = + IB_SEND_SIGNALED; + isert_pdu->wr[wr_cnt - 1].send_wr.wr.next = NULL; +#endif } out: @@ -574,7 +588,11 @@ int isert_pdu_send(struct isert_connection *isert_conn, #endif wr = &tx_pdu->wr[0]; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) wr->send_wr.num_sge = isert_pdu_prepare_send(isert_conn, tx_pdu); +#else + wr->send_wr.wr.num_sge = isert_pdu_prepare_send(isert_conn, tx_pdu); +#endif err = isert_post_send(isert_conn, wr, 1); if (unlikely(err)) { @@ -595,8 +613,13 @@ int isert_pdu_post_rdma_write(struct isert_connection *isert_conn, TRACE_ENTRY(); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) isert_rsp->wr[0].send_wr.num_sge = isert_pdu_prepare_send(isert_conn, isert_rsp); +#else + isert_rsp->wr[0].send_wr.wr.num_sge = isert_pdu_prepare_send(isert_conn, + isert_rsp); +#endif isert_link_send_pdu_wrs(isert_cmd, isert_rsp, wr_cnt); err = isert_post_send(isert_conn, &isert_cmd->wr[0], wr_cnt + 1); if (unlikely(err)) { diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index 8fd02ab4a..59e44dbb3 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -103,7 +103,11 @@ int isert_post_send(struct isert_connection *isert_conn, struct isert_wr *first_wr, int num_wr) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) struct ib_send_wr *first_ib_wr = &first_wr->send_wr; +#else + struct ib_send_wr *first_ib_wr = &first_wr->send_wr.wr; +#endif struct ib_send_wr *bad_wr; int num_posted; int err; @@ -131,9 +135,19 @@ void isert_post_drain(struct isert_connection *isert_conn) isert_wr_set_fields(&isert_conn->drain_wr, isert_conn, NULL); isert_conn->drain_wr.wr_op = ISER_WR_SEND; - isert_conn->drain_wr.send_wr.wr_id = _ptr_to_u64(&isert_conn->drain_wr); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) + isert_conn->drain_wr.send_wr.wr_id = + _ptr_to_u64(&isert_conn->drain_wr); isert_conn->drain_wr.send_wr.opcode = IB_WR_SEND; - err = ib_post_send(isert_conn->qp, &isert_conn->drain_wr.send_wr, &bad_wr); + err = ib_post_send(isert_conn->qp, + &isert_conn->drain_wr.send_wr, &bad_wr); +#else + isert_conn->drain_wr.send_wr.wr.wr_id = + _ptr_to_u64(&isert_conn->drain_wr); + isert_conn->drain_wr.send_wr.wr.opcode = IB_WR_SEND; + err = ib_post_send(isert_conn->qp, + &isert_conn->drain_wr.send_wr.wr, &bad_wr); +#endif if (unlikely(err)) { pr_err("Failed to post drain wr, err:%d\n", err); /* @@ -601,6 +615,7 @@ static void isert_handle_wc_error(struct ib_wc *wc) struct isert_buf *isert_buf = wr->buf; struct isert_device *isert_dev = wr->isert_dev; struct ib_device *ib_dev = isert_dev->ib_dev; + u32 num_sge; TRACE_ENTRY(); @@ -615,7 +630,12 @@ static void isert_handle_wc_error(struct ib_wc *wc) switch (wr->wr_op) { case ISER_WR_SEND: - if (unlikely(wr->send_wr.num_sge == 0)) /* Drain WR */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) + num_sge = wr->send_wr.num_sge; +#else + num_sge = wr->send_wr.wr.num_sge; +#endif + if (unlikely(num_sge == 0)) /* Drain WR */ isert_sched_conn_drained(isert_conn); else isert_pdu_err(&isert_pdu->iscsi); @@ -845,7 +865,6 @@ static void isert_async_evt_handler(struct ib_event *async_ev, void *context) static struct isert_device *isert_device_create(struct ib_device *ib_dev) { struct isert_device *isert_dev; - struct ib_device_attr *dev_attr; int cqe_num, err; struct ib_pd *pd; struct ib_mr *mr; @@ -862,12 +881,15 @@ static struct isert_device *isert_device_create(struct ib_device *ib_dev) goto out; } - dev_attr = &isert_dev->device_attr; - err = ib_query_device(ib_dev, dev_attr); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0) + err = ib_query_device(ib_dev, &isert_dev->device_attr); if (unlikely(err)) { pr_err("Failed to query device, err: %d\n", err); - goto fail_query; + goto free_isert_dev; } +#else + isert_dev->device_attr = ib_dev->attrs; +#endif isert_dev->num_cqs = min_t(int, num_online_cpus(), ib_dev->num_comp_vectors); @@ -878,7 +900,7 @@ static struct isert_device *isert_device_create(struct ib_device *ib_dev) if (unlikely(isert_dev->cq_qps == NULL)) { pr_err("Failed to allocate iser cq_qps\n"); err = -ENOMEM; - goto fail_cq_qps; + goto free_isert_dev; } isert_dev->cq_desc = vmalloc(sizeof(*isert_dev->cq_desc) * isert_dev->num_cqs); @@ -943,7 +965,8 @@ static struct isert_device *isert_device_create(struct ib_device *ib_dev) goto fail_cq; } -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) && \ + !defined(IB_CREATE_CQ_HAS_INIT_ATTR) cq = ib_create_cq(ib_dev, isert_cq_comp_handler, isert_async_evt_handler, @@ -1005,8 +1028,7 @@ fail_pd: vfree(isert_dev->cq_desc); fail_alloc_cq_desc: kfree(isert_dev->cq_qps); -fail_cq_qps: -fail_query: +free_isert_dev: kfree(isert_dev); out: TRACE_EXIT_RES(err); @@ -1648,9 +1670,12 @@ struct isert_portal *isert_portal_create(void) #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0) && \ (!defined(RHEL_MAJOR) || RHEL_MAJOR -0 <= 5) cm_id = rdma_create_id(isert_cm_evt_handler, portal, RDMA_PS_TCP); -#else +#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) cm_id = rdma_create_id(isert_cm_evt_handler, portal, RDMA_PS_TCP, IB_QPT_RC); +#else + cm_id = rdma_create_id(&init_net, isert_cm_evt_handler, portal, + RDMA_PS_TCP, IB_QPT_RC); #endif if (unlikely(IS_ERR(cm_id))) { err = PTR_ERR(cm_id); diff --git a/iscsi-scst/kernel/nthread.c b/iscsi-scst/kernel/nthread.c index 2d471ecac..4e9ea5f55 100644 --- a/iscsi-scst/kernel/nthread.c +++ b/iscsi-scst/kernel/nthread.c @@ -2,8 +2,8 @@ * Network threads. * * Copyright (C) 2004 - 2005 FUJITA Tomonori - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -81,7 +81,6 @@ again: spin_lock_bh(&conn->cmd_list_lock); list_for_each_entry(cmnd, &conn->cmd_list, cmd_list_entry) { struct iscsi_cmnd *rsp; - int restart = 0; TRACE_CONN_CLOSE_DBG("cmd %p, scst_state %x, " "r2t_len_to_receive %d, ref_cnt %d, parent_req %p, " @@ -98,6 +97,12 @@ again: if (cmnd_get_check(cmnd)) continue; + /* + * If we don't unlock here, we are risking to get into + * recursive deadlock in cmnd_done() called from cmnd_put() + */ + spin_unlock_bh(&conn->cmd_list_lock); + for (i = 0; i < cmnd->sg_cnt; i++) { struct page *page = sg_page(&cmnd->sg[i]); @@ -106,18 +111,12 @@ again: atomic_read(&page->_count)); if (page->net_priv != NULL) { - if (restart == 0) { - spin_unlock_bh(&conn->cmd_list_lock); - restart = 1; - } while (page->net_priv != NULL) iscsi_put_page_callback(page); } } cmnd_put(cmnd); - - if (restart) - goto again; + goto again; } list_for_each_entry(rsp, &cmnd->rsp_cmd_list, @@ -133,6 +132,13 @@ again: if (cmnd_get_check(rsp)) continue; + /* + * If we don't unlock here, we are risking to + * get into recursive deadlock in cmnd_done() + * called from cmnd_put() + */ + spin_unlock_bh(&conn->cmd_list_lock); + for (i = 0; i < rsp->sg_cnt; i++) { struct page *page = sg_page(&rsp->sg[i]); @@ -143,18 +149,12 @@ again: atomic_read(&page->_count)); if (page->net_priv != NULL) { - if (restart == 0) { - spin_unlock_bh(&conn->cmd_list_lock); - restart = 1; - } while (page->net_priv != NULL) iscsi_put_page_callback(page); } } cmnd_put(rsp); - - if (restart) - goto again; + goto again; } } } @@ -862,6 +862,12 @@ static int process_read_io(struct iscsi_conn *conn, int *closed) /* * This command not yet received on the aborted * time, so shouldn't be affected by any abort. + * It should not be affected by conn_abort() + * as well, because close connection is initiated + * from single (this) read thread, so conn_abort() + * call stack can not be initiated in parallel to + * receive all the data event (do_recv() has check + * of conn->closing in the beginning) */ EXTRACHECKS_BUG_ON(cmnd->prelim_compl_flags != 0); @@ -1359,7 +1365,7 @@ retry: set_fs(KERNEL_DS); res = vfs_writev(file, (struct iovec __force __user *)iop, - count, &off); + count, &off, 0); set_fs(oldfs); TRACE_WRITE("sid %#Lx, cid %u, res %d, iov_len %zd", (unsigned long long int)conn->session->sid, diff --git a/iscsi-scst/kernel/param.c b/iscsi-scst/kernel/param.c index 0e300231f..a8a185520 100644 --- a/iscsi-scst/kernel/param.c +++ b/iscsi-scst/kernel/param.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2005 FUJITA Tomonori - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/iscsi-scst/kernel/session.c b/iscsi-scst/kernel/session.c index 5b28d0fe4..d26031db6 100644 --- a/iscsi-scst/kernel/session.c +++ b/iscsi-scst/kernel/session.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2002 - 2003 Ardis Technolgies - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/iscsi-scst/kernel/target.c b/iscsi-scst/kernel/target.c index 7a3e0a546..520a2f4e3 100644 --- a/iscsi-scst/kernel/target.c +++ b/iscsi-scst/kernel/target.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2002 - 2003 Ardis Technolgies - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -128,7 +128,6 @@ int __add_target(struct iscsi_kern_target_info *info) int err; u32 tid = info->tid; struct iscsi_target *target = NULL; /* to calm down sparse */ - struct iscsi_kern_attr *attr_info; union add_info_union { struct iscsi_kern_params_info params_info; struct iscsi_kern_attr attr_info; @@ -165,7 +164,6 @@ int __add_target(struct iscsi_kern_target_info *info) err = -ENOMEM; goto out; } - attr_info = (struct iscsi_kern_attr *)add_info; if (tid == 0) { do { @@ -183,6 +181,9 @@ int __add_target(struct iscsi_kern_target_info *info) nr_targets++; #ifndef CONFIG_SCST_PROC + { + struct iscsi_kern_attr *attr_info = &add_info->attr_info; + mutex_lock(&target->target_mutex); attrs_ptr_long = info->attrs_ptr; @@ -208,6 +209,7 @@ int __add_target(struct iscsi_kern_target_info *info) } mutex_unlock(&target->target_mutex); + } #endif err = tid; diff --git a/iscsi-scst/usr/Makefile b/iscsi-scst/usr/Makefile index eec0bcaad..5af12bf5b 100644 --- a/iscsi-scst/usr/Makefile +++ b/iscsi-scst/usr/Makefile @@ -1,8 +1,8 @@ # # Makefile for the user space part of iSCSI-SCST. # -# Copyright (C) 2007 - 2015 Vladislav Bolkhovitin -# Copyright (C) 2007 - 2015 SanDisk Corporation +# Copyright (C) 2007 - 2016 Vladislav Bolkhovitin +# Copyright (C) 2007 - 2016 SanDisk Corporation # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License diff --git a/iscsi-scst/usr/chap.c b/iscsi-scst/usr/chap.c index febf69153..dfefae1ac 100644 --- a/iscsi-scst/usr/chap.c +++ b/iscsi-scst/usr/chap.c @@ -3,8 +3,8 @@ * * Copyright (C) 2004 Xiranet Communications GmbH * Copyright (C) 2002 - 2003 Ardis Technolgies , - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * and code taken from UNH iSCSI software: * Copyright (C) 2001-2003 InterOperability Lab (IOL) @@ -171,7 +171,7 @@ static inline void encode_hex_string(u8 *intnum, long length, char *string) strptr = string; for (i = 0; i < length; i++, strptr += 2) - sprintf(strptr, "%.2hhx", intnum[i]); + sprintf(strptr, "%.2hhx", intnum[i]); } /* Base64 encoding, taken from UNH iSCSI "IntegerToBase64String()" */ @@ -339,15 +339,15 @@ static inline void chap_calc_digest_sha1(char chap_id, const char *secret, int s */ static int chap_rand(void) { - int fd; - int r; + int fd; + int r; - fd = open("/dev/urandom", O_RDONLY); - assert(fd != -1); - if (read(fd, &r, sizeof(r)) < sizeof(r)) { - } - close(fd); - return r; + fd = open("/dev/urandom", O_RDONLY); + assert(fd != -1); + if (read(fd, &r, sizeof(r)) < sizeof(r)) { + } + close(fd); + return r; } static int chap_initiator_auth_create_challenge(struct connection *conn) @@ -575,7 +575,7 @@ static int chap_target_auth_create_response(struct connection *conn) response_len = 2 * digest_len; else response_len = ((digest_len - 1) / 3 + 1) * 4; - //"0x" / "0b" and "\0": + /* "0x" / "0b" and "\0": */ response_len += 3; if (!(digest = malloc(digest_len))) { @@ -639,7 +639,7 @@ int cmnd_exec_auth_chap(struct connection *conn) { int res; - switch(conn->auth_state) { + switch (conn->auth_state) { case CHAP_AUTH_STATE_START: res = chap_initiator_auth_create_challenge(conn); break; diff --git a/iscsi-scst/usr/config.c b/iscsi-scst/usr/config.c index 516db2ce3..8a11f32ae 100644 --- a/iscsi-scst/usr/config.c +++ b/iscsi-scst/usr/config.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2005 FUJITA Tomonori - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -514,6 +514,7 @@ int __config_account_add(struct target *target, int dir, char *name, char *pass, if (dir == ISCSI_USER_DIR_OUTGOING) { struct iscsi_attr *old; + list_for_each_entry(old, list, ulist) { log_warning("Only one outgoing %s account is " "supported. Replacing the old one.\n", @@ -1061,6 +1062,7 @@ static int config_isns_load(const char *config) isns_server = strdup(config_sep_string(&q)); } else if (!strcasecmp(p, ISCSI_ISNS_ACCESS_CONTROL_ATTR_NAME)) { char *str = config_sep_string(&q); + if (!strcasecmp(str, "No")) isns_access_control = 0; else @@ -1139,6 +1141,7 @@ int config_load(const char *config_name) err = config_isns_load(buf); if ((err == 0) && (isns_server != NULL)) { int rc = isns_init(); + if (rc != 0) { log_error("iSNS server %s init failed: %d", isns_server, rc); isns_exit(); diff --git a/iscsi-scst/usr/conn.c b/iscsi-scst/usr/conn.c index 4d62c3eff..e6cf77add 100644 --- a/iscsi-scst/usr/conn.c +++ b/iscsi-scst/usr/conn.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2002 - 2003 Ardis Technolgies - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/iscsi-scst/usr/ctldev.c b/iscsi-scst/usr/ctldev.c index f83668675..08db4d72b 100644 --- a/iscsi-scst/usr/ctldev.c +++ b/iscsi-scst/usr/ctldev.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2004 - 2005 FUJITA Tomonori - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -298,7 +298,7 @@ int kernel_params_get(u32 tid, u64 sid, int type, struct iscsi_param *params) if ((err = ioctl(ctrl_fd, ISCSI_PARAM_GET, &info)) < 0) { err = -errno; - log_debug(1, "Can't get session params for session 0x%" PRIx64 + log_debug(1, "Can't get session params for session 0x%" PRIx64 " (tid %u, err %d): %s\n", sid, tid, err, strerror(errno)); } diff --git a/iscsi-scst/usr/event.c b/iscsi-scst/usr/event.c index 8c8b5e601..8d0734767 100644 --- a/iscsi-scst/usr/event.c +++ b/iscsi-scst/usr/event.c @@ -2,8 +2,8 @@ * Event notification code. * * Copyright (C) 2005 FUJITA Tomonori - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -57,7 +57,7 @@ static int nl_write(int fd, void *data, int len) nlh.nlmsg_type = 0; memset(&msg, 0, sizeof(msg)); - msg.msg_name= (void *)&dest_addr; + msg.msg_name = (void *)&dest_addr; msg.msg_namelen = sizeof(dest_addr); msg.msg_iov = iov; msg.msg_iovlen = 2; @@ -105,6 +105,7 @@ static int strncasecmp_numwild(const char *name, const char *mask) if (!strncasecmp(name, mask, strlen(name))) { int j; + if (strlen(name) > strlen(mask)) goto out; for (j = strlen(name); j < strlen(mask); j++) { @@ -430,6 +431,7 @@ static int handle_e_mgmt_cmd(int fd, const struct iscsi_kern_event *event) res = handle_add_attr(NULL, p, event->cookie); } else if (strcasecmp("add_target_attribute", pp) == 0) { struct target *target; + pp = config_sep_string(&p); target = target_find_by_name(pp); if (target == NULL) { @@ -442,6 +444,7 @@ static int handle_e_mgmt_cmd(int fd, const struct iscsi_kern_event *event) res = handle_del_attr(NULL, p, event->cookie); } else if (strcasecmp("del_target_attribute", pp) == 0) { struct target *target; + pp = config_sep_string(&p); target = target_find_by_name(pp); if (target == NULL) { @@ -465,6 +468,7 @@ out: static void add_key_mark(char *res_str, int res_str_len, int new_line) { int offs = strlen(res_str); + snprintf(&res_str[offs], res_str_len - offs, "%s%s\n", new_line ? "\n" : "", SCST_SYSFS_KEY_MARK); return; @@ -702,6 +706,7 @@ static int handle_target_redirect(struct target *target, char *p) if (inet_pton(AF_INET, addr, &ia) != 1) { char tmp[sizeof(target->redirect.addr)]; + if (*addr == '[') t = addr+1; else diff --git a/iscsi-scst/usr/iscsi_adm.c b/iscsi-scst/usr/iscsi_adm.c index 3fd6033f5..7177d7783 100644 --- a/iscsi-scst/usr/iscsi_adm.c +++ b/iscsi-scst/usr/iscsi_adm.c @@ -2,8 +2,8 @@ * iscsi_adm - manage iSCSI-SCST Target software. * * Copyright (C) 2004 - 2005 FUJITA Tomonori - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -46,10 +46,9 @@ enum iscsi_adm_op { OP_SHOW, }; -static char program_name[] = "iscsi-scst-adm"; +static const char program_name[] = "iscsi-scst-adm"; -static struct option const long_options[] = -{ +static struct option const long_options[] = { {"op", required_argument, NULL, 'o'}, {"tid", required_argument, NULL, 't'}, {"sid", required_argument, NULL, 's'}, @@ -278,6 +277,7 @@ static int parse_trgt_params(struct msg_trgt *msg, char *params) while ((p = strsep(¶ms, ",")) != NULL) { int idx; u32 val; + if (!*p) continue; if (!(q = strchr(p, '='))) diff --git a/iscsi-scst/usr/iscsi_adm.h b/iscsi-scst/usr/iscsi_adm.h index ba87ff10f..94bb88a38 100644 --- a/iscsi-scst/usr/iscsi_adm.h +++ b/iscsi-scst/usr/iscsi_adm.h @@ -1,6 +1,6 @@ /* - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/iscsi-scst/usr/iscsi_hdr.h b/iscsi-scst/usr/iscsi_hdr.h index c766be279..e073f610e 100644 --- a/iscsi-scst/usr/iscsi_hdr.h +++ b/iscsi-scst/usr/iscsi_hdr.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2002 - 2003 Ardis Technolgies - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/iscsi-scst/usr/iscsi_scstd.c b/iscsi-scst/usr/iscsi_scstd.c index c2d35d2a8..147bd3da0 100644 --- a/iscsi-scst/usr/iscsi_scstd.c +++ b/iscsi-scst/usr/iscsi_scstd.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2002 - 2003 Ardis Technolgies - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -40,7 +40,7 @@ #include "iscsid.h" #include "iscsi_adm.h" -static char* server_address; +static char *server_address; uint16_t server_port = ISCSI_LISTEN_PORT; struct pollfd poll_array[POLL_MAX]; @@ -52,10 +52,9 @@ int conn_blocked; struct iscsi_init_params iscsi_init_params; -static char program_name[] = "iscsi-scstd"; +static const char program_name[] = "iscsi-scstd"; -static struct option const long_options[] = -{ +static struct option const long_options[] = { {"config", required_argument, 0, 'c'}, {"foreground", no_argument, 0, 'f'}, {"debug", required_argument, 0, 'd'}, @@ -209,6 +208,7 @@ out: static int transmit_iser(int fd, bool start) { int opt = start; + return ioctl(fd, RDMA_CORK, &opt, sizeof(opt)); } @@ -370,6 +370,7 @@ out_close: static int transmit_sock(int fd, bool start) { int opt = start; + return setsockopt(fd, SOL_TCP, TCP_CORK, &opt, sizeof(opt)); } @@ -620,7 +621,7 @@ again: switch (conn->state) { case STATE_KERNEL: conn_pass_to_kern(conn, pollfd->fd); - if(conn->passed_to_kern) + if (conn->passed_to_kern) conn->state = STATE_CLOSE; else conn->state = STATE_EXIT; @@ -744,6 +745,7 @@ static void event_loop(void) (conn->state == STATE_EXIT) || (conn->state == STATE_DROP)) { struct session *sess = conn->sess; + log_debug(1, "closing conn %p", conn); conn_free_pdu(conn); close(pollfd->fd); @@ -928,6 +930,7 @@ int main(int argc, char **argv) exit(1); } else if (pid) { int res = -1; + close(init_report_pipe[1]); if (read(init_report_pipe[0], &res, sizeof(res)) < sizeof(res)) exit(-1); diff --git a/iscsi-scst/usr/iscsid.c b/iscsi-scst/usr/iscsid.c index d1e0e46c6..c0a58fa97 100644 --- a/iscsi-scst/usr/iscsid.c +++ b/iscsi-scst/usr/iscsid.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2002 - 2003 Ardis Technolgies - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -299,6 +299,7 @@ static int login_check_reinstatement(struct connection *conn) goto out; } else { struct connection *c = conn_find(session, conn->cid); + if (c != NULL) { /* Kernel will do connection reinstatement */ log_debug(1, "Conn %x reinstatement " @@ -527,6 +528,7 @@ static void login_start(struct connection *conn) if (session_type) { if (!strcmp(session_type, "Discovery")) { int ret = conn->is_discovery(conn->fd); + if (ret) { login_rsp_tgt_err(conn, ISCSI_STATUS_MISSING_FIELDS); return; @@ -576,7 +578,7 @@ static void login_start(struct connection *conn) if (!config_initiator_access_allowed(conn->tid, conn->fd) || !target_portal_allowed(target, conn->target_portal, - conn->initiator) || + conn->initiator) || !isns_scn_access_allowed(conn->tid, name)) { log_info("Initiator %s not allowed to connect to " "target %s", name, target_name); @@ -645,6 +647,7 @@ static int login_finish(struct connection *conn) if (conn->is_iser && conn->session_params[key_target_recv_data_length].key_state == KEY_STATE_START) { char buf[32] = "\0"; + params_val_to_str(session_keys, key_target_recv_data_length, session_keys[key_target_recv_data_length].local_def, buf, sizeof(buf)); @@ -698,21 +701,21 @@ static void cmnd_reject(struct connection *conn, u8 reason) static int cmnd_exec_auth(struct connection *conn) { - int res; + int res; - switch (conn->auth_method) { - case AUTH_CHAP: - res = cmnd_exec_auth_chap(conn); - break; - case AUTH_NONE: - res = 0; - break; - default: - log_error("Unknown auth. method %d", conn->auth_method); - res = -3; - } + switch (conn->auth_method) { + case AUTH_CHAP: + res = cmnd_exec_auth_chap(conn); + break; + case AUTH_NONE: + res = 0; + break; + default: + log_error("Unknown auth. method %d", conn->auth_method); + res = -3; + } - return res; + return res; } static void cmnd_exec_login(struct connection *conn) @@ -750,7 +753,7 @@ static void cmnd_exec_login(struct connection *conn) login_start(conn); if (rsp->status_class) return; - //else fall through + /* else fall through */ case STATE_SECURITY: text_scan_security(conn); if (rsp->status_class) @@ -848,6 +851,7 @@ static void cmnd_exec_login(struct connection *conn) } if (!stay && !nsg_disagree) { int err; + text_check_params(conn); err = login_finish(conn); if (err != 0) { @@ -1081,7 +1085,7 @@ void cmnd_finish(struct connection *conn) conn->state = STATE_LOGIN; break; case STATE_SECURITY_FULL: - //fall through + /* fall through */ case STATE_LOGIN_FULL: if (conn->session_type == SESSION_NORMAL) conn->state = STATE_KERNEL; diff --git a/iscsi-scst/usr/iscsid.h b/iscsi-scst/usr/iscsid.h index eadc60911..885002876 100644 --- a/iscsi-scst/usr/iscsid.h +++ b/iscsi-scst/usr/iscsid.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2002 - 2003 Ardis Technolgies - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -180,8 +180,8 @@ struct connection { #define ISCSI_USER_DIR_INCOMING 0 #define ISCSI_USER_DIR_OUTGOING 1 -#define ISCSI_USER_NAME(attr) (attr)->attr_key -#define ISCSI_USER_PASS(attr) (attr)->attr_value +#define ISCSI_USER_NAME(attr) ((attr)->attr_key) +#define ISCSI_USER_PASS(attr) ((attr)->attr_value) struct iscsi_attr { struct __qelem ulist; diff --git a/iscsi-scst/usr/isns.c b/iscsi-scst/usr/isns.c index c5d5eafdf..9d1bde508 100644 --- a/iscsi-scst/usr/isns.c +++ b/iscsi-scst/usr/isns.c @@ -2,8 +2,8 @@ * iSNS functions * * Copyright (C) 2006 FUJITA Tomonori - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -507,9 +507,9 @@ int isns_target_register(char *name) err = isns_tlv_set(&tlv, max_buf - length, ISNS_ATTR_ISCSI_NAME, strlen(isns_entity_target_name) + 1, isns_entity_target_name); } -if (err < 0) + if (err < 0) goto out; - length += err; + length += err; err = isns_tlv_set(&tlv, max_buf - length, ISNS_ATTR_ENTITY_IDENTIFIER, strlen(eid) + 1, eid); @@ -551,6 +551,7 @@ if (err < 0) if (scn_listen_port) { uint32_t sport = htonl(scn_listen_port); + err = isns_tlv_set(&tlv, max_buf - length, ISNS_ATTR_SCN_PORT, sizeof(sport), &sport); if (err < 0) @@ -1010,7 +1011,7 @@ static int send_scn_rsp(char *name, uint16_t transaction) *((uint32_t *)hdr->pdu) = 0; max_buf = sizeof(buf) - offsetof(struct isns_hdr, pdu); tlv = (struct isns_tlv *)((char *)hdr->pdu + 4); - length +=4; + length += 4; err = isns_tlv_set(&tlv, max_buf - length, ISNS_ATTR_ISCSI_NAME, strlen(name) + 1, name); diff --git a/iscsi-scst/usr/isns_proto.h b/iscsi-scst/usr/isns_proto.h index 5bdfd3510..ea6cbcab6 100644 --- a/iscsi-scst/usr/isns_proto.h +++ b/iscsi-scst/usr/isns_proto.h @@ -2,8 +2,8 @@ * iSNS protocol data types * * Copyright (C) 2006 FUJITA Tomonori - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as diff --git a/iscsi-scst/usr/log.c b/iscsi-scst/usr/log.c index 2a552e290..7a3d4769e 100644 --- a/iscsi-scst/usr/log.c +++ b/iscsi-scst/usr/log.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2002 - 2003 Ardis Technolgies - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -37,6 +37,7 @@ static void dolog_nofunc(int prio, const char *fmt, va_list ap) if (log_daemon) { int len = strlen(fmt); char f[len+1+1]; + if (fmt[len] != '\n') sprintf(f, "%s\n", fmt); else @@ -63,6 +64,7 @@ static void dolog(int prio, const char *func, int line, const char *fmt, va_list if (log_daemon) { int len = strlen(func) + strlen(fmt); char f[len+1+1]; + if (fmt[len] != '\n') sprintf(f, "%s:%d: %s %s\n", func, line, (prio == LOG_ERR) ? "ERROR:" : "", fmt); @@ -83,13 +85,14 @@ static void dolog(int prio, const char *func, int line, const char *fmt, va_list void __log(const char *func, int line, int prio, int level, const char *fmt, ...) { + va_list ap; + if (level) { prio = LOG_DEBUG; if (log_level < level) return; } - va_list ap; va_start(ap, fmt); dolog(prio, func, line, fmt, ap); va_end(ap); diff --git a/iscsi-scst/usr/md5.c b/iscsi-scst/usr/md5.c index 746eef545..fcd7cdf2d 100644 --- a/iscsi-scst/usr/md5.c +++ b/iscsi-scst/usr/md5.c @@ -1,4 +1,4 @@ -/* +/* * MD5 Message Digest Algorithm (RFC1321). * * Derived from cryptoapi implementation, originally based on the @@ -6,10 +6,10 @@ * * Copyright (c) Cryptoapi developers. * Copyright (c) 2002 James Morris - * + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) + * Software Foundation; either version 2 of the License, or (at your option) * any later version. * */ diff --git a/iscsi-scst/usr/message.c b/iscsi-scst/usr/message.c index 6a6802108..9751b705a 100644 --- a/iscsi-scst/usr/message.c +++ b/iscsi-scst/usr/message.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2004 - 2005 FUJITA Tomonori - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/iscsi-scst/usr/misc.c b/iscsi-scst/usr/misc.c index 8a2273c28..c81ad40d2 100644 --- a/iscsi-scst/usr/misc.c +++ b/iscsi-scst/usr/misc.c @@ -1,6 +1,6 @@ /* - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/iscsi-scst/usr/misc.h b/iscsi-scst/usr/misc.h index 879a79ca7..eb388e1ad 100644 --- a/iscsi-scst/usr/misc.h +++ b/iscsi-scst/usr/misc.h @@ -1,6 +1,6 @@ /* - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -25,7 +25,7 @@ struct __qelem { #undef offsetof #ifdef __compiler_offsetof -#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER) +#define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE, MEMBER) #else #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #endif @@ -45,19 +45,19 @@ static inline int list_empty(const struct __qelem *head) static inline int list_length_is_one(const struct __qelem *head) { - return (!list_empty(head) && head->q_forw == head->q_back); + return (!list_empty(head) && head->q_forw == head->q_back); } #define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) #define list_entry(ptr, type, member) \ container_of(ptr, type, member) #define list_for_each_entry(pos, head, member) \ for (pos = list_entry((head)->q_forw, typeof(*pos), member); \ - &pos->member != (head); \ + &pos->member != (head); \ pos = list_entry(pos->member.q_forw, typeof(*pos), member)) #define list_for_each_entry_safe(pos, n, head, member) \ @@ -73,7 +73,7 @@ static inline int list_length_is_one(const struct __qelem *head) INIT_LIST_HEAD(elem); \ } while (0) -#define list_add(new, head) insque (new, head) +#define list_add(new, head) insque(new, head) #define list_add_tail(new, head) insque(new, (head)->q_back) @@ -94,12 +94,12 @@ static inline int list_length_is_one(const struct __qelem *head) #define min_t(type, x, y) ({ \ type __min1 = (x); \ type __min2 = (y); \ - __min1 < __min2 ? __min1: __min2; }) + __min1 < __min2 ? __min1 : __min2; }) #define max_t(type, x, y) ({ \ type __max1 = (x); \ type __max2 = (y); \ - __max1 > __max2 ? __max1: __max2; }) + __max1 > __max2 ? __max1 : __max2; }) #ifndef IPV6_V6ONLY #define IPV6_V6ONLY 26 diff --git a/iscsi-scst/usr/param.c b/iscsi-scst/usr/param.c index 04b692e78..08ea77fb2 100644 --- a/iscsi-scst/usr/param.c +++ b/iscsi-scst/usr/param.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2005 FUJITA Tomonori - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -29,6 +29,7 @@ size_t strlcpy(char *dest, const char *src, size_t size) if (size) { size_t len = (ret >= size) ? size - 1 : ret; + memcpy(dest, src, len); dest[len] = '\0'; } @@ -56,6 +57,7 @@ int params_index_by_name_numwild(const char *name, const struct iscsi_key *keys) for (i = 0; keys[i].name; i++) { if (!strncasecmp(keys[i].name, name, strlen(keys[i].name))) { int j; + if (strlen(keys[i].name) > strlen(name)) continue; for (j = strlen(keys[i].name); j < strlen(name); j++) { @@ -205,8 +207,8 @@ static int digest_str_to_val(const char *str, unsigned int *val) { int err = 0; const char *p, *q; - p = str; + p = str; *val = 0; do { while ((*p != '\0') && isspace(*p)) @@ -337,7 +339,7 @@ static struct iscsi_key_ops marker_ops = { .set_val = marker_set_val, }; -#define SET_KEY_VALUES(x) DEFAULT_##x,DEFAULT_##x,MIN_##x,MAX_##x +#define SET_KEY_VALUES(x) DEFAULT_##x, DEFAULT_##x, MIN_##x, MAX_##x /* * List of local target keys with initial values. diff --git a/iscsi-scst/usr/param.h b/iscsi-scst/usr/param.h index cc0e43c62..7f4860aa7 100644 --- a/iscsi-scst/usr/param.h +++ b/iscsi-scst/usr/param.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2005 FUJITA Tomonori - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/iscsi-scst/usr/session.c b/iscsi-scst/usr/session.c index 9886cfe42..fdfa65071 100644 --- a/iscsi-scst/usr/session.c +++ b/iscsi-scst/usr/session.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2002 - 2003 Ardis Technolgies - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/iscsi-scst/usr/sha1.c b/iscsi-scst/usr/sha1.c index 52771c459..e92dbac83 100644 --- a/iscsi-scst/usr/sha1.c +++ b/iscsi-scst/usr/sha1.c @@ -17,9 +17,9 @@ #include "sha1.h" /* SHA1 transforms */ -#define F1(x,y,z) (z ^ (x & (y ^ z))) /* x ? y : z */ -#define F2(x,y,z) (x ^ y ^ z) /* XOR */ -#define F3(x,y,z) ((x & y) + (z & (x ^ y))) /* majority */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) /* x ? y : z */ +#define F2(x, y, z) (x ^ y ^ z) /* XOR */ +#define F3(x, y, z) ((x & y) + (z & (x ^ y))) /* majority */ /* SHA1 per-round constants */ #define K1 0x5A827999UL /* Rounds 0-19: sqrt(2) * 2^30 */ @@ -56,17 +56,17 @@ static void __sha1_transform(u32 hash[SHA1_DIGEST_WORDS], e = d; d = c; c = rol32(b, 30); b = a; a = t; } - for (; i < 40; i ++) { + for (; i < 40; i++) { t = F2(b, c, d) + K2 + rol32(a, 5) + e + W[i]; e = d; d = c; c = rol32(b, 30); b = a; a = t; } - for (; i < 60; i ++) { + for (; i < 60; i++) { t = F3(b, c, d) + K3 + rol32(a, 5) + e + W[i]; e = d; d = c; c = rol32(b, 30); b = a; a = t; } - for (; i < 80; i ++) { + for (; i < 80; i++) { t = F2(b, c, d) + K4 + rol32(a, 5) + e + W[i]; e = d; d = c; c = rol32(b, 30); b = a; a = t; } diff --git a/iscsi-scst/usr/target.c b/iscsi-scst/usr/target.c index 030d9afa2..25558e629 100644 --- a/iscsi-scst/usr/target.c +++ b/iscsi-scst/usr/target.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2002 - 2003 Ardis Technolgies - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -292,7 +292,7 @@ void target_list_build(struct connection *conn, char *target_name) else if (strcmp(conn->target_portal, portal) && !is_addr_loopback(portal) && target_portal_allowed(target, portal, - conn->initiator)) + conn->initiator)) target_print_addr(conn, portal, family); } } diff --git a/iscsi-scst/usr/types.h b/iscsi-scst/usr/types.h index a4ff61f85..19ffab6df 100644 --- a/iscsi-scst/usr/types.h +++ b/iscsi-scst/usr/types.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2002 - 2003 Ardis Technolgies - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/mpt/mpt_scst.c b/mpt/mpt_scst.c index d0458fcdf..6fe26b01a 100644 --- a/mpt/mpt_scst.c +++ b/mpt/mpt_scst.c @@ -164,6 +164,7 @@ static int mpt_target_show(struct seq_file *seq, void *v) if (ioc->bus_type == SPI) { #endif int i = 0; + seq_printf(seq, "Target ID :%d\n" "Capabilities :0x%x\n" "PhysicalInterface:0x%x\n", @@ -252,6 +253,7 @@ static ssize_t mpt_proc_target_write(struct file *file, const char __user *buf, if (strncmp("target_id:", tmp, strlen("target_id:")) == 0) { char *s = tmp + strlen("target_id:"); int id = simple_strtoul(s, NULL, 0); + if (id < MPT_MAX_SCSI_DEVICES) { if (IsScsi(tgt->priv)) { TRACE_DBG("Changing target id to %d\n", id); diff --git a/mpt/mpt_scst.h b/mpt/mpt_scst.h index 98d11fcab..51dd1c55f 100644 --- a/mpt/mpt_scst.h +++ b/mpt/mpt_scst.h @@ -37,7 +37,7 @@ #define MPT_STM_64_BIT_DMA 1 #endif -#include "../drivers/message/fusion/mptbase.h" +#include "mptbase.h" #ifndef MPI_IOCLOGINFO_FC_LINK_ALREADY_INITIALIZED #define MPI_IOCLOGINFO_FC_LINK_ALREADY_INITIALIZED 0x24000002 diff --git a/nightly/conf/nightly.conf b/nightly/conf/nightly.conf index 6b79841c8..14b7649df 100644 --- a/nightly/conf/nightly.conf +++ b/nightly/conf/nightly.conf @@ -3,28 +3,29 @@ ABT_DETAILS="x86_64" ABT_JOBS=5 ABT_KERNELS=" \ -4.3 \ -4.2.6-nc \ -4.1.13-nc \ +4.4.1 \ +4.3.5-nc \ +4.2.8-nc \ +4.1.17-nc \ 4.0.9-nc \ -3.19.7-nc \ -3.18.19-nc \ +3.19.8-nc \ +3.18.26-nc \ 3.17.8-nc \ 3.16.7-nc \ 3.15.10-nc \ -3.14.57-nc \ +3.14.60-nc \ 3.13.11-nc \ -3.12.44-nc \ +3.12.53-nc \ 3.11.10-nc \ -3.10.93-nc \ +3.10.96-nc \ 3.9.11-nc \ 3.8.13-nc \ 3.7.10-nc \ 3.6.11-nc \ 3.5.7-nc \ -3.4.108-nc \ +3.4.110-nc \ 3.3.8-nc \ -3.2.67-nc \ +3.2.76-nc \ 3.1.10-nc \ 3.0.101-nc \ 2.6.39.4-nc \ @@ -35,7 +36,7 @@ ABT_KERNELS=" \ 2.6.35.14-u-nc \ 2.6.34.15-nc \ 2.6.33.20-nc \ -2.6.32.67-nc \ +2.6.32.70-nc \ 2.6.31.14-nc \ 2.6.30.10-nc \ 2.6.29.6-nc \ diff --git a/qla2x00t/qla2x00-target/Makefile b/qla2x00t/qla2x00-target/Makefile index e3065ff5a..409584300 100644 --- a/qla2x00t/qla2x00-target/Makefile +++ b/qla2x00t/qla2x00-target/Makefile @@ -1,9 +1,9 @@ # # Qlogic 2x00 SCSI target driver makefile # -# Copyright (C) 2004 - 2015 Vladislav Bolkhovitin +# Copyright (C) 2004 - 2016 Vladislav Bolkhovitin # Copyright (C) 2004 - 2005 Leonid Stoljar -# Copyright (C) 2007 - 2015 SanDisk Corporation +# Copyright (C) 2007 - 2016 SanDisk Corporation # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License diff --git a/qla2x00t/qla2x00-target/Makefile_in-tree-4.4 b/qla2x00t/qla2x00-target/Makefile_in-tree-4.4 new file mode 100644 index 000000000..9657aee84 --- /dev/null +++ b/qla2x00t/qla2x00-target/Makefile_in-tree-4.4 @@ -0,0 +1,5 @@ +ccflags-y += -Idrivers/scsi/qla2xxx + +qla2x00tgt-y := qla2x00t.o + +obj-$(CONFIG_SCST_QLA_TGT_ADDON) += qla2x00tgt.o diff --git a/qla2x00t/qla2x00-target/qla2x00t.c b/qla2x00t/qla2x00-target/qla2x00t.c index dad9e2711..12d2c12cd 100644 --- a/qla2x00t/qla2x00-target/qla2x00t.c +++ b/qla2x00t/qla2x00-target/qla2x00t.c @@ -1,10 +1,10 @@ /* * qla2x00t.c * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar * Copyright (C) 2006 Nathaniel Clark - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 SanDisk Corporation * * QLogic 22xx/23xx/24xx/25xx FC target driver. * @@ -5610,7 +5610,7 @@ static void q2t_response_pkt(scsi_qla_host_t *vha, response_t *pkt) */ q24_retry_term_exchange(vha, entry); } else - PRINT_ERROR("qla2x00t(%ld): ABTS_RESP_24XX " + PRINT_WARNING("qla2x00t(%ld): ABTS_RESP_24XX " "failed %x (subcode %x:%x)", vha->host_no, entry->compl_status, entry->error_subcode1, entry->error_subcode2); @@ -5815,7 +5815,7 @@ retry: "S_ID %x:%x:%x", s_id[0], s_id[1], s_id[2]); } else - PRINT_ERROR("qla2x00t(%ld): Unable to find " + PRINT_WARNING("qla2x00t(%ld): Unable to find " "initiator with S_ID %x:%x:%x", vha->host_no, s_id[0], s_id[1], s_id[2]); diff --git a/qla2x00t/qla2x00-target/qla2x00t.h b/qla2x00t/qla2x00-target/qla2x00t.h index 242fe5554..9ebbe431a 100644 --- a/qla2x00t/qla2x00-target/qla2x00t.h +++ b/qla2x00t/qla2x00-target/qla2x00t.h @@ -1,10 +1,10 @@ /* * qla2x00t.h * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar * Copyright (C) 2006 Nathaniel Clark - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 SanDisk Corporation * * QLogic 22xx/23xx/24xx/25xx FC target driver. * diff --git a/qla2x00t/qla2x_tgt.h b/qla2x00t/qla2x_tgt.h index 3ceb76b6c..0435e55c4 100644 --- a/qla2x00t/qla2x_tgt.h +++ b/qla2x00t/qla2x_tgt.h @@ -1,10 +1,10 @@ /* * qla2x_tgt.h * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar * Copyright (C) 2006 Nathaniel Clark - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 SanDisk Corporation * * Additional file for the target driver support. * diff --git a/qla2x00t/qla2x_tgt_def.h b/qla2x00t/qla2x_tgt_def.h index d96d6f1b5..464d860fa 100644 --- a/qla2x00t/qla2x_tgt_def.h +++ b/qla2x00t/qla2x_tgt_def.h @@ -1,10 +1,10 @@ /* * qla2x_tgt_def.h * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar * Copyright (C) 2006 Nathaniel Clark - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 SanDisk Corporation * * Additional file for the target driver support. * diff --git a/qla2x00t/qla_isr.c b/qla2x00t/qla_isr.c index 5f2923dbe..83714a603 100644 --- a/qla2x00t/qla_isr.c +++ b/qla2x00t/qla_isr.c @@ -261,7 +261,7 @@ qla2x00_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0) /* Read all mbox registers? */ mboxes = (1 << ha->mbx_count) - 1; if (!ha->mcp) - ql_dbg(ql_dbg_async, vha, 0x5001, "MBX pointer ERRROR.\n"); + ql_dbg(ql_dbg_async, vha, 0x5001, "MBX pointer ERROR.\n"); else mboxes = ha->mcp->in_mb; @@ -1516,7 +1516,7 @@ qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t par_sense_len, struct scsi_dif_tuple { __be16 guard; /* Checksum */ - __be16 app_tag; /* APPL identifer */ + __be16 app_tag; /* APPL identifier */ __be32 ref_tag; /* Target LBA or indirect LBA */ }; @@ -2073,7 +2073,7 @@ qla24xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0) /* Read all mbox registers? */ mboxes = (1 << ha->mbx_count) - 1; if (!ha->mcp) - ql_dbg(ql_dbg_async, vha, 0x504e, "MBX pointer ERRROR.\n"); + ql_dbg(ql_dbg_async, vha, 0x504e, "MBX pointer ERROR.\n"); else mboxes = ha->mcp->in_mb; diff --git a/qla2x00t/qla_os.c b/qla2x00t/qla_os.c index bbaad3885..eb40c5405 100644 --- a/qla2x00t/qla_os.c +++ b/qla2x00t/qla_os.c @@ -1171,7 +1171,7 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type, if (qla2x00_eh_wait_for_pending_commands(vha, cmd->device->id, cmd->device->lun, type) != QLA_SUCCESS) { ql_log(ql_log_warn, vha, 0x800d, - "wait for peding cmds failed for cmd=%p.\n", cmd); + "wait for pending cmds failed for cmd=%p.\n", cmd); goto eh_reset_failed; } @@ -1274,7 +1274,7 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) eh_bus_reset_done: ql_log(ql_log_warn, vha, 0x802b, "BUS RESET %s nexus=%ld:%d:%d.\n", - (ret == FAILED) ? "FAILED" : "SUCCEDED", vha->host_no, id, lun); + (ret == FAILED) ? "FAILED" : "SUCCEEDED", vha->host_no, id, lun); return ret; } diff --git a/scripts/generate-patched-kernel b/scripts/generate-patched-kernel index 2faba70fd..1f0cee235 100755 --- a/scripts/generate-patched-kernel +++ b/scripts/generate-patched-kernel @@ -48,7 +48,7 @@ extract_kernel_tree "$1" || exit $? cd "${target}" || exit $? -list-source-files "${scst_dir}" | +"${script_dir}/list-source-files" "${scst_dir}" | grep -- "-${kernel_version}.*.patch$" | grep -v /in-tree/ | while read p; do diff --git a/scripts/run-regression-tests b/scripts/run-regression-tests index 745e3d19d..031e73117 100755 --- a/scripts/run-regression-tests +++ b/scripts/run-regression-tests @@ -141,6 +141,26 @@ function compile_scst_unpatched { ) } +# Compile the unpatched SCST source code without DLM. +function compile_scst_no_dlm { + local scst="$PWD" + local outputfile="${outputdir}/compilation-output-no-dlm.txt" + local workingdirectory="${outputdir}/scst-no-dlm" + + echo "Testing whether the SCST tree compiles fine without DLM support ..." + ( + if mkdir -p "${workingdirectory}" \ + && cd "${workingdirectory}" \ + && duplicate_scst_source_tree "${scst}" \ + && CONFIG_SCST_NO_DLM=y compile_scst &> "${outputfile}" + then + echo "OK" + else + echo "FAILED" + fi + ) +} + # Test out-of-tree compilation agains the kernel header files in # /lib/modules/$(uname -r)/build. function compile_scst_patched { @@ -558,6 +578,7 @@ fi test_scst_tree_patches || exit $? if [ "${run_local_compilation}" = "true" ]; then compile_scst_unpatched || exit $? + compile_scst_no_dlm || exit $? compile_scst_patched 2release || exit $? compile_scst_patched 2perf || exit $? compile_scst_patched enable_proc || exit $? diff --git a/scst/Makefile b/scst/Makefile index be6936c9e..a191d8b0f 100644 --- a/scst/Makefile +++ b/scst/Makefile @@ -1,9 +1,9 @@ # # Common makefile for SCSI target mid-level and its drivers # -# Copyright (C) 2004 - 2015 Vladislav Bolkhovitin +# Copyright (C) 2004 - 2016 Vladislav Bolkhovitin # Copyright (C) 2004 - 2005 Leonid Stoljar -# Copyright (C) 2007 - 2015 SanDisk Corporation +# Copyright (C) 2007 - 2016 SanDisk Corporation # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License diff --git a/scst/README b/scst/README index 978d8f6fb..7f78d8159 100644 --- a/scst/README +++ b/scst/README @@ -353,6 +353,15 @@ in/out in Makefile and scst.h: functionality is working only if dif_mode doesn't contain dev_store and dif_type is 1. + - CONFIG_SCST_FORWARD_MODE_PASS_THROUGH - if defined, the pass-through + subsystem starts working in the forwarding mode, where reservation + commands processed locally and not passed to the backend SCSI device, + while COMPARE AND WRITE, EXTENDED COPY and RECEIVE COPY RESULTS + commands, which normally processed locally by the SCST core, not + processed locally, but passed to the backend device. Intended to be + used to implement NON-OPTIMIZED ALUA state together with "forwarding" + target attribute on the remote node. Disabled by default for safety. + HIGHMEM kernel configurations are fully supported, but not recommended for performance reasons, except for scst_user, where they are not supported, because this module deals with user supplied memory on a @@ -441,6 +450,19 @@ following entries: have different IDs and SNs. For instance, VDISK dev handler uses this ID to generate T10 vendor specific identifier and SN of the devices. + - suspend - globally suspends or releases all SCSI activities on all + devices. Useful for mass management, like adding or deleting LUNs. + Writing to it value v: + + * v > 0 - suspends activities, but waits no more, than v seconds + + * v = 0 - suspends activities, waits indefinitely + + * V < 0 - releases activities. + + Reading from this attribute returns number of previous suspend + requests. + - threads - allows to read and set number of global SCST I/O threads. Those threads used with async. dev handlers, for instance, vdisk BLOCKIO or NULLIO. @@ -1625,14 +1647,14 @@ perform actual path state switching on SET TARGET PORT GROUPS command, for instance, by calling drbdadm. For more information see stpgd README as well as sample script scst_on_stpg. -DRBD compatibility -.................. +DRBD and other replication/failover SW compatibility +.................................................... -DRBD does not allow to open its device on the secondary as well as does -not allow to perform primary to secondary transition, if this device is -open. +DRBD as well as other replication/failover SW does not allow to open its +device on the secondary as well as does not allow to perform primary to +secondary transition, if this device is open. -SCST BLOCKIO handler has all the necessary support for this behavior. If +SCST BLOCKIO handler has all the necessary support for such behavior. If you write new ALUA state in the "state" attribute, SCST BLOCKIO handler before transition closes the open devices' handles and after transition reopens them, if the new state is active or nonoptimized. @@ -1646,7 +1668,7 @@ above). Wait until the blocking finished. 2. Change the ALUA state to "transitioning". At this moment all open file handles will be closed. -3. Perform the DRBD state transition +3. Perform the DRBD or other replication/failover SW state transition 4. Change the ALUA state to your desired secondary state. @@ -1846,34 +1868,25 @@ EXTENDED COPY ~~~~~~~~~~~~~ SCST implements EXTENDED COPY via internal Copy Manager target. This -target has the following specific attributes in its sysfs: +target has the following specific attribute in its sysfs: - allow_not_connected_copy - if not set (default), an initiator can perform copy only between devices it has direct access to via any target/session. If set, any initiator can copy between any devices in the system. - - mgmt - this attribute allows to control data from which devices can -be copied using Copy Manager. By default, devices belonging to dev -handlers with flag auto_cm_assignment_possible set are auto assigned to -the Copy Manager on the registration. Currently, only vdisk has this -flag set, so all other devices (pass-through, user space, etc.) should -be assigned to the Copy Manager manually. - -Mgmt attribute supports the following commands: - - - add [vname|H:C:I:L] - adds device with name vname or H:C:I:L numbers -(pass-through) to the Copy Manager. - - - del [vname|H:C:I:L] - deletes device with name vname or H:C:I:L numbers -(pass-through) from the Copy Manager. - +The Copy Manager has access only to those devices, for which it has LUNs +in /sys/kernel/scst_tgt/targets/copy_manager/copy_manager_tgt/luns/. +Devices from scst_vdisk dev handler added to it automatically upon +registration, but for other devices you need to manually add LUNs there +the same way as for any target driver. You can also delete any device at +any time from the Copy Manager visibility by deleting the corresponding +LUN from the sysfs. It might be useful during ALUA state switching. Internally SCST implements EXTENDED COPY as generation of sets of internal READ(16) and WRITE(16) SCSI commands. Dev handlers don't need any manual actions to use it. - Also SCST provides for dev handlers possibility to remap blocks instead of copy them, if they support this feature. It allows them to perform EXTENDED COPY command much faster by just metadata update of their diff --git a/scst/README_in-tree b/scst/README_in-tree index 91d0b6ca6..5159aea88 100644 --- a/scst/README_in-tree +++ b/scst/README_in-tree @@ -243,6 +243,15 @@ your favorite kernel configuration Makefile target, e.g. "make xconfig": functionality is working only if dif_mode doesn't contain dev_store and dif_type is 1. + - CONFIG_SCST_FORWARD_MODE_PASS_THROUGH - if defined, the pass-through + subsystem starts working in the forwarding mode, where reservation + commands processed locally and not passed to the backend SCSI device, + while COMPARE AND WRITE, EXTENDED COPY and RECEIVE COPY RESULTS + commands, which normally processed locally by the SCST core, not + processed locally, but passed to the backend device. Intended to be + used to implement NON-OPTIMIZED ALUA state together with "forwarding" + target attribute on the remote node. Disabled by default for safety. + HIGHMEM kernel configurations are fully supported, but not recommended for performance reasons. @@ -305,6 +314,19 @@ following entries: have different IDs and SNs. For instance, VDISK dev handler uses this ID to generate T10 vendor specific identifier and SN of the devices. + - suspend - globally suspends or releases all SCSI activities on all + devices. Useful for mass management, like adding or deleting LUNs. + Writing to it value v: + + * v > 0 - suspends activities, but waits no more, than v seconds + + * v = 0 - suspends activities, waits indefinitely + + * V < 0 - releases activities. + + Reading from this attribute returns number of previous suspend + requests. + - threads - allows to read and set number of global SCST I/O threads. Those threads used with async. dev handlers, for instance, vdisk BLOCKIO or NULLIO. @@ -1478,14 +1500,14 @@ perform actual path state switching on SET TARGET PORT GROUPS command, for instance, by calling drbdadm. For more information see stpgd README as well as sample script scst_on_stpg. -DRBD compatibility -.................. +DRBD and other replication/failover SW compatibility +.................................................... -DRBD does not allow to open its device on the secondary as well as does -not allow to perform primary to secondary transition, if this device is -open. +DRBD as well as other replication/failover SW does not allow to open its +device on the secondary as well as does not allow to perform primary to +secondary transition, if this device is open. -SCST BLOCKIO handler has all the necessary support for this behavior. If +SCST BLOCKIO handler has all the necessary support for such behavior. If you write new ALUA state in the "state" attribute, SCST BLOCKIO handler before transition closes the open devices' handles and after transition reopens them, if the new state is active or nonoptimized. @@ -1499,7 +1521,7 @@ above). Wait until the blocking finished. 2. Change the ALUA state to "transitioning". At this moment all open file handles will be closed. -3. Perform the DRBD state transition +3. Perform the DRBD or other replication/failover SW state transition 4. Change the ALUA state to your desired secondary state. @@ -1699,34 +1721,25 @@ EXTENDED COPY ~~~~~~~~~~~~~ SCST implements EXTENDED COPY via internal Copy Manager target. This -target has the following specific attributes in its sysfs: +target has the following specific attribute in its sysfs: - allow_not_connected_copy - if not set (default), an initiator can perform copy only between devices it has direct access to via any target/session. If set, any initiator can copy between any devices in the system. - - mgmt - this attribute allows to control data from which devices can -be copied using Copy Manager. By default, devices belonging to dev -handlers with flag auto_cm_assignment_possible set are auto assigned to -the Copy Manager on the registration. Currently, only vdisk has this -flag set, so all other devices (pass-through, user space, etc.) should -be assigned to the Copy Manager manually. - -Mgmt attribute supports the following commands: - - - add [vname|H:C:I:L] - adds device with name vname or H:C:I:L numbers -(pass-through) to the Copy Manager. - - - del [vname|H:C:I:L] - deletes device with name vname or H:C:I:L numbers -(pass-through) from the Copy Manager. - +The Copy Manager has access only to those devices, for which it has LUNs +in /sys/kernel/scst_tgt/targets/copy_manager/copy_manager_tgt/luns/. +Devices from scst_vdisk dev handler added to it automatically upon +registration, but for other devices you need to manually add LUNs there +the same way as for any target driver. You can also delete any device at +any time from the Copy Manager visibility by deleting the corresponding +LUN from the sysfs. It might be useful during ALUA state switching. Internally SCST implements EXTENDED COPY as generation of sets of internal READ(16) and WRITE(16) SCSI commands. Dev handlers don't need any manual actions to use it. - Also SCST provides for dev handlers possibility to remap blocks instead of copy them, if they support this feature. It allows them to perform EXTENDED COPY command much faster by just metadata update of their diff --git a/scst/include/backport.h b/scst/include/backport.h index 480b13e3c..5d12d023b 100644 --- a/scst/include/backport.h +++ b/scst/include/backport.h @@ -2,7 +2,7 @@ #define _SCST_BACKPORT_H_ /* - * Copyright (C) 2015 SanDisk Corporation + * Copyright (C) 2015 -2016 SanDisk Corporation * * Backports of functions introduced in recent kernel versions. * @@ -20,8 +20,11 @@ * GNU General Public License for more details. */ +#include /* struct request_queue */ +#include /* struct scatterlist */ #include /* kmalloc() */ #include /* sync_page_range() */ +#include /* struct scsi_cmnd */ /* */ @@ -53,7 +56,7 @@ static inline unsigned int queue_max_hw_sectors(struct request_queue *q) #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 20) #ifndef __printf -#define __printf(a, b) __attribute__((format(printf,a,b))) +#define __printf(a, b) __attribute__((format(printf, a, b))) #endif #endif @@ -88,8 +91,10 @@ static inline unsigned int queue_max_hw_sectors(struct request_queue *q) typedef cpumask_t cpumask_var_t[1]; #define cpumask_bits(maskp) ((maskp)->bits) #ifdef CONFIG_CPUMASK_OFFSTACK -/* Assuming NR_CPUS is huge, a runtime limit is more efficient. Also, - * not all bits may be allocated. */ +/* + * Assuming NR_CPUS is huge, a runtime limit is more efficient. Also, + * not all bits may be allocated. + */ #define nr_cpumask_bits nr_cpu_ids #else #define nr_cpumask_bits NR_CPUS @@ -212,6 +217,25 @@ static inline struct inode *file_inode(const struct file *f) } #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0) +static inline ssize_t vfs_readv_backport(struct file *file, + const struct iovec __user *vec, + unsigned long vlen, loff_t *pos, + int flags) +{ + return vfs_readv(file, vec, vlen, pos); +} +static inline ssize_t vfs_writev_backport(struct file *file, + const struct iovec __user *vec, + unsigned long vlen, loff_t *pos, + int flags) +{ + return vfs_writev(file, vec, vlen, pos); +} +#define vfs_readv vfs_readv_backport +#define vfs_writev vfs_writev_backport +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) static inline int vfs_fsync_backport(struct file *file, int datasync) { @@ -322,7 +346,22 @@ static inline bool list_entry_in_list(const struct list_head *entry) /* */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32) -#define lockdep_assert_held(l) do { (void)(l); } while (0) +#define lockdep_assert_held(l) (void)(l) +#endif + +/* */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0) +static inline long get_user_pages_backport(unsigned long start, + unsigned long nr_pages, + int write, int force, + struct page **pages, + struct vm_area_struct **vmas) +{ + return get_user_pages(current, current->mm, start, nr_pages, write, + force, pages, vmas); +} +#define get_user_pages get_user_pages_backport #endif /* */ @@ -339,12 +378,44 @@ static inline bool list_entry_in_list(const struct list_head *entry) /* */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) && !defined(RHEL_MAJOR) +#define KERN_CONT "" +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28) -#ifndef pr_err -#define pr_err(fmt, ...) printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__) +/* + * See also the following commits: + * d091c2f5 - Introduction of pr_info() etc. in . + * 311d0761 - Introduction of pr_cont() in . + * 968ab183 - Moved pr_info() etc. from to + */ +#ifndef pr_emerg + +#ifndef pr_fmt +#define pr_fmt(fmt) fmt #endif + +#define pr_emerg(fmt, ...) printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__) +#define pr_alert(fmt, ...) printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__) +#define pr_crit(fmt, ...) printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__) +#define pr_err(fmt, ...) printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__) +#define pr_warning(fmt, ...) printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__) +#define pr_notice(fmt, ...) printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__) + +#endif /* pr_emerg */ + +#ifndef pr_info +#define pr_info(fmt, ...) printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) #endif +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28) */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30) +#ifndef pr_cont +#define pr_cont(fmt, ...) printk(KERN_CONT fmt, ##__VA_ARGS__) +#endif +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30) */ + #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) /* * See also patch "kernel.h: add pr_warn for symmetry to dev_warn, @@ -365,6 +436,43 @@ static inline __attribute__ ((format (printf, 1, 2))) int no_printk(const char *s, ...) { return 0; } #endif +/* */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) +/* See also commit 717115e1a585 */ + +#define DEFAULT_RATELIMIT_INTERVAL (5 * HZ) +#define DEFAULT_RATELIMIT_BURST 10 + +struct ratelimit_state { + int interval; + int burst; +}; + +#define DEFINE_RATELIMIT_STATE(name, interval, burst) \ + struct ratelimit_state name = {interval, burst,} + +static inline int __ratelimit(struct ratelimit_state *rs) +{ + return 1; +} +#endif + +/* */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0) && !defined(kfree_rcu) +typedef void (*rcu_callback_t)(struct rcu_head *); +#define __is_kfree_rcu_offset(offset) ((offset) < 4096) +#define kfree_call_rcu(head, rcb) call_rcu(head, rcb) +#define __kfree_rcu(head, offset) \ + do { \ + BUILD_BUG_ON(!__is_kfree_rcu_offset(offset)); \ + kfree_call_rcu(head, (rcu_callback_t)(unsigned long)(offset)); \ + } while (0) +#define kfree_rcu(ptr, rcu_head) \ + __kfree_rcu(&((ptr)->rcu_head), offsetof(typeof(*(ptr)), rcu_head)) +#endif + /* */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) && \ diff --git a/scst/include/scst.h b/scst/include/scst.h index beaff5deb..140412c43 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -1,9 +1,9 @@ /* * include/scst.h * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 SanDisk Corporation * Copyright (C) 2010 - 2011 Bart Van Assche . * * Main SCSI target mid-level include file. @@ -29,6 +29,7 @@ /** See README for description of those conditional defines **/ #define CONFIG_SCST_DIF_INJECT_CORRUPTED_TAGS +/* #define CONFIG_SCST_FORWARD_MODE_PASS_THROUGH */ #include #ifndef INSIDE_KERNEL_TREE @@ -1818,7 +1819,7 @@ struct scst_tgt { /* Divide two 64-bit numbers with reasonably accuracy. */ static inline void __scst_time_per_cmd(uint64_t *t, uint64_t n) { - unsigned shift; + unsigned int shift; if (!n) return; @@ -3829,6 +3830,7 @@ static inline void scst_sess_set_tgt_priv(struct scst_session *sess, } uint16_t scst_lookup_tg_id(struct scst_device *dev, struct scst_tgt *tgt); +enum scst_tg_state scst_get_alua_state(struct scst_device *dev, struct scst_tgt *tgt); bool scst_alua_configured(struct scst_device *dev); int scst_tg_get_group_info(void **buf, uint32_t *response_length, struct scst_device *dev, uint8_t data_format); @@ -5679,8 +5681,10 @@ struct scst_ext_copy_seg_descr { int tgt_descr_offs; }; +#ifndef CONFIG_SCST_PROC void scst_ext_copy_remap_done(struct scst_cmd *ec_cmd, struct scst_ext_copy_data_descr *dds, int dds_cnt); int scst_ext_copy_get_cur_seg_data_len(struct scst_cmd *ec_cmd); +#endif #endif /* __SCST_H */ diff --git a/scst/include/scst_const.h b/scst/include/scst_const.h index caa54728c..30c8f5115 100644 --- a/scst/include/scst_const.h +++ b/scst/include/scst_const.h @@ -1,8 +1,8 @@ /* * include/scst_const.h * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * Contains common SCST constants. This file supposed to be included * from both kernel and user spaces. @@ -341,7 +341,7 @@ static inline int scst_sense_response_code(const uint8_t *sense) #define scst_sense_reported_luns_data_changed UNIT_ATTENTION, 0x3F, 0xE /* DATA_PROTECT is 7 */ -#define scst_sense_data_protect DATA_PROTECT, 0x00, 0 +#define scst_sense_data_protect DATA_PROTECT, 0x27, 0 /* ABORTED_COMMAND is 0xb */ #define scst_sense_aborted_command ABORTED_COMMAND, 0x00, 0 @@ -481,7 +481,7 @@ static inline int scst_sense_response_code(const uint8_t *sense) * From . See also commit * d30a2605be9d5132d95944916e8f578fcfe4f976. */ -#define BLKDISCARD _IO(0x12,119) +#define BLKDISCARD _IO(0x12, 119) #endif /************************************************************* diff --git a/scst/include/scst_debug.h b/scst/include/scst_debug.h index 6941a55ea..ee2e18ee4 100644 --- a/scst/include/scst_debug.h +++ b/scst/include/scst_debug.h @@ -1,9 +1,9 @@ /* * include/scst_debug.h * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 SanDisk Corporation * * Contains macros for execution tracing and error reporting * @@ -31,41 +31,14 @@ #include /* for WARN_ON_ONCE */ #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28) -/* - * See also the following commits: - * d091c2f5 - Introduction of pr_info() etc. in . - * 311d0761 - Introduction of pr_cont() in . - * 968ab183 - Moved pr_info() etc. from to - */ -#ifndef pr_emerg -#ifndef pr_fmt -#define pr_fmt(fmt) fmt +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 27) +#include #endif -#define pr_emerg(fmt, ...) \ - printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__) -#define pr_alert(fmt, ...) \ - printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__) -#define pr_crit(fmt, ...) \ - printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__) -#define pr_err(fmt, ...) \ - printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__) -#define pr_warning(fmt, ...) \ - printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__) -#define pr_notice(fmt, ...) \ - printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__) -#endif -#ifndef pr_info -#define pr_info(fmt, ...) \ - printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) -#endif -#endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30) -#ifndef pr_cont -#define pr_cont(fmt, ...) \ - printk(KERN_CONT fmt, ##__VA_ARGS__) -#endif +#ifdef INSIDE_KERNEL_TREE +#include +#else +#include #endif #if !defined(INSIDE_KERNEL_TREE) @@ -144,10 +117,6 @@ #define TRACE_MINOR_AND_MGMT_DBG (TRACE_MINOR|TRACE_MGMT_DEBUG) -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) && !defined(RHEL_MAJOR) -#define KERN_CONT "" -#endif - /* * Note: in the next two printk() statements the KERN_CONT macro is only * present to suppress a checkpatch warning (KERN_CONT is defined as ""). @@ -171,12 +140,7 @@ #define ___unlikely(a) unlikely(a) #endif -int -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21) || defined(__printf) -__printf(6, 7) -#else -__attribute__((format(printf, 6, 7))) -#endif +int __printf(6, 7) debug_print_with_prefix(unsigned long trace_flag, const char *severity, const char *prefix, const char *func, int line, const char *fmt, ...); @@ -245,7 +209,7 @@ do { \ #define TRACING_MINOR() (false) #define TRACE(trace, format, args...) \ - ((void)(trace), no_printk(format, ##args)) + do { (void)(trace); no_printk(format, ##args); } while (0) #define PRINT_BUFFER(message, buff, len) \ ((void)(message), (void)(buff), (void)(len)) #define PRINT_BUFF_FLAG(flag, message, buff, len) \ @@ -284,6 +248,16 @@ do { \ #endif /* CONFIG_SCST_DEBUG || CONFIG_SCST_TRACING */ +#define PRINT_ERROR_RATELIMITED(format, args...) \ + do { \ + static DEFINE_RATELIMIT_STATE(_rs, \ + DEFAULT_RATELIMIT_INTERVAL, \ + DEFAULT_RATELIMIT_BURST); \ + \ + if (__ratelimit(&_rs)) \ + PRINT_ERROR(format, ##args); \ + } while (0) + #ifdef CONFIG_SCST_DEBUG #define TRACE_DBG_FLAG(trace, format, args...) \ @@ -391,7 +365,7 @@ do { \ #define TRACE_SG(format, args...) no_printk(format, ##args) #define TRACE_DBG(format, args...) no_printk(format, ##args) #define TRACE_DBG_FLAG(flag, format, args...) \ - ((void)(flag), no_printk(format, ##args)) + do { (void)(flag); no_printk(format, ##args); } while (0) #define TRACE_DBG_SPECIAL(format, args...) no_printk(format, ##args) #define TRACE_MGMT_DBG(format, args...) no_printk(format, ##args) #define TRACE_MGMT_DBG_SPECIAL(format, args...) no_printk(format, ##args) diff --git a/scst/include/scst_event.h b/scst/include/scst_event.h index a8c24269b..ea80064c5 100644 --- a/scst/include/scst_event.h +++ b/scst/include/scst_event.h @@ -1,7 +1,7 @@ /* * include/scst_event.h * - * Copyright (C) 2014 - 2015 SanDisk Corporation + * Copyright (C) 2014 - 2016 SanDisk Corporation * * Contains constants and data structures for scst_event module. */ diff --git a/scst/include/scst_sgv.h b/scst/include/scst_sgv.h index 36902931e..175181624 100644 --- a/scst/include/scst_sgv.h +++ b/scst/include/scst_sgv.h @@ -1,8 +1,8 @@ /* * include/scst_sgv.h * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * Include file for SCST SGV cache. * diff --git a/scst/include/scst_user.h b/scst/include/scst_user.h index 1ec529b11..890adfcf6 100644 --- a/scst/include/scst_user.h +++ b/scst/include/scst_user.h @@ -1,8 +1,8 @@ /* * include/scst_user.h * - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * Contains constants and data structures for scst_user module. * See http://scst.sourceforge.net/doc/scst_user_spec.txt or diff --git a/scst/kernel/in-tree/Kconfig.drivers.Linux-4.4.patch b/scst/kernel/in-tree/Kconfig.drivers.Linux-4.4.patch new file mode 100644 index 000000000..39d30a55e --- /dev/null +++ b/scst/kernel/in-tree/Kconfig.drivers.Linux-4.4.patch @@ -0,0 +1,13 @@ +diff --git a/drivers/Kconfig b/drivers/Kconfig +index c70d6e4..0a4ed1b 100644 +--- a/drivers/Kconfig ++++ b/drivers/Kconfig +@@ -26,6 +26,8 @@ source "drivers/ide/Kconfig" + + source "drivers/scsi/Kconfig" + ++source "drivers/scst/Kconfig" ++ + source "drivers/ata/Kconfig" + + source "drivers/md/Kconfig" diff --git a/scst/kernel/in-tree/Makefile.dev_handlers-4.4 b/scst/kernel/in-tree/Makefile.dev_handlers-4.4 new file mode 100644 index 000000000..f933b36f7 --- /dev/null +++ b/scst/kernel/in-tree/Makefile.dev_handlers-4.4 @@ -0,0 +1,14 @@ +ccflags-y += -Wno-unused-parameter + +obj-m := scst_cdrom.o scst_changer.o scst_disk.o scst_modisk.o scst_tape.o \ + scst_vdisk.o scst_raid.o scst_processor.o scst_user.o + +obj-$(CONFIG_SCST_DISK) += scst_disk.o +obj-$(CONFIG_SCST_TAPE) += scst_tape.o +obj-$(CONFIG_SCST_CDROM) += scst_cdrom.o +obj-$(CONFIG_SCST_MODISK) += scst_modisk.o +obj-$(CONFIG_SCST_CHANGER) += scst_changer.o +obj-$(CONFIG_SCST_RAID) += scst_raid.o +obj-$(CONFIG_SCST_PROCESSOR) += scst_processor.o +obj-$(CONFIG_SCST_VDISK) += scst_vdisk.o +obj-$(CONFIG_SCST_USER) += scst_user.o diff --git a/scst/kernel/in-tree/Makefile.drivers.Linux-4.4.patch b/scst/kernel/in-tree/Makefile.drivers.Linux-4.4.patch new file mode 100644 index 000000000..6bbacd12f --- /dev/null +++ b/scst/kernel/in-tree/Makefile.drivers.Linux-4.4.patch @@ -0,0 +1,12 @@ +diff --git a/drivers/Makefile b/drivers/Makefile +index 527a6da..db2c24f 100644 +--- a/drivers/Makefile ++++ b/drivers/Makefile +@@ -137,6 +137,7 @@ obj-$(CONFIG_SSB) += ssb/ + obj-$(CONFIG_BCMA) += bcma/ + obj-$(CONFIG_VHOST_RING) += vhost/ + obj-$(CONFIG_VLYNQ) += vlynq/ ++obj-$(CONFIG_SCST) += scst/ + obj-$(CONFIG_STAGING) += staging/ + obj-y += platform/ + #common clk code diff --git a/scst/kernel/in-tree/Makefile.scst-4.4 b/scst/kernel/in-tree/Makefile.scst-4.4 new file mode 100644 index 000000000..f4e0cc985 --- /dev/null +++ b/scst/kernel/in-tree/Makefile.scst-4.4 @@ -0,0 +1,17 @@ +ccflags-y += -Wno-unused-parameter + +scst-y += scst_copy_mgr.o +scst-y += scst_debug.o +scst-y += scst_dlm.o +scst-y += scst_event.o +scst-y += scst_lib.o +scst-y += scst_main.o +scst-y += scst_mem.o +scst-y += scst_no_dlm.o +scst-y += scst_pres.o +scst-y += scst_sysfs.o +scst-y += scst_targ.o +scst-y += scst_tg.o + +obj-$(CONFIG_SCST) += scst.o dev_handlers/ fcst/ iscsi-scst/ qla2xxx-target/ \ + srpt/ scst_local/ diff --git a/scst/src/Makefile b/scst/src/Makefile index 51d83b986..ac4238c52 100644 --- a/scst/src/Makefile +++ b/scst/src/Makefile @@ -1,9 +1,9 @@ # # SCSI target mid-level makefile # -# Copyright (C) 2004 - 2015 Vladislav Bolkhovitin +# Copyright (C) 2004 - 2016 Vladislav Bolkhovitin # Copyright (C) 2004 - 2005 Leonid Stoljar -# Copyright (C) 2007 - 2015 SanDisk Corporation +# Copyright (C) 2007 - 2016 SanDisk Corporation # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -49,12 +49,7 @@ scst-y += scst_mem.o scst-y += scst_debug.o scst-y += scst_pres.o scst-y += scst_no_dlm.o -ifdef CONFIG_DLM scst-y += scst_dlm.o -endif -ifdef CONFIG_DLM_MODULE -scst-y += scst_dlm.o -endif scst-y += scst_tg.o scst-y += scst_event.o scst-y += scst_copy_mgr.o @@ -160,7 +155,8 @@ INSTALL_DIR_H := $(DESTDIR)$(PREFIX)/include/scst enable-Wextra = $(shell uname_r="$$(uname -r)"; if [ "$${uname_r%.el5}" = "$${uname_r}" ]; then echo "$(1)"; fi) EXTRA_CFLAGS += -I$(SCST_INC_DIR) $(call enable-Wextra,-Wextra \ - -Wno-unused-parameter -Wno-missing-field-initializers) + -Wno-unused-parameter -Wno-missing-field-initializers) \ + $(shell [ -n "${CONFIG_SCST_NO_DLM}" ] && echo -DCONFIG_SCST_NO_DLM) #EXTRA_CFLAGS += -DCONFIG_SCST_STRICT_SERIALIZING diff --git a/scst/src/dev_handlers/Makefile b/scst/src/dev_handlers/Makefile index c59b81f88..d6b4bdd63 100644 --- a/scst/src/dev_handlers/Makefile +++ b/scst/src/dev_handlers/Makefile @@ -1,9 +1,9 @@ # # SCSI target mid-level dev handler's makefile # -# Copyright (C) 2004 - 2015 Vladislav Bolkhovitin +# Copyright (C) 2004 - 2016 Vladislav Bolkhovitin # Copyright (C) 2004 - 2005 Leonid Stoljar -# Copyright (C) 2007 - 2015 SanDisk Corporation +# Copyright (C) 2007 - 2016 SanDisk Corporation # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License diff --git a/scst/src/dev_handlers/scst_cdrom.c b/scst/src/dev_handlers/scst_cdrom.c index f1860f8d7..92697b5bb 100644 --- a/scst/src/dev_handlers/scst_cdrom.c +++ b/scst/src/dev_handlers/scst_cdrom.c @@ -1,9 +1,9 @@ /* * scst_cdrom.c * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 SanDisk Corporation * * SCSI CDROM (type 5) dev handler * @@ -99,7 +99,7 @@ static int cdrom_attach(struct scst_device *dev) rc = scsi_execute(dev->scsi_dev, cmd, data_dir, buffer, buffer_size, sense_buffer, SCST_GENERIC_CDROM_REG_TIMEOUT, 3, 0 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) , NULL #endif ); diff --git a/scst/src/dev_handlers/scst_changer.c b/scst/src/dev_handlers/scst_changer.c index 46e981972..2c66b8b58 100644 --- a/scst/src/dev_handlers/scst_changer.c +++ b/scst/src/dev_handlers/scst_changer.c @@ -1,9 +1,9 @@ /* * scst_changer.c * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 SanDisk Corporation * * SCSI medium changer (type 8) dev handler * diff --git a/scst/src/dev_handlers/scst_dev_handler.h b/scst/src/dev_handlers/scst_dev_handler.h index 5e65480f6..6810224f8 100644 --- a/scst/src/dev_handlers/scst_dev_handler.h +++ b/scst/src/dev_handlers/scst_dev_handler.h @@ -81,6 +81,7 @@ static int scst_dev_handler_build_std_proc(struct scst_dev_type *dev_type) /* Create the proc file entry for the device */ /* Workaround to keep /proc ABI intact */ const char *name; + if (strcmp(dev_type->name, "vdisk_fileio") == 0) name = "vdisk"; else diff --git a/scst/src/dev_handlers/scst_disk.c b/scst/src/dev_handlers/scst_disk.c index d294a138b..44de236b7 100644 --- a/scst/src/dev_handlers/scst_disk.c +++ b/scst/src/dev_handlers/scst_disk.c @@ -1,9 +1,9 @@ /* * scst_disk.c * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 SanDisk Corporation * * SCSI disk (type 0) dev handler * & @@ -196,7 +196,7 @@ static int disk_attach(struct scst_device *dev) rc = scsi_execute(dev->scsi_dev, cmd, data_dir, buffer, buffer_size, sense_buffer, SCST_GENERIC_DISK_REG_TIMEOUT, 3, 0 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) , NULL #endif ); @@ -268,6 +268,20 @@ static int disk_parse(struct scst_cmd *cmd) goto out; } +#ifdef CONFIG_SCST_FORWARD_MODE_PASS_THROUGH + if (unlikely(cmd->op_flags & SCST_LOCAL_CMD)) { + switch (cmd->cdb[0]) { + case COMPARE_AND_WRITE: + case EXTENDED_COPY: + case RECEIVE_COPY_RESULTS: + TRACE_DBG("Clearing LOCAL CMD flag for cmd %p " + "(op %s)", cmd, cmd->op_name); + cmd->op_flags &= ~SCST_LOCAL_CMD; + break; + } + } +#endif + cmd->retries = SCST_PASSTHROUGH_RETRIES; out: return res; @@ -400,6 +414,24 @@ static int disk_exec(struct scst_cmd *cmd) TRACE_ENTRY(); +#ifdef CONFIG_SCST_FORWARD_MODE_PASS_THROUGH + if (unlikely(cmd->op_flags & SCST_LOCAL_CMD)) { + switch (cmd->cdb[0]) { + case RESERVE: + case RESERVE_10: + case RELEASE: + case RELEASE_10: + TRACE_DBG("Skipping LOCAL cmd %p (op %s)", + cmd, cmd->op_name); + goto out_done; + case PERSISTENT_RESERVE_IN: + case PERSISTENT_RESERVE_OUT: + sBUG(); + break; + } + } +#endif + /* * For PC requests we are going to submit max_hw_sectors used instead * of max_sectors. diff --git a/scst/src/dev_handlers/scst_modisk.c b/scst/src/dev_handlers/scst_modisk.c index 80913010c..5dd8271c0 100644 --- a/scst/src/dev_handlers/scst_modisk.c +++ b/scst/src/dev_handlers/scst_modisk.c @@ -1,9 +1,9 @@ /* * scst_modisk.c * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 SanDisk Corporation * * SCSI MO disk (type 7) dev handler * & @@ -200,7 +200,7 @@ static int modisk_attach(struct scst_device *dev) rc = scsi_execute(dev->scsi_dev, cmd, data_dir, buffer, buffer_size, sense_buffer, SCST_GENERIC_MODISK_REG_TIMEOUT, 3, 0 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) , NULL #endif ); diff --git a/scst/src/dev_handlers/scst_processor.c b/scst/src/dev_handlers/scst_processor.c index 82f584c27..88b5bd233 100644 --- a/scst/src/dev_handlers/scst_processor.c +++ b/scst/src/dev_handlers/scst_processor.c @@ -1,9 +1,9 @@ /* * scst_processor.c * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 SanDisk Corporation * * SCSI medium processor (type 3) dev handler * diff --git a/scst/src/dev_handlers/scst_raid.c b/scst/src/dev_handlers/scst_raid.c index e4cf7e3d4..133aaacc8 100644 --- a/scst/src/dev_handlers/scst_raid.c +++ b/scst/src/dev_handlers/scst_raid.c @@ -1,9 +1,9 @@ /* * scst_raid.c * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 SanDisk Corporation * * SCSI raid(controller) (type 0xC) dev handler * diff --git a/scst/src/dev_handlers/scst_tape.c b/scst/src/dev_handlers/scst_tape.c index 1b56b01ed..b9a723edb 100644 --- a/scst/src/dev_handlers/scst_tape.c +++ b/scst/src/dev_handlers/scst_tape.c @@ -1,9 +1,9 @@ /* * scst_tape.c * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 SanDisk Corporation * * SCSI tape (type 1) dev handler * & diff --git a/scst/src/dev_handlers/scst_user.c b/scst/src/dev_handlers/scst_user.c index caf33d27c..643e0ade8 100644 --- a/scst/src/dev_handlers/scst_user.c +++ b/scst/src/dev_handlers/scst_user.c @@ -1,8 +1,8 @@ /* * scst_user.c * - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * SCSI virtual user space device handler * @@ -36,10 +36,10 @@ #ifndef INSIDE_KERNEL_TREE #if defined(CONFIG_HIGHMEM4G) || defined(CONFIG_HIGHMEM64G) -#warning HIGHMEM kernel configurations are not supported by this module,\ - because nowadays it is not worth the effort. Consider changing\ - VMSPLIT option or use a 64-bit configuration instead. See README file\ - for details. +#warning HIGHMEM kernel configurations are not supported by this module, \ +because nowadays it is not worth the effort. Consider changing \ +VMSPLIT option or use a 64-bit configuration instead. See README file \ +for details. #endif #endif @@ -955,6 +955,7 @@ static int dev_user_exec(struct scst_cmd *cmd) return res; } +#ifndef CONFIG_SCST_PROC static void dev_user_ext_copy_remap(struct scst_cmd *cmd, struct scst_ext_copy_seg_descr *seg) { @@ -985,6 +986,7 @@ static void dev_user_ext_copy_remap(struct scst_cmd *cmd, TRACE_EXIT(); return; } +#endif static void dev_user_free_sgv(struct scst_user_cmd *ucmd) { @@ -1265,8 +1267,8 @@ static int dev_user_map_buf(struct scst_user_cmd *ucmd, unsigned long ubuff, (ucmd->cmd != NULL) ? ucmd->cmd->bufflen : -1); down_read(&tsk->mm->mmap_sem); - rc = get_user_pages(tsk, tsk->mm, ubuff, ucmd->num_data_pages, - 1/*writable*/, 0/*don't force*/, ucmd->data_pages, NULL); + rc = get_user_pages(ubuff, ucmd->num_data_pages, 1/*writable*/, + 0/*don't force*/, ucmd->data_pages, NULL); up_read(&tsk->mm->mmap_sem); /* get_user_pages() flushes dcache */ @@ -1485,6 +1487,7 @@ static int dev_user_process_reply_on_cache_free(struct scst_user_cmd *ucmd) return res; } +#ifndef CONFIG_SCST_PROC static int dev_user_process_reply_ext_copy_remap(struct scst_user_cmd *ucmd, struct scst_user_reply_cmd *reply) { @@ -1628,6 +1631,7 @@ out_status: scst_set_cmd_error_status(cmd, rreply->status); goto out_done; } +#endif static int dev_user_process_ws_reply(struct scst_user_cmd *ucmd, struct scst_user_scsi_cmd_reply_exec *ereply) @@ -1950,9 +1954,11 @@ unlock_process: res = dev_user_process_reply_on_cache_free(ucmd); break; +#ifndef CONFIG_SCST_PROC case UCMD_STATE_EXT_COPY_REMAPPING: res = dev_user_process_reply_ext_copy_remap(ucmd, reply); break; +#endif case UCMD_STATE_TM_RECEIVED_EXECING: case UCMD_STATE_TM_DONE_EXECING: @@ -2677,7 +2683,11 @@ static void dev_user_unjam_cmd(struct scst_user_cmd *ucmd, int busy, SCST_CONTEXT_THREAD); else { sBUG_ON(state != UCMD_STATE_EXT_COPY_REMAPPING); +#ifndef CONFIG_SCST_PROC scst_ext_copy_remap_done(ucmd->cmd, NULL, 0); +#else + sBUG(); +#endif } /* !! At this point cmd and ucmd can be already freed !! */ @@ -3217,10 +3227,11 @@ static void dev_user_setup_functions(struct scst_user_dev *dev) dev->devtype.dev_alloc_data_buf = dev_user_alloc_data_buf; dev->devtype.dev_done = NULL; + dev->devtype.ext_copy_remap = NULL; +#ifndef CONFIG_SCST_PROC if (dev->ext_copy_remap_supported) dev->devtype.ext_copy_remap = dev_user_ext_copy_remap; - else - dev->devtype.ext_copy_remap = NULL; +#endif if (dev->parse_type != SCST_USER_PARSE_CALL) { switch (dev->devtype.type) { @@ -4037,11 +4048,13 @@ static int dev_user_read_proc(struct seq_file *seq, struct scst_dev_type *dev_ty list_for_each_entry(dev, &dev_list, dev_list_entry) { int i; + seq_printf(seq, "Device %s commands:\n", dev->name); spin_lock_irqsave(&dev->udev_cmd_threads.cmd_list_lock, flags); for (i = 0; i < (int)ARRAY_SIZE(dev->ucmd_hash); i++) { struct list_head *head = &dev->ucmd_hash[i]; struct scst_user_cmd *ucmd; + list_for_each_entry(ucmd, head, hash_list_entry) { seq_printf(seq, "ucmd %p (state %x, ref %d), " "sent_to_user %d, seen_by_user %d, " diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index bf980ebb5..c6a409a90 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -1,12 +1,12 @@ /* * scst_vdisk.c * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar * Copyright (C) 2007 Ming Zhang * Copyright (C) 2007 Ross Walker - * Copyright (C) 2007 - 2015 SanDisk Corporation - * Copyright (C) 2008 - 2015 Bart Van Assche + * Copyright (C) 2007 - 2016 SanDisk Corporation + * Copyright (C) 2008 - 2016 Bart Van Assche * * SCSI disk (type 0) and CDROM (type 5) dev handler using files * on file systems or block devices (VDISK) @@ -22,6 +22,9 @@ * GNU General Public License for more details. */ +#ifndef INSIDE_KERNEL_TREE +#include +#endif #include #include #include @@ -34,14 +37,15 @@ #include #include #include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) +#include +#else #include +#endif #include #include #include #include -#ifndef INSIDE_KERNEL_TREE -#include -#endif #include #include #include @@ -789,7 +793,7 @@ static struct scst_dev_type vdisk_blk_devtype = { static struct scst_dev_type vdisk_null_devtype = { .name = "vdisk_nullio", .type = TYPE_DISK, - .threads_num = 0, + .threads_num = 1, .parse_atomic = 1, .dev_done_atomic = 1, #ifdef CONFIG_SCST_PROC @@ -1407,6 +1411,7 @@ static int vdisk_init_block_integrity(struct scst_vdisk_dev *virt_dev) struct inode *inode; struct file *fd; struct blk_integrity *bi; + const char *bi_profile_name; TRACE_ENTRY(); @@ -1430,9 +1435,14 @@ static int vdisk_init_block_integrity(struct scst_vdisk_dev *virt_dev) goto out_no_bi; } - TRACE_DBG("BI name %s", bi->name); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) + bi_profile_name = bi->name; +#else + bi_profile_name = bi->profile->name; +#endif + TRACE_DBG("BI name %s", bi_profile_name); - if (!strcmp(bi->name, "T10-DIF-TYPE1-CRC")) { + if (!strcmp(bi_profile_name, "T10-DIF-TYPE1-CRC")) { dev->dev_dif_ip_not_supported = 1; if (virt_dev->dif_type != 1) { PRINT_ERROR("Integrity type mismatch, %d expected, " @@ -1441,7 +1451,7 @@ static int vdisk_init_block_integrity(struct scst_vdisk_dev *virt_dev) res = -EINVAL; goto out_close; } - } else if (!strcmp(bi->name, "T10-DIF-TYPE1-IP")) { + } else if (!strcmp(bi_profile_name, "T10-DIF-TYPE1-IP")) { if (virt_dev->dif_type != 1) { PRINT_ERROR("Integrity type mismatch, %d expected, " "but block device has 1 (dev %s)", @@ -1449,7 +1459,7 @@ static int vdisk_init_block_integrity(struct scst_vdisk_dev *virt_dev) res = -EINVAL; goto out_close; } - } else if (!strcmp(bi->name, "T10-DIF-TYPE3-CRC")) { + } else if (!strcmp(bi_profile_name, "T10-DIF-TYPE3-CRC")) { dev->dev_dif_ip_not_supported = 1; if (virt_dev->dif_type != 3) { PRINT_ERROR("Integrity type mismatch, %d expected, " @@ -1458,7 +1468,7 @@ static int vdisk_init_block_integrity(struct scst_vdisk_dev *virt_dev) res = -EINVAL; goto out_close; } - } else if (!strcmp(bi->name, "T10-DIF-TYPE3-IP")) { + } else if (!strcmp(bi_profile_name, "T10-DIF-TYPE3-IP")) { if (virt_dev->dif_type != 3) { PRINT_ERROR("Integrity type mismatch, %d expected, " "but block device has 3 (dev %s)", @@ -1468,7 +1478,7 @@ static int vdisk_init_block_integrity(struct scst_vdisk_dev *virt_dev) } } else { PRINT_ERROR("Unable to understand integrity name %s" - "(dev %s)", bi->name, dev->virt_name); + "(dev %s)", bi_profile_name, dev->virt_name); res = -EINVAL; goto out_close; } @@ -2017,8 +2027,8 @@ static int vdisk_format_dif(struct scst_cmd *cmd, uint64_t start_lba, full_len, (long long)loff); /* WRITE */ - err = vfs_writev(fd, (struct iovec __force __user *)iv, iv_count, - &loff); + err = vfs_writev(fd, (struct iovec __force __user *)iv, + iv_count, &loff, 0); if (err < 0) { PRINT_ERROR("Formatting DIF write() returned %lld from " "%zd", err, full_len); @@ -2039,7 +2049,7 @@ static int vdisk_format_dif(struct scst_cmd *cmd, uint64_t start_lba, } virt_dev->format_progress_done = done; - }; + } out_set_fs: set_fs(old_fs); @@ -2790,6 +2800,7 @@ static const struct scst_opcode_descriptor *vdisk_opcode_descriptors_type2[] = { &scst_op_descr_write_verify32, &scst_op_descr_write_same32, SCST_OPCODE_DESCRIPTORS + &scst_op_descr_stpg, /* must be last, see vdisk_get_supported_opcodes()! */ }; static const struct scst_opcode_descriptor *vcdrom_opcode_descriptors[] = { @@ -3310,7 +3321,8 @@ err: * @small_sg_size: size of @small_sg * @p_sg_cnt: pointer to an int where the sg vector size will be written */ -static struct scatterlist *alloc_sg(size_t size, unsigned off, gfp_t gfp_mask, +static struct scatterlist *alloc_sg(size_t size, unsigned int off, + gfp_t gfp_mask, struct scatterlist *small_sg, int small_sg_size, int *p_sg_cnt) { @@ -3492,6 +3504,12 @@ static int fileio_exec(struct scst_cmd *cmd) return vdev_do_job(cmd, ops); } +static void vdisk_on_free_cmd_params(const struct vdisk_cmd_params *p) +{ + if (p->iv != p->small_iv) + kfree(p->iv); +} + static void fileio_on_free_cmd(struct scst_cmd *cmd) { struct vdisk_cmd_params *p = cmd->dh_priv; @@ -3516,8 +3534,7 @@ static void fileio_on_free_cmd(struct scst_cmd *cmd) cmd->data_len = 0; } - if (p->iv != p->small_iv) - kfree(p->iv); + vdisk_on_free_cmd_params(p); kmem_cache_free(vdisk_cmd_param_cachep, p); @@ -3539,7 +3556,6 @@ static bool vdisk_no_fd_allowed_commands(const struct scst_cmd *cmd) switch (cmd->cdb[0]) { case TEST_UNIT_READY: - case GET_EVENT_STATUS_NOTIFICATION: case INQUIRY: case MODE_SENSE: case MODE_SENSE_10: @@ -3607,9 +3623,15 @@ static int blockio_exec(struct scst_cmd *cmd) if (unlikely(virt_dev->fd == NULL)) { if (!vdisk_no_fd_allowed_commands(cmd)) { - /* We should not get here */ - PRINT_WARNING("Closed FD on exec. Secondary DRBD or not " - "blocked dev before ALUA state change? " + /* + * We should not get here, unless the user space + * misconfiguring something, e.g. set optimized + * ALUA state for secondary DRBD device. See + * "DRBD and other replication/failover SW + * compatibility" section in SCST README. + */ + PRINT_WARNING("Closed FD on exec. Not active ALUA state " + "or not blocked dev before ALUA state change? " "(cmd %p, op %s, dev %s)", cmd, cmd->op_name, cmd->dev->virt_name); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_no_medium)); @@ -3622,6 +3644,7 @@ static int blockio_exec(struct scst_cmd *cmd) cmd->dh_priv = NULL; out: + vdisk_on_free_cmd_params(&p); return res; err: @@ -3649,6 +3672,7 @@ static int nullio_exec(struct scst_cmd *cmd) cmd->dh_priv = NULL; out: + vdisk_on_free_cmd_params(&p); return res; err: @@ -4361,6 +4385,7 @@ static enum compl_status_e vdisk_exec_inquiry(struct vdisk_cmd_params *p) uint8_t *buf; struct scst_device *dev = cmd->dev; struct scst_vdisk_dev *virt_dev = dev->dh_priv; + enum scst_tg_state alua_state; TRACE_ENTRY(); @@ -4382,8 +4407,13 @@ static enum compl_status_e vdisk_exec_inquiry(struct vdisk_cmd_params *p) goto out_put; } - buf[0] = virt_dev->dummy ? SCSI_INQ_PQ_NOT_CON << 5 | 0x1f : - SCSI_INQ_PQ_CON << 5 | dev->type; + alua_state = scst_get_alua_state(cmd->dev, cmd->tgt); + if ((alua_state == SCST_TG_STATE_UNAVAILABLE) || + (alua_state == SCST_TG_STATE_OFFLINE)) + buf[0] = SCSI_INQ_PQ_NOT_CON << 5 | dev->type; + else + buf[0] = virt_dev->dummy ? SCSI_INQ_PQ_NOT_CON << 5 | 0x1f : + SCSI_INQ_PQ_CON << 5 | dev->type; /* Vital Product */ if (cmd->cdb[1] & EVPD) { if (cmd->cdb[2] == 0) { @@ -5768,7 +5798,6 @@ static int vdev_read_dif_tags(struct vdisk_cmd_params *p) bool finished = false; int tags_num, l; struct scatterlist *tags_sg; - bool free_iv = false; TRACE_ENTRY(); @@ -5803,7 +5832,6 @@ static int vdev_read_dif_tags(struct vdisk_cmd_params *p) res = -ENOMEM; goto out; } - free_iv = true; } max_iv_count = p->iv_count; @@ -5841,7 +5869,7 @@ static int vdev_read_dif_tags(struct vdisk_cmd_params *p) /* READ */ err = vfs_readv(fd, (struct iovec __force __user *)iv, iv_count, - &loff); + &loff, 0); if ((err < 0) || (err < full_len)) { unsigned long flags; @@ -5866,14 +5894,10 @@ static int vdev_read_dif_tags(struct vdisk_cmd_params *p) if (finished) break; - }; + } set_fs(old_fs); -out_free_iv: - if (free_iv && (iv != p->small_iv)) - kfree(p->iv); - out: TRACE_EXIT_RES(res); return res; @@ -5882,7 +5906,7 @@ out_set_fs: set_fs(old_fs); for (i = 0; i < iv_count; i++) scst_put_dif_buf(cmd, (void __force *)(iv[i].iov_base)); - goto out_free_iv; + goto out; } static int vdev_write_dif_tags(struct vdisk_cmd_params *p) @@ -5901,7 +5925,6 @@ static int vdev_write_dif_tags(struct vdisk_cmd_params *p) bool finished = false; int tags_num, l; struct scatterlist *tags_sg; - bool free_iv = false; TRACE_ENTRY(); @@ -5936,7 +5959,6 @@ static int vdev_write_dif_tags(struct vdisk_cmd_params *p) res = -ENOMEM; goto out; } - free_iv = true; } max_iv_count = p->iv_count; @@ -5975,8 +5997,8 @@ restart: TRACE_DBG("Writing DIF: eiv_count %d, full_len %zd", eiv_count, full_len); /* WRITE */ - err = vfs_writev(fd, (struct iovec __force __user *)eiv, eiv_count, - &loff); + err = vfs_writev(fd, (struct iovec __force __user *)eiv, + eiv_count, &loff, 0); if (err < 0) { unsigned long flags; @@ -6028,14 +6050,10 @@ restart: if (finished) break; - }; + } set_fs(old_fs); -out_free_iv: - if (free_iv && (iv != p->small_iv)) - kfree(iv); - out: TRACE_EXIT_RES(res); return res; @@ -6044,7 +6062,7 @@ out_set_fs: set_fs(old_fs); for (i = 0; i < iv_count; i++) scst_put_dif_buf(cmd, (void __force *)(iv[i].iov_base)); - goto out_free_iv; + goto out; } static enum compl_status_e blockio_exec_read(struct vdisk_cmd_params *p) @@ -6122,7 +6140,7 @@ static enum compl_status_e fileio_exec_read(struct vdisk_cmd_params *p) /* READ */ err = vfs_readv(fd, (struct iovec __force __user *)iv, iv_count, - &loff); + &loff, 0); if ((err < 0) || (err < full_len)) { PRINT_ERROR("readv() returned %lld from %zd", (unsigned long long int)err, @@ -6143,7 +6161,7 @@ static enum compl_status_e fileio_exec_read(struct vdisk_cmd_params *p) break; length = scst_get_buf_next(cmd, (uint8_t __force **)&address); - }; + } set_fs(old_fs); @@ -6315,8 +6333,8 @@ restart: TRACE_DBG("Writing: eiv_count %d, full_len %zd", eiv_count, full_len); /* WRITE */ - err = vfs_writev(fd, (struct iovec __force __user *)eiv, eiv_count, - &loff); + err = vfs_writev(fd, (struct iovec __force __user *)eiv, + eiv_count, &loff, 0); if (err < 0) { PRINT_ERROR("write() returned %lld from %zd", (unsigned long long int)err, @@ -6433,6 +6451,7 @@ static inline void blockio_check_finish(struct scst_blockio_work *blockio_work) static void blockio_bio_destructor(struct bio *bio) { struct scst_blockio_work *blockio_work = bio->bi_private; + bio_free(bio, blockio_work->bioset); blockio_check_finish(blockio_work); } @@ -6469,7 +6488,8 @@ static void blockio_endio(struct bio *bio) if (unlikely(error != 0)) { unsigned long flags; - PRINT_ERROR("BLOCKIO for cmd %p finished with error %d", + PRINT_ERROR_RATELIMITED( + "BLOCKIO for cmd %p finished with error %d", blockio_work->cmd, error); /* @@ -6990,6 +7010,7 @@ struct bio_priv_sync { static void blockio_bio_destructor_sync(struct bio *bio) { struct bio_priv_sync *s = bio->bi_private; + bio_free(bio, s->bs); complete(&s->c1); } @@ -7043,7 +7064,7 @@ static void blockio_end_sync_io(struct bio *bio) * Increments *@loff with the number of bytes transferred upon success. */ static ssize_t blockio_rw_sync(struct scst_vdisk_dev *virt_dev, void *buf, - size_t len, loff_t *loff, unsigned rw) + size_t len, loff_t *loff, unsigned int rw) { struct bio_priv_sync s = { COMPLETION_INITIALIZER_ONSTACK(s.c), 0, @@ -7058,7 +7079,7 @@ static ssize_t blockio_rw_sync(struct scst_vdisk_dev *virt_dev, void *buf, void *p; struct page *q; int max_nr_vecs, rc; - unsigned bytes, off; + unsigned int bytes, off; ssize_t ret = -ENOMEM; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)) && (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 6, 0)) bool submitted = false; @@ -8671,7 +8692,7 @@ out: return res; out_free: - kfree(buf); + kfree(new_size); goto out; } @@ -10103,6 +10124,7 @@ static int vdisk_write_proc(char *buffer, char **start, off_t offset, if (isdigit(*p)) { char *pp; + block_size = simple_strtoul(p, &pp, 0); p = pp; if ((*p != '\0') && !isspace(*p)) { diff --git a/scst/src/scst_copy_mgr.c b/scst/src/scst_copy_mgr.c index 049ac0529..80ca7e8cb 100644 --- a/scst/src/scst_copy_mgr.c +++ b/scst/src/scst_copy_mgr.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 - 2015 SanDisk Corporation + * Copyright (C) 2013 - 2016 SanDisk Corporation * */ @@ -2519,14 +2519,16 @@ static bool scst_cm_is_lun_free(unsigned int lun) } /* scst_mutex supposed to be held and activities suspended */ -static int scst_cm_dev_register(struct scst_device *dev) +static int scst_cm_dev_register(struct scst_device *dev, uint64_t lun) { int res, i; - unsigned int lun; struct scst_acg_dev *acg_dev; + bool add_lun; TRACE_ENTRY(); + TRACE_DBG("dev %s, LUN %ld", dev->virt_name, (unsigned long)lun); + for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct scst_tgt_dev *tgt_dev; struct list_head *head = &scst_cm_sess->sess_tgt_dev_list[i]; @@ -2541,18 +2543,25 @@ static int scst_cm_dev_register(struct scst_device *dev) } } - while (1) { - lun = scst_cm_next_lun++; - if (lun == SCST_MAX_LUN) - continue; - if (scst_cm_is_lun_free(lun)) - break; - }; + if (lun == SCST_MAX_LUN) { + add_lun = true; + while (1) { + lun = scst_cm_next_lun++; + if (lun == SCST_MAX_LUN) + continue; + if (scst_cm_is_lun_free(lun)) + break; + } + } else + add_lun = false; - res = scst_acg_add_lun(scst_cm_tgt->default_acg, - scst_cm_tgt->tgt_luns_kobj, dev, lun, 0, &acg_dev); - if (res != 0) - goto out_err; + if (add_lun) { + res = scst_acg_add_lun(scst_cm_tgt->default_acg, + scst_cm_tgt->tgt_luns_kobj, dev, lun, SCST_ADD_LUN_CM, + &acg_dev); + if (res != 0) + goto out_err; + } spin_lock_bh(&dev->dev_lock); scst_block_dev(dev); @@ -2578,13 +2587,15 @@ out_err: } /* scst_mutex supposed to be held and activities suspended */ -static void scst_cm_dev_unregister(struct scst_device *dev) +static void scst_cm_dev_unregister(struct scst_device *dev, bool del_lun) { int i; struct scst_cm_desig *des, *t; TRACE_ENTRY(); + TRACE_DBG("dev %s, del_lun %d", dev->virt_name, del_lun); + list_for_each_entry_safe(des, t, &scst_cm_desig_list, cm_desig_list_entry) { if (des->desig_tgt_dev->dev == dev) { TRACE_DBG("Deleting des %p", des); @@ -2593,6 +2604,9 @@ static void scst_cm_dev_unregister(struct scst_device *dev) } } + if (!del_lun) + goto out; + for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct scst_tgt_dev *tgt_dev; struct list_head *head = &scst_cm_sess->sess_tgt_dev_list[i]; @@ -2606,6 +2620,7 @@ static void scst_cm_dev_unregister(struct scst_device *dev) } } +out: TRACE_EXIT(); return; } @@ -2620,7 +2635,7 @@ int scst_cm_on_dev_register(struct scst_device *dev) if (!dev->handler->auto_cm_assignment_possible) goto out; - res = scst_cm_dev_register(dev); + res = scst_cm_dev_register(dev, SCST_MAX_LUN); out: TRACE_EXIT_RES(res); @@ -2632,12 +2647,87 @@ void scst_cm_on_dev_unregister(struct scst_device *dev) { TRACE_ENTRY(); - scst_cm_dev_unregister(dev); + scst_cm_dev_unregister(dev, true); TRACE_EXIT(); return; } +/* scst_mutex supposed to be held and activities suspended */ +int scst_cm_on_add_acg(struct scst_acg *acg) +{ + int res = 0; + + TRACE_ENTRY(); + + if (scst_cm_tgt == NULL) + goto out; + + if (acg->tgt != scst_cm_tgt) + goto out; + + if (acg != scst_cm_tgt->default_acg) { + PRINT_ERROR("Copy Manager does not support security groups"); + res = -EINVAL; + goto out; + } + +out: + TRACE_EXIT_RES(res); + return res; +} + +/* scst_mutex supposed to be held and activities suspended */ +void scst_cm_on_del_acg(struct scst_acg *acg) +{ + /* Nothing to do */ +} + +/* scst_mutex supposed to be held and activities suspended */ +int scst_cm_on_add_lun(struct scst_acg_dev *acg_dev, uint64_t lun, + unsigned int *flags) +{ + int res = 0; + + TRACE_ENTRY(); + + if (acg_dev->acg != scst_cm_tgt->default_acg) + goto out; + + if (acg_dev->acg_dev_rd_only || acg_dev->dev->dev_rd_only) { + PRINT_ERROR("Copy Manager does not support read only devices"); + res = -EINVAL; + goto out; + } + + *flags &= ~SCST_ADD_LUN_GEN_UA; + + res = scst_cm_dev_register(acg_dev->dev, lun); + +out: + TRACE_EXIT_RES(res); + return res; +} + +/* scst_mutex supposed to be held and activities suspended */ +bool scst_cm_on_del_lun(struct scst_acg_dev *acg_dev, bool gen_report_luns_changed) +{ + bool res = gen_report_luns_changed; + + TRACE_ENTRY(); + + if (acg_dev->acg != scst_cm_tgt->default_acg) + goto out; + + scst_cm_dev_unregister(acg_dev->dev, false); + + res = false; + +out: + TRACE_EXIT_RES(res); + return res; +} + /* scst_mutex supposed to be locked */ static bool scst_cm_check_access_acg(const char *initiator_name, const struct scst_device *dev, const struct scst_acg *acg, @@ -2935,9 +3025,8 @@ static int scst_cm_add_to_descr_list(struct scst_cmd *ec_cmd, fcmd = __scst_create_prepare_internal_cmd(ec_cmd->cdb, ec_cmd->cdb_len, SCST_CMD_QUEUE_SIMPLE, tgt_dev, GFP_KERNEL, true); - if (fcmd == NULL) { + if (fcmd == NULL) goto out_enomem_free_e; - } fcmd->expected_data_direction = ec_cmd->expected_data_direction; fcmd->expected_transfer_len_full = ec_cmd->expected_transfer_len_full; @@ -2983,8 +3072,9 @@ skip_fcmd_create: if (tp != NULL) { if (((unsigned long)t->cm_fcmd->dev) <= ((unsigned long)tp->cm_fcmd->dev)) { list_for_each_entry(t, &priv->cm_sorted_devs_list, cm_sorted_devs_list_entry) { - printk(KERN_EMERG "%s: t %p, cm dev %p\n", __func__, - t, t->cm_fcmd->dev); + pr_emerg("%s: t %p, cm dev %p\n", + __func__, t, + t->cm_fcmd->dev); } sBUG(); break; @@ -3480,148 +3570,8 @@ static struct kobj_attribute scst_cm_allow_not_conn_copy_attr = scst_cm_allow_not_conn_copy_show, scst_cm_allow_not_conn_copy_store); -static ssize_t scst_cm_mgmt_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - static const char help[] = - "Usage: echo \"add H:C:I:L\" >mgmt\n" - " echo \"add VNAME\" >mgmt\n" - " echo \"del H:C:I:L\" >mgmt\n" - " echo \"del VNAME\" >mgmt\n"; - - return sprintf(buf, "%s", help); -} - -static int scst_cm_mgmt(struct scst_sysfs_work_item *work) -{ - int res = 0; - char *pp, *action, *devstr; - unsigned int host, channel, id, lun; - char *buf = work->buf; - bool vdev; - struct scst_device *d, *dev = NULL; - - TRACE_ENTRY(); - - TRACE_DBG("buffer %s", buf); - - pp = buf; - action = scst_get_next_lexem(&pp); - devstr = scst_get_next_lexem(&pp); - if (*devstr == '\0') { - PRINT_ERROR("%s", "Device required"); - res = -EINVAL; - goto out; - } - - if (*scst_get_next_lexem(&pp) != '\0') { - PRINT_ERROR("%s", "Too many parameters"); - res = -EINVAL; - goto out_syntax_err; - } - - if (sscanf(devstr, "%u:%u:%u:%u", &host, &channel, &id, &lun) != 4) { - vdev = true; - TRACE_DBG("Virt dev %s", devstr); - } else { - vdev = false; - TRACE_DBG("Pass-through dev %d:%d:%d:%d", host, channel, id, lun); - } - - res = scst_suspend_activity(SCST_SUSPEND_TIMEOUT_USER); - if (res != 0) - goto out; - - res = mutex_lock_interruptible(&scst_mutex); - if (res != 0) - goto out_resume; - - list_for_each_entry(d, &scst_dev_list, dev_list_entry) { - if (vdev) { - if ((d->scsi_dev == NULL) && - (strcmp(d->virt_name, devstr) == 0)) { - dev = d; - break; - } - } else if (d->scsi_dev != NULL && - d->scsi_dev->host->host_no == host && - d->scsi_dev->channel == channel && - d->scsi_dev->id == id && - d->scsi_dev->lun == lun) { - dev = d; - break; - } - } - if (dev == NULL) { - PRINT_ERROR("Device %s not found", devstr); - res = -EINVAL; - goto out_unlock; - } else - TRACE_DBG("Dev %p (%s) found", dev, dev->virt_name); - - if (strcasecmp("add", action) == 0) - res = scst_cm_dev_register(dev); - else if (strcasecmp("del", action) == 0) - scst_cm_dev_unregister(dev); - else { - PRINT_ERROR("Action %s not understood", action); - res = -EINVAL; - } - -out_unlock: - mutex_unlock(&scst_mutex); - -out_resume: - scst_resume_activity(); - -out: - TRACE_EXIT_RES(res); - return res; - -out_syntax_err: - PRINT_ERROR("Syntax error on \"%s\"", buf); - res = -EINVAL; - goto out; -} - -static ssize_t scst_cm_mgmt_store(struct kobject *kobj, - struct kobj_attribute *attr, const char *buffer, size_t size) -{ - int res; - struct scst_sysfs_work_item *work; - char *i_buf; - - TRACE_ENTRY(); - - i_buf = kasprintf(GFP_KERNEL, "%.*s", (int)size, buffer); - if (i_buf == NULL) { - PRINT_ERROR("Unable to alloc intermediate buffer with size %zd", - size+1); - res = -ENOMEM; - goto out; - } - - res = scst_alloc_sysfs_work(scst_cm_mgmt, false, &work); - if (res != 0) - goto out; - - work->buf = i_buf; - - res = scst_sysfs_queue_wait_work(work); - if (res == 0) - res = size; - -out: - TRACE_EXIT_RES(res); - return res; -} - -static struct kobj_attribute scst_cm_mgmt_attr = - __ATTR(mgmt, S_IRUGO|S_IWUSR, scst_cm_mgmt_show, scst_cm_mgmt_store); - -static const struct attribute *scst_cm_attrs[] = { +static const struct attribute *scst_cm_tgtt_attrs[] = { &scst_cm_allow_not_conn_copy_attr.attr, - &scst_cm_mgmt_attr.attr, NULL, }; @@ -3693,6 +3643,12 @@ static void scst_cm_task_mgmt_fn_done(struct scst_mgmt_cmd *scst_mcmd) return; } +static int scst_cm_report_aen(struct scst_aen *aen) +{ + /* Nothing to do */ + return 0; +} + static struct scst_tgt_template scst_cm_tgtt = { .name = SCST_CM_NAME, #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) @@ -3710,9 +3666,10 @@ static struct scst_tgt_template scst_cm_tgtt = { .release = scst_cm_release, .xmit_response = scst_cm_xmit_response, .task_mgmt_fn_done = scst_cm_task_mgmt_fn_done, + .report_aen = scst_cm_report_aen, .get_initiator_port_transport_id = scst_cm_get_initiator_port_transport_id, #ifndef CONFIG_SCST_PROC - .tgtt_attrs = scst_cm_attrs, + .tgtt_attrs = scst_cm_tgtt_attrs, #endif }; diff --git a/scst/src/scst_debug.c b/scst/src/scst_debug.c index 176e6dcad..16f04f453 100644 --- a/scst/src/scst_debug.c +++ b/scst/src/scst_debug.c @@ -1,9 +1,9 @@ /* * scst_debug.c * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 SanDisk Corporation * * Contains helper functions for execution tracing and error reporting. * Intended to be included in main .c file. diff --git a/scst/src/scst_dlm.c b/scst/src/scst_dlm.c index 0aa1372ea..5b4f79cf5 100644 --- a/scst/src/scst_dlm.c +++ b/scst/src/scst_dlm.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013 - 2014 Fusion-io, Inc. All rights reserved. - * Copyright (C) 2014 - 2015 SanDisk Corporation. + * Copyright (C) 2014 - 2016 SanDisk Corporation. * * Synchronization of persistent registration data with DLM lock value blocks. * @@ -30,6 +30,9 @@ #include "scst_pres.h" #include "scst_dlm.h" +#if (defined(CONFIG_DLM) || defined(CONFIG_DLM_MODULE)) && \ + !defined(CONFIG_SCST_NO_DLM) + static void scst_pr_dlm_cleanup(struct scst_device *dev); static void scst_dlm_pre_bast(void *bastarg, int mode); static void scst_dlm_post_bast(void *bastarg, int mode); @@ -522,11 +525,11 @@ struct scst_dlm_readdir_context { /* Append the name of each directory entry to the buffer @arg points to. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0) static int scst_dlm_filldir(void *arg, const char *name_arg, int name_len, - loff_t curr_pos, u64 inode, unsigned dtype) + loff_t curr_pos, u64 inode, unsigned int dtype) #else static int scst_dlm_filldir(struct dir_context *arg, const char *name_arg, int name_len, loff_t curr_pos, u64 inode, - unsigned dtype) + unsigned int dtype) #endif { char *p, *q, name[64]; @@ -1493,3 +1496,5 @@ const struct scst_cl_ops scst_dlm_cl_ops = { .is_not_rsv_holder = scst_dlm_is_not_rsv_holder, .reserve = scst_dlm_reserve, }; + +#endif diff --git a/scst/src/scst_dlm.h b/scst/src/scst_dlm.h index 0e0956060..f7dbb4cec 100644 --- a/scst/src/scst_dlm.h +++ b/scst/src/scst_dlm.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2013 - 2014 Fusion-io, Inc. All rights reserved. - * Copyright (C) 2014 - 2015 SanDisk Corporation. + * Copyright (C) 2014 - 2016 SanDisk Corporation. * * Synchronization of persistent registration data with DLM lock value blocks. * diff --git a/scst/src/scst_event.c b/scst/src/scst_event.c index 3b36b8e50..49805dbd7 100644 --- a/scst/src/scst_event.c +++ b/scst/src/scst_event.c @@ -1,7 +1,7 @@ /* * scst_event.c * - * Copyright (C) 2014 - 2015 SanDisk Corporation + * Copyright (C) 2014 - 2016 SanDisk Corporation * */ @@ -27,7 +27,7 @@ static struct class *scst_event_sysfs_class; static int scst_event_major; #define SCST_MAX_EVENTS 2048 -#define SCST_MAX_PAYLOAD 3*1024 +#define SCST_MAX_PAYLOAD (3*1024) #define SCST_DEFAULT_EVENT_TIMEOUT (60*HZ) struct scst_event_priv { @@ -866,7 +866,7 @@ static int scst_event_create_priv(struct file *file) PRINT_ERROR("Unable to allocate priv (size %zd)", sizeof(*priv)); res = -ENOMEM; - goto out; + goto out_put; } TRACE_MEM("priv %p allocated", priv); @@ -891,6 +891,10 @@ static int scst_event_create_priv(struct file *file) out: TRACE_EXIT_RES(res); return res; + +out_put: + module_put(THIS_MODULE); + goto out; } static long scst_event_ioctl(struct file *file, unsigned int cmd, @@ -1087,13 +1091,13 @@ int scst_event_init(void) } #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 21) - class_member = class_device_create(scst_event_sysfs_class, NULL, + class_member = class_device_create(scst_event_sysfs_class, NULL, MKDEV(scst_event_major, 0), NULL, SCST_EVENT_NAME); - if (IS_ERR(class_member)) { - res = PTR_ERR(class_member); - goto out_chrdev; - } + if (IS_ERR(class_member)) { + res = PTR_ERR(class_member); + goto out_chrdev; + } #else dev = device_create(scst_event_sysfs_class, NULL, MKDEV(scst_event_major, 0), diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index c73c54ba8..3fb4e0d29 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -1,11 +1,9 @@ /* * scst_lib.c * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar - * Copyright (C) 2007 - 2015 SanDisk Corporation - * Copyright (C) 2015 Permabit Technology Corporation. - * Copyright (C) 2015 Calsoft Pvt. Ltd. + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -1953,6 +1951,7 @@ go: memset(buf, 0, len); buf[0] = 0x7F; /* Peripheral qualifier 011b, Peripheral device type 1Fh */ + buf[2] = 6; /* Device complies to SPC-4 */ buf[4] = len - 4; TRACE_BUFFER("INQUIRY for not supported LUN set", buf, len); @@ -4444,6 +4443,12 @@ int scst_acg_add_lun(struct scst_acg *acg, struct kobject *parent, list_add_tail(&acg_dev->acg_dev_list_entry, &acg->acg_dev_list); list_add_tail(&acg_dev->dev_acg_dev_list_entry, &dev->dev_acg_dev_list); + if (!(flags & SCST_ADD_LUN_CM)) { + res = scst_cm_on_add_lun(acg_dev, lun, &flags); + if (res != 0) + goto out_free; + } + list_for_each_entry(sess, &acg->acg_sess_list, acg_sess_list_entry) { res = scst_alloc_add_tgt_dev(sess, acg_dev, &tgt_dev); if (res == -EPERM) @@ -4457,7 +4462,7 @@ int scst_acg_add_lun(struct scst_acg *acg, struct kobject *parent, res = scst_acg_dev_sysfs_create(acg_dev, parent); if (res != 0) - goto out_free; + goto out_on_del; if (flags & SCST_ADD_LUN_GEN_UA) scst_report_luns_changed(acg); @@ -4473,6 +4478,10 @@ out: TRACE_EXIT_RES(res); return res; +out_on_del: + if (!(flags & SCST_ADD_LUN_CM)) + scst_cm_on_del_lun(acg_dev, false); + out_free: list_for_each_entry_safe(tgt_dev, tt, &tmp_tgt_dev_list, extra_tgt_dev_list_entry) { @@ -4482,9 +4491,11 @@ out_free: goto out; } +/* Delete a LUN without generating a unit attention. */ static struct scst_acg_dev *__scst_acg_del_lun(struct scst_acg *acg, uint64_t lun, - struct list_head *tgt_dev_list) + struct list_head *tgt_dev_list, + bool *report_luns_changed) { struct scst_acg_dev *acg_dev = NULL, *a; struct scst_tgt_dev *tgt_dev, *tt; @@ -4503,6 +4514,9 @@ static struct scst_acg_dev *__scst_acg_del_lun(struct scst_acg *acg, if (acg_dev == NULL) goto out; + *report_luns_changed = scst_cm_on_del_lun(acg_dev, + *report_luns_changed); + list_for_each_entry_safe(tgt_dev, tt, &acg_dev->dev->dev_tgt_dev_list, dev_tgt_dev_list_entry) { if (tgt_dev->acg_dev == acg_dev) { @@ -4519,6 +4533,9 @@ static struct scst_acg_dev *__scst_acg_del_lun(struct scst_acg *acg, scst_del_acg_dev(acg_dev, true, true); + PRINT_INFO("Removed LUN %lld from group %s (target %s)", + lun, acg->acg_name, acg->tgt ? acg->tgt->tgt_name : "?"); + out: return acg_dev; } @@ -4541,9 +4558,9 @@ static void scst_wait_for_tgt_devs(struct list_head *tgt_dev_list) } int scst_acg_del_lun(struct scst_acg *acg, uint64_t lun, - bool gen_scst_report_luns_changed) + bool gen_report_luns_changed) { - int res = -EINVAL; + int res = 0; struct scst_acg_dev *acg_dev; struct scst_tgt_dev *tgt_dev, *tt; struct list_head tgt_dev_list; @@ -4552,13 +4569,15 @@ int scst_acg_del_lun(struct scst_acg *acg, uint64_t lun, lockdep_assert_held(&scst_mutex); - acg_dev = __scst_acg_del_lun(acg, lun, &tgt_dev_list); + acg_dev = __scst_acg_del_lun(acg, lun, &tgt_dev_list, + &gen_report_luns_changed); if (acg_dev == NULL) { PRINT_ERROR("Device is not found in group %s", acg->acg_name); + res = -EINVAL; goto out; } - if (gen_scst_report_luns_changed) + if (gen_report_luns_changed) scst_report_luns_changed(acg); mutex_unlock(&scst_mutex); @@ -4573,31 +4592,27 @@ int scst_acg_del_lun(struct scst_acg *acg, uint64_t lun, } scst_free_acg_dev(acg_dev); - res = 0; - - PRINT_INFO("Removed LUN %lld from group %s (target %s)", - lun, acg->acg_name, acg->tgt ? acg->tgt->tgt_name : "?"); - out: TRACE_EXIT_RES(res); return res; } +/* Either add or replace a LUN. */ int scst_acg_repl_lun(struct scst_acg *acg, struct kobject *parent, struct scst_device *dev, uint64_t lun, unsigned int flags) { struct scst_acg_dev *acg_dev; + bool del_gen_ua = false; struct scst_tgt_dev *tgt_dev, *tt; struct list_head tgt_dev_list; int res = -EINVAL; - TRACE_ENTRY(); - lockdep_assert_held(&scst_mutex); - acg_dev = __scst_acg_del_lun(acg, lun, &tgt_dev_list); - + acg_dev = __scst_acg_del_lun(acg, lun, &tgt_dev_list, &del_gen_ua); + if (!acg_dev) + flags |= SCST_ADD_LUN_GEN_UA; res = scst_acg_add_lun(acg, parent, dev, lun, flags, NULL); if (res != 0) goto out; @@ -4626,21 +4641,22 @@ int scst_acg_repl_lun(struct scst_acg *acg, struct kobject *parent, scst_free_acg_dev(acg_dev); out: - TRACE_EXIT_RES(res); return res; } /* The activity supposed to be suspended and scst_mutex held */ -struct scst_acg *scst_alloc_add_acg(struct scst_tgt *tgt, - const char *acg_name, bool tgt_acg) +int scst_alloc_add_acg(struct scst_tgt *tgt, const char *acg_name, + bool tgt_acg, struct scst_acg **out_acg) { struct scst_acg *acg; + int res; TRACE_ENTRY(); acg = kzalloc(sizeof(*acg), GFP_KERNEL); if (acg == NULL) { PRINT_ERROR("%s", "Allocation of acg failed"); + res = -ENOMEM; goto out; } @@ -4653,9 +4669,14 @@ struct scst_acg *scst_alloc_add_acg(struct scst_tgt *tgt, acg->acg_name = kstrdup(acg_name, GFP_KERNEL); if (acg->acg_name == NULL) { PRINT_ERROR("%s", "Allocation of acg_name failed"); + res = -ENOMEM; goto out_free; } + res = scst_cm_on_add_acg(acg); + if (res != 0) + goto out_undup; + #ifdef CONFIG_SCST_PROC acg->addr_method = tgt && tgt->tgtt ? tgt->tgtt->preferred_addr_method : SCST_LUN_ADDR_METHOD_PERIPHERAL; @@ -4668,30 +4689,35 @@ struct scst_acg *scst_alloc_add_acg(struct scst_tgt *tgt, acg->addr_method = tgt->tgtt->preferred_addr_method; if (tgt_acg) { - int rc; - TRACE_DBG("Adding acg '%s' to device '%s' acg_list", acg_name, tgt->tgt_name); list_add_tail(&acg->acg_list_entry, &tgt->tgt_acg_list); acg->tgt_acg = 1; - rc = scst_acg_sysfs_create(tgt, acg); - if (rc != 0) + res = scst_acg_sysfs_create(tgt, acg); + if (res != 0) goto out_del; } kobject_get(&tgt->tgt_kobj); #endif + res = 0; + out: - TRACE_EXIT_HRES(acg); - return acg; + *out_acg = acg; + + TRACE_EXIT_RES(res); + return res; #ifndef CONFIG_SCST_PROC out_del: list_del(&acg->acg_list_entry); #endif +out_undup: + kfree(acg->acg_name); + out_free: kfree(acg); acg = NULL; @@ -4714,6 +4740,8 @@ static void scst_del_acg(struct scst_acg *acg) scst_assert_activity_suspended(); lockdep_assert_held(&scst_mutex); + scst_cm_on_del_acg(acg); + list_for_each_entry_safe(acg_dev, acg_dev_tmp, &acg->acg_dev_list, acg_dev_list_entry) scst_del_acg_dev(acg_dev, false, true); @@ -6834,7 +6862,7 @@ static void scst_send_release(struct scst_device *dev) "SCSI mid-level"); rc = scsi_execute(scsi_dev, cdb, SCST_DATA_NONE, NULL, 0, sense, 15, 0, 0 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) , NULL #endif ); @@ -7885,6 +7913,9 @@ static struct request *__blk_map_kern_sg(struct request_queue *q, (PAGE_SIZE - sizeof(struct bio)) / sizeof(struct bio_vec), BIO_MAX_PAGES); + TRACE_DBG("max_nr_vecs %d, nents %d, reading %d", max_nr_vecs, + nents, reading); + need_new_bio = true; tot_len = 0; bios = 0; @@ -7906,6 +7937,10 @@ static struct request *__blk_map_kern_sg(struct request_queue *q, l = 0; else l = len; + + TRACE_DBG("i %d, len %zd, tot_len %zd, l %zd, offset %zd", + i, len, tot_len, l, offset); + if (((sg->offset | l) & queue_dma_alignment(q)) || (page_addr && object_is_on_stack(page_addr + sg->offset))) { rq = ERR_PTR(-EINVAL); @@ -7940,6 +7975,8 @@ static struct request *__blk_map_kern_sg(struct request_queue *q, bio->bi_private = bw; bio->bi_end_io = blk_bio_map_kern_endio; + TRACE_DBG("new bio %p, bios %d", bio, bios); + if (hbio == NULL) hbio = bio; else @@ -7949,6 +7986,8 @@ static struct request *__blk_map_kern_sg(struct request_queue *q, bytes = min_t(size_t, len, PAGE_SIZE - offset); + TRACE_DBG("len %zd, bytes %zd, offset %zd", len, bytes, offset); + rc = bio_add_pc_page(q, bio, page, bytes, offset); if (rc < bytes) { if (unlikely(need_new_bio || rc < 0)) { @@ -12163,6 +12202,19 @@ int scst_block_generic_dev_done(struct scst_cmd *cmd, TRACE_ENTRY(); + /* + * SCST sets good defaults for cmd->is_send_status and + * cmd->resp_data_len based on cmd->status and cmd->data_direction, + * therefore change them only if necessary + */ + + /* + * Potentially, a pass-through backend device can at any time change + * block size behind us, e.g. after FORMAT command, so we need to + * somehow detect it. Intercepting READ CAPACITY is, probably, the + * simplest, yet sufficient way for that. + */ + if (unlikely(opcode == READ_CAPACITY || (opcode == SERVICE_ACTION_IN_16 && cmd->cdb[1] == SAI_READ_CAPACITY_16))) { @@ -12172,8 +12224,8 @@ int scst_block_generic_dev_done(struct scst_cmd *cmd, uint8_t *buffer; buffer_size = scst_get_buf_full(cmd, &buffer); - if (unlikely(buffer_size <= 0)) { - if (buffer_size < 0) { + if (unlikely(buffer_size < 8)) { + if (buffer_size != 0) { PRINT_ERROR("%s: Unable to get cmd " "buffer (%d)", __func__, buffer_size); @@ -12195,7 +12247,7 @@ int scst_block_generic_dev_done(struct scst_cmd *cmd, cmd->op_name); } } - } else { + } else /* ToDo: add READ CAPACITY(16) here */ { /* It's all good */ } @@ -13227,7 +13279,7 @@ int scst_obtain_device_parameters(struct scst_device *dev, TRACE(TRACE_SCSI, "%s", "Doing internal MODE_SENSE"); rc = scsi_execute(dev->scsi_dev, cmd, SCST_DATA_READ, buffer, sizeof(buffer), sense_buffer, 15, 0, 0 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) , NULL #endif ); @@ -14527,7 +14579,7 @@ out_unlock: #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39) void scst_vfs_unlink_and_put(struct nameidata *nd) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) vfs_unlink(nd->dentry->d_parent->d_inode, nd->dentry); dput(nd->dentry); mntput(nd->mnt); @@ -14541,7 +14593,9 @@ void scst_vfs_unlink_and_put(struct nameidata *nd) void scst_vfs_unlink_and_put(struct path *path) { #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) && \ - (!defined(RHEL_MAJOR) || RHEL_MAJOR -0 < 7) + (!defined(RHEL_MAJOR) || RHEL_MAJOR -0 < 7) && \ + (!defined(CONFIG_SUSE_KERNEL) || \ + LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0)) vfs_unlink(path->dentry->d_parent->d_inode, path->dentry); #else vfs_unlink(path->dentry->d_parent->d_inode, path->dentry, NULL); @@ -14553,7 +14607,7 @@ void scst_vfs_unlink_and_put(struct path *path) #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39) void scst_path_put(struct nameidata *nd) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) dput(nd->dentry); mntput(nd->mnt); #else diff --git a/scst/src/scst_main.c b/scst/src/scst_main.c index 26e1a5648..995b30c59 100644 --- a/scst/src/scst_main.c +++ b/scst/src/scst_main.c @@ -1,9 +1,9 @@ /* * scst_main.c * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -550,8 +550,8 @@ struct scst_tgt *scst_register_target(struct scst_tgt_template *vtt, if (rc < 0) goto out_unlock; - tgt->default_acg = scst_alloc_add_acg(tgt, tgt->tgt_name, false); - if (tgt->default_acg == NULL) + rc = scst_alloc_add_acg(tgt, tgt->tgt_name, false, &tgt->default_acg); + if (rc != 0) goto out_sysfs_del; #endif @@ -645,6 +645,18 @@ again: mutex_unlock(&scst_mutex); #endif + /* + * Testing tgt->sysfs_sess_list below without holding scst_mutex + * is safe, because: + * + * - On the init path no attempts to create new sessions for this + * target can be done in a race with this function (see above) + * + * - On the shutdown path 'tgt' won't disappear until scst_free_tgt() + * is called below and because the mutex_lock(&scst_mutex) call below + * waits until scst_free_session() has finished accessing the 'tgt' + * object. + */ TRACE_DBG("%s", "Waiting for sessions shutdown"); wait_event(tgt->unreg_waitQ, list_empty(&tgt->sysfs_sess_list)); TRACE_DBG("%s", "wait_event() returned"); @@ -713,7 +725,7 @@ static const char *const scst_cmd_state_name[] = { [SCST_CMD_STATE_XMIT_WAIT] = "XMIT_WAIT", }; -char *scst_get_cmd_state_name(char *name, int len, unsigned state) +char *scst_get_cmd_state_name(char *name, int len, unsigned int state) { if (state < ARRAY_SIZE(scst_cmd_state_name) && scst_cmd_state_name[state]) @@ -792,7 +804,7 @@ static const char *const scst_tm_fn_name[] = { [SCST_PR_ABORT_ALL] = "PR_ABORT_ALL", }; -char *scst_get_tm_fn_name(char *name, int len, unsigned fn) +char *scst_get_tm_fn_name(char *name, int len, unsigned int fn) { if (fn < ARRAY_SIZE(scst_tm_fn_name) && scst_tm_fn_name[fn]) strlcpy(name, scst_tm_fn_name[fn], len); @@ -811,7 +823,7 @@ static const char *const scst_mcmd_state_name[] = { [SCST_MCMD_STATE_FINISHED] = "FINISHED", }; -char *scst_get_mcmd_state_name(char *name, int len, unsigned state) +char *scst_get_mcmd_state_name(char *name, int len, unsigned int state) { if (state < ARRAY_SIZE(scst_mcmd_state_name) && scst_mcmd_state_name[state]) @@ -1047,6 +1059,11 @@ static void __scst_resume_activity(void) TRACE_ENTRY(); + if (suspend_count == 0) { + PRINT_WARNING("Resume without suspend"); + goto out; + } + suspend_count--; TRACE_MGMT_DBG("suspend_count %d left", suspend_count); if (suspend_count > 0) @@ -1075,7 +1092,8 @@ static void __scst_resume_activity(void) TRACE_MGMT_DBG("Moving delayed mgmt cmd %p to head of active " "mgmt cmd list", m); } - list_splice(&scst_delayed_mgmt_cmd_list, &scst_active_mgmt_cmd_list); + list_splice_init(&scst_delayed_mgmt_cmd_list, + &scst_active_mgmt_cmd_list); spin_unlock_irq(&scst_mcmd_lock); wake_up_all(&scst_mgmt_cmd_list_waitQ); @@ -1107,6 +1125,11 @@ void scst_resume_activity(void) } EXPORT_SYMBOL_GPL(scst_resume_activity); +int scst_get_suspend_count(void) +{ + return suspend_count; +} + static int scst_register_device(struct scsi_device *scsidp) { int res; @@ -1156,6 +1179,17 @@ static int scst_register_device(struct scsi_device *scsidp) dev->scsi_dev = scsidp; +#ifdef CONFIG_SCST_FORWARD_MODE_PASS_THROUGH + res = scst_pr_set_file_name(dev, NULL, "%s/%s", SCST_PR_DIR, + dev->virt_name); + if (res != 0) + goto out_free_dev; + + res = scst_pr_init_dev(dev); + if (res != 0) + goto out_free_dev; +#endif + list_add_tail(&dev->dev_list_entry, &scst_dev_list); #ifdef CONFIG_SCST_PROC @@ -1203,6 +1237,10 @@ out_del_locked: list_del_init(&dev->dev_list_entry); #endif +#ifdef CONFIG_SCST_FORWARD_MODE_PASS_THROUGH + scst_pr_clear_dev(dev); +#endif + out_free_dev: scst_free_device(dev); @@ -1260,6 +1298,10 @@ static void scst_unregister_device(struct scsi_device *scsidp) list_del_init(&dev->dev_list_entry); +#ifdef CONFIG_SCST_FORWARD_MODE_PASS_THROUGH + scst_pr_clear_dev(dev); +#endif + scst_dg_dev_remove_by_dev(dev); scst_assign_dev_handler(dev, &scst_null_devtype); @@ -2628,11 +2670,9 @@ static int __init init_scst(void) goto out_sysfs_cleanup; #ifdef CONFIG_SCST_PROC - scst_default_acg = scst_alloc_add_acg(NULL, SCST_DEFAULT_ACG_NAME, false); - if (scst_default_acg == NULL) { - res = -ENOMEM; + res = scst_alloc_add_acg(NULL, SCST_DEFAULT_ACG_NAME, false, &scst_default_acg); + if (res != 0) goto out_destroy_sgv_pool; - } #endif res = scsi_register_interface(&scst_interface); diff --git a/scst/src/scst_mem.c b/scst/src/scst_mem.c index 9800d1a65..56d51c09c 100644 --- a/scst/src/scst_mem.c +++ b/scst/src/scst_mem.c @@ -1,8 +1,8 @@ /* * scst_mem.c * - * Copyright (C) 2006 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2006 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -366,7 +366,7 @@ static unsigned long __sgv_can_be_shrunk(void) } spin_unlock_bh(&sgv_pools_lock); - res = max((int)0, inactive_pages - sgv_lo_wmk); + res = max(0, inactive_pages - sgv_lo_wmk); TRACE_MEM("Can free %ld (total %d)", res, atomic_read(&sgv_pages_total)); TRACE_EXIT_RES(res); diff --git a/scst/src/scst_mem.h b/scst/src/scst_mem.h index e36153e64..8b37ca2a0 100644 --- a/scst/src/scst_mem.h +++ b/scst/src/scst_mem.h @@ -1,8 +1,8 @@ /* * scst_mem.h * - * Copyright (C) 2006 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2006 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/scst/src/scst_module.c b/scst/src/scst_module.c index da5a29fda..7ded3af32 100644 --- a/scst/src/scst_module.c +++ b/scst/src/scst_module.c @@ -1,9 +1,9 @@ /* * scst_module.c * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 SanDisk Corporation * * Support for loading target modules. The usage is similar to scsi_module.c * diff --git a/scst/src/scst_no_dlm.c b/scst/src/scst_no_dlm.c index 2c6d639d4..04ee63560 100644 --- a/scst/src/scst_no_dlm.c +++ b/scst/src/scst_no_dlm.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013 - 2014 Fusion-io, Inc. All rights reserved. - * Copyright (C) 2014 - 2015 SanDisk Corporation. + * Copyright (C) 2014 - 2016 SanDisk Corporation. * * Synchronization framework of persistent registration data without DLM lock. * diff --git a/scst/src/scst_pres.c b/scst/src/scst_pres.c index 8ce467d6e..5ac78d112 100644 --- a/scst/src/scst_pres.c +++ b/scst/src/scst_pres.c @@ -3,7 +3,7 @@ * * Copyright (C) 2009 - 2010 Alexey Obitotskiy * Copyright (C) 2009 - 2010 Open-E, Inc. - * Copyright (C) 2009 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2009 - 2016 Vladislav Bolkhovitin * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -47,7 +47,7 @@ #include #include -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) #include #endif @@ -1173,10 +1173,12 @@ void scst_pr_cleanup(struct scst_device *dev) int scst_pr_set_cluster_mode(struct scst_device *dev, bool cluster_mode, const char *cl_dev_id) { - bool cluster_mode_enabled = false; int res = 0; -#if defined(CONFIG_DLM) || defined(CONFIG_DLM_MODULE) +#if defined(CONFIG_DLM) || defined(CONFIG_DLM_MODULE) && \ + !defined(CONFIG_SCST_NO_DLM) + bool cluster_mode_enabled = false; + cluster_mode_enabled = dev->cl_ops == &scst_dlm_cl_ops; if (cluster_mode_enabled == cluster_mode) @@ -1192,11 +1194,12 @@ int scst_pr_set_cluster_mode(struct scst_device *dev, bool cluster_mode, dev->virt_name, cluster_mode, res); dev->cl_ops = &scst_no_dlm_cl_ops; } + +out: #else res = cluster_mode ? -ENOTSUPP : 0; #endif -out: return res; } EXPORT_SYMBOL(scst_pr_set_cluster_mode); diff --git a/scst/src/scst_pres.h b/scst/src/scst_pres.h index 5ee98a3ef..94a69f379 100644 --- a/scst/src/scst_pres.h +++ b/scst/src/scst_pres.h @@ -3,7 +3,7 @@ * * Copyright (C) 2009 - 2010 Alexey Obitotskiy * Copyright (C) 2009 - 2010 Open-E, Inc. - * Copyright (C) 2009 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2009 - 2016 Vladislav Bolkhovitin * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/scst/src/scst_priv.h b/scst/src/scst_priv.h index 0181356fc..e7bfd9862 100644 --- a/scst/src/scst_priv.h +++ b/scst/src/scst_priv.h @@ -1,9 +1,9 @@ /* * scst_priv.h * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -278,9 +278,9 @@ extern void scst_tgt_dev_stop_threads(struct scst_tgt_dev *tgt_dev); extern struct scst_dev_type scst_null_devtype; -char *scst_get_cmd_state_name(char *name, int len, unsigned state); -char *scst_get_mcmd_state_name(char *name, int len, unsigned state); -char *scst_get_tm_fn_name(char *name, int len, unsigned fn); +char *scst_get_cmd_state_name(char *name, int len, unsigned int state); +char *scst_get_mcmd_state_name(char *name, int len, unsigned int state); +char *scst_get_tm_fn_name(char *name, int len, unsigned int fn); extern struct scst_cmd *__scst_check_deferred_commands_locked( struct scst_order_data *order_data, bool return_first); @@ -348,8 +348,8 @@ int scst_alloc_device(gfp_t gfp_mask, struct scst_device **out_dev); void scst_free_device(struct scst_device *dev); bool scst_device_is_exported(struct scst_device *dev); -struct scst_acg *scst_alloc_add_acg(struct scst_tgt *tgt, - const char *acg_name, bool tgt_acg); +int scst_alloc_add_acg(struct scst_tgt *tgt, const char *acg_name, + bool tgt_acg, struct scst_acg **out_acg); int scst_del_free_acg(struct scst_acg *acg, bool close_sessions); void scst_get_acg(struct scst_acg *acg); void scst_put_acg(struct scst_acg *acg); @@ -429,7 +429,7 @@ static inline int scst_dlm_new_lockspace(const char *name, int namelen, #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30) static inline int scst_exec_req(struct scsi_device *sdev, const unsigned char *cmd, int cmd_len, int data_direction, - struct scatterlist *sgl, unsigned bufflen, unsigned nents, + struct scatterlist *sgl, unsigned int bufflen, unsigned int nents, int timeout, int retries, void *privdata, void (*done)(void *, char *, int, int), gfp_t gfp) { @@ -738,6 +738,8 @@ void scst_ext_unblock_dev(struct scst_device *dev, bool stpg); void __scst_ext_blocking_done(struct scst_device *dev); void scst_ext_blocking_done(struct scst_device *dev); +int scst_get_suspend_count(void); + /* * Increases global SCST ref counters which prevent from entering into suspended * activities stage, so protects from any global management operations. @@ -872,6 +874,13 @@ static inline bool scst_lba1_inside_lba2(int64_t lba1, int scst_cm_on_dev_register(struct scst_device *dev); void scst_cm_on_dev_unregister(struct scst_device *dev); +int scst_cm_on_add_acg(struct scst_acg *acg); +void scst_cm_on_del_acg(struct scst_acg *acg); +int scst_cm_on_add_lun(struct scst_acg_dev *acg_dev, uint64_t lun, + unsigned int *flags); +bool scst_cm_on_del_lun(struct scst_acg_dev *acg_dev, + bool gen_report_luns_changed); + int scst_cm_parse_descriptors(struct scst_cmd *cmd); void scst_cm_free_descriptors(struct scst_cmd *cmd); @@ -898,6 +907,27 @@ void scst_cm_exit(void); static inline int scst_cm_on_dev_register(struct scst_device *dev) { return 0; } static inline void scst_cm_on_dev_unregister(struct scst_device *dev) {} +static inline int scst_cm_on_add_acg(struct scst_acg *acg) +{ + return 0; +} + +static inline void scst_cm_on_del_acg(struct scst_acg *acg) +{ +} + +static inline int scst_cm_on_add_lun(struct scst_acg_dev *acg_dev, uint64_t lun, + unsigned int *flags) +{ + return 0; +} + +static inline bool scst_cm_on_del_lun(struct scst_acg_dev *acg_dev, + bool gen_report_luns_changed) +{ + return gen_report_luns_changed; +} + static inline int scst_cm_parse_descriptors(struct scst_cmd *cmd) { scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_invalid_opcode)); @@ -915,7 +945,11 @@ static inline int scst_cm_rcv_copy_res_exec(struct scst_cmd *cmd) return SCST_EXEC_NOT_COMPLETED; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) +static inline void sess_cm_list_id_cleanup_work_fn(void *p) {} +#else static inline void sess_cm_list_id_cleanup_work_fn(struct work_struct *work) {} +#endif static inline void scst_cm_free_pending_list_ids(struct scst_session *sess) {} static inline bool scst_cm_check_block_all_devs(struct scst_cmd *cmd) { return false; } diff --git a/scst/src/scst_proc.c b/scst/src/scst_proc.c index 91a8b880f..c529f0b45 100644 --- a/scst/src/scst_proc.c +++ b/scst/src/scst_proc.c @@ -1,9 +1,9 @@ /* * scst_proc.c * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -235,6 +235,7 @@ static DEFINE_MUTEX(scst_proc_mutex); static int strcasecmp(const char *s1, const char *s2) { int c1, c2; + do { c1 = tolower(*s1++); c2 = tolower(*s2++); @@ -246,6 +247,7 @@ static int strcasecmp(const char *s1, const char *s2) static int strncasecmp(const char *s1, const char *s2, size_t n) { int c1, c2; + do { c1 = tolower(*s1++); c2 = tolower(*s2++); @@ -596,6 +598,7 @@ static int lat_info_show(struct seq_file *seq, void *v) struct list_head *head = &sess->sess_tgt_dev_list[t]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry_rcu(tgt_dev, head, sess_tgt_dev_list_entry) { @@ -767,6 +770,7 @@ static ssize_t scst_proc_scsi_tgt_gen_write_lat(struct file *file, struct list_head *head = &sess->sess_tgt_dev_list[t]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry_rcu(tgt_dev, head, sess_tgt_dev_list_entry) { tgt_dev->scst_time = 0; @@ -953,8 +957,8 @@ static int scst_proc_group_add(const char *p, unsigned int addr_method) } strlcpy(name, p, len); - acg = scst_alloc_add_acg(NULL, name, false); - if (acg == NULL) { + res = scst_alloc_add_acg(NULL, name, false, &acg); + if (res != 0) { PRINT_ERROR("scst_alloc_add_acg() (name %s) failed", name); goto out_free; } @@ -974,6 +978,7 @@ out_free_acg: out_free: kfree(name); + goto out; out_nomem: res = -ENOMEM; @@ -1114,7 +1119,7 @@ static int __init scst_proc_init_sgv(void) return res; } -static void __exit scst_proc_cleanup_sgv(void) +static void scst_proc_cleanup_sgv(void) { TRACE_ENTRY(); remove_proc_entry("sgv", scst_proc_scsi_tgt); @@ -1221,7 +1226,7 @@ out_nomem: goto out; } -void __exit scst_proc_cleanup_module(void) +void scst_proc_cleanup_module(void) { TRACE_ENTRY(); @@ -2074,8 +2079,9 @@ static ssize_t scst_proc_groups_devices_write(struct file *file, } } - rc = scst_acg_add_lun(acg, NULL, dev, virt_lun, read_only, - false, NULL); + rc = scst_acg_add_lun(acg, NULL, dev, virt_lun, + read_only ? SCST_ADD_LUN_READ_ONLY : 0, + NULL); if (rc) { res = rc; goto out_free_up; @@ -2109,6 +2115,7 @@ static ssize_t scst_proc_groups_devices_write(struct file *file, * procfs is now obsoleted. */ struct scst_acg_dev *a; + list_for_each_entry(a, &acg->acg_dev_list, acg_dev_list_entry) { if (a->dev == dev) { rc = scst_acg_del_lun(acg, a->lun, true); @@ -2257,6 +2264,7 @@ static ssize_t scst_proc_groups_names_write(struct file *file, { struct scst_acg *a, *new_acg = NULL; char *name = p; + p = pp; while (!isspace(*pp) && *pp != '\0') pp++; @@ -2438,6 +2446,7 @@ static int scst_sessions_info_show(struct seq_file *seq, void *v) struct list_head *head = &sess->sess_tgt_dev_list[t]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry_rcu(tgt_dev, head, sess_tgt_dev_list_entry) { active_cmds += atomic_read(&tgt_dev->tgt_dev_cmd_count); diff --git a/scst/src/scst_sysfs.c b/scst/src/scst_sysfs.c index eb1ab9274..e9eeead3e 100644 --- a/scst/src/scst_sysfs.c +++ b/scst/src/scst_sysfs.c @@ -2,8 +2,8 @@ * scst_sysfs.c * * Copyright (C) 2009 Daniel Henrique Debonzi - * Copyright (C) 2009 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2009 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -1263,11 +1263,7 @@ static int scst_parse_add_repl_param(struct scst_acg *acg, *read_only = false; e = scst_get_next_lexem(&pp); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) res = kstrtoul(e, 0, virt_lun); -#else - res = strict_strtoul(e, 0, virt_lun); -#endif if (res != 0) { PRINT_ERROR("Valid LUN required for dev %s (res %d)", dev->virt_name, res); @@ -1309,13 +1305,9 @@ static int scst_parse_add_repl_param(struct scst_acg *acg, goto out; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) res = kstrtoul(pp, 0, &val); -#else - res = strict_strtoul(pp, 0, &val); -#endif if (res != 0) { - PRINT_ERROR("strict_strtoul() for %s failed: %d " + PRINT_ERROR("kstrtoul() for %s failed: %d " "(device %s)", pp, res, dev->virt_name); goto out; } @@ -1999,6 +1991,7 @@ static int __scst_acg_process_cpu_mask_store(struct scst_tgt *tgt, for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct scst_tgt_dev *tgt_dev; struct list_head *head = &sess->sess_tgt_dev_list[i]; + list_for_each_entry_rcu(tgt_dev, head, sess_tgt_dev_list_entry) { int rc; @@ -2194,8 +2187,8 @@ static int scst_process_ini_group_mgmt_store(char *buffer, res = -EINVAL; goto out_unlock; } - acg = scst_alloc_add_acg(tgt, p, true); - if (acg == NULL) + res = scst_alloc_add_acg(tgt, p, true, &acg); + if (res != 0) goto out_unlock; break; case SCST_INI_GROUP_ACTION_DEL: @@ -2810,7 +2803,7 @@ static int scst_tgt_sysfs_##attr##_show_work_fn( \ int res; \ uint64_t c = 0; \ \ - BUILD_BUG_ON((unsigned)(dir) >= ARRAY_SIZE(sess->io_stats)); \ + BUILD_BUG_ON((unsigned int)(dir) >= ARRAY_SIZE(sess->io_stats));\ \ res = mutex_lock_interruptible(&scst_mutex); \ if (res) \ @@ -3054,7 +3047,7 @@ static ssize_t scst_dev_sysfs_type_show(struct kobject *kobj, dev = container_of(kobj, struct scst_device, dev_kobj); pos = scnprintf(buf, SCST_SYSFS_BLOCK_SIZE, "%d - %s\n", dev->type, - (unsigned)dev->type >= ARRAY_SIZE(scst_dev_handler_types) ? + (unsigned int)dev->type >= ARRAY_SIZE(scst_dev_handler_types) ? "unknown" : scst_dev_handler_types[dev->type]); return pos; @@ -5735,7 +5728,7 @@ static ssize_t scst_devt_type_show(struct kobject *kobj, devt = container_of(kobj, struct scst_dev_type, devt_kobj); pos = sprintf(buf, "%d - %s\n", devt->type, - (unsigned)devt->type >= ARRAY_SIZE(scst_dev_handler_types) ? + (unsigned int)devt->type >= ARRAY_SIZE(scst_dev_handler_types) ? "unknown" : scst_dev_handler_types[devt->type]); return pos; @@ -7059,6 +7052,55 @@ static struct kobj_attribute scst_max_tasklet_cmd_attr = __ATTR(max_tasklet_cmd, S_IRUGO | S_IWUSR, scst_max_tasklet_cmd_show, scst_max_tasklet_cmd_store); +static ssize_t scst_suspend_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + int count; + + TRACE_ENTRY(); + + count = sprintf(buf, "%d\n", scst_get_suspend_count()); + + TRACE_EXIT(); + return count; +} + +static ssize_t scst_suspend_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + int res; + long val; + + TRACE_ENTRY(); + + res = kstrtol(buf, 0, &val); + if (res != 0) { + PRINT_ERROR("kstrtoul() for %s failed: %d ", buf, res); + goto out; + } + + if (val >= 0) { + PRINT_INFO("SYSFS: suspending activities (timeout %ld)...", val); + res = scst_suspend_activity(val*HZ); + if (res == 0) + PRINT_INFO("sysfs suspending done"); + } else { + PRINT_INFO("SYSFS: resuming activities"); + scst_resume_activity(); + } + + if (res == 0) + res = count; + +out: + TRACE_EXIT_RES(res); + return res; +} + +static struct kobj_attribute scst_suspend_attr = + __ATTR(suspend, S_IRUGO | S_IWUSR, scst_suspend_show, + scst_suspend_store); + #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) static ssize_t scst_main_trace_level_show(struct kobject *kobj, @@ -7284,6 +7326,7 @@ static struct attribute *scst_sysfs_root_default_attrs[] = { &scst_threads_attr.attr, &scst_setup_id_attr.attr, &scst_max_tasklet_cmd_attr.attr, + &scst_suspend_attr.attr, #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) &scst_main_trace_level_attr.attr, #endif diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index 5988e92fa..9a2cc2f2e 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -1,9 +1,9 @@ /* * scst_targ.c * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -2949,6 +2949,7 @@ static int scst_persistent_reserve_in_local(struct scst_cmd *cmd) goto out_done; } +#ifndef CONFIG_SCST_FORWARD_MODE_PASS_THROUGH if (dev->scsi_dev != NULL) { PRINT_WARNING("PR commands for pass-through devices not " "supported (device %s)", dev->virt_name); @@ -2956,6 +2957,7 @@ static int scst_persistent_reserve_in_local(struct scst_cmd *cmd) SCST_LOAD_SENSE(scst_sense_invalid_opcode)); goto out_done; } +#endif buffer_size = scst_get_buf_full_sense(cmd, &buffer); if (unlikely(buffer_size <= 0)) @@ -5211,6 +5213,7 @@ static void scst_ioctx_get(struct scst_cmd_threads *p_cmd_threads) #warning IO context sharing functionality disabled on 3.5 kernels due to bug in them. \ See "http://lkml.org/lkml/2012/7/17/515" for more details. static int q; + if (q == 0) { q++; PRINT_WARNING("IO context sharing functionality " diff --git a/scst/src/scst_tg.c b/scst/src/scst_tg.c index 4029fcefb..b8cc4456c 100644 --- a/scst/src/scst_tg.c +++ b/scst/src/scst_tg.c @@ -3,7 +3,7 @@ * * SCSI target group related code. * - * Copyright (C) 2011 - 2015 Bart Van Assche . + * Copyright (C) 2011 - 2016 Bart Van Assche . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -283,8 +283,6 @@ static int scst_tg_accept_standby(struct scst_cmd *cmd) TRACE_ENTRY(); switch (cmd->cdb[0]) { - case TEST_UNIT_READY: - case GET_EVENT_STATUS_NOTIFICATION: case INQUIRY: case MODE_SENSE: case MODE_SENSE_10: @@ -348,18 +346,10 @@ static int scst_tg_accept_unav(struct scst_cmd *cmd) TRACE_ENTRY(); switch (cmd->cdb[0]) { - case TEST_UNIT_READY: - case GET_EVENT_STATUS_NOTIFICATION: case INQUIRY: - case MODE_SENSE: - case MODE_SENSE_10: case READ_CAPACITY: case REPORT_LUNS: case REQUEST_SENSE: - case RELEASE: - case RELEASE_10: - case RESERVE: - case RESERVE_10: case READ_BUFFER: case WRITE_BUFFER: res = SCST_ALUA_CHECK_OK; @@ -458,6 +448,13 @@ static int scst_tg_accept_transitioning(struct scst_cmd *cmd) goto out; } break; + case MAINTENANCE_IN: + switch (cmd->cdb[1] & 0x1f) { + case MI_REPORT_TARGET_PGS: + res = SCST_ALUA_CHECK_OK; + goto out; + } + break; } if (cmd->already_transitioning) @@ -965,6 +962,7 @@ static void __scst_tg_set_state(struct scst_target_group *tg, struct scst_tg_tgt *tg_tgt; struct scst_tgt *tgt; enum scst_tg_state old_state = tg->state; + bool dev_changed; sBUG_ON(state >= ARRAY_SIZE(scst_alua_filter)); lockdep_assert_held(&scst_dg_mutex); @@ -976,8 +974,7 @@ static void __scst_tg_set_state(struct scst_target_group *tg, list_for_each_entry(dg_dev, &tg->dg->dev_list, entry) { dev = dg_dev->dev; - if (dev->handler->on_alua_state_change_start != NULL) - dev->handler->on_alua_state_change_start(dev, old_state, state); + dev_changed = false; list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list, dev_tgt_dev_list_entry) { tgt = tgt_dev->sess->tgt; @@ -985,6 +982,11 @@ static void __scst_tg_set_state(struct scst_target_group *tg, if (tg_tgt->tgt == tgt) { bool gen_ua = (state != SCST_TG_STATE_TRANSITIONING); + if ((dev->handler->on_alua_state_change_start != NULL) && !dev_changed) { + dev->handler->on_alua_state_change_start(dev, old_state, state); + dev_changed = true; + } + if ((tg->dg->stpg_rel_tgt_id == tgt_dev->sess->tgt->rel_tgt_id) && tid_equal(tg->dg->stpg_transport_id, tgt_dev->sess->transport_id)) gen_ua = false; @@ -994,7 +996,7 @@ static void __scst_tg_set_state(struct scst_target_group *tg, } } } - if (dev->handler->on_alua_state_change_finish != NULL) + if ((dev->handler->on_alua_state_change_finish != NULL) && dev_changed) dev->handler->on_alua_state_change_finish(dev, old_state, state); } @@ -1443,6 +1445,39 @@ out_unlock: } EXPORT_SYMBOL_GPL(scst_lookup_tg_id); +/** + * scst_get_alua_state() - returns ALUA state the target port group. + * @dev: SCST device. + * @tgt: SCST target. + * + * Returns a valid ALUA state (SCST_TG_STATE_OPTIMIZED is no ALUA configured) + */ +enum scst_tg_state scst_get_alua_state(struct scst_device *dev, struct scst_tgt *tgt) +{ + struct scst_dev_group *dg; + struct scst_target_group *tg; + struct scst_tg_tgt *tg_tgt; + enum scst_tg_state res = SCST_TG_STATE_OPTIMIZED; + + TRACE_ENTRY(); + mutex_lock(&scst_dg_mutex); + dg = __lookup_dg_by_dev(dev); + if (!dg) + goto out_unlock; + tg_tgt = __lookup_dg_tgt(dg, tgt->tgt_name); + if (!tg_tgt) + goto out_unlock; + tg = tg_tgt->tg; + BUG_ON(!tg); + res = tg->state; +out_unlock: + mutex_unlock(&scst_dg_mutex); + + TRACE_EXIT_RES(res); + return res; +} +EXPORT_SYMBOL_GPL(scst_get_alua_state); + /** * scst_alua_configured() - Whether implicit ALUA has been configured. * @dev: Pointer to the SCST device to verify. @@ -1537,10 +1572,12 @@ int scst_tg_get_group_info(void **buf, uint32_t *length, list_for_each_entry(tg, &dg->tg_list, entry) { /* Target port group descriptor header. */ *p++ = (tg->preferred ? SCST_TG_PREFERRED : 0) | tg->state; - *p++ = SCST_TG_SUP_OPTIMIZED - | SCST_TG_SUP_NONOPTIMIZED - | SCST_TG_SUP_STANDBY - | SCST_TG_SUP_UNAVAILABLE; + *p++ = SCST_TG_SUP_OPTIMIZED | + SCST_TG_SUP_NONOPTIMIZED | + SCST_TG_SUP_STANDBY | + SCST_TG_SUP_UNAVAILABLE | + SCST_TG_SUP_OFFLINE | + SCST_TG_SUP_TRANSITION; put_unaligned_be16(tg->group_id, p); p += 2; p++; /* reserved */ diff --git a/scst_local/in-tree/Makefile-4.4 b/scst_local/in-tree/Makefile-4.4 new file mode 100644 index 000000000..8cbbbff63 --- /dev/null +++ b/scst_local/in-tree/Makefile-4.4 @@ -0,0 +1,2 @@ +obj-$(CONFIG_SCST_LOCAL) += scst_local.o + diff --git a/scst_local/scst_local.c b/scst_local/scst_local.c index cf1cd8e31..b545a3951 100644 --- a/scst_local/scst_local.c +++ b/scst_local/scst_local.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2008 - 2010 Richard Sharpe * Copyright (C) 1992 Eric Youngdale - * Copyright (C) 2008 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2008 - 2016 Vladislav Bolkhovitin * * Simulate a host adapter and an SCST target adapter back to back * @@ -51,10 +51,10 @@ #ifndef INSIDE_KERNEL_TREE #if defined(CONFIG_HIGHMEM4G) || defined(CONFIG_HIGHMEM64G) -#warning HIGHMEM kernel configurations are not supported by this module,\ - because nowadays it is not worth the effort. Consider changing\ - VMSPLIT option or use a 64-bit configuration instead. See SCST core\ - README file for details. +#warning HIGHMEM kernel configurations are not supported by this module, \ +because nowadays it is not worth the effort. Consider changing \ +VMSPLIT option or use a 64-bit configuration instead. See SCST core \ +README file for details. #endif #endif @@ -1619,7 +1619,8 @@ static struct scsi_host_template scst_lcl_ini_driver_template = { #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)) .eh_target_reset_handler = scst_local_target_reset, #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) && \ + LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) .use_blk_tags = true, #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33) || \ diff --git a/scstadmin/init.d/scst b/scstadmin/init.d/scst index ba5ce6f19..5e609c26f 100755 --- a/scstadmin/init.d/scst +++ b/scstadmin/init.d/scst @@ -149,6 +149,7 @@ parse_scst_conf() { case "$d" in iscsi) echo iscsi_scst;; qla2x00t) echo qla2x00tgt;; + copy_manager) ;; *) echo "$d";; esac done | sort -u` \ @@ -171,7 +172,9 @@ unload_kmod() { m="$1" t="$2" i=0 - while [ -e "/sys/module/$m/refcnt" ] && ! rmmod "$m" && [ $i -lt "$t" ]; do + while [ -e "/sys/module/$m/refcnt" ] && ! rmmod "$m" 2>/dev/null && + [ $i -lt "$t" ] + do sleep 1 i=$((i+1)) done diff --git a/scstadmin/scstadmin.sysfs/Makefile b/scstadmin/scstadmin.sysfs/Makefile index 3a41eeb89..c728831ec 100644 --- a/scstadmin/scstadmin.sysfs/Makefile +++ b/scstadmin/scstadmin.sysfs/Makefile @@ -2,7 +2,7 @@ ifndef PREFIX PREFIX=/usr/local endif -MODULE_VERSION = 0.9.10 +MODULE_VERSION = 1.0.0 TOOL = scstadmin SBINDIR := $(PREFIX)/sbin @@ -13,18 +13,20 @@ install install_vendor: all $(MAKE) -C scst-$(MODULE_VERSION) $@ DESTDIR=$(DESTDIR) install -d $(DESTDIR)$(SBINDIR) install -m 755 $(TOOL) $(DESTDIR)$(SBINDIR) + regex="s|%INSTALLSITELIB%|$$(make -sC scst-$(MODULE_VERSION) print-INSTALLSITELIB | grep -v ^make)|"; echo "$${regex}"; sed -i "$${regex}" $(DESTDIR)$(SBINDIR)/$(TOOL) uninstall: -rm -f $(DESTDIR)$(SBINDIR)/$(TOOL) $(MAKE) -C scst-$(MODULE_VERSION) uninstall perl-module: - @cd ./scst-$(MODULE_VERSION); \ - perl Makefile.PL PREFIX=$(PREFIX); + @cd ./scst-$(MODULE_VERSION) && \ + perl Makefile.PL PREFIX=$(PREFIX) && \ + printf '\nprint-%%:\n\t@echo '"'"'$$($$*)'"'"'\n' >> Makefile $(MAKE) -C scst-$(MODULE_VERSION) test: - $(MAKE) -C scst-$(MODULE_VERSION) test + $(MAKE) -C scst-$(MODULE_VERSION) test #TEST_VERBOSE=1 clean: -$(MAKE) -C scst-$(MODULE_VERSION) clean diff --git a/scstadmin/scstadmin.sysfs/scst-0.9.10/MANIFEST b/scstadmin/scstadmin.sysfs/scst-1.0.0/MANIFEST similarity index 100% rename from scstadmin/scstadmin.sysfs/scst-0.9.10/MANIFEST rename to scstadmin/scstadmin.sysfs/scst-1.0.0/MANIFEST diff --git a/scstadmin/scstadmin.sysfs/scst-0.9.10/Makefile.PL b/scstadmin/scstadmin.sysfs/scst-1.0.0/Makefile.PL similarity index 100% rename from scstadmin/scstadmin.sysfs/scst-0.9.10/Makefile.PL rename to scstadmin/scstadmin.sysfs/scst-1.0.0/Makefile.PL diff --git a/scstadmin/scstadmin.sysfs/scst-0.9.10/README b/scstadmin/scstadmin.sysfs/scst-1.0.0/README similarity index 100% rename from scstadmin/scstadmin.sysfs/scst-0.9.10/README rename to scstadmin/scstadmin.sysfs/scst-1.0.0/README diff --git a/scstadmin/scstadmin.sysfs/scst-0.9.10/lib/SCST/SCST.pm b/scstadmin/scstadmin.sysfs/scst-1.0.0/lib/SCST/SCST.pm similarity index 99% rename from scstadmin/scstadmin.sysfs/scst-0.9.10/lib/SCST/SCST.pm rename to scstadmin/scstadmin.sysfs/scst-1.0.0/lib/SCST/SCST.pm index 4aa497f98..5fca60f2e 100644 --- a/scstadmin/scstadmin.sysfs/scst-0.9.10/lib/SCST/SCST.pm +++ b/scstadmin/scstadmin.sysfs/scst-1.0.0/lib/SCST/SCST.pm @@ -5,7 +5,7 @@ package SCST::SCST; # Author: Mark R. Buechler # License: GPLv2 # Copyright (c) 2005-2011 Mark R. Buechler -# Copyright (c) 2011 Bart Van Assche . +# Copyright (c) 2011-2015 Bart Van Assche . use 5.005; use Fcntl ':mode'; @@ -289,7 +289,7 @@ use vars qw(@ISA @EXPORT $VERSION); use vars qw($TGT_TYPE_HARDWARE $TGT_TYPE_VIRTUAL); -$VERSION = '0.9.10'; +$VERSION = '1.0.0'; $TGT_TYPE_HARDWARE = 1; $TGT_TYPE_VIRTUAL = 2; @@ -550,8 +550,7 @@ sub drivers { if (opendir($dHandle, $_path)) { foreach my $driver (readdir($dHandle)) { - next if ($driver eq '.' || $driver eq '..' || - $driver eq 'copy_manager'); + next if ($driver eq '.' || $driver eq '..'); if (-d make_path(SCST_TARGETS_DIR(), $driver)) { push @drivers, $driver; @@ -930,7 +929,7 @@ sub driverExists { opendir($dHandle, make_path(SCST_TARGETS_DIR(), $driver)); close $dHandle if ($result); - return $result; + return $result ? TRUE : FALSE; } sub driverDynamicAttributes { @@ -2225,7 +2224,7 @@ sub addLun { my $o_string = ""; foreach my $attribute (keys %{$attributes}) { my $value = $$attributes{$attribute}; - $o_string .= "$attribute=$value; "; + $o_string .= "$attribute=$value;"; } $o_string =~ s/\s$//; @@ -2416,7 +2415,7 @@ sub replaceLun { my $o_string = ""; foreach my $attribute (keys %{$attributes}) { my $value = $$attributes{$attribute}; - $o_string .= "$attribute=$value; "; + $o_string .= "$attribute=$value;"; } $o_string =~ s/\s$//; @@ -3931,7 +3930,11 @@ sub handlerAttributes { } } - next if ($attribute eq SCST_MGMT_IO); + if ($attribute eq SCST_MGMT_IO) { + $attributes{$attribute}->{'static'} = TRUE; + $attributes{$attribute}->{'value'} = $value; + next; + } if (!(($mode & S_IRUSR) >> 6)) { $attributes{$attribute}->{'static'} = FALSE; @@ -4132,7 +4135,7 @@ sub openDevice { my $o_string = ""; foreach my $attribute (keys %{$attributes}) { my $value = $$attributes{$attribute}; - $o_string .= "$attribute=$value; "; + $o_string .= "$attribute=$value;"; } $o_string =~ s/\s$//; diff --git a/scstadmin/scstadmin.sysfs/scst-0.9.10/t/01-start-scst.t b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/01-start-scst.t similarity index 90% rename from scstadmin/scstadmin.sysfs/scst-0.9.10/t/01-start-scst.t rename to scstadmin/scstadmin.sysfs/scst-1.0.0/t/01-start-scst.t index b30abe46a..703756e0f 100644 --- a/scstadmin/scstadmin.sysfs/scst-0.9.10/t/01-start-scst.t +++ b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/01-start-scst.t @@ -9,6 +9,8 @@ BEGIN { if ($> == 0) { ok(system("killall iscsi-scstd >/dev/null 2>&1; " . + "modprobe -r scst_cdrom; " . + "modprobe -r scst_disk; " . "modprobe -r scst_local; " . "modprobe -r isert-scst; " . "modprobe -r iscsi-scst; " . diff --git a/scstadmin/scstadmin.sysfs/scst-0.9.10/t/02-scst-attr.t b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/02-scst-attr.t similarity index 100% rename from scstadmin/scstadmin.sysfs/scst-0.9.10/t/02-scst-attr.t rename to scstadmin/scstadmin.sysfs/scst-1.0.0/t/02-scst-attr.t diff --git a/scstadmin/scstadmin.sysfs/scst-0.9.10/t/03-targets.t b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/03-targets.t similarity index 100% rename from scstadmin/scstadmin.sysfs/scst-0.9.10/t/03-targets.t rename to scstadmin/scstadmin.sysfs/scst-1.0.0/t/03-targets.t diff --git a/scstadmin/scstadmin.sysfs/scst-0.9.10/t/04-alua.t b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/04-alua.t similarity index 100% rename from scstadmin/scstadmin.sysfs/scst-0.9.10/t/04-alua.t rename to scstadmin/scstadmin.sysfs/scst-1.0.0/t/04-alua.t diff --git a/scstadmin/scstadmin.sysfs/scst-0.9.10/t/05-dynattr.t b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/05-dynattr.t similarity index 100% rename from scstadmin/scstadmin.sysfs/scst-0.9.10/t/05-dynattr.t rename to scstadmin/scstadmin.sysfs/scst-1.0.0/t/05-dynattr.t diff --git a/scstadmin/scstadmin.sysfs/scst-0.9.10/t/after-restore.conf b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/06-after-restore.conf similarity index 100% rename from scstadmin/scstadmin.sysfs/scst-0.9.10/t/after-restore.conf rename to scstadmin/scstadmin.sysfs/scst-1.0.0/t/06-after-restore.conf index f0c5264f2..8f5291be5 100644 --- a/scstadmin/scstadmin.sysfs/scst-0.9.10/t/after-restore.conf +++ b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/06-after-restore.conf @@ -14,6 +14,11 @@ TARGET_DRIVER scst_local { LUN 0 disk01 LUN 1 disk01 + GROUP group_without_luns_with_attrs { + + addr_method FLAT + } + GROUP initiator_group { LUN 0 disk01 LUN 1 disk01 { @@ -27,11 +32,6 @@ TARGET_DRIVER scst_local { INITIATOR ini3 } - - GROUP group_without_luns_with_attrs { - - addr_method FLAT - } } } diff --git a/scstadmin/scstadmin.sysfs/scst-0.9.10/t/06-cont-on-err.t b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/06-cont-on-err.t similarity index 88% rename from scstadmin/scstadmin.sysfs/scst-0.9.10/t/06-cont-on-err.t rename to scstadmin/scstadmin.sysfs/scst-1.0.0/t/06-cont-on-err.t index 883f020f3..c91b85c7e 100644 --- a/scstadmin/scstadmin.sysfs/scst-0.9.10/t/06-cont-on-err.t +++ b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/06-cont-on-err.t @@ -41,13 +41,15 @@ sub testRestoreConfig { "scstadmin-test-06-$$-1"); my $tmpfilename2 = File::Spec->catfile(File::Spec->tmpdir(), "scstadmin-test-06-$$-2"); + my $diff = File::Spec->catfile(File::Spec->tmpdir(), + "scstadmin-test-06-$$-diff"); system("$scstadmin -clear_config -force -noprompt -no_lip >/dev/null"); system("$scstadmin -cont_on_err -no_lip -config $to_be_restored" . " >/dev/null"); system("$scstadmin -write_config $tmpfilename1 >/dev/null"); system("awk 'BEGIN {t = 0 } /^# Automatically generated by SCST Configurator v/ { \$0 = \"# Automatically generated by SCST Configurator v...\" } /^TARGET_DRIVER.*{\$/ { if (\$0 != \"TARGET_DRIVER scst_local {\") t = 1 } /^}\$/ { if (t == 1) t = 2 } /^\$/ { if (t == 2) { t = 3 } } /^./ { if (t == 3) { t = 0 } } { if (t == 0) print }' <$tmpfilename1 >$tmpfilename2"); - my $compare_result = system("diff -u $tmpfilename2 $expected"); + my $compare_result = system("diff -u $tmpfilename2 $expected >$diff"); ok($compare_result, 0); if ($compare_result == 0) { unlink($tmpfilename2); @@ -62,6 +64,6 @@ die("Creation of SCST object failed") if (!defined($SCST)); setup($SCST); -testRestoreConfig(File::Spec->catfile($testdir, "to-be-restored.conf"), - File::Spec->catfile($testdir, "after-restore.conf")); +testRestoreConfig(File::Spec->catfile($testdir, "06-to-be-restored.conf"), + File::Spec->catfile($testdir, "06-after-restore.conf")); diff --git a/scstadmin/scstadmin.sysfs/scst-0.9.10/t/to-be-restored.conf b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/06-to-be-restored.conf similarity index 100% rename from scstadmin/scstadmin.sysfs/scst-0.9.10/t/to-be-restored.conf rename to scstadmin/scstadmin.sysfs/scst-1.0.0/t/06-to-be-restored.conf diff --git a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/07-result.conf b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/07-result.conf new file mode 100644 index 000000000..8bee55a95 --- /dev/null +++ b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/07-result.conf @@ -0,0 +1,38 @@ +# Automatically generated by SCST Configurator v... + + +HANDLER vdisk_fileio { + DEVICE disk0 { + filename /dev/scstadmin-regression-test-vdisk + read_only 1 + } + + DEVICE disk1 { + filename /dev/scstadmin-regression-test-vdisk + nv_cache 1 + } +} + +HANDLER vdisk_nullio { + DEVICE nodev { + dummy 1 + } +} + +TARGET_DRIVER scst_local { + TARGET local { + LUN 0 nodev + + GROUP ig { + LUN 0 disk0 { + read_only 1 + } + LUN 1 disk1 + + INITIATOR ini1 + + INITIATOR ini2 + } + } +} + diff --git a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/07-scstadmin-args.t b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/07-scstadmin-args.t new file mode 100644 index 000000000..58e149049 --- /dev/null +++ b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/07-scstadmin-args.t @@ -0,0 +1,96 @@ +#!perl + +use strict; +use Cwd qw(abs_path); +use File::Basename; +use File::Spec; +use Test; + +my $testdir; +my $scstadmin; +my $redirect_file; +my $redirect; + +BEGIN { + $redirect_file = "/tmp/07-output.txt"; + unlink($redirect_file); + $testdir = dirname(abs_path($0)); + my $scstadmin_pm_dir = dirname($testdir); + my $scstadmin_dir = dirname($scstadmin_pm_dir); + $scstadmin = File::Spec->catfile($scstadmin_dir, "scstadmin"); + unless(grep /blib/, @INC) { + unshift(@INC, File::Spec->catdir($scstadmin_pm_dir, "lib")); + } + plan tests => 2; +} + +use Data::Dumper; +use SCST::SCST; +use File::Temp qw/tempfile/; + +sub setup { + my $SCST = shift; + + my ($drivers, $errorString) = $SCST->drivers(); + my %drivers = map { $_ => 1 } @{$drivers}; + ok(exists($drivers{'scst_local'})); + system("dd if=/dev/zero of=/dev/scstadmin-regression-test-vdisk bs=1M count=1 >/dev/null 2>&1"); +} + +sub teardown { + system("rm -f /dev/scstadmin-regression-test-vdisk"); +} + +sub attributeTest { + my $expected = shift; + my $tmpfilename1 = File::Spec->catfile(File::Spec->tmpdir(), + "scstadmin-test-07-$$-1"); + my $tmpfilename2 = File::Spec->catfile(File::Spec->tmpdir(), + "scstadmin-test-07-$$-2"); + my $diff = File::Spec->catfile(File::Spec->tmpdir(), + "scstadmin-test-07-$$-diff"); + + system("$scstadmin -clear_config -force -noprompt -no_lip $redirect"); + system("$scstadmin -open_dev nodev -handler vdisk_nullio -attributes dummy=1 $redirect"); + system("$scstadmin -open_dev disk0 -handler vdisk_fileio -attributes filename=/dev/scstadmin-regression-test-vdisk,read_only=1 $redirect"); + system("$scstadmin -open_dev disk1 -handler vdisk_fileio -attributes filename=/dev/scstadmin-regression-test-vdisk,nv_cache=1 $redirect"); + system("$scstadmin -driver scst_local -add_target local $redirect"); + system("$scstadmin -driver scst_local -target local " . + "-add_lun 0 -device nodev $redirect"); + system("$scstadmin -driver scst_local -target local -add_group ig " . + "$redirect"); + system("$scstadmin -driver scst_local -target local -group ig " . + "-add_init ini1 $redirect"); + system("$scstadmin -driver scst_local -target local -group ig " . + "-add_init ini2 $redirect"); + system("$scstadmin -driver scst_local -target local -group ig " . + "-add_lun 0 -device disk0 $redirect"); + system("$scstadmin -driver scst_local -target local -group ig " . + "-add_lun 1 -device disk1 $redirect"); + system("$scstadmin -write_config $tmpfilename1 >/dev/null"); + system("awk 'BEGIN { t = 0 } /^# Automatically generated by SCST Configurator v/ { \$0 = \"# Automatically generated by SCST Configurator v...\" } /^TARGET_DRIVER.*{\$/ { if (\$0 != \"TARGET_DRIVER scst_local {\") t = 1 } /^}\$/ { if (t == 1) t = 2 } /^\$/ { if (t == 2) { t = 3 } } /^./ { if (t == 3) { t = 0 } } { if (t == 0) print }' <$tmpfilename1 >$tmpfilename2"); + my $compare_result = system("diff -u $tmpfilename2 $expected >$diff"); + ok($compare_result, 0); + if ($compare_result == 0) { + unlink($tmpfilename2); + unlink($tmpfilename1); + } +} + +my $_DEBUG_ = 0; +if ($_DEBUG_) { + $redirect = ">>$redirect_file"; + open(my $logfile, '>>', $redirect_file); + select $logfile; +} else { + $redirect = ">/dev/null"; +} + +my $SCST = eval { new SCST::SCST($_DEBUG_) }; +die("Creation of SCST object failed") if (!defined($SCST)); + +setup($SCST); + +attributeTest(File::Spec->catfile($testdir, "07-result.conf")); + +teardown(); diff --git a/scstadmin/scstadmin.sysfs/scst-0.9.10/t/99-stop-scst.t b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/99-stop-scst.t similarity index 100% rename from scstadmin/scstadmin.sysfs/scst-0.9.10/t/99-stop-scst.t rename to scstadmin/scstadmin.sysfs/scst-1.0.0/t/99-stop-scst.t diff --git a/scstadmin/scstadmin.sysfs/scstadmin b/scstadmin/scstadmin.sysfs/scstadmin index 60d609717..b6bac0e8d 100755 --- a/scstadmin/scstadmin.sysfs/scstadmin +++ b/scstadmin/scstadmin.sysfs/scstadmin @@ -7,7 +7,7 @@ $Version = 'SCST Configurator v3.1.0-pre1'; # Author: Mark R. Buechler # License: GPLv2 # Copyright (c) 2005-2011 Mark R. Buechler -# Copyright (C) 2011 Bart Van Assche +# Copyright (C) 2011-2015 Bart Van Assche sub usage { @@ -204,8 +204,10 @@ Target Driver Operations -issue_lip [] [-driver ] : Issue a LIP for a specific driver/target or for all drivers and targets. - -no_lip : Don\'t automatically issue a LIP after applying + -lip : Issue a LIP after having applied FC configuration changes. + -no_lip : Don\'t automatically issue a LIP after having + applied FC configuration changes. Options -nonkey : When writing a config file or listing attributes, @@ -240,12 +242,27 @@ Examples: EndUsage } -use SCST::SCST 0.9.10; +use strict; +use Cwd qw(abs_path); +use File::Basename; +use File::Spec; +use Test; + +BEGIN { + my $site_lib = '%INSTALLSITELIB%'; + if ($site_lib =~ '^%') { + my $scstadmindir = dirname(abs_path($0)); + $site_lib = File::Spec->catdir($scstadmindir, "scst-1.0.0", + "blib", "lib"); + } + unshift(@INC, $site_lib); +} + +use SCST::SCST 1.0.0; use Getopt::Long; use IO::File; use IO::Dir; use POSIX; -use strict; my $_DEF_CONFIG_ = '/etc/scst.conf'; @@ -349,6 +366,7 @@ sub getArgs { my $enableTarget; my $disableTarget; my $issueLip; + my $lip; my $noLip; my $handler; @@ -444,6 +462,7 @@ sub getArgs { 'enable_target=s' => \$enableTarget, 'disable_target=s' => \$disableTarget, 'issue_lip:s' => \$issueLip, + 'lip' => \$lip, 'no_lip' => \$noLip, 'handler=s' => \$handler, @@ -478,9 +497,10 @@ sub getArgs { $_NOPROMPT_ = TRUE if (defined($_NOPROMPT_)); $_CONT_ON_ERR_ = TRUE if (defined($_CONT_ON_ERR_)); - $force = TRUE if (defined($force)); + $force = TRUE if (defined($force)); $nonkey = TRUE if (defined($nonkey)); - $noLip = TRUE if (defined($noLip)); + $lip = TRUE if (defined($lip)); + $noLip = TRUE if (defined($noLip)); my $query_mode = defined($listHandler) || defined($listDevice) || defined($listDeviceGroup) || defined($listTargetGroup) || defined($listDriver) || defined($listTarget) || defined($listGroup) || defined($listSessions) || @@ -707,25 +727,104 @@ sub getArgs { } } - return ($applyConfig, $clearConfig, $writeConfig, $checkConfig, - $listScstAttr, $listHandler, $listDevice, $listDeviceGroup, $listTargetGroup, $listDriver, $listTarget, $listGroup, - $listSessions, $listHandlerAttr, $listDeviceAttr, $listDriverAttr, $listTargetAttr, - $listDeviceGroupAttr, $listTargetGroupAttr, $listTargetGroupTargetAttr, - $listGroupAttr, $listLunAttr, $listInitiatorAttr, $setScstAttr, $setHandlerAttr, - $setDeviceAttr, $setDriverAttr, $setTargetAttr, $setGroupAttr, $setLunAttr, $setInitiatorAttr, - $setDeviceGroupAttr, $setTargetGroupAttr, $setTargetGroupTargetAttr, - $addDriverAttr, $addTargetAttr, $remDriverAttr, $remTargetAttr, - $openDev, $closeDev, $resyncDev, - $addDevGroup, $removeDevGroup, $addDevGroupDevice, $removeDevGroupDevice, - $addTargetGroup, $removeTargetGroup, $addTargetGroupTarget, $removeTargetGroupTarget, - $addTarget, $removeTarget, - $addGroup, $removeGroup, - $addInitiator, $removeInitiator, $moveInitiator, $clearInitiators, - $addLun, $removeLun, $replaceLun, $clearLuns, - $enableTarget, $disableTarget, $issueLip, $noLip, - $handler, \%_attributes, - $driver, $target, $group, $to, $device,, $deviceGroup, $targetGroup, - $nonkey, $force); + my %args = ( + applyConfig => $applyConfig, + clearConfig => $clearConfig, + writeConfig => $writeConfig, + checkConfig => $checkConfig, + + listScstAttr => $listScstAttr, + listHandler => $listHandler, + listDevice => $listDevice, + listDeviceGroup => $listDeviceGroup, + listTargetGroup => $listTargetGroup, + listDriver => $listDriver, + listTarget => $listTarget, + listGroup => $listGroup, + + listSessions => $listSessions, + listHandlerAttr => $listHandlerAttr, + listDeviceAttr => $listDeviceAttr, + listDriverAttr => $listDriverAttr, + listTargetAttr => $listTargetAttr, + + listDeviceGroupAttr => $listDeviceGroupAttr, + listTargetGroupAttr => $listTargetGroupAttr, + listTargetGroupTargetAttr => $listTargetGroupTargetAttr, + + listGroupAttr => $listGroupAttr, + listLunAttr => $listLunAttr, + listInitiatorAttr => $listInitiatorAttr, + setScstAttr => $setScstAttr, + setHandlerAttr => $setHandlerAttr, + + setDeviceAttr => $setDeviceAttr, + setDriverAttr => $setDriverAttr, + setTargetAttr => $setTargetAttr, + setGroupAttr => $setGroupAttr, + setLunAttr => $setLunAttr, + setInitiatorAttr => $setInitiatorAttr, + + setDeviceGroupAttr => $setDeviceGroupAttr, + setTargetGroupAttr => $setTargetGroupAttr, + setTargetGroupTargetAttr => $setTargetGroupTargetAttr, + + addDriverAttr => $addDriverAttr, + addTargetAttr => $addTargetAttr, + remDriverAttr => $remDriverAttr, + remTargetAttr => $remTargetAttr, + + openDev => $openDev, + closeDev => $closeDev, + resyncDev => $resyncDev, + + addDevGroup => $addDevGroup, + removeDevGroup => $removeDevGroup, + addDevGroupDevice => $addDevGroupDevice, + removeDevGroupDevice => $removeDevGroupDevice, + + addTargetGroup => $addTargetGroup, + removeTargetGroup => $removeTargetGroup, + addTargetGroupTarget => $addTargetGroupTarget, + removeTargetGroupTarget => $removeTargetGroupTarget, + + addTarget => $addTarget, + removeTarget => $removeTarget, + + addGroup => $addGroup, + removeGroup => $removeGroup, + + addInitiator => $addInitiator, + removeInitiator => $removeInitiator, + moveInitiator => $moveInitiator, + clearInitiators => $clearInitiators, + + addLun => $addLun, + removeLun => $removeLun, + replaceLun => $replaceLun, + clearLuns => $clearLuns, + + enableTarget => $enableTarget, + disableTarget => $disableTarget, + issueLip => $issueLip, + lip => $lip, + noLip => $noLip, + + handler => $handler, + attributes => \%_attributes, + + driver => $driver, + target => $target, + group => $group, + to => $to, + device => $device, + deviceGroup => $deviceGroup, + targetGroup => $targetGroup, + + nonkey => $nonkey, + force => $force, + ); + return \%args; } sub main { @@ -736,25 +835,103 @@ sub main { # We need to run as root if ( $> ) {die("This program must run as root.\n");} - my ($applyConfig, $clearConfig, $writeConfig, $checkConfig, - $listScstAttr, $listHandler, $listDevice, $listDeviceGroup, $listTargetGroup, $listDriver, $listTarget, $listGroup, - $listSessions, $listHandlerAttr, $listDeviceAttr, $listDriverAttr, $listTargetAttr, - $listDeviceGroupAttr, $listTargetGroupAttr, $listTargetGroupTargetAttr, - $listGroupAttr, $listLunAttr, $listInitiatorAttr, $setScstAttr, $setHandlerAttr, - $setDeviceAttr, $setDriverAttr, $setTargetAttr, $setGroupAttr, $setLunAttr, $setInitiatorAttr, - $setDeviceGroupAttr, $setTargetGroupAttr, $setTargetGroupTargetAttr, - $addDriverAttr, $addTargetAttr, $remDriverAttr, $remTargetAttr, - $openDev, $closeDev, $resyncDev, - $addDevGroup, $removeDevGroup, $addDevGroupDevice, $removeDevGroupDevice, - $addTargetGroup, $removeTargetGroup, $addTargetGroupTarget, $removeTargetGroupTarget, - $addTarget, $removeTarget, - $addGroup, $removeGroup, - $addInitiator, $removeInitiator, $moveInitiator, $clearInitiators, - $addLun, $removeLun, $replaceLun, $clearLuns, - $enableTarget, $disableTarget, $issueLip, $noLip, - $handler, $attributes, - $driver, $target, $group, $to, $device, $deviceGroup, $targetGroup, - $nonkey, $force) = getArgs(); + my $args = getArgs(); + + my $applyConfig = $args->{applyConfig}; + my $clearConfig = $args->{clearConfig}; + my $writeConfig = $args->{writeConfig}; + my $checkConfig = $args->{checkConfig}; + + my $listScstAttr = $args->{listScstAttr}; + my $listHandler = $args->{listHandler}; + my $listDevice = $args->{listDevice}; + my $listDeviceGroup = $args->{listDeviceGroup}; + my $listTargetGroup = $args->{listTargetGroup}; + my $listDriver = $args->{listDriver}; + my $listTarget = $args->{listTarget}; + my $listGroup = $args->{listGroup}; + + my $listSessions = $args->{listSessions}; + my $listHandlerAttr = $args->{listHandlerAttr}; + my $listDeviceAttr = $args->{listDeviceAttr}; + my $listDriverAttr = $args->{listDriverAttr}; + my $listTargetAttr = $args->{listTargetAttr}; + + my $listDeviceGroupAttr = $args->{listDeviceGroupAttr}; + my $listTargetGroupAttr = $args->{listTargetGroupAttr}; + my $listTargetGroupTargetAttr = $args->{listTargetGroupTargetAttr}; + + my $listGroupAttr = $args->{listGroupAttr}; + my $listLunAttr = $args->{listLunAttr}; + my $listInitiatorAttr = $args->{listInitiatorAttr}; + my $setScstAttr = $args->{setScstAttr}; + my $setHandlerAttr = $args->{setHandlerAttr}; + + my $setDeviceAttr = $args->{setDeviceAttr}; + my $setDriverAttr = $args->{setDriverAttr}; + my $setTargetAttr = $args->{setTargetAttr}; + my $setGroupAttr = $args->{setGroupAttr}; + my $setLunAttr = $args->{setLunAttr}; + my $setInitiatorAttr = $args->{setInitiatorAttr}; + + my $setDeviceGroupAttr = $args->{setDeviceGroupAttr}; + my $setTargetGroupAttr = $args->{setTargetGroupAttr}; + my $setTargetGroupTargetAttr = $args->{setTargetGroupTargetAttr}; + + my $addDriverAttr = $args->{addDriverAttr}; + my $addTargetAttr = $args->{addTargetAttr}; + my $remDriverAttr = $args->{remDriverAttr}; + my $remTargetAttr = $args->{remTargetAttr}; + + my $openDev = $args->{openDev}; + my $closeDev = $args->{closeDev}; + my $resyncDev = $args->{resyncDev}; + + my $addDevGroup = $args->{addDevGroup}; + my $removeDevGroup = $args->{removeDevGroup}; + my $addDevGroupDevice = $args->{addDevGroupDevice}; + my $removeDevGroupDevice = $args->{removeDevGroupDevice}; + + my $addTargetGroup = $args->{addTargetGroup}; + my $removeTargetGroup = $args->{removeTargetGroup}; + my $addTargetGroupTarget = $args->{addTargetGroupTarget}; + my $removeTargetGroupTarget = $args->{removeTargetGroupTarget}; + + my $addTarget = $args->{addTarget}; + my $removeTarget = $args->{removeTarget}; + + my $addGroup = $args->{addGroup}; + my $removeGroup = $args->{removeGroup}; + + my $addInitiator = $args->{addInitiator}; + my $removeInitiator = $args->{removeInitiator}; + my $moveInitiator = $args->{moveInitiator}; + my $clearInitiators = $args->{clearInitiators}; + + my $addLun = $args->{addLun}; + my $removeLun = $args->{removeLun}; + my $replaceLun = $args->{replaceLun}; + my $clearLuns = $args->{clearLuns}; + + my $enableTarget = $args->{enableTarget}; + my $disableTarget = $args->{disableTarget}; + my $issueLip = $args->{issueLip}; + my $lip = $args->{lip}; + my $noLip = $args->{noLip}; + + my $handler = $args->{handler}; + my $attributes = $args->{attributes}; + + my $driver = $args->{driver}; + my $target = $args->{target}; + my $group = $args->{group}; + my $to = $args->{to}; + my $device = $args->{device}; + my $deviceGroup = $args->{deviceGroup}; + my $targetGroup = $args->{targetGroup}; + + my $nonkey = $args->{nonkey}; + my $force = $args->{force}; $SCST = new SCST::SCST($_DEBUG_); @@ -770,7 +947,7 @@ sub main { condExit("Configuration has errors, aborting.") if ($rc); last if ($force && prompt()); my $changes = applyConfiguration($force); - $rc = issueLip() if ($changes && !$noLip); + $rc = issueLip() if ($changes && $lip); last SWITCH; }; defined($checkConfig) && do { @@ -786,7 +963,7 @@ sub main { defined($clearConfig) && do { last if (prompt()); $rc = clearConfiguration(); - $rc = issueLip() if (!$rc && !$noLip); + $rc = issueLip() if (!$rc && $lip); last SWITCH; }; defined($listHandler) && do { @@ -945,14 +1122,14 @@ sub main { defined($addDriverAttr) && do { print "\n-> Making requested changes.\n"; $rc = addDriverDynamicAttributes($addDriverAttr, $attributes); - $rc = issueLip() if (!$rc && !$noLip); + $rc = issueLip() if (!$rc && $lip); print "\t-> Done.\n"; last SWITCH; }; defined($addTargetAttr) && do { print "\n-> Making requested changes.\n"; $rc = addTargetDynamicAttributes($driver, $addTargetAttr, $attributes); - $rc = issueLip() if (!$rc && !$noLip); + $rc = issueLip() if (!$rc && $lip); print "\t-> Done.\n"; last SWITCH; }; @@ -960,7 +1137,7 @@ sub main { last if (prompt()); print "\n-> Making requested changes.\n"; $rc = removeDriverDynamicAttributes($remDriverAttr, $attributes); - $rc = issueLip() if (!$rc && !$noLip); + $rc = issueLip() if (!$rc && $lip); print "\t-> Done.\n"; last SWITCH; }; @@ -968,7 +1145,7 @@ sub main { last if (prompt()); print "\n-> Making requested changes.\n"; $rc = removeTargetDynamicAttributes($driver, $remTargetAttr, $attributes); - $rc = issueLip() if (!$rc && !$noLip); + $rc = issueLip() if (!$rc && $lip); print "\t-> Done.\n"; last SWITCH; }; @@ -982,14 +1159,14 @@ sub main { last if (prompt()); print "\n-> Making requested changes.\n"; $rc = closeDevice($handler, $closeDev, $force); - $rc = issueLip() if (!$rc && !$noLip); + $rc = issueLip() if (!$rc && $lip); print "\t-> Done.\n"; last SWITCH; }; defined($resyncDev) && do { print "\n-> Making requested changes.\n"; $rc = resyncDevice($resyncDev); - $rc = issueLip() if (!$rc && !$noLip); + $rc = issueLip() if (!$rc && $lip); print "\t-> Done.\n"; last SWITCH; }; @@ -1051,7 +1228,7 @@ sub main { last if (prompt()); print "\n-> Making requested changes.\n"; $rc = removeVirtualTarget($driver, $removeTarget); - $rc = issueLip($driver) if (!$rc); + $rc = issueLip($driver) if (!$rc && $lip); print "\t-> Done.\n"; last SWITCH; }; @@ -1071,7 +1248,7 @@ sub main { defined($addInitiator) && do { print "\n-> Making requested changes.\n"; $rc = addInitiator($driver, $target, $group, $addInitiator); - $rc = issueLip($driver, $target) if (!$rc); + $rc = issueLip($driver, $target) if (!$rc && $lip); print "\t-> Done.\n"; last SWITCH; }; @@ -1079,7 +1256,7 @@ sub main { last if (prompt()); print "\n-> Making requested changes.\n"; $rc = removeInitiator($driver, $target, $group, $removeInitiator); - $rc = issueLip($driver, $target) if (!$rc); + $rc = issueLip($driver, $target) if (!$rc && $lip); print "\t-> Done.\n"; last SWITCH; }; @@ -1087,7 +1264,7 @@ sub main { last if (prompt()); print "\n-> Making requested changes.\n"; $rc = moveInitiator($driver, $target, $group, $moveInitiator, $to); - $rc = issueLip($driver, $target) if (!$rc); + $rc = issueLip($driver, $target) if (!$rc && $lip); print "\t-> Done.\n"; last SWITCH; }; @@ -1095,14 +1272,14 @@ sub main { last if (prompt()); print "\n-> Making requested changes.\n"; $rc = clearInitiators($driver, $target, $group); - $rc = issueLip($driver, $target) if (!$rc); + $rc = issueLip($driver, $target) if (!$rc && $lip); print "\t-> Done.\n"; last SWITCH; }; defined($addLun) && do { print "\n-> Making requested changes.\n"; $rc = addLun($driver, $target, $device, $addLun, $attributes, $group); - $rc = issueLip($driver, $target) if (!$rc); + $rc = issueLip($driver, $target) if (!$rc && $lip); print "\t-> Done.\n"; last SWITCH; }; @@ -1110,7 +1287,7 @@ sub main { last if (prompt()); print "\n-> Making requested changes.\n"; $rc = removeLun($driver, $target, $removeLun, $group); - $rc = issueLip($driver, $target) if (!$rc); + $rc = issueLip($driver, $target) if (!$rc && $lip); print "\t-> Done.\n"; last SWITCH; }; @@ -1118,7 +1295,7 @@ sub main { last if (prompt()); print "\n-> Making requested changes.\n"; $rc = replaceLun($driver, $target, $group, $replaceLun, $device, $attributes); - $rc = issueLip($driver, $target) if (!$rc); + $rc = issueLip($driver, $target) if (!$rc && $lip); print "\t-> Done.\n"; last SWITCH; }; @@ -1126,7 +1303,7 @@ sub main { last if (prompt()); print "\n-> Making requested changes.\n"; $rc = clearLuns($driver, $target, $group); - $rc = issueLip($driver, $target) if (!$rc); + $rc = issueLip($driver, $target) if (!$rc && $lip); print "\t-> Done.\n"; last SWITCH; }; @@ -1145,7 +1322,7 @@ sub main { }; defined($issueLip) && do { print "\n-> Making requested changes.\n"; - $rc = issueLip($driver, $issueLip, TRUE); + $rc = issueLip($driver, $issueLip, TRUE) if (!$noLip); print "\t-> Done.\n"; last SWITCH; }; @@ -1334,6 +1511,25 @@ sub serializeNkAttr { return $result; } +# Return TRUE if and only if $1 is an SCST pass-through device. +sub isPassthroughDev { + my $dev = shift; + my $pt = FALSE; + + foreach my $handler (keys %{$CURRENT{'handler'}}) { + my ($ha, $errorString) = $SCST->handlerAttributes($handler); + next if ($ha->{'mgmt'} !~ 'echo "add_device H:C:I:L"'); + my @devs = @{$CURRENT{'handler'}->{$handler}}; + for my $i (0 .. $#devs) { + if ($dev eq @devs[$i]) { + $pt = TRUE; + last; + } + } + last if $pt; + } +} + # Returns 0 upon success and 1 upon error. sub writeConfiguration { my $nonkey = shift; @@ -1464,6 +1660,12 @@ sub writeConfiguration { foreach my $lun (sort numerically keys %{$luns}) { my $lun_dev = $$luns{$lun}; + # Do not save copy_manager LUN definitions + # for LUNs associated with an SCST device + # handler. + next if ($driver eq 'copy_manager' && + isPassthroughDev($lun_dev)); + $t_lun_buff .= "\t\tLUN $lun $lun_dev"; my ($attributes, $errorString) = $SCST->lunAttributes($driver, $target, $lun); @@ -1892,7 +2094,7 @@ sub checkConfiguration { } } - if (!defined($$tgt{'LUN'}->{'0'})) { + if ($driver ne 'copy_manager' && !defined($$tgt{'LUN'}->{'0'})) { print "\t-> WARNING: No LUN 0 defined for driver/target '$driver/$target'. ". "Many initiators require a LUN 0 to be defined.\n\n"; $warnings++; @@ -2104,7 +2306,7 @@ sub applyConfigAssignments { if ($deletions) { removeLun($driver, $target, $lun); $changes++; - } else { + } elsif ($driver ne 'copy_manager') { print "\t-> Device '$device' at LUN '$lun' is not in configuration ". "for driver/target '$driver/$target'. ". "Use -force to remove it.\n"; @@ -4880,6 +5082,12 @@ sub addLun { my $attributes = shift; my $group = shift; + # Do not complain about existing copy manager LUNs. + if ($driver eq 'copy_manager' && + $SCST->lunExists($driver, $target, $lun, $group)) { + return FALSE; + } + if (defined($group)) { print "\t-> Adding device '$device' at LUN $lun to driver/target/group ". "'$driver/$target/$group': "; diff --git a/srpt/Makefile b/srpt/Makefile index 370b308b2..e224c4be4 100644 --- a/srpt/Makefile +++ b/srpt/Makefile @@ -139,8 +139,8 @@ src/$(MODULE_SYMVERS): $(SCST_SYMVERS_DIR)/$(MODULE_SYMVERS) \ clean: rm -rf conftest/pre_cflags conftest/kcflags - for d in conftest/* src; do \ - $(MAKE) -C $(KDIR) SUBDIRS=$(shell pwd)/$$d clean; \ + for d in conftest/* src; do \ + [ -d "$$d" ] && $(MAKE) -C $(KDIR) SUBDIRS=$(shell pwd)/$$d clean; \ done rm -f src/$(MODULE_SYMVERS) src/Module.markers src/modules.order diff --git a/srpt/conftest/register_mad_agent/register_mad_agent.c b/srpt/conftest/register_mad_agent/register_mad_agent.c index fe0421c2b..c464f1443 100644 --- a/srpt/conftest/register_mad_agent/register_mad_agent.c +++ b/srpt/conftest/register_mad_agent/register_mad_agent.c @@ -7,7 +7,7 @@ static int modinit(void) a = ib_register_mad_agent(NULL, 0, 0, NULL, 0, NULL, NULL, NULL, 0); - return a!= 0; + return a != 0; } module_init(modinit); diff --git a/srpt/src/ib_srpt.c b/srpt/src/ib_srpt.c index 8a8e09389..f4f0f698a 100644 --- a/srpt/src/ib_srpt.c +++ b/srpt/src/ib_srpt.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2006 - 2009 Mellanox Technology Inc. All rights reserved. - * Copyright (C) 2008 - 2015 Bart Van Assche . + * Copyright (C) 2008 - 2016 Bart Van Assche . * Copyright (C) 2008 Vladislav Bolkhovitin * * This software is available to you under a choice of one of two @@ -593,6 +593,9 @@ static void srpt_mad_send_handler(struct ib_mad_agent *mad_agent, * srpt_mad_recv_handler() - MAD reception callback function. */ static void srpt_mad_recv_handler(struct ib_mad_agent *mad_agent, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) + struct ib_mad_send_buf *send_buf, +#endif struct ib_mad_recv_wc *mad_wc) { struct srpt_port *sport = (struct srpt_port *)mad_agent->context; @@ -694,7 +697,8 @@ static int srpt_refresh_port(struct srpt_port *sport) sport->lid = port_attr.lid; ret = ib_query_gid(sport->sdev->device, sport->port, 0, &sport->gid -#ifdef IB_QUERY_GID_HAS_ATTR_ARG +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) || \ + defined(IB_QUERY_GID_HAS_ATTR_ARG) , NULL #endif ); @@ -2068,13 +2072,18 @@ static int srpt_poll(struct srpt_rdma_ch *ch, int budget) return processed; } -static int srpt_process_completion(struct srpt_rdma_ch *ch, int budget) +static int srpt_process_completion(struct srpt_rdma_ch *ch, int budget, + bool thread_context) { struct ib_cq *const cq = ch->cq; int processed = 0, n = budget; do { + if (thread_context) + set_current_state(TASK_RUNNING); processed += srpt_poll(ch, n); + if (thread_context) + set_current_state(TASK_INTERRUPTIBLE); n = ib_req_notify_cq(cq, IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS); } while (n > 0); @@ -2098,7 +2107,7 @@ static void srpt_free_ch(struct kref *kref) srpt_destroy_ch_ib(ch); - kfree(ch); + kfree_rcu(ch, rcu); } static void srpt_unreg_ch(struct srpt_rdma_ch *ch) @@ -2127,7 +2136,7 @@ static void srpt_unreg_ch(struct srpt_rdma_ch *ch) * after list_del() and before wake_up() has been invoked. */ mutex_lock(&sport->mutex); - list_del(&ch->list); + list_del_rcu(&ch->list); wake_up(&sport->ch_releaseQ); mutex_unlock(&sport->mutex); @@ -2143,6 +2152,7 @@ static int srpt_compl_thread(void *arg) { enum { poll_budget = 65536 }; struct srpt_rdma_ch *ch; + int n; /* Hibernation / freezing of the SRPT kernel thread is not supported. */ current->flags |= PF_NOFREEZE; @@ -2151,8 +2161,10 @@ static int srpt_compl_thread(void *arg) BUG_ON(!ch); while (ch->state < CH_LIVE) { - set_current_state(TASK_INTERRUPTIBLE); - if (srpt_process_completion(ch, poll_budget) >= poll_budget) + n = srpt_process_completion(ch, poll_budget, true); + if (ch->state >= CH_LIVE) + break; + if (n >= poll_budget) cond_resched(); else schedule(); @@ -2161,20 +2173,26 @@ static int srpt_compl_thread(void *arg) srpt_process_wait_list(ch); while (ch->state < CH_DISCONNECTED) { - set_current_state(TASK_INTERRUPTIBLE); - if (srpt_process_completion(ch, poll_budget) >= poll_budget) + n = srpt_process_completion(ch, poll_budget, true); + if (ch->state >= CH_DISCONNECTED) + break; + if (n >= poll_budget) cond_resched(); else schedule(); } set_current_state(TASK_RUNNING); - pr_debug("%s-%d: about to unregister this session()\n", + pr_debug("%s-%d: about to unregister this session\n", ch->sess_name, ch->qp->qp_num); scst_unregister_session(ch->sess, false, srpt_unreg_sess); - while (!kthread_should_stop()) - schedule_timeout(DIV_ROUND_UP(HZ, 10)); + set_current_state(TASK_INTERRUPTIBLE); + while (!kthread_should_stop()) { + schedule(); + set_current_state(TASK_INTERRUPTIBLE); + } + __set_current_state(TASK_RUNNING); return 0; } @@ -2397,7 +2415,8 @@ static struct srpt_nexus *srpt_get_nexus(struct srpt_port *sport, } } if (!nexus && tmp_nexus) { - list_add_tail(&tmp_nexus->entry, &sport->nexus_list); + list_add_tail_rcu(&tmp_nexus->entry, + &sport->nexus_list); swap(nexus, tmp_nexus); } mutex_unlock(&sport->mutex); @@ -2695,7 +2714,7 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev, rsp->rsp_flags = SRP_LOGIN_RSP_MULTICHAN_MAINTAINED; } - list_add_tail(&ch->list, &nexus->ch_list); + list_add_tail_rcu(&ch->list, &nexus->ch_list); ch->thread = thread; if (!sport->enabled) { @@ -3356,7 +3375,11 @@ static int srpt_perform_rdmas(struct srpt_rdma_ch *ch, struct srpt_send_ioctx *ioctx, scst_data_direction dir) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) struct ib_send_wr wr; +#else + struct ib_rdma_wr wr; +#endif struct ib_send_wr *bad_wr; struct rdma_iu *riu; int i; @@ -3377,6 +3400,7 @@ static int srpt_perform_rdmas(struct srpt_rdma_ch *ch, memset(&wr, 0, sizeof(wr)); for (i = 0; i < n_rdma; ++i, ++riu) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) if (dir == SCST_DATA_READ) { wr.opcode = IB_WR_RDMA_WRITE; wr.wr_id = encode_wr_id(i == n_rdma - 1 ? @@ -3401,6 +3425,32 @@ static int srpt_perform_rdmas(struct srpt_rdma_ch *ch, wr.send_flags = IB_SEND_SIGNALED; ret = ib_post_send(ch->qp, &wr, &bad_wr); +#else + if (dir == SCST_DATA_READ) { + wr.wr.opcode = IB_WR_RDMA_WRITE; + wr.wr.wr_id = encode_wr_id(i == n_rdma - 1 ? + SRPT_RDMA_WRITE_LAST : + SRPT_RDMA_MID, + ioctx->ioctx.index); + } else { + wr.wr.opcode = IB_WR_RDMA_READ; + wr.wr.wr_id = encode_wr_id(i == n_rdma - 1 ? + SRPT_RDMA_READ_LAST : + SRPT_RDMA_MID, + ioctx->ioctx.index); + } + wr.wr.next = NULL; + wr.remote_addr = riu->raddr; + wr.rkey = riu->rkey; + wr.wr.num_sge = riu->sge_cnt; + wr.wr.sg_list = riu->sge; + + /* only get completion event for the last rdma wr */ + if (i == (n_rdma - 1) && dir == SCST_DATA_WRITE) + wr.wr.send_flags = IB_SEND_SIGNALED; + + ret = ib_post_send(ch->qp, &wr.wr, &bad_wr); +#endif if (ret) break; } @@ -3409,6 +3459,7 @@ static int srpt_perform_rdmas(struct srpt_rdma_ch *ch, pr_err("%s: ib_post_send() returned %d for %d/%d\n", __func__, ret, i, n_rdma); if (ret && i > 0) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) wr.num_sge = 0; wr.wr_id = encode_wr_id(SRPT_RDMA_ABORT, ioctx->ioctx.index); wr.send_flags = IB_SEND_SIGNALED; @@ -3420,13 +3471,34 @@ static int srpt_perform_rdmas(struct srpt_rdma_ch *ch, ioctx->ioctx.index); msleep(1000); } +#else + wr.wr.num_sge = 0; + wr.wr.wr_id = encode_wr_id(SRPT_RDMA_ABORT, ioctx->ioctx.index); + wr.wr.send_flags = IB_SEND_SIGNALED; + pr_info("Trying to abort failed RDMA transfer [%d]\n", + ioctx->ioctx.index); + while (ch->state == CH_LIVE && + ib_post_send(ch->qp, &wr.wr, &bad_wr) != 0) { + pr_info("Trying to abort failed RDMA transfer [%d]\n", + ioctx->ioctx.index); + msleep(1000); + } +#endif pr_info("Waiting until RDMA abort finished [%d]\n", ioctx->ioctx.index); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) while (ch->state < CH_DISCONNECTED && !ioctx->rdma_aborted) { pr_info("Waiting until RDMA abort finished [%d]\n", ioctx->ioctx.index); msleep(1000); } +#else + while (ch->state < CH_DISCONNECTED && !ioctx->rdma_aborted) { + pr_info("Waiting until RDMA abort finished [%d]\n", + ioctx->ioctx.index); + msleep(1000); + } +#endif pr_info("%s[%d]: done\n", __func__, __LINE__); } @@ -3788,11 +3860,11 @@ static bool srpt_ch_list_empty(struct srpt_port *sport) struct srpt_nexus *nexus; bool res = true; - mutex_lock(&sport->mutex); - list_for_each_entry(nexus, &sport->nexus_list, entry) + rcu_read_lock(); + list_for_each_entry_rcu(nexus, &sport->nexus_list, entry) if (!list_empty(&nexus->ch_list)) res = false; - mutex_unlock(&sport->mutex); + rcu_read_unlock(); return res; } @@ -3832,8 +3904,8 @@ static int srpt_release_sport(struct srpt_port *sport) mutex_lock(&sport->mutex); list_for_each_entry_safe(nexus, next_n, &sport->nexus_list, entry) { - list_del(&nexus->entry); - kfree(nexus); + list_del_rcu(&nexus->entry); + kfree_rcu(nexus, rcu); } mutex_unlock(&sport->mutex); @@ -4141,11 +4213,15 @@ static void srpt_add_one(struct ib_device *device) sdev->device = device; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0) ret = ib_query_device(device, &sdev->dev_attr); if (ret) { pr_err("ib_query_device() failed: %d\n", ret); goto free_dev; } +#else + sdev->dev_attr = device->attrs; +#endif sdev->pd = ib_alloc_pd(device); if (IS_ERR(sdev->pd)) { @@ -4480,13 +4556,16 @@ static int __init srpt_init_module(void) if (rdma_cm_port) { struct sockaddr_in addr; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) || \ - defined(RHEL_MAJOR) && RHEL_MAJOR -0 >= 6 +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0) && \ + (!defined(RHEL_MAJOR) || RHEL_MAJOR -0 < 6) + rdma_cm_id = rdma_create_id(srpt_rdma_cm_handler, NULL, + RDMA_PS_TCP); +#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) rdma_cm_id = rdma_create_id(srpt_rdma_cm_handler, NULL, RDMA_PS_TCP, IB_QPT_RC); #else - rdma_cm_id = rdma_create_id(srpt_rdma_cm_handler, NULL, - RDMA_PS_TCP); + rdma_cm_id = rdma_create_id(&init_net, srpt_rdma_cm_handler, + NULL, RDMA_PS_TCP, IB_QPT_RC); #endif if (IS_ERR(rdma_cm_id)) { rdma_cm_id = NULL; @@ -4534,6 +4613,8 @@ out: static void __exit srpt_cleanup_module(void) { + rcu_barrier(); + if (rdma_cm_id) rdma_destroy_id(rdma_cm_id); ib_unregister_client(&srpt_client); diff --git a/srpt/src/ib_srpt.h b/srpt/src/ib_srpt.h index bbe52c011..c4c14b2f3 100644 --- a/srpt/src/ib_srpt.h +++ b/srpt/src/ib_srpt.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2006 - 2009 Mellanox Technology Inc. All rights reserved. - * Copyright (C) 2009 - 2015 Bart Van Assche . + * Copyright (C) 2009 - 2016 Bart Van Assche . * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -52,7 +52,7 @@ #define vlan_dev_vlan_id(dev) (panic("RHEL 5 misses vlan_dev_vlan_id()"),0) #endif #if defined(RHEL_MAJOR) && RHEL_MAJOR -0 <= 6 -#define __ethtool_get_settings(dev, cmd) (panic("RHEL misses __ethtool_get_settings()"),0) +#define __ethtool_get_settings(dev, cmd) (panic("RHEL misses __ethtool_get_settings()"), 0) #endif #include #include @@ -361,6 +361,7 @@ struct srpt_rdma_ch { }; struct ib_cq *cq; struct kref kref; + struct rcu_head rcu; int rq_size; int max_sge; int max_rsp_size; @@ -397,6 +398,7 @@ struct srpt_rdma_ch { struct srpt_nexus { struct list_head entry; struct list_head ch_list; + struct rcu_head rcu; u8 i_port_id[16]; u8 t_port_id[16]; }; diff --git a/usr/Makefile b/usr/Makefile index cff5548c2..56f34fb12 100644 --- a/usr/Makefile +++ b/usr/Makefile @@ -1,9 +1,9 @@ # # Common makefile for SCSI target mid-level and its drivers # -# Copyright (C) 2004 - 2015 Vladislav Bolkhovitin +# Copyright (C) 2004 - 2016 Vladislav Bolkhovitin # Copyright (C) 2004 - 2005 Leonid Stoljar -# Copyright (C) 2007 - 2015 SanDisk Corporation +# Copyright (C) 2007 - 2016 SanDisk Corporation # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License diff --git a/usr/events/Makefile b/usr/events/Makefile index ffce7d2d7..fa01f6b7f 100644 --- a/usr/events/Makefile +++ b/usr/events/Makefile @@ -97,6 +97,6 @@ extraclean: clean rm Makefile.aa release-archive: - ../../scripts/generate-release-archive events "$$(sed -n 's/^#define[[:blank:]]VERSION_STR[[:blank:]]*\"\([^\"]*\)\".*/\1/p' events.c)" + ../../scripts/generate-release-archive events "$$(sed -n 's/^#define[[:blank:]]VERSION_STR[[:blank:]]*\"\([^\"]*\)\".*/\1/p' ../include/version.h)" .PHONY: all install uninstall clean extraclean 2release 2debug 2perf diff --git a/usr/fileio/Makefile b/usr/fileio/Makefile index b91948369..6705f3496 100644 --- a/usr/fileio/Makefile +++ b/usr/fileio/Makefile @@ -1,8 +1,8 @@ # # SCSI target mid-level makefile # -# Copyright (C) 2007 - 2015 Vladislav Bolkhovitin -# Copyright (C) 2007 - 2015 SanDisk Corporation +# Copyright (C) 2007 - 2016 Vladislav Bolkhovitin +# Copyright (C) 2007 - 2016 SanDisk Corporation # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -118,6 +118,6 @@ extraclean: clean rm Makefile.aa release-archive: - ../../scripts/generate-release-archive fileio_tgt "$$(sed -n 's/^#define[[:blank:]]VERSION_STR[[:blank:]]*\"\([^\"]*\)\".*/\1/p' fileio.c)" + ../../scripts/generate-release-archive fileio_tgt "$$(sed -n 's/^#define[[:blank:]]VERSION_STR[[:blank:]]*\"\([^\"]*\)\".*/\1/p' ../include/version.h)" .PHONY: all install uninstall clean extraclean 2release 2debug 2perf diff --git a/usr/fileio/common.c b/usr/fileio/common.c index 8c7938b47..6394f5087 100644 --- a/usr/fileio/common.c +++ b/usr/fileio/common.c @@ -1,8 +1,8 @@ /* * common.c * - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/usr/fileio/common.h b/usr/fileio/common.h index aacdbc5da..070373745 100644 --- a/usr/fileio/common.h +++ b/usr/fileio/common.h @@ -1,8 +1,8 @@ /* * common.h * - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/usr/fileio/fileio.c b/usr/fileio/fileio.c index fbbedbb7c..fd9090758 100644 --- a/usr/fileio/fileio.c +++ b/usr/fileio/fileio.c @@ -1,8 +1,8 @@ /* * fileio.c * - * Copyright (C) 2007 - 2015 Vladislav Bolkhovitin - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 Vladislav Bolkhovitin + * Copyright (C) 2007 - 2016 SanDisk Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/usr/include/debug.c b/usr/include/debug.c index 8d77e475b..1713a3534 100644 --- a/usr/include/debug.c +++ b/usr/include/debug.c @@ -1,9 +1,9 @@ /* * debug.c * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 SanDisk Corporation * * Contains helper functions for execution tracing and error reporting. * Intended to be included in main .c file. diff --git a/usr/include/debug.h b/usr/include/debug.h index 9bdaddc0d..36544e24e 100644 --- a/usr/include/debug.h +++ b/usr/include/debug.h @@ -1,9 +1,9 @@ /* * debug.h * - * Copyright (C) 2004 - 2015 Vladislav Bolkhovitin + * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar - * Copyright (C) 2007 - 2015 SanDisk Corporation + * Copyright (C) 2007 - 2016 SanDisk Corporation * * Contains macroses for execution tracing and error reporting * diff --git a/usr/include/version.h b/usr/include/version.h index d1a857555..0984dc562 100644 --- a/usr/include/version.h +++ b/usr/include/version.h @@ -1,7 +1,7 @@ /* * version.h * - * Copyright (C) 2015 SanDisk Corporation + * Copyright (C) 2015 - 2016 SanDisk Corporation * * Contains macroses for execution tracing and error reporting * diff --git a/usr/stpgd/Makefile b/usr/stpgd/Makefile index 0f8336c95..fc340742e 100644 --- a/usr/stpgd/Makefile +++ b/usr/stpgd/Makefile @@ -89,16 +89,9 @@ extraclean: clean grep "^CFLAGS += \-DDEBUG -g -fno-inline -fno-inline-functions" Makefile >/dev/null rm Makefile.aa -2perf: - sed -i.aa s/"^C\?FLAGS += \-DEXTRACHECKS"/"#CFLAGS += \-DEXTRACHECKS"/ Makefile - grep "^#CFLAGS += \-DEXTRACHECKS" Makefile >/dev/null - sed -i.aa s/"^C\?FLAGS += \-DTRACING"/"#CFLAGS += \-DTRACING"/ Makefile - grep "^#CFLAGS += \-DTRACING" Makefile >/dev/null - sed -i.aa s/"^C\?FLAGS += \-DDEBUG -g -fno-inline -fno-inline-functions"/"#CFLAGS += \-DDEBUG -g -fno-inline -fno-inline-functions"/ Makefile - grep "^#CFLAGS += \-DDEBUG -g -fno-inline -fno-inline-functions" Makefile >/dev/null - rm Makefile.aa +2perf: 2release release-archive: - ../../scripts/generate-release-archive stpgd "$$(sed -n 's/^#define[[:blank:]]VERSION_STR[[:blank:]]*\"\([^\"]*\)\".*/\1/p' stpgd_main.c)" + ../../scripts/generate-release-archive stpgd "$$(sed -n 's/^#define[[:blank:]]VERSION_STR[[:blank:]]*\"\([^\"]*\)\".*/\1/p' ../include/version.h)" .PHONY: all install uninstall clean extraclean 2release 2debug 2perf diff --git a/usr/stpgd/stpgd_main.c b/usr/stpgd/stpgd_main.c index 625879cfc..63fa92bdd 100644 --- a/usr/stpgd/stpgd_main.c +++ b/usr/stpgd/stpgd_main.c @@ -46,12 +46,12 @@ char *app_name; # endif #endif /* DEBUG */ -#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) - bool log_daemon = true; unsigned long trace_flag = DEFAULT_LOG_FLAGS; #endif /* defined(DEBUG) || defined(TRACING) */ +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + int transition_timeout = DEFAULT_TRANSITION_TIME; static struct option const long_options[] = {