aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target/tcm_fc
diff options
context:
space:
mode:
authorAndy Grover <agrover@redhat.com>2011-07-20 15:28:46 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2011-07-22 05:37:48 -0400
commitec98f7825c6eaa4a9afb0eb518826efc8a2ed4a2 (patch)
treeb4ccee24db5d7d54ccfa5e3be2441d3a4e37f295 /drivers/target/tcm_fc
parent3a86720567fd92819b449df10db85a2f73447d87 (diff)
target: Eliminate usage of struct se_mem
Both backstores and fabrics use arrays of struct scatterlist to describe data buffers. However TCM used struct se_mems, basically a linked list of scatterlist entries. We are able to simplify the code by eliminating this intermediate data structure and just using struct scatterlist[] throughout. Also, moved attachment of task to cmd out of transport_generic_get_task and into allocate_control_task and allocate_data_tasks. The reasoning is that it's nonintuitive that get_task should automatically add it to the cmd's task list -- it should just return an allocated, initialized task. That's all it should do, based on the function's name, so either the function shouldn't do it, or the name should change to encapsulate the entire essence of what it does. (nab: Fix compile warnings in tcm_fc, and make transport_kmap_first_data_page honor sg->offset for SGLs from contigious memory with TCM_Loop, and fix control se_cmd descriptor memory leak) Signed-off-by: Andy Grover <agrover@redhat.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target/tcm_fc')
-rw-r--r--drivers/target/tcm_fc/tfc_cmd.c25
-rw-r--r--drivers/target/tcm_fc/tfc_io.c58
2 files changed, 39 insertions, 44 deletions
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c
index 1017f56bbbcc..9365e53947ad 100644
--- a/drivers/target/tcm_fc/tfc_cmd.c
+++ b/drivers/target/tcm_fc/tfc_cmd.c
@@ -59,7 +59,8 @@ void ft_dump_cmd(struct ft_cmd *cmd, const char *caller)
59 struct fc_exch *ep; 59 struct fc_exch *ep;
60 struct fc_seq *sp; 60 struct fc_seq *sp;
61 struct se_cmd *se_cmd; 61 struct se_cmd *se_cmd;
62 struct se_mem *mem; 62 struct scatterlist *sg;
63 int count;
63 64
64 if (!(ft_debug_logging & FT_DEBUG_IO)) 65 if (!(ft_debug_logging & FT_DEBUG_IO))
65 return; 66 return;
@@ -71,15 +72,16 @@ void ft_dump_cmd(struct ft_cmd *cmd, const char *caller)
71 caller, cmd, cmd->cdb); 72 caller, cmd, cmd->cdb);
72 printk(KERN_INFO "%s: cmd %p lun %d\n", caller, cmd, cmd->lun); 73 printk(KERN_INFO "%s: cmd %p lun %d\n", caller, cmd, cmd->lun);
73 74
74 printk(KERN_INFO "%s: cmd %p se_num %u len %u se_cmd_flags <0x%x>\n", 75 printk(KERN_INFO "%s: cmd %p data_nents %u len %u se_cmd_flags <0x%x>\n",
75 caller, cmd, se_cmd->t_tasks_se_num, 76 caller, cmd, se_cmd->t_data_nents,
76 se_cmd->data_length, se_cmd->se_cmd_flags); 77 se_cmd->data_length, se_cmd->se_cmd_flags);
77 78
78 list_for_each_entry(mem, &se_cmd->t_mem_list, se_list) 79 for_each_sg(se_cmd->t_data_sg, sg, se_cmd->t_data_nents, count)
79 printk(KERN_INFO "%s: cmd %p mem %p page %p " 80 printk(KERN_INFO "%s: cmd %p sg %p page %p "
80 "len 0x%x off 0x%x\n", 81 "len 0x%x off 0x%x\n",
81 caller, cmd, mem, 82 caller, cmd, sg,
82 mem->se_page, mem->se_len, mem->se_off); 83 sg_page(sg), sg->length, sg->offset);
84
83 sp = cmd->seq; 85 sp = cmd->seq;
84 if (sp) { 86 if (sp) {
85 ep = fc_seq_exch(sp); 87 ep = fc_seq_exch(sp);
@@ -256,10 +258,9 @@ int ft_write_pending(struct se_cmd *se_cmd)
256 (fh->fh_r_ctl == FC_RCTL_DD_DATA_DESC)) { 258 (fh->fh_r_ctl == FC_RCTL_DD_DATA_DESC)) {
257 if (se_cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) { 259 if (se_cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) {
258 /* 260 /*
259 * Map se_mem list to scatterlist, so that 261 * cmd may have been broken up into multiple
260 * DDP can be setup. DDP setup function require 262 * tasks. Link their sgs together so we can
261 * scatterlist. se_mem_list is internal to 263 * operate on them all at once.
262 * TCM/LIO target
263 */ 264 */
264 transport_do_task_sg_chain(se_cmd); 265 transport_do_task_sg_chain(se_cmd);
265 cmd->sg = se_cmd->t_tasks_sg_chained; 266 cmd->sg = se_cmd->t_tasks_sg_chained;
diff --git a/drivers/target/tcm_fc/tfc_io.c b/drivers/target/tcm_fc/tfc_io.c
index 837660728563..3563a9029c4a 100644
--- a/drivers/target/tcm_fc/tfc_io.c
+++ b/drivers/target/tcm_fc/tfc_io.c
@@ -68,17 +68,17 @@ int ft_queue_data_in(struct se_cmd *se_cmd)
68 struct fc_frame *fp = NULL; 68 struct fc_frame *fp = NULL;
69 struct fc_exch *ep; 69 struct fc_exch *ep;
70 struct fc_lport *lport; 70 struct fc_lport *lport;
71 struct se_mem *mem; 71 struct scatterlist *sg = NULL;
72 size_t remaining; 72 size_t remaining;
73 u32 f_ctl = FC_FC_EX_CTX | FC_FC_REL_OFF; 73 u32 f_ctl = FC_FC_EX_CTX | FC_FC_REL_OFF;
74 u32 mem_off; 74 u32 mem_off = 0;
75 u32 fh_off = 0; 75 u32 fh_off = 0;
76 u32 frame_off = 0; 76 u32 frame_off = 0;
77 size_t frame_len = 0; 77 size_t frame_len = 0;
78 size_t mem_len; 78 size_t mem_len = 0;
79 size_t tlen; 79 size_t tlen;
80 size_t off_in_page; 80 size_t off_in_page;
81 struct page *page; 81 struct page *page = NULL;
82 int use_sg; 82 int use_sg;
83 int error; 83 int error;
84 void *page_addr; 84 void *page_addr;
@@ -94,13 +94,12 @@ int ft_queue_data_in(struct se_cmd *se_cmd)
94 /* 94 /*
95 * Setup to use first mem list entry, unless no data. 95 * Setup to use first mem list entry, unless no data.
96 */ 96 */
97 BUG_ON(remaining && list_empty(&se_cmd->t_mem_list)); 97 BUG_ON(remaining && !se_cmd->t_data_sg);
98 if (remaining) { 98 if (remaining) {
99 mem = list_first_entry(&se_cmd->t_mem_list, 99 sg = se_cmd->t_data_sg;
100 struct se_mem, se_list); 100 mem_len = sg->length;
101 mem_len = mem->se_len; 101 mem_off = sg->offset;
102 mem_off = mem->se_off; 102 page = sg_page(sg);
103 page = mem->se_page;
104 } 103 }
105 104
106 /* no scatter/gather in skb for odd word length due to fc_seq_send() */ 105 /* no scatter/gather in skb for odd word length due to fc_seq_send() */
@@ -108,12 +107,10 @@ int ft_queue_data_in(struct se_cmd *se_cmd)
108 107
109 while (remaining) { 108 while (remaining) {
110 if (!mem_len) { 109 if (!mem_len) {
111 BUG_ON(!mem); 110 sg = sg_next(sg);
112 mem = list_entry(mem->se_list.next, 111 mem_len = min((size_t)sg->length, remaining);
113 struct se_mem, se_list); 112 mem_off = sg->offset;
114 mem_len = min((size_t)mem->se_len, remaining); 113 page = sg_page(sg);
115 mem_off = mem->se_off;
116 page = mem->se_page;
117 } 114 }
118 if (!frame_len) { 115 if (!frame_len) {
119 /* 116 /*
@@ -200,13 +197,13 @@ void ft_recv_write_data(struct ft_cmd *cmd, struct fc_frame *fp)
200 struct fc_exch *ep; 197 struct fc_exch *ep;
201 struct fc_lport *lport; 198 struct fc_lport *lport;
202 struct fc_frame_header *fh; 199 struct fc_frame_header *fh;
203 struct se_mem *mem; 200 struct scatterlist *sg = NULL;
204 u32 mem_off; 201 u32 mem_off = 0;
205 u32 rel_off; 202 u32 rel_off;
206 size_t frame_len; 203 size_t frame_len;
207 size_t mem_len; 204 size_t mem_len = 0;
208 size_t tlen; 205 size_t tlen;
209 struct page *page; 206 struct page *page = NULL;
210 void *page_addr; 207 void *page_addr;
211 void *from; 208 void *from;
212 void *to; 209 void *to;
@@ -288,23 +285,20 @@ void ft_recv_write_data(struct ft_cmd *cmd, struct fc_frame *fp)
288 /* 285 /*
289 * Setup to use first mem list entry, unless no data. 286 * Setup to use first mem list entry, unless no data.
290 */ 287 */
291 BUG_ON(frame_len && list_empty(&se_cmd->t_mem_list)); 288 BUG_ON(frame_len && !se_cmd->t_data_sg);
292 if (frame_len) { 289 if (frame_len) {
293 mem = list_first_entry(&se_cmd->t_mem_list, 290 sg = se_cmd->t_data_sg;
294 struct se_mem, se_list); 291 mem_len = sg->length;
295 mem_len = mem->se_len; 292 mem_off = sg->offset;
296 mem_off = mem->se_off; 293 page = sg_page(sg);
297 page = mem->se_page;
298 } 294 }
299 295
300 while (frame_len) { 296 while (frame_len) {
301 if (!mem_len) { 297 if (!mem_len) {
302 BUG_ON(!mem); 298 sg = sg_next(sg);
303 mem = list_entry(mem->se_list.next, 299 mem_len = sg->length;
304 struct se_mem, se_list); 300 mem_off = sg->offset;
305 mem_len = mem->se_len; 301 page = sg_page(sg);
306 mem_off = mem->se_off;
307 page = mem->se_page;
308 } 302 }
309 if (rel_off >= mem_len) { 303 if (rel_off >= mem_len) {
310 rel_off -= mem_len; 304 rel_off -= mem_len;