diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2007-10-23 03:49:25 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2007-10-23 03:49:25 -0400 |
commit | 7aeacf982203fb4dea2f3434eefdc268cfd5d6d9 (patch) | |
tree | 93a3991d5ab854fce477d9e28e55b720fd6ac81a /block/ll_rw_blk.c | |
parent | ad0d4083e65d9f223275adbfb9a7927e2120dc6c (diff) |
[BLOCK] blk_rq_map_sg: force clear termination bit
Since blk_rq_map_sg() sets the termination bit at the end of the sg
table, we could see it prematurely on the next mapping unless we
force drivers to do a full sg_init_table() prior to each mapping. So
force clear the termination bit to avoid having to put that clear in
the driver for every mapping.
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'block/ll_rw_blk.c')
-rw-r--r-- | block/ll_rw_blk.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index fb8fb8852c3..de5ba479c22 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c | |||
@@ -1351,8 +1351,20 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq, | |||
1351 | new_segment: | 1351 | new_segment: |
1352 | if (!sg) | 1352 | if (!sg) |
1353 | sg = sglist; | 1353 | sg = sglist; |
1354 | else | 1354 | else { |
1355 | /* | ||
1356 | * If the driver previously mapped a shorter | ||
1357 | * list, we could see a termination bit | ||
1358 | * prematurely unless it fully inits the sg | ||
1359 | * table on each mapping. We KNOW that there | ||
1360 | * must be more entries here or the driver | ||
1361 | * would be buggy, so force clear the | ||
1362 | * termination bit to avoid doing a full | ||
1363 | * sg_init_table() in drivers for each command. | ||
1364 | */ | ||
1365 | sg->page_link &= ~0x02; | ||
1355 | sg = sg_next(sg); | 1366 | sg = sg_next(sg); |
1367 | } | ||
1356 | 1368 | ||
1357 | sg_set_page(sg, bvec->bv_page); | 1369 | sg_set_page(sg, bvec->bv_page); |
1358 | sg->length = nbytes; | 1370 | sg->length = nbytes; |