diff options
Diffstat (limited to 'block')
-rw-r--r-- | block/blk-core.c | 13 | ||||
-rw-r--r-- | block/blk-merge.c | 27 | ||||
-rw-r--r-- | block/bsg.c | 12 | ||||
-rw-r--r-- | block/scsi_ioctl.c | 21 |
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 | ||
41 | static unsigned int __blk_recalc_rq_segments(struct request_queue *q, | 41 | static 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 | ||
98 | void blk_recalc_rq_segments(struct request *rq) | 100 | void 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 | ||
112 | void blk_recount_segments(struct request_queue *q, struct bio *bio) | 105 | void 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) | |||
353 | static void bsg_add_command(struct bsg_device *bd, struct request_queue *q, | 350 | static 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 | ||
374 | static struct bsg_command *bsg_next_done_cmd(struct bsg_device *bd) | 373 | static 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 | */ | ||
221 | static 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 | |||
228 | static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr, | 217 | static 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 | ||
264 | static int sg_io(struct request_queue *q, struct gendisk *bd_disk, | 251 | static int sg_io(struct request_queue *q, struct gendisk *bd_disk, |