Message ID | 1501342309-5433-1-git-send-email-varun@chelsio.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Sat, 2017-07-29 at 21:01 +0530, Varun Prakash wrote: > The current logic of calculating sg_nents can fail > if data_offset % PAGE_SIZE is not zero. > > For example - > PAGE_SIZE = 4096 > data_len = 3072 > data_offset = 3072 > > As per current logic > sg_nents = max(1UL, DIV_ROUND_UP(data_len, PAGE_SIZE)); > sg_nents = max(1UL, DIV_ROUND_UP(3072, 4096)); > sg_nents = 1 > > But as data_offset % PAGE_SIZE = 3072 we should skip 3072 bytes > skip = 3K > sg_nents = max(1UL, DIV_ROUND_UP(3K(skip) + 3K(data_len), 4K(PAGE_SIZE)); > sg_nents = 2; > > This patch fixes this issue by adding skip to data_len. > > Signed-off-by: Varun Prakash <varun@chelsio.com> > --- > drivers/target/iscsi/cxgbit/cxgbit_target.c | 12 +++++++----- > 1 file changed, 7 insertions(+), 5 deletions(-) > Applied to target-pending/master. Thanks Varun. -- To unsubscribe from this list: send the line "unsubscribe target-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/target/iscsi/cxgbit/cxgbit_target.c b/drivers/target/iscsi/cxgbit/cxgbit_target.c index dda13f1..514986b 100644 --- a/drivers/target/iscsi/cxgbit/cxgbit_target.c +++ b/drivers/target/iscsi/cxgbit/cxgbit_target.c @@ -827,7 +827,7 @@ cxgbit_put_login_tx(struct iscsi_conn *conn, struct iscsi_login *login, static void cxgbit_skb_copy_to_sg(struct sk_buff *skb, struct scatterlist *sg, - unsigned int nents) + unsigned int nents, u32 skip) { struct skb_seq_state st; const u8 *buf; @@ -846,7 +846,7 @@ cxgbit_skb_copy_to_sg(struct sk_buff *skb, struct scatterlist *sg, } consumed += sg_pcopy_from_buffer(sg, nents, (void *)buf, - buf_len, consumed); + buf_len, skip + consumed); } } @@ -912,7 +912,7 @@ cxgbit_handle_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr, struct scatterlist *sg = &cmd->se_cmd.t_data_sg[0]; u32 sg_nents = max(1UL, DIV_ROUND_UP(pdu_cb->dlen, PAGE_SIZE)); - cxgbit_skb_copy_to_sg(csk->skb, sg, sg_nents); + cxgbit_skb_copy_to_sg(csk->skb, sg, sg_nents, 0); } cmd->write_data_done += pdu_cb->dlen; @@ -1069,11 +1069,13 @@ static int cxgbit_handle_iscsi_dataout(struct cxgbit_sock *csk) cmd->se_cmd.data_length); if (!(pdu_cb->flags & PDUCBF_RX_DATA_DDPD)) { + u32 skip = data_offset % PAGE_SIZE; + sg_off = data_offset / PAGE_SIZE; sg_start = &cmd->se_cmd.t_data_sg[sg_off]; - sg_nents = max(1UL, DIV_ROUND_UP(data_len, PAGE_SIZE)); + sg_nents = max(1UL, DIV_ROUND_UP(skip + data_len, PAGE_SIZE)); - cxgbit_skb_copy_to_sg(csk->skb, sg_start, sg_nents); + cxgbit_skb_copy_to_sg(csk->skb, sg_start, sg_nents, skip); } check_payload:
The current logic of calculating sg_nents can fail if data_offset % PAGE_SIZE is not zero. For example - PAGE_SIZE = 4096 data_len = 3072 data_offset = 3072 As per current logic sg_nents = max(1UL, DIV_ROUND_UP(data_len, PAGE_SIZE)); sg_nents = max(1UL, DIV_ROUND_UP(3072, 4096)); sg_nents = 1 But as data_offset % PAGE_SIZE = 3072 we should skip 3072 bytes skip = 3K sg_nents = max(1UL, DIV_ROUND_UP(3K(skip) + 3K(data_len), 4K(PAGE_SIZE)); sg_nents = 2; This patch fixes this issue by adding skip to data_len. Signed-off-by: Varun Prakash <varun@chelsio.com> --- drivers/target/iscsi/cxgbit/cxgbit_target.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)