Tomo, please use this patch instead. It adds proper check for starting-lba so we return the right sense code if it is out of range. It also adds proper service action handling so that we will report that we support both varients (reacapacity16 and getlbastatus) of opcoe 0x9e That way sg_opcodes show them both properly, like this : sg_opcodes iscsi://10.1.1.125/iqn.ronnie.test/1 IET VIRTUAL-DISK 0001 Peripheral device type: disk Opcode Service CDB Name (hex) action(h) size ----------------------------------------------- 00 6 Test Unit Ready 03 6 Request Sense 04 6 Format Unit 08 6 Read(6) 0a 6 Write(6) 12 6 Inquiry 15 6 Mode select(6) 16 6 Reserve(6) 17 6 Release(6) 1a 6 Mode sense(6) 1b 6 Start stop unit 1d 6 Send diagnostic 1e 6 Prevent allow medium removal 25 10 Read capacity(10) 28 10 Read(10) 2a 10 Write(10) 2f 10 Verify(10) 34 10 Pre-fetch(10) 35 10 Synchronize cache(10) 41 10 Write same(10) 42 10 Unmap 55 10 Mode select(10) 5a 10 Mode sense(10) 5e 0 10 Persistent reserve in, read keys 5e 1 10 Persistent reserve in, read reservation 5e 2 10 Persistent reserve in, report capabilities 5f 0 10 Persistent reserve out, register 5f 1 10 Persistent reserve out, reserve 5f 2 10 Persistent reserve out, release 5f 3 10 Persistent reserve out, clear 5f 4 10 Persistent reserve out, preempt 5f 6 10 Persistent reserve out, register and ignore existing key 5f 7 10 Persistent reserve out, register and move 88 16 Read(16) 8a 16 Write(16) 8f 16 Verify(16) 90 16 Pre-fetch(16) 91 16 Synchronize cache(16) 93 16 Write same(16) 9e 10 16 Read capacity(16) 9e 12 16 Get LBA status a0 12 Report luns a3 c 12 Report supported operation codes a8 12 Read(12) aa 12 Write(12) af 12 Verify(12) tgtd does support a pretty fair number of opcodes ! regards ronnie sahlberg On Wed, May 30, 2012 at 7:16 PM, ronnie sahlberg <ronniesahlberg@xxxxxxxxx> wrote: > Please use this patch instead. It uses lseek64(). > > Resending since the previous reply did not go to the list. > > On Wed, May 30, 2012 at 9:01 AM, FUJITA Tomonori > <fujita.tomonori@xxxxxxxxxxxxx> wrote: >> On Tue, 29 May 2012 21:43:12 +1000 >> ronnie sahlberg <ronniesahlberg@xxxxxxxxx> wrote: >> >>> Tomo, >>> >>> Please find attached a patch that adds support for the opcode >>> GET_LBA_STATUS for thin-provisioned luns. >>> >>> >>> This patch uses the new lseek() SEEK_DATA/SEEK_HOLE to find what is >>> mapped and what is not on a sparse backend file. >>> These two new features are very new and only available on very recent >>> linux kernels and select filesystems. >>> >>> >>> Linux 3.2 and BTRFS (mint13 for example) support these two new seek types. >>> If SEEK_DATA/SEEK_HOLE is not available we emulate these as always >>> returning that the specified offset is mapped, and that the next >>> "hole" is at end-of-file, i.e. as if the file was not sparse at all. >>> >>>>From abd7df828a2b7ac6146a2e315138719a7f9f193f Mon Sep 17 00:00:00 2001 >>> From: Ronnie Sahlberg <ronniesahlberg@xxxxxxxxx> >>> Date: Tue, 29 May 2012 21:16:37 +1000 >>> Subject: [PATCH] SBC: Add GET_LBA_STATUS support >>> >>> Signed-off-by: Ronnie Sahlberg <ronniesahlberg@xxxxxxxxx> >>> --- >>> usr/sbc.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++---------- >>> usr/scsi.h | 1 + >>> 2 files changed, 90 insertions(+), 19 deletions(-) >>> >>> diff --git a/usr/sbc.c b/usr/sbc.c >>> index cf2b609..b7eaab0 100644 >>> --- a/usr/sbc.c >>> +++ b/usr/sbc.c >>> @@ -23,6 +23,9 @@ >>> * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA >>> * 02110-1301 USA >>> */ >>> +#define _FILE_OFFSET_BITS 64 >>> +#define __USE_GNU >>> + >>> #include <errno.h> >>> #include <stdio.h> >>> #include <stdlib.h> >>> @@ -30,6 +33,7 @@ >>> #include <stdint.h> >>> #include <unistd.h> >>> #include <linux/fs.h> >>> +#include <sys/types.h> >>> >>> #include "list.h" >>> #include "util.h" >>> @@ -45,6 +49,23 @@ >>> >>> static unsigned int blk_shift = DEFAULT_BLK_SHIFT; >>> >>> +static off_t find_next_data(struct scsi_lu *dev, off_t offset) >>> +{ >>> +#ifdef SEEK_DATA >>> + return lseek(dev->fd, offset, SEEK_DATA); >>> +#else >> >> Why not use lseek64 like other places in tgt? >> >>> + return offset; >>> +#endif >>> +} >>> +static off_t find_next_hole(struct scsi_lu *dev, off_t offset) >>> +{ >>> +#ifdef SEEK_HOLE >>> + return lseek(dev->fd, offset, SEEK_HOLE); >>> +#else >>> + return dev->size; >>> +#endif >>> +} >>> + >>> static int sbc_mode_page_update(struct scsi_cmd *cmd, uint8_t *data, int *changed) >>> { >>> uint8_t pcode = data[0] & 0x3f; >>> @@ -437,27 +458,76 @@ static int sbc_service_action(int host_no, struct scsi_cmd *cmd) >>> goto sense; >>> } >>> >>> - if (cmd->scb[1] != SAI_READ_CAPACITY_16) >>> - goto sense; >>> + if (cmd->scb[1] == SAI_READ_CAPACITY_16) { >>> + if (scsi_get_in_length(cmd) < 12) >>> + goto overflow; >>> >>> - if (scsi_get_in_length(cmd) < 12) >>> - goto overflow; >>> + len = min_t(int, len, scsi_get_in_length(cmd)); >>> >>> - len = min_t(int, len, scsi_get_in_length(cmd)); >>> - >>> - data = scsi_get_in_buffer(cmd); >>> - memset(data, 0, len); >>> - >>> - bshift = cmd->dev->blk_shift; >>> - size = cmd->dev->size >> bshift; >>> - >>> - *((uint64_t *)(data)) = __cpu_to_be64(size - 1); >>> - data[2] = __cpu_to_be32(1UL << bshift); >>> - >>> - val = (cmd->dev->attrs.lbppbe << 16) | cmd->dev->attrs.la_lba; >>> - if (cmd->dev->attrs.thinprovisioning) >>> - val |= (3 << 14); /* set LBPME and LBPRZ */ >>> - data[3] = __cpu_to_be32(val); >>> + data = scsi_get_in_buffer(cmd); >>> + memset(data, 0, len); >>> + >>> + bshift = cmd->dev->blk_shift; >>> + size = cmd->dev->size >> bshift; >>> + >>> + *((uint64_t *)(data)) = __cpu_to_be64(size - 1); >>> + data[2] = __cpu_to_be32(1UL << bshift); >>> + >>> + val = (cmd->dev->attrs.lbppbe << 16) | cmd->dev->attrs.la_lba; >>> + if (cmd->dev->attrs.thinprovisioning) >>> + val |= (3 << 14); /* set LBPME and LBPRZ */ >>> + data[3] = __cpu_to_be32(val); >>> + } else if (cmd->scb[1] == SAI_GET_LBA_STATUS) { >>> + uint64_t offset; >>> + uint32_t pdl; >>> + int type; >>> + char *buf; >>> + >>> + if (scsi_get_in_length(cmd) < 24) >>> + goto overflow; >>> + >>> + len = scsi_get_in_length(cmd); >>> + buf = scsi_get_in_buffer(cmd); >>> + memset(buf, 0, len); >>> + >>> + offset = __be64_to_cpu(*(uint64_t *)&cmd->scb[2]) >>> + << cmd->dev->blk_shift; >>> + pdl = 4; >>> + *(uint32_t *)&buf[0] = __cpu_to_be32(pdl); >>> + >>> + type = 0; >>> + while (len >= 4 + pdl + 16) { >>> + off_t next_offset; >>> + >>> + *(uint32_t *)&buf[0] = __cpu_to_be32(pdl + 16); >>> + >>> + if (offset >= cmd->dev->size) >>> + break; >>> + >>> + next_offset = (type == 0) ? >>> + find_next_hole(cmd->dev, offset) : >>> + find_next_data(cmd->dev, offset); >>> + if (next_offset == offset) { >>> + type = 1 - type; >>> + continue; >>> + } >>> + >>> + *(uint64_t *)&buf[4 + pdl + 0] = >>> + __cpu_to_be64(offset >>> + >> cmd->dev->blk_shift); >>> + *(uint64_t *)&buf[4 + pdl + 8] = >>> + __cpu_to_be32((next_offset - offset) >>> + >> cmd->dev->blk_shift); >>> + buf[4 + pdl + 12] = type; >>> + >>> + pdl += 16; >>> + type = 1 - type; >>> + offset = next_offset; >>> + } >>> + len = 4 + pdl; >>> + } else { >>> + goto sense; >>> + } >>> >>> overflow: >>> scsi_set_in_resid_by_actual(cmd, len); >>> diff --git a/usr/scsi.h b/usr/scsi.h >>> index 0a02c36..2b994f9 100644 >>> --- a/usr/scsi.h >>> +++ b/usr/scsi.h >>> @@ -80,6 +80,7 @@ >>> #define WRITE_SAME_16 0x93 >>> #define SERVICE_ACTION_IN 0x9e >>> #define SAI_READ_CAPACITY_16 0x10 >>> +#define SAI_GET_LBA_STATUS 0x12 >>> #define REPORT_LUNS 0xa0 >>> #define MOVE_MEDIUM 0xa5 >>> #define EXCHANGE_MEDIUM 0xa6 >>> -- >>> 1.7.3.1
Attachment:
0001-SBC-Add-GET_LBA_STATUS-command.patch.gz
Description: GNU Zip compressed data
Attachment:
0001-SBC-Add-GET_LBA_STATUS-command.patch
Description: Binary data