From bb4d276a54d1f1102a16f7cb4f2216a00c9a18b9 Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Fri, 14 Jul 2017 00:17:31 +0000 Subject: [PATCH] Merged revisions 7096,7101,7104,7106-7111,7115-7118,7125,7134-7137,7139,7141,7143,7152-7154,7158,7162-7163,7168-7171,7173,7175-7179,7185,7190,7193,7203,7208 via svnmerge from svn+ssh://svn.code.sf.net/p/scst/svn/trunk ........ r7096 | bvassche | 2017-02-23 18:08:17 -0800 (Thu, 23 Feb 2017) | 4 lines scst_copy_mgr: Avoid that LUN removal triggers a BUG() Reported-by: Jinpu Wang ........ r7101 | bvassche | 2017-03-01 07:31:59 -0800 (Wed, 01 Mar 2017) | 20 lines scst_vdisk: Avoid that LUN refresh triggers a general protection fault Avoid that triggering LUN referesh concurrently with device deletion triggers the following: general protection fault: 0000 [#1] Workqueue: events vdev_inq_changed_fn [scst_vdisk] Call Trace: _raw_spin_lock_bh+0x2b/0x30 scst_cm_update_dev+0x87/0x190 [scst] scst_dev_inquiry_data_changed+0xfb/0x1b0 [scst] vdev_inq_changed_fn+0x60/0x120 [scst_vdisk] process_one_work+0x14d/0x410 worker_thread+0x66/0x460 kthread+0xdb/0x100 ret_from_fork+0x3f/0x70 Reported-by: Jinpu Wang Tested-by: Jinpu Wang ........ r7104 | vlnb | 2017-03-07 20:36:45 -0800 (Tue, 07 Mar 2017) | 5 lines Linux kernel v4.10 build fix. Signed-off-by: Sebastian Herbszt ........ r7106 | bvassche | 2017-04-11 11:48:36 -0700 (Tue, 11 Apr 2017) | 4 lines ib_srpt: Ensure that the BUG_ON() argument has no side effects Reported-by: David Butterfield ........ r7107 | vlnb | 2017-04-13 15:04:07 -0700 (Thu, 13 Apr 2017) | 7 lines The argument to sleep() would get "promoted" to an integer with value zero. - sleep(0.1); + usleep(100*1000); Signed-off-by: David Butterfield ........ r7108 | vlnb | 2017-04-13 15:30:25 -0700 (Thu, 13 Apr 2017) | 6 lines create_and_open_dev() returns a (-errno), so the "if (iser_fd...)" check should detect *any* negative return value as a case when fd should be set to -1. Signed-off-by: David Butterfield ........ r7109 | vlnb | 2017-04-13 15:38:38 -0700 (Thu, 13 Apr 2017) | 8 lines Change memcpy() to strncpy() because the source name string is not guaranteed to exist as valid addressable memory beyond the NULL byte. Signed-off-by: David Butterfield with small addition to force set last byte NULL ........ r7110 | vlnb | 2017-04-13 16:02:18 -0700 (Thu, 13 Apr 2017) | 7 lines Thre is potential buffer overflow in iscsi_session_alloc() due to short computation of needed string size. Notice the "%s@%s" in the first call to sprintf(). Signed-off-by: David Butterfield ........ r7111 | vlnb | 2017-04-13 16:12:46 -0700 (Thu, 13 Apr 2017) | 8 lines iscsi: avoid a crash in iscsi_extracheck_is_rd_thread() Add an extra check in iscsi_extracheck_is_rd_thread() to avoid a crash when conn->rd_task is NULL. Signed-off-by: David Butterfield ........ r7115 | vlnb | 2017-04-13 16:37:13 -0700 (Thu, 13 Apr 2017) | 12 lines scst: fix memory leak in scst_proc_group_add() Valgrind noticed that the "name" allocated in scst_proc_group_add() was leaking. It turns out that scst_alloc_add_acg makes its own copy of the name passed to it from this code, making the string duplication done here redundant (and leaky). The change eliminates the string duplication (along with all its associated error handling logic) and simply passes the (unowned) incoming string down for duplication below. Signed-off-by: David Butterfield ........ r7116 | vlnb | 2017-04-13 16:39:14 -0700 (Thu, 13 Apr 2017) | 7 lines scst_vdisk: fix memory leak in vdisk_write_proc() Another leak valgrind popped out, this one in vdisk_write_proc(). Signed-off-by: David Butterfield ........ r7117 | vlnb | 2017-04-13 16:41:14 -0700 (Thu, 13 Apr 2017) | 9 lines scst: take scst_mutex before calling scst_del_free_acg() in exit_scst() scst_del_free_acg() does lockdep_assert_held(&scst_mutex), so we'd better take the lock before calling it. Signed-off-by: David Butterfield ........ r7118 | vlnb | 2017-04-13 16:42:51 -0700 (Thu, 13 Apr 2017) | 8 lines scst: take scst_mutex before calling scst_del_free_acg() in scst_proc_cleanup_module() Take lock before a call that ends up at the lockdep_assert_held() in scst_del_free_acg() without locking. Signed-off-by: David Butterfield ........ r7125 | vlnb | 2017-04-13 18:17:45 -0700 (Thu, 13 Apr 2017) | 6 lines extraclean does "rm tags cscope.out" Signed-off-by: David Butterfield ........ r7134 | vlnb | 2017-04-17 20:57:12 -0700 (Mon, 17 Apr 2017) | 5 lines iscsi-scst: replace strncpy() by strlcpy() Follow up for r7109: strlcpy() is more appropriate in this place. ........ r7135 | vlnb | 2017-04-17 21:02:44 -0700 (Mon, 17 Apr 2017) | 5 lines fcst: Linux kernel v4.10 build fix Signed-off-by: Sebastian Herbszt ........ r7136 | vlnb | 2017-04-17 21:06:18 -0700 (Mon, 17 Apr 2017) | 5 lines scst: avoid possible side effect with WARN_ON_ONCE() Reported-By: David Butterfield ........ r7137 | vlnb | 2017-04-18 20:44:20 -0700 (Tue, 18 Apr 2017) | 5 lines fileio_tgt: change "#if DEBUG_TM_FN_IGNORE" to "#ifdef ..." Signed-off-by: David Butterfield ........ r7139 | vlnb | 2017-04-20 18:02:25 -0700 (Thu, 20 Apr 2017) | 7 lines iscsi-scstd: replace signal() with sigaction() Replace signal() with sigaction() for validity in a multithreaded process Signed-off-by: David Butterfield ........ r7141 | vlnb | 2017-04-20 18:11:37 -0700 (Thu, 20 Apr 2017) | 7 lines scst: set file size for NULLIO in PROCFS build The file size wasn't getting set for NULLIO with /proc support Signed-off-by: David Butterfield ........ r7143 | vlnb | 2017-04-20 18:32:07 -0700 (Thu, 20 Apr 2017) | 9 lines iscsi-scst: fix ENOMEM path In an error path in iscsi_threads_pool_get(), when a new pool cannot be allocated, if there is a pool on iscsi_thread_pools_list, it passes that back as an alternative, so return zero in that case. Signed-off-by: David Butterfield ........ r7152 | bvassche | 2017-04-26 16:53:11 -0700 (Wed, 26 Apr 2017) | 5 lines scst: Introduce scst_scsi_execute() This patch does not change any functionality but makes it easier to port SCST to Linux kernel v4.11. ........ r7153 | bvassche | 2017-04-26 17:17:22 -0700 (Wed, 26 Apr 2017) | 1 line scst: Port to Linux kernel v4.11 ........ r7154 | vlnb | 2017-04-28 17:58:55 -0700 (Fri, 28 Apr 2017) | 5 lines scst: create proc/scst_threads with mode S_IRUGO, not 0 Signed-off-by: David Butterfield ........ r7158 | bvassche | 2017-05-01 14:01:33 -0700 (Mon, 01 May 2017) | 1 line scst: Kernel v4.12 build fixes ........ r7162 | bvassche | 2017-05-02 07:13:15 -0700 (Tue, 02 May 2017) | 1 line scst_lib: Fix kernel 2.6.30 build ........ r7163 | bvassche | 2017-05-02 07:23:00 -0700 (Tue, 02 May 2017) | 1 line scst: Fix build for kernels before v2.6.39 ........ r7168 | bvassche | 2017-05-03 19:56:27 -0700 (Wed, 03 May 2017) | 1 line scst: Fix build for kernels before v2.6.39 ........ r7169 | vlnb | 2017-05-05 18:31:59 -0700 (Fri, 05 May 2017) | 3 lines scst: nolockdep patch for kernel 4.9 ........ r7170 | vlnb | 2017-05-10 20:51:32 -0700 (Wed, 10 May 2017) | 3 lines qla2x00t: update to kernel 4.10 ........ r7171 | vlnb | 2017-05-10 20:52:51 -0700 (Wed, 10 May 2017) | 3 lines scst: nolockdep patch for kernel 4.10 ........ r7173 | vlnb | 2017-05-10 21:00:29 -0700 (Wed, 10 May 2017) | 7 lines fcst: Linux kernel v4.11 build fix Linux kernel v4.11 build fix. Signed-off-by: Sebastian Herbszt ........ r7175 | bvassche | 2017-05-13 17:42:24 -0700 (Sat, 13 May 2017) | 4 lines scst/include/backport.h: Remove duplicate definition of kthread_create_on_node() This patch reverts most of r7168. ........ r7176 | bvassche | 2017-05-13 17:55:39 -0700 (Sat, 13 May 2017) | 1 line scst/include/backport.h: Add a comment ........ r7177 | bvassche | 2017-05-13 19:55:24 -0700 (Sat, 13 May 2017) | 1 line scst/include/backport.h: Fix kthread_create_on_node() definition ........ r7178 | bvassche | 2017-05-13 20:06:54 -0700 (Sat, 13 May 2017) | 4 lines scst/include/backport.h: Add a kref_read() backport This patch does not change any functionality. ........ r7179 | bvassche | 2017-05-13 20:13:56 -0700 (Sat, 13 May 2017) | 4 lines scst/include/backport.h: Add a backport of rcu_dereference_protected() This patch does not change any functionality. ........ r7185 | bvassche | 2017-05-14 11:56:09 -0700 (Sun, 14 May 2017) | 14 lines scst_local: Fix a race condition Avoid that the following crash can occur: general protection fault: 0000 [#1] PREEMPT SMP RIP: 0010:scsi_is_host_device+0x7/0x20 [scsi_mod] Call Trace: scst_process_aens+0x95/0x1d0 [scst_local] scst_aen_work_fn+0x6f/0x120 [scst_local] process_one_work+0x20b/0x6c0 worker_thread+0x4e/0x4a0 kthread+0x113/0x150 ret_from_fork+0x31/0x40 ........ r7190 | vlnb | 2017-05-19 20:00:28 -0700 (Fri, 19 May 2017) | 8 lines scst: fix possible NULL dereference in TM code TM command accessing a non-existing LUN might lead NULL dereference in scst_call_dev_task_mgmt_fn_done(). Reported-By: > ........ r7193 | vlnb | 2017-05-22 19:23:38 -0700 (Mon, 22 May 2017) | 5 lines qla2x00t: fix broken 4.9 kernels build Reported-By: Marc Smith ........ r7203 | vlnb | 2017-06-02 19:38:51 -0700 (Fri, 02 Jun 2017) | 3 lines Update to 4.11 kernels ........ r7208 | vlnb | 2017-06-12 20:58:26 -0700 (Mon, 12 Jun 2017) | 5 lines scst: Linux kernel v4.12 warning fix. Signed-off-by: Sebastian Herbszt ........ git-svn-id: http://svn.code.sf.net/p/scst/svn/branches/3.2.x@7209 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- Makefile | 2 +- fcst/ft_cmd.c | 46 ++ fcst/ft_io.c | 8 + fcst/ft_sess.c | 18 +- iscsi-scst/kernel/conn.c | 3 +- iscsi-scst/kernel/iscsi.c | 2 +- iscsi-scst/kernel/isert-scst/iser_rdma.c | 2 +- iscsi-scst/kernel/isert-scst/isert_login.c | 2 +- iscsi-scst/kernel/session.c | 2 +- iscsi-scst/usr/iscsi_scstd.c | 12 +- iscsi-scst/usr/target.c | 2 +- qla2x00t/qla_bsg.c | 536 ++++++++++++++++++++- qla2x00t/qla_def.h | 8 + qla2x00t/qla_gbl.h | 5 + qla2x00t/qla_iocb.c | 18 + qla2x00t/qla_isr.c | 62 +++ scst/include/backport.h | 23 + scst/include/scst.h | 9 +- scst/include/scst_const.h | 2 + scst/kernel/nolockdep-4.10.patch | 114 +++++ scst/kernel/nolockdep-4.11.patch | 114 +++++ scst/kernel/nolockdep-4.9.patch | 114 +++++ scst/src/dev_handlers/scst_cdrom.c | 10 +- scst/src/dev_handlers/scst_disk.c | 10 +- scst/src/dev_handlers/scst_modisk.c | 10 +- scst/src/dev_handlers/scst_user.c | 8 +- scst/src/dev_handlers/scst_vdisk.c | 32 +- scst/src/scst_copy_mgr.c | 8 +- scst/src/scst_event.c | 4 + scst/src/scst_lib.c | 116 ++++- scst/src/scst_main.c | 22 +- scst/src/scst_proc.c | 26 +- scst/src/scst_sysfs.c | 2 +- scst/src/scst_targ.c | 3 +- scst_local/scst_local.c | 23 +- srpt/src/ib_srpt.c | 7 +- usr/fileio/common.c | 2 +- usr/stpgd/stpgd_main.c | 2 +- 38 files changed, 1267 insertions(+), 122 deletions(-) create mode 100644 scst/kernel/nolockdep-4.10.patch create mode 100644 scst/kernel/nolockdep-4.11.patch create mode 100644 scst/kernel/nolockdep-4.9.patch diff --git a/Makefile b/Makefile index 174180907..f6365b839 100644 --- a/Makefile +++ b/Makefile @@ -196,7 +196,7 @@ clean: @if [ -d $(EMULEX_DIR) ]; then cd $(EMULEX_DIR) && $(MAKE) $@; fi extraclean: - -rm -f TAGS + -rm -f TAGS tags cscope.out cd $(SCST_DIR) && $(MAKE) $@ @if [ -d $(DOC_DIR) ]; then cd $(DOC_DIR) && $(MAKE) $@; fi @if [ -d $(QLA_INI_DIR) ]; then cd $(QLA_INI_DIR) && $(MAKE) $@; fi diff --git a/fcst/ft_cmd.c b/fcst/ft_cmd.c index adc297847..b99880c1a 100644 --- a/fcst/ft_cmd.c +++ b/fcst/ft_cmd.c @@ -256,14 +256,24 @@ static void ft_cmd_done(struct ft_cmd *fcmd) { struct fc_frame *fp = fcmd->req_frame; struct fc_seq *sp = fcmd->seq; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) struct fc_lport *lport = fr_dev(fp); +#endif if (sp) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + fc_exch_done(sp); +#else lport->tt.exch_done(sp); +#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) if (fr_seq(fp)) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + fc_seq_release(fr_seq(fp)); +#else lport->tt.seq_release(fr_seq(fp)); +#endif #endif fc_frame_free(fp); @@ -385,11 +395,19 @@ int ft_send_response(struct scst_cmd *cmd) /* * Send response. */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + fcmd->seq = fc_seq_start_next(fcmd->seq); +#else fcmd->seq = lport->tt.seq_start_next(fcmd->seq); +#endif fc_fill_fc_hdr(fp, FC_RCTL_DD_CMD_STATUS, ep->did, ep->sid, FC_TYPE_FCP, FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ, 0); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + error = FCST_INJ_SEND_ERR(fc_seq_send(lport, fcmd->seq, fp)); +#else error = FCST_INJ_SEND_ERR(lport->tt.seq_send(lport, fcmd->seq, fp)); +#endif if (error < 0) { pr_err("Sending response for exchange with OX_ID %#x and RX_ID" " %#x failed: %d\n", ep->oxid, ep->rxid, error); @@ -487,10 +505,18 @@ int ft_send_xfer_rdy(struct scst_cmd *cmd) txrdy->ft_data_ro = 0; txrdy->ft_burst_len = htonl(scst_cmd_get_bufflen(cmd)); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + fcmd->seq = fc_seq_start_next(fcmd->seq); +#else fcmd->seq = lport->tt.seq_start_next(fcmd->seq); +#endif fc_fill_fc_hdr(fp, FC_RCTL_DD_DATA_DESC, ep->did, ep->sid, FC_TYPE_FCP, FC_FC_EX_CTX | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + error = FCST_INJ_SEND_ERR(fc_seq_send(lport, fcmd->seq, fp)); +#else error = FCST_INJ_SEND_ERR(lport->tt.seq_send(lport, fcmd->seq, fp)); +#endif switch (error) { case 0: return SCST_TGT_RES_SUCCESS; @@ -560,7 +586,11 @@ out: fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_DD_CMD_STATUS, 0); sp = fr_seq(fp); if (sp) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + fc_seq_send(lport, sp, fp); +#else lport->tt.seq_send(lport, sp, fp); +#endif else lport->tt.frame_send(lport, fp); #endif @@ -687,8 +717,12 @@ static void ft_recv_cmd(struct ft_sess *sess, struct fc_frame *fp) #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) sp = fr_seq(fp); +#else +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + sp = fc_seq_assign(lport, fp); #else sp = lport->tt.seq_assign(lport, fp); +#endif if (!sp) goto busy; #endif @@ -737,7 +771,11 @@ static void ft_recv_cmd(struct ft_sess *sess, struct fc_frame *fp) cmd->state = FT_STATE_NEW; fcmd->seq = sp; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + fc_seq_set_resp(sp, ft_recv_seq, cmd); +#else lport->tt.seq_set_resp(sp, ft_recv_seq, cmd); +#endif switch (fcp->fc_flags & (FCP_CFL_RDDATA | FCP_CFL_WRDATA)) { case 0: @@ -786,7 +824,11 @@ busy: if (fcmd) ft_cmd_done(fcmd); else if (sp) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + fc_exch_done(sp); +#else lport->tt.exch_done(sp); +#endif } /* @@ -825,8 +867,12 @@ static void ft_cmd_ls_rjt(struct fc_frame *rx_fp, enum fc_els_rjt_reason reason, lport = fr_dev(rx_fp); rjt_data.reason = reason; rjt_data.explan = explan; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + fc_seq_els_rsp_send(rx_fp, ELS_LS_RJT, &rjt_data); +#else lport->tt.seq_els_rsp_send(rx_fp, ELS_LS_RJT, &rjt_data); #endif +#endif } /* diff --git a/fcst/ft_io.c b/fcst/ft_io.c index 19be72e8b..42639cbc5 100644 --- a/fcst/ft_io.c +++ b/fcst/ft_io.c @@ -89,7 +89,11 @@ int ft_send_read_data(struct scst_cmd *cmd) mem_len -= tlen; mem_off = tlen; } else +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + fcmd->seq = fc_seq_start_next(fcmd->seq); +#else fcmd->seq = lport->tt.seq_start_next(fcmd->seq); +#endif /* no scatter/gather in skb for odd word length due to fc_seq_send() */ use_sg = !(remaining % 4) && lport->sg_supp; @@ -175,8 +179,12 @@ int ft_send_read_data(struct scst_cmd *cmd) remaining ? (FC_FC_EX_CTX | FC_FC_REL_OFF) : (FC_FC_EX_CTX | FC_FC_REL_OFF | FC_FC_END_SEQ), fh_off); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + error = FCST_INJ_SEND_ERR(fc_seq_send(lport, fcmd->seq, fp)); +#else error = FCST_INJ_SEND_ERR(lport->tt.seq_send(lport, fcmd->seq, fp)); +#endif if (error) { pr_warn("Sending frame with oid %#x oxid %#x resp_len" " %d failed at frame_off %u / remaining %zu" diff --git a/fcst/ft_sess.c b/fcst/ft_sess.c index 72754cd87..7486d1327 100644 --- a/fcst/ft_sess.c +++ b/fcst/ft_sess.c @@ -49,12 +49,8 @@ static struct ft_tport *ft_tport_create(struct fc_lport *lport) ft_format_wwn(name, sizeof(name), lport->wwpn); FT_SESS_DBG("create %s\n", name); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) tport = rcu_dereference_protected(lport->prov[FC_TYPE_FCP], lockdep_is_held(&ft_lport_lock)); -#else - tport = rcu_dereference(lport->prov[FC_TYPE_FCP]); -#endif if (tport) { FT_SESS_DBG("tport alloc %s - already setup\n", name); return tport; @@ -187,11 +183,7 @@ static struct ft_sess *ft_sess_get(struct fc_lport *lport, u32 port_id) struct ft_sess *sess; rcu_read_lock(); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) tport = rcu_dereference_protected(lport->prov[FC_TYPE_FCP], true); -#else - tport = rcu_dereference(lport->prov[FC_TYPE_FCP]); -#endif if (!tport) goto out; @@ -406,13 +398,9 @@ static int ft_prli_locked(struct fc_rport_priv *rdata, u32 spp_len, if (!(fcp_parm & FCP_SPPF_INIT_FCN)) return FC_SPP_RESP_CONF; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) tport = rcu_dereference_protected( rdata->local_port->prov[FC_TYPE_FCP], lockdep_is_held(&ft_lport_lock)); -#else - tport = rcu_dereference(rdata->local_port->prov[FC_TYPE_FCP]); -#endif if (!tport) { /* not a target for this local port */ return FC_SPP_RESP_CONF; @@ -482,7 +470,7 @@ static void ft_sess_free(struct kref *kref) static void ft_sess_put(struct ft_sess *sess) { BUG_ON(!sess); - BUG_ON(atomic_read(&sess->kref.refcount) <= 0); + BUG_ON(kref_read(&sess->kref) <= 0); kref_put(&sess->kref, ft_sess_free); } @@ -492,12 +480,8 @@ static void ft_prlo(struct fc_rport_priv *rdata) struct ft_tport *tport; mutex_lock(&ft_lport_lock); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) tport = rcu_dereference_protected(rdata->local_port->prov[FC_TYPE_FCP], lockdep_is_held(&ft_lport_lock)); -#else - tport = rcu_dereference(rdata->local_port->prov[FC_TYPE_FCP]); -#endif if (!tport) { mutex_unlock(&ft_lport_lock); return; diff --git a/iscsi-scst/kernel/conn.c b/iscsi-scst/kernel/conn.c index 3b1de7fea..b93da4dc7 100644 --- a/iscsi-scst/kernel/conn.c +++ b/iscsi-scst/kernel/conn.c @@ -1058,7 +1058,8 @@ void iscsi_extracheck_is_rd_thread(struct iscsi_conn *conn) local_bh_enable(); pr_emerg("rd_state %x\n", conn->rd_state); pr_emerg("rd_task %p\n", conn->rd_task); - pr_emerg("rd_task->pid %d\n", conn->rd_task->pid); + if (conn->rd_task) + pr_emerg("rd_task->pid %d\n", conn->rd_task->pid); BUG(); } } diff --git a/iscsi-scst/kernel/iscsi.c b/iscsi-scst/kernel/iscsi.c index 3b590de0b..7c4117d00 100644 --- a/iscsi-scst/kernel/iscsi.c +++ b/iscsi-scst/kernel/iscsi.c @@ -4214,7 +4214,7 @@ int iscsi_threads_pool_get(const cpumask_t *cpu_mask, if (p == NULL) { PRINT_ERROR("Unable to allocate iSCSI thread pool (size %zd)", sizeof(*p)); - res = -ENOMEM; + res = 0; if (!list_empty(&iscsi_thread_pools_list)) { PRINT_WARNING("%s", "Using global iSCSI thread pool " "instead"); diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index 66339c62f..0ed4cafaa 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -1398,7 +1398,7 @@ static void isert_kref_free(struct kref *kref) void isert_conn_free(struct isert_connection *isert_conn) { - sBUG_ON(atomic_read(&isert_conn->kref.refcount) == 0); + sBUG_ON(kref_read(&isert_conn->kref) == 0); kref_put(&isert_conn->kref, isert_kref_free); } diff --git a/iscsi-scst/kernel/isert-scst/isert_login.c b/iscsi-scst/kernel/isert-scst/isert_login.c index c43193bc4..e238f4cce 100644 --- a/iscsi-scst/kernel/isert-scst/isert_login.c +++ b/iscsi-scst/kernel/isert-scst/isert_login.c @@ -110,7 +110,7 @@ static void isert_kref_release_dev(struct kref *kref) static void isert_dev_release(struct isert_conn_dev *dev) { - sBUG_ON(atomic_read(&dev->kref.refcount) == 0); + sBUG_ON(kref_read(&dev->kref) == 0); mutex_lock(&isert_listen_dev.conn_lock); kref_put(&dev->kref, isert_kref_release_dev); mutex_unlock(&isert_listen_dev.conn_lock); diff --git a/iscsi-scst/kernel/session.c b/iscsi-scst/kernel/session.c index d26031db6..48754a497 100644 --- a/iscsi-scst/kernel/session.c +++ b/iscsi-scst/kernel/session.c @@ -65,7 +65,7 @@ static int iscsi_session_alloc(struct iscsi_target *target, #ifdef CONFIG_SCST_PROC name = kmalloc(strlen(info->user_name) + strlen(info->initiator_name) + - 1, GFP_KERNEL); + 2, GFP_KERNEL); /* +1 (for '\0') +1 (for '@') */ if (name == NULL) { err = -ENOMEM; goto err; diff --git a/iscsi-scst/usr/iscsi_scstd.c b/iscsi-scst/usr/iscsi_scstd.c index 147bd3da0..6bcd61052 100644 --- a/iscsi-scst/usr/iscsi_scstd.c +++ b/iscsi-scst/usr/iscsi_scstd.c @@ -232,14 +232,15 @@ static void create_iser_listen_socket(struct pollfd *array) iser_fd = create_and_open_dev("isert_scst", 1); - poll_array[POLL_ISER_LISTEN].fd = iser_fd; - if (iser_fd != -1) { + if (iser_fd >= 0) { + poll_array[POLL_ISER_LISTEN].fd = iser_fd; poll_array[POLL_ISER_LISTEN].events = POLLIN; /* RDMAExtensions */ session_keys[key_rdma_extensions].max = 1; session_keys[key_rdma_extensions].local_def = 1; } else { + poll_array[POLL_ISER_LISTEN].fd = -1; poll_array[POLL_ISER_LISTEN].events = 0; return; } @@ -839,8 +840,13 @@ int main(int argc, char **argv) /* * Otherwise we could die in some later write() during the event_loop() * instead of getting EPIPE! + * + * The effects of signal(2) in a multithreaded process are unspecified, + * so use sigaction(2) instead. */ - signal(SIGPIPE, SIG_IGN); + struct sigaction act = (struct sigaction) { .sa_handler = SIG_IGN }; + int rc = sigaction(SIGPIPE, &act, NULL); + assert(rc == 0); while ((ch = getopt_long(argc, argv, "c:fd:s:u:g:a:p:vh", long_options, &longindex)) >= 0) { switch (ch) { diff --git a/iscsi-scst/usr/target.c b/iscsi-scst/usr/target.c index 9c6898d98..d942afdf3 100644 --- a/iscsi-scst/usr/target.c +++ b/iscsi-scst/usr/target.c @@ -415,7 +415,7 @@ int target_create(const char *name, struct target **out_target) } memset(target, 0, sizeof(*target)); - memcpy(target->name, name, sizeof(target->name) - 1); + strlcpy(target->name, name, sizeof(target->name)); params_set_defaults(target->target_params, target_keys); params_set_defaults(target->session_params, session_keys); diff --git a/qla2x00t/qla_bsg.c b/qla2x00t/qla_bsg.c index 8d9b8244b..214552766 100644 --- a/qla2x00t/qla_bsg.c +++ b/qla2x00t/qla_bsg.c @@ -16,10 +16,21 @@ qla2x00_bsg_job_done(void *data, void *ptr, int res) { srb_t *sp = (srb_t*)ptr; struct scsi_qla_host *vha = (scsi_qla_host_t *)data; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) struct fc_bsg_job *bsg_job = sp->u.bsg_job; +#else + struct bsg_job *bsg_job = sp->u.bsg_job; + struct fc_bsg_reply *bsg_reply = bsg_job->reply; +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = res; bsg_job->job_done(bsg_job); +#else + bsg_reply->result = res; + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); +#endif sp->free(vha, sp); } @@ -28,7 +39,11 @@ qla2x00_bsg_sp_free(void *data, void *ptr) { srb_t *sp = (srb_t*)ptr; struct scsi_qla_host *vha = (scsi_qla_host_t *)data; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) struct fc_bsg_job *bsg_job = sp->u.bsg_job; +#else + struct bsg_job *bsg_job = sp->u.bsg_job; +#endif struct qla_hw_data *ha = vha->hw; dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list, @@ -99,9 +114,19 @@ qla24xx_fcp_prio_cfg_valid(scsi_qla_host_t *vha, } static int +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job) +#else +qla24xx_proc_fcp_prio_cfg_cmd(struct bsg_job *bsg_job) +#endif { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) struct Scsi_Host *host = bsg_job->shost; +#else + struct Scsi_Host *host = fc_bsg_to_shost(bsg_job); + struct fc_bsg_request *bsg_request = bsg_job->request; + struct fc_bsg_reply *bsg_reply = bsg_job->reply; +#endif scsi_qla_host_t *vha = shost_priv(host); struct qla_hw_data *ha = vha->hw; int ret = 0; @@ -114,7 +139,11 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job) } /* Get the sub command */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) oper = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1]; +#else + oper = bsg_request->rqst_data.h_vendor.vendor_cmd[1]; +#endif /* Only set config is allowed if config memory is not allocated */ if (!ha->fcp_prio_cfg && (oper != QLFC_FCP_PRIO_SET_CONFIG)) { @@ -128,10 +157,18 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job) ha->fcp_prio_cfg->attributes &= ~FCP_PRIO_ATTR_ENABLE; qla24xx_update_all_fcp_prio(vha); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = DID_OK; +#else + bsg_reply->result = DID_OK; +#endif } else { ret = -EINVAL; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = (DID_ERROR << 16); +#else + bsg_reply->result = (DID_ERROR << 16); +#endif goto exit_fcp_prio_cfg; } break; @@ -143,10 +180,18 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job) ha->fcp_prio_cfg->attributes |= FCP_PRIO_ATTR_ENABLE; qla24xx_update_all_fcp_prio(vha); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = DID_OK; +#else + bsg_reply->result = DID_OK; +#endif } else { ret = -EINVAL; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = (DID_ERROR << 16); +#else + bsg_reply->result = (DID_ERROR << 16); +#endif goto exit_fcp_prio_cfg; } } @@ -156,12 +201,21 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job) len = bsg_job->reply_payload.payload_len; if (!len || len > FCP_PRIO_CFG_SIZE) { ret = -EINVAL; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = (DID_ERROR << 16); +#else + bsg_reply->result = (DID_ERROR << 16); +#endif goto exit_fcp_prio_cfg; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = DID_OK; bsg_job->reply->reply_payload_rcv_len = +#else + bsg_reply->result = DID_OK; + bsg_reply->reply_payload_rcv_len = +#endif sg_copy_from_buffer( bsg_job->reply_payload.sg_list, bsg_job->reply_payload.sg_cnt, ha->fcp_prio_cfg, @@ -172,7 +226,11 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job) case QLFC_FCP_PRIO_SET_CONFIG: len = bsg_job->request_payload.payload_len; if (!len || len > FCP_PRIO_CFG_SIZE) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = (DID_ERROR << 16); +#else + bsg_reply->result = (DID_ERROR << 16); +#endif ret = -EINVAL; goto exit_fcp_prio_cfg; } @@ -183,7 +241,11 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job) ql_log(ql_log_warn, vha, 0x7050, "Unable to allocate memory for fcp prio " "config data (%x).\n", FCP_PRIO_CFG_SIZE); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = (DID_ERROR << 16); +#else + bsg_reply->result = (DID_ERROR << 16); +#endif ret = -ENOMEM; goto exit_fcp_prio_cfg; } @@ -198,7 +260,11 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job) if (!qla24xx_fcp_prio_cfg_valid(vha, (struct qla_fcp_prio_cfg *) ha->fcp_prio_cfg, 1)) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = (DID_ERROR << 16); +#else + bsg_reply->result = (DID_ERROR << 16); +#endif ret = -EINVAL; /* If buffer was invalidatic int * fcp_prio_cfg is of no use @@ -212,20 +278,37 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job) if (ha->fcp_prio_cfg->attributes & FCP_PRIO_ATTR_ENABLE) ha->flags.fcp_prio_enabled = 1; qla24xx_update_all_fcp_prio(vha); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = DID_OK; +#else + bsg_reply->result = DID_OK; +#endif break; default: ret = -EINVAL; break; } exit_fcp_prio_cfg: +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->job_done(bsg_job); +#else + if (!ret) + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); +#endif return ret; } static int +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) qla2x00_process_els(struct fc_bsg_job *bsg_job) +#else +qla2x00_process_els(struct bsg_job *bsg_job) +#endif { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + struct fc_bsg_request *bsg_request = bsg_job->request; +#endif struct fc_rport *rport; fc_port_t *fcport = NULL; struct Scsi_Host *host; @@ -238,19 +321,33 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job) uint16_t nextlid = 0; #ifdef __COVERITY__ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) BUG_ON(bsg_job->request->msgcode != FC_BSG_RPT_ELS && bsg_job->request->msgcode != FC_BSG_HST_ELS_NOLOGIN); +#else + BUG_ON(bsg_request->msgcode != FC_BSG_RPT_ELS && + bsg_request->msgcode != FC_BSG_HST_ELS_NOLOGIN); +#endif #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) { rport = bsg_job->rport; +#else + if (bsg_request->msgcode == FC_BSG_RPT_ELS) { + rport = fc_bsg_to_rport(bsg_job);; +#endif fcport = *(fc_port_t **) rport->dd_data; host = rport_to_shost(rport); vha = shost_priv(host); ha = vha->hw; type = "FC_BSG_RPT_ELS"; } else { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) host = bsg_job->shost; +#else + host = fc_bsg_to_shost(bsg_job); +#endif vha = shost_priv(host); ha = vha->hw; type = "FC_BSG_HST_ELS_NOLOGIN"; @@ -277,7 +374,11 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job) } /* ELS request for rport */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) { +#else + if (bsg_request->msgcode == FC_BSG_RPT_ELS) { +#endif /* make sure the rport is logged in, * if not perform fabric login */ @@ -302,12 +403,21 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job) /* Initialize all required fields of fcport */ fcport->vha = vha; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) fcport->d_id.b.al_pa = bsg_job->request->rqst_data.h_els.port_id[0]; fcport->d_id.b.area = bsg_job->request->rqst_data.h_els.port_id[1]; fcport->d_id.b.domain = bsg_job->request->rqst_data.h_els.port_id[2]; +#else + fcport->d_id.b.al_pa = + bsg_request->rqst_data.h_els.port_id[0]; + fcport->d_id.b.area = + bsg_request->rqst_data.h_els.port_id[1]; + fcport->d_id.b.domain = + bsg_request->rqst_data.h_els.port_id[2]; +#endif fcport->loop_id = (fcport->d_id.b.al_pa == 0xFD) ? NPH_FABRIC_CONTROLLER : NPH_F_PORT; @@ -352,12 +462,21 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job) goto done_unmap_sg; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) sp->type = (bsg_job->request->msgcode == FC_BSG_RPT_ELS ? SRB_ELS_CMD_RPT : SRB_ELS_CMD_HST); sp->name = (bsg_job->request->msgcode == FC_BSG_RPT_ELS ? "bsg_els_rpt" : "bsg_els_hst"); +#else + sp->type = + (bsg_request->msgcode == FC_BSG_RPT_ELS ? + SRB_ELS_CMD_RPT : SRB_ELS_CMD_HST); + sp->name = + (bsg_request->msgcode == FC_BSG_RPT_ELS ? + "bsg_els_rpt" : "bsg_els_hst"); +#endif sp->u.bsg_job = bsg_job; sp->free = qla2x00_bsg_sp_free; sp->done = qla2x00_bsg_job_done; @@ -365,7 +484,11 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job) ql_dbg(ql_dbg_user, vha, 0x700a, "bsg rqst type: %s els type: %x - loop-id=%x " "portid=%-2x%02x%02x.\n", type, +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->request->rqst_data.h_els.command_code, fcport->loop_id, +#else + bsg_request->rqst_data.h_els.command_code, fcport->loop_id, +#endif fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa); rval = qla2x00_start_sp(sp); @@ -386,7 +509,11 @@ done_unmap_sg: goto done_free_fcport; done_free_fcport: +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) if (bsg_job->request->msgcode == FC_BSG_HST_ELS_NOLOGIN) +#else + if (bsg_request->msgcode == FC_BSG_HST_ELS_NOLOGIN) +#endif kfree(fcport); done: return rval; @@ -407,10 +534,19 @@ qla24xx_calc_ct_iocbs(uint16_t dsds) } static int +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) qla2x00_process_ct(struct fc_bsg_job *bsg_job) +#else +qla2x00_process_ct(struct bsg_job *bsg_job) +#endif { srb_t *sp; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) struct Scsi_Host *host = bsg_job->shost; +#else + struct fc_bsg_request *bsg_request = bsg_job->request; + struct Scsi_Host *host = fc_bsg_to_shost(bsg_job); +#endif scsi_qla_host_t *vha = shost_priv(host); struct qla_hw_data *ha = vha->hw; int rval = (DRIVER_ERROR << 16); @@ -456,7 +592,11 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job) } loop_id = +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) (bsg_job->request->rqst_data.h_ct.preamble_word1 & 0xFF000000) +#else + (bsg_request->rqst_data.h_ct.preamble_word1 & 0xFF000000) +#endif >> 24; switch (loop_id) { case 0xFC: @@ -487,9 +627,15 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job) /* Initialize all required fields of fcport */ fcport->vha = vha; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) fcport->d_id.b.al_pa = bsg_job->request->rqst_data.h_ct.port_id[0]; fcport->d_id.b.area = bsg_job->request->rqst_data.h_ct.port_id[1]; fcport->d_id.b.domain = bsg_job->request->rqst_data.h_ct.port_id[2]; +#else + fcport->d_id.b.al_pa = bsg_request->rqst_data.h_ct.port_id[0]; + fcport->d_id.b.area = bsg_request->rqst_data.h_ct.port_id[1]; + fcport->d_id.b.domain = bsg_request->rqst_data.h_ct.port_id[2]; +#endif fcport->loop_id = loop_id; /* Alloc SRB structure */ @@ -511,7 +657,11 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job) ql_dbg(ql_dbg_user, vha, 0x7016, "bsg rqst type: %s else type: %x - " "loop-id=%x portid=%02x%02x%02x.\n", type, +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) (bsg_job->request->rqst_data.h_ct.preamble_word2 >> 16), +#else + (bsg_request->rqst_data.h_ct.preamble_word2 >> 16), +#endif fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa); @@ -627,9 +777,19 @@ done_reset_internal: } static int +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) qla2x00_process_loopback(struct fc_bsg_job *bsg_job) +#else +qla2x00_process_loopback(struct bsg_job *bsg_job) +#endif { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) struct Scsi_Host *host = bsg_job->shost; +#else + struct fc_bsg_request *bsg_request = bsg_job->request; + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + struct Scsi_Host *host = fc_bsg_to_shost(bsg_job); +#endif scsi_qla_host_t *vha = shost_priv(host); struct qla_hw_data *ha = vha->hw; int rval; @@ -711,7 +871,11 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job) elreq.rcv_dma = rsp_data_dma; elreq.transfer_size = req_data_len; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) elreq.options = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1]; +#else + elreq.options = bsg_request->rqst_data.h_vendor.vendor_cmd[1]; +#endif if ((ha->current_topology == ISP_CFG_F || ((IS_QLA81XX(ha) || IS_QLA8031(ha)) && @@ -730,7 +894,11 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job) if (qla81xx_get_port_config(vha, config)) { ql_log(ql_log_warn, vha, 0x701f, "Get port config failed.\n"); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = (DID_ERROR << 16); +#else + bsg_reply->result = (DID_ERROR << 16); +#endif rval = -EPERM; goto done_free_dma_req; } @@ -743,7 +911,11 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job) new_config)) { ql_log(ql_log_warn, vha, 0x7024, "Internal loopback failed.\n"); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = +#else + bsg_reply->result = +#endif (DID_ERROR << 16); rval = -EPERM; goto done_free_dma_req; @@ -754,7 +926,11 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job) */ if (qla81xx_reset_internal_loopback(vha, config, 1)) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = +#else + bsg_reply->result = +#endif (DID_ERROR << 16); rval = -EPERM; goto done_free_dma_req; @@ -790,7 +966,11 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job) "MPI reset failed.\n"); } +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = (DID_ERROR << 16); +#else + bsg_reply->result = (DID_ERROR << 16); +#endif rval = -EIO; goto done_free_dma_req; } @@ -807,33 +987,61 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job) ql_log(ql_log_warn, vha, 0x702c, "Vendor request %s failed.\n", type); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + fw_sts_ptr = ((uint8_t *)scsi_req(bsg_job->req)->sense) + + sizeof(struct fc_bsg_reply); +#else fw_sts_ptr = ((uint8_t *)bsg_job->req->sense) + sizeof(struct fc_bsg_reply); +#endif memcpy(fw_sts_ptr, response, sizeof(response)); fw_sts_ptr += sizeof(response); *fw_sts_ptr = command_sent; rval = 0; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = (DID_ERROR << 16); +#else + bsg_reply->result = (DID_ERROR << 16); +#endif } else { ql_dbg(ql_dbg_user, vha, 0x702d, "Vendor request %s completed.\n", type); bsg_job->reply_len = sizeof(struct fc_bsg_reply) + sizeof(response) + sizeof(uint8_t); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->reply_payload_rcv_len = +#else + bsg_reply->reply_payload_rcv_len = +#endif bsg_job->reply_payload.payload_len; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + fw_sts_ptr = ((uint8_t *)scsi_req(bsg_job->req)->sense) + + sizeof(struct fc_bsg_reply); +#else fw_sts_ptr = ((uint8_t *)bsg_job->req->sense) + sizeof(struct fc_bsg_reply); +#endif memcpy(fw_sts_ptr, response, sizeof(response)); fw_sts_ptr += sizeof(response); *fw_sts_ptr = command_sent; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = DID_OK; +#else + bsg_reply->result = DID_OK; +#endif sg_copy_from_buffer(bsg_job->reply_payload.sg_list, bsg_job->reply_payload.sg_cnt, rsp_data, rsp_data_len); } +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->job_done(bsg_job); +#else + if (!rval) + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); +#endif dma_free_coherent(&ha->pdev->dev, rsp_data_len, rsp_data, rsp_data_dma); @@ -852,9 +1060,19 @@ done_unmap_req_sg: } static int +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) qla84xx_reset(struct fc_bsg_job *bsg_job) +#else +qla84xx_reset(struct bsg_job *bsg_job) +#endif { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) struct Scsi_Host *host = bsg_job->shost; +#else + struct fc_bsg_request *bsg_request = bsg_job->request; + struct Scsi_Host *host = fc_bsg_to_shost(bsg_job); + struct fc_bsg_reply *bsg_reply = bsg_job->reply; +#endif scsi_qla_host_t *vha = shost_priv(host); struct qla_hw_data *ha = vha->hw; int rval = 0; @@ -865,7 +1083,11 @@ qla84xx_reset(struct fc_bsg_job *bsg_job) return -EINVAL; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) flag = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1]; +#else + flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1]; +#endif rval = qla84xx_reset_chip(vha, flag == A84_ISSUE_RESET_DIAG_FW); @@ -873,22 +1095,45 @@ qla84xx_reset(struct fc_bsg_job *bsg_job) ql_log(ql_log_warn, vha, 0x7030, "Vendor request 84xx reset failed.\n"); rval = 0; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = (DID_ERROR << 16); - +#else + bsg_reply->result = (DID_ERROR << 16); +#endif } else { ql_dbg(ql_dbg_user, vha, 0x7031, "Vendor request 84xx reset completed.\n"); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = DID_OK; +#else + bsg_reply->result = DID_OK; +#endif } +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->job_done(bsg_job); +#else + if (!rval) + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); +#endif return rval; } static int +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) qla84xx_updatefw(struct fc_bsg_job *bsg_job) +#else +qla84xx_updatefw(struct bsg_job *bsg_job) +#endif { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) struct Scsi_Host *host = bsg_job->shost; +#else + struct fc_bsg_request *bsg_request = bsg_job->request; + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + struct Scsi_Host *host = fc_bsg_to_shost(bsg_job); +#endif scsi_qla_host_t *vha = shost_priv(host); struct qla_hw_data *ha = vha->hw; struct verify_chip_entry_84xx *mn = NULL; @@ -945,7 +1190,11 @@ qla84xx_updatefw(struct fc_bsg_job *bsg_job) goto done_free_fw_buf; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) flag = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1]; +#else + flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1]; +#endif fw_ver = le32_to_cpu(*((uint32_t *)((uint32_t *)fw_buf + 2))); memset(mn, 0, sizeof(struct access_chip_84xx)); @@ -972,16 +1221,30 @@ qla84xx_updatefw(struct fc_bsg_job *bsg_job) "Vendor request 84xx updatefw failed.\n"); rval = 0; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = (DID_ERROR << 16); +#else + bsg_reply->result = (DID_ERROR << 16); +#endif } else { ql_dbg(ql_dbg_user, vha, 0x7038, "Vendor request 84xx updatefw completed.\n"); bsg_job->reply_len = sizeof(struct fc_bsg_reply); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = DID_OK; +#else + bsg_reply->result = DID_OK; +#endif } +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->job_done(bsg_job); +#else + if (!rval) + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); +#endif dma_pool_free(ha->s_dma_pool, mn, mn_dma); done_free_fw_buf: @@ -995,9 +1258,19 @@ done_unmap_sg: } static int +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job) +#else +qla84xx_mgmt_cmd(struct bsg_job *bsg_job) +#endif { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) struct Scsi_Host *host = bsg_job->shost; +#else + struct fc_bsg_request *bsg_request = bsg_job->request; + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + struct Scsi_Host *host = fc_bsg_to_shost(bsg_job); +#endif scsi_qla_host_t *vha = shost_priv(host); struct qla_hw_data *ha = vha->hw; struct access_chip_84xx *mn = NULL; @@ -1015,8 +1288,12 @@ qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job) return -EINVAL; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) ql84_mgmt = (struct qla_bsg_a84_mgmt *)((char *)bsg_job->request + sizeof(struct fc_bsg_request)); +#else + ql84_mgmt = (void *)bsg_request + sizeof(struct fc_bsg_request); +#endif mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma); if (!mn) { @@ -1154,18 +1431,29 @@ qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job) "Vendor request 84xx mgmt failed.\n"); rval = 0; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = (DID_ERROR << 16); - +#else + bsg_reply->result = (DID_ERROR << 16); +#endif } else { ql_dbg(ql_dbg_user, vha, 0x7044, "Vendor request 84xx mgmt completed.\n"); bsg_job->reply_len = sizeof(struct fc_bsg_reply); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = DID_OK; +#else + bsg_reply->result = DID_OK; +#endif if ((ql84_mgmt->mgmt.cmd == QLA84_MGMT_READ_MEM) || (ql84_mgmt->mgmt.cmd == QLA84_MGMT_GET_INFO)) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->reply_payload_rcv_len = +#else + bsg_reply->reply_payload_rcv_len = +#endif bsg_job->reply_payload.payload_len; sg_copy_from_buffer(bsg_job->reply_payload.sg_list, @@ -1174,7 +1462,13 @@ qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job) } } +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->job_done(bsg_job); +#else + if (!rval) + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); +#endif done_unmap_sg: if (mgmt_b) @@ -1194,9 +1488,19 @@ exit_mgmt: } static int +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) qla24xx_iidma(struct fc_bsg_job *bsg_job) +#else +qla24xx_iidma(struct bsg_job *bsg_job) +#endif { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) struct Scsi_Host *host = bsg_job->shost; +#else + struct fc_bsg_request *bsg_request = bsg_job->request; + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + struct Scsi_Host *host = fc_bsg_to_shost(bsg_job); +#endif scsi_qla_host_t *vha = shost_priv(host); int rval = 0; struct qla_port_param *port_param = NULL; @@ -1209,8 +1513,12 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job) return -EINVAL; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) port_param = (struct qla_port_param *)((char *)bsg_job->request + sizeof(struct fc_bsg_request)); +#else + port_param = (void *)bsg_request + sizeof(struct fc_bsg_request); +#endif if (port_param->fc_scsi_addr.dest_type != EXT_DEF_TYPE_WWPN) { ql_log(ql_log_warn, vha, 0x7048, "Invalid destination type.\n"); @@ -1261,8 +1569,11 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job) fcport->port_name[5], fcport->port_name[6], fcport->port_name[7], rval, fcport->fp_speed, mb[0], mb[1]); rval = 0; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = (DID_ERROR << 16); - +#else + bsg_reply->result = (DID_ERROR << 16); +#endif } else { if (!port_param->mode) { bsg_job->reply_len = sizeof(struct fc_bsg_reply) + @@ -1275,17 +1586,34 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job) sizeof(struct qla_port_param)); } +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = DID_OK; +#else + bsg_reply->result = DID_OK; +#endif } +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->job_done(bsg_job); +#else + if (!rval) + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); +#endif return rval; } static int +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) qla2x00_optrom_setup(struct fc_bsg_job *bsg_job, scsi_qla_host_t *vha, +#else +qla2x00_optrom_setup(struct bsg_job *bsg_job, scsi_qla_host_t *vha, +#endif uint8_t is_update) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + struct fc_bsg_request *bsg_request = bsg_job->request; +#endif uint32_t start = 0; int valid = 0; struct qla_hw_data *ha = vha->hw; @@ -1293,7 +1621,11 @@ qla2x00_optrom_setup(struct fc_bsg_job *bsg_job, scsi_qla_host_t *vha, if (unlikely(pci_channel_offline(ha->pdev))) return -EINVAL; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) start = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1]; +#else + start = bsg_request->rqst_data.h_vendor.vendor_cmd[1]; +#endif if (start > ha->optrom_size) { ql_log(ql_log_warn, vha, 0x7055, "start %d > optrom_size %d.\n", start, ha->optrom_size); @@ -1352,9 +1684,18 @@ qla2x00_optrom_setup(struct fc_bsg_job *bsg_job, scsi_qla_host_t *vha, } static int +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) qla2x00_read_optrom(struct fc_bsg_job *bsg_job) +#else +qla2x00_read_optrom(struct bsg_job *bsg_job) +#endif { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) struct Scsi_Host *host = bsg_job->shost; +#else + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + struct Scsi_Host *host = fc_bsg_to_shost(bsg_job); +#endif scsi_qla_host_t *vha = shost_priv(host); struct qla_hw_data *ha = vha->hw; int rval = 0; @@ -1373,19 +1714,38 @@ qla2x00_read_optrom(struct fc_bsg_job *bsg_job) bsg_job->reply_payload.sg_cnt, ha->optrom_buffer, ha->optrom_region_size); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->reply_payload_rcv_len = ha->optrom_region_size; bsg_job->reply->result = DID_OK; +#else + bsg_reply->reply_payload_rcv_len = ha->optrom_region_size; + bsg_reply->result = DID_OK; +#endif vfree(ha->optrom_buffer); ha->optrom_buffer = NULL; ha->optrom_state = QLA_SWAITING; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->job_done(bsg_job); +#else + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); +#endif return rval; } static int +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) qla2x00_update_optrom(struct fc_bsg_job *bsg_job) +#else +qla2x00_update_optrom(struct bsg_job *bsg_job) +#endif { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) struct Scsi_Host *host = bsg_job->shost; +#else + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + struct Scsi_Host *host = fc_bsg_to_shost(bsg_job); +#endif scsi_qla_host_t *vha = shost_priv(host); struct qla_hw_data *ha = vha->hw; int rval = 0; @@ -1404,18 +1764,36 @@ qla2x00_update_optrom(struct fc_bsg_job *bsg_job) ha->isp_ops->write_optrom(vha, ha->optrom_buffer, ha->optrom_region_start, ha->optrom_region_size); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = DID_OK; +#else + bsg_reply->result = DID_OK; +#endif vfree(ha->optrom_buffer); ha->optrom_buffer = NULL; ha->optrom_state = QLA_SWAITING; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->job_done(bsg_job); +#else + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); +#endif return rval; } static int +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) qla2x00_update_fru_versions(struct fc_bsg_job *bsg_job) +#else +qla2x00_update_fru_versions(struct bsg_job *bsg_job) +#endif { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) struct Scsi_Host *host = bsg_job->shost; +#else + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + struct Scsi_Host *host = fc_bsg_to_shost(bsg_job); +#endif scsi_qla_host_t *vha = shost_priv(host); struct qla_hw_data *ha = vha->hw; int rval = 0; @@ -1426,7 +1804,11 @@ qla2x00_update_fru_versions(struct fc_bsg_job *bsg_job) dma_addr_t sfp_dma; void *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma); if (!sfp) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = +#else + bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = +#endif EXT_STATUS_NO_MEMORY; goto done; } @@ -1442,30 +1824,53 @@ qla2x00_update_fru_versions(struct fc_bsg_job *bsg_job) image->field_address.device, image->field_address.offset, sizeof(image->field_info), image->field_address.option); if (rval) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = +#else + bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = +#endif EXT_STATUS_MAILBOX; goto dealloc; } image++; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0; +#else + bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0; +#endif dealloc: dma_pool_free(ha->s_dma_pool, sfp, sfp_dma); done: bsg_job->reply_len = sizeof(struct fc_bsg_reply); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = DID_OK << 16; bsg_job->job_done(bsg_job); +#else + bsg_reply->result = DID_OK << 16; + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); +#endif return 0; } static int +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) qla2x00_read_fru_status(struct fc_bsg_job *bsg_job) +#else +qla2x00_read_fru_status(struct bsg_job *bsg_job) +#endif { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) struct Scsi_Host *host = bsg_job->shost; +#else + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + struct Scsi_Host *host = fc_bsg_to_shost(bsg_job); +#endif scsi_qla_host_t *vha = shost_priv(host); struct qla_hw_data *ha = vha->hw; int rval = 0; @@ -1474,7 +1879,11 @@ qla2x00_read_fru_status(struct fc_bsg_job *bsg_job) dma_addr_t sfp_dma; uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma); if (!sfp) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = +#else + bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = +#endif EXT_STATUS_NO_MEMORY; goto done; } @@ -1488,7 +1897,11 @@ qla2x00_read_fru_status(struct fc_bsg_job *bsg_job) sr->status_reg = *sfp; if (rval) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = +#else + bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = +#endif EXT_STATUS_MAILBOX; goto dealloc; } @@ -1496,24 +1909,44 @@ qla2x00_read_fru_status(struct fc_bsg_job *bsg_job) sg_copy_from_buffer(bsg_job->reply_payload.sg_list, bsg_job->reply_payload.sg_cnt, sr, sizeof(*sr)); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0; +#else + bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0; +#endif dealloc: dma_pool_free(ha->s_dma_pool, sfp, sfp_dma); done: bsg_job->reply_len = sizeof(struct fc_bsg_reply); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->reply_payload_rcv_len = sizeof(*sr); bsg_job->reply->result = DID_OK << 16; bsg_job->job_done(bsg_job); +#else + bsg_reply->reply_payload_rcv_len = sizeof(*sr); + bsg_reply->result = DID_OK << 16; + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); +#endif return 0; } static int +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) qla2x00_write_fru_status(struct fc_bsg_job *bsg_job) +#else +qla2x00_write_fru_status(struct bsg_job *bsg_job) +#endif { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) struct Scsi_Host *host = bsg_job->shost; +#else + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + struct Scsi_Host *host = fc_bsg_to_shost(bsg_job); +#endif scsi_qla_host_t *vha = shost_priv(host); struct qla_hw_data *ha = vha->hw; int rval = 0; @@ -1522,7 +1955,11 @@ qla2x00_write_fru_status(struct fc_bsg_job *bsg_job) dma_addr_t sfp_dma; uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma); if (!sfp) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = +#else + bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = +#endif EXT_STATUS_NO_MEMORY; goto done; } @@ -1536,28 +1973,55 @@ qla2x00_write_fru_status(struct fc_bsg_job *bsg_job) sizeof(sr->status_reg), sr->field_address.option); if (rval) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = +#else + bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = +#endif EXT_STATUS_MAILBOX; goto dealloc; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0; +#else + bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0; +#endif dealloc: dma_pool_free(ha->s_dma_pool, sfp, sfp_dma); done: bsg_job->reply_len = sizeof(struct fc_bsg_reply); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = DID_OK << 16; bsg_job->job_done(bsg_job); +#else + bsg_reply->result = DID_OK << 16; + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); +#endif return 0; } static int +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job) +#else +qla2x00_process_vendor_specific(struct bsg_job *bsg_job) +#endif { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + struct fc_bsg_request *bsg_request = bsg_job->request; + struct fc_bsg_reply *bsg_reply = bsg_job->reply; +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) switch (bsg_job->request->rqst_data.h_vendor.vendor_cmd[0]) { +#else + switch (bsg_request->rqst_data.h_vendor.vendor_cmd[0]) { +#endif case QL_VND_LOOPBACK: return qla2x00_process_loopback(bsg_job); @@ -1592,15 +2056,27 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job) return qla2x00_write_fru_status(bsg_job); default: +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = (DID_ERROR << 16); bsg_job->job_done(bsg_job); +#else + bsg_reply->result = (DID_ERROR << 16); +#endif return -ENOTSUPP; } } int +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) qla24xx_bsg_request(struct fc_bsg_job *bsg_job) +#else +qla24xx_bsg_request(struct bsg_job *bsg_job) +#endif { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + struct fc_bsg_request *bsg_request = bsg_job->request; + struct fc_bsg_reply *bsg_reply = bsg_job->reply; +#endif int ret = -EINVAL; struct fc_rport *rport; fc_port_t *fcport = NULL; @@ -1608,31 +2084,55 @@ qla24xx_bsg_request(struct fc_bsg_job *bsg_job) scsi_qla_host_t *vha; /* In case no data transferred. */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->reply_payload_rcv_len = 0; if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) { rport = bsg_job->rport; +#else + bsg_reply->reply_payload_rcv_len = 0; + + if (bsg_request->msgcode == FC_BSG_RPT_ELS) { + rport = fc_bsg_to_rport(bsg_job); +#endif fcport = *(fc_port_t **) rport->dd_data; host = rport_to_shost(rport); vha = shost_priv(host); } else { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) host = bsg_job->shost; +#else + host = fc_bsg_to_shost(bsg_job); +#endif vha = shost_priv(host); } if (qla2x00_reset_active(vha)) { ql_dbg(ql_dbg_user, vha, 0x709f, "BSG: ISP abort active/needed -- cmd=%d.\n", +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->request->msgcode); bsg_job->reply->result = (DID_ERROR << 16); bsg_job->job_done(bsg_job); +#else + bsg_request->msgcode); + bsg_reply->result = (DID_ERROR << 16); +#endif return -EBUSY; } ql_dbg(ql_dbg_user, vha, 0x7000, +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) "Entered %s msgcode=0x%x.\n", __func__, bsg_job->request->msgcode); +#else + "Entered %s msgcode=0x%x.\n", __func__, bsg_request->msgcode); +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) switch (bsg_job->request->msgcode) { +#else + switch (bsg_request->msgcode) { +#endif case FC_BSG_RPT_ELS: case FC_BSG_HST_ELS_NOLOGIN: ret = qla2x00_process_els(bsg_job); @@ -1648,16 +2148,30 @@ qla24xx_bsg_request(struct fc_bsg_job *bsg_job) case FC_BSG_RPT_CT: default: ql_log(ql_log_warn, vha, 0x705a, "Unsupported BSG request.\n"); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = ret; +#else + bsg_reply->result = ret; +#endif break; } return ret; } int +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job) +#else +qla24xx_bsg_timeout(struct bsg_job *bsg_job) +#endif { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) scsi_qla_host_t *vha = shost_priv(bsg_job->shost); +#else + struct fc_bsg_request *bsg_request = bsg_job->request; + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job)); +#endif struct qla_hw_data *ha = vha->hw; srb_t *sp; int cnt, que; @@ -1683,13 +2197,21 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job) "mbx abort_command " "failed.\n"); bsg_job->req->errors = +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = -EIO; +#else + bsg_reply->result = -EIO; +#endif } else { ql_dbg(ql_dbg_user, vha, 0x708a, "mbx abort_command " "success.\n"); bsg_job->req->errors = +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->result = 0; +#else + bsg_reply->result = 0; +#endif } spin_lock_irqsave(&ha->hardware_lock, flags); goto done; @@ -1699,12 +2221,20 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job) } spin_unlock_irqrestore(&ha->hardware_lock, flags); ql_log(ql_log_info, vha, 0x708b, "SRB not found to abort.\n"); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->req->errors = bsg_job->reply->result = -ENXIO; +#else + bsg_job->req->errors = bsg_reply->result = -ENXIO; +#endif return 0; done: spin_unlock_irqrestore(&ha->hardware_lock, flags); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) if (bsg_job->request->msgcode == FC_BSG_HST_CT) +#else + if (bsg_request->msgcode == FC_BSG_HST_CT) +#endif kfree(sp->fcport); mempool_free(sp, ha->srb_mempool); return 0; diff --git a/qla2x00t/qla_def.h b/qla2x00t/qla_def.h index 83944e879..5d8569325 100644 --- a/qla2x00t/qla_def.h +++ b/qla2x00t/qla_def.h @@ -27,6 +27,10 @@ #include #include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) +#include +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) #error #error ***This version of qla2xxx does not support distributions based on*** @@ -289,7 +293,11 @@ typedef struct srb { int iocbs; union { struct srb_iocb iocb_cmd; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) struct fc_bsg_job *bsg_job; +#else + struct bsg_job *bsg_job; +#endif struct srb_cmd scmd; } u; void (*done)(void *, void *, int); diff --git a/qla2x00t/qla_gbl.h b/qla2x00t/qla_gbl.h index c83cfc393..880ee0cf2 100644 --- a/qla2x00t/qla_gbl.h +++ b/qla2x00t/qla_gbl.h @@ -604,8 +604,13 @@ extern int qla82xx_mbx_beacon_ctl(scsi_qla_host_t *, int); extern void qla82xx_clear_pending_mbx(scsi_qla_host_t *); /* BSG related functions */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) +extern int qla24xx_bsg_request(struct bsg_job *); +extern int qla24xx_bsg_timeout(struct bsg_job *); +#else extern int qla24xx_bsg_request(struct fc_bsg_job *); extern int qla24xx_bsg_timeout(struct fc_bsg_job *); +#endif extern int qla84xx_reset_chip(scsi_qla_host_t *, uint16_t); extern int qla2x00_issue_iocb_timeout(scsi_qla_host_t *, void *, dma_addr_t, size_t, uint32_t); diff --git a/qla2x00t/qla_iocb.c b/qla2x00t/qla_iocb.c index 512b83ee8..918058e69 100644 --- a/qla2x00t/qla_iocb.c +++ b/qla2x00t/qla_iocb.c @@ -2105,7 +2105,12 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk) static void qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) struct fc_bsg_job *bsg_job = sp->u.bsg_job; +#else + struct bsg_job *bsg_job = sp->u.bsg_job; + struct fc_bsg_request *bsg_request = bsg_job->request; +#endif els_iocb->entry_type = ELS_IOCB_TYPE; els_iocb->entry_count = 1; @@ -2120,8 +2125,13 @@ qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) els_iocb->opcode = sp->type == SRB_ELS_CMD_RPT ? +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->request->rqst_data.r_els.els_code : bsg_job->request->rqst_data.h_els.command_code; +#else + bsg_request->rqst_data.r_els.els_code : + bsg_request->rqst_data.h_els.command_code; +#endif els_iocb->port_id[0] = sp->fcport->d_id.b.al_pa; els_iocb->port_id[1] = sp->fcport->d_id.b.area; els_iocb->port_id[2] = sp->fcport->d_id.b.domain; @@ -2156,7 +2166,11 @@ qla2x00_ct_iocb(srb_t *sp, ms_iocb_entry_t *ct_iocb) uint16_t tot_dsds; scsi_qla_host_t *vha = sp->fcport->vha; struct qla_hw_data *ha = vha->hw; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) struct fc_bsg_job *bsg_job = sp->u.bsg_job; +#else + struct bsg_job *bsg_job = sp->u.bsg_job; +#endif int loop_iterartion = 0; int cont_iocb_prsnt = 0; int entry_count = 1; @@ -2233,7 +2247,11 @@ qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb) uint16_t tot_dsds; scsi_qla_host_t *vha = sp->fcport->vha; struct qla_hw_data *ha = vha->hw; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) struct fc_bsg_job *bsg_job = sp->u.bsg_job; +#else + struct bsg_job *bsg_job = sp->u.bsg_job; +#endif int loop_iterartion = 0; int cont_iocb_prsnt = 0; int entry_count = 1; diff --git a/qla2x00t/qla_isr.c b/qla2x00t/qla_isr.c index 83714a603..a24098631 100644 --- a/qla2x00t/qla_isr.c +++ b/qla2x00t/qla_isr.c @@ -1080,7 +1080,12 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req, const char func[] = "CT_IOCB"; const char *type; srb_t *sp; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) struct fc_bsg_job *bsg_job; +#else + struct bsg_job *bsg_job; + struct fc_bsg_reply *bsg_reply; +#endif uint16_t comp_status; int res; @@ -1089,6 +1094,9 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req, return; bsg_job = sp->u.bsg_job; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + bsg_reply = bsg_job->reply; +#endif type = "ct pass-through"; @@ -1097,32 +1105,52 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req, /* return FC_CTELS_STATUS_OK and leave the decoding of the ELS/CT * fc payload to the caller */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK; +#else + bsg_reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK; +#endif bsg_job->reply_len = sizeof(struct fc_bsg_reply); if (comp_status != CS_COMPLETE) { if (comp_status == CS_DATA_UNDERRUN) { res = DID_OK << 16; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->reply_payload_rcv_len = +#else + bsg_reply->reply_payload_rcv_len = +#endif le16_to_cpu(((sts_entry_t *)pkt)->rsp_info_len); ql_log(ql_log_warn, vha, 0x5048, "CT pass-through-%s error " "comp_status-status=0x%x total_byte = 0x%x.\n", type, comp_status, +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->reply_payload_rcv_len); +#else + bsg_reply->reply_payload_rcv_len); +#endif } else { ql_log(ql_log_warn, vha, 0x5049, "CT pass-through-%s error " "comp_status-status=0x%x.\n", type, comp_status); res = DID_ERROR << 16; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->reply_payload_rcv_len = 0; +#else + bsg_reply->reply_payload_rcv_len = 0; +#endif } ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5035, (uint8_t *)pkt, sizeof(*pkt)); } else { res = DID_OK << 16; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->reply_payload_rcv_len = +#else + bsg_reply->reply_payload_rcv_len = +#endif bsg_job->reply_payload.payload_len; bsg_job->reply_len = 0; } @@ -1136,7 +1164,12 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, const char func[] = "ELS_CT_IOCB"; const char *type; srb_t *sp; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) struct fc_bsg_job *bsg_job; +#else + struct bsg_job *bsg_job; + struct fc_bsg_reply *bsg_reply; +#endif uint16_t comp_status; uint32_t fw_status[3]; uint8_t* fw_sts_ptr; @@ -1146,6 +1179,9 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, if (!sp) return; bsg_job = sp->u.bsg_job; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + bsg_reply = bsg_job->reply; +#endif type = NULL; switch (sp->type) { @@ -1169,13 +1205,21 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, /* return FC_CTELS_STATUS_OK and leave the decoding of the ELS/CT * fc payload to the caller */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK; +#else + bsg_reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK; +#endif bsg_job->reply_len = sizeof(struct fc_bsg_reply) + sizeof(fw_status); if (comp_status != CS_COMPLETE) { if (comp_status == CS_DATA_UNDERRUN) { res = DID_OK << 16; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->reply_payload_rcv_len = +#else + bsg_reply->reply_payload_rcv_len = +#endif le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->total_byte_count); ql_dbg(ql_dbg_user, vha, 0x503f, @@ -1184,7 +1228,12 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, type, sp->handle, comp_status, fw_status[1], fw_status[2], le16_to_cpu(((struct els_sts_entry_24xx *) pkt)->total_byte_count)); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + fw_sts_ptr = ((uint8_t*)scsi_req(bsg_job->req)->sense) + + sizeof(struct fc_bsg_reply); +#else fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply); +#endif memcpy( fw_sts_ptr, fw_status, sizeof(fw_status)); } else { @@ -1197,8 +1246,17 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, le16_to_cpu(((struct els_sts_entry_24xx *) pkt)->error_subcode_2)); res = DID_ERROR << 16; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->reply_payload_rcv_len = 0; +#else + bsg_reply->reply_payload_rcv_len = 0; +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + fw_sts_ptr = ((uint8_t*)scsi_req(bsg_job->req)->sense) + + sizeof(struct fc_bsg_reply); +#else fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply); +#endif memcpy( fw_sts_ptr, fw_status, sizeof(fw_status)); } ql_dump_buffer(ql_dbg_user + ql_dbg_buffer, vha, 0x5056, @@ -1206,7 +1264,11 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, } else { res = DID_OK << 16; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) bsg_job->reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len; +#else + bsg_reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len; +#endif bsg_job->reply_len = 0; } sp->done(vha, sp, 0); diff --git a/scst/include/backport.h b/scst/include/backport.h index 8bb03ea6c..4cdd92da4 100644 --- a/scst/include/backport.h +++ b/scst/include/backport.h @@ -23,6 +23,7 @@ #include /* struct request_queue */ #include /* struct scatterlist */ #include /* kmalloc() */ +#include #include /* sync_page_range() */ #include /* struct scsi_cmnd */ #include @@ -290,6 +291,10 @@ static inline void hex2bin(u8 *dst, const char *src, size_t count) } #endif +/* + * See also commit 33ee3b2e2eb9. That commit was introduced in kernel v2.6.39 + * and later backported to kernel v2.6.38.4. + */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39) && \ LINUX_VERSION_CODE != KERNEL_VERSION(2, 6, 38) && \ (!defined(RHEL_MAJOR) || RHEL_MAJOR -0 < 6) @@ -349,6 +354,19 @@ static inline int __must_check kref_get_unless_zero(struct kref *kref) } #endif +/* See also commit 2c935bc57221 */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0) +#define kref_read(kref) (atomic_read(&(kref)->refcount)) +#endif + +/* */ + +/* See also commit 207205a2ba26 */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39) +#define kthread_create_on_node(threadfn, data, node, namefmt, arg...)\ + kthread_create((threadfn), (data), (namefmt), ##arg) +#endif + /* */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) && \ @@ -500,6 +518,11 @@ static inline int __ratelimit(struct ratelimit_state *rs) /* */ +/* See also commit b62730baea32 */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34) +#define rcu_dereference_protected(p, c) rcu_dereference(p) +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0) && !defined(kfree_rcu) typedef void (*rcu_callback_t)(struct rcu_head *); #define __is_kfree_rcu_offset(offset) ((offset) < 4096) diff --git a/scst/include/scst.h b/scst/include/scst.h index 797d756f2..98289eef2 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -3695,7 +3695,10 @@ enum dma_data_direction scst_to_tgt_dma_dir(int scst_dir); int scst_register_virtual_device(struct scst_dev_type *dev_handler, const char *dev_name); -void scst_unregister_virtual_device(int id); +void scst_unregister_virtual_device(int id, + void (*on_free)(struct scst_device *dev, + void *arg), + void *arg); /* * Get/Set functions for tgt's sg_tablesize @@ -5606,6 +5609,10 @@ struct scst_data_descriptor { }; void scst_write_same(struct scst_cmd *cmd, struct scst_data_descriptor *where); +int scst_scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, + int data_direction, void *buffer, unsigned bufflen, + unsigned char *sense, int timeout, int retries, + u64 flags); __be64 scst_pack_lun(const uint64_t lun, enum scst_lun_addr_method addr_method); uint64_t scst_unpack_lun(const uint8_t *lun, int len); diff --git a/scst/include/scst_const.h b/scst/include/scst_const.h index ed6b6fba3..1b5b2eceb 100644 --- a/scst/include/scst_const.h +++ b/scst/include/scst_const.h @@ -369,7 +369,9 @@ static inline int scst_sense_response_code(const uint8_t *sense) && (!defined(RHEL_MAJOR) || RHEL_MAJOR -0 <= 5) #define WRITE_ATTRIBUTE 0x8D #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0) #define WRITE_VERIFY_16 0x8E +#endif #define VERIFY_6 0x13 #ifndef VERIFY_12 #define VERIFY_12 0xAF diff --git a/scst/kernel/nolockdep-4.10.patch b/scst/kernel/nolockdep-4.10.patch new file mode 100644 index 000000000..de8440968 --- /dev/null +++ b/scst/kernel/nolockdep-4.10.patch @@ -0,0 +1,114 @@ +=== modified file 'include/linux/lockdep.h' +--- old/include/linux/lockdep.h 2017-05-04 04:27:46 +0000 ++++ new/include/linux/lockdep.h 2017-05-04 04:39:00 +0000 +@@ -373,7 +373,7 @@ extern struct pin_cookie lock_pin_lock(s + extern void lock_repin_lock(struct lockdep_map *lock, struct pin_cookie); + extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie); + +-# define INIT_LOCKDEP .lockdep_recursion = 0, .lockdep_reclaim_gfp = 0, ++# define INIT_LOCKDEP .lockdep_recursion = 0, .lockdep_reclaim_gfp = 0, .nolockdep_call = 0, + + #define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0) + + +=== modified file 'include/linux/sched.h' +--- old/include/linux/sched.h 2017-05-04 04:27:46 +0000 ++++ new/include/linux/sched.h 2017-05-04 04:39:00 +0000 +@@ -1789,6 +1789,9 @@ struct task_struct { + # define MAX_LOCK_DEPTH 48UL + u64 curr_chain_key; + int lockdep_depth; ++# define NOLOCKDEP_SUPPORTED 1 ++ unsigned int nolockdep_call:1; ++ unsigned int nolockdep_call_irq_saved:1; + unsigned int lockdep_recursion; + struct held_lock held_locks[MAX_LOCK_DEPTH]; + gfp_t lockdep_reclaim_gfp; + +=== modified file 'kernel/locking/lockdep.c' +--- old/kernel/locking/lockdep.c 2017-05-04 04:27:46 +0000 ++++ new/kernel/locking/lockdep.c 2017-05-04 04:39:00 +0000 +@@ -3745,9 +3745,11 @@ void lock_acquire(struct lockdep_map *lo + if (unlikely(current->lockdep_recursion)) + return; + ++ if (unlikely(current->nolockdep_call)) ++ return; ++ + raw_local_irq_save(flags); + check_flags(flags); +- + current->lockdep_recursion = 1; + trace_lock_acquire(lock, subclass, trylock, read, check, nest_lock, ip); + __lock_acquire(lock, subclass, trylock, read, check, +@@ -3765,6 +3767,9 @@ void lock_release(struct lockdep_map *lo + if (unlikely(current->lockdep_recursion)) + return; + ++ if (unlikely(current->nolockdep_call)) ++ return; ++ + raw_local_irq_save(flags); + check_flags(flags); + current->lockdep_recursion = 1; +@@ -4013,6 +4018,9 @@ void lock_contended(struct lockdep_map * + if (unlikely(current->lockdep_recursion)) + return; + ++ if (unlikely(current->nolockdep_call)) ++ return; ++ + raw_local_irq_save(flags); + check_flags(flags); + current->lockdep_recursion = 1; +@@ -4033,6 +4041,9 @@ void lock_acquired(struct lockdep_map *l + if (unlikely(current->lockdep_recursion)) + return; + ++ if (unlikely(current->nolockdep_call)) ++ return; ++ + raw_local_irq_save(flags); + check_flags(flags); + current->lockdep_recursion = 1; + +=== modified file 'kernel/softirq.c' +--- old/kernel/softirq.c 2017-05-04 04:27:46 +0000 ++++ new/kernel/softirq.c 2017-05-04 04:39:00 +0000 +@@ -335,6 +335,17 @@ asmlinkage __visible void do_softirq(voi + */ + void irq_enter(void) + { ++#ifdef CONFIG_LOCKDEP ++ if (unlikely(current->nolockdep_call)) { ++ unsigned long flags; ++ local_irq_save(flags); ++ if (current->nolockdep_call) { ++ current->nolockdep_call_irq_saved = 1; ++ current->nolockdep_call = 0; ++ } ++ local_irq_restore(flags); ++ } ++#endif + rcu_irq_enter(); + if (is_idle_task(current) && !in_interrupt()) { + /* +@@ -406,6 +417,17 @@ void irq_exit(void) + + tick_irq_exit(); + rcu_irq_exit(); ++#ifdef CONFIG_LOCKDEP ++ if (unlikely(current->nolockdep_call_irq_saved)) { ++ unsigned long flags; ++ local_irq_save(flags); ++ if (current->nolockdep_call_irq_saved) { ++ current->nolockdep_call_irq_saved = 0; ++ current->nolockdep_call = 1; ++ } ++ local_irq_restore(flags); ++ } ++#endif + trace_hardirq_exit(); /* must be last! */ + } + + diff --git a/scst/kernel/nolockdep-4.11.patch b/scst/kernel/nolockdep-4.11.patch new file mode 100644 index 000000000..21c312e34 --- /dev/null +++ b/scst/kernel/nolockdep-4.11.patch @@ -0,0 +1,114 @@ +=== modified file 'include/linux/lockdep.h' +--- old/include/linux/lockdep.h 2017-06-02 03:24:57 +0000 ++++ new/include/linux/lockdep.h 2017-06-02 03:31:44 +0000 +@@ -373,7 +373,7 @@ extern struct pin_cookie lock_pin_lock(s + extern void lock_repin_lock(struct lockdep_map *lock, struct pin_cookie); + extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie); + +-# define INIT_LOCKDEP .lockdep_recursion = 0, .lockdep_reclaim_gfp = 0, ++# define INIT_LOCKDEP .lockdep_recursion = 0, .lockdep_reclaim_gfp = 0, .nolockdep_call = 0, + + #define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0) + + +=== modified file 'include/linux/sched.h' +--- old/include/linux/sched.h 2017-06-02 03:24:57 +0000 ++++ new/include/linux/sched.h 2017-06-02 03:31:44 +0000 +@@ -808,6 +808,9 @@ struct task_struct { + # define MAX_LOCK_DEPTH 48UL + u64 curr_chain_key; + int lockdep_depth; ++# define NOLOCKDEP_SUPPORTED 1 ++ unsigned int nolockdep_call:1; ++ unsigned int nolockdep_call_irq_saved:1; + unsigned int lockdep_recursion; + struct held_lock held_locks[MAX_LOCK_DEPTH]; + gfp_t lockdep_reclaim_gfp; + +=== modified file 'kernel/locking/lockdep.c' +--- old/kernel/locking/lockdep.c 2017-06-02 03:24:57 +0000 ++++ new/kernel/locking/lockdep.c 2017-06-02 03:31:44 +0000 +@@ -3754,9 +3754,11 @@ void lock_acquire(struct lockdep_map *lo + if (unlikely(current->lockdep_recursion)) + return; + ++ if (unlikely(current->nolockdep_call)) ++ return; ++ + raw_local_irq_save(flags); + check_flags(flags); +- + current->lockdep_recursion = 1; + trace_lock_acquire(lock, subclass, trylock, read, check, nest_lock, ip); + __lock_acquire(lock, subclass, trylock, read, check, +@@ -3774,6 +3776,9 @@ void lock_release(struct lockdep_map *lo + if (unlikely(current->lockdep_recursion)) + return; + ++ if (unlikely(current->nolockdep_call)) ++ return; ++ + raw_local_irq_save(flags); + check_flags(flags); + current->lockdep_recursion = 1; +@@ -4022,6 +4027,9 @@ void lock_contended(struct lockdep_map * + if (unlikely(current->lockdep_recursion)) + return; + ++ if (unlikely(current->nolockdep_call)) ++ return; ++ + raw_local_irq_save(flags); + check_flags(flags); + current->lockdep_recursion = 1; +@@ -4042,6 +4050,9 @@ void lock_acquired(struct lockdep_map *l + if (unlikely(current->lockdep_recursion)) + return; + ++ if (unlikely(current->nolockdep_call)) ++ return; ++ + raw_local_irq_save(flags); + check_flags(flags); + current->lockdep_recursion = 1; + +=== modified file 'kernel/softirq.c' +--- old/kernel/softirq.c 2017-06-02 03:24:57 +0000 ++++ new/kernel/softirq.c 2017-06-02 03:31:44 +0000 +@@ -335,6 +335,17 @@ asmlinkage __visible void do_softirq(voi + */ + void irq_enter(void) + { ++#ifdef CONFIG_LOCKDEP ++ if (unlikely(current->nolockdep_call)) { ++ unsigned long flags; ++ local_irq_save(flags); ++ if (current->nolockdep_call) { ++ current->nolockdep_call_irq_saved = 1; ++ current->nolockdep_call = 0; ++ } ++ local_irq_restore(flags); ++ } ++#endif + rcu_irq_enter(); + if (is_idle_task(current) && !in_interrupt()) { + /* +@@ -406,6 +417,17 @@ void irq_exit(void) + + tick_irq_exit(); + rcu_irq_exit(); ++#ifdef CONFIG_LOCKDEP ++ if (unlikely(current->nolockdep_call_irq_saved)) { ++ unsigned long flags; ++ local_irq_save(flags); ++ if (current->nolockdep_call_irq_saved) { ++ current->nolockdep_call_irq_saved = 0; ++ current->nolockdep_call = 1; ++ } ++ local_irq_restore(flags); ++ } ++#endif + trace_hardirq_exit(); /* must be last! */ + } + + diff --git a/scst/kernel/nolockdep-4.9.patch b/scst/kernel/nolockdep-4.9.patch new file mode 100644 index 000000000..1f2158684 --- /dev/null +++ b/scst/kernel/nolockdep-4.9.patch @@ -0,0 +1,114 @@ +=== modified file 'include/linux/lockdep.h' +--- old/include/linux/lockdep.h 2017-02-02 22:58:27 +0000 ++++ new/include/linux/lockdep.h 2017-02-02 23:07:50 +0000 +@@ -364,7 +364,7 @@ extern struct pin_cookie lock_pin_lock(s + extern void lock_repin_lock(struct lockdep_map *lock, struct pin_cookie); + extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie); + +-# define INIT_LOCKDEP .lockdep_recursion = 0, .lockdep_reclaim_gfp = 0, ++# define INIT_LOCKDEP .lockdep_recursion = 0, .lockdep_reclaim_gfp = 0, .nolockdep_call = 0, + + #define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0) + + +=== modified file 'include/linux/sched.h' +--- old/include/linux/sched.h 2017-02-02 22:58:27 +0000 ++++ new/include/linux/sched.h 2017-02-02 23:07:50 +0000 +@@ -1746,6 +1746,9 @@ struct task_struct { + # define MAX_LOCK_DEPTH 48UL + u64 curr_chain_key; + int lockdep_depth; ++# define NOLOCKDEP_SUPPORTED 1 ++ unsigned int nolockdep_call:1; ++ unsigned int nolockdep_call_irq_saved:1; + unsigned int lockdep_recursion; + struct held_lock held_locks[MAX_LOCK_DEPTH]; + gfp_t lockdep_reclaim_gfp; + +=== modified file 'kernel/locking/lockdep.c' +--- old/kernel/locking/lockdep.c 2017-02-02 22:58:27 +0000 ++++ new/kernel/locking/lockdep.c 2017-02-02 23:07:50 +0000 +@@ -3741,9 +3741,11 @@ void lock_acquire(struct lockdep_map *lo + if (unlikely(current->lockdep_recursion)) + return; + ++ if (unlikely(current->nolockdep_call)) ++ return; ++ + raw_local_irq_save(flags); + check_flags(flags); +- + current->lockdep_recursion = 1; + trace_lock_acquire(lock, subclass, trylock, read, check, nest_lock, ip); + __lock_acquire(lock, subclass, trylock, read, check, +@@ -3761,6 +3763,9 @@ void lock_release(struct lockdep_map *lo + if (unlikely(current->lockdep_recursion)) + return; + ++ if (unlikely(current->nolockdep_call)) ++ return; ++ + raw_local_irq_save(flags); + check_flags(flags); + current->lockdep_recursion = 1; +@@ -4009,6 +4014,9 @@ void lock_contended(struct lockdep_map * + if (unlikely(current->lockdep_recursion)) + return; + ++ if (unlikely(current->nolockdep_call)) ++ return; ++ + raw_local_irq_save(flags); + check_flags(flags); + current->lockdep_recursion = 1; +@@ -4029,6 +4037,9 @@ void lock_acquired(struct lockdep_map *l + if (unlikely(current->lockdep_recursion)) + return; + ++ if (unlikely(current->nolockdep_call)) ++ return; ++ + raw_local_irq_save(flags); + check_flags(flags); + current->lockdep_recursion = 1; + +=== modified file 'kernel/softirq.c' +--- old/kernel/softirq.c 2017-02-02 22:58:27 +0000 ++++ new/kernel/softirq.c 2017-02-02 23:07:50 +0000 +@@ -335,6 +335,17 @@ asmlinkage __visible void do_softirq(voi + */ + void irq_enter(void) + { ++#ifdef CONFIG_LOCKDEP ++ if (unlikely(current->nolockdep_call)) { ++ unsigned long flags; ++ local_irq_save(flags); ++ if (current->nolockdep_call) { ++ current->nolockdep_call_irq_saved = 1; ++ current->nolockdep_call = 0; ++ } ++ local_irq_restore(flags); ++ } ++#endif + rcu_irq_enter(); + if (is_idle_task(current) && !in_interrupt()) { + /* +@@ -406,6 +417,17 @@ void irq_exit(void) + + tick_irq_exit(); + rcu_irq_exit(); ++#ifdef CONFIG_LOCKDEP ++ if (unlikely(current->nolockdep_call_irq_saved)) { ++ unsigned long flags; ++ local_irq_save(flags); ++ if (current->nolockdep_call_irq_saved) { ++ current->nolockdep_call_irq_saved = 0; ++ current->nolockdep_call = 1; ++ } ++ local_irq_restore(flags); ++ } ++#endif + trace_hardirq_exit(); /* must be last! */ + } + + diff --git a/scst/src/dev_handlers/scst_cdrom.c b/scst/src/dev_handlers/scst_cdrom.c index 92697b5bb..17415864f 100644 --- a/scst/src/dev_handlers/scst_cdrom.c +++ b/scst/src/dev_handlers/scst_cdrom.c @@ -96,13 +96,9 @@ static int cdrom_attach(struct scst_device *dev) data_dir = SCST_DATA_READ; TRACE_DBG("%s", "Doing READ_CAPACITY"); - rc = scsi_execute(dev->scsi_dev, cmd, data_dir, buffer, - buffer_size, sense_buffer, - SCST_GENERIC_CDROM_REG_TIMEOUT, 3, 0 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) - , NULL -#endif - ); + rc = scst_scsi_execute(dev->scsi_dev, cmd, data_dir, buffer, + buffer_size, sense_buffer, + SCST_GENERIC_CDROM_REG_TIMEOUT, 3, 0); TRACE_DBG("READ_CAPACITY done: %x", rc); diff --git a/scst/src/dev_handlers/scst_disk.c b/scst/src/dev_handlers/scst_disk.c index a6f00be1f..36254bf70 100644 --- a/scst/src/dev_handlers/scst_disk.c +++ b/scst/src/dev_handlers/scst_disk.c @@ -193,13 +193,9 @@ static int disk_attach(struct scst_device *dev) data_dir = SCST_DATA_READ; TRACE_DBG("%s", "Doing READ_CAPACITY"); - rc = scsi_execute(dev->scsi_dev, cmd, data_dir, buffer, - buffer_size, sense_buffer, - SCST_GENERIC_DISK_REG_TIMEOUT, 3, 0 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) - , NULL -#endif - ); + rc = scst_scsi_execute(dev->scsi_dev, cmd, data_dir, buffer, + buffer_size, sense_buffer, + SCST_GENERIC_DISK_REG_TIMEOUT, 3, 0); TRACE_DBG("READ_CAPACITY done: %x", rc); diff --git a/scst/src/dev_handlers/scst_modisk.c b/scst/src/dev_handlers/scst_modisk.c index 5dd8271c0..9e0f8fffa 100644 --- a/scst/src/dev_handlers/scst_modisk.c +++ b/scst/src/dev_handlers/scst_modisk.c @@ -197,13 +197,9 @@ static int modisk_attach(struct scst_device *dev) data_dir = SCST_DATA_READ; TRACE_DBG("%s", "Doing READ_CAPACITY"); - rc = scsi_execute(dev->scsi_dev, cmd, data_dir, buffer, - buffer_size, sense_buffer, - SCST_GENERIC_MODISK_REG_TIMEOUT, 3, 0 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) - , NULL -#endif - ); + rc = scst_scsi_execute(dev->scsi_dev, cmd, data_dir, buffer, + buffer_size, sense_buffer, + SCST_GENERIC_MODISK_REG_TIMEOUT, 3, 0); TRACE_DBG("READ_CAPACITY done: %x", rc); diff --git a/scst/src/dev_handlers/scst_user.c b/scst/src/dev_handlers/scst_user.c index 34f5fb1be..a4cf449ac 100644 --- a/scst/src/dev_handlers/scst_user.c +++ b/scst/src/dev_handlers/scst_user.c @@ -22,6 +22,10 @@ #include #include #include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) +#include +#endif #define LOG_PREFIX DEV_USER_NAME @@ -3510,7 +3514,7 @@ out: return res; out_unreg_drv: - scst_unregister_virtual_device(dev->virt_id); + scst_unregister_virtual_device(dev->virt_id, NULL, NULL); out_unreg_handler: scst_unregister_virtual_dev_driver(&dev->devtype); @@ -3879,7 +3883,7 @@ static int dev_user_exit_dev(struct scst_user_dev *dev) wake_up(&cleanup_list_waitQ); - scst_unregister_virtual_device(dev->virt_id); + scst_unregister_virtual_device(dev->virt_id, NULL, NULL); scst_unregister_virtual_dev_driver(&dev->devtype); sgv_pool_flush(dev->pool_clust); diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index 04f80fafe..3446bcf0c 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -55,6 +55,9 @@ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) #include #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) +#include +#endif #define LOG_PREFIX "dev_vdisk" @@ -352,6 +355,7 @@ static enum compl_status_e vdisk_exec_write_same(struct vdisk_cmd_params *p); static int vdisk_fsync(loff_t loff, loff_t len, struct scst_device *dev, gfp_t gfp_flags, struct scst_cmd *cmd, bool async); +static void vdev_on_free(struct scst_device *dev, void *arg); #ifdef CONFIG_SCST_PROC static int vdisk_read_proc(struct seq_file *seq, struct scst_dev_type *dev_type); @@ -1067,7 +1071,9 @@ check: if (virt_dev->unmap_opt_gran == virt_dev->unmap_align) virt_dev->unmap_align = 0; virt_dev->unmap_max_lba_cnt = q->limits.max_discard_sectors >> (block_shift - 9); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0) virt_dev->discard_zeroes_data = q->limits.discard_zeroes_data; +#endif #else sBUG(); #endif @@ -1677,6 +1683,11 @@ next: dev->dev_rd_only = virt_dev->rd_only; +#ifdef CONFIG_SCST_PROC + if (virt_dev->nullio && !virt_dev->file_size) + virt_dev->file_size = VDISK_NULLIO_SIZE; +#endif + res = vdisk_reexamine(virt_dev); if (res < 0) goto out; @@ -7836,8 +7847,6 @@ out_free: static void vdev_destroy(struct scst_vdisk_dev *virt_dev) { - cancel_work_sync(&virt_dev->vdev_inq_changed_work); - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) vdisk_free_bioset(virt_dev); #endif @@ -8322,12 +8331,27 @@ out: #endif /* CONFIG_SCST_PROC */ +static void vdev_on_free(struct scst_device *dev, void *arg) +{ + struct scst_vdisk_dev *virt_dev = arg; + + TRACE_DBG("%s(%s)", __func__, dev->virt_name ? : "(?)"); + + /* + * This call must happen after scst_unregister_virtual_device() + * has called scst_dev_sysfs_del() and before scst_free_device() + * starts deallocating *dev. + */ + cancel_work_sync(&virt_dev->vdev_inq_changed_work); +} + /* scst_vdisk_mutex supposed to be held */ static void vdev_del_device(struct scst_vdisk_dev *virt_dev) { TRACE_ENTRY(); - scst_unregister_virtual_device(virt_dev->virt_id); + scst_unregister_virtual_device(virt_dev->virt_id, vdev_on_free, + virt_dev); list_del(&virt_dev->vdev_list_entry); @@ -10304,7 +10328,7 @@ static int vdisk_write_proc(char *buffer, char **start, off_t offset, PRINT_ERROR("File path \"%s\" is not " "absolute", filename); res = -EINVAL; - goto out_up; + goto out_free_vdev; } virt_dev->filename = kstrdup(filename, GFP_KERNEL); diff --git a/scst/src/scst_copy_mgr.c b/scst/src/scst_copy_mgr.c index f367da21f..073df693a 100644 --- a/scst/src/scst_copy_mgr.c +++ b/scst/src/scst_copy_mgr.c @@ -2345,7 +2345,7 @@ static void scst_cm_init_inq_finish(struct scst_cmd *cmd) /* cmd->dev can be NULL here! */ rc = scst_cm_err_check_retry(cmd, cmd->start_time, scst_cm_inq_retry_fn); - if (rc == SCST_CM_STATUS_RETRY) + if (rc == SCST_CM_STATUS_RETRY || !cmd->dev || !cmd->tgt_dev) goto out; spin_lock_bh(&dev->dev_lock); @@ -2521,9 +2521,8 @@ static bool scst_cm_is_lun_free(unsigned int lun) /* scst_mutex supposed to be held and activities suspended */ static unsigned int scst_cm_get_lun(const struct scst_device *dev) { - unsigned int res = -1; + unsigned int res = SCST_MAX_LUN; int i; - bool found = false; TRACE_ENTRY(); @@ -2533,7 +2532,6 @@ static unsigned int scst_cm_get_lun(const struct scst_device *dev) list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { if (tgt_dev->dev == dev) { res = tgt_dev->lun; - found = true; TRACE_DBG("LUN %d found (full LUN %lld)", res, tgt_dev->lun); goto out; @@ -2541,8 +2539,6 @@ static unsigned int scst_cm_get_lun(const struct scst_device *dev) } } - sBUG_ON(!found); - out: TRACE_EXIT_RES(res); return res; diff --git a/scst/src/scst_event.c b/scst/src/scst_event.c index 49805dbd7..831726784 100644 --- a/scst/src/scst_event.c +++ b/scst/src/scst_event.c @@ -11,6 +11,10 @@ #include #include #include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) +#include +#endif #ifdef INSIDE_KERNEL_TREE #include diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index 5017447d9..f7df7a56a 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -37,6 +37,9 @@ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) #include #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) +#include +#endif #include #include @@ -4778,6 +4781,7 @@ static void scst_put_acg_work(struct work_struct *work) void scst_put_acg(struct scst_acg *acg) { struct scst_acg_put_work *put_work; + bool rc; put_work = kmalloc(sizeof(*put_work), GFP_KERNEL | __GFP_NOFAIL); if (WARN_ON_ONCE(!put_work)) { @@ -4796,7 +4800,9 @@ void scst_put_acg(struct scst_acg *acg) * Schedule the kref_put() call instead of invoking it directly to * avoid deep recursion and a stack overflow. */ - WARN_ON_ONCE(!queue_work(scst_release_acg_wq, &put_work->work)); + rc = queue_work(scst_release_acg_wq, &put_work->work); + WARN_ON_ONCE(!rc); + return; } void scst_get_acg(struct scst_acg *acg) @@ -6754,6 +6760,25 @@ out: return res; } +int scst_scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, + int data_direction, void *buffer, unsigned bufflen, + unsigned char *sense, int timeout, int retries, u64 flags) +{ + return scsi_execute(sdev, cmd, data_direction, buffer, bufflen, sense, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + NULL, /* sshdr */ +#endif + timeout, retries, flags +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + , 0 /* rq_flags */ +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) + , NULL /* resid */ +#endif + ); +} +EXPORT_SYMBOL(scst_scsi_execute); + static void scst_send_release(struct scst_device *dev) { struct scsi_device *scsi_dev; @@ -6778,12 +6803,8 @@ static void scst_send_release(struct scst_device *dev) TRACE(TRACE_DEBUG | TRACE_SCSI, "%s", "Sending RELEASE req to " "SCSI mid-level"); - rc = scsi_execute(scsi_dev, cdb, SCST_DATA_NONE, NULL, 0, - sense, 15, 0, 0 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) - , NULL -#endif - ); + rc = scst_scsi_execute(scsi_dev, cdb, SCST_DATA_NONE, NULL, 0, + sense, 15, 0, 0); TRACE_DBG("RELEASE done: %x", rc); if (scsi_status_is_good(rc)) { @@ -7813,7 +7834,11 @@ static struct request *blk_make_request(struct request_queue *q, if (IS_ERR(rq)) return rq; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + scsi_req_init(rq); +#else blk_rq_set_block_pc(rq); +#endif for_each_bio(bio) { struct bio *bounce_bio = bio; @@ -7979,7 +8004,15 @@ static struct request *__blk_map_kern_sg(struct request_queue *q, if (bw != NULL) { atomic_set(&bw->bios_inflight, bios); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) + /* + * See also patch "block: split out request-only flags into a new namespace" + * (commit e806402130c9). + */ rq->cmd_flags |= REQ_COPY_USER; +#else + rq->rq_flags |= RQF_COPY_USER; +#endif } out: @@ -8015,7 +8048,11 @@ static struct request *blk_map_kern_sg(struct request_queue *q, if (unlikely(!rq)) return ERR_PTR(-ENOMEM); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + scsi_req_init(rq); +#else rq->cmd_type = REQ_TYPE_BLOCK_PC; +#endif goto out; } @@ -8210,12 +8247,29 @@ static void scsi_end_async(struct request *req, int error) lockdep_assert_held(req->q->queue_lock); #endif - if (sioc->done) -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 30) - sioc->done(sioc->data, sioc->sense, req->errors, req->data_len); + if (sioc->done) { + int result, resid_len; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + result = scsi_req(req)->result; #else - sioc->done(sioc->data, sioc->sense, req->errors, req->resid_len); + result = req->errors; #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + resid_len = scsi_req(req)->resid_len; +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31) + resid_len = req->resid_len; +#else + /* + * A quote from commit c3a4d78c580d: "rq->data_len served two + * purposes - the length of data buffer on issue and the + * residual count on completion." + */ + resid_len = req->data_len; +#endif + + sioc->done(sioc->data, sioc->sense, result, resid_len); + } kmem_cache_free(scsi_io_context_cache, sioc); @@ -8235,6 +8289,11 @@ int scst_scsi_exec_async(struct scst_cmd *cmd, void *data, int res = 0; struct request_queue *q = cmd->dev->scsi_dev->request_queue; struct request *rq; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + struct scsi_request *req; +#else + struct request *req; +#endif struct scsi_io_context *sioc; bool reading = !(cmd->data_direction & SCST_DATA_WRITE); gfp_t gfp = cmd->cmd_gfp_mask; @@ -8283,17 +8342,27 @@ int scst_scsi_exec_async(struct scst_cmd *cmd, void *data, sioc->data = data; sioc->done = done; - rq->cmd_len = cmd_len; - if (rq->cmd_len <= BLK_MAX_CDB) { - memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */ - memcpy(rq->cmd, cmd->cdb, cmd->cdb_len); - } else - rq->cmd = cmd->cdb; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + req = scsi_req(rq); +#else + req = rq; +#endif - rq->sense = sioc->sense; - rq->sense_len = sizeof(sioc->sense); + req->cmd_len = cmd_len; + if (req->cmd_len <= BLK_MAX_CDB) { + memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */ + memcpy(req->cmd, cmd->cdb, cmd->cdb_len); + } else + req->cmd = cmd->cdb; + + req->sense = sioc->sense; + req->sense_len = sizeof(sioc->sense); rq->timeout = cmd->timeout; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + req->retries = cmd->retries; +#else rq->retries = cmd->retries; +#endif rq->end_io_data = sioc; #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35) rq->cmd_flags |= REQ_FAILFAST_MASK; @@ -13168,12 +13237,9 @@ int scst_obtain_device_parameters(struct scst_device *dev, memset(sense_buffer, 0, sizeof(sense_buffer)); TRACE(TRACE_SCSI, "%s", "Doing internal MODE_SENSE"); - rc = scsi_execute(dev->scsi_dev, cmd, SCST_DATA_READ, buffer, - sizeof(buffer), sense_buffer, 15, 0, 0 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) - , NULL -#endif - ); + rc = scst_scsi_execute(dev->scsi_dev, cmd, SCST_DATA_READ, + buffer, sizeof(buffer), sense_buffer, + 15, 0, 0); TRACE_DBG("MODE_SENSE done: %x", rc); diff --git a/scst/src/scst_main.c b/scst/src/scst_main.c index 8c569d274..36ddaf837 100644 --- a/scst/src/scst_main.c +++ b/scst/src/scst_main.c @@ -176,7 +176,7 @@ static unsigned int scst_max_cmd_mem; unsigned int scst_max_dev_cmd_mem; int scst_forcibly_close_sessions; -module_param_named(scst_threads, scst_threads, int, 0); +module_param_named(scst_threads, scst_threads, int, S_IRUGO); MODULE_PARM_DESC(scst_threads, "SCSI target threads count"); module_param_named(scst_max_cmd_mem, scst_max_cmd_mem, int, S_IRUGO); @@ -1266,7 +1266,10 @@ static struct scst_device *__scst_lookup_device(struct scsi_device *scsidp) return NULL; } -static void scst_unregister_device(struct scsi_device *scsidp) +static void scst_unregister_device(struct scsi_device *scsidp, + void (*on_free)(struct scst_device *dev, + void* arg), + void *arg) { struct scst_device *dev; struct scst_acg_dev *acg_dev, *aa; @@ -1324,6 +1327,9 @@ static void scst_unregister_device(struct scsi_device *scsidp) scsidp->host->host_no, scsidp->channel, scsidp->id, (u64)scsidp->lun, scsidp->type); + if (on_free) + on_free(dev, arg); + scst_free_device(dev); out: @@ -1553,7 +1559,10 @@ EXPORT_SYMBOL_GPL(scst_register_virtual_device); * scst_unregister_virtual_device() - unegister a virtual device. * @id: the device's ID, returned by the registration function */ -void scst_unregister_virtual_device(int id) +void scst_unregister_virtual_device(int id, + void (*on_free)(struct scst_device *dev, + void *arg), + void *arg) { struct scst_device *d, *dev = NULL; struct scst_acg_dev *acg_dev, *aa; @@ -1600,6 +1609,9 @@ void scst_unregister_virtual_device(int id) PRINT_INFO("Detached from virtual device %s (id %d)", dev->virt_name, dev->virt_id); + if (on_free) + on_free(dev, arg); + scst_free_device(dev); out: @@ -2394,7 +2406,7 @@ static void scst_remove(struct device *cdev, struct class_interface *intf) if ((scsidp->host->hostt->name == NULL) || (strcmp(scsidp->host->hostt->name, SCST_LOCAL_NAME) != 0)) - scst_unregister_device(scsidp); + scst_unregister_device(scsidp, NULL, NULL); TRACE_EXIT(); return; @@ -2836,7 +2848,9 @@ static void __exit exit_scst(void) scsi_unregister_interface(&scst_interface); #ifdef CONFIG_SCST_PROC + mutex_lock(&scst_mutex); scst_del_free_acg(scst_default_acg, false); + mutex_unlock(&scst_mutex); #endif scst_sgv_pools_deinit(); diff --git a/scst/src/scst_proc.c b/scst/src/scst_proc.c index ebd12d5e8..bf5d3637b 100644 --- a/scst/src/scst_proc.c +++ b/scst/src/scst_proc.c @@ -939,23 +939,14 @@ static void scst_proc_del_acg_tree(struct proc_dir_entry *acg_proc_root, /* The activity supposed to be suspended and scst_mutex held */ static int scst_proc_group_add(const char *p, unsigned int addr_method) { - int res = 0, len = strlen(p) + 1; + int res = 0; struct scst_acg *acg; - char *name = NULL; - TRACE_ENTRY(); - name = kmalloc(len, GFP_KERNEL); - if (name == NULL) { - PRINT_ERROR("Allocation of new name (size %d) failed", len); - goto out_nomem; - } - strlcpy(name, p, len); - - res = scst_alloc_add_acg(NULL, name, false, &acg); + res = scst_alloc_add_acg(NULL, p, false, &acg); if (res != 0) { - PRINT_ERROR("scst_alloc_add_acg() (name %s) failed", name); - goto out_free; + PRINT_ERROR("scst_alloc_add_acg() (name %s) failed", p); + goto out; } acg->addr_method = addr_method; @@ -971,11 +962,6 @@ out: out_free_acg: scst_proc_del_free_acg(acg, 0); -out_free: - kfree(name); - goto out; - -out_nomem: res = -ENOMEM; goto out; } @@ -1227,7 +1213,11 @@ void scst_proc_cleanup_module(void) /* We may not bother about locks here */ scst_proc_cleanup_sgv(); + + mutex_lock(&scst_mutex); scst_proc_cleanup_groups(); + mutex_unlock(&scst_mutex); + scst_proc_cleanup_module_log(); remove_proc_entry(SCST_PROC_THREADS_NAME, scst_proc_scsi_tgt); remove_proc_entry(SCST_PROC_HELP_NAME, scst_proc_scsi_tgt); diff --git a/scst/src/scst_sysfs.c b/scst/src/scst_sysfs.c index 8bc922cc8..282b9e9c0 100644 --- a/scst/src/scst_sysfs.c +++ b/scst/src/scst_sysfs.c @@ -1202,7 +1202,7 @@ void scst_kobject_put_and_wait(struct kobject *kobj, const char *category, goto out_free; PRINT_INFO("Waiting for release of sysfs entry for %s %s (%d refs)", - category, name ? : "(?)", atomic_read(&kobj->kref.refcount)); + category, name ? : "(?)", kref_read(&kobj->kref)); wait_for_completion(c); PRINT_INFO("Finished waiting for release of %s %s sysfs entry", category, name ? : "(?)"); diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index cb1d06939..c585a90c8 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -7077,7 +7077,8 @@ static int scst_mgmt_affected_cmds_done(struct scst_mgmt_cmd *mcmd) case SCST_CLEAR_TASK_SET: case SCST_PR_ABORT_ALL: case SCST_LUN_RESET: - scst_call_dev_task_mgmt_fn_done(mcmd, mcmd->mcmd_tgt_dev); + if (mcmd->mcmd_tgt_dev != NULL) + scst_call_dev_task_mgmt_fn_done(mcmd, mcmd->mcmd_tgt_dev); break; case SCST_TARGET_RESET: diff --git a/scst_local/scst_local.c b/scst_local/scst_local.c index b545a3951..f93d557d9 100644 --- a/scst_local/scst_local.c +++ b/scst_local/scst_local.c @@ -1265,6 +1265,7 @@ static void scst_process_aens(struct scst_local_sess *sess, __acquires(&sess->aen_lock) { struct scst_aen_work_item *work_item = NULL; + struct Scsi_Host *shost; TRACE_ENTRY(); @@ -1274,7 +1275,9 @@ static void scst_process_aens(struct scst_local_sess *sess, work_item = list_first_entry(&sess->aen_work_list, struct scst_aen_work_item, work_list_entry); list_del(&work_item->work_list_entry); - + shost = sess->shost; + if (shost && !scsi_host_get(shost)) + shost = NULL; spin_unlock(&sess->aen_lock); if (cleanup_only) @@ -1283,13 +1286,17 @@ static void scst_process_aens(struct scst_local_sess *sess, sBUG_ON(work_item->aen->event_fn != SCST_AEN_SCSI); /* Let's always rescan */ - scsi_scan_target(&sess->shost->shost_gendev, 0, 0, - SCAN_WILD_CARD, 1); + if (shost) + scsi_scan_target(&shost->shost_gendev, 0, 0, + SCAN_WILD_CARD, 1); done: scst_aen_done(work_item->aen); kfree(work_item); + if (shost) + scsi_host_put(shost); + spin_lock(&sess->aen_lock); } @@ -1707,12 +1714,18 @@ out: static int scst_local_driver_remove(struct device *dev) { struct scst_local_sess *sess; + struct Scsi_Host *shost = NULL; TRACE_ENTRY(); sess = to_scst_lcl_sess(dev); - scsi_remove_host(sess->shost); - scsi_host_put(sess->shost); + + spin_lock(&sess->aen_lock); + swap(sess->shost, shost); + spin_unlock(&sess->aen_lock); + + scsi_remove_host(shost); + scsi_host_put(shost); TRACE_EXIT(); return 0; diff --git a/srpt/src/ib_srpt.c b/srpt/src/ib_srpt.c index 83c3a40ec..97de279bf 100644 --- a/srpt/src/ib_srpt.c +++ b/srpt/src/ib_srpt.c @@ -3535,8 +3535,11 @@ static int srpt_xfer_data(struct srpt_rdma_ch *ch, int ret; if (ioctx->imm_data) { - BUG_ON(!srpt_test_and_set_cmd_state(ioctx, SRPT_STATE_NEED_DATA, - SRPT_STATE_DATA_IN)); + bool res; + + res = srpt_test_and_set_cmd_state(ioctx, SRPT_STATE_NEED_DATA, + SRPT_STATE_DATA_IN); + BUG_ON(!res); if (unlikely(!scst_cmd_get_tgt_data_buff_alloced(cmd))) { unsigned offset = 0, len; uint8_t *buf; diff --git a/usr/fileio/common.c b/usr/fileio/common.c index 8d0f1b9c8..44df2effe 100644 --- a/usr/fileio/common.c +++ b/usr/fileio/common.c @@ -747,7 +747,7 @@ static int process_cmd(struct vdisk_cmd *vcmd) case SCST_USER_TASK_MGMT_DONE: res = do_tm(vcmd, 1); -#if DEBUG_TM_FN_IGNORE +#ifdef DEBUG_TM_FN_IGNORE if (dev->debug_tm_ignore) { sleep(15); } diff --git a/usr/stpgd/stpgd_main.c b/usr/stpgd/stpgd_main.c index 63fa92bdd..be0796248 100644 --- a/usr/stpgd/stpgd_main.c +++ b/usr/stpgd/stpgd_main.c @@ -195,7 +195,7 @@ int wait_until_finished(pid_t pid, unsigned long deadline, int *status, int chil } break; } - sleep(0.1); + usleep(100*1000); time(&end); elapsed = difftime(end, start); } while (elapsed < deadline);