Commit 7a1f7b3d68174f99d01d52b585088b2eaee758a6

Authored by Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/scsi-post-merge-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/scsi-post-merge-2.6:
  tcm_fc: Fix conversion spec warning
  tcm_fc: Fix possible lock to unlock type deadlock
  tcm_fc: Fix ft_send_tm LUN lookup OOPs
  target: Fix incorrect strlen() NULL terminator checks
  target: Drop bogus ERR_PTR usage in target_fabric_configfs_init
  target: Fix ERR_PTR dereferencing bugs
  target: Convert transport_deregister_session_configfs nacl_sess_lock to save irq state
  target: Fix transport_get_lun_for_tmr failure cases
  [SCSI] target: Convert TASK_ATTR to scsi_tcq.h definitions
  [SCSI] target: Convert REPORT_LUNs to use int_to_scsilun
  [SCSI] target: Fix task->task_execute_queue=1 clear bug + LUN_RESET OOPs
  [SCSI] target: Fix bug with task_sg chained transport_free_dev_tasks release
  [SCSI] target: Fix interrupt context bug with stats_lock and core_tmr_alloc_req
  [SCSI] target: Fix multi task->task_sg[] chaining logic bug

Showing 10 changed files Side-by-side Diff

drivers/target/loopback/tcm_loop.c
... ... @@ -386,7 +386,7 @@
386 386 */
387 387 se_cmd->se_tmr_req = core_tmr_alloc_req(se_cmd, (void *)tl_tmr,
388 388 TMR_LUN_RESET);
389   - if (!se_cmd->se_tmr_req)
  389 + if (IS_ERR(se_cmd->se_tmr_req))
390 390 goto release;
391 391 /*
392 392 * Locate the underlying TCM struct se_lun from sc->device->lun
... ... @@ -1017,6 +1017,7 @@
1017 1017 struct se_portal_group *se_tpg;
1018 1018 struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
1019 1019 struct tcm_loop_nexus *tl_nexus;
  1020 + int ret = -ENOMEM;
1020 1021  
1021 1022 if (tl_tpg->tl_hba->tl_nexus) {
1022 1023 printk(KERN_INFO "tl_tpg->tl_hba->tl_nexus already exists\n");
1023 1024  
... ... @@ -1033,8 +1034,10 @@
1033 1034 * Initialize the struct se_session pointer
1034 1035 */
1035 1036 tl_nexus->se_sess = transport_init_session();
1036   - if (!tl_nexus->se_sess)
  1037 + if (IS_ERR(tl_nexus->se_sess)) {
  1038 + ret = PTR_ERR(tl_nexus->se_sess);
1037 1039 goto out;
  1040 + }
