diff options
| author | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-01-08 13:19:31 -0500 |
|---|---|---|
| committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-01-18 04:57:47 -0500 |
| commit | 2ed22c9cbca61f0f696a0a1cbbb777da281bd79d (patch) | |
| tree | 0cd4084400fedaebb9dd191fcf33c52594d5d71d | |
| parent | 0c30f421a7dba0a7ca9a3f67dad15d84d4d61e01 (diff) | |
target/configfs: Expose protection device attributes
This patch adds support for exposing DIF protection device
attributes via configfs. This includes:
pi_prot_type: Protection Type (0, 1, 3 currently support)
pi_prot_format: Protection Format Operation (FILEIO only)
Within se_dev_set_pi_prot_type() it also adds the se_subsystem_api
device callbacks to setup per device protection information.
v2 changes:
- Drop pi_guard_type + pi_prot_version related code (MKP)
- Add pi_prot_format logic (Sagi)
- Add ->free_prot callback in target_free_device
- Add hw_pi_prot_type read-only attribute
Cc: Martin K. Petersen <martin.petersen@oracle.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.de>
Cc: Sagi Grimberg <sagig@mellanox.com>
Cc: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
| -rw-r--r-- | drivers/target/target_core_configfs.c | 12 | ||||
| -rw-r--r-- | drivers/target/target_core_device.c | 89 | ||||
| -rw-r--r-- | drivers/target/target_core_internal.h | 2 |
3 files changed, 103 insertions, 0 deletions
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 5cf613544eeb..f0e85b119692 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c | |||
| @@ -643,6 +643,15 @@ SE_DEV_ATTR(emulate_caw, S_IRUGO | S_IWUSR); | |||
| 643 | DEF_DEV_ATTRIB(emulate_3pc); | 643 | DEF_DEV_ATTRIB(emulate_3pc); |
| 644 | SE_DEV_ATTR(emulate_3pc, S_IRUGO | S_IWUSR); | 644 | SE_DEV_ATTR(emulate_3pc, S_IRUGO | S_IWUSR); |
| 645 | 645 | ||
| 646 | DEF_DEV_ATTRIB(pi_prot_type); | ||
| 647 | SE_DEV_ATTR(pi_prot_type, S_IRUGO | S_IWUSR); | ||
| 648 | |||
| 649 | DEF_DEV_ATTRIB_RO(hw_pi_prot_type); | ||
| 650 | SE_DEV_ATTR_RO(hw_pi_prot_type); | ||
| 651 | |||
| 652 | DEF_DEV_ATTRIB(pi_prot_format); | ||
| 653 | SE_DEV_ATTR(pi_prot_format, S_IRUGO | S_IWUSR); | ||
| 654 | |||
| 646 | DEF_DEV_ATTRIB(enforce_pr_isids); | 655 | DEF_DEV_ATTRIB(enforce_pr_isids); |
| 647 | SE_DEV_ATTR(enforce_pr_isids, S_IRUGO | S_IWUSR); | 656 | SE_DEV_ATTR(enforce_pr_isids, S_IRUGO | S_IWUSR); |
| 648 | 657 | ||
| @@ -702,6 +711,9 @@ static struct configfs_attribute *target_core_dev_attrib_attrs[] = { | |||
| 702 | &target_core_dev_attrib_emulate_tpws.attr, | 711 | &target_core_dev_attrib_emulate_tpws.attr, |
| 703 | &target_core_dev_attrib_emulate_caw.attr, | 712 | &target_core_dev_attrib_emulate_caw.attr, |
| 704 | &target_core_dev_attrib_emulate_3pc.attr, | 713 | &target_core_dev_attrib_emulate_3pc.attr, |
| 714 | &target_core_dev_attrib_pi_prot_type.attr, | ||
| 715 | &target_core_dev_attrib_hw_pi_prot_type.attr, | ||
| 716 | &target_core_dev_attrib_pi_prot_format.attr, | ||
| 705 | &target_core_dev_attrib_enforce_pr_isids.attr, | 717 | &target_core_dev_attrib_enforce_pr_isids.attr, |
| 706 | &target_core_dev_attrib_is_nonrot.attr, | 718 | &target_core_dev_attrib_is_nonrot.attr, |
| 707 | &target_core_dev_attrib_emulate_rest_reord.attr, | 719 | &target_core_dev_attrib_emulate_rest_reord.attr, |
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 32440584ebbb..883099e89020 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
| @@ -918,6 +918,90 @@ int se_dev_set_emulate_3pc(struct se_device *dev, int flag) | |||
| 918 | return 0; | 918 | return 0; |
| 919 | } | 919 | } |
| 920 | 920 | ||
| 921 | int se_dev_set_pi_prot_type(struct se_device *dev, int flag) | ||
| 922 | { | ||
| 923 | int rc, old_prot = dev->dev_attrib.pi_prot_type; | ||
| 924 | |||
| 925 | if (flag != 0 && flag != 1 && flag != 2 && flag != 3) { | ||
| 926 | pr_err("Illegal value %d for pi_prot_type\n", flag); | ||
| 927 | return -EINVAL; | ||
| 928 | } | ||
| 929 | if (flag == 2) { | ||
| 930 | pr_err("DIF TYPE2 protection currently not supported\n"); | ||
| 931 | return -ENOSYS; | ||
| 932 | } | ||
| 933 | if (dev->dev_attrib.hw_pi_prot_type) { | ||
| 934 | pr_warn("DIF protection enabled on underlying hardware," | ||
| 935 | " ignoring\n"); | ||
| 936 | return 0; | ||
| 937 | } | ||
| 938 | if (!dev->transport->init_prot || !dev->transport->free_prot) { | ||
| 939 | pr_err("DIF protection not supported by backend: %s\n", | ||
| 940 | dev->transport->name); | ||
| 941 | return -ENOSYS; | ||
| 942 | } | ||
| 943 | if (!(dev->dev_flags & DF_CONFIGURED)) { | ||
| 944 | pr_err("DIF protection requires device to be configured\n"); | ||
| 945 | return -ENODEV; | ||
| 946 | } | ||
| 947 | if (dev->export_count) { | ||
| 948 | pr_err("dev[%p]: Unable to change SE Device PROT type while" | ||
| 949 | " export_count is %d\n", dev, dev->export_count); | ||
| 950 | return -EINVAL; | ||
| 951 | } | ||
| 952 | |||
| 953 | dev->dev_attrib.pi_prot_type = flag; | ||
| 954 | |||
| 955 | if (flag && !old_prot) { | ||
| 956 | rc = dev->transport->init_prot(dev); | ||
| 957 | if (rc) { | ||
| 958 | dev->dev_attrib.pi_prot_type = old_prot; | ||
| 959 | return rc; | ||
| 960 | } | ||
| 961 | |||
| 962 | } else if (!flag && old_prot) { | ||
| 963 | dev->transport->free_prot(dev); | ||
| 964 | } | ||
| 965 | pr_debug("dev[%p]: SE Device Protection Type: %d\n", dev, flag); | ||
| 966 | |||
| 967 | return 0; | ||
| 968 | } | ||
| 969 | |||
| 970 | int se_dev_set_pi_prot_format(struct se_device *dev, int flag) | ||
| 971 | { | ||
| 972 | int rc; | ||
| 973 | |||
| 974 | if (!flag) | ||
| 975 | return 0; | ||
| 976 | |||
| 977 | if (flag != 1) { | ||
| 978 | pr_err("Illegal value %d for pi_prot_format\n", flag); | ||
| 979 | return -EINVAL; | ||
| 980 | } | ||
| 981 | if (!dev->transport->format_prot) { | ||
| 982 | pr_err("DIF protection format not supported by backend %s\n", | ||
| 983 | dev->transport->name); | ||
| 984 | return -ENOSYS; | ||
| 985 | } | ||
| 986 | if (!(dev->dev_flags & DF_CONFIGURED)) { | ||
| 987 | pr_err("DIF protection format requires device to be configured\n"); | ||
| 988 | return -ENODEV; | ||
| 989 | } | ||
| 990 | if (dev->export_count) { | ||
| 991 | pr_err("dev[%p]: Unable to format SE Device PROT type while" | ||
| 992 | " export_count is %d\n", dev, dev->export_count); | ||
| 993 | return -EINVAL; | ||
| 994 | } | ||
| 995 | |||
| 996 | rc = dev->transport->format_prot(dev); | ||
| 997 | if (rc) | ||
| 998 | return rc; | ||
| 999 | |||
| 1000 | pr_debug("dev[%p]: SE Device Protection Format complete\n", dev); | ||
| 1001 | |||
| 1002 | return 0; | ||
| 1003 | } | ||
| 1004 | |||
| 921 | int se_dev_set_enforce_pr_isids(struct se_device *dev, int flag) | 1005 | int se_dev_set_enforce_pr_isids(struct se_device *dev, int flag) |
| 922 | { | 1006 | { |
| 923 | if ((flag != 0) && (flag != 1)) { | 1007 | if ((flag != 0) && (flag != 1)) { |
| @@ -1415,6 +1499,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) | |||
| 1415 | dev->dev_link_magic = SE_DEV_LINK_MAGIC; | 1499 | dev->dev_link_magic = SE_DEV_LINK_MAGIC; |
| 1416 | dev->se_hba = hba; | 1500 | dev->se_hba = hba; |
| 1417 | dev->transport = hba->transport; | 1501 | dev->transport = hba->transport; |
| 1502 | dev->prot_length = sizeof(struct se_dif_v1_tuple); | ||
| 1418 | 1503 | ||
| 1419 | INIT_LIST_HEAD(&dev->dev_list); | 1504 | INIT_LIST_HEAD(&dev->dev_list); |
| 1420 | INIT_LIST_HEAD(&dev->dev_sep_list); | 1505 | INIT_LIST_HEAD(&dev->dev_sep_list); |
| @@ -1457,6 +1542,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) | |||
| 1457 | dev->dev_attrib.emulate_tpws = DA_EMULATE_TPWS; | 1542 | dev->dev_attrib.emulate_tpws = DA_EMULATE_TPWS; |
| 1458 | dev->dev_attrib.emulate_caw = DA_EMULATE_CAW; | 1543 | dev->dev_attrib.emulate_caw = DA_EMULATE_CAW; |
| 1459 | dev->dev_attrib.emulate_3pc = DA_EMULATE_3PC; | 1544 | dev->dev_attrib.emulate_3pc = DA_EMULATE_3PC; |
| 1545 | dev->dev_attrib.pi_prot_type = TARGET_DIF_TYPE0_PROT; | ||
| 1460 | dev->dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS; | 1546 | dev->dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS; |
| 1461 | dev->dev_attrib.is_nonrot = DA_IS_NONROT; | 1547 | dev->dev_attrib.is_nonrot = DA_IS_NONROT; |
| 1462 | dev->dev_attrib.emulate_rest_reord = DA_EMULATE_REST_REORD; | 1548 | dev->dev_attrib.emulate_rest_reord = DA_EMULATE_REST_REORD; |
| @@ -1589,6 +1675,9 @@ void target_free_device(struct se_device *dev) | |||
| 1589 | core_scsi3_free_all_registrations(dev); | 1675 | core_scsi3_free_all_registrations(dev); |
| 1590 | se_release_vpd_for_dev(dev); | 1676 | se_release_vpd_for_dev(dev); |
| 1591 | 1677 | ||
| 1678 | if (dev->transport->free_prot) | ||
| 1679 | dev->transport->free_prot(dev); | ||
| 1680 | |||
| 1592 | dev->transport->free_device(dev); | 1681 | dev->transport->free_device(dev); |
| 1593 | } | 1682 | } |
| 1594 | 1683 | ||
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index 1e27614e6bcc..de9cab708f45 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h | |||
| @@ -35,6 +35,8 @@ int se_dev_set_emulate_tpu(struct se_device *, int); | |||
| 35 | int se_dev_set_emulate_tpws(struct se_device *, int); | 35 | int se_dev_set_emulate_tpws(struct se_device *, int); |
| 36 | int se_dev_set_emulate_caw(struct se_device *, int); | 36 | int se_dev_set_emulate_caw(struct se_device *, int); |
| 37 | int se_dev_set_emulate_3pc(struct se_device *, int); | 37 | int se_dev_set_emulate_3pc(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); | ||
| 38 | int se_dev_set_enforce_pr_isids(struct se_device *, int); | 40 | int se_dev_set_enforce_pr_isids(struct se_device *, int); |
| 39 | int se_dev_set_is_nonrot(struct se_device *, int); | 41 | int se_dev_set_is_nonrot(struct se_device *, int); |
| 40 | int se_dev_set_emulate_rest_reord(struct se_device *dev, int); | 42 | int se_dev_set_emulate_rest_reord(struct se_device *dev, int); |
