~ubuntu-branches/ubuntu/precise/tgt/precise

« back to all changes in this revision

Viewing changes to usr/spc.c

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2011-02-08 10:31:04 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20110208103104-oots1az6acnkfvuw
Tags: 1:1.0.13-0ubuntu1
* New upstream release.
* debian/patches/make-tgt-setup-lun-executable: Dropped no longer needed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
852
852
                else
853
853
                        res_key = reg->key;
854
854
 
855
 
                put_unaligned_be32(res_key, &buf[8]);
 
855
                put_unaligned_be64(res_key, &buf[8]);
856
856
                buf[21] = ((reg->pr_scope << 4) & 0xf0) | (reg->pr_type & 0x0f);
857
857
        } else
858
858
                put_unaligned_be32(0, &buf[4]);
926
926
        return NULL;
927
927
}
928
928
 
 
929
static int check_registration_key_exists(struct scsi_lu *lu, uint64_t key)
 
930
{
 
931
        struct registration *reg;
 
932
 
 
933
        list_for_each_entry(reg, &lu->registration_list,
 
934
                                registration_siblings) {
 
935
                if (reg->key == key)
 
936
                        return 0;
 
937
        }
 
938
 
 
939
        return 1;
 
940
}
 
941
 
929
942
static void __unregister(struct scsi_lu *lu, struct registration *reg)
930
943
{
931
944
        list_del(&reg->registration_siblings);
1192
1205
                                 registration_siblings) {
1193
1206
                /* we don't send myself */
1194
1207
                if (sibling != reg)
1195
 
                        ua_sense_add_other_it_nexus(sibling->nexus_id,
1196
 
                                                    cmd->dev,
1197
 
                                                    ASC_RESERVATIONS_PREEMPTED);
 
1208
                        ua_sense_add_it_nexus(sibling->nexus_id,
 
1209
                                cmd->dev, ASC_RESERVATIONS_PREEMPTED);
1198
1210
                list_del(&sibling->registration_siblings);
1199
1211
                free(sibling);
1200
1212
        }
1211
1223
        uint16_t asc = ASC_INVALID_FIELD_IN_CDB;
1212
1224
        uint8_t key = ILLEGAL_REQUEST;
1213
1225
        int ret, abort;
 
1226
        int res_released = 0, remove_all_reg = 0;
1214
1227
        uint64_t res_key, sa_res_key;
1215
1228
        uint8_t pr_scope, pr_type;
1216
1229
        uint8_t *buf;
1217
 
        struct registration *reg, *sibling, *n;
 
1230
        struct registration *holder, *reg, *sibling, *n;
1218
1231
 
1219
1232
        ret = check_pr_out_basic_parameter(cmd);
1220
1233
        if (ret)
1237
1250
        if (reg->key != res_key)
1238
1251
                return SAM_STAT_RESERVATION_CONFLICT;
1239
1252
 
1240
 
