Skip to content

Commit 85b1bb2

Browse files
committed
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
2 parents 67936a4 + 88e6538 commit 85b1bb2

File tree

8 files changed

+36
-31
lines changed

8 files changed

+36
-31
lines changed

drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3767,7 +3767,7 @@ static int ibmvscsis_write_pending(struct se_cmd *se_cmd)
37673767
*/
37683768
if ((vscsi->flags & (CLIENT_FAILED | RESPONSE_Q_DOWN))) {
37693769
pr_err("write_pending failed since: %d\n", vscsi->flags);
3770-
return 0;
3770+
return -EIO;
37713771
}
37723772

37733773
rc = srp_transfer_data(cmd, &vio_iu(iue)->srp.cmd, ibmvscsis_rdma,

drivers/scsi/libiscsi.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2851,9 +2851,6 @@ EXPORT_SYMBOL_GPL(iscsi_session_setup);
28512851
/**
28522852
* iscsi_session_teardown - destroy session, host, and cls_session
28532853
* @cls_session: iscsi session
2854-
*
2855-
* The driver must have called iscsi_remove_session before
2856-
* calling this.
28572854
*/
28582855
void iscsi_session_teardown(struct iscsi_cls_session *cls_session)
28592856
{
@@ -2863,6 +2860,8 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session)
28632860

28642861
iscsi_pool_free(&session->cmdpool);
28652862

2863+
iscsi_remove_session(cls_session);
2864+
28662865
kfree(session->password);
28672866
kfree(session->password_in);
28682867
kfree(session->username);
@@ -2877,7 +2876,8 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session)
28772876
kfree(session->portal_type);
28782877
kfree(session->discovery_parent_type);
28792878

2880-
iscsi_destroy_session(cls_session);
2879+
iscsi_free_session(cls_session);
2880+
28812881
iscsi_host_dec_session_cnt(shost);
28822882
module_put(owner);
28832883
}

drivers/scsi/scsi_scan.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,9 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
956956
if (*bflags & BLIST_NO_DIF)
957957
sdev->no_dif = 1;
958958

959+
if (*bflags & BLIST_UNMAP_LIMIT_WS)
960+
sdev->unmap_limit_for_ws = 1;
961+
959962
sdev->eh_timeout = SCSI_DEFAULT_EH_TIMEOUT;
960963

961964
if (*bflags & BLIST_TRY_VPD_PAGES)

drivers/scsi/scsi_transport_iscsi.c

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2210,22 +2210,6 @@ void iscsi_free_session(struct iscsi_cls_session *session)
22102210
}
22112211
EXPORT_SYMBOL_GPL(iscsi_free_session);
22122212

