[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