diff options
author | Hannes Reinecke <hare@suse.de> | 2013-12-17 03:18:44 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-12-17 13:33:58 -0500 |
commit | 1e0b9403bd2e77006ae8dcdf279c0f30c7efc258 (patch) | |
tree | 83958d62dfff14470cadaa53aef2d12a1ed52712 | |
parent | bb91c1a087ed29ceb5b25b9c210c6665e13c36eb (diff) |
target_core_alua: Allocate ALUA metadata on demand
We should only allocate ALUA metadata if we're actually going
to write them.
Signed-off-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r-- | drivers/target/target_core_alua.c | 70 | ||||
-rw-r--r-- | drivers/target/target_core_alua.h | 3 | ||||
-rw-r--r-- | include/target/target_core_base.h | 3 |
3 files changed, 34 insertions, 42 deletions
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 292ecce98d1f..738244bceb1b 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c | |||
@@ -770,16 +770,22 @@ static int core_alua_write_tpg_metadata( | |||
770 | */ | 770 | */ |
771 | static int core_alua_update_tpg_primary_metadata( | 771 | static int core_alua_update_tpg_primary_metadata( |
772 | struct t10_alua_tg_pt_gp *tg_pt_gp, | 772 | struct t10_alua_tg_pt_gp *tg_pt_gp, |
773 | int primary_state, | 773 | int primary_state) |
774 | unsigned char *md_buf) | ||
775 | { | 774 | { |
775 | unsigned char *md_buf; | ||
776 | struct t10_wwn *wwn = &tg_pt_gp->tg_pt_gp_dev->t10_wwn; | 776 | struct t10_wwn *wwn = &tg_pt_gp->tg_pt_gp_dev->t10_wwn; |
777 | char path[ALUA_METADATA_PATH_LEN]; | 777 | char path[ALUA_METADATA_PATH_LEN]; |
778 | int len; | 778 | int len, rc; |
779 | |||
780 | md_buf = kzalloc(ALUA_MD_BUF_LEN, GFP_KERNEL); | ||
781 | if (!md_buf) { | ||
782 | pr_err("Unable to allocate buf for ALUA metadata\n"); | ||
783 | return -ENOMEM; | ||
784 | } | ||
779 | 785 | ||
780 | memset(path, 0, ALUA_METADATA_PATH_LEN); | 786 | memset(path, 0, ALUA_METADATA_PATH_LEN); |
781 | 787 | ||
782 | len = snprintf(md_buf, tg_pt_gp->tg_pt_gp_md_buf_len, | 788 | len = snprintf(md_buf, ALUA_MD_BUF_LEN, |
783 | "tg_pt_gp_id=%hu\n" | 789 | "tg_pt_gp_id=%hu\n" |
784 | "alua_access_state=0x%02x\n" | 790 | "alua_access_state=0x%02x\n" |
785 | "alua_access_status=0x%02x\n", | 791 | "alua_access_status=0x%02x\n", |
@@ -790,14 +796,15 @@ static int core_alua_update_tpg_primary_metadata( | |||
790 | "/var/target/alua/tpgs_%s/%s", &wwn->unit_serial[0], | 796 | "/var/target/alua/tpgs_%s/%s", &wwn->unit_serial[0], |
791 | config_item_name(&tg_pt_gp->tg_pt_gp_group.cg_item)); | 797 | config_item_name(&tg_pt_gp->tg_pt_gp_group.cg_item)); |
792 | 798 | ||
793 | return core_alua_write_tpg_metadata(path, md_buf, len); | 799 | rc = core_alua_write_tpg_metadata(path, md_buf, len); |
800 | kfree(md_buf); | ||
801 | return rc; | ||
794 | } | 802 | } |
795 | 803 | ||
796 | static int core_alua_do_transition_tg_pt( | 804 | static int core_alua_do_transition_tg_pt( |
797 | struct t10_alua_tg_pt_gp *tg_pt_gp, | 805 | struct t10_alua_tg_pt_gp *tg_pt_gp, |
798 | struct se_port *l_port, | 806 | struct se_port *l_port, |
799 | struct se_node_acl *nacl, | 807 | struct se_node_acl *nacl, |
800 | unsigned char *md_buf, | ||
801 | int new_state, | 808 | int new_state, |
802 | int explicit) | 809 | int explicit) |
803 | { | 810 | { |
@@ -885,8 +892,7 @@ static int core_alua_do_transition_tg_pt( | |||
885 | */ | 892 | */ |
886 | if (tg_pt_gp->tg_pt_gp_write_metadata) { | 893 | if (tg_pt_gp->tg_pt_gp_write_metadata) { |
887 | mutex_lock(&tg_pt_gp->tg_pt_gp_md_mutex); | 894 | mutex_lock(&tg_pt_gp->tg_pt_gp_md_mutex); |
888 | core_alua_update_tpg_primary_metadata(tg_pt_gp, | 895 | core_alua_update_tpg_primary_metadata(tg_pt_gp, new_state); |
889 | new_state, md_buf); | ||
890 | mutex_unlock(&tg_pt_gp->tg_pt_gp_md_mutex); | 896 | mutex_unlock(&tg_pt_gp->tg_pt_gp_md_mutex); |
891 | } | 897 | } |
892 | /* | 898 | /* |
@@ -917,19 +923,12 @@ int core_alua_do_port_transition( | |||
917 | struct t10_alua_lu_gp *lu_gp; | 923 | struct t10_alua_lu_gp *lu_gp; |
918 | struct t10_alua_lu_gp_member *lu_gp_mem, *local_lu_gp_mem; | 924 | struct t10_alua_lu_gp_member *lu_gp_mem, *local_lu_gp_mem; |
919 | struct t10_alua_tg_pt_gp *tg_pt_gp; | 925 | struct t10_alua_tg_pt_gp *tg_pt_gp; |
920 | unsigned char *md_buf; | ||
921 | int primary, valid_states; | 926 | int primary, valid_states; |
922 | 927 | ||
923 | valid_states = l_tg_pt_gp->tg_pt_gp_alua_supported_states; | 928 | valid_states = l_tg_pt_gp->tg_pt_gp_alua_supported_states; |
924 | if (core_alua_check_transition(new_state, valid_states, &primary) != 0) | 929 | if (core_alua_check_transition(new_state, valid_states, &primary) != 0) |
925 | return -EINVAL; | 930 | return -EINVAL; |
926 | 931 | ||
927 | md_buf = kzalloc(l_tg_pt_gp->tg_pt_gp_md_buf_len, GFP_KERNEL); | ||
928 | if (!md_buf) { | ||
929 | pr_err("Unable to allocate buf for ALUA metadata\n"); | ||
930 | return -ENOMEM; | ||
931 | } | ||
932 | |||
933 | local_lu_gp_mem = l_dev->dev_alua_lu_gp_mem; | 932 | local_lu_gp_mem = l_dev->dev_alua_lu_gp_mem; |
934 | spin_lock(&local_lu_gp_mem->lu_gp_mem_lock); | 933 | spin_lock(&local_lu_gp_mem->lu_gp_mem_lock); |
935 | lu_gp = local_lu_gp_mem->lu_gp; | 934 | lu_gp = local_lu_gp_mem->lu_gp; |
@@ -947,10 +946,9 @@ int core_alua_do_port_transition( | |||
947 | * success. | 946 | * success. |
948 | */ | 947 | */ |
949 | core_alua_do_transition_tg_pt(l_tg_pt_gp, l_port, l_nacl, | 948 | core_alua_do_transition_tg_pt(l_tg_pt_gp, l_port, l_nacl, |
950 | md_buf, new_state, explicit); | 949 | new_state, explicit); |
951 | atomic_dec(&lu_gp->lu_gp_ref_cnt); | 950 | atomic_dec(&lu_gp->lu_gp_ref_cnt); |
952 | smp_mb__after_atomic_dec(); | 951 | smp_mb__after_atomic_dec(); |
953 | kfree(md_buf); | ||
954 | return 0; | 952 | return 0; |
955 | } | 953 | } |
956 | /* | 954 | /* |
@@ -1000,7 +998,7 @@ int core_alua_do_port_transition( | |||
1000 | * success. | 998 | * success. |
1001 | */ | 999 | */ |
1002 | core_alua_do_transition_tg_pt(tg_pt_gp, port, | 1000 | core_alua_do_transition_tg_pt(tg_pt_gp, port, |
1003 | nacl, md_buf, new_state, explicit); | 1001 | nacl, new_state, explicit); |
1004 | 1002 | ||
1005 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); | 1003 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
1006 | atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt); | 1004 | atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt); |
@@ -1022,7 +1020,6 @@ int core_alua_do_port_transition( | |||
1022 | 1020 | ||
1023 | atomic_dec(&lu_gp->lu_gp_ref_cnt); | 1021 | atomic_dec(&lu_gp->lu_gp_ref_cnt); |
1024 | smp_mb__after_atomic_dec(); | 1022 | smp_mb__after_atomic_dec(); |
1025 | kfree(md_buf); | ||
1026 | return 0; | 1023 | return 0; |
1027 | } | 1024 | } |
1028 | 1025 | ||
@@ -1031,13 +1028,18 @@ int core_alua_do_port_transition( | |||
1031 | */ | 1028 | */ |
1032 | static int core_alua_update_tpg_secondary_metadata( | 1029 | static int core_alua_update_tpg_secondary_metadata( |
1033 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem, | 1030 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem, |
1034 | struct se_port *port, | 1031 | struct se_port *port) |
1035 | unsigned char *md_buf, | ||
1036 | u32 md_buf_len) | ||
1037 | { | 1032 | { |
1033 | unsigned char *md_buf; | ||
1038 | struct se_portal_group *se_tpg = port->sep_tpg; | 1034 | struct se_portal_group *se_tpg = port->sep_tpg; |
1039 | char path[ALUA_METADATA_PATH_LEN], wwn[ALUA_SECONDARY_METADATA_WWN_LEN]; | 1035 | char path[ALUA_METADATA_PATH_LEN], wwn[ALUA_SECONDARY_METADATA_WWN_LEN]; |
1040 | int len; | 1036 | int len, rc; |
1037 | |||
1038 | md_buf = kzalloc(ALUA_MD_BUF_LEN, GFP_KERNEL); | ||
1039 | if (!md_buf) { | ||
1040 | pr_err("Unable to allocate buf for ALUA metadata\n"); | ||
1041 | return -ENOMEM; | ||
1042 | } | ||
1041 | 1043 | ||
1042 | memset(path, 0, ALUA_METADATA_PATH_LEN); | 1044 | memset(path, 0, ALUA_METADATA_PATH_LEN); |
1043 | memset(wwn, 0, ALUA_SECONDARY_METADATA_WWN_LEN); | 1045 | memset(wwn, 0, ALUA_SECONDARY_METADATA_WWN_LEN); |
@@ -1049,7 +1051,7 @@ static int core_alua_update_tpg_secondary_metadata( | |||
1049 | snprintf(wwn+len, ALUA_SECONDARY_METADATA_WWN_LEN-len, "+%hu", | 1051 | snprintf(wwn+len, ALUA_SECONDARY_METADATA_WWN_LEN-len, "+%hu", |
1050 | se_tpg->se_tpg_tfo->tpg_get_tag(se_tpg)); | 1052 | se_tpg->se_tpg_tfo->tpg_get_tag(se_tpg)); |
1051 | 1053 | ||
1052 | len = snprintf(md_buf, md_buf_len, "alua_tg_pt_offline=%d\n" | 1054 | len = snprintf(md_buf, ALUA_MD_BUF_LEN, "alua_tg_pt_offline=%d\n" |
1053 | "alua_tg_pt_status=0x%02x\n", | 1055 | "alua_tg_pt_status=0x%02x\n", |
1054 | atomic_read(&port->sep_tg_pt_secondary_offline), | 1056 | atomic_read(&port->sep_tg_pt_secondary_offline), |
1055 | port->sep_tg_pt_secondary_stat); | 1057 | port->sep_tg_pt_secondary_stat); |
@@ -1058,7 +1060,10 @@ static int core_alua_update_tpg_secondary_metadata( | |||
1058 | se_tpg->se_tpg_tfo->get_fabric_name(), wwn, | 1060 | se_tpg->se_tpg_tfo->get_fabric_name(), wwn, |
1059 | port->sep_lun->unpacked_lun); | 1061 | port->sep_lun->unpacked_lun); |
1060 | 1062 | ||
1061 | return core_alua_write_tpg_metadata(path, md_buf, len); | 1063 | rc = core_alua_write_tpg_metadata(path, md_buf, len); |
1064 | kfree(md_buf); | ||
1065 | |||
1066 | return rc; | ||
1062 | } | 1067 | } |
1063 | 1068 | ||
1064 | static int core_alua_set_tg_pt_secondary_state( | 1069 | static int core_alua_set_tg_pt_secondary_state( |
@@ -1068,8 +1073,6 @@ static int core_alua_set_tg_pt_secondary_state( | |||
1068 | int offline) | 1073 | int offline) |
1069 | { | 1074 | { |
1070 | struct t10_alua_tg_pt_gp *tg_pt_gp; | 1075 | struct t10_alua_tg_pt_gp *tg_pt_gp; |
1071 | unsigned char *md_buf; | ||
1072 | u32 md_buf_len; | ||
1073 | int trans_delay_msecs; | 1076 | int trans_delay_msecs; |
1074 | 1077 | ||
1075 | spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); | 1078 | spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); |
@@ -1090,7 +1093,6 @@ static int core_alua_set_tg_pt_secondary_state( | |||
1090 | else | 1093 | else |
1091 | atomic_set(&port->sep_tg_pt_secondary_offline, 0); | 1094 | atomic_set(&port->sep_tg_pt_secondary_offline, 0); |
1092 | 1095 | ||
1093 | md_buf_len = tg_pt_gp->tg_pt_gp_md_buf_len; | ||
1094 | port->sep_tg_pt_secondary_stat = (explicit) ? | 1096 | port->sep_tg_pt_secondary_stat = (explicit) ? |
1095 | ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG : | 1097 | ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG : |
1096 | ALUA_STATUS_ALTERED_BY_IMPLICIT_ALUA; | 1098 | ALUA_STATUS_ALTERED_BY_IMPLICIT_ALUA; |
@@ -1112,18 +1114,9 @@ static int core_alua_set_tg_pt_secondary_state( | |||
1112 | * secondary state and status | 1114 | * secondary state and status |
1113 | */ | 1115 | */ |
1114 | if (port->sep_tg_pt_secondary_write_md) { | 1116 | if (port->sep_tg_pt_secondary_write_md) { |
1115 | md_buf = kzalloc(md_buf_len, GFP_KERNEL); | ||
1116 | if (!md_buf) { | ||
1117 | pr_err("Unable to allocate md_buf for" | ||
1118 | " secondary ALUA access metadata\n"); | ||
1119 | return -ENOMEM; | ||
1120 | } | ||
1121 | mutex_lock(&port->sep_tg_pt_md_mutex); | 1117 | mutex_lock(&port->sep_tg_pt_md_mutex); |
1122 | core_alua_update_tpg_secondary_metadata(tg_pt_gp_mem, port, | 1118 | core_alua_update_tpg_secondary_metadata(tg_pt_gp_mem, port); |
1123 | md_buf, md_buf_len); | ||
1124 | mutex_unlock(&port->sep_tg_pt_md_mutex); | 1119 | mutex_unlock(&port->sep_tg_pt_md_mutex); |
1125 | |||
1126 | kfree(md_buf); | ||
1127 | } | 1120 | } |
1128 | 1121 | ||
1129 | return 0; | 1122 | return 0; |
@@ -1382,7 +1375,6 @@ struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(struct se_device *dev, | |||
1382 | spin_lock_init(&tg_pt_gp->tg_pt_gp_lock); | 1375 | spin_lock_init(&tg_pt_gp->tg_pt_gp_lock); |
1383 | atomic_set(&tg_pt_gp->tg_pt_gp_ref_cnt, 0); | 1376 | atomic_set(&tg_pt_gp->tg_pt_gp_ref_cnt, 0); |
1384 | tg_pt_gp->tg_pt_gp_dev = dev; | 1377 | tg_pt_gp->tg_pt_gp_dev = dev; |
1385 | tg_pt_gp->tg_pt_gp_md_buf_len = ALUA_MD_BUF_LEN; | ||
1386 | atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state, | 1378 | atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state, |
1387 | ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED); | 1379 | ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED); |
1388 | /* | 1380 | /* |
diff --git a/drivers/target/target_core_alua.h b/drivers/target/target_core_alua.h index 88e2e835f14a..1a152cd59471 100644 --- a/drivers/target/target_core_alua.h +++ b/drivers/target/target_core_alua.h | |||
@@ -78,6 +78,9 @@ | |||
78 | */ | 78 | */ |
79 | #define ALUA_SECONDARY_METADATA_WWN_LEN 256 | 79 | #define ALUA_SECONDARY_METADATA_WWN_LEN 256 |
80 | 80 | ||
81 | /* Used by core_alua_update_tpg_(primary,secondary)_metadata */ | ||
82 | #define ALUA_MD_BUF_LEN 1024 | ||
83 | |||
81 | extern struct kmem_cache *t10_alua_lu_gp_cache; | 84 | extern struct kmem_cache *t10_alua_lu_gp_cache; |
82 | extern struct kmem_cache *t10_alua_lu_gp_mem_cache; | 85 | extern struct kmem_cache *t10_alua_lu_gp_mem_cache; |
83 | extern struct kmem_cache *t10_alua_tg_pt_gp_cache; | 86 | extern struct kmem_cache *t10_alua_tg_pt_gp_cache; |
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index d6f96c735309..bf9a4d6c26da 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h | |||
@@ -291,9 +291,6 @@ struct t10_alua_tg_pt_gp { | |||
291 | int tg_pt_gp_implicit_trans_secs; | 291 | int tg_pt_gp_implicit_trans_secs; |
292 | int tg_pt_gp_pref; | 292 | int tg_pt_gp_pref; |
293 | int tg_pt_gp_write_metadata; | 293 | int tg_pt_gp_write_metadata; |
294 | /* Used by struct t10_alua_tg_pt_gp->tg_pt_gp_md_buf_len */ | ||
295 | #define ALUA_MD_BUF_LEN 1024 | ||
296 | u32 tg_pt_gp_md_buf_len; | ||
297 | u32 tg_pt_gp_members; | 294 | u32 tg_pt_gp_members; |
298 | atomic_t tg_pt_gp_alua_access_state; | 295 | atomic_t tg_pt_gp_alua_access_state; |
299 | atomic_t tg_pt_gp_ref_cnt; | 296 | atomic_t tg_pt_gp_ref_cnt; |