1038 1041 /*
1039 1042 * Since we are running in 'demo mode' this call with generate a
1040 1043 * struct se_node_acl for the tcm_loop struct se_portal_group with the SCSI
... ... @@ -1060,7 +1063,7 @@
1060 1063  
1061 1064 out:
1062 1065 kfree(tl_nexus);
1063   - return -ENOMEM;
  1066 + return ret;
1064 1067 }
1065 1068  
1066 1069 static int tcm_loop_drop_nexus(
... ... @@ -1140,7 +1143,7 @@
1140 1143 * the fabric protocol_id set in tcm_loop_make_scsi_hba(), and call
1141 1144 * tcm_loop_make_nexus()
1142 1145 */
1143   - if (strlen(page) > TL_WWN_ADDR_LEN) {
  1146 + if (strlen(page) >= TL_WWN_ADDR_LEN) {
1144 1147 printk(KERN_ERR "Emulated NAA Sas Address: %s, exceeds"
1145 1148 " max: %d\n", page, TL_WWN_ADDR_LEN);
1146 1149 return -EINVAL;
... ... @@ -1321,7 +1324,7 @@
1321 1324 return ERR_PTR(-EINVAL);
1322 1325  
1323 1326 check_len:
1324   - if (strlen(name) > TL_WWN_ADDR_LEN) {
  1327 + if (strlen(name) >= TL_WWN_ADDR_LEN) {
1325 1328 printk(KERN_ERR "Emulated NAA %s Address: %s, exceeds"
1326 1329 " max: %d\n", name, tcm_loop_dump_proto_id(tl_hba),
1327 1330 TL_WWN_ADDR_LEN);
drivers/target/target_core_configfs.c
... ... @@ -304,7 +304,7 @@
304 304 printk(KERN_ERR "Unable to locate passed fabric name\n");
305 305 return NULL;
306 306 }
307   - if (strlen(name) > TARGET_FABRIC_NAME_SIZE) {
  307 + if (strlen(name) >= TARGET_FABRIC_NAME_SIZE) {
308 308 printk(KERN_ERR "Passed name: %s exceeds TARGET_FABRIC"
309 309 "_NAME_SIZE\n", name);
310 310 return NULL;
... ... @@ -312,7 +312,7 @@
312 312  
313 313 tf = kzalloc(sizeof(struct target_fabric_configfs), GFP_KERNEL);
314 314 if (!(tf))
315   - return ERR_PTR(-ENOMEM);
  315 + return NULL;
316 316  
317 317 INIT_LIST_HEAD(&tf->tf_list);
318 318 atomic_set(&tf->tf_access_cnt, 0);
... ... @@ -851,7 +851,7 @@
851 851 return -EOPNOTSUPP;
852 852 }
853 853  
854   - if ((strlen(page) + 1) > INQUIRY_VPD_SERIAL_LEN) {
  854 + if (strlen(page) >= INQUIRY_VPD_SERIAL_LEN) {
855 855 printk(KERN_ERR "Emulated VPD Unit Serial exceeds"
856 856 " INQUIRY_VPD_SERIAL_LEN: %d\n", INQUIRY_VPD_SERIAL_LEN);
857 857 return -EOVERFLOW;
... ... @@ -917,7 +917,7 @@
917 917  
918 918 transport_dump_vpd_proto_id(vpd, buf, VPD_TMP_BUF_SIZE);
919 919  
920   - if ((len + strlen(buf) > PAGE_SIZE))
  920 + if ((len + strlen(buf) >= PAGE_SIZE))
921 921 break;
922 922  
923 923 len += sprintf(page+len, "%s", buf);
924 924  
925 925  
... ... @@ -962,19 +962,19 @@
962 962 \
963 963 memset(buf, 0, VPD_TMP_BUF_SIZE); \
964 964 transport_dump_vpd_assoc(vpd, buf, VPD_TMP_BUF_SIZE); \
965   - if ((len + strlen(buf) > PAGE_SIZE)) \
  965 + if ((len + strlen(buf) >= PAGE_SIZE)) \
966 966 break; \
967 967 len += sprintf(page+len, "%s", buf); \
968 968 \
969 969 memset(buf, 0, VPD_TMP_BUF_SIZE); \
970 970 transport_dump_vpd_ident_type(vpd, buf, VPD_TMP_BUF_SIZE); \
971   - if ((len + strlen(buf) > PAGE_SIZE)) \
  971 + if ((len + strlen(buf) >= PAGE_SIZE)) \
972 972 break; \
973 973 len += sprintf(page+len, "%s", buf); \
974 974 \
975 975 memset(buf, 0, VPD_TMP_BUF_SIZE); \
976 976 transport_dump_vpd_ident(vpd, buf, VPD_TMP_BUF_SIZE); \
977   - if ((len + strlen(buf) > PAGE_SIZE)) \
  977 + if ((len + strlen(buf) >= PAGE_SIZE)) \
978 978 break; \
979 979 len += sprintf(page+len, "%s", buf); \
980 980 } \
... ... @@ -1299,7 +1299,7 @@
1299 1299 &i_buf[0] : "", pr_reg->pr_res_key,
1300 1300 pr_reg->pr_res_generation);
1301 1301  
1302   - if ((len + strlen(buf) > PAGE_SIZE))
  1302 + if ((len + strlen(buf) >= PAGE_SIZE))
1303 1303 break;
1304 1304  
1305 1305 len += sprintf(page+len, "%s", buf);
... ... @@ -1496,7 +1496,7 @@
1496 1496 ret = -ENOMEM;
1497 1497 goto out;
1498 1498 }
1499   - if (strlen(i_port) > PR_APTPL_MAX_IPORT_LEN) {
  1499 + if (strlen(i_port) >= PR_APTPL_MAX_IPORT_LEN) {
1500 1500 printk(KERN_ERR "APTPL metadata initiator_node="
1501 1501 " exceeds PR_APTPL_MAX_IPORT_LEN: %d\n",
1502 1502 PR_APTPL_MAX_IPORT_LEN);
... ... @@ -1510,7 +1510,7 @@
1510 1510 ret = -ENOMEM;
1511 1511 goto out;
1512 1512 }
1513   - if (strlen(isid) > PR_REG_ISID_LEN) {
  1513 + if (strlen(isid) >= PR_REG_ISID_LEN) {
1514 1514 printk(KERN_ERR "APTPL metadata initiator_isid"
1515 1515 "= exceeds PR_REG_ISID_LEN: %d\n",
1516 1516 PR_REG_ISID_LEN);
... ... @@ -1571,7 +1571,7 @@
1571 1571 ret = -ENOMEM;
1572 1572 goto out;
1573 1573 }
1574   - if (strlen(t_port) > PR_APTPL_MAX_TPORT_LEN) {
  1574 + if (strlen(t_port) >= PR_APTPL_MAX_TPORT_LEN) {
1575 1575 printk(KERN_ERR "APTPL metadata target_node="
1576 1576 " exceeds PR_APTPL_MAX_TPORT_LEN: %d\n",
1577 1577 PR_APTPL_MAX_TPORT_LEN);
... ... @@ -3052,7 +3052,7 @@
3052 3052 int ret;
3053 3053  
3054 3054 memset(buf, 0, TARGET_CORE_NAME_MAX_LEN);
3055   - if (strlen(name) > TARGET_CORE_NAME_MAX_LEN) {
  3055 + if (strlen(name) >= TARGET_CORE_NAME_MAX_LEN) {
3056 3056 printk(KERN_ERR "Passed *name strlen(): %d exceeds"
3057 3057 " TARGET_CORE_NAME_MAX_LEN: %d\n", (int)strlen(name),
3058 3058 TARGET_CORE_NAME_MAX_LEN);
drivers/target/target_core_device.c
... ... @@ -192,7 +192,7 @@
192 192 &SE_NODE_ACL(se_sess)->device_list[unpacked_lun];
193 193 if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) {
194 194 se_lun = se_cmd->se_lun = se_tmr->tmr_lun = deve->se_lun;
195   - dev = se_tmr->tmr_dev = se_lun->lun_se_dev;
  195 + dev = se_lun->lun_se_dev;
196 196 se_cmd->pr_res_key = deve->pr_res_key;
197 197 se_cmd->orig_fe_lun = unpacked_lun;
198 198 se_cmd->se_orig_obj_ptr = SE_LUN(se_cmd)->lun_se_dev;
... ... @@ -216,6 +216,7 @@
216 216 se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
217 217 return -1;
218 218 }
  219 + se_tmr->tmr_dev = dev;
219 220  
220 221 spin_lock(&dev->se_tmr_lock);
221 222 list_add_tail(&se_tmr->tmr_list, &dev->dev_tmr_list);
... ... @@ -1430,7 +1431,7 @@
1430 1431 struct se_lun_acl *lacl;
1431 1432 struct se_node_acl *nacl;
1432 1433  
1433   - if (strlen(initiatorname) > TRANSPORT_IQN_LEN) {
  1434 + if (strlen(initiatorname) >= TRANSPORT_IQN_LEN) {
1434 1435 printk(KERN_ERR "%s InitiatorName exceeds maximum size.\n",
1435 1436 TPG_TFO(tpg)->get_fabric_name());
1436 1437 *ret = -EOVERFLOW;
drivers/target/target_core_pr.c
... ... @@ -1916,7 +1916,7 @@
1916 1916 pr_reg->pr_res_mapped_lun);
1917 1917 }
1918 1918  
1919   - if ((len + strlen(tmp) > pr_aptpl_buf_len)) {
  1919 + if ((len + strlen(tmp) >= pr_aptpl_buf_len)) {
1920 1920 printk(KERN_ERR "Unable to update renaming"
1921 1921 " APTPL metadata\n");
1922 1922 spin_unlock(&T10_RES(su_dev)->registration_lock);
... ... @@ -1934,7 +1934,7 @@
1934 1934 TPG_TFO(tpg)->tpg_get_tag(tpg),
1935 1935 lun->lun_sep->sep_rtpi, lun->unpacked_lun, reg_count);
1936 1936  
1937   - if ((len + strlen(tmp) > pr_aptpl_buf_len)) {
  1937 + if ((len + strlen(tmp) >= pr_aptpl_buf_len)) {
1938 1938 printk(KERN_ERR "Unable to update renaming"
1939 1939 " APTPL metadata\n");
1940 1940 spin_unlock(&T10_RES(su_dev)->registration_lock);
... ... @@ -1986,7 +1986,7 @@
1986 1986 memset(iov, 0, sizeof(struct iovec));
1987 1987 memset(path, 0, 512);
1988 1988  
1989   - if (strlen(&wwn->unit_serial[0]) > 512) {
  1989 + if (strlen(&wwn->unit_serial[0]) >= 512) {
1990 1990 printk(KERN_ERR "WWN value for struct se_device does not fit"
1991 1991 " into path buffer\n");
1992 1992 return -1;
drivers/target/target_core_tmr.c
... ... @@ -75,10 +75,16 @@
75 75 {
76 76 struct se_device *dev = tmr->tmr_dev;
77 77  
  78 + if (!dev) {
  79 + kmem_cache_free(se_tmr_req_cache, tmr);
  80 + return;
  81 + }
  82 +
78 83 spin_lock(&dev->se_tmr_lock);
79 84 list_del(&tmr->tmr_list);
80   - kmem_cache_free(se_tmr_req_cache, tmr);
81 85 spin_unlock(&dev->se_tmr_lock);
  86 +
  87 + kmem_cache_free(se_tmr_req_cache, tmr);
82 88 }
83 89  
84 90 static void core_tmr_handle_tas_abort(
drivers/target/target_core_transport.c
... ... @@ -536,13 +536,13 @@
536 536 void transport_deregister_session_configfs(struct se_session *se_sess)
537 537 {
538 538 struct se_node_acl *se_nacl;
539   -
  539 + unsigned long flags;
540 540 /*
541 541 * Used by struct se_node_acl's under ConfigFS to locate active struct se_session
542 542 */
543 543 se_nacl = se_sess->se_node_acl;
544 544 if ((se_nacl)) {
545   - spin_lock_irq(&se_nacl->nacl_sess_lock);
  545 + spin_lock_irqsave(&se_nacl->nacl_sess_lock, flags);
546 546 list_del(&se_sess->sess_acl_list);
547 547 /*
548 548 * If the session list is empty, then clear the pointer.
... ... @@ -556,7 +556,7 @@
556 556 se_nacl->acl_sess_list.prev,
557 557 struct se_session, sess_acl_list);
558 558 }
559   - spin_unlock_irq(&se_nacl->nacl_sess_lock);
  559 + spin_unlock_irqrestore(&se_nacl->nacl_sess_lock, flags);
560 560 }
561 561 }
562 562 EXPORT_SYMBOL(transport_deregister_session_configfs);
drivers/target/tcm_fc/tcm_fc.h
... ... @@ -144,7 +144,7 @@
144 144 */
145 145 struct ft_cmd {
146 146 enum ft_cmd_state state;
147   - u16 lun; /* LUN from request */
  147 + u32 lun; /* LUN from request */
148 148 struct ft_sess *sess; /* session held for cmd */
149 149 struct fc_seq *seq; /* sequence in exchange mgr */
150 150 struct se_cmd se_cmd; /* Local TCM I/O descriptor */
drivers/target/tcm_fc/tfc_cmd.c
... ... @@ -94,29 +94,6 @@
94 94 16, 4, cmd->cdb, MAX_COMMAND_SIZE, 0);
95 95 }
96 96  
97   -/*
98   - * Get LUN from CDB.
99   - */
100   -static int ft_get_lun_for_cmd(struct ft_cmd *cmd, u8 *lunp)
101   -{
102   - u64 lun;
103   -
104   - lun = lunp[1];
105   - switch (lunp[0] >> 6) {
106   - case 0:
107   - break;
108   - case 1:
109   - lun |= (lunp[0] & 0x3f) << 8;
110   - break;
111   - default:
112   - return -1;
113   - }
114   - if (lun >= TRANSPORT_MAX_LUNS_PER_TPG)
115   - return -1;
116   - cmd->lun = lun;
117   - return transport_get_lun_for_cmd(&cmd->se_cmd, NULL, lun);
118   -}
119   -
120 97 static void ft_queue_cmd(struct ft_sess *sess, struct ft_cmd *cmd)
121 98 {
122 99 struct se_queue_obj *qobj;
... ... @@ -418,6 +395,7 @@
418 395 {
419 396 struct se_tmr_req *tmr;
420 397 struct fcp_cmnd *fcp;
  398 + struct ft_sess *sess;
421 399 u8 tm_func;
422 400  
423 401 fcp = fc_frame_payload_get(cmd->req_frame, sizeof(*fcp));
... ... @@ -425,13 +403,6 @@
425 403 switch (fcp->fc_tm_flags) {
426 404 case FCP_TMF_LUN_RESET:
427 405 tm_func = TMR_LUN_RESET;
428   - if (ft_get_lun_for_cmd(cmd, fcp->fc_lun) < 0) {
429   - ft_dump_cmd(cmd, __func__);
430   - transport_send_check_condition_and_sense(&cmd->se_cmd,
431   - cmd->se_cmd.scsi_sense_reason, 0);
432   - ft_sess_put(cmd->sess);
433   - return;
434   - }
435 406 break;
436 407 case FCP_TMF_TGT_RESET:
437 408 tm_func = TMR_TARGET_WARM_RESET;
... ... @@ -463,6 +434,36 @@
463 434 return;
464 435 }
465 436 cmd->se_cmd.se_tmr_req = tmr;
  437 +
  438 + switch (fcp->fc_tm_flags) {
  439 + case FCP_TMF_LUN_RESET:
  440 + cmd->lun = scsilun_to_int((struct scsi_lun *)fcp->fc_lun);
  441 + if (transport_get_lun_for_tmr(&cmd->se_cmd, cmd->lun) < 0) {
  442 + /*
  443 + * Make sure to clean up newly allocated TMR request
  444 + * since "unable to handle TMR request because failed
  445 + * to get to LUN"
  446 + */
  447 + FT_TM_DBG("Failed to get LUN for TMR func %d, "
  448 + "se_cmd %p, unpacked_lun %d\n",
  449 + tm_func, &cmd->se_cmd, cmd->lun);
  450 + ft_dump_cmd(cmd, __func__);
  451 + sess = cmd->sess;
  452 + transport_send_check_condition_and_sense(&cmd->se_cmd,
  453 + cmd->se_cmd.scsi_sense_reason, 0);
  454 + transport_generic_free_cmd(&cmd->se_cmd, 0, 1, 0);
  455 + ft_sess_put(sess);
  456 + return;
  457 + }
  458 + break;
  459 + case FCP_TMF_TGT_RESET:
  460 + case FCP_TMF_CLR_TASK_SET:
  461 + case FCP_TMF_ABT_TASK_SET:
  462 + case FCP_TMF_CLR_ACA:
  463 + break;
  464 + default:
  465 + return;
  466 + }
466 467 transport_generic_handle_tmr(&cmd->se_cmd);
467 468 }
468 469  
... ... @@ -635,7 +636,8 @@
635 636  
636 637 fc_seq_exch(cmd->seq)->lp->tt.seq_set_resp(cmd->seq, ft_recv_seq, cmd);
637 638  
638   - ret = ft_get_lun_for_cmd(cmd, fcp->fc_lun);
  639 + cmd->lun = scsilun_to_int((struct scsi_lun *)fcp->fc_lun);
  640 + ret = transport_get_lun_for_cmd(&cmd->se_cmd, NULL, cmd->lun);
639 641 if (ret < 0) {
640 642 ft_dump_cmd(cmd, __func__);
641 643 transport_send_check_condition_and_sense(&cmd->se_cmd,
drivers/target/tcm_fc/tfc_io.c
... ... @@ -203,7 +203,7 @@
203 203 /* XXX For now, initiator will retry */
204 204 if (printk_ratelimit())
205 205 printk(KERN_ERR "%s: Failed to send frame %p, "
206   - "xid <0x%x>, remaining <0x%x>, "
  206 + "xid <0x%x>, remaining %zu, "
207 207 "lso_max <0x%x>\n",
208 208 __func__, fp, ep->xid,
209 209 remaining, lport->lso_max);
drivers/target/tcm_fc/tfc_sess.c
... ... @@ -229,7 +229,7 @@
229 229 return NULL;
230 230  
231 231 sess->se_sess = transport_init_session();
232   - if (!sess->se_sess) {
  232 + if (IS_ERR(sess->se_sess)) {
233 233 kfree(sess);
234 234 return NULL;
235 235 }
... ... @@ -332,7 +332,7 @@
332 332 lport = sess->tport->lport;
333 333 port_id = sess->port_id;
334 334 if (port_id == -1) {
335   - mutex_lock(&ft_lport_lock);
  335 + mutex_unlock(&ft_lport_lock);
336 336 return;
337 337 }
338 338 FT_SESS_DBG("port_id %x\n", port_id);