Commit 85b1bb24 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull SCSI fixes from James Bottomley:

 - a couple of serious fixes: use after free and blacklist for WRITE
   SAME

 - one error leg fix: write_pending failure

 - one user experience problem: do not override max_sectors_kb

 - one minor unused function removal

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  scsi: ibmvscsis: Fix write_pending failure path
  scsi: libiscsi: Remove iscsi_destroy_session
  scsi: libiscsi: Fix use-after-free race during iscsi_session_teardown
  scsi: sd: Do not override max_sectors_kb sysfs setting
  scsi: sd: Implement blacklist option for WRITE SAME w/ UNMAP
parents 67936a41 88e65389
...@@ -3767,7 +3767,7 @@ static int ibmvscsis_write_pending(struct se_cmd *se_cmd) ...@@ -3767,7 +3767,7 @@ static int ibmvscsis_write_pending(struct se_cmd *se_cmd)
*/ */
if ((vscsi->flags & (CLIENT_FAILED | RESPONSE_Q_DOWN))) { if ((vscsi->flags & (CLIENT_FAILED | RESPONSE_Q_DOWN))) {
pr_err("write_pending failed since: %d\n", vscsi->flags); pr_err("write_pending failed since: %d\n", vscsi->flags);
return 0; return -EIO;
} }
rc = srp_transfer_data(cmd, &vio_iu(iue)->srp.cmd, ibmvscsis_rdma, rc = srp_transfer_data(cmd, &vio_iu(iue)->srp.cmd, ibmvscsis_rdma,
......
...@@ -2851,9 +2851,6 @@ EXPORT_SYMBOL_GPL(iscsi_session_setup); ...@@ -2851,9 +2851,6 @@ EXPORT_SYMBOL_GPL(iscsi_session_setup);
/** /**
* iscsi_session_teardown - destroy session, host, and cls_session * iscsi_session_teardown - destroy session, host, and cls_session
* @cls_session: iscsi session * @cls_session: iscsi session
*
* The driver must have called iscsi_remove_session before
* calling this.
*/ */
void iscsi_session_teardown(struct iscsi_cls_session *cls_session) void iscsi_session_teardown(struct iscsi_cls_session *cls_session)
{ {
...@@ -2863,6 +2860,8 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) ...@@ -2863,6 +2860,8 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session)
iscsi_pool_free(&session->cmdpool); iscsi_pool_free(&session->cmdpool);
iscsi_remove_session(cls_session);
kfree(session->password); kfree(session->password);
kfree(session->password_in); kfree(session->password_in);
kfree(session->username); kfree(session->username);
...@@ -2877,7 +2876,8 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) ...@@ -2877,7 +2876,8 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session)
kfree(session->portal_type); kfree(session->portal_type);
kfree(session->discovery_parent_type); kfree(session->discovery_parent_type);
iscsi_destroy_session(cls_session); iscsi_free_session(cls_session);
iscsi_host_dec_session_cnt(shost); iscsi_host_dec_session_cnt(shost);
module_put(owner); module_put(owner);
} }
......
...@@ -956,6 +956,9 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, ...@@ -956,6 +956,9 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
if (*bflags & BLIST_NO_DIF) if (*bflags & BLIST_NO_DIF)
sdev->no_dif = 1; sdev->no_dif = 1;
if (*bflags & BLIST_UNMAP_LIMIT_WS)
sdev->unmap_limit_for_ws = 1;
sdev->eh_timeout = SCSI_DEFAULT_EH_TIMEOUT; sdev->eh_timeout = SCSI_DEFAULT_EH_TIMEOUT;
if (*bflags & BLIST_TRY_VPD_PAGES) if (*bflags & BLIST_TRY_VPD_PAGES)
......
...@@ -2210,22 +2210,6 @@ void iscsi_free_session(struct iscsi_cls_session *session) ...@@ -2210,22 +2210,6 @@ void iscsi_free_session(struct iscsi_cls_session *session)
} }
EXPORT_SYMBOL_GPL(iscsi_free_session); EXPORT_SYMBOL_GPL(iscsi_free_session);
/**
* iscsi_destroy_session - destroy iscsi session
* @session: iscsi_session
*
* Can be called by a LLD or iscsi_transport. There must not be
* any running connections.
*/
int iscsi_destroy_session(struct iscsi_cls_session *session)
{
iscsi_remove_session(session);
ISCSI_DBG_TRANS_SESSION(session, "Completing session destruction\n");
iscsi_free_session(session);
return 0;
}
EXPORT_SYMBOL_GPL(iscsi_destroy_session);
/** /**
* iscsi_create_conn - create iscsi class connection * iscsi_create_conn - create iscsi class connection
* @session: iscsi cls session * @session: iscsi cls session
......
...@@ -715,13 +715,21 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) ...@@ -715,13 +715,21 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
break; break;
case SD_LBP_WS16: case SD_LBP_WS16:
max_blocks = min_not_zero(sdkp->max_ws_blocks, if (sdkp->device->unmap_limit_for_ws)
(u32)SD_MAX_WS16_BLOCKS); max_blocks = sdkp->max_unmap_blocks;
else
max_blocks = sdkp->max_ws_blocks;
max_blocks = min_not_zero(max_blocks, (u32)SD_MAX_WS16_BLOCKS);
break; break;
case SD_LBP_WS10: case SD_LBP_WS10:
max_blocks = min_not_zero(sdkp->max_ws_blocks, if (sdkp->device->unmap_limit_for_ws)
(u32)SD_MAX_WS10_BLOCKS); max_blocks = sdkp->max_unmap_blocks;
else
max_blocks = sdkp->max_ws_blocks;
max_blocks = min_not_zero(max_blocks, (u32)SD_MAX_WS10_BLOCKS);
break; break;
case SD_LBP_ZERO: case SD_LBP_ZERO:
...@@ -3099,8 +3107,6 @@ static int sd_revalidate_disk(struct gendisk *disk) ...@@ -3099,8 +3107,6 @@ static int sd_revalidate_disk(struct gendisk *disk)
sd_read_security(sdkp, buffer); sd_read_security(sdkp, buffer);
} }
sdkp->first_scan = 0;
/* /*
* We now have all cache related info, determine how we deal * We now have all cache related info, determine how we deal
* with flush requests. * with flush requests.
...@@ -3115,7 +3121,7 @@ static int sd_revalidate_disk(struct gendisk *disk) ...@@ -3115,7 +3121,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
q->limits.max_dev_sectors = logical_to_sectors(sdp, dev_max); q->limits.max_dev_sectors = logical_to_sectors(sdp, dev_max);
/* /*
* Use the device's preferred I/O size for reads and writes * Determine the device's preferred I/O size for reads and writes
* unless the reported value is unreasonably small, large, or * unless the reported value is unreasonably small, large, or
* garbage. * garbage.
*/ */
...@@ -3129,8 +3135,19 @@ static int sd_revalidate_disk(struct gendisk *disk) ...@@ -3129,8 +3135,19 @@ static int sd_revalidate_disk(struct gendisk *disk)
rw_max = min_not_zero(logical_to_sectors(sdp, dev_max), rw_max = min_not_zero(logical_to_sectors(sdp, dev_max),
(sector_t)BLK_DEF_MAX_SECTORS); (sector_t)BLK_DEF_MAX_SECTORS);
/* Combine with controller limits */ /* Do not exceed controller limit */
q->limits.max_sectors = min(rw_max, queue_max_hw_sectors(q)); rw_max = min(rw_max, queue_max_hw_sectors(q));
/*
* Only update max_sectors if previously unset or if the current value
* exceeds the capabilities of the hardware.
*/
if (sdkp->first_scan ||
q->limits.max_sectors > q->limits.max_dev_sectors ||
q->limits.max_sectors > q->limits.max_hw_sectors)
q->limits.max_sectors = rw_max;
sdkp->first_scan = 0;
set_capacity(disk, logical_to_sectors(sdp, sdkp->capacity)); set_capacity(disk, logical_to_sectors(sdp, sdkp->capacity));
sd_config_write_same(sdkp); sd_config_write_same(sdkp);
......
...@@ -192,6 +192,7 @@ struct scsi_device { ...@@ -192,6 +192,7 @@ struct scsi_device {
unsigned no_dif:1; /* T10 PI (DIF) should be disabled */ unsigned no_dif:1; /* T10 PI (DIF) should be disabled */
unsigned broken_fua:1; /* Don't set FUA bit */ unsigned broken_fua:1; /* Don't set FUA bit */
unsigned lun_in_cdb:1; /* Store LUN bits in CDB[1] */ unsigned lun_in_cdb:1; /* Store LUN bits in CDB[1] */
unsigned unmap_limit_for_ws:1; /* Use the UNMAP limit for WRITE SAME */
atomic_t disk_events_disable_depth; /* disable depth for disk events */ atomic_t disk_events_disable_depth; /* disable depth for disk events */
......
...@@ -29,5 +29,6 @@ ...@@ -29,5 +29,6 @@
#define BLIST_TRY_VPD_PAGES 0x10000000 /* Attempt to read VPD pages */ #define BLIST_TRY_VPD_PAGES 0x10000000 /* Attempt to read VPD pages */
#define BLIST_NO_RSOC 0x20000000 /* don't try to issue RSOC */ #define BLIST_NO_RSOC 0x20000000 /* don't try to issue RSOC */
#define BLIST_MAX_1024 0x40000000 /* maximum 1024 sector cdb length */ #define BLIST_MAX_1024 0x40000000 /* maximum 1024 sector cdb length */
#define BLIST_UNMAP_LIMIT_WS 0x80000000 /* Use UNMAP limit for WRITE SAME */
#endif #endif
...@@ -434,7 +434,6 @@ extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost, ...@@ -434,7 +434,6 @@ extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost,
unsigned int target_id); unsigned int target_id);
extern void iscsi_remove_session(struct iscsi_cls_session *session); extern void iscsi_remove_session(struct iscsi_cls_session *session);
extern void iscsi_free_session(struct iscsi_cls_session *session); extern void iscsi_free_session(struct iscsi_cls_session *session);
extern int iscsi_destroy_session(struct iscsi_cls_session *session);
extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess, extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess,
int dd_size, uint32_t cid); int dd_size, uint32_t cid);
extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn); extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment