[PATCH 4/5] SBC: Support unmapping blocks using WRITE_SAME/WRITE_SAME16

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


Add support for WRITE_SAME and WRITE_SAME16 to unmap blocks if the
UNMAP bit is set, and the LUN is set for thin-provisioning.

Log error if the ANCHOR bit is set since we not not yet support
resource-provisioned luns.

Update VPD page 0xb2 to indicate that both write same 10 and write same 16
can be used for unmapping blocks

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@xxxxxxxxx>
---
 usr/bs_rdwr.c |   13 +++++++++++++
 usr/sbc.c     |   14 ++++++++++++++
 usr/spc.c     |    2 +-
 3 files changed, 28 insertions(+), 1 deletions(-)

diff --git a/usr/bs_rdwr.c b/usr/bs_rdwr.c
index cd4518b..7d05359 100644
--- a/usr/bs_rdwr.c
+++ b/usr/bs_rdwr.c
@@ -114,6 +114,19 @@ static void bs_rdwr_request(struct scsi_cmd *cmd)
 		break;
 	case WRITE_SAME:
 	case WRITE_SAME_16:
+		/* WRITE_SAME used to punch hole in file */
+		if (cmd->scb[1] & 0x08) {
+			ret = unmap_file_region(fd, offset, tl);
+			if (ret != 0) {
+				eprintf("Failed to punch hole for WRITE_SAME"
+					" command\n");
+				result = SAM_STAT_CHECK_CONDITION;
+				key = HARDWARE_ERROR;
+				asc = ASC_INTERNAL_TGT_FAILURE;
+				break;
+			}
+			break;
+		}
 		while (tl > 0) {
 			blocksize = 1 << cmd->dev->blk_shift;
 			tmpbuf = scsi_get_out_buffer(cmd);
diff --git a/usr/sbc.c b/usr/sbc.c
index de0a13b..2cfcd11 100644
--- a/usr/sbc.c
+++ b/usr/sbc.c
@@ -230,6 +230,20 @@ static int sbc_rw(int host_no, struct scsi_cmd *cmd)
 		break;
 	case WRITE_SAME:
 	case WRITE_SAME_16:
+		/* We dont support resource-provisioning so
+		 * ANCHOR bit == 1 is an error.
+		 */
+		if (cmd->scb[1] & 0x10) {
+			key = ILLEGAL_REQUEST;
+			asc = ASC_INVALID_FIELD_IN_CDB;
+			goto sense;
+		}
+		/* We only support unmap for thin provisioned LUNS */
+		if (cmd->scb[1] & 0x08 && !lu->attrs.thinprovisioning) {
+			key = ILLEGAL_REQUEST;
+			asc = ASC_INVALID_FIELD_IN_CDB;
+			goto sense;
+		}
 		/* We only support protection information type 0 */
 		if (cmd->scb[1] & 0xe0) {
 			key = ILLEGAL_REQUEST;
diff --git a/usr/spc.c b/usr/spc.c
index b0a305f..eb435ae 100644
--- a/usr/spc.c
+++ b/usr/spc.c
@@ -146,7 +146,7 @@ static void update_vpd_b2(struct scsi_lu *lu, void *id)
 
 	if (lu->attrs.thinprovisioning) {
 		data[0] = 0;		/* threshold exponent */
-		data[1] = 0x84;		/* LBPU LBPRZ */
+		data[1] = 0xe4;		/* LBPU LBPWS(10) LBPRZ */
 		data[2] = 0x02;		/* provisioning type */
 		data[3] = 0;
 	} else {
-- 
1.7.3.1

--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Linux SCSI]     [Linux RAID]     [Linux Clusters]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]    [Yosemite Photos]    [Free Online Dating]     [Linux Kernel]     [XFree86]     [Video Devices]

Add to Google Powered by Linux