2213-
/**
2214-
* iscsi_destroy_session - destroy iscsi session
2215-
* @session: iscsi_session
2216-
*
2217-
* Can be called by a LLD or iscsi_transport. There must not be
2218-
* any running connections.
2219-
*/
2220-
int iscsi_destroy_session(struct iscsi_cls_session *session)
2221-
{
2222-
iscsi_remove_session(session);
2223-
ISCSI_DBG_TRANS_SESSION(session, "Completing session destruction\n");
2224-
iscsi_free_session(session);
2225-
return 0;
2226-
}
2227-
EXPORT_SYMBOL_GPL(iscsi_destroy_session);
2228-
22292213
/**
22302214
* iscsi_create_conn - create iscsi class connection
22312215
* @session: iscsi cls session

drivers/scsi/sd.c

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -715,13 +715,21 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
715715
break;
716716

717717
case SD_LBP_WS16:
718-
max_blocks = min_not_zero(sdkp->max_ws_blocks,
719-
(u32)SD_MAX_WS16_BLOCKS);
718+
if (sdkp->device->unmap_limit_for_ws)
719+
max_blocks = sdkp->max_unmap_blocks;
720+
else
721+
max_blocks = sdkp->max_ws_blocks;
722+
723+
max_blocks = min_not_zero(max_blocks, (u32)SD_MAX_WS16_BLOCKS);
720724
break;
721725

722726
case SD_LBP_WS10:
723-
max_blocks = min_not_zero(sdkp->max_ws_blocks,
724-
(u32)SD_MAX_WS10_BLOCKS);
727+
if (sdkp->device->unmap_limit_for_ws)
728+
max_blocks = sdkp->max_unmap_blocks;
729+
else
730+
max_blocks = sdkp->max_ws_blocks;
731+
732+
max_blocks = min_not_zero(max_blocks, (u32)SD_MAX_WS10_BLOCKS);
725733
break;
726734

727735
case SD_LBP_ZERO:
@@ -3099,8 +3107,6 @@ static int sd_revalidate_disk(struct gendisk *disk)
30993107
sd_read_security(sdkp, buffer);
31003108
}
31013109

3102-
sdkp->first_scan = 0;
3103-
31043110
/*
31053111
* We now have all cache related info, determine how we deal
31063112
* with flush requests.
@@ -3115,7 +3121,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
31153121
q->limits.max_dev_sectors = logical_to_sectors(sdp, dev_max);
31163122

31173123
/*
3118-
* Use the device's preferred I/O size for reads and writes
3124+
* Determine the device's preferred I/O size for reads and writes
31193125
* unless the reported value is unreasonably small, large, or
31203126
* garbage.
31213127
*/
@@ -3129,8 +3135,19 @@ static int sd_revalidate_disk(struct gendisk *disk)
31293135
rw_max = min_not_zero(logical_to_sectors(sdp, dev_max),
31303136
(sector_t)BLK_DEF_MAX_SECTORS);
31313137

3132-
/* Combine with controller limits */
3133-
q->limits.max_sectors = min(rw_max, queue_max_hw_sectors(q));
3138+
/* Do not exceed controller limit */
3139+
rw_max = min(rw_max, queue_max_hw_sectors(q));
3140+
3141+
/*
3142+
* Only update max_sectors if previously unset or if the current value
3143+
* exceeds the capabilities of the hardware.
3144+
*/
3145+
if (sdkp->first_scan ||
3146+
q->limits.max_sectors > q->limits.max_dev_sectors ||
3147+
q->limits.max_sectors > q->limits.max_hw_sectors)
3148+
q->limits.max_sectors = rw_max;
3149+
3150+
sdkp->first_scan = 0;
31343151

31353152
set_capacity(disk, logical_to_sectors(sdp, sdkp->capacity));
31363153
sd_config_write_same(sdkp);

include/scsi/scsi_device.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ struct scsi_device {
192192
unsigned no_dif:1; /* T10 PI (DIF) should be disabled */
193193
unsigned broken_fua:1; /* Don't set FUA bit */
194194
unsigned lun_in_cdb:1; /* Store LUN bits in CDB[1] */
195+
unsigned unmap_limit_for_ws:1; /* Use the UNMAP limit for WRITE SAME */
195196

196197
atomic_t disk_events_disable_depth; /* disable depth for disk events */
197198

include/scsi/scsi_devinfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@
2929
#define BLIST_TRY_VPD_PAGES 0x10000000 /* Attempt to read VPD pages */
3030
#define BLIST_NO_RSOC 0x20000000 /* don't try to issue RSOC */
3131
#define BLIST_MAX_1024 0x40000000 /* maximum 1024 sector cdb length */
32+
#define BLIST_UNMAP_LIMIT_WS 0x80000000 /* Use UNMAP limit for WRITE SAME */
3233

3334
#endif

include/scsi/scsi_transport_iscsi.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,6 @@ extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost,
434434
unsigned int target_id);
435435
extern void iscsi_remove_session(struct iscsi_cls_session *session);
436436
extern void iscsi_free_session(struct iscsi_cls_session *session);
437-
extern int iscsi_destroy_session(struct iscsi_cls_session *session);
438437
extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess,
439438
int dd_size, uint32_t cid);
440439
extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn);

0 commit comments

Comments
 (0)