Re: WRITE BUFFER commands through SG_IO getting rounded up to sector past 32k

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch has some problem. While ioctls with dxfer_len < 32k still make it through properly, the problematic ones now show up in open-iscsi's queuecommand with request_bufflen = 0. I'm not sure what the problem is now.

Aravind.

michaelc@xxxxxxxxxxx wrote:
Aravind Parchuri wrote:
In fact, even with the newer kernel, all commands smaller than 32k make
it through with the right size, which leads me to think it's something
to do with the scatter-gather list. I'm not particularly familiar with
the scsi code, but inside scsi_execute_async, in scsi_map_req_sg, should
the request's data_len be set to the dxfer_len instead of summing up the
scatter-gather list lengths? I must mention again that I haven't really
gone through the code thoroughly.


You are right. sg_build_indirect will do this
blk_size = (blk_size + SG_SECTOR_MSK) & (~SG_SECTOR_MSK)
so we should be using the bufflen passed into us. Attached is a patch
made over scsi-misc. It should also apply to scsi rc fixes.
------------------------------------------------------------------------

sg's may have setup a the buffer with a different length than
the transfer length so we should be using the bufflen passed
in as the request's data len.

Signed-off-by: Mike Christie <michaelc@xxxxxxxxxxx>

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 9f7482d..dfe3ccd 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -301,7 +301,7 @@ static int scsi_req_map_sg(struct reques
 {
    struct request_queue *q = rq->q;
    int nr_pages = (bufflen + sgl[0].offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
-   unsigned int data_len = 0, len, bytes, off;
+   unsigned int len, bytes, off;
    struct page *page;
    struct bio *bio = NULL;
    int i, err, nr_vecs = 0;
@@ -310,7 +310,6 @@ static int scsi_req_map_sg(struct reques
        page = sgl[i].page;
        off = sgl[i].offset;
        len = sgl[i].length;
-       data_len += len;
while (len > 0) {
            bytes = min_t(unsigned int, len, PAGE_SIZE - off);
@@ -350,7 +349,7 @@ static int scsi_req_map_sg(struct reques
    }
rq->buffer = rq->data = NULL;
-   rq->data_len = data_len;
+   rq->data_len = bufflen;
    return 0;
free_bios:

-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux