[stgt] [PATCH] discard support

FUJITA Tomonori fujita.tomonori at lab.ntt.co.jp
Fri Jul 9 09:32:12 CEST 2010


This is a really hacky patch to add discard support.

I don't plan to merge this. Let me know if someone is interested in
it. I'll think about how to support discard cleanly.

I'll give you an example how useful this is.

On the target box, I have one 2GB file on xfs. It's exported to an
initiator:

clover:/home/fujita# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/cciss/c0d0p1     130G  7.2G  116G   6% /
tmpfs                 4.0G     0  4.0G   0% /lib/init/rw
udev                   10M   96K   10M   1% /dev
tmpfs                 4.0G     0  4.0G   0% /dev/shm
/dev/cciss/c0d1p1     137G  2.1G  135G   2% /mnt/xfs

clover:/home/fujita# ls -lh /mnt/xfs/sbc1
-rw-r--r-- 1 root root 2.0G 2010-07-09 16:17 /mnt/xfs/sbc1

clover:/home/fujita# ./tgt/usr/tgtadm --op show --mode target
Target 1: iqn.2001-04.com.example:storage.sr.rose.sys1.xyz
    System information:
        Driver: iscsi
        State: ready
    I_T nexus information:
        I_T nexus: 1
            Initiator: iqn.2005-03.org.open-iscsi:7e4eaf7a28q
            Connection: 0
                IP Address: 10.76.0.32
    LUN information:
        LUN: 0
            Type: controller
            SCSI ID: IET     00010000
            SCSI SN: beaf10
            Size: 0 MB
            Online: Yes
            Removable media: No
            Backing store type: null
            Backing store path: None
            Backing store flags: 
        LUN: 1
            Type: disk
            SCSI ID: IET     00010001
            SCSI SN: beaf11
            Size: 2147 MB
            Online: Yes
            Removable media: No
            Backing store type: rdwr
            Backing store path: /mnt/xfs/sbc1
            Backing store flags: 
    Account information:
    ACL information:
        ALL


On the initiator box, I run mkfs.xfs

Then, on the target box:

clover:/home/fujita# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/cciss/c0d0p1     130G  7.2G  116G   6% /
tmpfs                 4.0G     0  4.0G   0% /lib/init/rw
udev                   10M   96K   10M   1% /dev
tmpfs                 4.0G     0  4.0G   0% /dev/shm
/dev/cciss/c0d1p1     137G   43M  137G   1% /mnt/xfs

Surprisingly, now I only use 43MB.

clover:/home/fujita# ls -lh /mnt/xfs/sbc1
-rw-r--r-- 1 root root 2.0G 2010-07-09 16:17 /mnt/xfs/sbc1

But I still have the 2GB file. The trick is that the majority data of
file was discarded.


=
diff --git a/usr/sbc.c b/usr/sbc.c
index a048d53..a94f803 100644
--- a/usr/sbc.c
+++ b/usr/sbc.c
@@ -161,23 +161,27 @@ static int sbc_service_action(int host_no, struct scsi_cmd *cmd)
 {
 	uint32_t *data;
 	uint64_t size;
+	uint8_t *p;
 
 	if (cmd->scb[1] != SAI_READ_CAPACITY_16)
 		goto sense;
 
-	if (scsi_get_in_length(cmd) < 12)
+	if (scsi_get_in_length(cmd) < 32)
 		goto overflow;
 
 	data = scsi_get_in_buffer(cmd);
-	memset(data, 0, 12);
+	memset(data, 0, 32);
 
 	size = cmd->dev->size >> BLK_SHIFT;
 
 	*((uint64_t *)(data)) = __cpu_to_be64(size - 1);
 	data[2] = __cpu_to_be32(1UL << BLK_SHIFT);
 
+	p = (void *)data;
+	p[14] |= 0x80;
+
 overflow:
-	scsi_set_in_resid_by_actual(cmd, 12);
+	scsi_set_in_resid_by_actual(cmd, 32);
 	return SAM_STAT_GOOD;
 sense:
 	sense_data_build(cmd, ILLEGAL_REQUEST, ASC_INVALID_OP_CODE);
@@ -219,10 +223,49 @@ sense:
 	return SAM_STAT_CHECK_CONDITION;
 }
 
