Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=6b00769fe1502b4ad97bb327ef7ac971b208bfb5
Commit:     6b00769fe1502b4ad97bb327ef7ac971b208bfb5
Parent:     40b01b9bbdf51ae543a04744283bf2d56c4a6afa
Author:     Tejun Heo <[EMAIL PROTECTED]>
AuthorDate: Tue Feb 19 11:36:35 2008 +0100
Committer:  Jens Axboe <[EMAIL PROTECTED]>
CommitDate: Tue Feb 19 11:36:35 2008 +0100

    block: add request->raw_data_len
    
    With padding and draining moved into it, block layer now may extend
    requests as directed by queue parameters, so now a request has two
    sizes - the original request size and the extended size which matches
    the size of area pointed to by bios and later by sgs.  The latter size
    is what lower layers are primarily interested in when allocating,
    filling up DMA tables and setting up the controller.
    
    Both padding and draining extend the data area to accomodate
    controller characteristics.  As any controller which speaks SCSI can
    handle underflows, feeding larger data area is safe.
    
    So, this patch makes the primary data length field, request->data_len,
    indicate the size of full data area and add a separate length field,
    request->raw_data_len, for the unmodified request size.  The latter is
    used to report to higher layer (userland) and where the original
    request size should be fed to the controller or device.
    
    Signed-off-by: Tejun Heo <[EMAIL PROTECTED]>
    Cc: James Bottomley <[EMAIL PROTECTED]>
    Signed-off-by: Jens Axboe <[EMAIL PROTECTED]>
---
 block/blk-core.c        |    2 ++
 block/blk-map.c         |    2 ++
 block/blk-merge.c       |    1 +
 block/bsg.c             |    8 ++++----
 block/scsi_ioctl.c      |    3 ++-
 drivers/scsi/scsi_lib.c |    8 ++++----
 include/linux/blkdev.h  |    1 +
 7 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index c013ca2..775c851 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -127,6 +127,7 @@ void rq_init(struct request_queue *q, struct request *rq)
        rq->nr_hw_segments = 0;
        rq->ioprio = 0;
        rq->special = NULL;
+       rq->raw_data_len = 0;
        rq->buffer = NULL;
        rq->tag = -1;
        rq->errors = 0;
@@ -2015,6 +2016,7 @@ void blk_rq_bio_prep(struct request_queue *q, struct 
request *rq,
        rq->hard_cur_sectors = rq->current_nr_sectors;
        rq->hard_nr_sectors = rq->nr_sectors = bio_sectors(bio);
        rq->buffer = bio_data(bio);
+       rq->raw_data_len = bio->bi_size;
        rq->data_len = bio->bi_size;
 
        rq->bio = rq->biotail = bio;
diff --git a/block/blk-map.c b/block/blk-map.c
index a7cf63c..09f7fd0 100644
--- a/block/blk-map.c
+++ b/block/blk-map.c
@@ -19,6 +19,7 @@ int blk_rq_append_bio(struct request_queue *q, struct request 
*rq,
                rq->biotail->bi_next = bio;
                rq->biotail = bio;
 
+               rq->raw_data_len += bio->bi_size;
                rq->data_len += bio->bi_size;
        }
        return 0;
@@ -154,6 +155,7 @@ int blk_rq_map_user(struct request_queue *q, struct request 
*rq,
 
                bio->bi_io_vec[bio->bi_vcnt - 1].bv_len += pad_len;
                bio->bi_size += pad_len;
+               rq->data_len += pad_len;
        }
 
        rq->buffer = rq->data = NULL;
diff --git a/block/blk-merge.c b/block/blk-merge.c
index d3b84bb..39f2e07 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -228,6 +228,7 @@ new_segment:
                            ((unsigned long)q->dma_drain_buffer) &
                            (PAGE_SIZE - 1));
                nsegs++;
+               rq->data_len += q->dma_drain_size;
        }
 
        if (sg)
diff --git a/block/bsg.c b/block/bsg.c
index 8917c51..7f3c095 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -437,14 +437,14 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, 
struct sg_io_v4 *hdr,
        }
 
        if (rq->next_rq) {
-               hdr->dout_resid = rq->data_len;
-               hdr->din_resid = rq->next_rq->data_len;
+               hdr->dout_resid = rq->raw_data_len;
+               hdr->din_resid = rq->next_rq->raw_data_len;
                blk_rq_unmap_user(bidi_bio);
                blk_put_request(rq->next_rq);
        } else if (rq_data_dir(rq) == READ)
-               hdr->din_resid = rq->data_len;
+               hdr->din_resid = rq->raw_data_len;
        else
-               hdr->dout_resid = rq->data_len;
+               hdr->dout_resid = rq->raw_data_len;
 
        /*
         * If the request generated a negative error number, return it
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index 9675b34..e993cac 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -266,7 +266,7 @@ static int blk_complete_sghdr_rq(struct request *rq, struct 
sg_io_hdr *hdr,
        hdr->info = 0;
        if (hdr->masked_status || hdr->host_status || hdr->driver_status)
                hdr->info |= SG_INFO_CHECK;
-       hdr->resid = rq->data_len;
+       hdr->resid = rq->raw_data_len;
        hdr->sb_len_wr = 0;
 
        if (rq->sense_len && hdr->sbp) {
@@ -528,6 +528,7 @@ static int __blk_send_generic(struct request_queue *q, 
struct gendisk *bd_disk,
        rq = blk_get_request(q, WRITE, __GFP_WAIT);
        rq->cmd_type = REQ_TYPE_BLOCK_PC;
        rq->data = NULL;
+       rq->raw_data_len = 0;
        rq->data_len = 0;
        rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
        memset(rq->cmd, 0, sizeof(rq->cmd));
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 135c1d0..ba21d97 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1014,10 +1014,6 @@ static int scsi_init_sgtable(struct request *req, struct 
scsi_data_buffer *sdb,
        }
 
        req->buffer = NULL;
-       if (blk_pc_request(req))
-               sdb->length = req->data_len;
-       else
-               sdb->length = req->nr_sectors << 9;
 
        /* 
         * Next, walk the list, and fill in the addresses and sizes of
@@ -1026,6 +1022,10 @@ static int scsi_init_sgtable(struct request *req, struct 
scsi_data_buffer *sdb,
        count = blk_rq_map_sg(req->q, req, sdb->table.sgl);
        BUG_ON(count > sdb->table.nents);
        sdb->table.nents = count;
+       if (blk_pc_request(req))
+               sdb->length = req->data_len;
+       else
+               sdb->length = req->nr_sectors << 9;
        return BLKPREP_OK;
 }
 
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index e1888cc..f1fe9fb 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -216,6 +216,7 @@ struct request {
        unsigned int cmd_len;
        unsigned char cmd[BLK_MAX_CDB];
 
+       unsigned int raw_data_len;
        unsigned int data_len;
        unsigned int sense_len;
        void *data;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to