aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@daterainc.com>2013-08-20 13:45:16 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2013-09-09 17:29:33 -0400
commit47e459e622f07c2564e6be8412d75389d2a807b8 (patch)
tree685709343f949e5cc858e8657dba5d2bd79d91ca
parent8cefe07b5e9c2b0212ad6809a219e4489807a746 (diff)
target: Add transport_reset_sgl_orig() for COMPARE_AND_WRITE
After COMPARE_AND_WRITE completes it's comparision, the WRITE payload SGLs head expect to be updated to point from the verify instance of user data, to the write instance of user data. So for this special case, add transport_reset_sgl_orig() usage within transport_free_pages() and add se_cmd->t_data_[sg,nents]_orig members to save the original assignments. 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.c21
-rw-r--r--include/target/target_core_base.h2
2 files changed, 22 insertions, 1 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index c974e1373c77..87d64add7874 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1991,10 +1991,29 @@ static inline void transport_free_sgl(struct scatterlist *sgl, int nents)
1991 kfree(sgl); 1991 kfree(sgl);
1992} 1992}
1993 1993
1994static inline void transport_reset_sgl_orig(struct se_cmd *cmd)
1995{
1996 /*
1997 * Check for saved t_data_sg that may be used for COMPARE_AND_WRITE
1998 * emulation, and free + reset pointers if necessary..
1999 */
2000 if (!cmd->t_data_sg_orig)
2001 return;
2002
2003 kfree(cmd->t_data_sg);
2004 cmd->t_data_sg = cmd->t_data_sg_orig;
2005 cmd->t_data_sg_orig = NULL;
2006 cmd->t_data_nents = cmd->t_data_nents_orig;
2007 cmd->t_data_nents_orig = 0;
2008}
2009
1994static inline void transport_free_pages(struct se_cmd *cmd) 2010static inline void transport_free_pages(struct se_cmd *cmd)
1995{ 2011{
1996 if (cmd->se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC) 2012 if (cmd->se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC) {
2013 transport_reset_sgl_orig(cmd);
1997 return; 2014 return;
2015 }
2016 transport_reset_sgl_orig(cmd);
1998 2017
1999 transport_free_sgl(cmd->t_data_sg, cmd->t_data_nents); 2018 transport_free_sgl(cmd->t_data_sg, cmd->t_data_nents);
2000 cmd->t_data_sg = NULL; 2019 cmd->t_data_sg = NULL;
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 4a26a18a24d6..7fdb3fae2961 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -478,7 +478,9 @@ struct se_cmd {
478 struct work_struct work; 478 struct work_struct work;
479 479
480 struct scatterlist *t_data_sg; 480 struct scatterlist *t_data_sg;
481 struct scatterlist *t_data_sg_orig;
481 unsigned int t_data_nents; 482 unsigned int t_data_nents;
483 unsigned int t_data_nents_orig;
482 void *t_data_vmap; 484 void *t_data_vmap;
483 struct scatterlist *t_bidi_data_sg; 485 struct scatterlist *t_bidi_data_sg;
484 unsigned int t_bidi_data_nents; 486 unsigned int t_bidi_data_nents;