+#include <xfs/xfs.h>
+
+static int sbc_write_same_16(int host_no, struct scsi_cmd *cmd)
+{
+	struct xfs_flock64 fl;
+	int ret;
+
+	memset(&fl, 0, sizeof(fl));
+	fl.l_whence = SEEK_SET;
+	fl.l_start = scsi_rw_offset(cmd->scb) << BLK_SHIFT;
+	fl.l_len = scsi_rw_count(cmd->scb) << BLK_SHIFT;
+
+	ret = xfsctl(NULL, cmd->dev->fd, XFS_IOC_UNRESVSP64, &fl);
+
+	eprintf("%llu %lld %d\n", fl.l_start, fl.l_len, ret);
+
+	scsi_set_in_resid_by_actual(cmd, 0);
+	return SAM_STAT_GOOD;
+}
+
+static unsigned char vpdb0_data[] = {
+	/* from 4th byte */ 0,0,0,4, 0,0,0x4,0, 0,0,0,64,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+};
+
+static void update_vpd_b0(struct scsi_lu *lu, void *sn)
+{
+	struct vpd *vpd_pg = lu->attrs.lu_vpd[PCODE_OFFSET(0xb0)];
+	char *data = (char *)vpd_pg->data;
+	uint32_t g = 1;
+
+	memcpy(data, vpdb0_data, sizeof(vpdb0_data));
+	put_unaligned_be32(g, data + 24);
+}
+
 static int sbc_lu_init(struct scsi_lu *lu)
 {
+	struct vpd **lu_vpd = lu->attrs.lu_vpd;
 	uint64_t size;
 	uint8_t *data;
+	int pg;
 
 	if (spc_lu_init(lu))
 		return TGTADM_NOMEM;
@@ -259,6 +302,12 @@ static int sbc_lu_init(struct scsi_lu *lu)
 	/* Informational Exceptions Control page */
 	add_mode_page(lu, "0x1c:0:10:8:0:0:0:0:0:0:0:0:0");
 
+	/* VPD page 0xb0 */
+	pg = PCODE_OFFSET(0xb0);
+	lu_vpd[pg] = alloc_vpd(0x3c);
+	lu_vpd[pg]->vpd_update = update_vpd_b0;
+	lu_vpd[pg]->vpd_update(lu, NULL);
+
 	return 0;
 }
 
@@ -391,7 +440,7 @@ static struct device_type_template sbc_template = {
 		{spc_illegal_op,},
 		{sbc_sync_cache, NULL, PR_WE_FA|PR_EA_FA|PR_WE_FN|PR_EA_FN},
 		{spc_illegal_op,},
-		{spc_illegal_op,},
+		{sbc_write_same_16,},
 		{spc_illegal_op,},
 		{spc_illegal_op,},
 		{spc_illegal_op,},
diff --git a/usr/scsi.c b/usr/scsi.c
index cef231b..62819e2 100644
--- a/usr/scsi.c
+++ b/usr/scsi.c
@@ -123,6 +123,7 @@ uint64_t scsi_rw_offset(uint8_t *scb)
 	case WRITE_12:
 	case VERIFY_12:
 	case WRITE_VERIFY_12:
+	case WRITE_SAME_16:
 		off = (uint32_t)scb[2] << 24 | (uint32_t)scb[3] << 16 |
 			(uint32_t)scb[4] << 8 | (uint32_t)scb[5];
 		break;
@@ -172,6 +173,7 @@ uint32_t scsi_rw_count(uint8_t *scb)
 	case VERIFY_16:
 	case WRITE_VERIFY_16:
 	case SYNCHRONIZE_CACHE_16:
+	case WRITE_SAME_16:
 		cnt = (uint32_t)scb[10] << 24 | (uint32_t)scb[11] << 16 |
 			(uint32_t)scb[12] << 8 | (uint32_t)scb[13];
 		break;
diff --git a/usr/scsi.h b/usr/scsi.h
index f4d8c11..117888d 100644
--- a/usr/scsi.h
+++ b/usr/scsi.h
@@ -75,6 +75,7 @@
 #define WRITE_VERIFY_16       0x8e
 #define VERIFY_16	      0x8f
 #define SYNCHRONIZE_CACHE_16  0x91
+#define WRITE_SAME_16         0x93
 #define SERVICE_ACTION_IN     0x9e
 #define	SAI_READ_CAPACITY_16  0x10
 #define REPORT_LUNS           0xa0
--
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