[stgt] [PATCH 2/5] SBC: Initial WRITE_SAME support
Ronnie Sahlberg
ronniesahlberg at gmail.com
Sun Apr 22 09:24:26 CEST 2012
Initial support for WRITE_SAME command. Basic support but not yet support
for unmapping of blocks.
WRITE_SAME support only implemented for the bs_rdwr.c backend
and errors will be returned for the bs_aio.c backend.
At a later stage we can add WRITE_SAME support for bs_aio.c too.
Signed-off-by: Ronnie Sahlberg <ronniesahlberg at gmail.com>
---
usr/bs_aio.c | 4 ++++
usr/bs_rdwr.c | 24 ++++++++++++++++++++++++
usr/sbc.c | 17 ++++++++++++++++-
usr/scsi.c | 2 ++
4 files changed, 46 insertions(+), 1 deletions(-)
diff --git a/usr/bs_aio.c b/usr/bs_aio.c
index 75ae66f..d69c6a1 100644
--- a/usr/bs_aio.c
+++ b/usr/bs_aio.c
@@ -206,6 +206,10 @@ static int bs_aio_cmd_submit(struct scsi_cmd *cmd)
case READ_16:
break;
+ case WRITE_SAME:
+ eprintf("WRITE_SAME not yet supported for AIO backend.\n");
+ return -1;
+
case SYNCHRONIZE_CACHE:
case SYNCHRONIZE_CACHE_16:
default:
diff --git a/usr/bs_rdwr.c b/usr/bs_rdwr.c
index 31f4441..5110a90 100644
--- a/usr/bs_rdwr.c
+++ b/usr/bs_rdwr.c
@@ -65,6 +65,7 @@ static void bs_rdwr_request(struct scsi_cmd *cmd)
uint8_t key;
uint16_t asc;
char *tmpbuf;
+ size_t blocksize;
uint64_t offset = cmd->offset;
uint32_t tl = cmd->tl;
@@ -111,6 +112,29 @@ static void bs_rdwr_request(struct scsi_cmd *cmd)
POSIX_FADV_NOREUSE);
break;
+ case WRITE_SAME:
+ while (tl > 0) {
+ blocksize = 1 << cmd->dev->blk_shift;
+ tmpbuf = scsi_get_out_buffer(cmd);
+
+ switch(cmd->scb[1] & 0x06) {
+ case 0x02: /* PBDATA==0 LBDATA==1 */
+ put_unaligned_be32(offset, tmpbuf);
+ break;
+ case 0x04: /* PBDATA==1 LBDATA==0 */
+ /* physical sector format */
+ put_unaligned_be64(offset, tmpbuf);
+ break;
+ }
+
+ ret = pwrite64(fd, tmpbuf, blocksize, offset);
+ if (ret != blocksize)
+ set_medium_error(&result, &key, &asc);
+
+ offset += blocksize;
+ tl -= blocksize;
+ }
+ break;
case READ_6:
case READ_10:
case READ_12:
diff --git a/usr/sbc.c b/usr/sbc.c
index 55145cf..cf72e65 100644
--- a/usr/sbc.c
+++ b/usr/sbc.c
@@ -228,6 +228,20 @@ static int sbc_rw(int host_no, struct scsi_cmd *cmd)
goto sense;
}
break;
+ case WRITE_SAME:
+ /* We only support protection information type 0 */
+ if (cmd->scb[1] & 0xe0) {
+ key = ILLEGAL_REQUEST;
+ asc = ASC_INVALID_FIELD_IN_CDB;
+ goto sense;
+ }
+ /* LBDATA and PBDATA can not both be set */
+ if ((cmd->scb[1] & 0x06) == 0x06) {
+ key = ILLEGAL_REQUEST;
+ asc = ASC_INVALID_FIELD_IN_CDB;
+ goto sense;
+ }
+ break;
}
if (lu->attrs.readonly) {
@@ -236,6 +250,7 @@ static int sbc_rw(int host_no, struct scsi_cmd *cmd)
case WRITE_10:
case WRITE_12:
case WRITE_16:
+ case WRITE_SAME:
case PRE_FETCH_10:
case PRE_FETCH_16:
key = DATA_PROTECT;
@@ -607,7 +622,7 @@ static struct device_type_template sbc_template = {
/* 0x40 */
{spc_illegal_op,},
- {spc_illegal_op,},
+ {sbc_rw,}, /* WRITE_SAME10 */
{sbc_unmap,},
{spc_illegal_op,},
{spc_illegal_op,},
diff --git a/usr/scsi.c b/usr/scsi.c
index 7802ba1..c46753e 100644
--- a/usr/scsi.c
+++ b/usr/scsi.c
@@ -119,6 +119,7 @@ uint64_t scsi_rw_offset(uint8_t *scb)
case WRITE_10:
case VERIFY_10:
case WRITE_VERIFY:
+ case WRITE_SAME:
case SYNCHRONIZE_CACHE:
case READ_12:
case WRITE_12:
@@ -162,6 +163,7 @@ uint32_t scsi_rw_count(uint8_t *scb)
case WRITE_10:
case VERIFY_10:
case WRITE_VERIFY:
+ case WRITE_SAME:
case SYNCHRONIZE_CACHE:
cnt = (uint16_t)scb[7] << 8 | (uint16_t)scb[8];
break;
--
1.7.3.1
--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
More information about the stgt
mailing list