[stgt] [PATCH] Add support for SBC GET_LBA_STATUS opcode

ronnie sahlberg ronniesahlberg at gmail.com
Wed May 30 11:16:07 CEST 2012


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 at lab.ntt.co.jp> wrote:
> On Tue, 29 May 2012 21:43:12 +1000
> ronnie sahlberg <ronniesahlberg at gmail.com> 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 at gmail.com>
>> Date: Tue, 29 May 2012 21:16:37 +1000
>> Subject: [PATCH] SBC: Add GET_LBA_STATUS support
>>
>> Signed-off-by: Ronnie Sahlberg <ronniesahlberg at gmail.com>
>> ---
>>  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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-SBC-Add-support-for-GET_LBA_STATUS-command.patch.gz
Type: application/x-gzip
Size: 1840 bytes
Desc: not available
URL: <http://lists.wpkg.org/pipermail/stgt/attachments/20120530/627767bb/attachment-0002.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-SBC-Add-support-for-GET_LBA_STATUS-command.patch
Type: application/octet-stream
Size: 4612 bytes
Desc: not available
URL: <http://lists.wpkg.org/pipermail/stgt/attachments/20120530/627767bb/attachment-0002.obj>


More information about the stgt mailing list