remove_registration:
1241
 
        if (!cmd->dev->pr_holder) {
1242
 
                list_for_each_entry_safe(sibling, n, &cmd->dev->registration_list,
1243
 
                                         registration_siblings) {
1244
 
 
1245
 
                        if (sibling->key == sa_res_key) {
1246
 
                                __unregister(cmd->dev, sibling);
1247
 
                                break;
 
1253
        if (sa_res_key) {
 
1254
                ret = check_registration_key_exists(cmd->dev, sa_res_key);
 
1255
                if (ret)
 
1256
                        return SAM_STAT_RESERVATION_CONFLICT;
 
1257
        }
 
1258
 
 
1259
        holder = cmd->dev->pr_holder;
 
1260
 
 
1261
        if (holder) {
 
1262
                if (holder->pr_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG ||
 
1263
                        holder->pr_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG) {
 
1264
 
 
1265
                        if (!sa_res_key) {
 
1266
                                if (pr_type != holder->pr_type ||
 
1267
                                        pr_scope != holder->pr_scope)
 
1268
                                        res_released = 1;
 
1269
                                reg->pr_type = pr_type;
 
1270
                                reg->pr_scope = pr_scope;
 
1271
                                cmd->dev->pr_holder = reg;
 
1272
                                remove_all_reg = 1;
 
1273
                        }
 
1274
                } else {
 
1275
                        if (holder->key == sa_res_key) {
 
1276
                                if ((pr_type != holder->pr_type) ||
 
1277
                                        (pr_scope != holder->pr_scope))
 
1278
                                        res_released = 1;
 
1279
                                reg->pr_type = pr_type;
 
1280
                                reg->pr_scope = pr_scope;
 
1281
                                cmd->dev->pr_holder = reg;
 
1282
                        } else {
 
1283
                                if (!sa_res_key)
 
1284
                                        goto sense;
1248
1285
                        }
1249
1286
                }
1250
 
 
1251
 
                return SAM_STAT_GOOD;
1252
1287
        }
1253
1288
 
1254
 
        if (cmd->dev->pr_holder->pr_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG ||
1255
 
            cmd->dev->pr_holder->pr_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG) {
1256
 
 
1257
 
                if (sa_res_key)
1258
 
                        goto remove_registration;
1259
 
 
1260
 
                list_for_each_entry_safe(sibling, n, &cmd->dev->registration_list,
1261
 
                                         registration_siblings) {
1262
 
 
1263
 
                        if (sibling == reg)
1264
 
                                continue;
1265
 
 
 
1289
        list_for_each_entry_safe(sibling, n, &cmd->dev->registration_list,
 
1290
                                        registration_siblings) {
 
1291
                if (sibling == reg)
 
1292
                        continue;
 
1293
 
 
1294
                if (sibling->key == sa_res_key || remove_all_reg) {
 
1295
                        ua_sense_add_it_nexus(sibling->nexus_id,
 
1296
                                cmd->dev, ASC_RESERVATIONS_PREEMPTED);
1266
1297
                        __unregister(cmd->dev, sibling);
 
1298
                } else {
 
1299
                        if (res_released)
 
1300
                                ua_sense_add_it_nexus(sibling->nexus_id,
 
1301
                                cmd->dev, ASC_RESERVATIONS_RELEASED);
1267
1302
                }
1268
 
 
1269
 
                cmd->dev->pr_holder = reg;
1270
 
                reg->pr_type = pr_type;
1271
 
                reg->pr_scope = pr_scope;
1272
 
 
1273
 
                return SAM_STAT_GOOD;
1274
 
        }
1275
 
 
1276
 
        if (cmd->dev->pr_holder->key == sa_res_key) {
1277
 
                cmd->dev->pr_holder = reg;
1278
 
                reg->pr_type = pr_type;
1279
 
                reg->pr_scope = pr_scope;
1280
 
 
1281
 
                goto remove_registration;
1282
 
        }
1283
 
 
1284
 
        if (sa_res_key)
1285
 
                goto remove_registration;
1286
 
 
1287
 
        else
1288
 
                goto sense;
1289
 
 
 
1303
        }
 
1304
 
 
1305
        cmd->dev->prgeneration++;
1290
1306
        return SAM_STAT_GOOD;
1291
1307
sense:
1292
1308
        scsi_set_in_resid_by_actual(cmd, 0);
1578
1594
        Opt_scsi_id, Opt_scsi_sn,
1579
1595
        Opt_vendor_id, Opt_product_id,
1580
1596
        Opt_product_rev, Opt_sense_format,
1581
 
        Opt_removable, Opt_online,
 
1597
        Opt_removable, Opt_readonly, Opt_online,
1582
1598
        Opt_mode_page,
1583
1599
        Opt_path,
 
1600
        Opt_bsoflags,
1584
1601
        Opt_err,
1585
1602
};
1586
1603
 
1592
1609
        {Opt_product_rev, "product_rev=%s"},
1593
1610
        {Opt_sense_format, "sense_format=%s"},
1594
1611
        {Opt_removable, "removable=%s"},
 
1612
        {Opt_readonly, "readonly=%s"},
1595
1613
        {Opt_online, "online=%s"},
1596
1614
        {Opt_mode_page, "mode_page=%s"},
1597
1615
        {Opt_path, "path=%s"},
 
1616
        {Opt_bsoflags, "bsoflags=%s"},
1598
1617
        {Opt_err, NULL},
1599
1618
};
1600
1619
 
1627
1646
        while ((p = strsep(&params, ",")) != NULL) {
1628
1647
                substring_t args[MAX_OPT_ARGS];
1629
1648
                int token;
 
1649
 
1630
1650
                if (!*p)
1631
1651
                        continue;
1632
1652
                token = match_token(p, tokens, args);
1661
1681
                        match_strncpy(buf, &args[0], sizeof(buf));
1662
1682
                        attrs->removable = atoi(buf);
1663
1683
                        break;
 
1684
                case Opt_readonly:
 
1685
                        match_strncpy(buf, &args[0], sizeof(buf));
 
1686
                        attrs->readonly = atoi(buf);
 
1687
                        break;
1664
1688
                case Opt_online:
1665
1689
                        match_strncpy(buf, &args[0], sizeof(buf));
1666
1690
                        if (atoi(buf))
1719
1743
        lu_vpd[pg]->vpd_update(lu, lu->attrs.scsi_id);
1720
1744
 
1721
1745
        lu->attrs.removable = 0;
 
1746
        lu->attrs.readonly = 0;
1722
1747
        lu->attrs.sense_format = 0;
1723
1748
        lu->dev_type_template.lu_offline(lu);
1724
1749