Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 85b1bb24 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -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,
+4 −4
Original line number Original line Diff line number Diff line
@@ -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)


	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)
	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);
}
}
+3 −0
Original line number Original line Diff line number Diff line
@@ -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)
+0 −16
Original line number Original line Diff line number Diff line
@@ -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
+26 −9
Original line number Original line Diff line number Diff line
@@ -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)
		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)
	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)
		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);
Loading