mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
SCSI fixes on 20171007
A couple of serious fixes (use after free and blacklist for WRITE SAME). One error leg fix (write_pending failure) and one user experience problem (do not override max_sectors_kb) and one minor unused function removal. Signed-off-by: James E.J. Bottomley <jejb@linux.vnet.ibm.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABAgAGBQJZ2P68AAoJEAVr7HOZEZN48hEP/0d7RH77AjV1smqQHJpel7b8 WFh7zWHfhyHEmDMf1xtepqw1RAsrkXfRy12wOOc3ppnaozBIh1GIvjHRWXtaEIaA qsTJkROWro3XskxfKL8n0CqeATuk6EjfE+ehRFyXQ9F9yhIB4FxaYROzGUfM9rON ScD2vHH0sE4PIUiavizjxSk6G4KNvGyqM/xtgUIymH7Dcd7MorOq1WBvGXp7etkG QSCV1tvB63yg2jcqatANTLO0LuI9N023VGA/QrTLzpu6M54QZwMGAmVwZfkQ1/nO RLGWTj6jrB4RSF690NN1QLRnf58GYEyIEa37Dlwp/bLyHv4Y9NxO3KB/M0MIf/x2 PJ5FmUw7IwPVzAk6WmGoUIvscDnrDplzVL0fMZKlnW3+8mQav+IIev7sBvPjMkMw HA7PLNXrEpR1tOBhr9je2V2Jz9KxARZFRUqm238Rq03W6kjYQQbSG+dC06A7o2DQ UYuXCWp+CZhbBSG29qPf8wzNbdndpkmXatwLrwVmmRn+/eo3BGF5/SfOKu0M8PTu M4apqkZTZdMAzPckIe0lg6RIJ+F5lWPPX454CZqivM8MFNyjHbf2VJAvQbU9dNhM dfrPsLogZNgCop13H06xAFS6m3dIP5YqUEo/yWXciC6hnvCP7z6ZkiqHTHJIIJMm vwQJLkkB2Ex4NscJcZfw =X/MK -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
85b1bb2480
@ -3767,7 +3767,7 @@ static int ibmvscsis_write_pending(struct se_cmd *se_cmd)
|
||||
*/
|
||||
if ((vscsi->flags & (CLIENT_FAILED | RESPONSE_Q_DOWN))) {
|
||||
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,
|
||||
|
@ -2851,9 +2851,6 @@ EXPORT_SYMBOL_GPL(iscsi_session_setup);
|
||||
/**
|
||||
* iscsi_session_teardown - destroy session, host, and cls_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)
|
||||
{
|
||||
@ -2863,6 +2860,8 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session)
|
||||
|
||||
iscsi_pool_free(&session->cmdpool);
|
||||
|
||||
iscsi_remove_session(cls_session);
|
||||
|
||||
kfree(session->password);
|
||||
kfree(session->password_in);
|
||||
kfree(session->username);
|
||||
@ -2877,7 +2876,8 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session)
|
||||
kfree(session->portal_type);
|
||||
kfree(session->discovery_parent_type);
|
||||
|
||||
iscsi_destroy_session(cls_session);
|
||||
iscsi_free_session(cls_session);
|
||||
|
||||
iscsi_host_dec_session_cnt(shost);
|
||||
module_put(owner);
|
||||
}
|
||||
|
@ -956,6 +956,9 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
|
||||
if (*bflags & BLIST_NO_DIF)
|
||||
sdev->no_dif = 1;
|
||||
|
||||
if (*bflags & BLIST_UNMAP_LIMIT_WS)
|
||||
sdev->unmap_limit_for_ws = 1;
|
||||
|
||||
sdev->eh_timeout = SCSI_DEFAULT_EH_TIMEOUT;
|
||||
|
||||
if (*bflags & BLIST_TRY_VPD_PAGES)
|
||||
|
@ -2210,22 +2210,6 @@ void iscsi_free_session(struct iscsi_cls_session *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
|
||||
* @session: iscsi cls session
|
||||
|
@ -715,13 +715,21 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
|
||||
break;
|
||||
|
||||
case SD_LBP_WS16:
|
||||
max_blocks = min_not_zero(sdkp->max_ws_blocks,
|
||||
(u32)SD_MAX_WS16_BLOCKS);
|
||||
if (sdkp->device->unmap_limit_for_ws)
|
||||
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;
|
||||
|
||||
case SD_LBP_WS10:
|
||||
max_blocks = min_not_zero(sdkp->max_ws_blocks,
|
||||
(u32)SD_MAX_WS10_BLOCKS);
|
||||
if (sdkp->device->unmap_limit_for_ws)
|
||||
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;
|
||||
|
||||
case SD_LBP_ZERO:
|
||||
@ -3099,8 +3107,6 @@ static int sd_revalidate_disk(struct gendisk *disk)
|
||||
sd_read_security(sdkp, buffer);
|
||||
}
|
||||
|
||||
sdkp->first_scan = 0;
|
||||
|
||||
/*
|
||||
* We now have all cache related info, determine how we deal
|
||||
* with flush requests.
|
||||
@ -3115,7 +3121,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
|
||||
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
|
||||
* garbage.
|
||||
*/
|
||||
@ -3129,8 +3135,19 @@ static int sd_revalidate_disk(struct gendisk *disk)
|
||||
rw_max = min_not_zero(logical_to_sectors(sdp, dev_max),
|
||||
(sector_t)BLK_DEF_MAX_SECTORS);
|
||||
|
||||
/* Combine with controller limits */
|
||||
q->limits.max_sectors = min(rw_max, queue_max_hw_sectors(q));
|
||||
/* Do not exceed controller limit */
|
||||
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));
|
||||
sd_config_write_same(sdkp);
|
||||
|
@ -192,6 +192,7 @@ struct scsi_device {
|
||||
unsigned no_dif:1; /* T10 PI (DIF) should be disabled */
|
||||
unsigned broken_fua:1; /* Don't set FUA bit */
|
||||
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 */
|
||||
|
||||
|
@ -29,5 +29,6 @@
|
||||
#define BLIST_TRY_VPD_PAGES 0x10000000 /* Attempt to read VPD pages */
|
||||
#define BLIST_NO_RSOC 0x20000000 /* don't try to issue RSOC */
|
||||
#define BLIST_MAX_1024 0x40000000 /* maximum 1024 sector cdb length */
|
||||
#define BLIST_UNMAP_LIMIT_WS 0x80000000 /* Use UNMAP limit for WRITE SAME */
|
||||
|
||||
#endif
|
||||
|
@ -434,7 +434,6 @@ extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost,
|
||||
unsigned int target_id);
|
||||
extern void iscsi_remove_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,
|
||||
int dd_size, uint32_t cid);
|
||||
extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn);
|
||||
|
Loading…
Reference in New Issue
Block a user