diff --git a/README b/README index 04f0fd0b5..aa14955cd 100644 --- a/README +++ b/README @@ -48,9 +48,15 @@ qla2x00t_git 3. Symlink drivers/scsi/qla2xxx subdirectory in the cloned git tree to the qla2x00t_git subdirectory -Thats all. Now "make all" and other common and QLA specific root -Makefile targets "magically" start working. For detail instructions how -to setup QLA target build environment see its README or HOWTO. +Thats all. Now run either "make all" to build the SCST core and all +target drivers with in-tree QLogic drivers, or the following command +with standalone QLogic drivers: + +BUILD_2X_MODULE=y CONFIG_SCSI_QLA_FC=y CONFIG_SCSI_QLA2XXX_TARGET=y make all + +and other common and QLA specific root Makefile targets "magically" start +working. For detail instructions how to setup QLA target build environment see +its README or HOWTO. You can still build the old driver using qla_old* root Makefile targets. diff --git a/SVN_TAGS b/SVN_TAGS index 789a05d4c..b8fb6f4f4 100644 --- a/SVN_TAGS +++ b/SVN_TAGS @@ -17,5 +17,6 @@ SRPT 1.0.0 450 2.2.x branch start 3981, which is a copy of r3979 on the 2.1.0.x branch 2.2.0 4102 2.2.1 4737 on the 2.2.x branch -3.0.x branch start 5534, which is a copy of trunk r5533. +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 diff --git a/iscsi-scst/doc/SCST_Gentoo_HOWTO.txt b/iscsi-scst/doc/SCST_Gentoo_HOWTO.txt index a2549013a..cca3aa443 100644 --- a/iscsi-scst/doc/SCST_Gentoo_HOWTO.txt +++ b/iscsi-scst/doc/SCST_Gentoo_HOWTO.txt @@ -1,5 +1,5 @@ ============================================== -SCST 2.x Installation on Gentoo Linux +SCST 3.x Installation on Gentoo Linux ============================================== This howto will get you a working SCST installation on Gentoo Linux, it @@ -15,12 +15,11 @@ Prerequisites: - User with root privileges - Read the official iSCSI-SCST howto for more options and information -Assumptions for this howto: +Assumptions for the examples used in this howto: - User logged on as root -- Gentoo Sources version 2.6.39-r3 installed - Manual build kernel without initramfs - Gentoo AMD64 version -- Grub bootloader +- Grub 1 bootloader (use of GRUB2 should be an easy change) - /boot on a separate partition - One iSCSI target with 2 LUNS, both LUNS virtual disk files - One iSCSI target with one LUN, LUN is a real device @@ -29,17 +28,32 @@ When the above options differ from your environment/setup you will need to change some of the commands provided in this howto for things to work. +1. Download SCST. -1. Download the latest SCST version. +Choose to download a specific branch or the latest development version +a) Latest development version cd /root - svn co https://scst.svn.sourceforge.net/svnroot/scst/trunk scst + svn checkout svn://svn.code.sf.net/p/scst/svn/trunk scst +b) Specific branch (3.0 used in example) + cd /root + svn checkout svn://svn.code.sf.net/p/scst/svn/branches/3.0.x scst + 2. Patch the kernel (Optional but required for the best speed) - cd /usr/src/linux-2.6.39-gentoo-r3 - patch -p1 < /root/scst/iscsi-scst/kernel/patches/put_page_callback-2.6.39.patch +If the SCST version downloaded above does not have the patches for the correct kernel +you can try the newest patches available, note the errors (if any) during the patch +and fix those manually by looking at the sourcefile.rej files generated by the patch +that list the failed changes. Use vi or nano to find and change the correct places for +the patch changes. (I had to change 2 lines in one source file and add 2 in another +when patching a 4.1.12 kernel with 3.18 patch files, so the majority of changes did +work perfectly) + + cd /usr/src/linux + patch -p1 < /root/scst/iscsi-scst/kernel/patches/put_page_callback-3.18.patch + patch -p1 < /root/scst/scst/kernel/scst_exec_req_fifo-3.18.patch make clean @@ -49,6 +63,9 @@ work. Select Networking support -> Networking options -> TCP/IP networking Select Networking support -> Networking options -> TCP/IP zero-copy transfer completion notification Select Device Drivers -> SCSI device support -> SCSI disk support + Select Device Drivers -> InfiniBand support + Select Device Drivers -> InfiniBand support -> InfiniBand SCSI RDMA Protocol + Select Device Drivers -> InfiniBand support -> iSCSI Extension for RDMA (iSER) Select Enable the block layer -> IO Schedulers -> CFQ I/O Scheduler Set Enable the Block layer -> IO Schedulers -> Default I/O Scheduler to 'CFQ' Set Processor type and features -> Preemption Model to 'No Forced Preemption (Server)' @@ -60,8 +77,8 @@ work. 4. Install the new kernel and reboot the system mount /boot - cp arch/x86_64/boot/bzImage /boot/kernel-2.6.39-gentoo-r3-SCST - nano -w /boot/grub/grub.conf (add a new boot entry with the newly compiled kernel) + cp arch/x86_64/boot/bzImage /boot/kernel-4.1.12-gentoo-SCST + nano -w /boot/grub/grub.conf (GRUB1: add a new boot entry with the newly compiled kernel) umount /boot shutdown -r now @@ -113,23 +130,13 @@ to all ip's 8. Run SCST automatically at startup -For SCST 2.1 SVN version r3805 and newer do: rc-update add scst default -For SCST 2.0 and for a SVN version before r3805 and Gentoo with the old baselayout without OpenRC do: - rc-update add scst default -For SCST 2.0 and for a SVN version before r3805 and you have the new Gentoo baselayout do: - echo "/etc/init.d/scst start" >> /etc/local.d/scst.start - echo "/etc/init.d/scst stop" >> /etc/local.d/scst.stop - chmod 775 /etc/local.d/scst.* -(the SCST init script doesn't work with openRC and changing it would be a lot of work so local.d is used as an easy workaround) - - -9. Using SCST access control (optional) +9. Using SCST accesscontrol (optional) SCST listens on all the targets IP addresses and allows access to any -initiators per default. There are a couple of ways to restict access and +initiators per default. There are a couple of ways to restrict access and here I will give some examples. For the full documentation see the README file in the scst/iscsi-scst/ directory @@ -137,7 +144,7 @@ To make a target accessible on only one IP address do: scstadmin -set_tgt_attr iqn.2011-08.nl.feka:storage.vdisk1 -driver iscsi -attributes allowed_portal=192.168.100.15 (Remember the IP address is the address of the target machine, not of the allowed initiator, you can add multiple entries on the same target - by repeating the above command, you can also use the wildcards * and ? + by repeating the above command, you can also use the wild cards * and ? where the ? stands for any single digit) To make targets only accessible by specific inititators add a group to @@ -162,7 +169,7 @@ Notes ============================================== SCST's vdisk_fileio handler will use a default blocksize of 512b, this -is the only safe option for vmware ESXi or older windows versions, for +is the only safe option for VMware ESXi or older windows versions, for best performance with newer windows versions a blocksize of 4096 will be much faster. diff --git a/iscsi-scst/kernel/config.c b/iscsi-scst/kernel/config.c index f774ebcd3..2e39e2523 100644 --- a/iscsi-scst/kernel/config.c +++ b/iscsi-scst/kernel/config.c @@ -1297,6 +1297,7 @@ unsigned long iscsi_get_flow_ctrl_or_mgmt_dbg_log_flag(struct iscsi_cmnd *cmnd) flag = TRACE_MGMT_DEBUG; else { int status = scst_cmd_get_status(cmnd->scst_cmd); + if ((status == SAM_STAT_TASK_SET_FULL) || (status == SAM_STAT_BUSY)) flag = TRACE_FLOW_CONTROL; diff --git a/iscsi-scst/kernel/conn.c b/iscsi-scst/kernel/conn.c index 057747296..de76de85d 100644 --- a/iscsi-scst/kernel/conn.c +++ b/iscsi-scst/kernel/conn.c @@ -116,10 +116,10 @@ void conn_info_show(struct seq_file *seq, struct iscsi_session *session) "[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]", NIP6(inet6_sk(sk)->daddr)); #elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) - snprintf(buf, sizeof(buf), "[%p6]", + snprintf(buf, sizeof(buf), "[%pI6]", &inet6_sk(sk)->daddr); #else - snprintf(buf, sizeof(buf), "[%p6]", + snprintf(buf, sizeof(buf), "[%pI6]", &sk->sk_v6_daddr); #endif break; @@ -525,6 +525,7 @@ static void conn_rsp_timer_fn(unsigned long arg) if (!list_empty(&conn->write_timeout_list)) { unsigned long timeout_time; + cmnd = list_first_entry(&conn->write_timeout_list, struct iscsi_cmnd, write_timeout_list_entry); @@ -583,7 +584,7 @@ static void conn_nop_in_delayed_work_fn(struct work_struct *work) #endif { #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) - struct iscsi_conn *conn = (struct iscsi_conn *)p; + struct iscsi_conn *conn = p; #else struct iscsi_conn *conn = container_of(work, struct iscsi_conn, nop_in_delayed_work.work); @@ -834,6 +835,7 @@ void conn_free(struct iscsi_conn *conn) /* Just in case if new conn gets freed before the old one */ if (test_bit(ISCSI_CONN_REINSTATING, &conn->conn_aflags)) { struct iscsi_conn *c; + TRACE_MGMT_DBG("Freeing being reinstated conn %p", conn); list_for_each_entry(c, &session->conn_list, conn_list_entry) { diff --git a/iscsi-scst/kernel/digest.c b/iscsi-scst/kernel/digest.c index 5d682aab5..cbfff039e 100644 --- a/iscsi-scst/kernel/digest.c +++ b/iscsi-scst/kernel/digest.c @@ -76,6 +76,7 @@ static __be32 evaluate_crc32_from_sg(struct scatterlist *sg, int nbytes, while (nbytes > 0) { int d = min(nbytes, (int)(sg->length)); + crc = crc32c(crc, sg_virt(sg), d); nbytes -= d; sg++; diff --git a/iscsi-scst/kernel/iscsi.c b/iscsi-scst/kernel/iscsi.c index cca896e3f..2bedfae17 100644 --- a/iscsi-scst/kernel/iscsi.c +++ b/iscsi-scst/kernel/iscsi.c @@ -138,6 +138,7 @@ static inline int cmnd_read_size(struct iscsi_cmnd *cmnd) if (ahdr != NULL) { uint8_t *p = (uint8_t *)ahdr; unsigned int size = 0; + do { int s; @@ -469,6 +470,7 @@ void cmnd_done(struct iscsi_cmnd *cmnd) { /* It can be for some aborted commands */ struct scst_cmd *scst_cmd = cmnd->scst_cmd; + TRACE_DBG("cmd %p AFTER_PREPROC", cmnd); cmnd->scst_state = ISCSI_CMD_STATE_RESTARTED; cmnd->scst_cmd = NULL; @@ -1087,6 +1089,7 @@ static void iscsi_tcp_send_data_rsp(struct iscsi_cmnd *req, u8 *sense, send_data_rsp(req, status, is_send_status); } else { struct iscsi_cmnd *rsp; + send_data_rsp(req, 0, 0); if (is_send_status) { rsp = create_status_rsp(req, status, sense, @@ -1221,6 +1224,7 @@ static int create_reject_rsp(struct iscsi_cmnd *req, int reason, bool get_data) if (req->scst_cmd == NULL) { /* BUSY status must be already set */ struct iscsi_scsi_rsp_hdr *rsp_hdr1; + rsp_hdr1 = (struct iscsi_scsi_rsp_hdr *)&req->main_rsp->pdu.bhs; sBUG_ON(rsp_hdr1->cmd_status == 0); /* @@ -1523,6 +1527,7 @@ int iscsi_preliminary_complete(struct iscsi_cmnd *req, #ifdef CONFIG_SCST_DEBUG { struct iscsi_hdr *req_hdr = &req->pdu.bhs; + TRACE_DBG_FLAG(iscsi_get_flow_ctrl_or_mgmt_dbg_log_flag(orig_req), "Prelim completed req %p, orig_req %p (FINAL %x, " "outstanding_r2t %d)", req, orig_req, @@ -1740,8 +1745,7 @@ out: static int iscsi_pre_exec(struct scst_cmd *scst_cmd) { int res = SCST_PREPROCESS_STATUS_SUCCESS; - struct iscsi_cmnd *req = (struct iscsi_cmnd *) - scst_cmd_get_tgt_priv(scst_cmd); + struct iscsi_cmnd *req = scst_cmd_get_tgt_priv(scst_cmd); struct iscsi_cmnd *c, *t; TRACE_ENTRY(); @@ -2047,6 +2051,7 @@ static int scsi_cmnd_start(struct iscsi_cmnd *req) if ((req_hdr->flags & ISCSI_CMD_READ) && (req_hdr->flags & ISCSI_CMD_WRITE)) { int sz = cmnd_read_size(req); + if (unlikely(sz < 0)) { PRINT_ERROR("%s", "BIDI data transfer, but initiator " "not supplied Bidirectional Read Expected Data " @@ -2109,6 +2114,7 @@ static int scsi_cmnd_start(struct iscsi_cmnd *req) if (ahdr != NULL) { uint8_t *p = (uint8_t *)ahdr; unsigned int size = 0; + do { int s; @@ -2509,6 +2515,7 @@ static void iscsi_cmnd_abort_fn(struct work_struct *work) */ list_for_each_entry(conn, &session->conn_list, conn_list_entry) { struct iscsi_cmnd *c; + spin_lock_bh(&conn->cmd_list_lock); list_for_each_entry(c, &conn->cmd_list, cmd_list_entry) { if (c == cmnd) { @@ -3303,9 +3310,9 @@ static ssize_t iscsi_tcp_get_initiator_ip(struct iscsi_conn *conn, #else #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) && \ (!defined(RHEL_MAJOR) || RHEL_MAJOR -0 < 7) - pos = scnprintf(buf, size, "[%p6]", &inet6_sk(sk)->daddr); + pos = scnprintf(buf, size, "[%pI6]", &inet6_sk(sk)->daddr); #else - pos = scnprintf(buf, size, "[%p6]", &sk->sk_v6_daddr); + pos = scnprintf(buf, size, "[%pI6]", &sk->sk_v6_daddr); #endif #endif break; @@ -3368,8 +3375,7 @@ static void iscsi_tcp_preprocessing_done(struct iscsi_cmnd *req) static void iscsi_preprocessing_done(struct scst_cmd *scst_cmd) { - struct iscsi_cmnd *req = (struct iscsi_cmnd *) - scst_cmd_get_tgt_priv(scst_cmd); + struct iscsi_cmnd *req = scst_cmd_get_tgt_priv(scst_cmd); req->conn->transport->iscsit_preprocessing_done(req); } @@ -3481,8 +3487,7 @@ static void iscsi_tcp_conn_close(struct iscsi_conn *conn, int flags) static int iscsi_xmit_response(struct scst_cmd *scst_cmd) { int is_send_status = scst_cmd_get_is_send_status(scst_cmd); - struct iscsi_cmnd *req = (struct iscsi_cmnd *) - scst_cmd_get_tgt_priv(scst_cmd); + struct iscsi_cmnd *req = scst_cmd_get_tgt_priv(scst_cmd); struct iscsi_conn *conn = req->conn; int status = scst_cmd_get_status(scst_cmd); u8 *sense = scst_cmd_get_sense_buffer(scst_cmd); @@ -3566,6 +3571,7 @@ static int iscsi_xmit_response(struct scst_cmd *scst_cmd) is_send_status); } else if (is_send_status) { struct iscsi_cmnd *rsp; + rsp = create_status_rsp(req, status, sense, sense_len); iscsi_cmnd_init_write(rsp, 0); } @@ -3760,8 +3766,7 @@ static inline int iscsi_get_mgmt_response(int status) static void iscsi_task_mgmt_fn_done(struct scst_mgmt_cmd *scst_mcmd) { int fn = scst_mgmt_cmd_get_fn(scst_mcmd); - struct iscsi_cmnd *req = (struct iscsi_cmnd *) - scst_mgmt_cmd_get_tgt_priv(scst_mcmd); + struct iscsi_cmnd *req = scst_mgmt_cmd_get_tgt_priv(scst_mcmd); int status = iscsi_get_mgmt_response(scst_mgmt_cmd_get_status(scst_mcmd)); if ((status == ISCSI_RESPONSE_UNKNOWN_TASK) && diff --git a/iscsi-scst/kernel/iscsi.h b/iscsi-scst/kernel/iscsi.h index 7a4ca36ab..986f5132c 100644 --- a/iscsi-scst/kernel/iscsi.h +++ b/iscsi-scst/kernel/iscsi.h @@ -693,6 +693,7 @@ static inline bool cmnd_get_check(struct iscsi_cmnd *cmnd) { int r = atomic_inc_return(&cmnd->ref_cnt); int res; + if (unlikely(r == 1)) { TRACE_DBG("cmnd %p is being destroyed", cmnd); atomic_dec(&cmnd->ref_cnt); diff --git a/iscsi-scst/kernel/isert-scst/iser_buf.c b/iscsi-scst/kernel/isert-scst/iser_buf.c index b84a68f68..daa78c72a 100644 --- a/iscsi-scst/kernel/isert-scst/iser_buf.c +++ b/iscsi-scst/kernel/isert-scst/iser_buf.c @@ -49,8 +49,8 @@ static int isert_buf_alloc_pg(struct ib_device *ib_dev, struct page *page; isert_buf->sg_cnt = DIV_ROUND_UP(size, PAGE_SIZE); - isert_buf->sg = kmalloc(sizeof(*isert_buf->sg) * isert_buf->sg_cnt, - GFP_KERNEL); + isert_buf->sg = kmalloc_array(isert_buf->sg_cnt, sizeof(*isert_buf->sg), + GFP_KERNEL); if (unlikely(!isert_buf->sg)) { pr_err("Failed to allocate buffer SG\n"); res = -ENOMEM; @@ -294,6 +294,7 @@ out: void isert_wr_release(struct isert_wr *wr) { struct isert_buf *isert_buf = wr->buf; + if (isert_buf && isert_buf->is_alloced) { struct isert_device *isert_dev = wr->isert_dev; struct ib_device *ib_dev; diff --git a/iscsi-scst/kernel/isert-scst/iser_datamover.c b/iscsi-scst/kernel/isert-scst/iser_datamover.c index 19fc58640..165ab071b 100644 --- a/iscsi-scst/kernel/isert-scst/iser_datamover.c +++ b/iscsi-scst/kernel/isert-scst/iser_datamover.c @@ -63,7 +63,8 @@ int isert_get_peer_addr(struct iscsi_conn *iscsi_conn, struct sockaddr *sa, size_t *addr_len) { int ret; - struct isert_connection *isert_conn = (struct isert_connection *)iscsi_conn; + struct isert_connection *isert_conn = container_of(iscsi_conn, + struct isert_connection, iscsi); struct sockaddr *peer_sa = (struct sockaddr *)&isert_conn->peer_addr; ret = isert_get_addr_size(peer_sa, addr_len); @@ -79,7 +80,8 @@ int isert_get_target_addr(struct iscsi_conn *iscsi_conn, struct sockaddr *sa, size_t *addr_len) { int ret; - struct isert_connection *isert_conn = (struct isert_connection *)iscsi_conn; + struct isert_connection *isert_conn = container_of(iscsi_conn, + struct isert_connection, iscsi); struct sockaddr *self_sa = (struct sockaddr *)&isert_conn->self_addr; ret = isert_get_addr_size(self_sa, addr_len); @@ -106,14 +108,17 @@ int isert_portal_remove(void *portal_h) void isert_free_connection(struct iscsi_conn *iscsi_conn) { - struct isert_connection *isert_conn = (struct isert_connection *)iscsi_conn; + struct isert_connection *isert_conn = container_of(iscsi_conn, + struct isert_connection, iscsi); + isert_post_drain(isert_conn); isert_conn_free(isert_conn); } struct iscsi_cmnd *isert_alloc_login_rsp_pdu(struct iscsi_conn *iscsi_conn) { - struct isert_connection *isert_conn = (struct isert_connection *)iscsi_conn; + struct isert_connection *isert_conn = container_of(iscsi_conn, + struct isert_connection, iscsi); struct isert_cmnd *isert_pdu = isert_conn->login_rsp_pdu; isert_tx_pdu_init(isert_pdu, isert_conn); @@ -123,7 +128,8 @@ struct iscsi_cmnd *isert_alloc_login_rsp_pdu(struct iscsi_conn *iscsi_conn) static struct iscsi_cmnd *isert_alloc_scsi_pdu(struct iscsi_conn *iscsi_conn, int fake) { - struct isert_connection *isert_conn = (struct isert_connection *)iscsi_conn; + struct isert_connection *isert_conn = container_of(iscsi_conn, + struct isert_connection, iscsi); struct isert_cmnd *isert_pdu; again: @@ -153,8 +159,10 @@ struct iscsi_cmnd *isert_alloc_scsi_fake_pdu(struct iscsi_conn *iscsi_conn) void isert_release_tx_pdu(struct iscsi_cmnd *iscsi_pdu) { - struct isert_cmnd *isert_pdu = (struct isert_cmnd *)iscsi_pdu; - struct isert_connection *isert_conn = (struct isert_connection *)iscsi_pdu->conn; + struct isert_cmnd *isert_pdu = container_of(iscsi_pdu, + struct isert_cmnd, iscsi); + struct isert_connection *isert_conn = container_of(iscsi_pdu->conn, + struct isert_connection, iscsi); isert_tx_pdu_init_iscsi(isert_pdu); @@ -165,16 +173,17 @@ void isert_release_tx_pdu(struct iscsi_cmnd *iscsi_pdu) void isert_release_rx_pdu(struct iscsi_cmnd *iscsi_pdu) { - struct isert_cmnd *isert_pdu = (struct isert_cmnd *)iscsi_pdu; + struct isert_cmnd *isert_pdu = container_of(iscsi_pdu, + struct isert_cmnd, iscsi); - if (likely(!isert_pdu->is_fake_rx)) - isert_rx_pdu_done(isert_pdu); + isert_rx_pdu_done(isert_pdu); } /* if last transition into FF (Fully Featured) state */ int isert_login_rsp_tx(struct iscsi_cmnd *login_rsp, int last, int discovery) { - struct isert_connection *isert_conn = (struct isert_connection *)login_rsp->conn; + struct isert_connection *isert_conn = container_of(login_rsp->conn, + struct isert_connection, iscsi); int err; if (last && !discovery) { @@ -202,7 +211,8 @@ int isert_set_session_params(struct iscsi_conn *iscsi_conn, struct iscsi_sess_params *sess_params, struct iscsi_tgt_params *tgt_params) { - struct isert_connection *isert_conn = (struct isert_connection *)iscsi_conn; + struct isert_connection *isert_conn = container_of(iscsi_conn, + struct isert_connection, iscsi); isert_conn->queue_depth = tgt_params->queued_cmnds; @@ -217,8 +227,10 @@ int isert_set_session_params(struct iscsi_conn *iscsi_conn, int isert_pdu_tx(struct iscsi_cmnd *iscsi_cmnd) { - struct isert_cmnd *isert_cmnd = (struct isert_cmnd *)iscsi_cmnd; - struct isert_connection *isert_conn = (struct isert_connection *)iscsi_cmnd->conn; + struct isert_cmnd *isert_cmnd = container_of(iscsi_cmnd, + struct isert_cmnd, iscsi); + struct isert_connection *isert_conn = container_of(iscsi_cmnd->conn, + struct isert_connection, iscsi); int err; isert_tx_pdu_convert_from_iscsi(isert_cmnd, iscsi_cmnd); @@ -229,8 +241,10 @@ int isert_pdu_tx(struct iscsi_cmnd *iscsi_cmnd) int isert_request_data_out(struct iscsi_cmnd *iscsi_cmnd) { - struct isert_cmnd *isert_cmnd = (struct isert_cmnd *)iscsi_cmnd; - struct isert_connection *isert_conn = (struct isert_connection *)iscsi_cmnd->conn; + struct isert_cmnd *isert_cmnd = container_of(iscsi_cmnd, + struct isert_cmnd, iscsi); + struct isert_connection *isert_conn = container_of(iscsi_cmnd->conn, + struct isert_connection, iscsi); int ret; ret = isert_prepare_rdma(isert_cmnd, isert_conn, ISER_WR_RDMA_READ); @@ -245,9 +259,12 @@ int isert_request_data_out(struct iscsi_cmnd *iscsi_cmnd) int isert_send_data_in(struct iscsi_cmnd *iscsi_cmnd, struct iscsi_cmnd *iscsi_rsp) { - struct isert_cmnd *isert_cmnd = (struct isert_cmnd *)iscsi_cmnd; - struct isert_connection *isert_conn = (struct isert_connection *)iscsi_cmnd->conn; - struct isert_cmnd *isert_rsp = (struct isert_cmnd *)iscsi_rsp; + struct isert_cmnd *isert_cmnd = container_of(iscsi_cmnd, + struct isert_cmnd, iscsi); + struct isert_connection *isert_conn = container_of(iscsi_cmnd->conn, + struct isert_connection, iscsi); + struct isert_cmnd *isert_rsp = container_of(iscsi_rsp, + struct isert_cmnd, iscsi); int ret; ret = isert_prepare_rdma(isert_cmnd, isert_conn, ISER_WR_RDMA_WRITE); @@ -262,7 +279,8 @@ int isert_send_data_in(struct iscsi_cmnd *iscsi_cmnd, int isert_close_connection(struct iscsi_conn *iscsi_conn) { - struct isert_connection *isert_conn = (struct isert_connection *)iscsi_conn; + struct isert_connection *isert_conn = container_of(iscsi_conn, + struct isert_connection, iscsi); isert_conn_disconnect(isert_conn); @@ -276,14 +294,16 @@ int isert_task_abort(struct iscsi_cmnd *cmnd) void *isert_get_priv(struct iscsi_conn *iscsi_conn) { - struct isert_connection *isert_conn = (struct isert_connection *)iscsi_conn; + struct isert_connection *isert_conn = container_of(iscsi_conn, + struct isert_connection, iscsi); return isert_conn->priv_data; } void isert_set_priv(struct iscsi_conn *iscsi_conn, void *priv) { - struct isert_connection *isert_conn = (struct isert_connection *)iscsi_conn; + struct isert_connection *isert_conn = container_of(iscsi_conn, + struct isert_connection, iscsi); isert_conn->priv_data = priv; } diff --git a/iscsi-scst/kernel/isert-scst/iser_pdu.c b/iscsi-scst/kernel/isert-scst/iser_pdu.c index 4a23d06c9..0c6e81b32 100644 --- a/iscsi-scst/kernel/isert-scst/iser_pdu.c +++ b/iscsi-scst/kernel/isert-scst/iser_pdu.c @@ -82,6 +82,7 @@ static int isert_rx_pdu_init(struct isert_cmnd *isert_pdu, { struct iscsi_cmnd *iscsi_cmnd = &isert_pdu->iscsi; int err = isert_pdu_rx_buf_init(isert_pdu, isert_conn); + if (unlikely(err < 0)) return err; iscsi_cmnd->conn = &isert_conn->iscsi; @@ -174,14 +175,14 @@ static int isert_alloc_for_rdma(struct isert_cmnd *pdu, int sge_cnt, int i, ret = 0; int wr_cnt; - sg_pool = kmalloc(sizeof(*sg_pool) * sge_cnt, GFP_KERNEL); + sg_pool = kmalloc_array(sge_cnt, sizeof(*sg_pool), GFP_KERNEL); if (unlikely(sg_pool == NULL)) { ret = -ENOMEM; goto out; } wr_cnt = DIV_ROUND_UP(sge_cnt, isert_conn->max_sge); - wr = kmalloc(sizeof(*wr) * wr_cnt, GFP_KERNEL); + wr = kmalloc_array(wr_cnt, sizeof(*wr), GFP_KERNEL); if (unlikely(wr == NULL)) { ret = -ENOMEM; goto out_free_sg_pool; @@ -478,7 +479,8 @@ clean_pdus: static int isert_reinit_rx_pdu(struct isert_cmnd *pdu) { - struct isert_connection *isert_conn = (struct isert_connection *)pdu->iscsi.conn; + struct isert_connection *isert_conn = container_of(pdu->iscsi.conn, + struct isert_connection, iscsi); pdu->is_rstag_valid = 0; pdu->is_wstag_valid = 0; @@ -491,7 +493,8 @@ static int isert_reinit_rx_pdu(struct isert_cmnd *pdu) int isert_rx_pdu_done(struct isert_cmnd *pdu) { int err; - struct isert_connection *isert_conn = (struct isert_connection *)pdu->iscsi.conn; + struct isert_connection *isert_conn = container_of(pdu->iscsi.conn, + struct isert_connection, iscsi); TRACE_ENTRY(); diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index 1b3e849a9..8fd02ab4a 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -136,8 +136,10 @@ void isert_post_drain(struct isert_connection *isert_conn) err = ib_post_send(isert_conn->qp, &isert_conn->drain_wr.send_wr, &bad_wr); if (unlikely(err)) { pr_err("Failed to post drain wr, err:%d\n", err); - /* We need to decrement iser_conn->kref in order to be able to cleanup - * the connection */ + /* + * We need to decrement iser_conn->kref in order to be + * able to cleanup the connection. + */ set_bit(ISERT_DRAIN_FAILED, &isert_conn->flags); isert_conn_free(isert_conn); } @@ -352,7 +354,9 @@ static void isert_send_completion_handler(struct isert_wr *wr) struct isert_cmnd *isert_pdu = wr->pdu; struct iscsi_cmnd *iscsi_pdu = &isert_pdu->iscsi; struct iscsi_cmnd *iscsi_req_pdu = iscsi_pdu->parent_req; - struct isert_cmnd *isert_req_pdu = (struct isert_cmnd *)iscsi_req_pdu; + struct isert_cmnd *isert_req_pdu = container_of(iscsi_req_pdu, + struct isert_cmnd, iscsi); + TRACE_ENTRY(); @@ -633,9 +637,11 @@ static void isert_handle_wc_error(struct ib_wc *wc) isert_buf->dma_dir); isert_buf->sg_cnt = 0; } - /* RDMA-WR and SEND response of a READ task - are sent together, so when receiving RDMA-WR error, - wait until SEND error arrives to complete the task */ + /* + * RDMA-WR and SEND response of a READ task + * are sent together, so when receiving RDMA-WR error, + * wait until SEND error arrives to complete the task. + */ break; default: pr_err("unexpected opcode %d, wc:%p wr_id:%p conn:%p\n", @@ -866,7 +872,8 @@ static struct isert_device *isert_device_create(struct ib_device *ib_dev) isert_dev->num_cqs = min_t(int, num_online_cpus(), ib_dev->num_comp_vectors); - isert_dev->cq_qps = kzalloc(sizeof(*isert_dev->cq_qps) * isert_dev->num_cqs, + isert_dev->cq_qps = kcalloc(isert_dev->num_cqs, + sizeof(*isert_dev->cq_qps), GFP_KERNEL); if (unlikely(isert_dev->cq_qps == NULL)) { pr_err("Failed to allocate iser cq_qps\n"); diff --git a/iscsi-scst/kernel/isert-scst/isert.c b/iscsi-scst/kernel/isert-scst/isert.c index 5cdc28901..2a3693754 100644 --- a/iscsi-scst/kernel/isert-scst/isert.c +++ b/iscsi-scst/kernel/isert-scst/isert.c @@ -46,6 +46,7 @@ #endif #include "isert_dbg.h" #include "isert.h" +#include "iser.h" #include "iser_datamover.h" #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) @@ -190,6 +191,9 @@ static struct iscsi_cmnd *isert_cmnd_alloc(struct iscsi_conn *conn, static void isert_cmnd_free(struct iscsi_cmnd *cmnd) { + struct isert_cmnd *isert_cmnd = container_of(cmnd, struct isert_cmnd, + iscsi); + TRACE_ENTRY(); #ifdef CONFIG_SCST_EXTRACHECKS @@ -211,7 +215,7 @@ static void isert_cmnd_free(struct iscsi_cmnd *cmnd) sBUG(); } #endif - if (cmnd->parent_req) + if (cmnd->parent_req || isert_cmnd->is_fake_rx) isert_release_tx_pdu(cmnd); else isert_release_rx_pdu(cmnd); @@ -282,9 +286,11 @@ static void isert_free_conn(struct iscsi_conn *conn) int isert_handle_close_connection(struct iscsi_conn *conn) { isert_mark_conn_closed(conn, 0); - /* Take care of case where our connection is being closed - * without being connected to a session - if connection allocation - * failed for some reason */ + /* + * Take care of case where our connection is being closed without + * being connected to a session - if connection allocation failed for + * some reason. + */ if (unlikely(!conn->session)) isert_free_connection(conn); else @@ -438,7 +444,7 @@ static ssize_t isert_get_initiator_ip(struct iscsi_conn *conn, "[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]", NIP6(((struct sockaddr_in6 *)&ss)->sin6_addr)); #else - pos = scnprintf(buf, size, "[%p6]", + pos = scnprintf(buf, size, "[%pI6]", &((struct sockaddr_in6 *)&ss)->sin6_addr); #endif break; diff --git a/iscsi-scst/kernel/isert-scst/isert_login.c b/iscsi-scst/kernel/isert-scst/isert_login.c index f92eafe30..0a3720306 100644 --- a/iscsi-scst/kernel/isert-scst/isert_login.c +++ b/iscsi-scst/kernel/isert-scst/isert_login.c @@ -567,6 +567,7 @@ static ssize_t isert_read(struct file *filp, char __user *buf, size_t count, if (will_read_block(dev)) { int ret; + if (filp->f_flags & O_NONBLOCK) return -EAGAIN; ret = wait_event_freezable(dev->waitqueue, @@ -804,11 +805,8 @@ int isert_login_req_rx(struct iscsi_cmnd *login_req) switch (dev->state) { case CS_INIT: case CS_RSP_FINISHED: - if (unlikely(dev->login_req != NULL)) { + if (unlikely(dev->login_req != NULL)) sBUG(); - res = -EINVAL; - goto out; - } break; case CS_REQ_BHS: /* Got login request before done handling old one */ @@ -825,8 +823,6 @@ int isert_login_req_rx(struct iscsi_cmnd *login_req) default: sBUG(); - res = -EINVAL; - goto out; } @@ -956,7 +952,7 @@ int __init isert_init_login_devs(unsigned int ndevs) * allocate the devices -- we can't have them static, as the number * can be specified at load time */ - isert_conn_devices = kzalloc(n_devs * sizeof(struct isert_conn_dev), + isert_conn_devices = kcalloc(n_devs, sizeof(struct isert_conn_dev), GFP_KERNEL); if (unlikely(!isert_conn_devices)) { res = -ENOMEM; diff --git a/iscsi-scst/kernel/nthread.c b/iscsi-scst/kernel/nthread.c index 00b9d4165..2d6333229 100644 --- a/iscsi-scst/kernel/nthread.c +++ b/iscsi-scst/kernel/nthread.c @@ -100,6 +100,7 @@ again: for (i = 0; i < cmnd->sg_cnt; i++) { struct page *page = sg_page(&cmnd->sg[i]); + TRACE_CONN_CLOSE_DBG("page %p, net_priv %p, " "_count %d", page, page->net_priv, atomic_read(&page->_count)); @@ -282,8 +283,10 @@ static void trace_conn_close(struct iscsi_conn *conn) cmnd->sg); if (cmnd->sg != NULL) { int i; + for (i = 0; i < cmnd->sg_cnt; i++) { struct page *page = sg_page(&cmnd->sg[i]); + TRACE_CONN_CLOSE_DBG("page %p, " "net_priv %p, _count %d", page, page->net_priv, @@ -301,6 +304,7 @@ static void trace_conn_close(struct iscsi_conn *conn) atomic_read(&rsp->net_ref_cnt), rsp->sg); if (rsp->sg != cmnd->sg && rsp->sg) { int i; + for (i = 0; i < rsp->sg_cnt; i++) { TRACE_CONN_CLOSE_DBG(" page %p, " "net_priv %p, _count %d", @@ -330,7 +334,7 @@ void iscsi_task_mgmt_affected_cmds_done(struct scst_mgmt_cmd *scst_mcmd) switch (fn) { case SCST_NEXUS_LOSS_SESS: { - struct iscsi_conn *conn = (struct iscsi_conn *)priv; + struct iscsi_conn *conn = priv; struct iscsi_session *sess = conn->session; struct iscsi_conn *c; @@ -459,6 +463,7 @@ static void close_conn(struct iscsi_conn *conn) spin_lock(&session->sn_lock); if (session->tm_rsp && session->tm_rsp->conn == conn) { struct iscsi_cmnd *tm_rsp = session->tm_rsp; + iscsi_drop_delayed_tm_rsp(tm_rsp); spin_unlock(&session->sn_lock); mutex_unlock(&target->target_mutex); @@ -579,7 +584,7 @@ static void close_conn(struct iscsi_conn *conn) static int close_conn_thr(void *arg) { - struct iscsi_conn *conn = (struct iscsi_conn *)arg; + struct iscsi_conn *conn = arg; TRACE_ENTRY(); @@ -795,6 +800,7 @@ static int iscsi_rx_check_ddigest(struct iscsi_conn *conn) res = digest_rx_data(cmnd); if (unlikely(res != 0)) { struct iscsi_cmnd *orig_req; + if (cmnd_opcode(cmnd) == ISCSI_OP_SCSI_DATA_OUT) orig_req = cmnd->cmd_req; else @@ -914,6 +920,7 @@ static int process_read_io(struct iscsi_conn *conn, int *closed) res = do_recv(conn); if (res == 0) { int psz = ((cmnd->pdu.datasize + 3) & -4) - cmnd->pdu.datasize; + if (psz != 0) { TRACE_DBG("padding %d bytes", psz); iscsi_conn_init_read(conn, @@ -1138,7 +1145,7 @@ static inline void __iscsi_get_page_callback(struct iscsi_cmnd *cmd) void iscsi_get_page_callback(struct page *page) { - struct iscsi_cmnd *cmd = (struct iscsi_cmnd *)page->net_priv; + struct iscsi_cmnd *cmd = page->net_priv; TRACE_NET_PAGE("page %p, _count %d", page, atomic_read(&page->_count)); @@ -1154,8 +1161,10 @@ static inline void __iscsi_put_page_callback(struct iscsi_cmnd *cmd) if (atomic_dec_and_test(&cmd->net_ref_cnt)) { int i, sg_cnt = cmd->sg_cnt; + for (i = 0; i < sg_cnt; i++) { struct page *page = sg_page(&cmd->sg[i]); + TRACE_NET_PAGE("Clearing page %p", page); if (page->net_priv == cmd) page->net_priv = NULL; @@ -1167,7 +1176,7 @@ static inline void __iscsi_put_page_callback(struct iscsi_cmnd *cmd) void iscsi_put_page_callback(struct page *page) { - struct iscsi_cmnd *cmd = (struct iscsi_cmnd *)page->net_priv; + struct iscsi_cmnd *cmd = page->net_priv; TRACE_NET_PAGE("page %p, _count %d", page, atomic_read(&page->_count)); @@ -1222,9 +1231,11 @@ void req_add_to_write_timeout_list(struct iscsi_cmnd *req) unsigned long req_tt = iscsi_get_timeout_time(req); struct iscsi_cmnd *r; bool inserted = false; + list_for_each_entry(r, &conn->write_timeout_list, write_timeout_list_entry) { unsigned long tt = iscsi_get_timeout_time(r); + if (time_after(tt, req_tt)) { TRACE_DBG("Add NOP IN req %p (tt %ld) before " "req %p (tt %ld)", req, req_tt, r, tt); @@ -1256,6 +1267,7 @@ void req_add_to_write_timeout_list(struct iscsi_cmnd *req) if (!timer_pending(&conn->rsp_timer)) { unsigned long timeout_time; + if (unlikely(conn->conn_tm_active || test_bit(ISCSI_CMD_ABORTED, &req->prelim_compl_flags))) { @@ -1276,6 +1288,7 @@ void req_add_to_write_timeout_list(struct iscsi_cmnd *req) &req->prelim_compl_flags))) { unsigned long timeout_time = jiffies + ISCSI_TM_DATA_WAIT_TIMEOUT + ISCSI_ADD_SCHED_TIME; + set_conn_tm_active = true; if (time_after(conn->rsp_timer.expires, timeout_time)) { TRACE_MGMT_DBG("Mod timer on %ld (conn %p)", @@ -1454,6 +1467,7 @@ retry: #if defined(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION) { static DEFINE_SPINLOCK(net_priv_lock); + spin_lock(&net_priv_lock); if (unlikely(page->net_priv != NULL)) { if (page->net_priv != ref_cmd) { diff --git a/iscsi-scst/kernel/session.c b/iscsi-scst/kernel/session.c index 52dd682be..5b28d0fe4 100644 --- a/iscsi-scst/kernel/session.c +++ b/iscsi-scst/kernel/session.c @@ -199,6 +199,7 @@ int __add_session(struct iscsi_target *target, list_for_each_entry_reverse(sess, &target->session_list, session_list_entry) { union iscsi_sid s = *(union iscsi_sid *)&sess->sid; + s.id.tsih = 0; if ((sid.id64 == s.id64) && (strcmp(info->initiator_name, sess->initiator_name) == 0)) { @@ -332,6 +333,7 @@ int session_free(struct iscsi_session *session, bool del) if (session->sess_reinstating) { struct iscsi_session *s; + TRACE_MGMT_DBG("Freeing being reinstated sess %p", session); list_for_each_entry(s, &session->target->session_list, session_list_entry) { diff --git a/iscsi-scst/kernel/target.c b/iscsi-scst/kernel/target.c index 0677b7428..7a3e0a546 100644 --- a/iscsi-scst/kernel/target.c +++ b/iscsi-scst/kernel/target.c @@ -298,6 +298,7 @@ void target_del_session(struct iscsi_target *target, if (!list_empty(&session->conn_list)) { struct iscsi_conn *conn, *tc; + list_for_each_entry_safe(conn, tc, &session->conn_list, conn_list_entry) { TRACE_MGMT_DBG("Del session: closing conn %p", conn); @@ -616,6 +617,7 @@ ssize_t iscsi_sysfs_del_target(const char *target_name) /* We don't want to have tgt visible after the mutex unlock */ { struct iscsi_target *tgt; + mutex_lock(&target_mgmt_mutex); tgt = target_lookup_by_name(target_name); if (tgt == NULL) { diff --git a/nightly/conf/nightly.conf b/nightly/conf/nightly.conf index bdee4697d..6b79841c8 100644 --- a/nightly/conf/nightly.conf +++ b/nightly/conf/nightly.conf @@ -4,19 +4,19 @@ ABT_DETAILS="x86_64" ABT_JOBS=5 ABT_KERNELS=" \ 4.3 \ -4.2.5-nc \ -4.1.12-nc \ +4.2.6-nc \ +4.1.13-nc \ 4.0.9-nc \ 3.19.7-nc \ 3.18.19-nc \ 3.17.8-nc \ 3.16.7-nc \ 3.15.10-nc \ -3.14.56-nc \ +3.14.57-nc \ 3.13.11-nc \ 3.12.44-nc \ 3.11.10-nc \ -3.10.92-nc \ +3.10.93-nc \ 3.9.11-nc \ 3.8.13-nc \ 3.7.10-nc \ diff --git a/qla2x00t/qla2x00-target/qla2x00t.c b/qla2x00t/qla2x00-target/qla2x00t.c index a817faf0c..dad9e2711 100644 --- a/qla2x00t/qla2x00-target/qla2x00t.c +++ b/qla2x00t/qla2x00-target/qla2x00t.c @@ -308,6 +308,7 @@ static inline struct q2t_sess *q2t_find_sess_by_loop_id(struct q2t_tgt *tgt, uint16_t loop_id) { struct q2t_sess *sess; + list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) { if (loop_id == sess->loop_id) { EXTRACHECKS_BUG_ON(sess->deleted); @@ -322,6 +323,7 @@ static inline struct q2t_sess *q2t_find_sess_by_s_id_include_deleted( struct q2t_tgt *tgt, const uint8_t *s_id) { struct q2t_sess *sess; + list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) { if ((sess->s_id.b.al_pa == s_id[2]) && (sess->s_id.b.area == s_id[1]) && @@ -346,6 +348,7 @@ static inline struct q2t_sess *q2t_find_sess_by_s_id(struct q2t_tgt *tgt, const uint8_t *s_id) { struct q2t_sess *sess; + list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) { if ((sess->s_id.b.al_pa == s_id[2]) && (sess->s_id.b.area == s_id[1]) && @@ -362,6 +365,7 @@ static inline struct q2t_sess *q2t_find_sess_by_s_id_le(struct q2t_tgt *tgt, const uint8_t *s_id) { struct q2t_sess *sess; + list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) { if ((sess->s_id.b.al_pa == s_id[0]) && (sess->s_id.b.area == s_id[1]) && @@ -378,6 +382,7 @@ static inline struct q2t_sess *q2t_find_sess_by_port_name(struct q2t_tgt *tgt, const uint8_t *port_name) { struct q2t_sess *sess; + list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) { if ((sess->port_name[0] == port_name[0]) && (sess->port_name[1] == port_name[1]) && @@ -399,6 +404,7 @@ static inline struct q2t_sess *q2t_find_sess_by_port_name_include_deleted( struct q2t_tgt *tgt, const uint8_t *port_name) { struct q2t_sess *sess; + list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) { if ((sess->port_name[0] == port_name[0]) && (sess->port_name[1] == port_name[1]) && @@ -446,6 +452,7 @@ static inline int q2t_issue_marker(scsi_qla_host_t *vha, int vha_locked) /* Send marker if required */ if (unlikely(vha->marker_needed != 0)) { int rc = qla2x00_issue_marker(vha, vha_locked); + if (rc != QLA_SUCCESS) { PRINT_ERROR("qla2x00t(%ld): issue_marker() " "failed", vha->host_no); @@ -468,6 +475,7 @@ static inline scsi_qla_host_t *q2t_find_host_by_d_id(scsi_qla_host_t *vha, if (IS_FWI2_CAPABLE(ha)) { uint8_t vp_idx; + sBUG_ON(ha->tgt_vp_map == NULL); vp_idx = ha->tgt_vp_map[d_id[2]].idx; if (likely(test_bit(vp_idx, ha->vp_idx_map))) @@ -547,6 +555,7 @@ static void q24_try_to_dequeue_unknown_atios(struct qla_hw_data *ha) list_for_each_entry_safe(u, t, &ha->unknown_atio_list, unknown_atio_list_entry) { scsi_qla_host_t *host, *vha = u->vha; + sBUG_ON(vha->hw != ha); host = q2t_find_host_by_d_id(vha, u->atio7.fcp_hdr.d_id); if (host != NULL) { @@ -610,7 +619,8 @@ static void q24_atio_pkt_all_vps(scsi_qla_host_t *vha, atio7_entry_t *atio) case ATIO_TYPE7: { scsi_qla_host_t *host = q2t_find_host_by_d_id(vha, atio->fcp_hdr.d_id); - if (unlikely(NULL == host)) { + + if (unlikely(host == NULL)) { /* * It might happen, because there is a small gap between * requesting the DPC thread to update loop and actual @@ -628,8 +638,10 @@ static void q24_atio_pkt_all_vps(scsi_qla_host_t *vha, atio7_entry_t *atio) case IMMED_NOTIFY_TYPE: { scsi_qla_host_t *host = vha; + if (IS_FWI2_CAPABLE(ha)) { notify24xx_entry_t *entry = (notify24xx_entry_t *)atio; + if ((entry->vp_index != 0xFF) && (entry->nport_handle != 0xFFFF)) { host = q2t_find_host_by_vp_idx(vha, @@ -671,6 +683,7 @@ static void q2t_response_pkt_all_vps(scsi_qla_host_t *vha, response_t *pkt) ctio7_fw_entry_t *entry = (ctio7_fw_entry_t *)pkt; scsi_qla_host_t *host = q2t_find_host_by_vp_idx(vha, entry->vp_index); + if (unlikely(!host)) { PRINT_ERROR("qla2x00t(%ld): Response pkt (CTIO_TYPE7) " "received, with unknown vp_index %d", @@ -684,8 +697,10 @@ static void q2t_response_pkt_all_vps(scsi_qla_host_t *vha, response_t *pkt) case IMMED_NOTIFY_TYPE: { scsi_qla_host_t *host = vha; + if (IS_FWI2_CAPABLE(ha)) { notify24xx_entry_t *entry = (notify24xx_entry_t *)pkt; + host = q2t_find_host_by_vp_idx(vha, entry->vp_index); if (unlikely(!host)) { PRINT_ERROR("qla2x00t(%ld): Response pkt " @@ -702,9 +717,11 @@ static void q2t_response_pkt_all_vps(scsi_qla_host_t *vha, response_t *pkt) case NOTIFY_ACK_TYPE: { scsi_qla_host_t *host = vha; + if (IS_FWI2_CAPABLE(ha)) { nack24xx_entry_t *entry = (nack24xx_entry_t *)pkt; - if (0xFF != entry->vp_index) { + + if (entry->vp_index != 0xFF) { host = q2t_find_host_by_vp_idx(vha, entry->vp_index); if (unlikely(!host)) { @@ -726,6 +743,7 @@ static void q2t_response_pkt_all_vps(scsi_qla_host_t *vha, response_t *pkt) abts24_recv_entry_t *entry = (abts24_recv_entry_t *)pkt; scsi_qla_host_t *host = q2t_find_host_by_vp_idx(vha, entry->vp_index); + if (unlikely(!host)) { PRINT_ERROR("qla2x00t(%ld): Response pkt " "(ABTS_RECV_24XX) received, with unknown " @@ -741,6 +759,7 @@ static void q2t_response_pkt_all_vps(scsi_qla_host_t *vha, response_t *pkt) abts24_resp_entry_t *entry = (abts24_resp_entry_t *)pkt; scsi_qla_host_t *host = q2t_find_host_by_vp_idx(vha, entry->vp_index); + if (unlikely(!host)) { PRINT_ERROR("qla2x00t(%ld): Response pkt " "(ABTS_RECV_24XX) received, with unknown " @@ -882,6 +901,7 @@ static int q2t_reset(scsi_qla_host_t *vha, void *iocb, int mcmd) if (IS_FWI2_CAPABLE(ha)) { notify24xx_entry_t *n = (notify24xx_entry_t *)iocb; + if ((le16_to_cpu(n->status) == IMM_NTFY_ELS) && ((n->status_subcode == ELS_TPRLO) || (n->status_subcode == ELS_LOGO))) { @@ -1154,6 +1174,7 @@ retry: res = -1; for (i = 0; i < entries; i++) { struct gid_list_info *gid = (struct gid_list_info *)id_iter; + if ((gid->al_pa == s_id[2]) && (gid->area == s_id[1]) && (gid->domain == s_id[0])) { @@ -2053,6 +2074,7 @@ static int __q24_handle_abts(scsi_qla_host_t *vha, abts24_recv_entry_t *abts, */ while (!list_empty(&ha->unknown_atio_list)) { struct q2t_unknown_atio *u; + u = list_first_entry(&ha->unknown_atio_list, struct q2t_unknown_atio, unknown_atio_list_entry); TRACE_MGMT_DBG("qla2x00t(%ld): Clearing unknown " @@ -3304,6 +3326,7 @@ static int __q2t_rdy_to_xfer(struct q2t_cmd *cmd) if (IS_FWI2_CAPABLE(ha)) { ctio7_status0_entry_t *pkt; + res = q24_build_ctio_pkt(&prm); if (unlikely(res != SCST_TGT_RES_SUCCESS)) goto out_unlock_free_unmap; @@ -3314,6 +3337,7 @@ static int __q2t_rdy_to_xfer(struct q2t_cmd *cmd) p = pkt; } else { ctio_common_entry_t *pkt; + q2x_build_ctio_pkt(&prm); pkt = (ctio_common_entry_t *)prm.pkt; pkt->flags = cpu_to_le16(OF_FAST_POST | OF_DATA_OUT); @@ -3573,6 +3597,7 @@ static int q2t_prepare_srr_ctio(scsi_qla_host_t *vha, struct q2t_cmd *cmd, sc, sc->srr_id); if (tgt->imm_srr_id == tgt->ctio_srr_id) { int found = 0; + list_for_each_entry(imm, &tgt->srr_imm_list, srr_list_entry) { if (imm->srr_id == sc->srr_id) { @@ -3600,6 +3625,7 @@ static int q2t_prepare_srr_ctio(scsi_qla_host_t *vha, struct q2t_cmd *cmd, spin_unlock(&tgt->srr_lock); } else { struct srr_imm *ti; + PRINT_ERROR("qla2x00t(%ld): Unable to allocate SRR CTIO entry", vha->host_no); spin_lock(&tgt->srr_lock); @@ -3643,6 +3669,7 @@ static bool q2t_term_ctio_exchange(scsi_qla_host_t *vha, void *ctio, } if (ctio != NULL) { ctio7_fw_entry_t *c = (ctio7_fw_entry_t *)ctio; + term = !(c->flags & cpu_to_le16(OF_TERM_EXCH)); } else term = true; @@ -3654,6 +3681,7 @@ static bool q2t_term_ctio_exchange(scsi_qla_host_t *vha, void *ctio, #if 0 /* Seems, it isn't needed. If enable it, add support for NULL cmd! */ if (ctio != NULL) { ctio_common_entry_t *c = (ctio_common_entry_t *)ctio; + term = !(c->flags & cpu_to_le16(CTIO7_FLAGS_TERMINATE)); } else term = true; @@ -3673,6 +3701,7 @@ static inline struct q2t_cmd *q2t_get_cmd(scsi_qla_host_t *vha, uint32_t handle) handle--; if (vha->cmds[handle] != NULL) { struct q2t_cmd *cmd = vha->cmds[handle]; + vha->cmds[handle] = NULL; return cmd; } else @@ -3728,6 +3757,7 @@ static struct q2t_cmd *q2t_ctio_to_cmd(scsi_qla_host_t *vha, uint32_t handle, goto out; } else { ctio_common_entry_t *c = (ctio_common_entry_t *)ctio; + loop_id = GET_TARGET_ID(ha, c); tag = c->rx_id; } @@ -4103,6 +4133,7 @@ static int q2t_send_cmd_to_scst(scsi_qla_host_t *vha, atio_t *atio) if (IS_FWI2_CAPABLE(ha)) { atio7_entry_t *a = (atio7_entry_t *)atio; + sess = q2t_find_sess_by_s_id(tgt, a->fcp_hdr.s_id); if (unlikely(sess == NULL)) { TRACE_MGMT_DBG("qla2x00t(%ld): Unable to find " @@ -4166,6 +4197,7 @@ static int q2t_issue_task_mgmt(struct q2t_sess *sess, uint8_t *lun, */ while (!list_empty(&ha->unknown_atio_list)) { struct q2t_unknown_atio *u; + u = list_first_entry(&ha->unknown_atio_list, struct q2t_unknown_atio, unknown_atio_list_entry); TRACE_MGMT_DBG("qla2x00t(%ld): Clearing unknown " @@ -4300,12 +4332,14 @@ static int q2t_handle_task_mgmt(scsi_qla_host_t *vha, void *iocb) tgt = vha->tgt; if (IS_FWI2_CAPABLE(ha)) { atio7_entry_t *a = (atio7_entry_t *)iocb; + lun = (uint8_t *)&a->fcp_cmnd.lun; lun_size = sizeof(a->fcp_cmnd.lun); fn = a->fcp_cmnd.task_mgmt_flags; sess = q2t_find_sess_by_s_id(tgt, a->fcp_hdr.s_id); } else { notify_entry_t *n = (notify_entry_t *)iocb; + /* make it be in network byte order */ lun_data = swab16(le16_to_cpu(n->lun)); lun = (uint8_t *)&lun_data; @@ -4468,6 +4502,7 @@ static int q24_handle_els(scsi_qla_host_t *vha, notify24xx_entry_t *iocb) case ELS_ADISC: { struct q2t_tgt *tgt = vha->tgt; + if (tgt->link_reinit_iocb_pending) { q24_send_notify_ack(vha, &tgt->link_reinit_iocb, 0, 0, 0); tgt->link_reinit_iocb_pending = 0; @@ -4506,6 +4541,7 @@ static int q2t_cut_cmd_data_head(struct q2t_cmd *cmd, unsigned int offset) l += cmd->sg[i].length; if (l > offset) { int sg_offs = l - cmd->sg[i].length; + first_sg = i; if (cmd->sg[i].offset == 0) { first_page_offs = offset % PAGE_SIZE; @@ -4541,7 +4577,7 @@ static int q2t_cut_cmd_data_head(struct q2t_cmd *cmd, unsigned int offset) first_sg, first_page, first_page_offs, cmd->bufflen, cmd->sg_cnt); - sg = kmalloc(cnt * sizeof(sg[0]), GFP_KERNEL); + sg = kmalloc_array(cnt, sizeof(sg[0]), GFP_KERNEL); if (sg == NULL) { PRINT_ERROR("qla2x00t(%ld): Unable to allocate cut " "SG (len %zd)", cmd->tgt->vha->host_no, @@ -4555,6 +4591,7 @@ static int q2t_cut_cmd_data_head(struct q2t_cmd *cmd, unsigned int offset) cur_src = first_sg; if (first_page_offs != 0) { int fpgs; + sg_set_page(&sg[cur_dst], &sg_page(&cmd->sg[cur_src])[first_page], PAGE_SIZE - first_page_offs, first_page_offs); bufflen += sg[cur_dst].length; @@ -4657,6 +4694,7 @@ static void q24_handle_srr(scsi_qla_host_t *vha, struct srr_ctio *sctio, (scst_cmd_get_data_direction(&cmd->scst_cmd) & SCST_DATA_READ)) { uint32_t offset; int xmit_type; + offset = le32_to_cpu(imm->imm.notify_entry24.srr_rel_offs); if (q2t_srr_adjust_data(cmd, offset, &xmit_type) != 0) goto out_reject; @@ -4681,6 +4719,7 @@ static void q24_handle_srr(scsi_qla_host_t *vha, struct srr_ctio *sctio, (scst_cmd_get_data_direction(&cmd->scst_cmd) & SCST_DATA_WRITE)) { uint32_t offset; int xmit_type; + offset = le32_to_cpu(imm->imm.notify_entry24.srr_rel_offs); if (q2t_srr_adjust_data(cmd, offset, &xmit_type) != 0) goto out_reject; @@ -4751,6 +4790,7 @@ static void q2x_handle_srr(scsi_qla_host_t *vha, struct srr_ctio *sctio, if (q2t_has_data(cmd)) { uint32_t offset; int xmit_type; + offset = le32_to_cpu(imm->imm.notify_entry.srr_rel_offs); if (q2t_srr_adjust_data(cmd, offset, &xmit_type) != 0) goto out_reject; @@ -4773,6 +4813,7 @@ static void q2x_handle_srr(scsi_qla_host_t *vha, struct srr_ctio *sctio, if (q2t_has_data(cmd)) { uint32_t offset; int xmit_type; + offset = le32_to_cpu(imm->imm.notify_entry.srr_rel_offs); if (q2t_srr_adjust_data(cmd, offset, &xmit_type) != 0) goto out_reject; @@ -4949,6 +4990,7 @@ static void q2t_prepare_srr_imm(scsi_qla_host_t *vha, void *iocb) imm->srr_id, iocb24->srr_ui); if (tgt->imm_srr_id == tgt->ctio_srr_id) { int found = 0; + list_for_each_entry(sctio, &tgt->srr_ctio_list, srr_list_entry) { if (sctio->srr_id == imm->srr_id) { @@ -5064,6 +5106,7 @@ static void q2t_handle_imm_notify(scsi_qla_host_t *vha, void *iocb) case IMM_NTFY_LIP_LINK_REINIT: { struct q2t_tgt *tgt = vha->tgt; + TRACE(TRACE_MGMT, "qla2x00t(%ld): LINK REINIT (loop %#x, " "subcode %x)", vha->host_no, le16_to_cpu(iocb24->nport_handle), @@ -5359,6 +5402,7 @@ static void q24_atio_pkt(scsi_qla_host_t *vha, atio7_entry_t *atio) case IMMED_NOTIFY_TYPE: { notify_entry_t *pkt = (notify_entry_t *)atio; + if (unlikely(pkt->entry_status != 0)) { PRINT_ERROR("qla2x00t(%ld): Received ATIO packet %x " "with error status %x", vha->host_no, @@ -5426,6 +5470,7 @@ static void q2t_response_pkt(scsi_qla_host_t *vha, response_t *pkt) case CTIO_TYPE7: { ctio7_fw_entry_t *entry = (ctio7_fw_entry_t *)pkt; + TRACE_DBG("CTIO_TYPE7: instance %ld", vha->host_no); TRACE_BUFFER("Incoming CTIO7 packet data", entry, @@ -5440,6 +5485,7 @@ static void q2t_response_pkt(scsi_qla_host_t *vha, response_t *pkt) { atio_entry_t *atio; int rc; + atio = (atio_entry_t *)pkt; TRACE_DBG("ACCEPT_TGT_IO instance %ld status %04x " "lun %04x read/write %d data_length %04x " @@ -5481,6 +5527,7 @@ static void q2t_response_pkt(scsi_qla_host_t *vha, response_t *pkt) case CONTINUE_TGT_IO_TYPE: { ctio_common_entry_t *entry = (ctio_common_entry_t *)pkt; + TRACE_DBG("CONTINUE_TGT_IO: instance %ld", vha->host_no); TRACE_BUFFER("Incoming CTIO packet data", entry, REQUEST_ENTRY_SIZE); @@ -5493,6 +5540,7 @@ static void q2t_response_pkt(scsi_qla_host_t *vha, response_t *pkt) case CTIO_A64_TYPE: { ctio_common_entry_t *entry = (ctio_common_entry_t *)pkt; + TRACE_DBG("CTIO_A64: instance %ld", vha->host_no); TRACE_BUFFER("Incoming CTIO_A64 packet data", entry, REQUEST_ENTRY_SIZE); @@ -5510,6 +5558,7 @@ static void q2t_response_pkt(scsi_qla_host_t *vha, response_t *pkt) case NOTIFY_ACK_TYPE: if (tgt->notify_ack_expected > 0) { nack_entry_t *entry = (nack_entry_t *)pkt; + TRACE_DBG("NOTIFY_ACK seq %08x status %x", le16_to_cpu(entry->seq_id), le16_to_cpu(entry->status)); @@ -5538,6 +5587,7 @@ static void q2t_response_pkt(scsi_qla_host_t *vha, response_t *pkt) if (tgt->abts_resp_expected > 0) { abts24_resp_fw_entry_t *entry = (abts24_resp_fw_entry_t *)pkt; + TRACE_DBG("ABTS_RESP_24XX: compl_status %x", entry->compl_status); TRACE_BUFF_FLAG(TRACE_BUFF, "Incoming ABTS_RESP " @@ -5574,6 +5624,7 @@ static void q2t_response_pkt(scsi_qla_host_t *vha, response_t *pkt) case MODIFY_LUN_TYPE: if (tgt->modify_lun_expected > 0) { modify_lun_entry_t *entry = (modify_lun_entry_t *)pkt; + TRACE_DBG("MODIFY_LUN %x, imm %c%d, cmd %c%d", entry->status, (entry->operators & MODIFY_LUN_IMM_ADD) ? '+' @@ -5599,6 +5650,7 @@ static void q2t_response_pkt(scsi_qla_host_t *vha, response_t *pkt) case ENABLE_LUN_TYPE: { elun_entry_t *entry = (elun_entry_t *)pkt; + TRACE_DBG("ENABLE_LUN %x imm %u cmd %u ", entry->status, entry->immed_notify_count, entry->command_count); @@ -5835,8 +5887,10 @@ static void q2t_exec_sess_work(struct q2t_tgt *tgt, case Q2T_SESS_WORK_CMD: { struct q2t_cmd *cmd = prm->cmd; + if (IS_FWI2_CAPABLE(ha)) { atio7_entry_t *a = (atio7_entry_t *)&cmd->atio; + s_id = a->fcp_hdr.s_id; } else loop_id = GET_TARGET_ID(ha, (atio_entry_t *)&cmd->atio); @@ -5896,6 +5950,7 @@ send: case Q2T_SESS_WORK_CMD: { struct q2t_cmd *cmd = prm->cmd; + if (tgt->tm_to_unknown) { /* * Cmd might be already aborted behind us, so be safe @@ -5923,12 +5978,14 @@ send: if (IS_FWI2_CAPABLE(ha)) { atio7_entry_t *a = &prm->tm_iocb2; + iocb = a; lun = (uint8_t *)&a->fcp_cmnd.lun; lun_size = sizeof(a->fcp_cmnd.lun); fn = a->fcp_cmnd.task_mgmt_flags; } else { notify_entry_t *n = &prm->tm_iocb; + iocb = n; /* make it be in network byte order */ lun_data = swab16(le16_to_cpu(n->lun)); @@ -5962,6 +6019,7 @@ out_term: case Q2T_SESS_WORK_CMD: { struct q2t_cmd *cmd = prm->cmd; + TRACE_MGMT_DBG("Terminating work cmd %p", cmd); /* * cmd has not sent to SCST yet, so pass NULL as the second @@ -6195,8 +6253,10 @@ static int q2t_add_target(scsi_qla_host_t *vha) scst_get_tgt_name(tgt->scst_tgt)); if (vha->vp_idx == 0) { int i = 0; + while (1) { const struct attribute *a = q2t_hw_tgt_attrs[i]; + if (a == NULL) break; rc = sysfs_create_file(scst_sysfs_get_tgt_kobj(tgt->scst_tgt), a); @@ -6209,8 +6269,10 @@ static int q2t_add_target(scsi_qla_host_t *vha) } } else { int i = 0; + while (1) { const struct attribute *a = q2t_npiv_tgt_attrs[i]; + if (a == NULL) break; rc = sysfs_create_file(scst_sysfs_get_tgt_kobj(tgt->scst_tgt), a); diff --git a/qla2x00t/qla2x_tgt.h b/qla2x00t/qla2x_tgt.h index 4ce125311..3ceb76b6c 100644 --- a/qla2x00t/qla2x_tgt.h +++ b/qla2x00t/qla2x_tgt.h @@ -124,6 +124,7 @@ qla2x00_send_enable_lun(scsi_qla_host_t *vha, bool enable) if (!IS_FWI2_CAPABLE(ha)) { unsigned long flags; + spin_lock_irqsave(&ha->hardware_lock, flags); __qla2x00_send_enable_lun(vha, enable); spin_unlock_irqrestore(&ha->hardware_lock, flags); @@ -139,7 +140,7 @@ extern size_t qla2xxx_del_vtarget(u64 port_name); #endif /*((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)) || \ defined(FC_VPORT_CREATE_DEFINED))*/ -extern void qla_unknown_atio_work_fn(struct delayed_work *work); +extern void qla_unknown_atio_work_fn(struct work_struct *work); #else /* CONFIG_SCSI_QLA2XXX_TARGET */ @@ -159,6 +160,7 @@ static inline bool qla_firmware_active(scsi_qla_host_t *vha) { struct qla_hw_data *ha = vha->hw; struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); + return qla_tgt_mode_enabled(base_vha) || qla_ini_mode_enabled(base_vha); } diff --git a/qla2x00t/qla2x_tgt_def.h b/qla2x00t/qla2x_tgt_def.h index 0957ecb31..d96d6f1b5 100644 --- a/qla2x00t/qla2x_tgt_def.h +++ b/qla2x00t/qla2x_tgt_def.h @@ -148,7 +148,7 @@ typedef struct { uint16_t reserved_5; uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ uint16_t reserved_6[20]; -} __attribute__((packed)) elun_entry_t; +} __packed elun_entry_t; #define ENABLE_LUN_SUCCESS 0x01 #define ENABLE_LUN_RC_NONZERO 0x04 #define ENABLE_LUN_INVALID_REQUEST 0x06 @@ -179,7 +179,7 @@ typedef struct { uint16_t reserved_5; uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ uint16_t reserved_7[20]; -} __attribute__((packed)) modify_lun_entry_t; +} __packed modify_lun_entry_t; #define MODIFY_LUN_SUCCESS 0x01 #define MODIFY_LUN_CMD_ADD BIT_0 #define MODIFY_LUN_CMD_SUB BIT_1 @@ -219,7 +219,7 @@ typedef struct { uint16_t srr_ox_id; uint8_t reserved_2[30]; uint16_t ox_id; -} __attribute__((packed)) notify_entry_t; +} __packed notify_entry_t; #endif #ifndef NOTIFY_ACK_TYPE @@ -250,7 +250,7 @@ typedef struct { uint8_t srr_reject_code_expl; uint8_t reserved_2[26]; uint16_t ox_id; -} __attribute__((packed)) nack_entry_t; +} __packed nack_entry_t; #define NOTIFY_ACK_SRR_FLAGS_ACCEPT 0 #define NOTIFY_ACK_SRR_FLAGS_REJECT 1 @@ -287,7 +287,7 @@ typedef struct { uint8_t initiator_port_name[WWN_SIZE]; /* on qla23xx */ uint16_t reserved_32[6]; uint16_t ox_id; -} __attribute__((packed)) atio_entry_t; +} __packed atio_entry_t; #endif #ifndef CONTINUE_TGT_IO_TYPE @@ -314,7 +314,7 @@ typedef struct { uint16_t scsi_status; uint32_t transfer_length; uint32_t dseg_0_address[0]; -} __attribute__((packed)) ctio_common_entry_t; +} __packed ctio_common_entry_t; #define ATIO_PATH_INVALID 0x07 #define ATIO_CANT_PROV_CAP 0x16 #define ATIO_CDB_VALID 0x3D @@ -333,7 +333,7 @@ typedef struct { uint32_t dseg_1_length; /* Data segment 1 length. */ uint32_t dseg_2_address; /* Data segment 2 address. */ uint32_t dseg_2_length; /* Data segment 2 length. */ -} __attribute__((packed)) ctio_entry_t; +} __packed ctio_entry_t; #define CTIO_SUCCESS 0x01 #define CTIO_ABORTED 0x02 #define CTIO_INVALID_RX_ID 0x08 @@ -371,7 +371,7 @@ typedef struct { uint16_t scsi_status; uint16_t response_length; uint8_t sense_data[26]; -} __attribute__((packed)) ctio_ret_entry_t; +} __packed ctio_ret_entry_t; #endif #define ATIO_TYPE7 0x06 /* Accept target I/O entry for 24xx */ @@ -389,7 +389,7 @@ typedef struct { uint16_t ox_id; uint16_t rx_id; uint32_t parameter; -} __attribute__((packed)) fcp_hdr_t; +} __packed fcp_hdr_t; typedef struct { uint8_t d_id[3]; @@ -404,7 +404,7 @@ typedef struct { uint16_t rx_id; uint16_t ox_id; uint32_t parameter; -} __attribute__((packed)) fcp_hdr_le_t; +} __packed fcp_hdr_le_t; #define F_CTL_EXCH_CONTEXT_RESP BIT_23 #define F_CTL_SEQ_CONTEXT_RESIP BIT_22 @@ -449,7 +449,7 @@ typedef struct { */ uint8_t add_cdb[4]; /* uint32_t data_length; */ -} __attribute__((packed)) fcp_cmnd_t; +} __packed fcp_cmnd_t; /* * ISP queue - Accept Target I/O (ATIO) type 7 entry for 24xx structure @@ -470,7 +470,7 @@ typedef struct { #define ATIO_EXCHANGE_ADDRESS_UNKNOWN 0xFFFFFFFF fcp_hdr_t fcp_hdr; fcp_cmnd_t fcp_cmnd; -} __attribute__((packed)) atio7_entry_t; +} __packed atio7_entry_t; #define CTIO_TYPE7 0x12 /* Continue target I/O entry (for 24xx) */ @@ -494,7 +494,7 @@ typedef struct { uint8_t initiator_id[3]; uint8_t reserved; uint32_t exchange_addr; -} __attribute__((packed)) ctio7_common_entry_t; +} __packed ctio7_common_entry_t; typedef struct { ctio7_common_entry_t common; @@ -509,7 +509,7 @@ typedef struct { uint32_t reserved3; uint32_t dseg_0_address[2]; /* Data segment 0 address. */ uint32_t dseg_0_length; /* Data segment 0 length. */ -} __attribute__((packed)) ctio7_status0_entry_t; +} __packed ctio7_status0_entry_t; typedef struct { ctio7_common_entry_t common; @@ -521,7 +521,7 @@ typedef struct { uint16_t response_len; uint16_t reserved; uint8_t sense_data[24]; -} __attribute__((packed)) ctio7_status1_entry_t; +} __packed ctio7_status1_entry_t; typedef struct { uint8_t entry_type; /* Entry type. */ @@ -542,7 +542,7 @@ typedef struct { uint16_t reserved3; uint32_t relative_offset; uint8_t reserved4[24]; -} __attribute__((packed)) ctio7_fw_entry_t; +} __packed ctio7_fw_entry_t; /* CTIO7 flags values */ #define CTIO7_FLAGS_SEND_STATUS BIT_15 @@ -589,7 +589,7 @@ typedef struct { uint8_t reserved_7; uint16_t reserved_8; uint16_t ox_id; -} __attribute__((packed)) notify24xx_entry_t; +} __packed notify24xx_entry_t; #define ELS_PLOGI 0x3 #define ELS_FLOGI 0x4 @@ -627,7 +627,7 @@ typedef struct { uint8_t srr_reject_code; uint8_t reserved_5[7]; uint16_t ox_id; -} __attribute__((packed)) nack24xx_entry_t; +} __packed nack24xx_entry_t; /* * ISP queue - ABTS received/response entries structure definition for 24xx. @@ -655,7 +655,7 @@ typedef struct { fcp_hdr_le_t fcp_hdr_le; uint8_t reserved_4[16]; uint32_t exchange_addr_to_abort; -} __attribute__((packed)) abts24_recv_entry_t; +} __packed abts24_recv_entry_t; #define ABTS_PARAM_ABORT_SEQ BIT_0 @@ -669,7 +669,7 @@ typedef struct { uint16_t ox_id; uint16_t high_seq_cnt; uint16_t low_seq_cnt; -} __attribute__((packed)) ba_acc_le_t; +} __packed ba_acc_le_t; typedef struct { uint8_t vendor_uniq; @@ -678,7 +678,7 @@ typedef struct { #define BA_RJT_REASON_CODE_INVALID_COMMAND 0x1 #define BA_RJT_REASON_CODE_UNABLE_TO_PERFORM 0x9 uint8_t reserved; -} __attribute__((packed)) ba_rjt_le_t; +} __packed ba_rjt_le_t; typedef struct { uint8_t entry_type; /* Entry type. */ @@ -703,10 +703,10 @@ typedef struct { union { ba_acc_le_t ba_acct; ba_rjt_le_t ba_rjt; - } __attribute__((packed)) payload; + } __packed payload; uint32_t reserved_4; uint32_t exchange_addr_to_abort; -} __attribute__((packed)) abts24_resp_entry_t; +} __packed abts24_resp_entry_t; typedef struct { uint8_t entry_type; /* Entry type. */ @@ -734,7 +734,7 @@ typedef struct { #define ABTS_RESP_SUBCODE_ERR_ABORTED_EXCH_NOT_TERM 0x1E uint32_t error_subcode2; uint32_t exchange_addr_to_abort; -} __attribute__((packed)) abts24_resp_fw_entry_t; +} __packed abts24_resp_fw_entry_t; /********************************************************************\ * Type Definitions used by initiator & target halves diff --git a/qla2x00t/qla_bsg.c b/qla2x00t/qla_bsg.c index 1b5922dfc..8d9b8244b 100644 --- a/qla2x00t/qla_bsg.c +++ b/qla2x00t/qla_bsg.c @@ -1594,7 +1594,7 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job) default: bsg_job->reply->result = (DID_ERROR << 16); bsg_job->job_done(bsg_job); - return -ENOSYS; + return -ENOTSUPP; } } diff --git a/qla2x00t/qla_bsg.h b/qla2x00t/qla_bsg.h index 70caa63a8..1128cf0d1 100644 --- a/qla2x00t/qla_bsg.h +++ b/qla2x00t/qla_bsg.h @@ -126,12 +126,12 @@ struct qla84_msg_mgmt { struct qla_bsg_a84_mgmt { struct qla84_msg_mgmt mgmt; -} __attribute__ ((packed)); +} __packed; struct qla_scsi_addr { uint16_t bus; uint16_t target; -} __attribute__ ((packed)); +} __packed; struct qla_ext_dest_addr { union { @@ -144,13 +144,13 @@ struct qla_ext_dest_addr { #define EXT_DEF_TYPE_WWPN 2 uint16_t lun; uint16_t padding[2]; -} __attribute__ ((packed)); +} __packed; struct qla_port_param { struct qla_ext_dest_addr fc_scsi_addr; uint16_t mode; uint16_t speed; -} __attribute__ ((packed)); +} __packed; /* FRU VPD */ diff --git a/qla2x00t/qla_def.h b/qla2x00t/qla_def.h index 3f2dcb32d..83944e879 100644 --- a/qla2x00t/qla_def.h +++ b/qla2x00t/qla_def.h @@ -361,7 +361,7 @@ struct device_reg_2xxx { uint16_t mailbox6; uint16_t mailbox7; uint16_t unused_2[59]; /* Gap */ - } __attribute__((packed)) isp2100; + } __packed isp2100; struct { /* Request Queue */ uint16_t req_q_in; /* In-Pointer */ @@ -412,7 +412,7 @@ struct device_reg_2xxx { uint16_t mailbox31; uint16_t fb_cmd; uint16_t unused_4[10]; /* Gap */ - } __attribute__((packed)) isp2300; + } __packed isp2300; } u; uint16_t fpm_diag_config; @@ -469,7 +469,7 @@ struct device_reg_2xxx { uint16_t mailbox21; uint16_t mailbox22; uint16_t mailbox23; /* Also probe reg. */ - } __attribute__((packed)) isp2200; + } __packed isp2200; } u_end; }; diff --git a/qla2x00t/qla_isr.c b/qla2x00t/qla_isr.c index 8e3652d2a..5f2923dbe 100644 --- a/qla2x00t/qla_isr.c +++ b/qla2x00t/qla_isr.c @@ -2632,8 +2632,8 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) struct qla_msix_entry *qentry; scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); - entries = kzalloc(sizeof(struct msix_entry) * ha->msix_count, - GFP_KERNEL); + entries = kcalloc(ha->msix_count, sizeof(struct msix_entry), + GFP_KERNEL); if (!entries) { ql_log(ql_log_warn, vha, 0x00bc, "Failed to allocate memory for msix_entry.\n"); @@ -2664,8 +2664,8 @@ msix_failed: } ha->max_rsp_queues = ha->msix_count - 1; } - ha->msix_entries = kzalloc(sizeof(struct qla_msix_entry) * - ha->msix_count, GFP_KERNEL); + ha->msix_entries = kcalloc(ha->msix_count, + sizeof(struct qla_msix_entry), GFP_KERNEL); if (!ha->msix_entries) { ql_log(ql_log_fatal, vha, 0x00c8, "Failed to allocate memory for ha->msix_entries.\n"); diff --git a/qla2x00t/qla_nx.c b/qla2x00t/qla_nx.c index f5b5d837e..db309bd6a 100644 --- a/qla2x00t/qla_nx.c +++ b/qla2x00t/qla_nx.c @@ -1222,7 +1222,11 @@ qla82xx_pinit_from_rom(scsi_qla_host_t *vha) ql_log(ql_log_info, vha, 0x0072, "%d CRB init values found in ROM.\n", n); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) + buf = kmalloc_array(n, sizeof(struct crb_addr_pair), GFP_KERNEL); +#else buf = kmalloc(n * sizeof(struct crb_addr_pair), GFP_KERNEL); +#endif if (buf == NULL) { ql_log(ql_log_fatal, vha, 0x010c, "Unable to allocate memory.\n"); diff --git a/qla2x00t/qla_os.c b/qla2x00t/qla_os.c index 401778dcf..bbaad3885 100644 --- a/qla2x00t/qla_os.c +++ b/qla2x00t/qla_os.c @@ -367,7 +367,7 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req, struct rsp_que *rsp) { scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); - ha->req_q_map = kzalloc(sizeof(struct req_que *) * ha->max_req_queues, + ha->req_q_map = kcalloc(ha->max_req_queues, sizeof(struct req_que *), GFP_KERNEL); if (!ha->req_q_map) { ql_log(ql_log_fatal, vha, 0x003b, @@ -375,7 +375,7 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req, goto fail_req_map; } - ha->rsp_q_map = kzalloc(sizeof(struct rsp_que *) * ha->max_rsp_queues, + ha->rsp_q_map = kcalloc(ha->max_rsp_queues, sizeof(struct rsp_que *), GFP_KERNEL); if (!ha->rsp_q_map) { ql_log(ql_log_fatal, vha, 0x003c, @@ -2386,10 +2386,10 @@ EXPORT_SYMBOL(qla2xxx_del_vtarget); #endif /*((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)) || \ defined(FC_VPORT_CREATE_DEFINED))*/ -void qla_unknown_atio_work_fn(struct delayed_work *work) +void qla_unknown_atio_work_fn(struct work_struct *work) { struct qla_hw_data *ha = container_of(work, struct qla_hw_data, - unknown_atio_work); + unknown_atio_work.work); qla_target.tgt_try_to_dequeue_unknown_atios(ha); return; } @@ -2661,8 +2661,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) mutex_init(&base_vha->tgt_mutex); mutex_init(&base_vha->tgt_host_action_mutex); INIT_LIST_HEAD(&ha->unknown_atio_list); - INIT_DELAYED_WORK(&ha->unknown_atio_work, - (void (*)(struct work_struct *))qla_unknown_atio_work_fn); + INIT_DELAYED_WORK(&ha->unknown_atio_work, qla_unknown_atio_work_fn); qla_clear_tgt_mode(base_vha); #endif /* CONFIG_SCSI_QLA2XXX_TARGET */ @@ -3286,8 +3285,9 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, #ifdef CONFIG_SCSI_QLA2XXX_TARGET if (IS_FWI2_CAPABLE(ha)) { - ha->tgt_vp_map = kzalloc(sizeof(struct qla_tgt_vp_map) * - MAX_MULTI_ID_FABRIC, GFP_KERNEL); + ha->tgt_vp_map = kcalloc(MAX_MULTI_ID_FABRIC, + sizeof(struct qla_tgt_vp_map), + GFP_KERNEL); if (!ha->tgt_vp_map) goto fail_free_init_cb; @@ -3433,8 +3433,9 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, (*rsp)->ring); /* Allocate memory for NVRAM data for vports */ if (ha->nvram_npiv_size) { - ha->npiv_info = kzalloc(sizeof(struct qla_npiv_entry) * - ha->nvram_npiv_size, GFP_KERNEL); + ha->npiv_info = kcalloc(ha->nvram_npiv_size, + sizeof(struct qla_npiv_entry), + GFP_KERNEL); if (!ha->npiv_info) { ql_log_pci(ql_log_fatal, ha->pdev, 0x002d, "Failed to allocate memory for npiv_info.\n"); diff --git a/scripts/generate-kernel-patch b/scripts/generate-kernel-patch index af2f3a825..8f8692fff 100755 --- a/scripts/generate-kernel-patch +++ b/scripts/generate-kernel-patch @@ -302,8 +302,11 @@ do done -scst_03_public_headers="scst/include/scst.h scst/include/scst_const.h scst/include/backport.h" -scst_04_main="scst/src/scst_main.c scst/src/scst_module.c scst/src/scst_priv.h" +scst_03_public_headers="scst/include/scst.h scst/include/scst_const.h \ +scst/include/scst_event.h scst/include/backport.h" +scst_04_main="scst/src/scst_main.c scst/src/scst_module.c scst/src/scst_priv.h \ +scst/src/scst_copy_mgr.c scst/src/scst_dlm.c scst/src/scst_dlm.h \ +scst/src/scst_event.c scst/src/scst_no_dlm.c" scst_05_targ="scst/src/scst_targ.c" scst_06_lib="scst/src/scst_lib.c" scst_07_pres="scst/src/scst_pres.h scst/src/scst_pres.c" diff --git a/scst.spec.in b/scst.spec.in index b6b528f7b..e7138ceef 100644 --- a/scst.spec.in +++ b/scst.spec.in @@ -8,7 +8,8 @@ # version number when building on a koji build server. # - Otherwise use the version number of the running kernel. %{!?kversion: - %{?kdir:%define kversion %{expand:%%(make -sC %{kdir} kernelversion)}} + %{?kdir:%define kversion %{expand:%%( + make -sC "%{kdir}" kernelversion | grep -v ^make)}} %{!?kdir: %define kversion %{expand:%%( if rpm --quiet -q kernel-headers; then @@ -200,6 +201,10 @@ rm -rf /usr/local/include/scst /usr/include/scst/scst_user.h %changelog +* Wed May 6 2015 Bart Van Assche +- Build in release mode instead of debug mode. +* Mon May 4 2015 Bart Van Assche +- Added iSER target driver. * Mon Feb 23 2015 Bart Van Assche - Split spec file into a non-DKMS and a DKMS spec file. * Fri Jan 16 2015 Bart Van Assche diff --git a/scst/README b/scst/README index 8779958e6..aba51c655 100644 --- a/scst/README +++ b/scst/README @@ -30,7 +30,7 @@ SCST supports the following I/O modes: * User space mode using scst_user device handler, which allows to implement in the user space high performance virtual SCSI devices. Comparing with fully in-kernel dev handlers this mode has - very low overhead (few %%) + very low overhead (few %%). * "Performance" device handlers, which provide in pseudo pass-through mode a way for direct performance measurements without overhead of @@ -1881,7 +1881,7 @@ backend storage, which supposed to be nearly instantaneous. To use this feature, a dev handler should setup ext_copy_remap() callback in its struct scst_dev_type. This callback is called by SCST -during EXTENDED COPY command processing to let the dev hander try to +during EXTENDED COPY command processing to let the dev handler try to remap affected blocks at first. Upon finish, the dev handler should call scst_ext_copy_remap_done(). In diff --git a/scst/README_in-tree b/scst/README_in-tree index 4a1e010a1..91d0b6ca6 100644 --- a/scst/README_in-tree +++ b/scst/README_in-tree @@ -24,6 +24,11 @@ SCST supports the following I/O modes: caching between application and disk or need the large block throughput. + * User space mode using scst_user device handler, which allows to + implement in the user space high performance virtual SCSI + devices. Comparing with fully in-kernel dev handlers this mode has + very low overhead (few %%). + * "Performance" device handlers, which provide in pseudo pass-through mode a way for direct performance measurements without overhead of actual data transferring from/to underlying SCSI device. @@ -1729,7 +1734,7 @@ backend storage, which supposed to be nearly instantaneous. To use this feature, a dev handler should setup ext_copy_remap() callback in its struct scst_dev_type. This callback is called by SCST -during EXTENDED COPY command processing to let the dev hander try to +during EXTENDED COPY command processing to let the dev handler try to remap affected blocks at first. Upon finish, the dev handler should call scst_ext_copy_remap_done(). In diff --git a/scst/include/backport.h b/scst/include/backport.h index d8ce44ef3..8bb4f4bfb 100644 --- a/scst/include/backport.h +++ b/scst/include/backport.h @@ -187,6 +187,15 @@ static inline bool cpumask_equal(const cpumask_t *src1p, } #endif +/* */ + +/* See also commit 0f8e0d9a317406612700426fad3efab0b7bbc467 */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28) +enum { + DLM_LSFL_NEWEXCL = 0 +}; +#endif + /* */ #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0) && \ @@ -255,6 +264,44 @@ static inline void hex2bin(u8 *dst, const char *src, size_t count) } #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39) && \ + LINUX_VERSION_CODE != KERNEL_VERSION(2, 6, 38) && \ + (!defined(RHEL_MAJOR) || RHEL_MAJOR -0 < 6) +static inline int __must_check kstrtoull(const char *s, unsigned int base, + unsigned long long *res) +{ + return strict_strtoull(s, base, res); +} + +static inline int __must_check kstrtoll(const char *s, unsigned int base, + long long *res) +{ + return strict_strtoll(s, base, res); +} + +static inline int __must_check kstrtoul(const char *s, unsigned int base, + unsigned long *res) +{ + return strict_strtoul(s, base, res); +} + +static inline int __must_check kstrtol(const char *s, unsigned int base, + long *res) +{ + return strict_strtol(s, base, res); +} +#endif + +/* */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) +enum umh_wait { + UMH_NO_WAIT = -1, /* don't wait at all */ + UMH_WAIT_EXEC = 0, /* wait for the exec, but not the process */ + UMH_WAIT_PROC = 1, /* wait for the process to complete */ +}; +#endif + /* */ #ifndef __list_for_each @@ -401,6 +448,18 @@ static inline void sg_set_page(struct scatterlist *sg, struct page *page, (__flags), NULL, NULL) #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0) && \ + !(LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 52) && \ + LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)) && \ + (!defined(RHEL_MAJOR) || RHEL_MAJOR -0 < 6) +static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags) +{ + if (size != 0 && n > ULONG_MAX / size) + return NULL; + return kmalloc(n * size, flags); +} +#endif + /* */ #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0) diff --git a/scst/include/scst.h b/scst/include/scst.h index aeaef440f..a88f6cce1 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -1428,7 +1428,7 @@ struct scst_dev_type { void (*on_free_cmd)(struct scst_cmd *cmd); /* - * Called during EXTENDED COPY command processing to let dev hander + * Called during EXTENDED COPY command processing to let dev handler * try to remap blocks at first. Upon finish, the dev handler supposed * to call scst_ext_copy_remap_done(). See description of this * function for more details. @@ -1971,7 +1971,11 @@ struct scst_session { */ struct list_head sess_cm_list_id_list; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) + struct work_struct sess_cm_list_id_cleanup_work; +#else struct delayed_work sess_cm_list_id_cleanup_work; +#endif /* sysfs release completion */ struct completion *sess_kobj_release_cmpl; @@ -2757,7 +2761,7 @@ struct scst_device { unsigned int dev_unregistering:1; /* - * Set if ext blocking is pending. It if just shortcut for + * Set if ext blocking is pending. It is just shortcut for * !list_empty(&dev->ext_blockers_list) to save a cache miss. */ unsigned int ext_blocking_pending:1; @@ -2915,9 +2919,11 @@ struct scst_device { int (*dev_dif_fn)(struct scst_cmd *cmd); __be16 dev_dif_static_app_tag; /* fixed APP TAG for all blocks in dev */ - __be32 dev_dif_static_app_ref_tag; /* fixed APP TAG part from REF - * TAG for all blocks in dev. - * Valid only with dif type 3 */ + /* + * Fixed APP TAG part from REF TAG for all blocks in dev. Valid only + * with dif type 3. + */ + __be32 dev_dif_static_app_ref_tag; /* Cache to optimize scst_parse_*protect() routines */ enum scst_dif_actions dev_dif_rd_actions; diff --git a/scst/include/scst_const.h b/scst/include/scst_const.h index 3d1ffaf12..22e585756 100644 --- a/scst/include/scst_const.h +++ b/scst/include/scst_const.h @@ -319,6 +319,7 @@ static inline int scst_sense_response_code(const uint8_t *sense) #define scst_sense_invalid_release ILLEGAL_REQUEST, 0x26, 4 #define scst_sense_too_many_target_descriptors ILLEGAL_REQUEST, 0x26, 6 #define scst_sense_unsupported_tgt_descr_type ILLEGAL_REQUEST, 0x26, 7 +#define scst_sense_too_many_segment_descriptors ILLEGAL_REQUEST, 0x26, 8 #define scst_sense_unsupported_seg_descr_type ILLEGAL_REQUEST, 0x26, 9 #define scst_sense_inline_data_length_exceeded ILLEGAL_REQUEST, 0x26, 0xB #define scst_sense_saving_params_unsup ILLEGAL_REQUEST, 0x39, 0 diff --git a/scst/include/scst_event.h b/scst/include/scst_event.h index c13f2b47f..a8c24269b 100644 --- a/scst/include/scst_event.h +++ b/scst/include/scst_event.h @@ -63,7 +63,11 @@ struct scst_event_entry { int *pqueued_events_cnt; union { struct work_struct scst_event_queue_work; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) + struct work_struct event_timeout_work; +#else struct delayed_work event_timeout_work; +#endif }; struct scst_event event; @@ -137,7 +141,7 @@ struct scst_event_tm_fn_received_payload { #define SCST_EVENT_STPG_USER_INVOKE 5 struct scst_event_stpg_descr { - uint16_t group_id; + uint16_t group_id; /* * Better to keep below fields as small as possible to fit * in single page as many descriptors as possible. diff --git a/scst/kernel/in-tree/Makefile.scst-2.6.23 b/scst/kernel/in-tree/Makefile.scst-2.6.23 index f801073af..09dc56ac9 100644 --- a/scst/kernel/in-tree/Makefile.scst-2.6.23 +++ b/scst/kernel/in-tree/Makefile.scst-2.6.23 @@ -1,14 +1,17 @@ -EXTRA_CFLAGS += -Iinclude/scst -Wno-unused-parameter +EXTRA_CFLAGS += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_proc.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/ iscsi-scst/ qla2xxx-target/ srpt/ \ - scst_local/ - + scst_local/ diff --git a/scst/kernel/in-tree/Makefile.scst-2.6.24 b/scst/kernel/in-tree/Makefile.scst-2.6.24 index e040252e4..7aacdd48e 100644 --- a/scst/kernel/in-tree/Makefile.scst-2.6.24 +++ b/scst/kernel/in-tree/Makefile.scst-2.6.24 @@ -1,14 +1,17 @@ -ccflags-y += -Iinclude/scst -Wno-unused-parameter +ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_proc.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/ iscsi-scst/ qla2xxx-target/ srpt/ \ scst_local/ - diff --git a/scst/kernel/in-tree/Makefile.scst-2.6.25 b/scst/kernel/in-tree/Makefile.scst-2.6.25 index e040252e4..7aacdd48e 100644 --- a/scst/kernel/in-tree/Makefile.scst-2.6.25 +++ b/scst/kernel/in-tree/Makefile.scst-2.6.25 @@ -1,14 +1,17 @@ -ccflags-y += -Iinclude/scst -Wno-unused-parameter +ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_proc.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/ iscsi-scst/ qla2xxx-target/ srpt/ \ scst_local/ - diff --git a/scst/kernel/in-tree/Makefile.scst-2.6.26 b/scst/kernel/in-tree/Makefile.scst-2.6.26 index 1379402be..7aacdd48e 100644 --- a/scst/kernel/in-tree/Makefile.scst-2.6.26 +++ b/scst/kernel/in-tree/Makefile.scst-2.6.26 @@ -1,14 +1,17 @@ -ccflags-y += -Iinclude/scst -Wno-unused-parameter +ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/ iscsi-scst/ qla2xxx-target/ srpt/ \ scst_local/ - diff --git a/scst/kernel/in-tree/Makefile.scst-2.6.27 b/scst/kernel/in-tree/Makefile.scst-2.6.27 index 1379402be..7aacdd48e 100644 --- a/scst/kernel/in-tree/Makefile.scst-2.6.27 +++ b/scst/kernel/in-tree/Makefile.scst-2.6.27 @@ -1,14 +1,17 @@ -ccflags-y += -Iinclude/scst -Wno-unused-parameter +ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/ iscsi-scst/ qla2xxx-target/ srpt/ \ scst_local/ - diff --git a/scst/kernel/in-tree/Makefile.scst-2.6.28 b/scst/kernel/in-tree/Makefile.scst-2.6.28 index 1379402be..7aacdd48e 100644 --- a/scst/kernel/in-tree/Makefile.scst-2.6.28 +++ b/scst/kernel/in-tree/Makefile.scst-2.6.28 @@ -1,14 +1,17 @@ -ccflags-y += -Iinclude/scst -Wno-unused-parameter +ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/ iscsi-scst/ qla2xxx-target/ srpt/ \ scst_local/ - diff --git a/scst/kernel/in-tree/Makefile.scst-2.6.29 b/scst/kernel/in-tree/Makefile.scst-2.6.29 index 1379402be..7aacdd48e 100644 --- a/scst/kernel/in-tree/Makefile.scst-2.6.29 +++ b/scst/kernel/in-tree/Makefile.scst-2.6.29 @@ -1,14 +1,17 @@ -ccflags-y += -Iinclude/scst -Wno-unused-parameter +ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/ iscsi-scst/ qla2xxx-target/ srpt/ \ scst_local/ - diff --git a/scst/kernel/in-tree/Makefile.scst-2.6.30 b/scst/kernel/in-tree/Makefile.scst-2.6.30 index 1379402be..7aacdd48e 100644 --- a/scst/kernel/in-tree/Makefile.scst-2.6.30 +++ b/scst/kernel/in-tree/Makefile.scst-2.6.30 @@ -1,14 +1,17 @@ -ccflags-y += -Iinclude/scst -Wno-unused-parameter +ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/ iscsi-scst/ qla2xxx-target/ srpt/ \ scst_local/ - diff --git a/scst/kernel/in-tree/Makefile.scst-2.6.31 b/scst/kernel/in-tree/Makefile.scst-2.6.31 index 1379402be..7aacdd48e 100644 --- a/scst/kernel/in-tree/Makefile.scst-2.6.31 +++ b/scst/kernel/in-tree/Makefile.scst-2.6.31 @@ -1,14 +1,17 @@ -ccflags-y += -Iinclude/scst -Wno-unused-parameter +ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/ iscsi-scst/ qla2xxx-target/ srpt/ \ scst_local/ - diff --git a/scst/kernel/in-tree/Makefile.scst-2.6.32 b/scst/kernel/in-tree/Makefile.scst-2.6.32 index 1379402be..7aacdd48e 100644 --- a/scst/kernel/in-tree/Makefile.scst-2.6.32 +++ b/scst/kernel/in-tree/Makefile.scst-2.6.32 @@ -1,14 +1,17 @@ -ccflags-y += -Iinclude/scst -Wno-unused-parameter +ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/ iscsi-scst/ qla2xxx-target/ srpt/ \ scst_local/ - diff --git a/scst/kernel/in-tree/Makefile.scst-2.6.33 b/scst/kernel/in-tree/Makefile.scst-2.6.33 index d2dd04dc2..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-2.6.33 +++ b/scst/kernel/in-tree/Makefile.scst-2.6.33 @@ -1,13 +1,17 @@ -ccflags-y += -Iinclude/scst -Wno-unused-parameter +ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-2.6.34 b/scst/kernel/in-tree/Makefile.scst-2.6.34 index d2dd04dc2..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-2.6.34 +++ b/scst/kernel/in-tree/Makefile.scst-2.6.34 @@ -1,13 +1,17 @@ -ccflags-y += -Iinclude/scst -Wno-unused-parameter +ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-2.6.35 b/scst/kernel/in-tree/Makefile.scst-2.6.35 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-2.6.35 +++ b/scst/kernel/in-tree/Makefile.scst-2.6.35 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-2.6.36 b/scst/kernel/in-tree/Makefile.scst-2.6.36 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-2.6.36 +++ b/scst/kernel/in-tree/Makefile.scst-2.6.36 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-2.6.37 b/scst/kernel/in-tree/Makefile.scst-2.6.37 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-2.6.37 +++ b/scst/kernel/in-tree/Makefile.scst-2.6.37 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-2.6.38 b/scst/kernel/in-tree/Makefile.scst-2.6.38 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-2.6.38 +++ b/scst/kernel/in-tree/Makefile.scst-2.6.38 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-2.6.39 b/scst/kernel/in-tree/Makefile.scst-2.6.39 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-2.6.39 +++ b/scst/kernel/in-tree/Makefile.scst-2.6.39 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-3.0 b/scst/kernel/in-tree/Makefile.scst-3.0 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-3.0 +++ b/scst/kernel/in-tree/Makefile.scst-3.0 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-3.1 b/scst/kernel/in-tree/Makefile.scst-3.1 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-3.1 +++ b/scst/kernel/in-tree/Makefile.scst-3.1 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-3.10 b/scst/kernel/in-tree/Makefile.scst-3.10 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-3.10 +++ b/scst/kernel/in-tree/Makefile.scst-3.10 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-3.11 b/scst/kernel/in-tree/Makefile.scst-3.11 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-3.11 +++ b/scst/kernel/in-tree/Makefile.scst-3.11 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-3.12 b/scst/kernel/in-tree/Makefile.scst-3.12 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-3.12 +++ b/scst/kernel/in-tree/Makefile.scst-3.12 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-3.13 b/scst/kernel/in-tree/Makefile.scst-3.13 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-3.13 +++ b/scst/kernel/in-tree/Makefile.scst-3.13 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-3.14 b/scst/kernel/in-tree/Makefile.scst-3.14 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-3.14 +++ b/scst/kernel/in-tree/Makefile.scst-3.14 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-3.15 b/scst/kernel/in-tree/Makefile.scst-3.15 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-3.15 +++ b/scst/kernel/in-tree/Makefile.scst-3.15 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-3.16 b/scst/kernel/in-tree/Makefile.scst-3.16 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-3.16 +++ b/scst/kernel/in-tree/Makefile.scst-3.16 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-3.17 b/scst/kernel/in-tree/Makefile.scst-3.17 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-3.17 +++ b/scst/kernel/in-tree/Makefile.scst-3.17 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-3.18 b/scst/kernel/in-tree/Makefile.scst-3.18 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-3.18 +++ b/scst/kernel/in-tree/Makefile.scst-3.18 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-3.19 b/scst/kernel/in-tree/Makefile.scst-3.19 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-3.19 +++ b/scst/kernel/in-tree/Makefile.scst-3.19 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-3.2 b/scst/kernel/in-tree/Makefile.scst-3.2 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-3.2 +++ b/scst/kernel/in-tree/Makefile.scst-3.2 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-3.3 b/scst/kernel/in-tree/Makefile.scst-3.3 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-3.3 +++ b/scst/kernel/in-tree/Makefile.scst-3.3 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-3.4 b/scst/kernel/in-tree/Makefile.scst-3.4 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-3.4 +++ b/scst/kernel/in-tree/Makefile.scst-3.4 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-3.5 b/scst/kernel/in-tree/Makefile.scst-3.5 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-3.5 +++ b/scst/kernel/in-tree/Makefile.scst-3.5 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-3.6 b/scst/kernel/in-tree/Makefile.scst-3.6 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-3.6 +++ b/scst/kernel/in-tree/Makefile.scst-3.6 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-3.7 b/scst/kernel/in-tree/Makefile.scst-3.7 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-3.7 +++ b/scst/kernel/in-tree/Makefile.scst-3.7 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-3.8 b/scst/kernel/in-tree/Makefile.scst-3.8 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-3.8 +++ b/scst/kernel/in-tree/Makefile.scst-3.8 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-3.9 b/scst/kernel/in-tree/Makefile.scst-3.9 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-3.9 +++ b/scst/kernel/in-tree/Makefile.scst-3.9 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-4.0 b/scst/kernel/in-tree/Makefile.scst-4.0 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-4.0 +++ b/scst/kernel/in-tree/Makefile.scst-4.0 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-4.1 b/scst/kernel/in-tree/Makefile.scst-4.1 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-4.1 +++ b/scst/kernel/in-tree/Makefile.scst-4.1 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-4.2 b/scst/kernel/in-tree/Makefile.scst-4.2 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-4.2 +++ b/scst/kernel/in-tree/Makefile.scst-4.2 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/kernel/in-tree/Makefile.scst-4.3 b/scst/kernel/in-tree/Makefile.scst-4.3 index 53af5f388..f4e0cc985 100644 --- a/scst/kernel/in-tree/Makefile.scst-4.3 +++ b/scst/kernel/in-tree/Makefile.scst-4.3 @@ -1,13 +1,17 @@ ccflags-y += -Wno-unused-parameter -scst-y += scst_main.o -scst-y += scst_pres.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_sysfs.o -scst-y += scst_mem.o -scst-y += scst_tg.o +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/dev_handlers/scst_cdrom.c b/scst/src/dev_handlers/scst_cdrom.c index a08999b4f..f1860f8d7 100644 --- a/scst/src/dev_handlers/scst_cdrom.c +++ b/scst/src/dev_handlers/scst_cdrom.c @@ -123,6 +123,7 @@ static int cdrom_attach(struct scst_device *dev) if (rc == 0) { uint32_t sector_size = get_unaligned_be32(&buffer[4]); + if (sector_size == 0) dev->block_shift = CDROM_DEF_BLOCK_SHIFT; else diff --git a/scst/src/dev_handlers/scst_disk.c b/scst/src/dev_handlers/scst_disk.c index a56cc204c..d694633fd 100644 --- a/scst/src/dev_handlers/scst_disk.c +++ b/scst/src/dev_handlers/scst_disk.c @@ -217,6 +217,7 @@ static int disk_attach(struct scst_device *dev) } if (rc == 0) { uint32_t sector_size = get_unaligned_be32(&buffer[4]); + if (sector_size == 0) dev->block_shift = DISK_DEF_BLOCK_SHIFT; else @@ -474,6 +475,7 @@ split: if (unlikely(sg_is_chain(&sg[j]))) { bool reset_start_sg = (start_sg == &sg[j]); + sg = sg_chain_ptr(&sg[j]); j = 0; if (reset_start_sg) diff --git a/scst/src/dev_handlers/scst_modisk.c b/scst/src/dev_handlers/scst_modisk.c index 850f8efe2..80913010c 100644 --- a/scst/src/dev_handlers/scst_modisk.c +++ b/scst/src/dev_handlers/scst_modisk.c @@ -222,6 +222,7 @@ static int modisk_attach(struct scst_device *dev) if (rc == 0) { uint32_t sector_size = get_unaligned_be32(&buffer[4]); + if (sector_size == 0) dev->block_shift = MODISK_DEF_BLOCK_SHIFT; else diff --git a/scst/src/dev_handlers/scst_tape.c b/scst/src/dev_handlers/scst_tape.c index 4daa84d84..1b56b01ed 100644 --- a/scst/src/dev_handlers/scst_tape.c +++ b/scst/src/dev_handlers/scst_tape.c @@ -206,6 +206,7 @@ static int tape_attach(struct scst_device *dev) if (rc == 0) { int medium_type, mode, speed, density; + if (buffer[3] == 8) dev->block_size = get_unaligned_be24(&buffer[9]); else @@ -299,6 +300,7 @@ static int tape_done(struct scst_cmd *cmd) (cmd->sense[2] & 0xe0)) { /* EOF, EOM, or ILI */ unsigned int TransferLength, Residue = 0; + if ((cmd->sense[2] & 0x0f) == BLANK_CHECK) /* No need for EOM in this case */ cmd->sense[2] &= 0xcf; @@ -312,6 +314,7 @@ static int tape_done(struct scst_cmd *cmd) cmd->cdb[1], TransferLength, Residue); if (TransferLength > Residue) { int resp_data_len = TransferLength - Residue; + if (cmd->cdb[1] & 1) { /* * No need for locks here, since diff --git a/scst/src/dev_handlers/scst_user.c b/scst/src/dev_handlers/scst_user.c index c4c65a2a2..caf33d27c 100644 --- a/scst/src/dev_handlers/scst_user.c +++ b/scst/src/dev_handlers/scst_user.c @@ -261,6 +261,7 @@ static inline bool ucmd_get_check(struct scst_user_cmd *ucmd) { int r = atomic_inc_return(&ucmd->ucmd_ref); int res; + if (unlikely(r == 1)) { TRACE_DBG("ucmd %p is being destroyed", ucmd); atomic_dec(&ucmd->ucmd_ref); @@ -551,6 +552,7 @@ static int dev_user_alloc_sg(struct scst_user_cmd *ucmd, int cached_buff) } else { /* Make out_sg->offset 0 */ int len = cmd->bufflen + ucmd->first_page_offset; + out_sg_pages = (len >> PAGE_SHIFT) + ((len & ~PAGE_MASK) != 0); orig_bufflen = (out_sg_pages << PAGE_SHIFT) + cmd->out_bufflen; pool = dev->pool; @@ -612,6 +614,7 @@ static int dev_user_alloc_sg(struct scst_user_cmd *ucmd, int cached_buff) if (unlikely(cmd->sg_cnt > cmd->tgt_dev->max_sg_cnt)) { static int ll; + if ((ll < 10) || TRACING_MINOR()) { PRINT_INFO("Unable to complete command due to " "SG IO count limitation (requested %d, " @@ -885,9 +888,11 @@ static void dev_user_flush_dcache(struct scst_user_cmd *ucmd) for (i = 0; (bufflen > 0) && (i < buf_ucmd->num_data_pages); i++) { struct page *page __attribute__((unused)); + page = buf_ucmd->data_pages[i]; #ifdef ARCH_HAS_FLUSH_ANON_PAGE struct vm_area_struct *vma = find_vma(current->mm, start); + if (vma != NULL) flush_anon_page(vma, page, start); #endif @@ -1090,6 +1095,7 @@ static void dev_user_set_block_size(struct scst_cmd *cmd, int block_size) dev->block_size = block_size; else { struct scst_user_dev *udev = cmd->dev->dh_priv; + dev->block_size = udev->def_block_size; } dev->block_shift = -1; /* not used */ @@ -1243,8 +1249,9 @@ static int dev_user_map_buf(struct scst_user_cmd *ucmd, unsigned long ubuff, ucmd->num_data_pages = num_pg; - ucmd->data_pages = kmalloc(sizeof(*ucmd->data_pages) * ucmd->num_data_pages, - GFP_KERNEL); + ucmd->data_pages = kmalloc_array(ucmd->num_data_pages, + sizeof(*ucmd->data_pages), + GFP_KERNEL); if (ucmd->data_pages == NULL) { TRACE(TRACE_OUT_OF_MEM, "Unable to allocate data_pages array " "(num_data_pages=%d)", ucmd->num_data_pages); @@ -1311,6 +1318,7 @@ static int dev_user_process_reply_alloc(struct scst_user_cmd *ucmd, if (likely(reply->alloc_reply.pbuf != 0)) { int pages; + if (ucmd->buff_cached) { if (unlikely((reply->alloc_reply.pbuf & ~PAGE_MASK) != 0)) { PRINT_ERROR("Supplied pbuf %llx isn't " @@ -1530,7 +1538,7 @@ static int dev_user_process_reply_ext_copy_remap(struct scst_user_cmd *ucmd, goto out_hw_err_free_buf; } - left = kmalloc(sizeof(*left) * count, GFP_KERNEL); + left = kmalloc_array(count, sizeof(*left), GFP_KERNEL); if (unlikely(left == NULL)) { PRINT_ERROR("Unable to alloc leftover remap descriptors " "(size %zd, count %d)", sizeof(*left) * count, count); @@ -1686,7 +1694,7 @@ static int dev_user_process_ws_reply(struct scst_user_cmd *ucmd, goto out_free_buf; } - where = kmalloc(sizeof(*where) * count, GFP_KERNEL); + where = kmalloc_array(count, sizeof(*where), GFP_KERNEL); if (unlikely(where == NULL)) { PRINT_ERROR("Unable to alloc WS descriptors where (size %zd)", sizeof(*where) * count); @@ -1775,6 +1783,7 @@ static int dev_user_process_reply_exec(struct scst_user_cmd *ucmd, if (ereply->resp_data_len != 0) { if (ucmd->ubuff == 0) { int pages, rc; + if (unlikely(ereply->pbuf == 0)) goto out_busy; if (ucmd->buff_cached) { @@ -2324,6 +2333,7 @@ static int dev_user_reply_get_cmd(struct file *file, void __user *arg) if (ureply != 0) { unsigned long u = (unsigned long)ureply; + rc = copy_from_user(&reply, (void __user *)u, sizeof(reply)); if (unlikely(rc != 0)) { PRINT_ERROR("Failed to copy %d user's bytes", rc); @@ -2476,6 +2486,7 @@ static long dev_user_ioctl(struct file *file, unsigned int cmd, case SCST_USER_REGISTER_DEVICE: { struct scst_user_dev_desc *dev_desc; + TRACE_DBG("%s", "REGISTER_DEVICE"); dev_desc = kmalloc(sizeof(*dev_desc), GFP_KERNEL); if (dev_desc == NULL) { @@ -2511,6 +2522,7 @@ static long dev_user_ioctl(struct file *file, unsigned int cmd, case SCST_USER_SET_OPTIONS: { struct scst_user_opt opt; + TRACE_DBG("%s", "SET_OPTIONS"); rc = copy_from_user(&opt, (void __user *)arg, sizeof(opt)); if (rc != 0) { @@ -3777,6 +3789,7 @@ static int dev_user_get_opt(struct file *file, void __user *arg) if (unlikely(res != 0)) goto out; + memset(&opt, 0, sizeof(opt)); opt.parse_type = dev->parse_type; opt.on_free_cmd_type = dev->on_free_cmd_type; opt.memory_reuse_type = dev->memory_reuse_type; @@ -3867,6 +3880,7 @@ static int dev_user_exit_dev(struct scst_user_dev *dev) static int __dev_user_release(void *arg) { struct scst_user_dev *dev = arg; + dev_user_exit_dev(dev); kmem_cache_free(user_dev_cachep, dev); return 0; @@ -3937,6 +3951,7 @@ static int dev_user_process_cleanup(struct scst_user_dev *dev) #ifdef CONFIG_SCST_EXTRACHECKS { int i; + for (i = 0; i < (int)ARRAY_SIZE(dev->ucmd_hash); i++) { struct list_head *head = &dev->ucmd_hash[i]; struct scst_user_cmd *ucmd2, *tmp; @@ -3978,6 +3993,7 @@ static ssize_t dev_user_sysfs_commands_show(struct kobject *kobj, for (i = 0; i < (int)ARRAY_SIZE(udev->ucmd_hash); i++) { struct list_head *head = &udev->ucmd_hash[i]; struct scst_user_cmd *ucmd; + list_for_each_entry(ucmd, head, hash_list_entry) { ppos = pos; pos += scnprintf(&buf[pos], diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index e47d79631..085bf56a7 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -190,12 +190,14 @@ struct scst_vdisk_dev { uint64_t format_progress_to_do, format_progress_done; int virt_id; - char name[64+1]; /* Name of the virtual device, - must be <= SCSI Model + 1 */ - char *filename; /* File name, protected by - scst_mutex and suspended activities */ + /* Name of the virtual device, must be <= SCSI Model + 1 */ + char name[64+1]; + /* File name, protected by scst_mutex and suspended activities */ + char *filename; uint16_t command_set_version; + unsigned int initial_cluster_mode:1; + /* All 14 protected by vdisk_serial_rwlock */ unsigned int t10_vend_id_set:1; /* true if t10_vend_id manually set */ /* true if vend_specific_id manually set */ @@ -1034,6 +1036,7 @@ check: if (virt_dev->thin_provisioned) { int block_shift = virt_dev->dev->block_shift; + if (virt_dev->blockio) { struct request_queue *q; @@ -1109,11 +1112,11 @@ static int vdisk_get_file_size(const char *filename, bool blockio, goto out_close; } - if (S_ISREG(inode->i_mode)) - /* Nothing to do */; - else if (S_ISBLK(inode->i_mode)) + if (S_ISREG(inode->i_mode)) { + /* Nothing to do */ + } else if (S_ISBLK(inode->i_mode)) { inode = inode->i_bdev->bd_inode; - else { + } else { res = -EINVAL; goto out_close; } @@ -1297,11 +1300,7 @@ static int __vdev_load_mode_pages(struct scst_vdisk_dev *virt_dev, char *params) if (scst_get_next_lexem(¶m)[0] != '\0') goto out_too_many; -#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) goto out_strtoul_failed; @@ -1571,6 +1570,7 @@ static int vdisk_attach(struct scst_device *dev) dev->block_shift = virt_dev->blk_shift; dev->block_size = 1 << dev->block_shift; + dev->cluster_mode = virt_dev->initial_cluster_mode; if ((virt_dev->dif_type == 0) && ((virt_dev->dif_mode != SCST_DIF_MODE_NONE) || @@ -1856,6 +1856,7 @@ static enum compl_status_e vdisk_synchronize_cache(struct vdisk_cmd_params *p) if (data_len == 0) { struct scst_vdisk_dev *virt_dev = dev->dh_priv; + data_len = virt_dev->file_size - ((loff_t)scst_cmd_get_lba(cmd) << dev->block_shift); } @@ -2000,6 +2001,7 @@ static int vdisk_format_dif(struct scst_cmd *cmd, uint64_t start_lba, i = -1; while (1) { int len = min_t(size_t, (size_t)left, PAGE_SIZE); + full_len += len; i++; iv_count++; @@ -2209,6 +2211,7 @@ static enum compl_status_e vdisk_exec_format_unit(struct vdisk_cmd_params *p) if (virt_dev->thin_provisioned) { int rc = vdisk_unmap_range(cmd, virt_dev, 0, virt_dev->nblocks); + if (rc != 0) goto finished; } @@ -3003,6 +3006,7 @@ out: static int vcdrom_parse(struct scst_cmd *cmd) { int res, rc; + rc = scst_cdrom_generic_parse(cmd); if (rc != 0) { res = scst_get_cmd_abnormal_done_state(cmd); @@ -3318,7 +3322,7 @@ static struct scatterlist *alloc_sg(size_t size, unsigned off, gfp_t gfp_mask, sg_cnt = PAGE_ALIGN(size + off) >> PAGE_SHIFT; sg = sg_cnt <= small_sg_size ? small_sg : - kmalloc(sg_cnt * sizeof(*sg), gfp_mask); + kmalloc_array(sg_cnt, sizeof(*sg), gfp_mask); if (!sg) goto out; @@ -4180,7 +4184,7 @@ static int vdisk_block_limits(uint8_t *buf, struct scst_cmd *cmd, buf[1] = 0xB0; buf[3] = 0x3C; buf[4] = 1; /* WSNZ set */ - buf[5] = 0xFF; /* No MAXIMUM COMPARE AND WRITE LENGTH limit */ + buf[5] = 0xFF; /* No MAXIMUM COMPARE AND WRITE LENGTH limit */ /* Optimal transfer granuality is PAGE_SIZE */ put_unaligned_be16(max_t(int, PAGE_SIZE / dev->block_size, 1), &buf[6]); @@ -4310,6 +4314,7 @@ static int vdisk_inq(uint8_t *buf, struct scst_cmd *cmd, /* Physical transport */ if (cmd->tgtt->get_phys_transport_version != NULL) { uint16_t v = cmd->tgtt->get_phys_transport_version(cmd->tgt); + if (v != 0) { put_unaligned_be16(v, &buf[58 + num]); num += 2; @@ -4382,19 +4387,19 @@ static enum compl_status_e vdisk_exec_inquiry(struct vdisk_cmd_params *p) SCSI_INQ_PQ_CON << 5 | dev->type; /* Vital Product */ if (cmd->cdb[1] & EVPD) { - if (0 == cmd->cdb[2]) { + if (cmd->cdb[2] == 0) { resp_len = vdisk_sup_vpd(buf, cmd, virt_dev); - } else if (0x80 == cmd->cdb[2]) { + } else if (cmd->cdb[2] == 0x80) { resp_len = vdisk_usn_vpd(buf, cmd, virt_dev); - } else if (0x83 == cmd->cdb[2]) { + } else if (cmd->cdb[2] == 0x83) { resp_len = vdisk_dev_id_vpd(buf, cmd, virt_dev); - } else if (0x86 == cmd->cdb[2]) { + } else if (cmd->cdb[2] == 0x86) { resp_len = vdisk_ext_inq(buf, cmd, virt_dev); - } else if ((0xB0 == cmd->cdb[2]) && (dev->type == TYPE_DISK)) { + } else if (cmd->cdb[2] == 0xB0 && dev->type == TYPE_DISK) { resp_len = vdisk_block_limits(buf, cmd, virt_dev); - } else if ((0xB1 == cmd->cdb[2]) && (dev->type == TYPE_DISK)) { + } else if (cmd->cdb[2] == 0xB1 && dev->type == TYPE_DISK) { resp_len = vdisk_bdev_char(buf, cmd, virt_dev); - } else if ((0xB2 == cmd->cdb[2]) && (dev->type == TYPE_DISK) && + } else if (cmd->cdb[2] == 0xB2 && dev->type == TYPE_DISK && virt_dev->thin_provisioned) { resp_len = vdisk_tp_vpd(buf, cmd, virt_dev); } else { @@ -4501,7 +4506,7 @@ static int vdisk_err_recov_pg(unsigned char *p, int pcontrol, 1, 0, 0xff, 0xff}; memcpy(p, err_recov_pg, sizeof(err_recov_pg)); - if (1 == pcontrol) + if (pcontrol == 1) memset(p + 2, 0, sizeof(err_recov_pg) - 2); return sizeof(err_recov_pg); } @@ -4513,7 +4518,7 @@ static int vdisk_disconnect_pg(unsigned char *p, int pcontrol, 0, 0, 0, 0, 0, 0, 0, 0}; memcpy(p, disconnect_pg, sizeof(disconnect_pg)); - if (1 == pcontrol) + if (pcontrol == 1) memset(p + 2, 0, sizeof(disconnect_pg) - 2); return sizeof(disconnect_pg); } @@ -4540,7 +4545,7 @@ static int vdisk_rigid_geo_pg(unsigned char *p, int pcontrol, memcpy(&n, p + 2, sizeof(u32)); n = n | ((__force u32)cpu_to_be32(ncyl) >> 8); memcpy(p + 2, &n, sizeof(u32)); - if (1 == pcontrol) + if (pcontrol == 1) memset(p + 2, 0, sizeof(geo_m_pg) - 2); return sizeof(geo_m_pg); } @@ -4555,7 +4560,7 @@ static int vdisk_format_pg(unsigned char *p, int pcontrol, memcpy(p, format_pg, sizeof(format_pg)); put_unaligned_be16(DEF_SECTORS, &p[10]); put_unaligned_be16(virt_dev->dev->block_size, &p[12]); - if (1 == pcontrol) + if (pcontrol == 1) memset(p + 2, 0, sizeof(format_pg) - 2); return sizeof(format_pg); } @@ -4674,7 +4679,7 @@ static int vdisk_iec_m_pg(unsigned char *p, int pcontrol, const unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, 0, 0, 0x0, 0x0}; memcpy(p, iec_m_pg, sizeof(iec_m_pg)); - if (1 == pcontrol) + if (pcontrol == 1) memset(p + 2, 0, sizeof(iec_m_pg) - 2); return sizeof(iec_m_pg); } @@ -4711,7 +4716,7 @@ static enum compl_status_e vdisk_exec_mode_sense(struct vdisk_cmd_params *p) pcontrol = (cmd->cdb[2] & 0xc0) >> 6; pcode = cmd->cdb[2] & 0x3f; subpcode = cmd->cdb[3]; - msense_6 = (MODE_SENSE == cmd->cdb[0]); + msense_6 = (cmd->cdb[0] == MODE_SENSE); dev_spec = cmd->tgt_dev->tgt_dev_rd_only ? WP : 0; if (type != TYPE_ROM) @@ -4721,7 +4726,7 @@ static enum compl_status_e vdisk_exec_mode_sense(struct vdisk_cmd_params *p) if (unlikely(length <= 0)) goto out_free; - if (!vdev_saved_mode_pages_enabled && (0x3 == pcontrol)) { + if (!vdev_saved_mode_pages_enabled && (pcontrol == 0x3)) { TRACE_DBG("%s", "MODE SENSE: Saving values not supported"); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_saving_params_unsup)); @@ -4738,7 +4743,7 @@ static enum compl_status_e vdisk_exec_mode_sense(struct vdisk_cmd_params *p) offset = 8; } - if (0 != subpcode) { + if (subpcode != 0) { /* TODO: Control Extension page */ TRACE_DBG("%s", "MODE SENSE: Only subpage 0 is supported"); scst_set_invalid_field_in_cdb(cmd, 3, 0); @@ -5123,7 +5128,7 @@ static enum compl_status_e vdisk_exec_mode_select(struct vdisk_cmd_params *p) goto out; } - mselect_6 = (MODE_SELECT == cmd->cdb[0]); + mselect_6 = (cmd->cdb[0] == MODE_SELECT); type = cmd->dev->type; length = scst_get_buf_full_sense(cmd, &address); @@ -5230,6 +5235,7 @@ static enum compl_status_e vdisk_exec_read_capacity(struct vdisk_cmd_params *p) if ((cmd->cdb[8] & 1) == 0) { uint32_t lba = get_unaligned_be32(&cmd->cdb[2]); + if (lba != 0) { TRACE_DBG("PMI zero and LBA not zero (cmd %p)", cmd); scst_set_invalid_field_in_cdb(cmd, 2, 0); @@ -5305,6 +5311,7 @@ static enum compl_status_e vdisk_exec_read_capacity16(struct vdisk_cmd_params *p if ((cmd->cdb[14] & 1) == 0) { uint32_t lba = get_unaligned_be32(&cmd->cdb[2]); + if (lba != 0) { TRACE_DBG("PMI zero and LBA not zero (cmd %p)", cmd); scst_set_invalid_field_in_cdb(cmd, 2, 0); @@ -5494,8 +5501,10 @@ static enum compl_status_e vdisk_exec_read_toc(struct vdisk_cmd_params *p) off = 4; if (cmd->cdb[6] <= 1) { /* Fistr TOC Track Descriptor */ - /* ADDR 0x10 - Q Sub-channel encodes current position data - CONTROL 0x04 - Data track, recoreded uninterrupted */ + /* + * ADDR 0x10 - Q Sub-channel encodes current position data + * CONTROL 0x04 - Data track, recoreded uninterrupted + */ buffer[off+1] = 0x14; /* Track Number */ buffer[off+2] = 0x01; @@ -5700,7 +5709,8 @@ static struct iovec *vdisk_alloc_iv(struct scst_cmd *cmd, p->iv_count = 0; /* It can't be called in atomic context */ p->iv = (iv_count <= ARRAY_SIZE(p->small_iv)) ? p->small_iv : - kmalloc(sizeof(*p->iv) * iv_count, cmd->cmd_gfp_mask); + kmalloc_array(iv_count, sizeof(*p->iv), + cmd->cmd_gfp_mask); if (p->iv == NULL) { PRINT_ERROR("Unable to allocate iv (%d)", iv_count); goto out; @@ -5786,6 +5796,7 @@ static int vdev_read_dif_tags(struct vdisk_cmd_params *p) iv = vdisk_alloc_iv(cmd, p); if (iv == NULL) { unsigned long flags; + /* To protect sense setting against blockio data reads */ spin_lock_irqsave(&vdev_err_lock, flags); scst_set_busy(cmd); @@ -5834,6 +5845,7 @@ static int vdev_read_dif_tags(struct vdisk_cmd_params *p) &loff); if ((err < 0) || (err < full_len)) { unsigned long flags; + PRINT_ERROR("DIF readv() returned %lld from %zd " "(offs %lld, dev %s)", (long long)err, full_len, (long long)loff, cmd->dev->virt_name); @@ -5917,6 +5929,7 @@ static int vdev_write_dif_tags(struct vdisk_cmd_params *p) iv = vdisk_alloc_iv(cmd, p); if (iv == NULL) { unsigned long flags; + /* To protect sense setting against blockio data writes */ spin_lock_irqsave(&vdev_err_lock, flags); scst_set_busy(cmd); @@ -5967,6 +5980,7 @@ restart: &loff); if (err < 0) { unsigned long flags; + PRINT_ERROR("DIF write() returned %lld from %zd", (long long)err, full_len); /* To protect sense setting with blockio */ @@ -5986,6 +6000,7 @@ restart: * value less, than requested. Let's restart. */ int e = eiv_count; + TRACE_MGMT_DBG("DIF write() returned %d from %zd " "(iv_count=%d)", (int)err, full_len, eiv_count); @@ -6320,6 +6335,7 @@ restart: * value less, than requested. Let's restart. */ int e = eiv_count; + TRACE_MGMT_DBG("write() returned %d from %zd " "(iv_count=%d)", (int)err, full_len, eiv_count); @@ -6686,6 +6702,7 @@ static void blockio_exec_rw(struct vdisk_cmd_params *p, bool write, bool fua) #if 0 { static int err_inj_cntr; + if (++err_inj_cntr % 256 == 0) { PRINT_INFO("blockio_exec_rw() error injection"); scst_set_busy(cmd); @@ -6911,6 +6928,7 @@ static int vdisk_blockio_flush(struct block_device *bdev, gfp_t gfp_mask, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) if (async) { struct bio *bio = bio_alloc(gfp_mask, 0); + if (bio == NULL) { res = -ENOMEM; goto out_rep; @@ -7369,6 +7387,7 @@ static void vdisk_task_mgmt_fn_done(struct scst_mgmt_cmd *mcmd, } else if (mcmd->fn == SCST_PR_ABORT_ALL) { struct scst_device *dev = tgt_dev->dev; struct scst_vdisk_dev *virt_dev = dev->dh_priv; + spin_lock(&virt_dev->flags_lock); virt_dev->prevent_allow_medium_removal = 0; spin_unlock(&virt_dev->flags_lock); @@ -7383,7 +7402,7 @@ static void vdev_ext_copy_remap(struct scst_cmd *cmd, struct scst_ext_copy_seg_descr *seg) { struct scst_ext_copy_data_descr *d; - static int shift = 0; + static int shift; static DEFINE_SPINLOCK(lock); int s; @@ -7596,7 +7615,7 @@ static int vdisk_create_bioset(struct scst_vdisk_dev *virt_dev) /* The same, pool size doesn't really matter */ res = bioset_integrity_create(virt_dev->vdisk_bioset, 2); #else - res = -ENOSYS; + res = -ENOTSUPP; #endif if (res != 0) { PRINT_ERROR("Failed to create integrity bioset " @@ -7864,11 +7883,7 @@ static int vdev_parse_add_dev_params(struct scst_vdisk_dev *virt_dev, continue; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) res = kstrtoull(pp, 0, &val); -#else - res = strict_strtoull(pp, 0, &val); -#endif if (res != 0) { PRINT_ERROR("strtoull() for %s failed: %d (device %s)", pp, res, virt_dev->name); @@ -7926,6 +7941,10 @@ static int vdev_parse_add_dev_params(struct scst_vdisk_dev *virt_dev, virt_dev->file_size = val; } else if (!strcasecmp("size_mb", p)) { virt_dev->file_size = val * 1024 * 1024; + } else if (!strcasecmp("cluster_mode", p)) { + virt_dev->initial_cluster_mode = val; + TRACE_DBG("CLUSTER_MODE %d", + virt_dev->initial_cluster_mode); } else if (!strcasecmp("blocksize", p)) { virt_dev->blk_shift = scst_calc_block_shift(val); if (virt_dev->blk_shift < 9) { @@ -8027,7 +8046,8 @@ static int vdev_blockio_add_device(const char *device_name, char *params) int res = 0; const char *const allowed_params[] = { "filename", "read_only", "write_through", "removable", "blocksize", "nv_cache", - "rotational", "thin_provisioned", "tst", + "rotational", "cluster_mode", + "thin_provisioned", "tst", "dif_mode", "dif_type", "dif_static_app_tag", "dif_filename", NULL }; struct scst_vdisk_dev *virt_dev; @@ -8404,6 +8424,7 @@ static int vcdrom_change(struct scst_vdisk_dev *virt_dev, if (!virt_dev->cdrom_empty) { char *fn = kstrdup(filename, GFP_KERNEL); + if (fn == NULL) { PRINT_ERROR("%s", "Allocation of filename failed"); res = -ENOMEM; @@ -8802,7 +8823,7 @@ static ssize_t vdisk_sysfs_expl_alua_store(struct kobject *kobj, struct scst_device *dev; struct scst_vdisk_dev *virt_dev; char ch[16]; - bool expl_alua; + unsigned long expl_alua; int res; TRACE_ENTRY(); @@ -8810,14 +8831,17 @@ static ssize_t vdisk_sysfs_expl_alua_store(struct kobject *kobj, dev = container_of(kobj, struct scst_device, dev_kobj); virt_dev = dev->dh_priv; sprintf(ch, "%.*s", min_t(int, sizeof(ch) - 1, count), buf); - expl_alua = !!simple_strtoul(ch, NULL, 0); + res = kstrtoul(ch, 0, &expl_alua); + if (res < 0) + goto out; spin_lock(&virt_dev->flags_lock); - virt_dev->expl_alua = expl_alua; + virt_dev->expl_alua = !!expl_alua; spin_unlock(&virt_dev->flags_lock); res = count; +out: TRACE_EXIT_RES(res); return res; } @@ -8897,11 +8921,7 @@ static ssize_t vdev_sysfs_rz_store(struct kobject *kobj, char ch[16]; sprintf(ch, "%.*s", min_t(int, sizeof(ch) - 1, count), buf); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) res = kstrtol(ch, 0, &read_zero); -#else - res = strict_strtol(ch, 0, &read_zero); -#endif if (res) goto out; res = -EINVAL; @@ -9116,11 +9136,7 @@ static int vdev_sysfs_process_cluster_mode_store( * have been dropped before invoking .detach(). */ virt_dev = dev->dh_priv; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) res = kstrtol(work->buf, 0, &clm); -#else - res = strict_strtol(work->buf, 0, &clm); -#endif if (res) goto unlock; res = -EINVAL; @@ -10623,6 +10639,7 @@ static void exit_scst_vdisk(struct scst_dev_type *devtype) static void init_ops(vdisk_op_fn *ops, int count) { int i; + for (i = 0; i < count; i++) if (ops[i] == NULL) ops[i] = vdisk_invalid_opcode; diff --git a/scst/src/scst_copy_mgr.c b/scst/src/scst_copy_mgr.c index 63183f206..2b873f088 100644 --- a/scst/src/scst_copy_mgr.c +++ b/scst/src/scst_copy_mgr.c @@ -11,7 +11,11 @@ #include #include +#ifdef INSIDE_KERNEL_TREE +#include +#else #include "scst.h" +#endif #include "scst_priv.h" #include "scst_pres.h" @@ -35,6 +39,13 @@ /* Too big value is not too good for the blocking machinery */ #define SCST_CM_MAX_TGT_DESCR_CNT 5 +#define SCST_CM_MAX_SEG_DESCR_CNT \ + (((PAGE_SIZE * 2) - sizeof(struct scst_cm_ec_cmd_priv)) / \ + sizeof(struct scst_ext_copy_seg_descr)) + +/* MAXIMUM DESCRIPTOR LIST LENGTH */ +#define SCST_MAX_SEG_DESC_LEN 0xFFFF + static struct scst_tgt *scst_cm_tgt; static struct scst_session *scst_cm_sess; @@ -172,14 +183,18 @@ typedef void (*scst_cm_retry_fn_t)(struct scst_cmd *cmd); struct scst_cm_retry { struct scst_cmd *cm_retry_cmd; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) + struct work_struct cm_retry_work; +#else struct delayed_work cm_retry_work; +#endif scst_cm_retry_fn_t cm_retry_fn; }; -static void scst_cm_retry_work_fn(struct delayed_work *work) +static void scst_cm_retry_work_fn(struct work_struct *work) { struct scst_cm_retry *retry = container_of(work, struct scst_cm_retry, - cm_retry_work); + cm_retry_work.work); TRACE_ENTRY(); @@ -269,7 +284,7 @@ try_retry: next_retry_time = cur_time + SCST_CM_RETRIES_WAIT; TRACE_DBG("Retrying cmd %p (imm_retry %d, next_retry_time %ld, " - "cur_time %ld, " "start_time %ld, max_retry_time %ld): going " + "cur_time %ld, start_time %ld, max_retry_time %ld): going " "to sleep", cmd, imm_retry, next_retry_time, cur_time, start_time, max_retry_time); @@ -288,8 +303,7 @@ try_retry: } retry->cm_retry_cmd = cmd; __scst_cmd_get(cmd); - INIT_DELAYED_WORK(&retry->cm_retry_work, - (void (*)(struct work_struct *))scst_cm_retry_work_fn); + INIT_DELAYED_WORK(&retry->cm_retry_work, scst_cm_retry_work_fn); retry->cm_retry_fn = retry_fn; if (imm_retry) { @@ -349,7 +363,7 @@ static int scst_cm_setup_this_data_descr(struct scst_cmd *ec_cmd) EXTRACHECKS_BUG_ON(priv->cm_cur_data_descr > priv->cm_data_descrs_cnt); if (priv->cm_cur_data_descr == priv->cm_data_descrs_cnt) { - TRACE_DBG("No more data desriptors for ec_cmd %p", ec_cmd); + TRACE_DBG("No more data descriptors for ec_cmd %p", ec_cmd); res = -ENOENT; goto out; } @@ -720,6 +734,7 @@ static void scst_cm_store_list_id_details(struct scst_cmd *ec_cmd) l->cm_status = ec_cmd->status; if (scst_sense_valid(ec_cmd->sense)) { int len = ec_cmd->sense_valid_len; + if (len > sizeof(l->cm_sense)) { PRINT_WARNING("EC command's sense is " "too big (%d) with max allowed " @@ -1320,6 +1335,7 @@ static void scst_cm_gen_reads(struct scst_cmd *ec_cmd) while (1) { int rc; + while ((priv->cm_left_to_read > 0) && (priv->cm_cur_in_flight < SCST_MAX_IN_FLIGHT_INTERNAL_COMMANDS)) { int blocks; @@ -1788,6 +1804,7 @@ bool scst_cm_check_block_all_devs(struct scst_cmd *cmd) if (unlikely(res)) { struct scst_cmd *blocked_cmd = e->cm_fcmd; + list_for_each_entry(e, &d->cm_sorted_devs_list, cm_sorted_devs_list_entry) { if (e->cm_fcmd == blocked_cmd) @@ -1832,6 +1849,7 @@ void scst_cm_abort_ec_cmd(struct scst_cmd *ec_cmd) list_for_each_entry(ip, &p->cm_internal_cmd_list, cm_internal_cmd_list_entry) { struct scst_cmd *c = ip->cm_cmd; + TRACE_MGMT_DBG("Aborting (f)cmd %p", c); set_bit(SCST_CMD_ABORTED, &c->cmd_flags); } @@ -1974,10 +1992,16 @@ out_unlock_free: goto out; } -void sess_cm_list_id_cleanup_work_fn(struct delayed_work *work) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) +void sess_cm_list_id_cleanup_work_fn(void *p) { - struct scst_session *sess = container_of((struct delayed_work *)work, - struct scst_session, sess_cm_list_id_cleanup_work); + struct scst_session *sess = p; +#else +void sess_cm_list_id_cleanup_work_fn(struct work_struct *work) +{ + struct scst_session *sess = container_of(work, + struct scst_session, sess_cm_list_id_cleanup_work.work); +#endif struct scst_cm_list_id *l, *t; unsigned long cur_time = jiffies; unsigned long flags; @@ -2210,11 +2234,10 @@ static void scst_cm_oper_parameters(struct scst_cmd *cmd) put_unaligned_be16(SCST_CM_MAX_TGT_DESCR_CNT, &tbuf[8]); /* MAXIMUM SEGMENT DESCRIPTOR COUNT */ - put_unaligned_be16(((PAGE_SIZE * 2) - sizeof(struct scst_cm_ec_cmd_priv)) / - sizeof(struct scst_ext_copy_seg_descr), &tbuf[10]); + put_unaligned_be16(SCST_CM_MAX_SEG_DESCR_CNT, &tbuf[10]); /* MAXIMUM DESCRIPTOR LIST LENGTH */ - put_unaligned_be32(0xFFFF, &tbuf[12]); + put_unaligned_be32(SCST_MAX_SEG_DESC_LEN, &tbuf[12]); /* MAXIMUM SEGMENT LENGTH: 256MB */ put_unaligned_be32(256*1024*1024, &tbuf[16]); @@ -2507,6 +2530,7 @@ static int scst_cm_dev_register(struct scst_device *dev) 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]; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { if (tgt_dev->dev == dev) { PRINT_ERROR("Copy Manager already registered " @@ -2572,6 +2596,7 @@ static void scst_cm_dev_unregister(struct scst_device *dev) 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]; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { if (tgt_dev->dev == dev) { scst_acg_del_lun(scst_cm_tgt->default_acg, @@ -2626,6 +2651,7 @@ static bool scst_cm_check_access_acg(const char *initiator_name, list_for_each_entry(acg_dev, &acg->acg_dev_list, acg_dev_list_entry) { if (acg_dev->dev == dev) { struct scst_acn *acn; + if (default_acg) goto found; list_for_each_entry(acn, &acg->acn_list, acn_list_entry) { @@ -2951,6 +2977,7 @@ skip_fcmd_create: #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_EXTRACHECKS) { struct scst_cm_dev_entry *tp = NULL; + list_for_each_entry(t, &priv->cm_sorted_devs_list, cm_sorted_devs_list_entry) { TRACE_DBG("t %p, cm dev %p", t, t->cm_fcmd->dev); if (tp != NULL) { @@ -3039,7 +3066,7 @@ static int scst_cm_parse_b2b_seg_descr(struct scst_cmd *ec_cmd, scst_cm_set_seg_err_sense(ec_cmd, 0xD, 2, seg_num, 6); goto out_err; } - if (tgt_des->read_only){ + if (tgt_des->read_only) { PRINT_WARNING("Target descriptor refers to read-only device"); scst_cm_set_seg_err_sense(ec_cmd, 0, 0, seg_num, 6); goto out_err; @@ -3119,6 +3146,7 @@ static void scst_cm_free_ec_priv(struct scst_cmd *ec_cmd, bool unblock_dev) list_for_each_entry_safe(ip, it, &p->cm_internal_cmd_list, cm_internal_cmd_list_entry) { struct scst_cmd *c = ip->cm_cmd; + scst_cm_del_free_from_internal_cmd_list(c, unblock_dev); __scst_cmd_put(c); } @@ -3207,7 +3235,7 @@ int scst_cm_parse_descriptors(struct scst_cmd *ec_cmd) if (seg_len == 0) goto out_del_put; else { - PRINT_WARNING("Zero target descriptors with none zero " + PRINT_WARNING("Zero target descriptors with non-zero " "segments len (%d)", seg_len); scst_set_invalid_field_in_parm_list(ec_cmd, 2, 0); goto out_del_abn_put; @@ -3244,7 +3272,7 @@ int scst_cm_parse_descriptors(struct scst_cmd *ec_cmd) TRACE_DBG("tgt_cnt %d", tgt_cnt); - tgt_descrs = kzalloc(sizeof(*tgt_descrs) * tgt_cnt, GFP_KERNEL); + tgt_descrs = kcalloc(tgt_cnt, sizeof(*tgt_descrs), GFP_KERNEL); if (tgt_descrs == NULL) { TRACE(TRACE_OUT_OF_MEM, "Unable to allocate tgt_descrs " "(count %d, size %zd)", tgt_cnt, @@ -3277,6 +3305,13 @@ int scst_cm_parse_descriptors(struct scst_cmd *ec_cmd) t = offs; seg_cnt = 0; while (offs < length) { + if (seg_cnt == SCST_CM_MAX_SEG_DESCR_CNT) { + PRINT_WARNING("Too many segment descriptors"); + scst_set_cmd_error(ec_cmd, + SCST_LOAD_SENSE( + scst_sense_too_many_segment_descriptors)); + goto out_free_tgt_descr; + } switch (buf[offs]) { case 2: /* block device to block device segment descriptor */ offs += 28; @@ -3425,11 +3460,7 @@ static ssize_t scst_cm_allow_not_conn_copy_store(struct kobject *kobj, TRACE_ENTRY(); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) res = kstrtoul(buffer, 0, &val); -#else - res = strict_strtoul(buffer, 0, &val); -#endif if (res != 0) { PRINT_ERROR("strtoul() for %s failed: %zd", buffer, res); goto out; diff --git a/scst/src/scst_dlm.c b/scst/src/scst_dlm.c index 438486244..0aa1372ea 100644 --- a/scst/src/scst_dlm.c +++ b/scst/src/scst_dlm.c @@ -572,7 +572,8 @@ static int scst_dlm_update_nodeids(struct scst_pr_dlm_data *pr_dlm) static const char comms_dir[] = "/sys/kernel/config/dlm/cluster/comms"; struct file *comms; char *p, *entries = kzalloc(1, GFP_KERNEL); - uint32_t nodeid, *new; + unsigned long nodeid; + uint32_t *new; int i, ret, num_nodes; char path[256], buf[64]; @@ -612,7 +613,9 @@ static int scst_dlm_update_nodeids(struct scst_pr_dlm_data *pr_dlm) pr_dlm->nodeid = new; pr_dlm->participants = num_nodes; for (i = 0, p = entries; *p; i++, p += strlen(p) + 1) { - nodeid = simple_strtoul(p, NULL, 0); + ret = kstrtoul(p, 0, &nodeid); + if (WARN_ON_ONCE(ret < 0)) + continue; snprintf(path, sizeof(path), "%s/%s/local", comms_dir, p); if (scst_read_file(path, buf, sizeof(buf)) >= 0 && strcmp(buf, "1\n") == 0) @@ -1077,10 +1080,16 @@ static void scst_dlm_pre_bast(void *bastarg, int mode) queue_work(pr_dlm->from_wq, &pr_dlm->pre_upd_work); } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) +static void scst_pre_join_work(void *p) +{ + struct scst_pr_dlm_data *pr_dlm = p; +#else static void scst_pre_join_work(struct work_struct *work) { struct scst_pr_dlm_data *pr_dlm = container_of(work, struct scst_pr_dlm_data, pre_join_work); +#endif dlm_lockspace_t *ls; mutex_lock(&pr_dlm->ls_mutex); @@ -1094,10 +1103,16 @@ static void scst_pre_join_work(struct work_struct *work) mutex_unlock(&pr_dlm->ls_mutex); } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) +static void scst_pre_upd_work(void *p) +{ + struct scst_pr_dlm_data *pr_dlm = p; +#else static void scst_pre_upd_work(struct work_struct *work) { struct scst_pr_dlm_data *pr_dlm = container_of(work, struct scst_pr_dlm_data, pre_upd_work); +#endif dlm_lockspace_t *ls; mutex_lock(&pr_dlm->ls_mutex); @@ -1128,10 +1143,16 @@ static void scst_dlm_post_bast(void *bastarg, int mode) * Note: the node that has invoked scst_trigger_lvb_update() holds PR_LOCK * in EX mode and waits until this function has finished. */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) +static void scst_copy_to_dlm_work(void *p) +{ + struct scst_pr_dlm_data *pr_dlm = p; +#else static void scst_copy_to_dlm_work(struct work_struct *work) { struct scst_pr_dlm_data *pr_dlm = container_of(work, struct scst_pr_dlm_data, copy_to_dlm_work); +#endif struct scst_device *dev = pr_dlm->dev; dlm_lockspace_t *ls; int res; @@ -1195,10 +1216,16 @@ unlock_ls: * scst_pr_init_tgt_dev() and scst_pr_clear_tgt_dev() in scst_pres.c protect * these manipulations by locking the PR data structures for writing. */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) +static void scst_copy_from_dlm_work(void *p) +{ + struct scst_pr_dlm_data *pr_dlm = p; +#else static void scst_copy_from_dlm_work(struct work_struct *work) { struct scst_pr_dlm_data *pr_dlm = container_of(work, struct scst_pr_dlm_data, copy_from_dlm_work); +#endif struct scst_device *dev = pr_dlm->dev; dlm_lockspace_t *ls; int res = -ENOENT; @@ -1250,10 +1277,16 @@ static void scst_dlm_post_ast(void *astarg) } /* Tell other nodes to refresh their local state from the lock value blocks. */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) +static void scst_reread_lvb_work(void *p) +{ + struct scst_pr_dlm_data *pr_dlm = p; +#else static void scst_reread_lvb_work(struct work_struct *work) { struct scst_pr_dlm_data *pr_dlm = container_of(work, struct scst_pr_dlm_data, reread_lvb_work); +#endif dlm_lockspace_t *ls; struct scst_lksb pr_lksb; int res; @@ -1275,10 +1308,16 @@ unlock_ls: } /* Tell other nodes to update the DLM lock value blocks. */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) +static void scst_lvb_upd_work(void *p) +{ + struct scst_pr_dlm_data *pr_dlm = p; +#else static void scst_lvb_upd_work(struct work_struct *work) { struct scst_pr_dlm_data *pr_dlm = container_of(work, struct scst_pr_dlm_data, lvb_upd_work); +#endif dlm_lockspace_t *ls; struct scst_lksb lksb; int res; @@ -1298,7 +1337,8 @@ unlock_ls: mutex_unlock(&pr_dlm->ls_mutex); } -static struct workqueue_struct *create_st_wq(const char *fmt, ...) +static struct workqueue_struct *__printf(1, 2) +create_st_wq(const char *fmt, ...) { struct workqueue_struct *wq = NULL; va_list ap; @@ -1319,47 +1359,58 @@ static struct workqueue_struct *create_st_wq(const char *fmt, ...) */ static int scst_pr_dlm_init(struct scst_device *dev, const char *cl_dev_id) { + struct scst_pr_dlm_data *pr_dlm; int res = -ENOMEM; compile_time_size_checks(); - dev->pr_dlm = kzalloc(sizeof(*dev->pr_dlm), GFP_KERNEL); - if (!dev->pr_dlm) + pr_dlm = kzalloc(sizeof(*dev->pr_dlm), GFP_KERNEL); + if (!pr_dlm) goto out; - dev->pr_dlm->dev = dev; - mutex_init(&dev->pr_dlm->ls_cr_mutex); - mutex_init(&dev->pr_dlm->ls_mutex); - dev->pr_dlm->data_lksb.lksb.sb_lvbptr = dev->pr_dlm->lvb; - INIT_WORK(&dev->pr_dlm->pre_join_work, scst_pre_join_work); - INIT_WORK(&dev->pr_dlm->pre_upd_work, scst_pre_upd_work); - INIT_WORK(&dev->pr_dlm->copy_from_dlm_work, scst_copy_from_dlm_work); - INIT_WORK(&dev->pr_dlm->copy_to_dlm_work, scst_copy_to_dlm_work); - INIT_WORK(&dev->pr_dlm->lvb_upd_work, scst_lvb_upd_work); - INIT_WORK(&dev->pr_dlm->reread_lvb_work, scst_reread_lvb_work); - dev->pr_dlm->latest_lscr_attempt = jiffies - 100 * HZ; + dev->pr_dlm = pr_dlm; + pr_dlm->dev = dev; + mutex_init(&pr_dlm->ls_cr_mutex); + mutex_init(&pr_dlm->ls_mutex); + pr_dlm->data_lksb.lksb.sb_lvbptr = pr_dlm->lvb; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) + INIT_WORK(&pr_dlm->pre_join_work, scst_pre_join_work, pr_dlm); + INIT_WORK(&pr_dlm->pre_upd_work, scst_pre_upd_work, pr_dlm); + INIT_WORK(&pr_dlm->copy_from_dlm_work, scst_copy_from_dlm_work, pr_dlm); + INIT_WORK(&pr_dlm->copy_to_dlm_work, scst_copy_to_dlm_work, pr_dlm); + INIT_WORK(&pr_dlm->lvb_upd_work, scst_lvb_upd_work, pr_dlm); + INIT_WORK(&pr_dlm->reread_lvb_work, scst_reread_lvb_work, pr_dlm); +#else + INIT_WORK(&pr_dlm->pre_join_work, scst_pre_join_work); + INIT_WORK(&pr_dlm->pre_upd_work, scst_pre_upd_work); + INIT_WORK(&pr_dlm->copy_from_dlm_work, scst_copy_from_dlm_work); + INIT_WORK(&pr_dlm->copy_to_dlm_work, scst_copy_to_dlm_work); + INIT_WORK(&pr_dlm->lvb_upd_work, scst_lvb_upd_work); + INIT_WORK(&pr_dlm->reread_lvb_work, scst_reread_lvb_work); +#endif + pr_dlm->latest_lscr_attempt = jiffies - 100 * HZ; res = -ENOMEM; - dev->pr_dlm->cl_dev_id = kstrdup(cl_dev_id, GFP_KERNEL); - if (!dev->pr_dlm->cl_dev_id) + pr_dlm->cl_dev_id = kstrdup(cl_dev_id, GFP_KERNEL); + if (!pr_dlm->cl_dev_id) goto err_free; - dev->pr_dlm->from_wq = create_st_wq("%s_from_dlm", dev->virt_name); - if (IS_ERR(dev->pr_dlm->from_wq)) { - res = PTR_ERR(dev->pr_dlm->from_wq); - dev->pr_dlm->from_wq = NULL; + pr_dlm->from_wq = create_st_wq("%s_from_dlm", dev->virt_name); + if (IS_ERR(pr_dlm->from_wq)) { + res = PTR_ERR(pr_dlm->from_wq); + pr_dlm->from_wq = NULL; goto err_free; } - dev->pr_dlm->to_wq = create_st_wq("%s_to_dlm", dev->virt_name); - if (IS_ERR(dev->pr_dlm->to_wq)) { - res = PTR_ERR(dev->pr_dlm->to_wq); - dev->pr_dlm->to_wq = NULL; + pr_dlm->to_wq = create_st_wq("%s_to_dlm", dev->virt_name); + if (IS_ERR(pr_dlm->to_wq)) { + res = PTR_ERR(pr_dlm->to_wq); + pr_dlm->to_wq = NULL; goto err_free; } - dev->pr_dlm->upd_wq = create_st_wq("%s_upd_dlm", dev->virt_name); - if (IS_ERR(dev->pr_dlm->upd_wq)) { - res = PTR_ERR(dev->pr_dlm->upd_wq); - dev->pr_dlm->upd_wq = NULL; + pr_dlm->upd_wq = create_st_wq("%s_upd_dlm", dev->virt_name); + if (IS_ERR(pr_dlm->upd_wq)) { + res = PTR_ERR(pr_dlm->upd_wq); + pr_dlm->upd_wq = NULL; goto err_free; } diff --git a/scst/src/scst_event.c b/scst/src/scst_event.c index 52cec1121..3b36b8e50 100644 --- a/scst/src/scst_event.c +++ b/scst/src/scst_event.c @@ -88,10 +88,16 @@ out: return res; } -static void scst_event_timeout_fn(struct delayed_work *work) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) +static void scst_event_timeout_fn(void *p) +{ + struct scst_event_entry *event_entry = p; +#else +static void scst_event_timeout_fn(struct work_struct *work) { struct scst_event_entry *event_entry = container_of(work, - struct scst_event_entry, event_timeout_work); + struct scst_event_entry, event_timeout_work.work); +#endif TRACE_ENTRY(); @@ -198,8 +204,14 @@ static void __scst_event_queue(struct scst_event_entry *event_entry) break; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) + INIT_WORK(&new_event_entry->event_timeout_work, + scst_event_timeout_fn, + new_event_entry); +#else INIT_DELAYED_WORK(&new_event_entry->event_timeout_work, - (void (*)(struct work_struct *))scst_event_timeout_fn); + scst_event_timeout_fn); +#endif if (new_event_entry->event_notify_fn != NULL) { new_event_entry->event.event_id = atomic_inc_return(&base_event_id); if (new_event_entry->event_timeout == 0) @@ -245,10 +257,16 @@ done: return; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) +static void scst_event_queue_work_fn(void *p) +{ + struct scst_event_entry *e = p; +#else static void scst_event_queue_work_fn(struct work_struct *work) { struct scst_event_entry *e = container_of(work, struct scst_event_entry, scst_event_queue_work); +#endif TRACE_ENTRY(); @@ -264,7 +282,11 @@ void scst_event_queue(uint32_t event_code, const char *issuer_name, { TRACE_ENTRY(); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) + INIT_WORK(&e->scst_event_queue_work, scst_event_queue_work_fn, e); +#else INIT_WORK(&e->scst_event_queue_work, scst_event_queue_work_fn); +#endif TRACE_DBG("Scheduling event entry %p", e); @@ -545,12 +567,12 @@ static int scst_event_get_event_from_user(void __user *arg, struct scst_event_entry **out_event_entry) { int res, rc, event_entry_len; - int32_t payload_len; + uint32_t payload_len; struct scst_event_entry *event_entry; TRACE_ENTRY(); - res = get_user(payload_len, (int32_t __user *)arg); + res = get_user(payload_len, (uint32_t __user *)arg); if (res != 0) { PRINT_ERROR("Failed to get payload len: %d", res); goto out; @@ -1042,7 +1064,11 @@ static const struct file_operations scst_event_fops = { int scst_event_init(void) { int res = 0; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 21) + struct class_device *class_member; +#else struct device *dev; +#endif TRACE_ENTRY(); @@ -1060,6 +1086,15 @@ int scst_event_init(void) goto out_class; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 21) + 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; + } +#else dev = device_create(scst_event_sysfs_class, NULL, MKDEV(scst_event_major, 0), NULL, @@ -1068,6 +1103,7 @@ int scst_event_init(void) res = PTR_ERR(dev); goto out_chrdev; } +#endif #ifdef CONFIG_EVENTS_WAIT_TEST sysfs_create_file(kernel_kobj, &event_wait_test_attr.attr); diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index c447d2c26..c026d02e0 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -74,7 +74,11 @@ static DEFINE_SPINLOCK(scst_global_stpg_list_lock); static LIST_HEAD(scst_global_stpg_list); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) +static void scst_put_acg_work(void *p); +#else static void scst_put_acg_work(struct work_struct *work); +#endif static void scst_del_acn(struct scst_acn *acn); static void scst_free_acn(struct scst_acn *acn, bool reassign); @@ -492,19 +496,19 @@ static int get_cdb_info_var_len(struct scst_cmd *cmd, const struct scst_sdbops *sdbops); /* -+=====================================-============-======- -| Command name | Operation | Type | -| | code | | -|-------------------------------------+------------+------+ - -+=========================================================+ -|Key: M = command implementation is mandatory. | -| O = command implementation is optional. | -| V = Vendor-specific | -| R = Reserved | -| ' '= DON'T use for this device | -+=========================================================+ -*/ + * +=====================================-============-======- + * | Command name | Operation | Type | + * | | code | | + * |-------------------------------------+------------+------+ + * + * +=========================================================+ + * |Key: M = command implementation is mandatory. | + * | O = command implementation is optional. | + * | V = Vendor-specific | + * | R = Reserved | + * | ' '= DON'T use for this device | + * +=========================================================+ + */ #define SCST_CDB_MANDATORY 'M' /* mandatory */ #define SCST_CDB_OPTIONAL 'O' /* optional */ @@ -581,7 +585,8 @@ static const struct scst_sdbops scst_scsi_op_table[] = { * |||||||||| |||+----> Optical card (F) * |||||||||| |||| * |||||||||| |||| - * 0123456789ABCDEF -> TYPE_???? */ + * 0123456789ABCDEF -> TYPE_???? + */ /* 6-bytes length CDB */ {.ops = 0x00, .devkey = "MMMMMMMMMMMMMMMM", @@ -2027,6 +2032,7 @@ int scst_set_cmd_error_and_inf(struct scst_cmd *cmd, int key, int asc, { /* Fixed format */ uint32_t i = information; + cmd->sense[0] |= 0x80; /* Information field is valid */ put_unaligned_be32(i, &cmd->sense[3]); break; @@ -2930,6 +2936,7 @@ next: something_freed = false; for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct scst_tgt_dev *t; + head = &sess->sess_tgt_dev_list[i]; list_for_each_entry_safe(tgt_dev, t, head, @@ -3000,8 +3007,10 @@ void scst_check_reassign_sessions(void) list_for_each_entry(tgtt, &scst_template_list, scst_template_list_entry) { struct scst_tgt *tgt; + list_for_each_entry(tgt, &tgtt->tgt_list, tgt_list_entry) { struct scst_session *sess; + list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) { scst_check_reassign_sess(sess); @@ -3314,7 +3323,7 @@ static void scst_adjust_sg(struct scst_cmd *cmd, bool reg_sg, return; } -static bool __scst_adjust_sg_get_tail(struct scst_cmd *cmd, +static int __scst_adjust_sg_get_tail(struct scst_cmd *cmd, struct scatterlist *sg, int *sg_cnt, struct scatterlist **res_sg, int *res_sg_cnt, int adjust_len, struct scst_orig_sg_data *orig_sg, int must_left) @@ -3344,7 +3353,7 @@ static bool __scst_adjust_sg_get_tail(struct scst_cmd *cmd, TRACE_DBG_FLAG(TRACE_SG_OP|TRACE_MEMORY|TRACE_DEBUG, "cmd %p (tag %llu), sg %p, adjust_len %d, i %d, " "j %d, sg[j].length %d, offs %d", - cmd, (long long unsigned int)cmd->tag, + cmd, (unsigned long long)cmd->tag, sg, adjust_len, i, j, sg[j].length, offs); if (offs == sg[j].length) { @@ -3736,6 +3745,7 @@ bool __scst_get_resid(struct scst_cmd *cmd, int *resid, int *bidi_out_resid) if (cmd->expected_data_direction & SCST_DATA_READ) { int resp = cmd->resp_data_len; + if (cmd->tgt_dif_data_expected) resp += (resp >> cmd->dev->block_shift) << SCST_DIF_TAG_SHIFT; *resid = cmd->expected_transfer_len_full - resp; @@ -3748,6 +3758,7 @@ bool __scst_get_resid(struct scst_cmd *cmd, int *resid, int *bidi_out_resid) } } else if (cmd->expected_data_direction & SCST_DATA_WRITE) { int wl = cmd->write_len; + if (cmd->tgt_dif_data_expected) wl += (wl >> cmd->dev->block_shift) << SCST_DIF_TAG_SHIFT; if (wl < cmd->expected_transfer_len_full) @@ -3756,6 +3767,7 @@ bool __scst_get_resid(struct scst_cmd *cmd, int *resid, int *bidi_out_resid) *resid = cmd->write_len - cmd->bufflen; if (cmd->tgt_dif_data_expected) { int r = *resid; + if (r < 0) r = -r; r += (r >> cmd->dev->block_shift) << SCST_DIF_TAG_SHIFT; @@ -3952,6 +3964,7 @@ static bool __scst_is_relative_target_port_id_unique(uint16_t id, list_for_each_entry(tgtt, &scst_template_list, scst_template_list_entry) { struct scst_tgt *tgt; + list_for_each_entry(tgt, &tgtt->tgt_list, tgt_list_entry) { if (tgt == t) continue; @@ -4097,6 +4110,7 @@ void scst_free_tgt(struct scst_tgt *tgt) static void scst_init_order_data(struct scst_order_data *order_data) { int i; + spin_lock_init(&order_data->sn_lock); INIT_LIST_HEAD(&order_data->deferred_cmd_list); INIT_LIST_HEAD(&order_data->skipped_sn_list); @@ -4109,7 +4123,11 @@ static void scst_init_order_data(struct scst_order_data *order_data) return; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) +static void scst_ext_blocking_done_fn(void *p); +#else static void scst_ext_blocking_done_fn(struct work_struct *work); +#endif static int scst_dif_none(struct scst_cmd *cmd); #ifdef CONFIG_SCST_DIF_INJECT_CORRUPTED_TAGS @@ -4144,7 +4162,11 @@ int scst_alloc_device(gfp_t gfp_mask, struct scst_device **out_dev) INIT_LIST_HEAD(&dev->dev_tgt_dev_list); INIT_LIST_HEAD(&dev->dev_acg_dev_list); INIT_LIST_HEAD(&dev->ext_blockers_list); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) + INIT_WORK(&dev->ext_blockers_work, scst_ext_blocking_done_fn, dev); +#else INIT_WORK(&dev->ext_blockers_work, scst_ext_blocking_done_fn); +#endif dev->dev_double_ua_possible = 1; dev->queue_alg = SCST_QUEUE_ALG_1_UNRESTRICTED_REORDER; @@ -4588,6 +4610,7 @@ static void scst_free_acg(struct scst_acg *acg) list_for_each_entry_safe(acg_dev, acg_dev_tmp, &acg->acg_dev_list, acg_dev_list_entry) { struct scst_tgt_dev *tgt_dev, *tt; + list_for_each_entry_safe(tgt_dev, tt, &acg_dev->dev->dev_tgt_dev_list, dev_tgt_dev_list_entry) { @@ -4622,13 +4645,19 @@ struct scst_acg_put_work { struct scst_acg *acg; }; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) +static void scst_put_acg_work(void *p) +{ + struct scst_acg_put_work *put_work = p; +#else static void scst_put_acg_work(struct work_struct *work) { struct scst_acg_put_work *put_work = container_of(work, typeof(*put_work), work); +#endif struct scst_acg *acg = put_work->acg; - kfree(work); + kfree(put_work); kref_put(&acg->acg_kref, scst_release_acg); } @@ -4642,7 +4671,11 @@ void scst_put_acg(struct scst_acg *acg) return; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) + INIT_WORK(&put_work->work, scst_put_acg_work, put_work); +#else INIT_WORK(&put_work->work, scst_put_acg_work); +#endif put_work->acg = acg; /* @@ -4892,6 +4925,7 @@ int scst_tgt_dev_setup_threads(struct scst_tgt_dev *tgt_dev) if (dev->threads_num == 0) { struct scst_tgt_dev *shared_io_tgt_dev; + tgt_dev->active_cmd_threads = &scst_main_cmd_threads; shared_io_tgt_dev = scst_find_shared_io_tgt_dev(tgt_dev); @@ -5336,6 +5370,7 @@ void scst_sess_free_tgt_devs(struct scst_session *sess) /* The session is going down, no users, so no locks */ for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &sess->sess_tgt_dev_list[i]; + list_for_each_entry_safe(tgt_dev, t, head, sess_tgt_dev_list_entry) { scst_free_tgt_dev(tgt_dev); @@ -5779,6 +5814,7 @@ static int scst_ws_push_single_write(struct scst_write_same_priv *wsp, write_cdb[1] = ws_cmd->cdb[1]; if (needs_dif) { uint8_t wrprotect = ws_cmd->cdb[1] & 0xE0; + if (wrprotect == 0) wrprotect = 0x20; write_cdb[1] |= wrprotect; @@ -5788,6 +5824,7 @@ static int scst_ws_push_single_write(struct scst_write_same_priv *wsp, } else { /* There might be WRITE SAME(16) with WRPROTECT 0 here */ uint8_t wrprotect; + if (ws_cmd->cdb_len != 32) wrprotect = ws_cmd->cdb[1] & 0xE0; else @@ -5850,6 +5887,7 @@ static int scst_ws_push_single_write(struct scst_write_same_priv *wsp, for_each_sg(dif_sg, s, dif_sg_cnt, i) { int left = (s->length - s->offset) >> SCST_DIF_TAG_SHIFT; struct t10_pi_tuple *t = sg_virt(s); + TRACE_DBG("sg %p, offset %d, length %d, left %d", s, s->offset, s->length, left); while (left > 0) { @@ -5908,8 +5946,7 @@ static void scst_ws_finished(struct scst_write_same_priv *wsp) else if (wsp->ws_sg_tails && wsp->ws_sg_tails[0].sg_cnt != 0 && sg_page(&wsp->ws_sg_tails[0].sg[0]) != sg_page(ws_cmd->sg)) __free_page(sg_page(&wsp->ws_sg_tails[0].sg[0])); - if (wsp->ws_sg_full) - kfree(wsp->ws_sg_full); + kfree(wsp->ws_sg_full); if (wsp->ws_sg_tails) { for (i = 0; wsp->ws_descriptors[i].sdd_blocks != 0; i++) if (wsp->ws_sg_tails[i].sg_cnt != 0) @@ -5950,6 +5987,7 @@ static void scst_ws_write_cmd_finished(struct scst_cmd *cmd) if (cmd->status != 0) { int rc; + TRACE_DBG("Write cmd %p (ws cmd %p) finished not successfully", cmd, ws_cmd); sBUG_ON(cmd->resp_data_len != 0); @@ -5973,7 +6011,7 @@ static void scst_ws_write_cmd_finished(struct scst_cmd *cmd) wsp->ws_cur_lba = wsp->ws_descriptors[wsp->ws_cur_descr].sdd_lba; wsp->ws_left_to_send = wsp->ws_descriptors[wsp->ws_cur_descr].sdd_blocks; TRACE_DBG("wsp %p, cur descr %d, cur lba %lld, left %d", - wsp, wsp->ws_cur_descr, (long long )wsp->ws_cur_lba, + wsp, wsp->ws_cur_descr, (long long)wsp->ws_cur_lba, wsp->ws_left_to_send); } if (wsp->ws_left_to_send == 0) @@ -6041,7 +6079,7 @@ again: wsp->ws_cur_lba = wsp->ws_descriptors[wsp->ws_cur_descr].sdd_lba; wsp->ws_left_to_send = wsp->ws_descriptors[wsp->ws_cur_descr].sdd_blocks; TRACE_DBG("wsp %p, cur descr %d, cur lba %lld, left %d", - wsp, wsp->ws_cur_descr, (long long )wsp->ws_cur_lba, + wsp, wsp->ws_cur_descr, (long long)wsp->ws_cur_lba, wsp->ws_left_to_send); goto again; } @@ -6073,7 +6111,7 @@ static int scst_ws_sg_init(struct scatterlist **ws_sg, int ws_sg_cnt, struct scatterlist *sg; int i; - *ws_sg = kmalloc(ws_sg_cnt * sizeof(**ws_sg), GFP_KERNEL); + *ws_sg = kmalloc_array(ws_sg_cnt, sizeof(**ws_sg), GFP_KERNEL); if (*ws_sg == NULL) { PRINT_ERROR("Unable to alloc sg for %d entries", ws_sg_cnt); return -ENOMEM; @@ -6081,6 +6119,7 @@ static int scst_ws_sg_init(struct scatterlist **ws_sg, int ws_sg_cnt, sg_init_table(*ws_sg, ws_sg_cnt); for_each_sg(*ws_sg, sg, ws_sg_cnt, i) { u32 len = min(total_bytes, length); + sg_set_page(sg, pg, len, offset); total_bytes -= len; } @@ -6104,7 +6143,8 @@ static int scst_ws_sg_tails_get(struct scst_data_descriptor *where, struct scst_ while (where[i].sdd_blocks != 0) i++; - wsp->ws_sg_tails = kzalloc(sizeof(*(wsp->ws_sg_tails))*(i+1), GFP_KERNEL); + wsp->ws_sg_tails = kcalloc(i + 1, sizeof(*wsp->ws_sg_tails), + GFP_KERNEL); if (wsp->ws_sg_tails == NULL) { PRINT_ERROR("Unable to allocate ws_sg_tails (size %zd)", sizeof(*wsp->ws_sg_tails)*i); @@ -6336,6 +6376,7 @@ static void scst_cwr_write_cmd_finished(struct scst_cmd *cmd) if (cmd->status != 0) { int rc; + TRACE_DBG("WRITE cmd %p (cwr cmd %p) finished not successfully", cmd, cwr_cmd); sBUG_ON(cmd->resp_data_len != 0); @@ -6374,6 +6415,7 @@ static void scst_cwr_read_cmd_finished(struct scst_cmd *cmd) if (cmd->status != 0) { int rc; + TRACE_DBG("Read cmd %p (cwr cmd %p) finished not successfully", cmd, cwr_cmd); sBUG_ON(cmd->resp_data_len != 0); @@ -6582,6 +6624,7 @@ int scst_finish_internal_cmd(struct scst_cmd *cmd) scst_complete_request_sense(cmd); else { scst_i_finish_fn_t f = (void *) *((unsigned long long **)cmd->tgt_i_priv); + f(cmd); } @@ -6684,6 +6727,7 @@ struct scst_session *scst_alloc_session(struct scst_tgt *tgt, gfp_t gfp_mask, atomic_set(&sess->refcnt, 0); for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &sess->sess_tgt_dev_list[i]; + INIT_LIST_HEAD(head); } spin_lock_init(&sess->sess_list_lock); @@ -6692,11 +6736,13 @@ struct scst_session *scst_alloc_session(struct scst_tgt *tgt, gfp_t gfp_mask, INIT_LIST_HEAD(&sess->init_deferred_cmd_list); INIT_LIST_HEAD(&sess->init_deferred_mcmd_list); INIT_LIST_HEAD(&sess->sess_cm_list_id_list); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) INIT_DELAYED_WORK(&sess->sess_cm_list_id_cleanup_work, - (void (*)(struct work_struct *))sess_cm_list_id_cleanup_work_fn); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)) + sess_cm_list_id_cleanup_work_fn); INIT_DELAYED_WORK(&sess->hw_pending_work, scst_hw_pending_work_fn); #else + INIT_WORK(&sess->sess_cm_list_id_cleanup_work, + sess_cm_list_id_cleanup_work_fn, sess); INIT_WORK(&sess->hw_pending_work, scst_hw_pending_work_fn, sess); #endif @@ -6899,6 +6945,7 @@ int scst_pre_init_cmd(struct scst_cmd *cmd, const uint8_t *cdb, { int i; uint8_t *b = (uint8_t *)cmd; + for (i = 0; i < sizeof(*cmd); i++) EXTRACHECKS_BUG_ON(b[i] != 0); } @@ -7032,7 +7079,7 @@ void scst_stpg_del_unblock_next(struct scst_cmd *cmd) EXTRACHECKS_BUG_ON(!cmd->cmd_on_global_stpg_list); - TRACE_DBG("STPG cmd %p: unblocking next", cmd); + TRACE_DBG("STPG cmd %p done: unblocking next", cmd); list_del(&cmd->global_stpg_list_entry); cmd->cmd_on_global_stpg_list = 0; @@ -7089,7 +7136,7 @@ void scst_free_cmd(struct scst_cmd *cmd) TRACE_MGMT_DBG("Freeing aborted cmd %p", cmd); EXTRACHECKS_BUG_ON(cmd->unblock_dev || cmd->dec_on_dev_needed || - cmd->on_dev_exec_list); + cmd->on_dev_exec_list); /* * Target driver can already free sg buffer before calling @@ -7100,6 +7147,7 @@ void scst_free_cmd(struct scst_cmd *cmd) if (likely(cmd->dev != NULL)) { struct scst_dev_type *devt = cmd->devt; + if (devt->on_free_cmd != NULL) { TRACE_DBG("Calling dev handler %s on_free_cmd(%p)", devt->name, cmd); @@ -8204,6 +8252,7 @@ static int sg_cmp_elem(struct scatterlist **pdst_sg, size_t *pdst_len, /* Fast path: both buffers and len aligned */ unsigned long long *s = saddr; unsigned long long *d = daddr; + EXTRACHECKS_BUG_ON(len % align_size != 0); len /= align_size; for (i = 0; i < len; i++) { @@ -8211,6 +8260,7 @@ static int sg_cmp_elem(struct scatterlist **pdst_sg, size_t *pdst_len, uint8_t *s8 = (uint8_t *)&s[i]; uint8_t *d8 = (uint8_t *)&d[i]; int j; + for (j = 0; j < align_size; j++) { if (s8[j] != d8[j]) { *miscompare_offs = i * align_size + j; @@ -8223,6 +8273,7 @@ static int sg_cmp_elem(struct scatterlist **pdst_sg, size_t *pdst_len, } else { uint8_t *s = saddr; uint8_t *d = daddr; + for (i = 0; i < len; i++) { if (s[i] != d[i]) { *miscompare_offs = i; @@ -8692,6 +8743,7 @@ static int scst_verify_dif_type1(struct scst_cmd *cmd) if ((checks & SCST_DIF_CHECK_GUARD_TAG) && !cmd->internal) { __be16 crc = crc_fn(cur_buf, block_size); + if (t->guard_tag != crc) { PRINT_WARNING("GUARD TAG check failed, " "expected 0x%x, seeing 0x%x " @@ -9014,6 +9066,7 @@ static int scst_do_dif(struct scst_cmd *cmd, case SCST_DIF_ACTION_PASS_CHECK: { enum scst_dif_actions checks = scst_get_dif_checks(cmd->cmd_dif_actions); + if (likely(checks != SCST_DIF_ACTION_NONE)) res = verify_fn(cmd); else @@ -9140,6 +9193,7 @@ static int scst_verify_dif_type2(struct scst_cmd *cmd) if ((checks & SCST_DIF_CHECK_GUARD_TAG) && !cmd->internal) { __be16 crc = crc_fn(cur_buf, block_size); + if (t->guard_tag != crc) { PRINT_WARNING("GUARD TAG check failed, " "expected 0x%x, seeing 0x%x " @@ -9357,6 +9411,7 @@ static int scst_verify_dif_type3(struct scst_cmd *cmd) if ((checks & SCST_DIF_CHECK_GUARD_TAG) && !cmd->internal) { __be16 crc = crc_fn(cur_buf, block_size); + if (t->guard_tag != crc) { PRINT_WARNING("GUARD TAG check failed, " "expected 0x%x, seeing 0x%x " @@ -10812,10 +10867,12 @@ static int get_cdb_info_lba_3_len_1_256_read(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { int res = get_cdb_info_lba_3_len_1_256(cmd, sdbops); + if (res != 0) goto out; else { struct scst_device *dev = cmd->dev; + if ((dev->dev_dif_mode != SCST_DIF_MODE_NONE) && !dev->dpicz) cmd->cmd_dif_actions = dev->dev_dif_rd_prot0_actions | SCST_DIF_CHECK_GUARD_TAG | dev->dif_app_chk | @@ -10829,10 +10886,12 @@ static int get_cdb_info_lba_3_len_1_256_write(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { int res = get_cdb_info_lba_3_len_1_256(cmd, sdbops); + if (res != 0) goto out; else { struct scst_device *dev = cmd->dev; + if (dev->dev_dif_mode != SCST_DIF_MODE_NONE) cmd->cmd_dif_actions = dev->dev_dif_wr_prot0_actions | SCST_DIF_CHECK_GUARD_TAG | dev->dif_app_chk | @@ -10940,6 +10999,7 @@ static int get_cdb_info_read_10(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { int res = get_cdb_info_lba_4_len_2(cmd, sdbops); + if (res != 0) return res; else { @@ -10955,6 +11015,7 @@ static int get_cdb_info_lba_4_len_2_wrprotect(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { int res = get_cdb_info_lba_4_len_2(cmd, sdbops); + if (res != 0) return res; else @@ -10980,6 +11041,7 @@ static int get_cdb_info_lba_4_len_4_rdprotect(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { int res = get_cdb_info_lba_4_len_4(cmd, sdbops); + if (res != 0) return res; else @@ -10990,6 +11052,7 @@ static int get_cdb_info_lba_4_len_4_wrprotect(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { int res = get_cdb_info_lba_4_len_4(cmd, sdbops); + if (res != 0) return res; else @@ -11015,6 +11078,7 @@ static int get_cdb_info_read_16(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { int res = get_cdb_info_lba_8_len_4(cmd, sdbops); + if (res != 0) return res; else { @@ -11030,6 +11094,7 @@ static int get_cdb_info_lba_8_len_4_wrprotect(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { int res = get_cdb_info_lba_8_len_4(cmd, sdbops); + if (res != 0) return res; else @@ -11040,6 +11105,7 @@ static int get_cdb_info_lba_8_len_4_wrprotect32(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { int res = get_cdb_info_lba_8_len_4(cmd, sdbops); + if (res != 0) return res; else @@ -11050,6 +11116,7 @@ static int get_cdb_info_lba_8_len_4_rdprotect32(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { int res = get_cdb_info_lba_8_len_4(cmd, sdbops); + if (res != 0) return res; else @@ -11383,6 +11450,7 @@ static int get_cdb_info_mo(struct scst_cmd *cmd, case MO_SET_TARGET_PGS: { unsigned long flags; + cmd->op_name = "SET TARGET PORT GROUPS"; cmd->op_flags |= SCST_STRICTLY_SERIALIZED; spin_lock_irqsave(&scst_global_stpg_list_lock, flags); @@ -11748,6 +11816,7 @@ int scst_tape_generic_parse(struct scst_cmd *cmd) if (cmd->op_flags & SCST_TRANSFER_LEN_TYPE_FIXED && cmd->cdb[1] & 1) { int block_size = cmd->dev->block_size; + cmd->bufflen = cmd->bufflen * block_size; cmd->data_len = cmd->data_len * block_size; cmd->out_bufflen = cmd->out_bufflen * block_size; @@ -12193,6 +12262,7 @@ static void scst_check_internal_sense(struct scst_device *dev, int result, if (host_byte(result) == DID_RESET) { int sl; + TRACE(TRACE_MGMT, "DID_RESET received for device %s, " "triggering reset UA", dev->virt_name); sl = scst_set_sense(sense, sense_len, dev->d_sense, @@ -12382,6 +12452,7 @@ again: for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &sess->sess_tgt_dev_list[i]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { /* Lockdep triggers here a false positive.. */ @@ -12424,6 +12495,7 @@ again: list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { struct scst_tgt_dev_UA *ua; + list_for_each_entry(ua, &tgt_dev->UA_list, UA_list_entry) { if (ua->global_UA && @@ -12455,6 +12527,7 @@ out_unlock: for (i = SESS_TGT_DEV_LIST_HASH_SIZE-1; i >= 0; i--) { struct list_head *head = &sess->sess_tgt_dev_list[i]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry_reverse(tgt_dev, head, sess_tgt_dev_list_entry) { spin_unlock(&tgt_dev->tgt_dev_lock); @@ -12924,8 +12997,6 @@ void scst_unblock_dev(struct scst_device *dev) break; } local_irq_restore_nort(flags); - - dev->strictly_serialized_cmd_waiting = 0; } sBUG_ON(dev->block_count < 0); @@ -13588,7 +13659,7 @@ static int scst_parse_unmap_descriptors(struct scst_cmd *cmd) if (cnt == 0) goto out_put; - pd = kzalloc(sizeof(*pd) * cnt, GFP_KERNEL); + pd = kcalloc(cnt, sizeof(*pd), GFP_KERNEL); if (pd == NULL) { PRINT_ERROR("Unable to kmalloc UNMAP %d descriptors", cnt+1); scst_set_busy(cmd); @@ -13600,6 +13671,7 @@ static int scst_parse_unmap_descriptors(struct scst_cmd *cmd) i = 0; while ((offset - 8) < descriptor_len) { struct scst_data_descriptor *d = &pd[i]; + d->sdd_lba = get_unaligned_be64(&address[offset]); offset += 8; d->sdd_blocks = get_unaligned_be32(&address[offset]); @@ -13971,11 +14043,7 @@ int scst_restore_global_mode_pages(struct scst_device *dev, char *params, if (scst_get_next_lexem(¶m)[0] != '\0') goto out_too_many; -#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) goto out_strtoul_failed; @@ -14067,10 +14135,16 @@ void __scst_ext_blocking_done(struct scst_device *dev) return; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) +static void scst_ext_blocking_done_fn(void *p) +{ + struct scst_device *dev = p; +#else static void scst_ext_blocking_done_fn(struct work_struct *work) { struct scst_device *dev = container_of(work, struct scst_device, ext_blockers_work); +#endif TRACE_ENTRY(); @@ -14125,15 +14199,15 @@ static void scst_sync_ext_blocking_done(struct scst_device *dev, return; } -int scst_ext_block_dev(struct scst_device *dev, bool sync, - ext_blocker_done_fn_t done_fn, const uint8_t *priv, int priv_len) +int scst_ext_block_dev(struct scst_device *dev, ext_blocker_done_fn_t done_fn, + const uint8_t *priv, int priv_len, int flags) { int res; struct scst_ext_blocker *b; TRACE_ENTRY(); - if (sync) + if (flags & SCST_EXT_BLOCK_SYNC) priv_len = sizeof(void *); b = kzalloc(sizeof(*b) + priv_len, GFP_KERNEL); @@ -14144,8 +14218,8 @@ int scst_ext_block_dev(struct scst_device *dev, bool sync, goto out; } - TRACE_MGMT_DBG("New (%d) %s ext blocker %p for dev %s", dev->ext_blocks_cnt+1, - sync ? "sync" : "async", b, dev->virt_name); + TRACE_MGMT_DBG("New %d ext blocker %p for dev %s (flags %x)", + dev->ext_blocks_cnt+1, b, dev->virt_name, flags); spin_lock_bh(&dev->dev_lock); @@ -14161,10 +14235,15 @@ int scst_ext_block_dev(struct scst_device *dev, bool sync, } else scst_block_dev(dev); + if (flags & SCST_EXT_BLOCK_STPG) { + WARN_ON(dev->stpg_ext_blocked); + dev->stpg_ext_blocked = 1; + } + dev->ext_blocks_cnt++; TRACE_DBG("ext_blocks_cnt %d", dev->ext_blocks_cnt); - if (sync && (dev->on_dev_cmd_count == 0)) { + if ((flags & SCST_EXT_BLOCK_SYNC) && (dev->on_dev_cmd_count == 0)) { TRACE_DBG("No commands to wait for sync blocking (dev %s)", dev->virt_name); spin_unlock_bh(&dev->dev_lock); @@ -14174,7 +14253,7 @@ int scst_ext_block_dev(struct scst_device *dev, bool sync, list_add_tail(&b->ext_blockers_list_entry, &dev->ext_blockers_list); dev->ext_blocking_pending = 1; - if (sync) { + if (flags & SCST_EXT_BLOCK_SYNC) { DECLARE_WAIT_QUEUE_HEAD_ONSTACK(w); b->ext_blocker_done_fn = scst_sync_ext_blocking_done; @@ -14208,7 +14287,7 @@ out: return res; out_free_success: - sBUG_ON(!sync); + sBUG_ON(!(flags & SCST_EXT_BLOCK_SYNC)); kfree(b); goto out_success; } @@ -14225,8 +14304,14 @@ void scst_ext_unblock_dev(struct scst_device *dev, bool stpg) } if ((dev->ext_blocks_cnt == 1) && dev->stpg_ext_blocked && !stpg) { - TRACE_DBG("Can not unblock internal STPG ext block (dev %s)", - dev->virt_name); + /* + * User space is sending too many unblock calls during + * STPG processing + */ + TRACE_MGMT_DBG("Can not unblock internal STPG ext block " + "(dev %s, ext_blocks_cnt %d, stpg_ext_blocked %d, stpg %d)", + dev->virt_name, dev->ext_blocks_cnt, + dev->stpg_ext_blocked, stpg); goto out_unlock; } @@ -14241,7 +14326,7 @@ void scst_ext_unblock_dev(struct scst_device *dev, bool stpg) spin_unlock_bh(&dev->dev_lock); TRACE_DBG("Ext unblock (dev %s): still pending...", dev->virt_name); - rc = scst_ext_block_dev(dev, true, NULL, NULL, 0); + rc = scst_ext_block_dev(dev, NULL, NULL, 0, SCST_EXT_BLOCK_SYNC); if (rc != 0) { /* Oops, have to poll */ PRINT_WARNING("scst_ext_block_dev(dev %s) failed, " @@ -14348,11 +14433,11 @@ int scst_copy_file(const char *src, const char *dest) inode = file_inode(file_src); - if (S_ISREG(inode->i_mode)) - /* Nothing to do */; - else if (S_ISBLK(inode->i_mode)) + if (S_ISREG(inode->i_mode)) { + /* Nothing to do */ + } else if (S_ISBLK(inode->i_mode)) { inode = inode->i_bdev->bd_inode; - else { + } else { PRINT_ERROR("Invalid file mode 0x%x", inode->i_mode); res = -EINVAL; set_fs(old_fs); @@ -14547,11 +14632,11 @@ static int __scst_read_file_transactional(const char *file_name, inode = file_inode(file); - if (S_ISREG(inode->i_mode)) - /* Nothing to do */; - else if (S_ISBLK(inode->i_mode)) + if (S_ISREG(inode->i_mode)) { + /* Nothing to do */ + } else if (S_ISBLK(inode->i_mode)) { inode = inode->i_bdev->bd_inode; - else { + } else { PRINT_ERROR("Invalid file mode 0x%x", inode->i_mode); res = -EINVAL; goto out_close; @@ -14822,6 +14907,7 @@ static void tm_dbg_deinit_tgt_dev(struct scst_tgt_dev *tgt_dev) { if (tm_dbg_tgt_dev == tgt_dev) { unsigned long flags; + TRACE_MGMT_DBG("Deinit TM debugging tgt_dev %p", tgt_dev); del_timer_sync(&tm_dbg_timer); spin_lock_irqsave(&scst_tm_dbg_lock, flags); @@ -14846,6 +14932,7 @@ static void tm_dbg_delay_cmd(struct scst_cmd *cmd) case TM_DBG_STATE_ABORT: if (tm_dbg_delayed_cmds_count == 0) { unsigned long d = 58*HZ + (scst_random() % (4*HZ)); + TRACE_MGMT_DBG("STATE ABORT: delaying cmd %p (tag %llu)" " for %ld.%ld seconds (%ld HZ), " "tm_dbg_on_state_passes=%d", cmd, cmd->tag, @@ -14891,6 +14978,7 @@ void tm_dbg_check_released_cmds(void) { if (tm_dbg_flags.tm_dbg_release) { struct scst_cmd *cmd, *tc; + spin_lock_irq(&scst_tm_dbg_lock); list_for_each_entry_safe_reverse(cmd, tc, &tm_dbg_delayed_cmd_list, cmd_list_entry) { @@ -15072,6 +15160,7 @@ void scst_check_debug_sn(struct scst_cmd *cmd) /* To simulate from time to time queue flushing */ if (!in_interrupt() && (scst_random() % 120) == 8) { int t = scst_random() % 1200; + TRACE_SN("Delaying IO on %d ms", t); msleep(t); } @@ -15153,8 +15242,8 @@ void scst_set_pre_exec_time(struct scst_cmd *cmd) void scst_set_exec_start(struct scst_cmd *cmd) { - cmd->exec_time_counting = true; - scst_set_cur_start(cmd); + cmd->exec_time_counting = true; + scst_set_cur_start(cmd); } void scst_set_exec_time(struct scst_cmd *cmd) diff --git a/scst/src/scst_main.c b/scst/src/scst_main.c index 67cbc797a..85ab18fe1 100644 --- a/scst/src/scst_main.c +++ b/scst/src/scst_main.c @@ -596,6 +596,7 @@ EXPORT_SYMBOL(scst_register_target); static inline int test_sess_list(struct scst_tgt *tgt) { int res; + mutex_lock(&scst_mutex); res = list_empty(&tgt->sysfs_sess_list); mutex_unlock(&scst_mutex); @@ -637,6 +638,7 @@ void scst_unregister_target(struct scst_tgt *tgt) again: { struct scst_session *sess; + list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) { if (sess->shut_phase == SCST_SESS_SPH_READY) { /* @@ -870,6 +872,7 @@ static void __printf(2, 3) scst_to_syslog(void *arg, const char *fmt, ...) int scst_get_cmd_counter(void) { int i, res = 0; + for (i = 0; i < (int)ARRAY_SIZE(scst_percpu_infos); i++) res += atomic_read(&scst_percpu_infos[i].cpu_cmd_count); return res; @@ -1877,6 +1880,7 @@ int scst_add_threads(struct scst_cmd_threads *cmd_threads, if (tgt_dev != NULL) { struct scst_tgt_dev *t; + list_for_each_entry(t, &tgt_dev->dev->dev_tgt_dev_list, dev_tgt_dev_list_entry) { if (t == tgt_dev) @@ -2447,7 +2451,8 @@ static int __init init_scst(void) struct scsi_sense_hdr *shdr; struct scst_order_data *o; struct scst_cmd *c; - BUILD_BUG_ON(SCST_SENSE_BUFFERSIZE < sizeof(*shdr)); + + BUILD_BUG_ON(sizeof(*shdr) > SCST_SENSE_BUFFERSIZE); BUILD_BUG_ON(sizeof(o->curr_sn) != sizeof(o->expected_sn)); BUILD_BUG_ON(sizeof(c->sn) != sizeof(o->expected_sn)); } @@ -2606,6 +2611,7 @@ static int __init init_scst(void) if (scst_max_cmd_mem == 0) { struct sysinfo si; + si_meminfo(&si); #if BITS_PER_LONG == 32 scst_max_cmd_mem = min( @@ -2679,7 +2685,6 @@ static int __init init_scst(void) goto out_thread_free; #endif - PRINT_INFO("SCST version %s loaded successfully (max mem for " "commands %dMB, per device %dMB)", SCST_VERSION_STRING, scst_max_cmd_mem, scst_max_dev_cmd_mem); diff --git a/scst/src/scst_mem.c b/scst/src/scst_mem.c index 1706acb78..9800d1a65 100644 --- a/scst/src/scst_mem.c +++ b/scst/src/scst_mem.c @@ -675,6 +675,7 @@ static int sgv_alloc_sg_entries(struct scatterlist *sg, int pages, pg = 0; for (i = 0; i < pages; i++) { int n = PAGE_ALIGN(sg[i].length) >> PAGE_SHIFT; + trans_tbl[i].pg_count = pg; for (j = 0; j < n; j++) trans_tbl[pg++].sg_num = i+1; @@ -972,6 +973,7 @@ struct scatterlist *sgv_pool_alloc(struct sgv_pool *pool, unsigned int size, pages = PAGE_ALIGN(size) >> PAGE_SHIFT; if (pool->single_alloc_pages == 0) { int pages_order = get_order(size); + cache_num = pages_order; pages_to_alloc = (1 << pages_order); } else { @@ -1128,6 +1130,7 @@ struct scatterlist *sgv_pool_alloc(struct sgv_pool *pool, unsigned int size, success: if (cache_num >= 0) { int sg; + atomic_inc(&pool->cache_acc[cache_num].total_alloc); if (sgv_pool_clustered(pool)) cnt = obj->trans_tbl[pages-1].sg_num; @@ -1255,10 +1258,12 @@ void sgv_pool_free(struct sgv_pool_obj *obj, struct scst_mem_lim *mem_lim) { struct scatterlist *sg = obj->sg_entries; int i; + for (i = 0; i < obj->sg_count; i++) { struct page *p = sg_page(&sg[i]); int len = sg[i].length; int pages = PAGE_ALIGN(len) >> PAGE_SHIFT; + while (pages > 0) { if (page_count(p) != 1) { PRINT_WARNING("Freeing page %p with " @@ -1327,7 +1332,7 @@ struct scatterlist *scst_alloc_sg(int size, gfp_t gfp_mask, int *count) } } - res = kmalloc(pages*sizeof(*res), gfp_mask); + res = kmalloc_array(pages, sizeof(*res), gfp_mask); if (res == NULL) { TRACE(TRACE_OUT_OF_MEM, "Unable to allocate sg for %d pages", pages); diff --git a/scst/src/scst_pres.c b/scst/src/scst_pres.c index 037c0d462..8ce467d6e 100644 --- a/scst/src/scst_pres.c +++ b/scst/src/scst_pres.c @@ -103,6 +103,7 @@ static inline void tid_secure(uint8_t *tid) { if ((tid[0] & 0x0f) == SCSI_TRANSPORTID_PROTOCOLID_ISCSI) { int size = scst_tid_size(tid); + tid[size - 1] = '\0'; } @@ -137,6 +138,7 @@ bool tid_equal(const uint8_t *tid_a, const uint8_t *tid_b) else if (tid_a_fmt == 0x40) { if (tid_a_fmt != tid_b_fmt) { uint8_t *p = strnchr(tid_a, tid_a_max, ','); + if (p == NULL) goto out_error; tid_a_len = p - tid_a; @@ -153,6 +155,7 @@ bool tid_equal(const uint8_t *tid_a, const uint8_t *tid_b) else if (tid_b_fmt == 0x40) { if (tid_a_fmt != tid_b_fmt) { uint8_t *p = strnchr(tid_b, tid_b_max, ','); + if (p == NULL) goto out_error; tid_b_len = p - tid_b; @@ -243,6 +246,7 @@ void scst_pr_dump_prs(struct scst_device *dev, bool force) else { struct scst_dev_registrant *reg; int i = 0; + list_for_each_entry(reg, &dev->dev_registrants_list, dev_registrants_list_entry) { PRINT_INFO(" [%d] registrant %s/%d, key %016llx " @@ -256,6 +260,7 @@ void scst_pr_dump_prs(struct scst_device *dev, bool force) if (dev->pr_is_set) { struct scst_dev_registrant *holder = dev->pr_holder; + if (holder != NULL) PRINT_INFO("Reservation holder is %s/%d (key %016llx, " "scope %x, type %x, reg %p, tgt_dev %p)", @@ -629,6 +634,7 @@ static void scst_pr_abort_reg(struct scst_device *dev, if ((reg->tgt_dev != pr_cmd->tgt_dev) && !dev->tas) { uint8_t sense_buffer[SCST_STANDARD_SENSE_LEN]; int sl; + sl = scst_set_sense(sense_buffer, sizeof(sense_buffer), dev->d_sense, SCST_LOAD_SENSE(scst_sense_cleared_by_another_ini_UA)); @@ -688,11 +694,11 @@ static int scst_pr_do_load_device_file(struct scst_device *dev, inode = file_inode(file); - if (S_ISREG(inode->i_mode)) - /* Nothing to do */; - else if (S_ISBLK(inode->i_mode)) + if (S_ISREG(inode->i_mode)) { + /* Nothing to do */ + } else if (S_ISBLK(inode->i_mode)) { inode = inode->i_bdev->bd_inode; - else { + } else { PRINT_ERROR("Invalid file mode 0x%x", inode->i_mode); goto out_close; } diff --git a/scst/src/scst_priv.h b/scst/src/scst_priv.h index f0606d677..327504f35 100644 --- a/scst/src/scst_priv.h +++ b/scst/src/scst_priv.h @@ -406,7 +406,10 @@ static inline int scst_dlm_new_lockspace(const char *name, int namelen, uint32_t flags, int lvblen) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) + return dlm_new_lockspace((char *)name, namelen, lockspace, flags, + lvblen); +#elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0) return dlm_new_lockspace(name, namelen, lockspace, flags, lvblen); #else return dlm_new_lockspace(name, NULL, flags, lvblen, NULL, NULL, NULL, @@ -718,8 +721,10 @@ bool __scst_check_blocked_dev(struct scst_cmd *cmd); void __scst_check_unblock_dev(struct scst_cmd *cmd); void scst_check_unblock_dev(struct scst_cmd *cmd); -int scst_ext_block_dev(struct scst_device *dev, bool sync, - ext_blocker_done_fn_t done_fn, const uint8_t *priv, int priv_len); +#define SCST_EXT_BLOCK_SYNC 1 +#define SCST_EXT_BLOCK_STPG 2 +int scst_ext_block_dev(struct scst_device *dev, ext_blocker_done_fn_t done_fn, + const uint8_t *priv, int priv_len, int flags); 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); @@ -753,6 +758,7 @@ static inline atomic_t *scst_get(void) static inline void scst_put(atomic_t *a) { int f; + f = atomic_dec_and_test(a); /* See comment about smp_mb() in scst_suspend_activity() */ if (unlikely(test_bit(SCST_FLAG_SUSPENDED, &scst_flags)) && f) { @@ -855,7 +861,11 @@ void scst_cm_free_descriptors(struct scst_cmd *cmd); int scst_cm_ext_copy_exec(struct scst_cmd *cmd); int scst_cm_rcv_copy_res_exec(struct scst_cmd *cmd); -void sess_cm_list_id_cleanup_work_fn(struct delayed_work *work); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) +void sess_cm_list_id_cleanup_work_fn(void *p); +#else +void sess_cm_list_id_cleanup_work_fn(struct work_struct *work); +#endif void scst_cm_free_pending_list_ids(struct scst_session *sess); bool scst_cm_check_block_all_devs(struct scst_cmd *cmd); diff --git a/scst/src/scst_proc.c b/scst/src/scst_proc.c index a7f2169b5..1d4dc3c25 100644 --- a/scst/src/scst_proc.c +++ b/scst/src/scst_proc.c @@ -1399,7 +1399,7 @@ static ssize_t scst_proc_scsi_tgt_write(struct file *file, TRACE_ENTRY(); if (vtt->tgtt->write_proc == NULL) { - res = -ENOSYS; + res = -ENOTSUPP; goto out; } @@ -1554,7 +1554,7 @@ static ssize_t scst_proc_scsi_dev_handler_write(struct file *file, TRACE_ENTRY(); if (dev_type->write_proc == NULL) { - res = -ENOSYS; + res = -ENOTSUPP; goto out; } diff --git a/scst/src/scst_sysfs.c b/scst/src/scst_sysfs.c index c67891ee3..9b7336dd8 100644 --- a/scst/src/scst_sysfs.c +++ b/scst/src/scst_sysfs.c @@ -272,11 +272,7 @@ static int scst_write_trace(const char *buf, size_t length, } break; case SCST_TRACE_ACTION_VALUE: -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) res = kstrtoul(p, 0, &level); -#else - res = strict_strtoul(p, 0, &level); -#endif if (res != 0) { PRINT_ERROR("Invalid trace value \"%s\"", p); res = -EINVAL; @@ -668,9 +664,11 @@ static int scst_check_tgt_acg_ptrs(struct scst_tgt *tgt, struct scst_acg *acg) list_for_each_entry(tgtt, &scst_template_list, scst_template_list_entry) { struct scst_tgt *t; + list_for_each_entry(t, &tgtt->tgt_list, tgt_list_entry) { if (t == tgt) { struct scst_acg *a; + if (acg == NULL) goto out; if (acg == tgt->default_acg) @@ -783,8 +781,8 @@ static ssize_t scst_show(struct kobject *kobj, struct attribute *attr, char *buf) { struct kobj_attribute *kobj_attr; - kobj_attr = container_of(attr, struct kobj_attribute, attr); + kobj_attr = container_of(attr, struct kobj_attribute, attr); return kobj_attr->show(kobj, kobj_attr, buf); } @@ -792,8 +790,8 @@ static ssize_t scst_store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t count) { struct kobj_attribute *kobj_attr; - kobj_attr = container_of(attr, struct kobj_attribute, attr); + kobj_attr = container_of(attr, struct kobj_attribute, attr); if (kobj_attr->store) return kobj_attr->store(kobj, kobj_attr, buf, count); else @@ -1073,6 +1071,7 @@ static ssize_t scst_tgtt_dif_capable_show(struct kobject *kobj, if (tgtt->supported_dif_block_sizes) { const int *p = tgtt->supported_dif_block_sizes; int j; + pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, "Supported blocks: "); j = pos; @@ -1330,11 +1329,7 @@ static int __scst_process_luns_mgmt_store(char *buffer, bool dev_replaced = 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)", p, res); goto out_unlock; @@ -1375,13 +1370,9 @@ static int __scst_process_luns_mgmt_store(char *buffer, goto out_unlock; } -#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_unlock; } @@ -1448,11 +1439,7 @@ static int __scst_process_luns_mgmt_store(char *buffer, } case SCST_LUN_ACTION_DEL: p = scst_get_next_lexem(&pp); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) res = kstrtoul(p, 0, &virt_lun); -#else - res = strict_strtoul(p, 0, &virt_lun); -#endif if (res != 0) goto out_unlock; @@ -1764,11 +1751,7 @@ static ssize_t __scst_acg_io_grouping_type_store(struct scst_acg *acg, min_t(int, strlen(SCST_IO_GROUPING_NEVER_STR), count)) == 0) io_grouping_type = SCST_IO_GROUPING_NEVER; else { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) res = kstrtol(buf, 0, &io_grouping_type); -#else - res = strict_strtol(buf, 0, &io_grouping_type); -#endif if ((res != 0) || (io_grouping_type <= 0)) { PRINT_ERROR("Unknown or not allowed I/O grouping type " "%s", buf); @@ -1893,9 +1876,11 @@ static ssize_t __scst_acg_black_hole_store(struct scst_acg *acg, list_for_each_entry(sess, &acg->acg_sess_list, acg_sess_list_entry) { int i; + for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &sess->sess_tgt_dev_list[i]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { if (t != SCST_ACG_BLACK_HOLE_NONE) set_bit(SCST_TGT_DEV_BLACK_HOLE, &tgt_dev->tgt_dev_flags); @@ -1991,9 +1976,11 @@ static int __scst_acg_process_cpu_mask_store(struct scst_tgt *tgt, list_for_each_entry(sess, &acg->acg_sess_list, acg_sess_list_entry) { int i; + 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(tgt_dev, head, sess_tgt_dev_list_entry) { int rc; @@ -2470,11 +2457,7 @@ static ssize_t scst_rel_tgt_id_store(struct kobject *kobj, tgt = container_of(kobj, struct scst_tgt, tgt_kobj); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) res = kstrtoul(buf, 0, &rel_tgt_id); -#else - res = strict_strtoul(buf, 0, &rel_tgt_id); -#endif if (res != 0) { PRINT_ERROR("%s", "Wrong rel_tgt_id"); res = -EINVAL; @@ -2562,9 +2545,11 @@ static ssize_t scst_tgt_forwarding_store(struct kobject *kobj, list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) { int i; + for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &sess->sess_tgt_dev_list[i]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { if (tgt->tgt_forwarding) set_bit(SCST_TGT_DEV_FORWARDING, &tgt_dev->tgt_dev_flags); @@ -2727,6 +2712,7 @@ static ssize_t scst_tgt_dif_capable_show(struct kobject *kobj, if (tgt->tgt_supported_dif_block_sizes) { const int *p = tgt->tgt_supported_dif_block_sizes; int j; + pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, "Supported blocks: "); j = pos; @@ -3337,13 +3323,9 @@ static ssize_t scst_dev_sysfs_threads_num_store(struct kobject *kobj, dev = container_of(kobj, struct scst_device, dev_kobj); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) res = kstrtol(buf, 0, &newtn); -#else - res = strict_strtol(buf, 0, &newtn); -#endif if (res != 0) { - PRINT_ERROR("strict_strtol() for %s failed: %d ", buf, res); + PRINT_ERROR("kstrtol() for %s failed: %d ", buf, res); goto out; } if (newtn < 0) { @@ -3578,10 +3560,10 @@ static ssize_t scst_dev_block_store(struct kobject *kobj, "data_len %d)", dev->virt_name, sync, data_start, data_len); if (sync) - res = scst_ext_block_dev(dev, true, NULL, NULL, 0); + res = scst_ext_block_dev(dev, NULL, NULL, 0, SCST_EXT_BLOCK_SYNC); else - res = scst_ext_block_dev(dev, false, scst_sysfs_ext_blocking_done, - data_start, data_len); + res = scst_ext_block_dev(dev, scst_sysfs_ext_blocking_done, + data_start, data_len, 0); if (res != 0) goto out; @@ -3898,11 +3880,7 @@ static ssize_t scst_dev_sysfs_dif_static_app_tag_store(struct kobject *kobj, dev = container_of(kobj, struct scst_device, dev_kobj); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) res = kstrtoull(buf, 0, &val); -#else - res = strict_strtoull(buf, 0, &val); -#endif if (res != 0) { PRINT_ERROR("strtoul() for %s failed: %d (device %s)", buf, res, dev->virt_name); @@ -4463,6 +4441,7 @@ static int scst_sess_zero_latency(struct scst_sysfs_work_item *work) for (t = SESS_TGT_DEV_LIST_HASH_SIZE-1; t >= 0; t--) { struct list_head *head = &sess->sess_tgt_dev_list[t]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { tgt_dev->scst_time = 0; tgt_dev->tgt_time = 0; @@ -4546,6 +4525,7 @@ static int scst_sysfs_sess_get_active_commands(struct scst_session *sess) for (t = SESS_TGT_DEV_LIST_HASH_SIZE-1; t >= 0; t--) { struct list_head *head = &sess->sess_tgt_dev_list[t]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { active_cmds += atomic_read(&tgt_dev->tgt_dev_cmd_count); } @@ -4615,6 +4595,7 @@ static int scst_sysfs_sess_get_dif_checks_failed_work_fn(struct scst_sysfs_work_ for (t = SESS_TGT_DEV_LIST_HASH_SIZE-1; t >= 0; t--) { struct list_head *head = &sess->sess_tgt_dev_list[t]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { app_failed_tgt += atomic_read(&tgt_dev->tgt_dev_dif_app_failed_tgt); ref_failed_tgt += atomic_read(&tgt_dev->tgt_dev_dif_ref_failed_tgt); @@ -4695,6 +4676,7 @@ static int scst_sess_zero_dif_checks_failed(struct scst_sysfs_work_item *work) for (t = SESS_TGT_DEV_LIST_HASH_SIZE-1; t >= 0; t--) { struct list_head *head = &sess->sess_tgt_dev_list[t]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { atomic_set(&tgt_dev->tgt_dev_dif_app_failed_tgt, 0); atomic_set(&tgt_dev->tgt_dev_dif_ref_failed_tgt, 0); @@ -6297,11 +6279,7 @@ static ssize_t scst_tg_tgt_rel_tgt_id_store(struct kobject *kobj, TRACE_ENTRY(); tg_tgt = container_of(kobj, struct scst_tg_tgt, kobj); snprintf(ch, sizeof(ch), "%.*s", min_t(int, count, sizeof(ch)-1), buf); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) res = kstrtoul(ch, 0, &rel_tgt_id); -#else - res = strict_strtoul(ch, 0, &rel_tgt_id); -#endif if (res) goto out; res = -EINVAL; @@ -6391,11 +6369,7 @@ static ssize_t scst_tg_group_id_store(struct kobject *kobj, TRACE_ENTRY(); tg = container_of(kobj, struct scst_target_group, kobj); snprintf(ch, sizeof(ch), "%.*s", min_t(int, count, sizeof(ch)-1), buf); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) res = kstrtoul(ch, 0, &group_id); -#else - res = strict_strtoul(ch, 0, &group_id); -#endif if (res) goto out; res = -EINVAL; @@ -6433,11 +6407,7 @@ static int scst_tg_preferred_store_work_fn(struct scst_sysfs_work_item *w) TRACE_ENTRY(); cmd = w->buf; tg = container_of(w->kobj, struct scst_target_group, kobj); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) res = kstrtoul(cmd, 0, &preferred); -#else - res = strict_strtoul(cmd, 0, &preferred); -#endif if (res) goto out; res = -EINVAL; @@ -6971,13 +6941,9 @@ static ssize_t scst_threads_store(struct kobject *kobj, TRACE_ENTRY(); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) res = kstrtol(buf, 0, &newtn); -#else - res = strict_strtol(buf, 0, &newtn); -#endif if (res != 0) { - PRINT_ERROR("strict_strtol() for %s failed: %d ", buf, res); + PRINT_ERROR("kstrtol() for %s failed: %d ", buf, res); goto out; } if (newtn <= 0) { @@ -7027,13 +6993,9 @@ static ssize_t scst_setup_id_store(struct kobject *kobj, TRACE_ENTRY(); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) res = kstrtoul(buf, 0, &val); -#else - res = strict_strtoul(buf, 0, &val); -#endif if (res != 0) { - PRINT_ERROR("strict_strtoul() for %s failed: %d ", buf, res); + PRINT_ERROR("kstrtoul() for %s failed: %d ", buf, res); goto out; } @@ -7074,13 +7036,9 @@ static ssize_t scst_max_tasklet_cmd_store(struct kobject *kobj, TRACE_ENTRY(); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) res = kstrtoul(buf, 0, &val); -#else - res = strict_strtoul(buf, 0, &val); -#endif if (res != 0) { - PRINT_ERROR("strict_strtoul() for %s failed: %d ", buf, res); + PRINT_ERROR("kstrtoul() for %s failed: %d ", buf, res); goto out; } @@ -7537,10 +7495,9 @@ int scst_wait_info_completion(struct scst_sysfs_user_info *info, break; } } else if (rc != -ERESTARTSYS) { - res = rc; - PRINT_ERROR("wait_for_completion() failed: %d", - res); - goto out; + res = rc; + PRINT_ERROR("wait_for_completion() failed: %d", res); + goto out; } else { TRACE_DBG("Waiting for info %p finished with %d, " "retrying", info, rc); diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index f6d8a01e7..3f3ee4d24 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -117,6 +117,7 @@ static bool scst_unmap_overlap(struct scst_cmd *cmd, int64_t lba2, for (i = 0; pd[i].sdd_blocks != 0; i++) { struct scst_data_descriptor *d = &pd[i]; + TRACE_DBG("i %d, lba %lld, blocks %lld", i, (long long)d->sdd_lba, (long long)d->sdd_blocks); res = scst_lba1_inside_lba2(d->sdd_lba, lba2, lba2_blocks); @@ -292,6 +293,7 @@ static bool scst_check_scsi_atomicity(struct scst_cmd *chk_cmd) continue; if (scst_cmd_overlap(chk_cmd, cmd)) { struct scst_cmd **p = cmd->scsi_atomic_blocked_cmds; + /* * kmalloc() allocates by at least 32 bytes increments, * hence krealloc() on 8 bytes increments, if not all @@ -328,6 +330,7 @@ out: out_busy_undo: list_for_each_entry(cmd, &dev->dev_exec_cmd_list, dev_exec_cmd_list_entry) { struct scst_cmd **p = cmd->scsi_atomic_blocked_cmds; + if ((p != NULL) && (p[cmd->scsi_atomic_blocked_cmds_count-1] == chk_cmd)) { cmd->scsi_atomic_blocked_cmds_count--; chk_cmd->scsi_atomic_blockers--; @@ -472,6 +475,7 @@ static void scst_check_unblock_scsi_atomic_cmds(struct scst_cmd *cmd) for (i = 0; i < cmd->scsi_atomic_blocked_cmds_count; i++) { struct scst_cmd *acmd = cmd->scsi_atomic_blocked_cmds[i]; + acmd->scsi_atomic_blockers--; if (acmd->scsi_atomic_blockers == 0) { TRACE_BLOCK("Unblocking blocked acmd %p (blocker " @@ -543,6 +547,7 @@ void __scst_check_unblock_dev(struct scst_cmd *cmd) TRACE_BLOCK("Strictly serialized cmd waiting: " "unblocking dev %s", dev->virt_name); scst_unblock_dev(dev); + dev->strictly_serialized_cmd_waiting = 0; } } @@ -766,6 +771,7 @@ out_redirect: msleep(50); } else { unsigned long flags; + spin_lock_irqsave(&scst_init_lock, flags); TRACE_DBG("Adding cmd %p to init cmd list", cmd); list_add_tail(&cmd->cmd_list_entry, &scst_init_cmd_list); @@ -1401,6 +1407,7 @@ out_check_compl: if (unlikely(test_bit(SCST_TGT_DEV_BLACK_HOLE, &cmd->tgt_dev->tgt_dev_flags))) { struct scst_session *sess = cmd->sess; bool abort = false; + switch (sess->acg->acg_black_hole_type) { case SCST_ACG_BLACK_HOLE_CMD: case SCST_ACG_BLACK_HOLE_ALL: @@ -1803,6 +1810,7 @@ static int scst_rdy_to_xfer(struct scst_cmd *cmd) if (tgtt->on_hw_pending_cmd_timeout != NULL) { struct scst_session *sess = cmd->sess; + cmd->hw_pending_start = jiffies; cmd->cmd_hw_pending = 1; if (!test_bit(SCST_SESS_HW_PENDING_WORK_SCHEDULED, &sess->sess_aflags)) { @@ -2062,6 +2070,7 @@ static int scst_tgt_pre_exec(struct scst_cmd *cmd) if (unlikely(cmd->resid_possible)) { if (cmd->data_direction & SCST_DATA_WRITE) { bool remainder = false; + if (cmd->data_direction & SCST_DATA_READ) { if (cmd->write_len != cmd->out_bufflen) remainder = true; @@ -2141,6 +2150,7 @@ static int scst_tgt_pre_exec(struct scst_cmd *cmd) out_descr: if (unlikely(cmd->op_flags & SCST_DESCRIPTORS_BASED)) { int r = scst_parse_descriptors(cmd); + if (unlikely(r != 0)) goto out; } @@ -2314,6 +2324,7 @@ static int scst_report_luns_local(struct scst_cmd *cmd) */ for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &cmd->sess->sess_tgt_dev_list[i]; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { if (!overflow) { if ((buffer_size - offs) < 8) { @@ -3153,7 +3164,7 @@ out_unlock: scst_put_buf_full(cmd, buffer); out_done: - if (SCST_EXEC_COMPLETED == res) { + if (res == SCST_EXEC_COMPLETED) { if (!aborted) cmd->completed = 1; cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, @@ -3388,6 +3399,7 @@ static struct scst_cmd *scst_post_exec_sn(struct scst_cmd *cmd, if (inc_expected_sn) { bool rc = scst_inc_expected_sn(cmd); + if (!rc) goto out; if (make_active) @@ -3653,6 +3665,7 @@ static inline bool scst_check_alua(struct scst_cmd *cmd, int *out_res) alua_filter = ACCESS_ONCE(cmd->tgt_dev->alua_filter); if (unlikely(alua_filter)) { int ac = alua_filter(cmd); + if (ac != SCST_ALUA_CHECK_OK) { if (ac != SCST_ALUA_CHECK_DELAYED) { EXTRACHECKS_BUG_ON(cmd->status == 0); @@ -3692,6 +3705,7 @@ static int scst_exec_check_blocking(struct scst_cmd **active_cmd) #ifdef CONFIG_SCST_DEBUG_SN if ((scst_random() % 120) == 7) { int t = scst_random() % 200; + TRACE_SN("Delaying IO on %d ms", t); msleep(t); } @@ -3721,9 +3735,9 @@ static int scst_exec_check_blocking(struct scst_cmd **active_cmd) cmd->state = SCST_CMD_STATE_LOCAL_EXEC; rc = scst_do_local_exec(cmd); - if (likely(rc == SCST_EXEC_NOT_COMPLETED)) - /* Nothing to do */; - else { + if (likely(rc == SCST_EXEC_NOT_COMPLETED)) { + /* Nothing to do */ + } else { sBUG_ON(rc != SCST_EXEC_COMPLETED); goto done; } @@ -3865,6 +3879,7 @@ static int scst_check_sense(struct scst_cmd *cmd) } else { int sl; uint8_t sense[SCST_STANDARD_SENSE_LEN]; + TRACE(TRACE_MGMT, "DID_RESET received for device %s, " "triggering reset UA", dev->virt_name); sl = scst_set_sense(sense, sizeof(sense), dev->d_sense, @@ -4041,6 +4056,7 @@ next: if (likely(scst_cmd_completed_good(cmd))) { if (cmd->deferred_dif_read_check) { int rc = scst_dif_process_read(cmd); + if (unlikely(rc != 0)) { cmd->deferred_dif_read_check = 0; goto again; @@ -4153,6 +4169,7 @@ static int scst_mode_select_checks(struct scst_cmd *cmd) if (likely(scsi_status_is_good(cmd->status))) { int atomic = scst_cmd_atomic(cmd); + if (unlikely((cmd->cdb[0] == MODE_SELECT) || (cmd->cdb[0] == MODE_SELECT_10) || (cmd->cdb[0] == LOG_SELECT))) { @@ -4206,6 +4223,7 @@ static int scst_mode_select_checks(struct scst_cmd *cmd) SCST_SENSE_ASC_VALID, 0, 0x2F, 0))) { int atomic = scst_cmd_atomic(cmd); + if (atomic) { TRACE_DBG("Possible parameters changed UA %x: " "thread context required", cmd->sense[12]); @@ -4315,6 +4333,7 @@ static int scst_dev_done(struct scst_cmd *cmd) if (cmd->inc_expected_sn_on_done && cmd->sent_for_exec && cmd->sn_set) { bool rc = scst_inc_expected_sn(cmd); + if (rc) scst_make_deferred_commands_active(cmd->cur_order_data); } @@ -4478,6 +4497,7 @@ static int scst_xmit_response(struct scst_cmd *cmd) (cmd->data_direction & SCST_DATA_READ)) { int i, sg_cnt; struct scatterlist *sg, *sgi; + if (cmd->tgt_i_sg != NULL) { sg = cmd->tgt_i_sg; sg_cnt = cmd->tgt_i_sg_cnt; @@ -4502,6 +4522,7 @@ static int scst_xmit_response(struct scst_cmd *cmd) if (tgtt->on_hw_pending_cmd_timeout != NULL) { struct scst_session *sess = cmd->sess; + cmd->hw_pending_start = jiffies; cmd->cmd_hw_pending = 1; if (!test_bit(SCST_SESS_HW_PENDING_WORK_SCHEDULED, &sess->sess_aflags)) { @@ -4762,6 +4783,7 @@ again: order_data->cur_sn_slot = order_data->sn_slots; if (unlikely(atomic_read(order_data->cur_sn_slot) != 0)) { static int q; + if (q++ < 10) PRINT_WARNING("Not enough SN slots " "(dev %s)", cmd->dev->virt_name); @@ -5002,6 +5024,7 @@ static int __scst_init_cmd(struct scst_cmd *cmd) else { struct scst_order_data *order_data = cmd->cur_order_data; unsigned long flags; + spin_lock_irqsave(&order_data->init_done_lock, flags); scst_cmd_set_sn(cmd); spin_unlock_irqrestore(&order_data->init_done_lock, flags); @@ -5046,6 +5069,7 @@ restart: list_for_each_entry(cmd, &scst_init_cmd_list, cmd_list_entry) { int rc; + if (susp && !test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags)) continue; if (!test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags)) { @@ -5922,6 +5946,7 @@ void scst_abort_cmd(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd, if (mstb->done_counted || mstb->finish_counted) { unsigned long t; char state_name[32]; + if (mcmd->fn != SCST_PR_ABORT_ALL) t = TRACE_MGMT; else @@ -6009,6 +6034,7 @@ static int scst_set_mcmd_next_state(struct scst_mgmt_cmd *mcmd) default: { char fn_name[16], state_name[32]; + PRINT_CRIT_ERROR("Wrong mcmd %p state %s (fn %s, " "cmd_finish_wait_count %d, cmd_done_wait_count %d)", mcmd, scst_get_mcmd_state_name(state_name, @@ -6033,6 +6059,7 @@ static bool __scst_check_unblock_aborted_cmd(struct scst_cmd *cmd, struct list_head *list_entry, bool blocked) { bool res; + if (test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags)) { list_del(list_entry); if (blocked) @@ -6090,6 +6117,7 @@ void scst_unblock_aborted_cmds(const struct scst_tgt *tgt, list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list, dev_tgt_dev_list_entry) { struct scst_order_data *order_data = tgt_dev->curr_order_data; + spin_lock(&order_data->sn_lock); list_for_each_entry_safe(cmd, tcmd, &order_data->deferred_cmd_list, @@ -6306,8 +6334,10 @@ static int scst_clear_task_set(struct scst_mgmt_cmd *mcmd) return res; } -/* Returns 0 if the command processing should be continued, - * >0, if it should be requeued, <0 otherwise */ +/* + * Returns 0 if the command processing should be continued, + * >0, if it should be requeued, <0 otherwise. + */ static int scst_mgmt_cmd_init(struct scst_mgmt_cmd *mcmd) { int res = 0, rc, t; @@ -6588,6 +6618,7 @@ static void scst_do_nexus_loss_sess(struct scst_mgmt_cmd *mcmd) for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &sess->sess_tgt_dev_list[i]; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { scst_nexus_loss(tgt_dev, (mcmd->fn != SCST_UNREG_SESS_TM)); @@ -6621,6 +6652,7 @@ static int scst_abort_all_nexus_loss_sess(struct scst_mgmt_cmd *mcmd, for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &sess->sess_tgt_dev_list[i]; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { __scst_abort_task_set(mcmd, tgt_dev); @@ -6655,6 +6687,7 @@ static void scst_do_nexus_loss_tgt(struct scst_mgmt_cmd *mcmd) for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &sess->sess_tgt_dev_list[i]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { scst_nexus_loss(tgt_dev, true); @@ -6690,6 +6723,7 @@ static int scst_abort_all_nexus_loss_tgt(struct scst_mgmt_cmd *mcmd, for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &sess->sess_tgt_dev_list[i]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { __scst_abort_task_set(mcmd, tgt_dev); @@ -6882,6 +6916,7 @@ static int scst_mgmt_affected_cmds_done(struct scst_mgmt_cmd *mcmd) { struct scst_acg *acg = sess->acg; struct scst_acg_dev *acg_dev; + mutex_lock(&scst_mutex); list_for_each_entry(acg_dev, &acg->acg_dev_list, acg_dev_list_entry) { dev = acg_dev->dev; @@ -6903,6 +6938,7 @@ static int scst_mgmt_affected_cmds_done(struct scst_mgmt_cmd *mcmd) mutex_lock(&scst_mutex); for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &sess->sess_tgt_dev_list[i]; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { scst_call_dev_task_mgmt_fn_done(mcmd, tgt_dev); } @@ -6915,11 +6951,13 @@ static int scst_mgmt_affected_cmds_done(struct scst_mgmt_cmd *mcmd) { struct scst_session *s; struct scst_tgt *tgt = sess->tgt; + mutex_lock(&scst_mutex); list_for_each_entry(s, &tgt->sess_list, sess_list_entry) { for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &s->sess_tgt_dev_list[i]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { if (mcmd->sess == tgt_dev->sess) @@ -7071,6 +7109,7 @@ static int scst_process_mgmt_cmd(struct scst_mgmt_cmd *mcmd) default: { char fn_name[16], state_name[32]; + PRINT_CRIT_ERROR("Wrong mcmd %p state %s (fn %s, " "cmd_finish_wait_count %d, cmd_done_wait_count " "%d)", mcmd, scst_get_mcmd_state_name(state_name, @@ -7114,6 +7153,7 @@ int scst_tm_thread(void *arg) while (!list_empty(&scst_active_mgmt_cmd_list)) { int rc; struct scst_mgmt_cmd *mcmd; + mcmd = list_first_entry(&scst_active_mgmt_cmd_list, typeof(*mcmd), mgmt_cmd_list_entry); TRACE_MGMT_DBG("Deleting mgmt cmd %p from active cmd " @@ -8112,6 +8152,7 @@ struct scst_cmd *scst_find_cmd_by_tag(struct scst_session *sess, { unsigned long flags; struct scst_cmd *cmd; + spin_lock_irqsave(&sess->sess_list_lock, flags); cmd = __scst_find_cmd_by_tag(sess, tag, false); spin_unlock_irqrestore(&sess->sess_list_lock, flags); diff --git a/scst/src/scst_tg.c b/scst/src/scst_tg.c index 20a469939..4029fcefb 100644 --- a/scst/src/scst_tg.c +++ b/scst/src/scst_tg.c @@ -21,11 +21,12 @@ #include #ifdef INSIDE_KERNEL_TREE #include +#include #else #include "scst.h" +#include "scst_event.h" #endif #include "scst_priv.h" -#include "scst_event.h" #include "scst_pres.h" struct alua_state_and_name { @@ -396,13 +397,24 @@ out: struct scst_alua_retry { struct scst_cmd *alua_retry_cmd; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) + struct work_struct alua_retry_work; +#else struct delayed_work alua_retry_work; +#endif }; -static void scst_alua_transitioning_work_fn(struct delayed_work *work) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) +static void scst_alua_transitioning_work_fn(void *p) { - struct scst_alua_retry *retry = container_of(work, struct scst_alua_retry, - alua_retry_work); + struct scst_alua_retry *retry = p; +#else +static void scst_alua_transitioning_work_fn(struct work_struct *work) +{ + struct scst_alua_retry *retry = + container_of(work, struct scst_alua_retry, + alua_retry_work.work); +#endif struct scst_cmd *cmd = retry->alua_retry_cmd; TRACE_ENTRY(); @@ -467,8 +479,13 @@ static int scst_tg_accept_transitioning(struct scst_cmd *cmd) /* No get is needed, because cmd is sync here */ retry->alua_retry_cmd = cmd; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) + INIT_WORK(&retry->alua_retry_work, + scst_alua_transitioning_work_fn, retry); +#else INIT_DELAYED_WORK(&retry->alua_retry_work, - (void (*)(struct work_struct *))scst_alua_transitioning_work_fn); + scst_alua_transitioning_work_fn); +#endif cmd->already_transitioning = 1; schedule_delayed_work(&retry->alua_retry_work, HZ/2); res = SCST_ALUA_CHECK_DELAYED; @@ -905,6 +922,7 @@ static void scst_event_stpg_notify_fn(struct scst_event *event, for (i = 0, d = &p->stpg_descriptors[0]; i < p->stpg_descriptors_cnt; i++, d++) { struct scst_target_group *tg = __lookup_tg_by_group_id(dg, d->group_id); + if (!tg) { PRINT_ERROR("STPG: unable to find TG %d", d->group_id); goto out_fail; @@ -966,9 +984,10 @@ static void __scst_tg_set_state(struct scst_target_group *tg, list_for_each_entry(tg_tgt, &tg->tgt_list, entry) { if (tg_tgt->tgt == tgt) { bool gen_ua = (state != SCST_TG_STATE_TRANSITIONING); - 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; + + 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; scst_tg_change_tgt_dev_state(tgt_dev, state, gen_ua); break; @@ -1687,7 +1706,13 @@ int scst_tg_set_group_info(struct scst_cmd *cmd) TRACE_DBG("dg %s (%p) found, dev %s", dg->name, dg, dev->virt_name); for (i = 4, j = 0; i + 4 <= len; i += 4, j++) { +#ifndef __CHECKER__ + /* + * Hide the statement below for smatch because otherwise it + * triggers a false positive. + */ WARN_ON_ONCE(j >= tpg_desc_count); +#endif osi[j].new_state = buf[i] & 0x1f; switch (osi[j].new_state) { case SCST_TG_STATE_OPTIMIZED: @@ -1843,17 +1868,11 @@ int scst_tg_set_group_info(struct scst_cmd *cmd) atomic_inc(&wait->stpg_wait_left); - spin_lock_bh(&dev->dev_lock); - WARN_ON(dgd->dev->stpg_ext_blocked); - dgd->dev->stpg_ext_blocked = 1; - spin_unlock_bh(&dev->dev_lock); - - rc = scst_ext_block_dev(dgd->dev, false, - scst_stpg_ext_blocking_done, (uint8_t *)&wait, - sizeof(wait)); + rc = scst_ext_block_dev(dgd->dev, scst_stpg_ext_blocking_done, + (uint8_t *)&wait, sizeof(wait), SCST_EXT_BLOCK_STPG); if (rc != 0) { - TRACE_DBG("scst_ext_block_dev() returned %d, " - "stepping back (cmd %p)", rc, cmd); + TRACE_DBG("scst_ext_block_dev() failed " + "with %d, reverting (cmd %p)", rc, cmd); wait->status = rc; wait->dg = dg; atomic_dec(&wait->stpg_wait_left); diff --git a/scst_local/scst_local.c b/scst_local/scst_local.c index eca959e8b..278c3588e 100644 --- a/scst_local/scst_local.c +++ b/scst_local/scst_local.c @@ -446,11 +446,7 @@ static ssize_t scst_local_scsi_transport_version_store(struct kobject *kobj, if (!tgt) goto out_up; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) res = kstrtoul(buffer, 0, &val); -#else - res = strict_strtoul(buffer, 0, &val); -#endif if (res != 0) { PRINT_ERROR("strtoul() for %s failed: %zd", buffer, res); goto out_up; @@ -516,11 +512,7 @@ static ssize_t scst_local_phys_transport_version_store(struct kobject *kobj, if (!tgt) goto out_up; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) res = kstrtoul(buffer, 0, &val); -#else - res = strict_strtoul(buffer, 0, &val); -#endif if (res != 0) { PRINT_ERROR("strtoul() for %s failed: %zd", buffer, res); goto out_up; @@ -778,6 +770,7 @@ static ssize_t scst_local_sysfs_mgmt_cmd(char *buf) res = __scst_local_add_adapter(tgt, session_name, true); } else if (strcasecmp("del_session", command) == 0) { struct scst_local_sess *s, *sess = NULL; + list_for_each_entry(s, &tgt->sessions_list, sessions_list_entry) { if (strcmp(s->scst_sess->initiator_name, session_name) == 0) { @@ -897,8 +890,7 @@ static void scst_local_copy_sense(struct scsi_cmnd *cmnd, struct scst_cmd *scst_ TRACE_ENTRY(); - scst_cmnd_sense_len = (SCSI_SENSE_BUFFERSIZE < scst_cmnd_sense_len ? - SCSI_SENSE_BUFFERSIZE : scst_cmnd_sense_len); + scst_cmnd_sense_len = min(scst_cmnd_sense_len, SCSI_SENSE_BUFFERSIZE); memcpy(cmnd->sense_buffer, scst_cmd_get_sense_buffer(scst_cmnd), scst_cmnd_sense_len); @@ -1671,7 +1663,7 @@ static int scst_local_driver_probe(struct device *dev) TRACE_DBG("sess %p", sess); hpnt = scsi_host_alloc(&scst_lcl_ini_driver_template, sizeof(*sess)); - if (NULL == hpnt) { + if (hpnt == NULL) { PRINT_ERROR("%s", "scsi_register() failed"); ret = -ENODEV; goto out; @@ -1828,7 +1820,7 @@ static int __scst_local_add_adapter(struct scst_local_tgt *tgt, /* It's read-mostly, so cache alignment isn't needed */ sess = kzalloc(sizeof(*sess), GFP_KERNEL); - if (NULL == sess) { + if (sess == NULL) { PRINT_ERROR("Unable to alloc scst_lcl_host (size %zu)", sizeof(*sess)); res = -ENOMEM; @@ -1947,7 +1939,7 @@ static int scst_local_add_target(const char *target_name, TRACE_ENTRY(); tgt = kzalloc(sizeof(*tgt), GFP_KERNEL); - if (NULL == tgt) { + if (tgt == NULL) { PRINT_ERROR("Unable to alloc tgt (size %zu)", sizeof(*tgt)); res = -ENOMEM; goto out; diff --git a/scstadmin/scstadmin.sysfs/scst-0.9.10/t/03-targets.t b/scstadmin/scstadmin.sysfs/scst-0.9.10/t/03-targets.t index f1b6bcac7..d07b11a34 100644 --- a/scstadmin/scstadmin.sysfs/scst-0.9.10/t/03-targets.t +++ b/scstadmin/scstadmin.sysfs/scst-0.9.10/t/03-targets.t @@ -24,6 +24,7 @@ sub addTargets { my $all_hw_tgt = 1; for my $driver (@{$drivers}) { + next if $driver eq 'copy_manager'; my ($targets, $errorString) = $SCST->targets($driver); for my $target (@{$targets}) { if ($SCST->targetType($driver, $target) != diff --git a/scstadmin/scstadmin.sysfs/scstadmin b/scstadmin/scstadmin.sysfs/scstadmin index 60d609717..7c7a7939e 100755 --- a/scstadmin/scstadmin.sysfs/scstadmin +++ b/scstadmin/scstadmin.sysfs/scstadmin @@ -1423,6 +1423,8 @@ sub writeConfiguration { } foreach my $driver (sort keys %{$CURRENT{'assign'}}) { + next if $driver eq 'copy_manager'; + my $driver_buff; my ($drv_attrs, $errorString) = $SCST->driverAttributes($driver); diff --git a/srpt/src/ib_srpt.c b/srpt/src/ib_srpt.c index 6f34cbe13..a003b16b1 100644 --- a/srpt/src/ib_srpt.c +++ b/srpt/src/ib_srpt.c @@ -852,7 +852,7 @@ static struct srpt_ioctx **srpt_alloc_ioctx_ring(struct srpt_device *sdev, WARN_ON(ioctx_size != sizeof(struct srpt_recv_ioctx) && ioctx_size != sizeof(struct srpt_send_ioctx)); - ring = kmalloc(ring_size * sizeof(ring[0]), GFP_KERNEL); + ring = kmalloc_array(ring_size, sizeof(ring[0]), GFP_KERNEL); if (!ring) goto out; for (i = 0; i < ring_size; ++i) { @@ -1154,8 +1154,8 @@ static int srpt_get_desc_tbl(struct srpt_recv_ioctx *recv_ioctx, if (ioctx->n_rbuf == 1) ioctx->rbufs = &ioctx->single_rbuf; else { - ioctx->rbufs = - kmalloc(ioctx->n_rbuf * sizeof(*db), GFP_ATOMIC); + ioctx->rbufs = kmalloc_array(ioctx->n_rbuf, + sizeof(*db), GFP_ATOMIC); if (!ioctx->rbufs) { ioctx->n_rbuf = 0; ret = -ENOMEM; @@ -1640,7 +1640,7 @@ static int srpt_build_cmd_rsp(struct srpt_rdma_ch *ch, if (!scst_sense_valid(sense_data)) { sense_data_len = 0; } else { - BUILD_BUG_ON(MIN_MAX_RSP_SIZE <= sizeof(*srp_rsp)); + BUILD_BUG_ON(sizeof(*srp_rsp) >= MIN_MAX_RSP_SIZE); max_sense_len = ch->max_ti_iu_len - sizeof(*srp_rsp); if (sense_data_len > max_sense_len) { pr_warn("truncated sense data from %d to %d bytes\n", @@ -4173,7 +4173,7 @@ static void srpt_add_one(struct ib_device *device) #endif sdev->srq = use_srq ? ib_create_srq(sdev->pd, &srq_attr) : - ERR_PTR(-ENOSYS); + ERR_PTR(-ENOTSUPP); if (IS_ERR(sdev->srq)) { pr_debug("ib_create_srq() failed: %ld\n", PTR_ERR(sdev->srq)); diff --git a/usr/Makefile b/usr/Makefile index 85bed6073..cff5548c2 100644 --- a/usr/Makefile +++ b/usr/Makefile @@ -18,8 +18,6 @@ # SHELL=/bin/bash -# Decide to use which kernel src. If not specified, is current running kernel. -#export KDIR=/usr/src/linux-2.6 FILEIO_DIR=fileio STPGD_DIR=stpgd diff --git a/usr/fileio/fileio.c b/usr/fileio/fileio.c index ec19a1980..fbbedbb7c 100644 --- a/usr/fileio/fileio.c +++ b/usr/fileio/fileio.c @@ -65,10 +65,11 @@ char *app_name; # endif #endif /* DEBUG */ -bool log_daemon = false; unsigned long trace_flag = DEFAULT_LOG_FLAGS; #endif /* defined(DEBUG) || defined(TRACING) */ +bool log_daemon = false; + #define DEF_BLOCK_SHIFT 9 #define THREADS 7 diff --git a/usr/include/debug.h b/usr/include/debug.h index bba07f5ef..9bdaddc0d 100644 --- a/usr/include/debug.h +++ b/usr/include/debug.h @@ -82,9 +82,10 @@ extern char *app_name; #define __LOG_PREFIX NULL #endif +extern bool log_daemon; + #if defined(DEBUG) || defined(TRACING) -extern bool log_daemon; extern unsigned long trace_flag; extern int debug_init(void); diff --git a/www/target_lsi.html b/www/target_lsi.html index b460cef78..f086d30ac 100644 --- a/www/target_lsi.html +++ b/www/target_lsi.html @@ -60,9 +60,15 @@

It supports parallel SCSI (SPI), including Wide SCSI, and Fibre Channel, but also should work with SAS. This driver is on the alpha stage and available for download from the SCST SVN repository. See the download page how to setup access to it. -




- + +

Recently Theodore Vaida updated it for the latest hardware generation, including 12G support. You can download current version + from Github.

+ +


+