aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
Diffstat (limited to 'block')
-rw-r--r--block/ll_rw_blk.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 094c0fa5c405..2de9bad1d042 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1441,7 +1441,8 @@ static inline int ll_new_hw_segment(struct request_queue *q,
1441 return 1; 1441 return 1;
1442} 1442}
1443 1443
1444int ll_back_merge_fn(struct request_queue *q, struct request *req, struct bio *bio) 1444static int ll_back_merge_fn(struct request_queue *q, struct request *req,
1445 struct bio *bio)
1445{ 1446{
1446 unsigned short max_sectors; 1447 unsigned short max_sectors;
1447 int len; 1448 int len;
@@ -1477,7 +1478,6 @@ int ll_back_merge_fn(struct request_queue *q, struct request *req, struct bio *b
1477 1478
1478 return ll_new_hw_segment(q, req, bio); 1479 return ll_new_hw_segment(q, req, bio);
1479} 1480}
1480EXPORT_SYMBOL(ll_back_merge_fn);
1481 1481
1482static int ll_front_merge_fn(struct request_queue *q, struct request *req, 1482static int ll_front_merge_fn(struct request_queue *q, struct request *req,
1483 struct bio *bio) 1483 struct bio *bio)
@@ -2367,6 +2367,23 @@ static int __blk_rq_unmap_user(struct bio *bio)
2367 return ret; 2367 return ret;
2368} 2368}
2369 2369
2370int blk_rq_append_bio(struct request_queue *q, struct request *rq,
2371 struct bio *bio)
2372{
2373 if (!rq->bio)
2374 blk_rq_bio_prep(q, rq, bio);
2375 else if (!ll_back_merge_fn(q, rq, bio))
2376 return -EINVAL;
2377 else {
2378 rq->biotail->bi_next = bio;
2379 rq->biotail = bio;
2380
2381 rq->data_len += bio->bi_size;
2382 }
2383 return 0;
2384}
2385EXPORT_SYMBOL(blk_rq_append_bio);
2386
2370static int __blk_rq_map_user(struct request_queue *q, struct request *rq, 2387static int __blk_rq_map_user(struct request_queue *q, struct request *rq,
2371 void __user *ubuf, unsigned int len) 2388 void __user *ubuf, unsigned int len)
2372{ 2389{
@@ -2398,21 +2415,10 @@ static int __blk_rq_map_user(struct request_queue *q, struct request *rq,
2398 */ 2415 */
2399 bio_get(bio); 2416 bio_get(bio);
2400 2417
2401 if (!rq->bio) 2418 ret = blk_rq_append_bio(q, rq, bio);
2402 blk_rq_bio_prep(q, rq, bio); 2419 if (!ret)
2403 else if (!ll_back_merge_fn(q, rq, bio)) { 2420 return bio->bi_size;
2404 ret = -EINVAL;
2405 goto unmap_bio;
2406 } else {
2407 rq->biotail->bi_next = bio;
2408 rq->biotail = bio;
2409
2410 rq->data_len += bio->bi_size;
2411 }
2412
2413 return bio->bi_size;
2414 2421
2415unmap_bio:
2416 /* if it was boucned we must call the end io function */ 2422 /* if it was boucned we must call the end io function */
2417 bio_endio(bio, bio->bi_size, 0); 2423 bio_endio(bio, bio->bi_size, 0);
2418 __blk_rq_unmap_user(orig_bio); 2424 __blk_rq_unmap_user(orig_bio);