Commit 47e459e6 authored by Nicholas Bellinger's avatar Nicholas Bellinger Committed by Nicholas Bellinger

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: default avatarNicholas Bellinger <nab@daterainc.com>
parent 8cefe07b
...@@ -1991,10 +1991,29 @@ static inline void transport_free_sgl(struct scatterlist *sgl, int nents) ...@@ -1991,10 +1991,29 @@ static inline void transport_free_sgl(struct scatterlist *sgl, int nents)
kfree(sgl); kfree(sgl);
} }
static inline void transport_reset_sgl_orig(struct se_cmd *cmd)
{
/*
* Check for saved t_data_sg that may be used for COMPARE_AND_WRITE
* emulation, and free + reset pointers if necessary..
*/
if (!cmd->t_data_sg_orig)
return;
kfree(cmd->t_data_sg);
cmd->t_data_sg = cmd->t_data_sg_orig;
cmd->t_data_sg_orig = NULL;
cmd->t_data_nents = cmd->t_data_nents_orig;
cmd->t_data_nents_orig = 0;
}
static inline void transport_free_pages(struct se_cmd *cmd) static inline void transport_free_pages(struct se_cmd *cmd)
{ {
if (cmd->se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC) if (cmd->se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC) {
transport_reset_sgl_orig(cmd);
return; return;
}
transport_reset_sgl_orig(cmd);
transport_free_sgl(cmd->t_data_sg, cmd->t_data_nents); transport_free_sgl(cmd->t_data_sg, cmd->t_data_nents);
cmd->t_data_sg = NULL; cmd->t_data_sg = NULL;
......
...@@ -478,7 +478,9 @@ struct se_cmd { ...@@ -478,7 +478,9 @@ struct se_cmd {
struct work_struct work; struct work_struct work;
struct scatterlist *t_data_sg; struct scatterlist *t_data_sg;
struct scatterlist *t_data_sg_orig;
unsigned int t_data_nents; unsigned int t_data_nents;
unsigned int t_data_nents_orig;
void *t_data_vmap; void *t_data_vmap;
struct scatterlist *t_bidi_data_sg; struct scatterlist *t_bidi_data_sg;
unsigned int t_bidi_data_nents; unsigned int t_bidi_data_nents;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment