aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@daterainc.com>2013-08-25 18:44:03 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2013-09-09 17:29:30 -0400
commit200939940e040fa11609956a09c78a5782310c61 (patch)
tree5ee5aa0fcb81e24099baab8f16af0fb7405a0de2 /drivers/target
parent64577407085b7b117971f2bf35b0ef3ccd9c89f1 (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>
Diffstat (limited to 'drivers/target')
-rw-r--r--drivers/target/target_core_transport.c35
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;
67static void transport_complete_task_attr(struct se_cmd *cmd); 67static void transport_complete_task_attr(struct se_cmd *cmd);
68static void transport_handle_queue_full(struct se_cmd *cmd, 68static void transport_handle_queue_full(struct se_cmd *cmd,
69 struct se_device *dev); 69 struct se_device *dev);
70static int transport_generic_get_mem(struct se_cmd *cmd);
71static int transport_put_cmd(struct se_cmd *cmd); 70static int transport_put_cmd(struct se_cmd *cmd);
72static void target_complete_ok_work(struct work_struct *work); 71static void target_complete_ok_work(struct work_struct *work);
73 72
@@ -2092,23 +2091,21 @@ void transport_kunmap_data_sg(struct se_cmd *cmd)
2092EXPORT_SYMBOL(transport_kunmap_data_sg); 2091EXPORT_SYMBOL(transport_kunmap_data_sg);
2093 2092
2094static int 2093static int
2095transport_generic_get_mem(struct se_cmd *cmd) 2094target_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
2125out: 2124out:
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 }