diff options
author | Nicholas Bellinger <nab@daterainc.com> | 2013-08-25 18:44:03 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-09-09 17:29:30 -0400 |
commit | 200939940e040fa11609956a09c78a5782310c61 (patch) | |
tree | 5ee5aa0fcb81e24099baab8f16af0fb7405a0de2 | |
parent | 64577407085b7b117971f2bf35b0ef3ccd9c89f1 (diff) |
target: Refactor transport_generic_get_mem to target_alloc_sgl
This patch refactors transport_generic_get_mem() to target_alloc_sgl()
for accepting **sgl, *nents, length and zero_page as function parameters
in order to be used for both se_cmd->t_data_sg + se_cmd->t_bidi_data_sg
allocations.
Reported-by: Christoph Hellwig <hch@lst.de>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.de>
Cc: Martin Petersen <martin.petersen@oracle.com>
Cc: Chris Mason <chris.mason@fusionio.com>
Cc: James Bottomley <JBottomley@Parallels.com>
Cc: Nicholas Bellinger <nab@linux-iscsi.org>
Signed-off-by: Nicholas Bellinger <nab@daterainc.com>
-rw-r--r-- | drivers/target/target_core_transport.c | 35 |
1 files changed, 18 insertions, 17 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 781859e9d517..607bc3d2bb40 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -67,7 +67,6 @@ struct kmem_cache *t10_alua_tg_pt_gp_mem_cache; | |||
67 | static void transport_complete_task_attr(struct se_cmd *cmd); | 67 | static void transport_complete_task_attr(struct se_cmd *cmd); |
68 | static void transport_handle_queue_full(struct se_cmd *cmd, | 68 | static void transport_handle_queue_full(struct se_cmd *cmd, |
69 | struct se_device *dev); | 69 | struct se_device *dev); |
70 | static int transport_generic_get_mem(struct se_cmd *cmd); | ||
71 | static int transport_put_cmd(struct se_cmd *cmd); | 70 | static int transport_put_cmd(struct se_cmd *cmd); |
72 | static void target_complete_ok_work(struct work_struct *work); | 71 | static void target_complete_ok_work(struct work_struct *work); |
73 | 72 | ||
@@ -2092,23 +2091,21 @@ void transport_kunmap_data_sg(struct se_cmd *cmd) | |||
2092 | EXPORT_SYMBOL(transport_kunmap_data_sg); | 2091 | EXPORT_SYMBOL(transport_kunmap_data_sg); |
2093 | 2092 | ||
2094 | static int | 2093 | static int |
2095 | transport_generic_get_mem(struct se_cmd *cmd) | 2094 | target_alloc_sgl(struct scatterlist **sgl, unsigned int *nents, u32 length, |
2095 | bool zero_page) | ||
2096 | { | 2096 | { |
2097 | u32 length = cmd->data_length; | 2097 | struct scatterlist *sg; |
2098 | unsigned int nents; | ||
2099 | struct page *page; | 2098 | struct page *page; |
2100 | gfp_t zero_flag; | 2099 | gfp_t zero_flag = (zero_page) ? __GFP_ZERO : 0; |
2100 | unsigned int nent; | ||
2101 | int i = 0; | 2101 | int i = 0; |
2102 | 2102 | ||
2103 | nents = DIV_ROUND_UP(length, PAGE_SIZE); | 2103 | nent = DIV_ROUND_UP(length, PAGE_SIZE); |
2104 | cmd->t_data_sg = kmalloc(sizeof(struct scatterlist) * nents, GFP_KERNEL); | 2104 | sg = kmalloc(sizeof(struct scatterlist) * nent, GFP_KERNEL); |
2105 | if (!cmd->t_data_sg) | 2105 | if (!sg) |
2106 | return -ENOMEM; | 2106 | return -ENOMEM; |
2107 | 2107 | ||
2108 | cmd->t_data_nents = nents; | 2108 | sg_init_table(sg, nent); |
2109 | sg_init_table(cmd->t_data_sg, nents); | ||
2110 | |||
2111 | zero_flag = cmd->se_cmd_flags & SCF_SCSI_DATA_CDB ? 0 : __GFP_ZERO; | ||
2112 | 2109 | ||
2113 | while (length) { | 2110 | while (length) { |
2114 | u32 page_len = min_t(u32, length, PAGE_SIZE); | 2111 | u32 page_len = min_t(u32, length, PAGE_SIZE); |
@@ -2116,19 +2113,20 @@ transport_generic_get_mem(struct se_cmd *cmd) | |||
2116 | if (!page) | 2113 | if (!page) |
2117 | goto out; | 2114 | goto out; |
2118 | 2115 | ||
2119 | sg_set_page(&cmd->t_data_sg[i], page, page_len, 0); | 2116 | sg_set_page(&sg[i], page, page_len, 0); |
2120 | length -= page_len; | 2117 | length -= page_len; |
2121 | i++; | 2118 | i++; |
2122 | } | 2119 | } |
2120 | *sgl = sg; | ||
2121 | *nents = nent; | ||
2123 | return 0; | 2122 | return 0; |
2124 | 2123 | ||
2125 | out: | 2124 | out: |
2126 | while (i > 0) { | 2125 | while (i > 0) { |
2127 | i--; | 2126 | i--; |
2128 | __free_page(sg_page(&cmd->t_data_sg[i])); | 2127 | __free_page(sg_page(&sg[i])); |
2129 | } | 2128 | } |
2130 | kfree(cmd->t_data_sg); | 2129 | kfree(sg); |
2131 | cmd->t_data_sg = NULL; | ||
2132 | return -ENOMEM; | 2130 | return -ENOMEM; |
2133 | } | 2131 | } |
2134 | 2132 | ||
@@ -2149,7 +2147,10 @@ transport_generic_new_cmd(struct se_cmd *cmd) | |||
2149 | */ | 2147 | */ |
2150 | if (!(cmd->se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC) && | 2148 | if (!(cmd->se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC) && |
2151 | cmd->data_length) { | 2149 | cmd->data_length) { |
2152 | ret = transport_generic_get_mem(cmd); | 2150 | bool zero_flag = !(cmd->se_cmd_flags & SCF_SCSI_DATA_CDB); |
2151 | |||
2152 | ret = target_alloc_sgl(&cmd->t_data_sg, &cmd->t_data_nents, | ||
2153 | cmd->data_length, zero_flag); | ||
2153 | if (ret < 0) | 2154 | if (ret < 0) |
2154 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 2155 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2155 | } | 2156 | } |