diff options
Diffstat (limited to 'block')
-rw-r--r-- | block/as-iosched.c | 2 | ||||
-rw-r--r-- | block/blk-core.c | 68 | ||||
-rw-r--r-- | block/blk-ioc.c | 2 | ||||
-rw-r--r-- | block/blk-merge.c | 12 | ||||
-rw-r--r-- | block/blk-settings.c | 8 | ||||
-rw-r--r-- | block/blk-sysfs.c | 6 | ||||
-rw-r--r-- | block/blk-tag.c | 9 | ||||
-rw-r--r-- | block/blktrace.c | 31 | ||||
-rw-r--r-- | block/bsg.c | 12 | ||||
-rw-r--r-- | block/cfq-iosched.c | 57 | ||||
-rw-r--r-- | block/compat_ioctl.c | 2 | ||||
-rw-r--r-- | block/elevator.c | 2 | ||||
-rw-r--r-- | block/genhd.c | 11 | ||||
-rw-r--r-- | block/scsi_ioctl.c | 5 |
14 files changed, 152 insertions, 75 deletions
diff --git a/block/as-iosched.c b/block/as-iosched.c index 8c3946787dbb..743f33a01a07 100644 --- a/block/as-iosched.c +++ b/block/as-iosched.c | |||
@@ -831,6 +831,8 @@ static void as_completed_request(struct request_queue *q, struct request *rq) | |||
831 | } | 831 | } |
832 | 832 | ||
833 | if (ad->changed_batch && ad->nr_dispatched == 1) { | 833 | if (ad->changed_batch && ad->nr_dispatched == 1) { |
834 | ad->current_batch_expires = jiffies + | ||
835 | ad->batch_expire[ad->batch_data_dir]; | ||
834 | kblockd_schedule_work(&ad->antic_work); | 836 | kblockd_schedule_work(&ad->antic_work); |
835 | ad->changed_batch = 0; | 837 | ad->changed_batch = 0; |
836 | 838 | ||
diff --git a/block/blk-core.c b/block/blk-core.c index b754a4a2f9bd..1905aaba49fb 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -54,15 +54,16 @@ static DEFINE_PER_CPU(struct list_head, blk_cpu_done); | |||
54 | 54 | ||
55 | static void drive_stat_acct(struct request *rq, int new_io) | 55 | static void drive_stat_acct(struct request *rq, int new_io) |
56 | { | 56 | { |
57 | struct hd_struct *part; | ||
57 | int rw = rq_data_dir(rq); | 58 | int rw = rq_data_dir(rq); |
58 | 59 | ||
59 | if (!blk_fs_request(rq) || !rq->rq_disk) | 60 | if (!blk_fs_request(rq) || !rq->rq_disk) |
60 | return; | 61 | return; |
61 | 62 | ||
62 | if (!new_io) { | 63 | part = get_part(rq->rq_disk, rq->sector); |
63 | __all_stat_inc(rq->rq_disk, merges[rw], rq->sector); | 64 | if (!new_io) |
64 | } else { | 65 | __all_stat_inc(rq->rq_disk, part, merges[rw], rq->sector); |
65 | struct hd_struct *part = get_part(rq->rq_disk, rq->sector); | 66 | else { |
66 | disk_round_stats(rq->rq_disk); | 67 | disk_round_stats(rq->rq_disk); |
67 | rq->rq_disk->in_flight++; | 68 | rq->rq_disk->in_flight++; |
68 | if (part) { | 69 | if (part) { |
@@ -253,9 +254,11 @@ EXPORT_SYMBOL(__generic_unplug_device); | |||
253 | **/ | 254 | **/ |
254 | void generic_unplug_device(struct request_queue *q) | 255 | void generic_unplug_device(struct request_queue *q) |
255 | { | 256 | { |
256 | spin_lock_irq(q->queue_lock); | 257 | if (blk_queue_plugged(q)) { |
257 | __generic_unplug_device(q); | 258 | spin_lock_irq(q->queue_lock); |
258 | spin_unlock_irq(q->queue_lock); | 259 | __generic_unplug_device(q); |
260 | spin_unlock_irq(q->queue_lock); | ||
261 | } | ||
259 | } | 262 | } |
260 | EXPORT_SYMBOL(generic_unplug_device); | 263 | EXPORT_SYMBOL(generic_unplug_device); |
261 | 264 | ||
@@ -479,6 +482,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id) | |||
479 | kobject_init(&q->kobj, &blk_queue_ktype); | 482 | kobject_init(&q->kobj, &blk_queue_ktype); |
480 | 483 | ||
481 | mutex_init(&q->sysfs_lock); | 484 | mutex_init(&q->sysfs_lock); |
485 | spin_lock_init(&q->__queue_lock); | ||
482 | 486 | ||
483 | return q; | 487 | return q; |
484 | } | 488 | } |
@@ -541,10 +545,8 @@ blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id) | |||
541 | * if caller didn't supply a lock, they get per-queue locking with | 545 | * if caller didn't supply a lock, they get per-queue locking with |
542 | * our embedded lock | 546 | * our embedded lock |
543 | */ | 547 | */ |
544 | if (!lock) { | 548 | if (!lock) |
545 | spin_lock_init(&q->__queue_lock); | ||
546 | lock = &q->__queue_lock; | 549 | lock = &q->__queue_lock; |
547 | } | ||
548 | 550 | ||
549 | q->request_fn = rfn; | 551 | q->request_fn = rfn; |
550 | q->prep_rq_fn = NULL; | 552 | q->prep_rq_fn = NULL; |
@@ -804,35 +806,32 @@ static struct request *get_request_wait(struct request_queue *q, int rw_flags, | |||
804 | rq = get_request(q, rw_flags, bio, GFP_NOIO); | 806 | rq = get_request(q, rw_flags, bio, GFP_NOIO); |
805 | while (!rq) { | 807 | while (!rq) { |
806 | DEFINE_WAIT(wait); | 808 | DEFINE_WAIT(wait); |
809 | struct io_context *ioc; | ||
807 | struct request_list *rl = &q->rq; | 810 | struct request_list *rl = &q->rq; |
808 | 811 | ||
809 | prepare_to_wait_exclusive(&rl->wait[rw], &wait, | 812 | prepare_to_wait_exclusive(&rl->wait[rw], &wait, |
810 | TASK_UNINTERRUPTIBLE); | 813 | TASK_UNINTERRUPTIBLE); |
811 | 814 | ||
812 | rq = get_request(q, rw_flags, bio, GFP_NOIO); | 815 | blk_add_trace_generic(q, bio, rw, BLK_TA_SLEEPRQ); |
813 | |||
814 | if (!rq) { | ||
815 | struct io_context *ioc; | ||
816 | |||
817 | blk_add_trace_generic(q, bio, rw, BLK_TA_SLEEPRQ); | ||
818 | 816 | ||
819 | __generic_unplug_device(q); | 817 | __generic_unplug_device(q); |
820 | spin_unlock_irq(q->queue_lock); | 818 | spin_unlock_irq(q->queue_lock); |
821 | io_schedule(); | 819 | io_schedule(); |
822 | 820 | ||
823 | /* | 821 | /* |
824 | * After sleeping, we become a "batching" process and | 822 | * After sleeping, we become a "batching" process and |
825 | * will be able to allocate at least one request, and | 823 | * will be able to allocate at least one request, and |
826 | * up to a big batch of them for a small period time. | 824 | * up to a big batch of them for a small period time. |
827 | * See ioc_batching, ioc_set_batching | 825 | * See ioc_batching, ioc_set_batching |
828 | */ | 826 | */ |
829 | ioc = current_io_context(GFP_NOIO, q->node); | 827 | ioc = current_io_context(GFP_NOIO, q->node); |
830 | ioc_set_batching(q, ioc); | 828 | ioc_set_batching(q, ioc); |
831 | 829 | ||
832 | spin_lock_irq(q->queue_lock); | 830 | spin_lock_irq(q->queue_lock); |
833 | } | ||
834 | finish_wait(&rl->wait[rw], &wait); | 831 | finish_wait(&rl->wait[rw], &wait); |
835 | } | 832 | |
833 | rq = get_request(q, rw_flags, bio, GFP_NOIO); | ||
834 | }; | ||
836 | 835 | ||
837 | return rq; | 836 | return rq; |
838 | } | 837 | } |
@@ -1536,10 +1535,11 @@ static int __end_that_request_first(struct request *req, int error, | |||
1536 | } | 1535 | } |
1537 | 1536 | ||
1538 | if (blk_fs_request(req) && req->rq_disk) { | 1537 | if (blk_fs_request(req) && req->rq_disk) { |
1538 | struct hd_struct *part = get_part(req->rq_disk, req->sector); | ||
1539 | const int rw = rq_data_dir(req); | 1539 | const int rw = rq_data_dir(req); |
1540 | 1540 | ||
1541 | all_stat_add(req->rq_disk, sectors[rw], | 1541 | all_stat_add(req->rq_disk, part, sectors[rw], |
1542 | nr_bytes >> 9, req->sector); | 1542 | nr_bytes >> 9, req->sector); |
1543 | } | 1543 | } |
1544 | 1544 | ||
1545 | total_bytes = bio_nbytes = 0; | 1545 | total_bytes = bio_nbytes = 0; |
@@ -1725,8 +1725,8 @@ static void end_that_request_last(struct request *req, int error) | |||
1725 | const int rw = rq_data_dir(req); | 1725 | const int rw = rq_data_dir(req); |
1726 | struct hd_struct *part = get_part(disk, req->sector); | 1726 | struct hd_struct *part = get_part(disk, req->sector); |
1727 | 1727 | ||
1728 | __all_stat_inc(disk, ios[rw], req->sector); | 1728 | __all_stat_inc(disk, part, ios[rw], req->sector); |
1729 | __all_stat_add(disk, ticks[rw], duration, req->sector); | 1729 | __all_stat_add(disk, part, ticks[rw], duration, req->sector); |
1730 | disk_round_stats(disk); | 1730 | disk_round_stats(disk); |
1731 | disk->in_flight--; | 1731 | disk->in_flight--; |
1732 | if (part) { | 1732 | if (part) { |
diff --git a/block/blk-ioc.c b/block/blk-ioc.c index e34df7c9fc36..012f065ac8e2 100644 --- a/block/blk-ioc.c +++ b/block/blk-ioc.c | |||
@@ -41,8 +41,8 @@ int put_io_context(struct io_context *ioc) | |||
41 | rcu_read_lock(); | 41 | rcu_read_lock(); |
42 | if (ioc->aic && ioc->aic->dtor) | 42 | if (ioc->aic && ioc->aic->dtor) |
43 | ioc->aic->dtor(ioc->aic); | 43 | ioc->aic->dtor(ioc->aic); |
44 | rcu_read_unlock(); | ||
45 | cfq_dtor(ioc); | 44 | cfq_dtor(ioc); |
45 | rcu_read_unlock(); | ||
46 | 46 | ||
47 | kmem_cache_free(iocontext_cachep, ioc); | 47 | kmem_cache_free(iocontext_cachep, ioc); |
48 | return 1; | 48 | return 1; |
diff --git a/block/blk-merge.c b/block/blk-merge.c index 73b23562af20..651136aae76e 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c | |||
@@ -149,9 +149,9 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio, | |||
149 | static int blk_hw_contig_segment(struct request_queue *q, struct bio *bio, | 149 | static int blk_hw_contig_segment(struct request_queue *q, struct bio *bio, |
150 | struct bio *nxt) | 150 | struct bio *nxt) |
151 | { | 151 | { |
152 | if (unlikely(!bio_flagged(bio, BIO_SEG_VALID))) | 152 | if (!bio_flagged(bio, BIO_SEG_VALID)) |
153 | blk_recount_segments(q, bio); | 153 | blk_recount_segments(q, bio); |
154 | if (unlikely(!bio_flagged(nxt, BIO_SEG_VALID))) | 154 | if (!bio_flagged(nxt, BIO_SEG_VALID)) |
155 | blk_recount_segments(q, nxt); | 155 | blk_recount_segments(q, nxt); |
156 | if (!BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)) || | 156 | if (!BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)) || |
157 | BIOVEC_VIRT_OVERSIZE(bio->bi_hw_back_size + nxt->bi_hw_front_size)) | 157 | BIOVEC_VIRT_OVERSIZE(bio->bi_hw_back_size + nxt->bi_hw_front_size)) |
@@ -312,9 +312,9 @@ int ll_back_merge_fn(struct request_queue *q, struct request *req, | |||
312 | q->last_merge = NULL; | 312 | q->last_merge = NULL; |
313 | return 0; | 313 | return 0; |
314 | } | 314 | } |
315 | if (unlikely(!bio_flagged(req->biotail, BIO_SEG_VALID))) | 315 | if (!bio_flagged(req->biotail, BIO_SEG_VALID)) |
316 | blk_recount_segments(q, req->biotail); | 316 | blk_recount_segments(q, req->biotail); |
317 | if (unlikely(!bio_flagged(bio, BIO_SEG_VALID))) | 317 | if (!bio_flagged(bio, BIO_SEG_VALID)) |
318 | blk_recount_segments(q, bio); | 318 | blk_recount_segments(q, bio); |
319 | len = req->biotail->bi_hw_back_size + bio->bi_hw_front_size; | 319 | len = req->biotail->bi_hw_back_size + bio->bi_hw_front_size; |
320 | if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(req->biotail), __BVEC_START(bio)) | 320 | if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(req->biotail), __BVEC_START(bio)) |
@@ -352,9 +352,9 @@ int ll_front_merge_fn(struct request_queue *q, struct request *req, | |||
352 | return 0; | 352 | return 0; |
353 | } | 353 | } |
354 | len = bio->bi_hw_back_size + req->bio->bi_hw_front_size; | 354 | len = bio->bi_hw_back_size + req->bio->bi_hw_front_size; |
355 | if (unlikely(!bio_flagged(bio, BIO_SEG_VALID))) | 355 | if (!bio_flagged(bio, BIO_SEG_VALID)) |
356 | blk_recount_segments(q, bio); | 356 | blk_recount_segments(q, bio); |
357 | if (unlikely(!bio_flagged(req->bio, BIO_SEG_VALID))) | 357 | if (!bio_flagged(req->bio, BIO_SEG_VALID)) |
358 | blk_recount_segments(q, req->bio); | 358 | blk_recount_segments(q, req->bio); |
359 | if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(req->bio)) && | 359 | if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(req->bio)) && |
360 | !BIOVEC_VIRT_OVERSIZE(len)) { | 360 | !BIOVEC_VIRT_OVERSIZE(len)) { |
diff --git a/block/blk-settings.c b/block/blk-settings.c index bb93d4c32775..8dd86418f35d 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c | |||
@@ -286,8 +286,14 @@ void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b) | |||
286 | t->max_hw_segments = min(t->max_hw_segments, b->max_hw_segments); | 286 | t->max_hw_segments = min(t->max_hw_segments, b->max_hw_segments); |
287 | t->max_segment_size = min(t->max_segment_size, b->max_segment_size); | 287 | t->max_segment_size = min(t->max_segment_size, b->max_segment_size); |
288 | t->hardsect_size = max(t->hardsect_size, b->hardsect_size); | 288 | t->hardsect_size = max(t->hardsect_size, b->hardsect_size); |
289 | if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) | 289 | if (!t->queue_lock) |
290 | WARN_ON_ONCE(1); | ||
291 | else if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) { | ||
292 | unsigned long flags; | ||
293 | spin_lock_irqsave(t->queue_lock, flags); | ||
290 | queue_flag_clear(QUEUE_FLAG_CLUSTER, t); | 294 | queue_flag_clear(QUEUE_FLAG_CLUSTER, t); |
295 | spin_unlock_irqrestore(t->queue_lock, flags); | ||
296 | } | ||
291 | } | 297 | } |
292 | EXPORT_SYMBOL(blk_queue_stack_limits); | 298 | EXPORT_SYMBOL(blk_queue_stack_limits); |
293 | 299 | ||
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index e85c4013e8a2..304ec73ab821 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c | |||
@@ -146,11 +146,13 @@ static ssize_t queue_nomerges_store(struct request_queue *q, const char *page, | |||
146 | unsigned long nm; | 146 | unsigned long nm; |
147 | ssize_t ret = queue_var_store(&nm, page, count); | 147 | ssize_t ret = queue_var_store(&nm, page, count); |
148 | 148 | ||
149 | spin_lock_irq(q->queue_lock); | ||
149 | if (nm) | 150 | if (nm) |
150 | set_bit(QUEUE_FLAG_NOMERGES, &q->queue_flags); | 151 | queue_flag_set(QUEUE_FLAG_NOMERGES, q); |
151 | else | 152 | else |
152 | clear_bit(QUEUE_FLAG_NOMERGES, &q->queue_flags); | 153 | queue_flag_clear(QUEUE_FLAG_NOMERGES, q); |
153 | 154 | ||
155 | spin_unlock_irq(q->queue_lock); | ||
154 | return ret; | 156 | return ret; |
155 | } | 157 | } |
156 | 158 | ||
diff --git a/block/blk-tag.c b/block/blk-tag.c index de64e0429977..32667beb03ee 100644 --- a/block/blk-tag.c +++ b/block/blk-tag.c | |||
@@ -70,7 +70,7 @@ void __blk_queue_free_tags(struct request_queue *q) | |||
70 | __blk_free_tags(bqt); | 70 | __blk_free_tags(bqt); |
71 | 71 | ||
72 | q->queue_tags = NULL; | 72 | q->queue_tags = NULL; |
73 | queue_flag_clear(QUEUE_FLAG_QUEUED, q); | 73 | queue_flag_clear_unlocked(QUEUE_FLAG_QUEUED, q); |
74 | } | 74 | } |
75 | 75 | ||
76 | /** | 76 | /** |
@@ -98,7 +98,7 @@ EXPORT_SYMBOL(blk_free_tags); | |||
98 | **/ | 98 | **/ |
99 | void blk_queue_free_tags(struct request_queue *q) | 99 | void blk_queue_free_tags(struct request_queue *q) |
100 | { | 100 | { |
101 | queue_flag_clear(QUEUE_FLAG_QUEUED, q); | 101 | queue_flag_clear_unlocked(QUEUE_FLAG_QUEUED, q); |
102 | } | 102 | } |
103 | EXPORT_SYMBOL(blk_queue_free_tags); | 103 | EXPORT_SYMBOL(blk_queue_free_tags); |
104 | 104 | ||
@@ -171,6 +171,9 @@ EXPORT_SYMBOL(blk_init_tags); | |||
171 | * @q: the request queue for the device | 171 | * @q: the request queue for the device |
172 | * @depth: the maximum queue depth supported | 172 | * @depth: the maximum queue depth supported |
173 | * @tags: the tag to use | 173 | * @tags: the tag to use |
174 | * | ||
175 | * Queue lock must be held here if the function is called to resize an | ||
176 | * existing map. | ||
174 | **/ | 177 | **/ |
175 | int blk_queue_init_tags(struct request_queue *q, int depth, | 178 | int blk_queue_init_tags(struct request_queue *q, int depth, |
176 | struct blk_queue_tag *tags) | 179 | struct blk_queue_tag *tags) |
@@ -197,7 +200,7 @@ int blk_queue_init_tags(struct request_queue *q, int depth, | |||
197 | * assign it, all done | 200 | * assign it, all done |
198 | */ | 201 | */ |
199 | q->queue_tags = tags; | 202 | q->queue_tags = tags; |
200 | queue_flag_set(QUEUE_FLAG_QUEUED, q); | 203 | queue_flag_set_unlocked(QUEUE_FLAG_QUEUED, q); |
201 | INIT_LIST_HEAD(&q->tag_busy_list); | 204 | INIT_LIST_HEAD(&q->tag_busy_list); |
202 | return 0; | 205 | return 0; |
203 | fail: | 206 | fail: |
diff --git a/block/blktrace.c b/block/blktrace.c index 568588cd16b2..8d3a27780260 100644 --- a/block/blktrace.c +++ b/block/blktrace.c | |||
@@ -75,6 +75,24 @@ static void trace_note_time(struct blk_trace *bt) | |||
75 | local_irq_restore(flags); | 75 | local_irq_restore(flags); |
76 | } | 76 | } |
77 | 77 | ||
78 | void __trace_note_message(struct blk_trace *bt, const char *fmt, ...) | ||
79 | { | ||
80 | int n; | ||
81 | va_list args; | ||
82 | unsigned long flags; | ||
83 | char *buf; | ||
84 | |||
85 | local_irq_save(flags); | ||
86 | buf = per_cpu_ptr(bt->msg_data, smp_processor_id()); | ||
87 | va_start(args, fmt); | ||
88 | n = vscnprintf(buf, BLK_TN_MAX_MSG, fmt, args); | ||
89 | va_end(args); | ||
90 | |||
91 | trace_note(bt, 0, BLK_TN_MESSAGE, buf, n); | ||
92 | local_irq_restore(flags); | ||
93 | } | ||
94 | EXPORT_SYMBOL_GPL(__trace_note_message); | ||
95 | |||
78 | static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector, | 96 | static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector, |
79 | pid_t pid) | 97 | pid_t pid) |
80 | { | 98 | { |
@@ -141,10 +159,7 @@ void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, | |||
141 | /* | 159 | /* |
142 | * A word about the locking here - we disable interrupts to reserve | 160 | * A word about the locking here - we disable interrupts to reserve |
143 | * some space in the relay per-cpu buffer, to prevent an irq | 161 | * some space in the relay per-cpu buffer, to prevent an irq |
144 | * from coming in and stepping on our toes. Once reserved, it's | 162 | * from coming in and stepping on our toes. |
145 | * enough to get preemption disabled to prevent read of this data | ||
146 | * before we are through filling it. get_cpu()/put_cpu() does this | ||
147 | * for us | ||
148 | */ | 163 | */ |
149 | local_irq_save(flags); | 164 | local_irq_save(flags); |
150 | 165 | ||
@@ -232,6 +247,7 @@ static void blk_trace_cleanup(struct blk_trace *bt) | |||
232 | debugfs_remove(bt->dropped_file); | 247 | debugfs_remove(bt->dropped_file); |
233 | blk_remove_tree(bt->dir); | 248 | blk_remove_tree(bt->dir); |
234 | free_percpu(bt->sequence); | 249 | free_percpu(bt->sequence); |
250 | free_percpu(bt->msg_data); | ||
235 | kfree(bt); | 251 | kfree(bt); |
236 | } | 252 | } |
237 | 253 | ||
@@ -346,6 +362,10 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, | |||
346 | if (!bt->sequence) | 362 | if (!bt->sequence) |
347 | goto err; | 363 | goto err; |
348 | 364 | ||
365 | bt->msg_data = __alloc_percpu(BLK_TN_MAX_MSG); | ||
366 | if (!bt->msg_data) | ||
367 | goto err; | ||
368 | |||
349 | ret = -ENOENT; | 369 | ret = -ENOENT; |
350 | dir = blk_create_tree(buts->name); | 370 | dir = blk_create_tree(buts->name); |
351 | if (!dir) | 371 | if (!dir) |
@@ -392,6 +412,7 @@ err: | |||
392 | if (bt->dropped_file) | 412 | if (bt->dropped_file) |
393 | debugfs_remove(bt->dropped_file); | 413 | debugfs_remove(bt->dropped_file); |
394 | free_percpu(bt->sequence); | 414 | free_percpu(bt->sequence); |
415 | free_percpu(bt->msg_data); | ||
395 | if (bt->rchan) | 416 | if (bt->rchan) |
396 | relay_close(bt->rchan); | 417 | relay_close(bt->rchan); |
397 | kfree(bt); | 418 | kfree(bt); |
@@ -476,7 +497,7 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg) | |||
476 | 497 | ||
477 | switch (cmd) { | 498 | switch (cmd) { |
478 | case BLKTRACESETUP: | 499 | case BLKTRACESETUP: |
479 | strcpy(b, bdevname(bdev, b)); | 500 | bdevname(bdev, b); |
480 | ret = blk_trace_setup(q, b, bdev->bd_dev, arg); | 501 | ret = blk_trace_setup(q, b, bdev->bd_dev, arg); |
481 | break; | 502 | break; |
482 | case BLKTRACESTART: | 503 | case BLKTRACESTART: |
diff --git a/block/bsg.c b/block/bsg.c index fa796b605f55..f0b7cd343216 100644 --- a/block/bsg.c +++ b/block/bsg.c | |||
@@ -174,7 +174,11 @@ unlock: | |||
174 | static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq, | 174 | static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq, |
175 | struct sg_io_v4 *hdr, int has_write_perm) | 175 | struct sg_io_v4 *hdr, int has_write_perm) |
176 | { | 176 | { |
177 | memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */ | 177 | if (hdr->request_len > BLK_MAX_CDB) { |
178 | rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL); | ||
179 | if (!rq->cmd) | ||
180 | return -ENOMEM; | ||
181 | } | ||
178 | 182 | ||
179 | if (copy_from_user(rq->cmd, (void *)(unsigned long)hdr->request, | 183 | if (copy_from_user(rq->cmd, (void *)(unsigned long)hdr->request, |
180 | hdr->request_len)) | 184 | hdr->request_len)) |
@@ -211,8 +215,6 @@ bsg_validate_sgv4_hdr(struct request_queue *q, struct sg_io_v4 *hdr, int *rw) | |||
211 | 215 | ||
212 | if (hdr->guard != 'Q') | 216 | if (hdr->guard != 'Q') |
213 | return -EINVAL; | 217 | return -EINVAL; |
214 | if (hdr->request_len > BLK_MAX_CDB) | ||
215 | return -EINVAL; | ||
216 | if (hdr->dout_xfer_len > (q->max_sectors << 9) || | 218 | if (hdr->dout_xfer_len > (q->max_sectors << 9) || |
217 | hdr->din_xfer_len > (q->max_sectors << 9)) | 219 | hdr->din_xfer_len > (q->max_sectors << 9)) |
218 | return -EIO; | 220 | return -EIO; |
@@ -302,6 +304,8 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr) | |||
302 | } | 304 | } |
303 | return rq; | 305 | return rq; |
304 | out: | 306 | out: |
307 | if (rq->cmd != rq->__cmd) | ||
308 | kfree(rq->cmd); | ||
305 | blk_put_request(rq); | 309 | blk_put_request(rq); |
306 | if (next_rq) { | 310 | if (next_rq) { |
307 | blk_rq_unmap_user(next_rq->bio); | 311 | blk_rq_unmap_user(next_rq->bio); |
@@ -455,6 +459,8 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, | |||
455 | ret = rq->errors; | 459 | ret = rq->errors; |
456 | 460 | ||
457 | blk_rq_unmap_user(bio); | 461 | blk_rq_unmap_user(bio); |
462 | if (rq->cmd != rq->__cmd) | ||
463 | kfree(rq->cmd); | ||
458 | blk_put_request(rq); | 464 | blk_put_request(rq); |
459 | 465 | ||
460 | return ret; | 466 | return ret; |
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index f4e1006c253d..d01b411c72f0 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -124,6 +124,8 @@ struct cfq_data { | |||
124 | struct cfq_queue { | 124 | struct cfq_queue { |
125 | /* reference count */ | 125 | /* reference count */ |
126 | atomic_t ref; | 126 | atomic_t ref; |
127 | /* various state flags, see below */ | ||
128 | unsigned int flags; | ||
127 | /* parent cfq_data */ | 129 | /* parent cfq_data */ |
128 | struct cfq_data *cfqd; | 130 | struct cfq_data *cfqd; |
129 | /* service_tree member */ | 131 | /* service_tree member */ |
@@ -138,14 +140,14 @@ struct cfq_queue { | |||
138 | int queued[2]; | 140 | int queued[2]; |
139 | /* currently allocated requests */ | 141 | /* currently allocated requests */ |
140 | int allocated[2]; | 142 | int allocated[2]; |
141 | /* pending metadata requests */ | ||
142 | int meta_pending; | ||
143 | /* fifo list of requests in sort_list */ | 143 | /* fifo list of requests in sort_list */ |
144 | struct list_head fifo; | 144 | struct list_head fifo; |
145 | 145 | ||
146 | unsigned long slice_end; | 146 | unsigned long slice_end; |
147 | long slice_resid; | 147 | long slice_resid; |
148 | 148 | ||
149 | /* pending metadata requests */ | ||
150 | int meta_pending; | ||
149 | /* number of requests that are on the dispatch list or inside driver */ | 151 | /* number of requests that are on the dispatch list or inside driver */ |
150 | int dispatched; | 152 | int dispatched; |
151 | 153 | ||
@@ -153,8 +155,6 @@ struct cfq_queue { | |||
153 | unsigned short ioprio, org_ioprio; | 155 | unsigned short ioprio, org_ioprio; |
154 | unsigned short ioprio_class, org_ioprio_class; | 156 | unsigned short ioprio_class, org_ioprio_class; |
155 | 157 | ||
156 | /* various state flags, see below */ | ||
157 | unsigned int flags; | ||
158 | }; | 158 | }; |
159 | 159 | ||
160 | enum cfqq_state_flags { | 160 | enum cfqq_state_flags { |
@@ -1143,18 +1143,28 @@ static void cfq_put_queue(struct cfq_queue *cfqq) | |||
1143 | } | 1143 | } |
1144 | 1144 | ||
1145 | /* | 1145 | /* |
1146 | * Call func for each cic attached to this ioc. | 1146 | * Must always be called with the rcu_read_lock() held |
1147 | */ | 1147 | */ |
1148 | static void | 1148 | static void |
1149 | call_for_each_cic(struct io_context *ioc, | 1149 | __call_for_each_cic(struct io_context *ioc, |
1150 | void (*func)(struct io_context *, struct cfq_io_context *)) | 1150 | void (*func)(struct io_context *, struct cfq_io_context *)) |
1151 | { | 1151 | { |
1152 | struct cfq_io_context *cic; | 1152 | struct cfq_io_context *cic; |
1153 | struct hlist_node *n; | 1153 | struct hlist_node *n; |
1154 | 1154 | ||
1155 | rcu_read_lock(); | ||
1156 | hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list) | 1155 | hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list) |
1157 | func(ioc, cic); | 1156 | func(ioc, cic); |
1157 | } | ||
1158 | |||
1159 | /* | ||
1160 | * Call func for each cic attached to this ioc. | ||
1161 | */ | ||
1162 | static void | ||
1163 | call_for_each_cic(struct io_context *ioc, | ||
1164 | void (*func)(struct io_context *, struct cfq_io_context *)) | ||
1165 | { | ||
1166 | rcu_read_lock(); | ||
1167 | __call_for_each_cic(ioc, func); | ||
1158 | rcu_read_unlock(); | 1168 | rcu_read_unlock(); |
1159 | } | 1169 | } |
1160 | 1170 | ||
@@ -1190,6 +1200,11 @@ static void cic_free_func(struct io_context *ioc, struct cfq_io_context *cic) | |||
1190 | cfq_cic_free(cic); | 1200 | cfq_cic_free(cic); |
1191 | } | 1201 | } |
1192 | 1202 | ||
1203 | /* | ||
1204 | * Must be called with rcu_read_lock() held or preemption otherwise disabled. | ||
1205 | * Only two callers of this - ->dtor() which is called with the rcu_read_lock(), | ||
1206 | * and ->trim() which is called with the task lock held | ||
1207 | */ | ||
1193 | static void cfq_free_io_context(struct io_context *ioc) | 1208 | static void cfq_free_io_context(struct io_context *ioc) |
1194 | { | 1209 | { |
1195 | /* | 1210 | /* |
@@ -1198,7 +1213,7 @@ static void cfq_free_io_context(struct io_context *ioc) | |||
1198 | * should be ok to iterate over the known list, we will see all cic's | 1213 | * should be ok to iterate over the known list, we will see all cic's |
1199 | * since no new ones are added. | 1214 | * since no new ones are added. |
1200 | */ | 1215 | */ |
1201 | call_for_each_cic(ioc, cic_free_func); | 1216 | __call_for_each_cic(ioc, cic_free_func); |
1202 | } | 1217 | } |
1203 | 1218 | ||
1204 | static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) | 1219 | static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) |
@@ -1296,10 +1311,10 @@ static void cfq_init_prio_data(struct cfq_queue *cfqq, struct io_context *ioc) | |||
1296 | printk(KERN_ERR "cfq: bad prio %x\n", ioprio_class); | 1311 | printk(KERN_ERR "cfq: bad prio %x\n", ioprio_class); |
1297 | case IOPRIO_CLASS_NONE: | 1312 | case IOPRIO_CLASS_NONE: |
1298 | /* | 1313 | /* |
1299 | * no prio set, place us in the middle of the BE classes | 1314 | * no prio set, inherit CPU scheduling settings |
1300 | */ | 1315 | */ |
1301 | cfqq->ioprio = task_nice_ioprio(tsk); | 1316 | cfqq->ioprio = task_nice_ioprio(tsk); |
1302 | cfqq->ioprio_class = IOPRIO_CLASS_BE; | 1317 | cfqq->ioprio_class = task_nice_ioclass(tsk); |
1303 | break; | 1318 | break; |
1304 | case IOPRIO_CLASS_RT: | 1319 | case IOPRIO_CLASS_RT: |
1305 | cfqq->ioprio = task_ioprio(ioc); | 1320 | cfqq->ioprio = task_ioprio(ioc); |
@@ -1495,20 +1510,24 @@ static struct cfq_io_context * | |||
1495 | cfq_cic_lookup(struct cfq_data *cfqd, struct io_context *ioc) | 1510 | cfq_cic_lookup(struct cfq_data *cfqd, struct io_context *ioc) |
1496 | { | 1511 | { |
1497 | struct cfq_io_context *cic; | 1512 | struct cfq_io_context *cic; |
1513 | unsigned long flags; | ||
1498 | void *k; | 1514 | void *k; |
1499 | 1515 | ||
1500 | if (unlikely(!ioc)) | 1516 | if (unlikely(!ioc)) |
1501 | return NULL; | 1517 | return NULL; |
1502 | 1518 | ||
1519 | rcu_read_lock(); | ||
1520 | |||
1503 | /* | 1521 | /* |
1504 | * we maintain a last-hit cache, to avoid browsing over the tree | 1522 | * we maintain a last-hit cache, to avoid browsing over the tree |
1505 | */ | 1523 | */ |
1506 | cic = rcu_dereference(ioc->ioc_data); | 1524 | cic = rcu_dereference(ioc->ioc_data); |
1507 | if (cic && cic->key == cfqd) | 1525 | if (cic && cic->key == cfqd) { |
1526 | rcu_read_unlock(); | ||
1508 | return cic; | 1527 | return cic; |
1528 | } | ||
1509 | 1529 | ||
1510 | do { | 1530 | do { |
1511 | rcu_read_lock(); | ||
1512 | cic = radix_tree_lookup(&ioc->radix_root, (unsigned long) cfqd); | 1531 | cic = radix_tree_lookup(&ioc->radix_root, (unsigned long) cfqd); |
1513 | rcu_read_unlock(); | 1532 | rcu_read_unlock(); |
1514 | if (!cic) | 1533 | if (!cic) |
@@ -1517,10 +1536,13 @@ cfq_cic_lookup(struct cfq_data *cfqd, struct io_context *ioc) | |||
1517 | k = cic->key; | 1536 | k = cic->key; |
1518 | if (unlikely(!k)) { | 1537 | if (unlikely(!k)) { |
1519 | cfq_drop_dead_cic(cfqd, ioc, cic); | 1538 | cfq_drop_dead_cic(cfqd, ioc, cic); |
1539 | rcu_read_lock(); | ||
1520 | continue; | 1540 | continue; |
1521 | } | 1541 | } |
1522 | 1542 | ||
1543 | spin_lock_irqsave(&ioc->lock, flags); | ||
1523 | rcu_assign_pointer(ioc->ioc_data, cic); | 1544 | rcu_assign_pointer(ioc->ioc_data, cic); |
1545 | spin_unlock_irqrestore(&ioc->lock, flags); | ||
1524 | break; | 1546 | break; |
1525 | } while (1); | 1547 | } while (1); |
1526 | 1548 | ||
@@ -2127,6 +2149,10 @@ static void *cfq_init_queue(struct request_queue *q) | |||
2127 | 2149 | ||
2128 | static void cfq_slab_kill(void) | 2150 | static void cfq_slab_kill(void) |
2129 | { | 2151 | { |
2152 | /* | ||
2153 | * Caller already ensured that pending RCU callbacks are completed, | ||
2154 | * so we should have no busy allocations at this point. | ||
2155 | */ | ||
2130 | if (cfq_pool) | 2156 | if (cfq_pool) |
2131 | kmem_cache_destroy(cfq_pool); | 2157 | kmem_cache_destroy(cfq_pool); |
2132 | if (cfq_ioc_pool) | 2158 | if (cfq_ioc_pool) |
@@ -2285,6 +2311,11 @@ static void __exit cfq_exit(void) | |||
2285 | ioc_gone = &all_gone; | 2311 | ioc_gone = &all_gone; |
2286 | /* ioc_gone's update must be visible before reading ioc_count */ | 2312 | /* ioc_gone's update must be visible before reading ioc_count */ |
2287 | smp_wmb(); | 2313 | smp_wmb(); |
2314 | |||
2315 | /* | ||
2316 | * this also protects us from entering cfq_slab_kill() with | ||
2317 | * pending RCU callbacks | ||
2318 | */ | ||
2288 | if (elv_ioc_count_read(ioc_count)) | 2319 | if (elv_ioc_count_read(ioc_count)) |
2289 | wait_for_completion(ioc_gone); | 2320 | wait_for_completion(ioc_gone); |
2290 | cfq_slab_kill(); | 2321 | cfq_slab_kill(); |
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c index c70d0b6f666f..c23177e4623f 100644 --- a/block/compat_ioctl.c +++ b/block/compat_ioctl.c | |||
@@ -555,7 +555,7 @@ static int compat_blk_trace_setup(struct block_device *bdev, char __user *arg) | |||
555 | if (copy_from_user(&cbuts, arg, sizeof(cbuts))) | 555 | if (copy_from_user(&cbuts, arg, sizeof(cbuts))) |
556 | return -EFAULT; | 556 | return -EFAULT; |
557 | 557 | ||
558 | strcpy(b, bdevname(bdev, b)); | 558 | bdevname(bdev, b); |
559 | 559 | ||
560 | buts = (struct blk_user_trace_setup) { | 560 | buts = (struct blk_user_trace_setup) { |
561 | .act_mask = cbuts.act_mask, | 561 | .act_mask = cbuts.act_mask, |
diff --git a/block/elevator.c b/block/elevator.c index 980f8ae147b4..902dd1344d56 100644 --- a/block/elevator.c +++ b/block/elevator.c | |||
@@ -1110,6 +1110,8 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e) | |||
1110 | queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q); | 1110 | queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q); |
1111 | spin_unlock_irq(q->queue_lock); | 1111 | spin_unlock_irq(q->queue_lock); |
1112 | 1112 | ||
1113 | blk_add_trace_msg(q, "elv switch: %s", e->elevator_type->elevator_name); | ||
1114 | |||
1113 | return 1; | 1115 | return 1; |
1114 | 1116 | ||
1115 | fail_register: | 1117 | fail_register: |
diff --git a/block/genhd.c b/block/genhd.c index fda9c7a63c29..b922d4801c87 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
@@ -653,15 +653,21 @@ void genhd_media_change_notify(struct gendisk *disk) | |||
653 | EXPORT_SYMBOL_GPL(genhd_media_change_notify); | 653 | EXPORT_SYMBOL_GPL(genhd_media_change_notify); |
654 | #endif /* 0 */ | 654 | #endif /* 0 */ |
655 | 655 | ||
656 | dev_t blk_lookup_devt(const char *name) | 656 | dev_t blk_lookup_devt(const char *name, int part) |
657 | { | 657 | { |
658 | struct device *dev; | 658 | struct device *dev; |
659 | dev_t devt = MKDEV(0, 0); | 659 | dev_t devt = MKDEV(0, 0); |
660 | 660 | ||
661 | mutex_lock(&block_class_lock); | 661 | mutex_lock(&block_class_lock); |
662 | list_for_each_entry(dev, &block_class.devices, node) { | 662 | list_for_each_entry(dev, &block_class.devices, node) { |
663 | if (dev->type != &disk_type) | ||
664 | continue; | ||
663 | if (strcmp(dev->bus_id, name) == 0) { | 665 | if (strcmp(dev->bus_id, name) == 0) { |
664 | devt = dev->devt; | 666 | struct gendisk *disk = dev_to_disk(dev); |
667 | |||
668 | if (part < disk->minors) | ||
669 | devt = MKDEV(MAJOR(dev->devt), | ||
670 | MINOR(dev->devt) + part); | ||
665 | break; | 671 | break; |
666 | } | 672 | } |
667 | } | 673 | } |
@@ -669,7 +675,6 @@ dev_t blk_lookup_devt(const char *name) | |||
669 | 675 | ||
670 | return devt; | 676 | return devt; |
671 | } | 677 | } |
672 | |||
673 | EXPORT_SYMBOL(blk_lookup_devt); | 678 | EXPORT_SYMBOL(blk_lookup_devt); |
674 | 679 | ||
675 | struct gendisk *alloc_disk(int minors) | 680 | struct gendisk *alloc_disk(int minors) |
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index ffa3720e6ca0..78199c08ec92 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c | |||
@@ -33,13 +33,12 @@ | |||
33 | #include <scsi/scsi_cmnd.h> | 33 | #include <scsi/scsi_cmnd.h> |
34 | 34 | ||
35 | /* Command group 3 is reserved and should never be used. */ | 35 | /* Command group 3 is reserved and should never be used. */ |
36 | const unsigned char scsi_command_size[8] = | 36 | const unsigned char scsi_command_size_tbl[8] = |
37 | { | 37 | { |
38 | 6, 10, 10, 12, | 38 | 6, 10, 10, 12, |
39 | 16, 12, 10, 10 | 39 | 16, 12, 10, 10 |
40 | }; | 40 | }; |
41 | 41 | EXPORT_SYMBOL(scsi_command_size_tbl); | |
42 | EXPORT_SYMBOL(scsi_command_size); | ||
43 | 42 | ||
44 | #include <scsi/sg.h> | 43 | #include <scsi/sg.h> |
45 | 44 | ||