aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
Diffstat (limited to 'block')
-rw-r--r--block/blk-core.c13
-rw-r--r--block/blk-merge.c27
-rw-r--r--block/bsg.c12
-rw-r--r--block/scsi_ioctl.c21
4 files changed, 28 insertions, 45 deletions
diff --git a/block/blk-core.c b/block/blk-core.c
index 29bcfac6c688..996ed906d8ca 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -603,13 +603,10 @@ blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id)
603 q->queue_flags = QUEUE_FLAG_DEFAULT; 603 q->queue_flags = QUEUE_FLAG_DEFAULT;
604 q->queue_lock = lock; 604 q->queue_lock = lock;
605 605
606 blk_queue_segment_boundary(q, BLK_SEG_BOUNDARY_MASK); 606 /*
607 607 * This also sets hw/phys segments, boundary and size
608 */
608 blk_queue_make_request(q, __make_request); 609 blk_queue_make_request(q, __make_request);
609 blk_queue_max_segment_size(q, MAX_SEGMENT_SIZE);
610
611 blk_queue_max_hw_segments(q, MAX_HW_SEGMENTS);
612 blk_queue_max_phys_segments(q, MAX_PHYS_SEGMENTS);
613 610
614 q->sg_reserved_size = INT_MAX; 611 q->sg_reserved_size = INT_MAX;
615 612
@@ -735,7 +732,6 @@ static void freed_request(struct request_queue *q, int rw, int priv)
735 __freed_request(q, rw ^ 1); 732 __freed_request(q, rw ^ 1);
736} 733}
737 734
738#define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist)
739/* 735/*
740 * Get a free request, queue_lock must be held. 736 * Get a free request, queue_lock must be held.
741 * Returns NULL on failure, with queue_lock held. 737 * Returns NULL on failure, with queue_lock held.
@@ -1066,6 +1062,9 @@ void __blk_put_request(struct request_queue *q, struct request *req)
1066 1062
1067 elv_completed_request(q, req); 1063 elv_completed_request(q, req);
1068 1064
1065 /* this is a bio leak */
1066 WARN_ON(req->bio != NULL);
1067
1069 /* 1068 /*
1070 * Request may not have originated from ll_rw_blk. if not, 1069 * Request may not have originated from ll_rw_blk. if not,
1071 * it didn't come out of our reserved rq pools 1070 * it didn't come out of our reserved rq pools
diff --git a/block/blk-merge.c b/block/blk-merge.c
index a104593e70c3..e39cb24b7679 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -39,14 +39,13 @@ void blk_recalc_rq_sectors(struct request *rq, int nsect)
39} 39}
40 40
41static unsigned int __blk_recalc_rq_segments(struct request_queue *q, 41static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
42 struct bio *bio, 42 struct bio *bio)
43 unsigned int *seg_size_ptr)
44{ 43{
45 unsigned int phys_size; 44 unsigned int phys_size;
46 struct bio_vec *bv, *bvprv = NULL; 45 struct bio_vec *bv, *bvprv = NULL;
47 int cluster, i, high, highprv = 1; 46 int cluster, i, high, highprv = 1;
48 unsigned int seg_size, nr_phys_segs; 47 unsigned int seg_size, nr_phys_segs;
49 struct bio *fbio; 48 struct bio *fbio, *bbio;
50 49
51 if (!bio) 50 if (!bio)
52 return 0; 51 return 0;
@@ -87,26 +86,20 @@ new_segment:
87 seg_size = bv->bv_len; 86 seg_size = bv->bv_len;
88 highprv = high; 87 highprv = high;
89 } 88 }
89 bbio = bio;
90 } 90 }
91 91
92 if (seg_size_ptr) 92 if (nr_phys_segs == 1 && seg_size > fbio->bi_seg_front_size)
93 *seg_size_ptr = seg_size; 93 fbio->bi_seg_front_size = seg_size;
94 if (seg_size > bbio->bi_seg_back_size)
95 bbio->bi_seg_back_size = seg_size;
94 96
95 return nr_phys_segs; 97 return nr_phys_segs;
96} 98}
97 99
98void blk_recalc_rq_segments(struct request *rq) 100void blk_recalc_rq_segments(struct request *rq)
99{ 101{
100 unsigned int seg_size = 0, phys_segs; 102 rq->nr_phys_segments = __blk_recalc_rq_segments(rq->q, rq->bio);
101
102 phys_segs = __blk_recalc_rq_segments(rq->q, rq->bio, &seg_size);
103
104 if (phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
105 rq->bio->bi_seg_front_size = seg_size;
106 if (seg_size > rq->biotail->bi_seg_back_size)
107 rq->biotail->bi_seg_back_size = seg_size;
108
109 rq->nr_phys_segments = phys_segs;
110} 103}
111 104
112void blk_recount_segments(struct request_queue *q, struct bio *bio) 105void blk_recount_segments(struct request_queue *q, struct bio *bio)
@@ -114,7 +107,7 @@ void blk_recount_segments(struct request_queue *q, struct bio *bio)
114 struct bio *nxt = bio->bi_next; 107 struct bio *nxt = bio->bi_next;
115 108
116 bio->bi_next = NULL; 109 bio->bi_next = NULL;
117 bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, NULL); 110 bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio);
118 bio->bi_next = nxt; 111 bio->bi_next = nxt;
119 bio->bi_flags |= (1 << BIO_SEG_VALID); 112 bio->bi_flags |= (1 << BIO_SEG_VALID);
120} 113}
@@ -410,6 +403,8 @@ static int attempt_merge(struct request_queue *q, struct request *req,
410 if (blk_rq_cpu_valid(next)) 403 if (blk_rq_cpu_valid(next))
411 req->cpu = next->cpu; 404 req->cpu = next->cpu;
412 405
406 /* owner-ship of bio passed from next to req */
407 next->bio = NULL;
413 __blk_put_request(q, next); 408 __blk_put_request(q, next);
414 return 1; 409 return 1;
415} 410}
diff --git a/block/bsg.c b/block/bsg.c
index 0ce8806dd0c1..206060e795da 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -218,9 +218,6 @@ bsg_validate_sgv4_hdr(struct request_queue *q, struct sg_io_v4 *hdr, int *rw)
218 218
219 if (hdr->guard != 'Q') 219 if (hdr->guard != 'Q')
220 return -EINVAL; 220 return -EINVAL;
221 if (hdr->dout_xfer_len > (q->max_sectors << 9) ||
222 hdr->din_xfer_len > (q->max_sectors << 9))
223 return -EIO;
224 221
225 switch (hdr->protocol) { 222 switch (hdr->protocol) {
226 case BSG_PROTOCOL_SCSI: 223 case BSG_PROTOCOL_SCSI:
@@ -353,6 +350,8 @@ static void bsg_rq_end_io(struct request *rq, int uptodate)
353static void bsg_add_command(struct bsg_device *bd, struct request_queue *q, 350static void bsg_add_command(struct bsg_device *bd, struct request_queue *q,
354 struct bsg_command *bc, struct request *rq) 351 struct bsg_command *bc, struct request *rq)
355{ 352{
353 int at_head = (0 == (bc->hdr.flags & BSG_FLAG_Q_AT_TAIL));
354
356 /* 355 /*
357 * add bc command to busy queue and submit rq for io 356 * add bc command to busy queue and submit rq for io
358 */ 357 */
@@ -368,7 +367,7 @@ static void bsg_add_command(struct bsg_device *bd, struct request_queue *q,
368 dprintk("%s: queueing rq %p, bc %p\n", bd->name, rq, bc); 367 dprintk("%s: queueing rq %p, bc %p\n", bd->name, rq, bc);
369 368
370 rq->end_io_data = bc; 369 rq->end_io_data = bc;
371 blk_execute_rq_nowait(q, NULL, rq, 1, bsg_rq_end_io); 370 blk_execute_rq_nowait(q, NULL, rq, at_head, bsg_rq_end_io);
372} 371}
373 372
374static struct bsg_command *bsg_next_done_cmd(struct bsg_device *bd) 373static struct bsg_command *bsg_next_done_cmd(struct bsg_device *bd)
@@ -924,6 +923,7 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
924 struct request *rq; 923 struct request *rq;
925 struct bio *bio, *bidi_bio = NULL; 924 struct bio *bio, *bidi_bio = NULL;
926 struct sg_io_v4 hdr; 925 struct sg_io_v4 hdr;
926 int at_head;
927 u8 sense[SCSI_SENSE_BUFFERSIZE]; 927 u8 sense[SCSI_SENSE_BUFFERSIZE];
928 928
929 if (copy_from_user(&hdr, uarg, sizeof(hdr))) 929 if (copy_from_user(&hdr, uarg, sizeof(hdr)))
@@ -936,7 +936,9 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
936 bio = rq->bio; 936 bio = rq->bio;
937 if (rq->next_rq) 937 if (rq->next_rq)
938 bidi_bio = rq->next_rq->bio; 938 bidi_bio = rq->next_rq->bio;
939 blk_execute_rq(bd->queue, NULL, rq, 0); 939
940 at_head = (0 == (hdr.flags & BSG_FLAG_Q_AT_TAIL));
941 blk_execute_rq(bd->queue, NULL, rq, at_head);
940 ret = blk_complete_sgv4_hdr_rq(rq, &hdr, bio, bidi_bio); 942 ret = blk_complete_sgv4_hdr_rq(rq, &hdr, bio, bidi_bio);
941 943
942 if (copy_to_user(uarg, &hdr, sizeof(hdr))) 944 if (copy_to_user(uarg, &hdr, sizeof(hdr)))
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index ee9c67d7e1be..626ee274c5c4 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -214,21 +214,10 @@ static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq,
214 return 0; 214 return 0;
215} 215}
216 216
217/*
218 * unmap a request that was previously mapped to this sg_io_hdr. handles
219 * both sg and non-sg sg_io_hdr.
220 */
221static int blk_unmap_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr)
222{
223 blk_rq_unmap_user(rq->bio);
224 blk_put_request(rq);
225 return 0;
226}
227
228static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr, 217static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
229 struct bio *bio) 218 struct bio *bio)
230{ 219{
231 int r, ret = 0; 220 int ret = 0;
232 221
233 /* 222 /*
234 * fill in all the output members 223 * fill in all the output members
@@ -253,12 +242,10 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
253 ret = -EFAULT; 242 ret = -EFAULT;
254 } 243 }
255 244
256 rq->bio = bio; 245 blk_rq_unmap_user(bio);
257 r = blk_unmap_sghdr_rq(rq, hdr); 246 blk_put_request(rq);
258 if (ret)
259 r = ret;
260 247
261 return r; 248 return ret;
262} 249}
263 250
264static int sg_io(struct request_queue *q, struct gendisk *bd_disk, 251static int sg_io(struct request_queue *q, struct gendisk *bd_disk,