diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-10-03 21:06:08 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-10-04 01:41:20 -0400 |
commit | 92404e609a2dffc55a9a22540ed48b6f0edc9c59 (patch) | |
tree | f815d53d2611a9b0cab864fc70bcffc26c8f043b | |
parent | e24805637d2d270d7975502e9024d473de86afdb (diff) |
target: Add force_pr_aptpl device attribute
This patch adds a force_pr_aptpl device attribute used to force SPC-3 PR
Activate Persistence across Target Power Loss (APTPL) operation. This
makes PR metadata write-out occur during state change regardless if new
PERSISTENT_RESERVE_OUT CDBs have their APTPL feature bit set.
This is useful during H/A failover in active/passive setups where all PR
state is being re-created on a different node, driven by configfs backend
device + export layout and pre-loaded $DEV/pr/res_aptpl_metadata.
Cc: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r-- | drivers/target/target_core_configfs.c | 4 | ||||
-rw-r--r-- | drivers/target/target_core_device.c | 18 | ||||
-rw-r--r-- | drivers/target/target_core_internal.h | 1 | ||||
-rw-r--r-- | drivers/target/target_core_pr.c | 9 | ||||
-rw-r--r-- | include/target/target_core_base.h | 3 |
5 files changed, 35 insertions, 0 deletions
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 291dc711fbc3..b30fc8f53bd8 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c | |||
@@ -665,6 +665,9 @@ SE_DEV_ATTR(is_nonrot, S_IRUGO | S_IWUSR); | |||
665 | DEF_DEV_ATTRIB(emulate_rest_reord); | 665 | DEF_DEV_ATTRIB(emulate_rest_reord); |
666 | SE_DEV_ATTR(emulate_rest_reord, S_IRUGO | S_IWUSR); | 666 | SE_DEV_ATTR(emulate_rest_reord, S_IRUGO | S_IWUSR); |
667 | 667 | ||
668 | DEF_DEV_ATTRIB(force_pr_aptpl); | ||
669 | SE_DEV_ATTR(force_pr_aptpl, S_IRUGO | S_IWUSR); | ||
670 | |||
668 | DEF_DEV_ATTRIB_RO(hw_block_size); | 671 | DEF_DEV_ATTRIB_RO(hw_block_size); |
669 | SE_DEV_ATTR_RO(hw_block_size); | 672 | SE_DEV_ATTR_RO(hw_block_size); |
670 | 673 | ||
@@ -719,6 +722,7 @@ static struct configfs_attribute *target_core_dev_attrib_attrs[] = { | |||
719 | &target_core_dev_attrib_hw_pi_prot_type.attr, | 722 | &target_core_dev_attrib_hw_pi_prot_type.attr, |
720 | &target_core_dev_attrib_pi_prot_format.attr, | 723 | &target_core_dev_attrib_pi_prot_format.attr, |
721 | &target_core_dev_attrib_enforce_pr_isids.attr, | 724 | &target_core_dev_attrib_enforce_pr_isids.attr, |
725 | &target_core_dev_attrib_force_pr_aptpl.attr, | ||
722 | &target_core_dev_attrib_is_nonrot.attr, | 726 | &target_core_dev_attrib_is_nonrot.attr, |
723 | &target_core_dev_attrib_emulate_rest_reord.attr, | 727 | &target_core_dev_attrib_emulate_rest_reord.attr, |
724 | &target_core_dev_attrib_hw_block_size.attr, | 728 | &target_core_dev_attrib_hw_block_size.attr, |
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index d18dd8b532a8..c45f9e907e44 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
@@ -1018,6 +1018,23 @@ int se_dev_set_enforce_pr_isids(struct se_device *dev, int flag) | |||
1018 | return 0; | 1018 | return 0; |
1019 | } | 1019 | } |
1020 | 1020 | ||
1021 | int se_dev_set_force_pr_aptpl(struct se_device *dev, int flag) | ||
1022 | { | ||
1023 | if ((flag != 0) && (flag != 1)) { | ||
1024 | printk(KERN_ERR "Illegal value %d\n", flag); | ||
1025 | return -EINVAL; | ||
1026 | } | ||
1027 | if (dev->export_count) { | ||
1028 | pr_err("dev[%p]: Unable to set force_pr_aptpl while" | ||
1029 | " export_count is %d\n", dev, dev->export_count); | ||
1030 | return -EINVAL; | ||
1031 | } | ||
1032 | |||
1033 | dev->dev_attrib.force_pr_aptpl = flag; | ||
1034 | pr_debug("dev[%p]: SE Device force_pr_aptpl: %d\n", dev, flag); | ||
1035 | return 0; | ||
1036 | } | ||
1037 | |||
1021 | int se_dev_set_is_nonrot(struct se_device *dev, int flag) | 1038 | int se_dev_set_is_nonrot(struct se_device *dev, int flag) |
1022 | { | 1039 | { |
1023 | if ((flag != 0) && (flag != 1)) { | 1040 | if ((flag != 0) && (flag != 1)) { |
@@ -1544,6 +1561,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) | |||
1544 | dev->dev_attrib.emulate_3pc = DA_EMULATE_3PC; | 1561 | dev->dev_attrib.emulate_3pc = DA_EMULATE_3PC; |
1545 | dev->dev_attrib.pi_prot_type = TARGET_DIF_TYPE0_PROT; | 1562 | dev->dev_attrib.pi_prot_type = TARGET_DIF_TYPE0_PROT; |
1546 | dev->dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS; | 1563 | dev->dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS; |
1564 | dev->dev_attrib.force_pr_aptpl = DA_FORCE_PR_APTPL; | ||
1547 | dev->dev_attrib.is_nonrot = DA_IS_NONROT; | 1565 | dev->dev_attrib.is_nonrot = DA_IS_NONROT; |
1548 | dev->dev_attrib.emulate_rest_reord = DA_EMULATE_REST_REORD; | 1566 | dev->dev_attrib.emulate_rest_reord = DA_EMULATE_REST_REORD; |
1549 | dev->dev_attrib.max_unmap_lba_count = DA_MAX_UNMAP_LBA_COUNT; | 1567 | dev->dev_attrib.max_unmap_lba_count = DA_MAX_UNMAP_LBA_COUNT; |
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index 42ef4ab70585..e31f42f369ff 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h | |||
@@ -38,6 +38,7 @@ int se_dev_set_emulate_3pc(struct se_device *, int); | |||
38 | int se_dev_set_pi_prot_type(struct se_device *, int); | 38 | int se_dev_set_pi_prot_type(struct se_device *, int); |
39 | int se_dev_set_pi_prot_format(struct se_device *, int); | 39 | int se_dev_set_pi_prot_format(struct se_device *, int); |
40 | int se_dev_set_enforce_pr_isids(struct se_device *, int); | 40 | int se_dev_set_enforce_pr_isids(struct se_device *, int); |
41 | int se_dev_set_force_pr_aptpl(struct se_device *, int); | ||
41 | int se_dev_set_is_nonrot(struct se_device *, int); | 42 | int se_dev_set_is_nonrot(struct se_device *, int); |
42 | int se_dev_set_emulate_rest_reord(struct se_device *dev, int); | 43 | int se_dev_set_emulate_rest_reord(struct se_device *dev, int); |
43 | int se_dev_set_queue_depth(struct se_device *, u32); | 44 | int se_dev_set_queue_depth(struct se_device *, u32); |
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index a06edb59b67f..8c60a1a1ae8d 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
@@ -895,6 +895,7 @@ static int __core_scsi3_check_aptpl_registration( | |||
895 | spin_lock(&pr_tmpl->aptpl_reg_lock); | 895 | spin_lock(&pr_tmpl->aptpl_reg_lock); |
896 | list_for_each_entry_safe(pr_reg, pr_reg_tmp, &pr_tmpl->aptpl_reg_list, | 896 | list_for_each_entry_safe(pr_reg, pr_reg_tmp, &pr_tmpl->aptpl_reg_list, |
897 | pr_reg_aptpl_list) { | 897 | pr_reg_aptpl_list) { |
898 | |||
898 | if (!strcmp(pr_reg->pr_iport, i_port) && | 899 | if (!strcmp(pr_reg->pr_iport, i_port) && |
899 | (pr_reg->pr_res_mapped_lun == deve->mapped_lun) && | 900 | (pr_reg->pr_res_mapped_lun == deve->mapped_lun) && |
900 | !(strcmp(pr_reg->pr_tport, t_port)) && | 901 | !(strcmp(pr_reg->pr_tport, t_port)) && |
@@ -3470,6 +3471,7 @@ static unsigned long long core_scsi3_extract_reservation_key(unsigned char *cdb) | |||
3470 | sense_reason_t | 3471 | sense_reason_t |
3471 | target_scsi3_emulate_pr_out(struct se_cmd *cmd) | 3472 | target_scsi3_emulate_pr_out(struct se_cmd *cmd) |
3472 | { | 3473 | { |
3474 | struct se_device *dev = cmd->se_dev; | ||
3473 | unsigned char *cdb = &cmd->t_task_cdb[0]; | 3475 | unsigned char *cdb = &cmd->t_task_cdb[0]; |
3474 | unsigned char *buf; | 3476 | unsigned char *buf; |
3475 | u64 res_key, sa_res_key; | 3477 | u64 res_key, sa_res_key; |
@@ -3534,6 +3536,13 @@ target_scsi3_emulate_pr_out(struct se_cmd *cmd) | |||
3534 | aptpl = (buf[17] & 0x01); | 3536 | aptpl = (buf[17] & 0x01); |
3535 | unreg = (buf[17] & 0x02); | 3537 | unreg = (buf[17] & 0x02); |
3536 | } | 3538 | } |
3539 | /* | ||
3540 | * If the backend device has been configured to force APTPL metadata | ||
3541 | * write-out, go ahead and propigate aptpl=1 down now. | ||
3542 | */ | ||
3543 | if (dev->dev_attrib.force_pr_aptpl) | ||
3544 | aptpl = 1; | ||
3545 | |||
3537 | transport_kunmap_data_sg(cmd); | 3546 | transport_kunmap_data_sg(cmd); |
3538 | buf = NULL; | 3547 | buf = NULL; |
3539 | 3548 | ||
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index b106240d8385..23c518a0340c 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h | |||
@@ -108,6 +108,8 @@ | |||
108 | #define DA_EMULATE_ALUA 0 | 108 | #define DA_EMULATE_ALUA 0 |
109 | /* Enforce SCSI Initiator Port TransportID with 'ISID' for PR */ | 109 | /* Enforce SCSI Initiator Port TransportID with 'ISID' for PR */ |
110 | #define DA_ENFORCE_PR_ISIDS 1 | 110 | #define DA_ENFORCE_PR_ISIDS 1 |
111 | /* Force SPC-3 PR Activate Persistence across Target Power Loss */ | ||
112 | #define DA_FORCE_PR_APTPL 0 | ||
111 | #define DA_STATUS_MAX_SECTORS_MIN 16 | 113 | #define DA_STATUS_MAX_SECTORS_MIN 16 |
112 | #define DA_STATUS_MAX_SECTORS_MAX 8192 | 114 | #define DA_STATUS_MAX_SECTORS_MAX 8192 |
113 | /* By default don't report non-rotating (solid state) medium */ | 115 | /* By default don't report non-rotating (solid state) medium */ |
@@ -680,6 +682,7 @@ struct se_dev_attrib { | |||
680 | enum target_prot_type pi_prot_type; | 682 | enum target_prot_type pi_prot_type; |
681 | enum target_prot_type hw_pi_prot_type; | 683 | enum target_prot_type hw_pi_prot_type; |
682 | int enforce_pr_isids; | 684 | int enforce_pr_isids; |
685 | int force_pr_aptpl; | ||
683 | int is_nonrot; | 686 | int is_nonrot; |
684 | int emulate_rest_reord; | 687 | int emulate_rest_reord; |
685 | u32 hw_block_size; | 688 | u32 hw_block_size; |