[stgt] [PATCH] Add support for SoftwareWriteProtect and fix bugs in modeselect

ronnie sahlberg ronniesahlberg at gmail.com
Sun Jul 7 08:17:02 CEST 2013


I have also added a utility iscsi-swp to libiscsi that can be used to
manage the SWP flag of an iSCSI LUN.

./bin/iscsi-swp iscsi://127.0.0.1/iqn.ronnie.test/1 --swp on



On Sat, Jul 6, 2013 at 11:13 PM, Ronnie Sahlberg
<ronniesahlberg at gmail.com> wrote:
> Fix a bug in sbc_mode_page_update. We only have a subpagecode in byte 1
> IFF the SPF bit in byte 0 is set.
>
> Add support for using modeselect for the CONTROLS page and set the
> mask to allow SWP to be changed.
>
> Add a SWP flag to the device attributes and update this as the CONTROLS/SWP
> flag is set by the initiator.
>
> Update SBC so that we treat writeprotect as either the current ->readonly flag
> that is used to se the hard property for the lun,   or the ->swp flag
> that is set in software by the initiators.
> Thus like on a real disk, SWP can be used to turn a read-write LUN to become
> temporarily readonly, but SWP can NOT be used to turn a physically readonly
> medium to become read-write.
>
> Signed-off-by: Ronnie Sahlberg <ronniesahlberg at gmail.com>
> ---
>  usr/sbc.c    |   37 +++++++++++++++++++++++++++++++------
>  usr/spc.c    |    1 +
>  usr/target.c |    2 ++
>  usr/tgtd.h   |    1 +
>  4 files changed, 35 insertions(+), 6 deletions(-)
>
> diff --git a/usr/sbc.c b/usr/sbc.c
> index 1f50191..c4f012c 100644
> --- a/usr/sbc.c
> +++ b/usr/sbc.c
> @@ -69,17 +69,21 @@ static off_t find_next_hole(struct scsi_lu *dev, off_t offset)
>  static int sbc_mode_page_update(struct scsi_cmd *cmd, uint8_t *data, int *changed)
>  {
>         uint8_t pcode = data[0] & 0x3f;
> -       uint8_t subpcode = data[1];
> +       uint8_t subpcode = 0;
>         struct mode_pg *pg;
>         uint8_t old;
>
> +       if (data[0] & 0x40)
> +               subpcode = data[1];
> +
>         pg = find_mode_page(cmd->dev, pcode, subpcode);
>         if (pg == NULL)
>                 return 1;
>
>         eprintf("%x %x\n", pg->mode_data[0], data[2]);
>
> -       if (pcode == 0x08) {
> +       switch (pcode) {
> +       case 0x08: /* Cachning mode page */
>                 old = pg->mode_data[0];
>                 if (0x4 & data[2])
>                         pg->mode_data[0] |= 0x4;
> @@ -90,6 +94,19 @@ static int sbc_mode_page_update(struct scsi_cmd *cmd, uint8_t *data, int *change
>                         *changed = 1;
>
>                 return 0;
> +       case 0x0a: /* Control mode page */
> +               old = pg->mode_data[2];
> +               if (0x8 & data[4])
> +                       pg->mode_data[2] |= 0x8;
> +               else
> +                       pg->mode_data[2] &= ~0x8;
> +
> +               if (old != pg->mode_data[2])
> +                       *changed = 1;
> +
> +               cmd->dev->attrs.swp = (0x8 & data[4]) ? 1 : 0;
> +
> +               return 0;
>         }
>
>         return 1;
> @@ -110,7 +127,8 @@ static int sbc_mode_sense(int host_no, struct scsi_cmd *cmd)
>          * If this is a read-only lun, we must modify the data and set the
>          * write protect bit
>          */
> -       if (cmd->dev->attrs.readonly && ret == SAM_STAT_GOOD) {
> +       if ((cmd->dev->attrs.readonly || cmd->dev->attrs.swp)
> +       && ret == SAM_STAT_GOOD) {
>                 uint8_t *data, mode6;
>
>                 mode6 = (cmd->scb[0] == 0x1a);
> @@ -141,7 +159,7 @@ static int sbc_format_unit(int host_no, struct scsi_cmd *cmd)
>                 goto sense;
>         }
>
> -       if (cmd->dev->attrs.readonly) {
> +       if (cmd->dev->attrs.readonly || cmd->dev->attrs.swp) {
>                 key = DATA_PROTECT;
>                 asc = ASC_WRITE_PROTECT;
>                 goto sense;
> @@ -199,7 +217,7 @@ static int sbc_unmap(int host_no, struct scsi_cmd *cmd)
>                 goto sense;
>         }
>
> -       if (lu->attrs.readonly) {
> +       if (lu->attrs.readonly || cmd->dev->attrs.swp) {
>                 key = DATA_PROTECT;
>                 asc = ASC_WRITE_PROTECT;
>                 goto sense;
> @@ -290,7 +308,7 @@ static int sbc_rw(int host_no, struct scsi_cmd *cmd)
>                 break;
>         }
>
> -       if (lu->attrs.readonly) {
> +       if (lu->attrs.readonly || cmd->dev->attrs.swp) {
>                 switch (cmd->scb[0]) {
>                 case WRITE_6:
>                 case WRITE_10:
> @@ -736,6 +754,13 @@ static tgtadm_err sbc_lu_init(struct scsi_lu *lu)
>
>         /* Control page */
>         add_mode_page(lu, "0x0a:0:10:2:0x10:0:0:0:0:0:0:2:0");
> +       {
> +               uint8_t mask[10];
> +               memset(mask, 0, sizeof(mask));
> +               mask[2] = 0x08; /* allow changing SWP */
> +
> +               set_mode_page_changeable_mask(lu, 0x0a, 0, mask);
> +       }
>
>         /* Control Extensions mode page:  TCMOS:1 */
>         add_mode_page(lu, "0x0a:1:0x1c:0x04:0x00:0x00");
> diff --git a/usr/spc.c b/usr/spc.c
> index 0cbba95..15077ca 100644
> --- a/usr/spc.c
> +++ b/usr/spc.c
> @@ -2028,6 +2028,7 @@ int spc_lu_init(struct scsi_lu *lu)
>         lu->attrs.thinprovisioning = 0;
>         lu->attrs.removable = 0;
>         lu->attrs.readonly = 0;
> +       lu->attrs.swp = 0;
>         lu->attrs.sense_format = 0;
>
>         snprintf(lu->attrs.vendor_id, sizeof(lu->attrs.vendor_id),
> diff --git a/usr/target.c b/usr/target.c
> index 9a8f2fd..fd087ad 100644
> --- a/usr/target.c
> +++ b/usr/target.c
> @@ -2023,6 +2023,7 @@ tgtadm_err tgt_target_show_all(struct concat_buf *b)
>                                 _TAB3 "Removable media: %s\n"
>                                 _TAB3 "Prevent removal: %s\n"
>                                 _TAB3 "Readonly: %s\n"
> +                               _TAB3 "SWP: %s\n"
>                                 _TAB3 "Thin-provisioning: %s\n"
>                                 _TAB3 "Backing store type: %s\n"
>                                 _TAB3 "Backing store path: %s\n"
> @@ -2037,6 +2038,7 @@ tgtadm_err tgt_target_show_all(struct concat_buf *b)
>                                 lu->attrs.removable ? "Yes" : "No",
>                                 lu_prevent_removal(lu) ? "Yes" : "No",
>                                 lu->attrs.readonly ? "Yes" : "No",
> +                               lu->attrs.swp ? "Yes" : "No",
>                                 lu->attrs.thinprovisioning ? "Yes" : "No",
>                                 lu->bst ?
>                                         (lu->bst->bs_name ? : "Unknown") :
> diff --git a/usr/tgtd.h b/usr/tgtd.h
> index f3d9674..484e6e9 100644
> --- a/usr/tgtd.h
> +++ b/usr/tgtd.h
> @@ -74,6 +74,7 @@ struct lu_phy_attr {
>         char qualifier;         /* Peripheral Qualifier */
>         char removable;         /* Removable media */
>         char readonly;          /* Read-Only media */
> +       char swp;               /* Software Write Protect */
>         char thinprovisioning;  /* Use thin-provisioning for this LUN */
>         char online;            /* Logical Unit online */
>         char sense_format;      /* Descrptor format sense data supported */
> --
> 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