aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
Diffstat (limited to 'block')
-rw-r--r--block/ll_rw_blk.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 4df7d027eb06..527bd8d4db50 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -30,6 +30,7 @@
30#include <linux/cpu.h> 30#include <linux/cpu.h>
31#include <linux/blktrace_api.h> 31#include <linux/blktrace_api.h>
32#include <linux/fault-inject.h> 32#include <linux/fault-inject.h>
33#include <linux/scatterlist.h>
33 34
34/* 35/*
35 * for max sense size 36 * for max sense size
@@ -1318,9 +1319,10 @@ static int blk_hw_contig_segment(struct request_queue *q, struct bio *bio,
1318 * must make sure sg can hold rq->nr_phys_segments entries 1319 * must make sure sg can hold rq->nr_phys_segments entries
1319 */ 1320 */
1320int blk_rq_map_sg(struct request_queue *q, struct request *rq, 1321int blk_rq_map_sg(struct request_queue *q, struct request *rq,
1321 struct scatterlist *sg) 1322 struct scatterlist *sglist)
1322{ 1323{
1323 struct bio_vec *bvec, *bvprv; 1324 struct bio_vec *bvec, *bvprv;
1325 struct scatterlist *next_sg, *sg;
1324 struct req_iterator iter; 1326 struct req_iterator iter;
1325 int nsegs, cluster; 1327 int nsegs, cluster;
1326 1328
@@ -1331,11 +1333,12 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
1331 * for each bio in rq 1333 * for each bio in rq
1332 */ 1334 */
1333 bvprv = NULL; 1335 bvprv = NULL;
1336 sg = next_sg = &sglist[0];
1334 rq_for_each_segment(bvec, rq, iter) { 1337 rq_for_each_segment(bvec, rq, iter) {
1335 int nbytes = bvec->bv_len; 1338 int nbytes = bvec->bv_len;
1336 1339
1337 if (bvprv && cluster) { 1340 if (bvprv && cluster) {
1338 if (sg[nsegs - 1].length + nbytes > q->max_segment_size) 1341 if (sg->length + nbytes > q->max_segment_size)
1339 goto new_segment; 1342 goto new_segment;
1340 1343
1341 if (!BIOVEC_PHYS_MERGEABLE(bvprv, bvec)) 1344 if (!BIOVEC_PHYS_MERGEABLE(bvprv, bvec))
@@ -1343,14 +1346,15 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
1343 if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bvec)) 1346 if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bvec))
1344 goto new_segment; 1347 goto new_segment;
1345 1348
1346 sg[nsegs - 1].length += nbytes; 1349 sg->length += nbytes;
1347 } else { 1350 } else {
1348new_segment: 1351new_segment:
1349 memset(&sg[nsegs],0,sizeof(struct scatterlist)); 1352 sg = next_sg;
1350 sg[nsegs].page = bvec->bv_page; 1353 next_sg = sg_next(sg);
1351 sg[nsegs].length = nbytes;
1352 sg[nsegs].offset = bvec->bv_offset;
1353 1354
1355 sg->page = bvec->bv_page;
1356 sg->length = nbytes;
1357 sg->offset = bvec->bv_offset;
1354 nsegs++; 1358 nsegs++;
1355 } 1359 }
1356 bvprv = bvec; 1360 bvprv = bvec;
@@ -4068,7 +4072,23 @@ static ssize_t queue_max_hw_sectors_show(struct request_queue *q, char *page)
4068 return queue_var_show(max_hw_sectors_kb, (page)); 4072 return queue_var_show(max_hw_sectors_kb, (page));
4069} 4073}
4070 4074
4075static ssize_t queue_max_segments_show(struct request_queue *q, char *page)
4076{
4077 return queue_var_show(q->max_phys_segments, page);
4078}
4079
4080static ssize_t queue_max_segments_store(struct request_queue *q,
4081 const char *page, size_t count)
4082{
4083 unsigned long segments;
4084 ssize_t ret = queue_var_store(&segments, page, count);
4071 4085
4086 spin_lock_irq(q->queue_lock);
4087 q->max_phys_segments = segments;
4088 spin_unlock_irq(q->queue_lock);
4089
4090 return ret;
4091}
4072static struct queue_sysfs_entry queue_requests_entry = { 4092static struct queue_sysfs_entry queue_requests_entry = {
4073 .attr = {.name = "nr_requests", .mode = S_IRUGO | S_IWUSR }, 4093 .attr = {.name = "nr_requests", .mode = S_IRUGO | S_IWUSR },
4074 .show = queue_requests_show, 4094 .show = queue_requests_show,
@@ -4092,6 +4112,12 @@ static struct queue_sysfs_entry queue_max_hw_sectors_entry = {
4092 .show = queue_max_hw_sectors_show, 4112 .show = queue_max_hw_sectors_show,
4093}; 4113};
4094 4114
4115static struct queue_sysfs_entry queue_max_segments_entry = {
4116 .attr = {.name = "max_segments", .mode = S_IRUGO | S_IWUSR },
4117 .show = queue_max_segments_show,
4118 .store = queue_max_segments_store,
4119};
4120
4095static struct queue_sysfs_entry queue_iosched_entry = { 4121static struct queue_sysfs_entry queue_iosched_entry = {
4096 .attr = {.name = "scheduler", .mode = S_IRUGO | S_IWUSR }, 4122 .attr = {.name = "scheduler", .mode = S_IRUGO | S_IWUSR },
4097 .show = elv_iosched_show, 4123 .show = elv_iosched_show,
@@ -4103,6 +4129,7 @@ static struct attribute *default_attrs[] = {
4103 &queue_ra_entry.attr, 4129 &queue_ra_entry.attr,
4104 &queue_max_hw_sectors_entry.attr, 4130 &queue_max_hw_sectors_entry.attr,
4105 &queue_max_sectors_entry.attr, 4131 &queue_max_sectors_entry.attr,
4132 &queue_max_segments_entry.attr,
4106 &queue_iosched_entry.attr, 4133 &queue_iosched_entry.attr,
4107 NULL, 4134 NULL,
4108}; 4135};