aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/blk-core.c30
-rw-r--r--block/blk-ioc.c5
-rw-r--r--block/blk-merge.c3
-rw-r--r--block/cfq-iosched.c56
-rw-r--r--block/genhd.c6
-rw-r--r--drivers/block/loop.c6
-rw-r--r--drivers/md/dm.c2
-rw-r--r--fs/bio-integrity.c7
-rw-r--r--fs/char_dev.c2
-rw-r--r--fs/nfsd/vfs.c5
-rw-r--r--fs/partitions/check.c8
-rw-r--r--fs/splice.c43
-rw-r--r--include/linux/blkdev.h1
-rw-r--r--include/linux/genhd.h25
-rw-r--r--include/trace/events/block.h6
-rw-r--r--kernel/trace/blktrace.c25
16 files changed, 135 insertions, 95 deletions
diff --git a/block/blk-core.c b/block/blk-core.c
index 151070541e21..2f4002f79a24 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -64,13 +64,27 @@ static void drive_stat_acct(struct request *rq, int new_io)
64 return; 64 return;
65 65
66 cpu = part_stat_lock(); 66 cpu = part_stat_lock();
67 part = disk_map_sector_rcu(rq->rq_disk, blk_rq_pos(rq));
68 67
69 if (!new_io) 68 if (!new_io) {
69 part = rq->part;
70 part_stat_inc(cpu, part, merges[rw]); 70 part_stat_inc(cpu, part, merges[rw]);
71 else { 71 } else {
72 part = disk_map_sector_rcu(rq->rq_disk, blk_rq_pos(rq));
73 if (!hd_struct_try_get(part)) {
74 /*
75 * The partition is already being removed,
76 * the request will be accounted on the disk only
77 *
78 * We take a reference on disk->part0 although that
79 * partition will never be deleted, so we can treat
80 * it as any other partition.
81 */
82 part = &rq->rq_disk->part0;
83 hd_struct_get(part);
84 }
72 part_round_stats(cpu, part); 85 part_round_stats(cpu, part);
73 part_inc_in_flight(part, rw); 86 part_inc_in_flight(part, rw);
87 rq->part = part;
74 } 88 }
75 89
76 part_stat_unlock(); 90 part_stat_unlock();
@@ -128,6 +142,7 @@ void blk_rq_init(struct request_queue *q, struct request *rq)
128 rq->ref_count = 1; 142 rq->ref_count = 1;
129 rq->start_time = jiffies; 143 rq->start_time = jiffies;
130 set_start_time_ns(rq); 144 set_start_time_ns(rq);
145 rq->part = NULL;
131} 146}
132EXPORT_SYMBOL(blk_rq_init); 147EXPORT_SYMBOL(blk_rq_init);
133 148
@@ -1776,7 +1791,7 @@ static void blk_account_io_completion(struct request *req, unsigned int bytes)
1776 int cpu; 1791 int cpu;
1777 1792
1778 cpu = part_stat_lock(); 1793 cpu = part_stat_lock();
1779 part = disk_map_sector_rcu(req->rq_disk, blk_rq_pos(req)); 1794 part = req->part;
1780 part_stat_add(cpu, part, sectors[rw], bytes >> 9); 1795 part_stat_add(cpu, part, sectors[rw], bytes >> 9);
1781 part_stat_unlock(); 1796 part_stat_unlock();
1782 } 1797 }
@@ -1796,13 +1811,14 @@ static void blk_account_io_done(struct request *req)
1796 int cpu; 1811 int cpu;
1797 1812
1798 cpu = part_stat_lock(); 1813 cpu = part_stat_lock();
1799 part = disk_map_sector_rcu(req->rq_disk, blk_rq_pos(req)); 1814 part = req->part;
1800 1815
1801 part_stat_inc(cpu, part, ios[rw]); 1816 part_stat_inc(cpu, part, ios[rw]);
1802 part_stat_add(cpu, part, ticks[rw], duration); 1817 part_stat_add(cpu, part, ticks[rw], duration);
1803 part_round_stats(cpu, part); 1818 part_round_stats(cpu, part);
1804 part_dec_in_flight(part, rw); 1819 part_dec_in_flight(part, rw);
1805 1820
1821 hd_struct_put(part);
1806 part_stat_unlock(); 1822 part_stat_unlock();
1807 } 1823 }
1808} 1824}
@@ -2606,7 +2622,9 @@ int __init blk_dev_init(void)
2606 BUILD_BUG_ON(__REQ_NR_BITS > 8 * 2622 BUILD_BUG_ON(__REQ_NR_BITS > 8 *
2607 sizeof(((struct request *)0)->cmd_flags)); 2623 sizeof(((struct request *)0)->cmd_flags));
2608 2624
2609 kblockd_workqueue = create_workqueue("kblockd"); 2625 /* used for unplugging and affects IO latency/throughput - HIGHPRI */
2626 kblockd_workqueue = alloc_workqueue("kblockd",
2627 WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
2610 if (!kblockd_workqueue) 2628 if (!kblockd_workqueue)
2611 panic("Failed to create kblockd\n"); 2629 panic("Failed to create kblockd\n");
2612 2630
diff --git a/block/blk-ioc.c b/block/blk-ioc.c
index 3c7a339fe381..b791022beef3 100644
--- a/block/blk-ioc.c
+++ b/block/blk-ioc.c
@@ -64,7 +64,7 @@ static void cfq_exit(struct io_context *ioc)
64 rcu_read_unlock(); 64 rcu_read_unlock();
65} 65}
66 66
67/* Called by the exitting task */ 67/* Called by the exiting task */
68void exit_io_context(struct task_struct *task) 68void exit_io_context(struct task_struct *task)
69{ 69{
70 struct io_context *ioc; 70 struct io_context *ioc;
@@ -74,10 +74,9 @@ void exit_io_context(struct task_struct *task)
74 task->io_context = NULL; 74 task->io_context = NULL;
75 task_unlock(task); 75 task_unlock(task);
76 76
77 if (atomic_dec_and_test(&ioc->nr_tasks)) { 77 if (atomic_dec_and_test(&ioc->nr_tasks))
78 cfq_exit(ioc); 78 cfq_exit(ioc);
79 79
80 }
81 put_io_context(ioc); 80 put_io_context(ioc);
82} 81}
83 82
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 77b7c26df6b5..00b7d31b38a2 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -351,11 +351,12 @@ static void blk_account_io_merge(struct request *req)
351 int cpu; 351 int cpu;
352 352
353 cpu = part_stat_lock(); 353 cpu = part_stat_lock();
354 part = disk_map_sector_rcu(req->rq_disk, blk_rq_pos(req)); 354 part = req->part;
355 355
356 part_round_stats(cpu, part); 356 part_round_stats(cpu, part);
357 part_dec_in_flight(part, rq_data_dir(req)); 357 part_dec_in_flight(part, rq_data_dir(req));
358 358
359 hd_struct_put(part);
359 part_stat_unlock(); 360 part_stat_unlock();
360 } 361 }
361} 362}
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 9b186fd6bf47..f083bda30546 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -96,7 +96,7 @@ struct cfq_rb_root {
96 */ 96 */
97struct cfq_queue { 97struct cfq_queue {
98 /* reference count */ 98 /* reference count */
99 atomic_t ref; 99 int ref;
100 /* various state flags, see below */ 100 /* various state flags, see below */
101 unsigned int flags; 101 unsigned int flags;
102 /* parent cfq_data */ 102 /* parent cfq_data */
@@ -207,7 +207,7 @@ struct cfq_group {
207 struct blkio_group blkg; 207 struct blkio_group blkg;
208#ifdef CONFIG_CFQ_GROUP_IOSCHED 208#ifdef CONFIG_CFQ_GROUP_IOSCHED
209 struct hlist_node cfqd_node; 209 struct hlist_node cfqd_node;
210 atomic_t ref; 210 int ref;
211#endif 211#endif
212 /* number of requests that are on the dispatch list or inside driver */ 212 /* number of requests that are on the dispatch list or inside driver */
213 int dispatched; 213 int dispatched;
@@ -1014,7 +1014,7 @@ cfq_find_alloc_cfqg(struct cfq_data *cfqd, struct cgroup *cgroup, int create)
1014 * elevator which will be dropped by either elevator exit 1014 * elevator which will be dropped by either elevator exit
1015 * or cgroup deletion path depending on who is exiting first. 1015 * or cgroup deletion path depending on who is exiting first.
1016 */ 1016 */
1017 atomic_set(&cfqg->ref, 1); 1017 cfqg->ref = 1;
1018 1018
1019 /* 1019 /*
1020 * Add group onto cgroup list. It might happen that bdi->dev is 1020 * Add group onto cgroup list. It might happen that bdi->dev is
@@ -1059,7 +1059,7 @@ static struct cfq_group *cfq_get_cfqg(struct cfq_data *cfqd, int create)
1059 1059
1060static inline struct cfq_group *cfq_ref_get_cfqg(struct cfq_group *cfqg) 1060static inline struct cfq_group *cfq_ref_get_cfqg(struct cfq_group *cfqg)
1061{ 1061{
1062 atomic_inc(&cfqg->ref); 1062 cfqg->ref++;
1063 return cfqg; 1063 return cfqg;
1064} 1064}
1065 1065
@@ -1071,7 +1071,7 @@ static void cfq_link_cfqq_cfqg(struct cfq_queue *cfqq, struct cfq_group *cfqg)
1071 1071
1072 cfqq->cfqg = cfqg; 1072 cfqq->cfqg = cfqg;
1073 /* cfqq reference on cfqg */ 1073 /* cfqq reference on cfqg */
1074 atomic_inc(&cfqq->cfqg->ref); 1074 cfqq->cfqg->ref++;
1075} 1075}
1076 1076
1077static void cfq_put_cfqg(struct cfq_group *cfqg) 1077static void cfq_put_cfqg(struct cfq_group *cfqg)
@@ -1079,8 +1079,9 @@ static void cfq_put_cfqg(struct cfq_group *cfqg)
1079 struct cfq_rb_root *st; 1079 struct cfq_rb_root *st;
1080 int i, j; 1080 int i, j;
1081 1081
1082 BUG_ON(atomic_read(&cfqg->ref) <= 0); 1082 BUG_ON(cfqg->ref <= 0);
1083 if (!atomic_dec_and_test(&cfqg->ref)) 1083 cfqg->ref--;
1084 if (cfqg->ref)
1084 return; 1085 return;
1085 for_each_cfqg_st(cfqg, i, j, st) 1086 for_each_cfqg_st(cfqg, i, j, st)
1086 BUG_ON(!RB_EMPTY_ROOT(&st->rb)); 1087 BUG_ON(!RB_EMPTY_ROOT(&st->rb));
@@ -1188,7 +1189,7 @@ static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq,
1188 cfq_group_service_tree_del(cfqd, cfqq->cfqg); 1189 cfq_group_service_tree_del(cfqd, cfqq->cfqg);
1189 cfqq->orig_cfqg = cfqq->cfqg; 1190 cfqq->orig_cfqg = cfqq->cfqg;
1190 cfqq->cfqg = &cfqd->root_group; 1191 cfqq->cfqg = &cfqd->root_group;
1191 atomic_inc(&cfqd->root_group.ref); 1192 cfqd->root_group.ref++;
1192 group_changed = 1; 1193 group_changed = 1;
1193 } else if (!cfqd->cfq_group_isolation 1194 } else if (!cfqd->cfq_group_isolation
1194 && cfqq_type(cfqq) == SYNC_WORKLOAD && cfqq->orig_cfqg) { 1195 && cfqq_type(cfqq) == SYNC_WORKLOAD && cfqq->orig_cfqg) {
@@ -2025,7 +2026,7 @@ static int cfqq_process_refs(struct cfq_queue *cfqq)
2025 int process_refs, io_refs; 2026 int process_refs, io_refs;
2026 2027
2027 io_refs = cfqq->allocated[READ] + cfqq->allocated[WRITE]; 2028 io_refs = cfqq->allocated[READ] + cfqq->allocated[WRITE];
2028 process_refs = atomic_read(&cfqq->ref) - io_refs; 2029 process_refs = cfqq->ref - io_refs;
2029 BUG_ON(process_refs < 0); 2030 BUG_ON(process_refs < 0);
2030 return process_refs; 2031 return process_refs;
2031} 2032}
@@ -2065,10 +2066,10 @@ static void cfq_setup_merge(struct cfq_queue *cfqq, struct cfq_queue *new_cfqq)
2065 */ 2066 */
2066 if (new_process_refs >= process_refs) { 2067 if (new_process_refs >= process_refs) {
2067 cfqq->new_cfqq = new_cfqq; 2068 cfqq->new_cfqq = new_cfqq;
2068 atomic_add(process_refs, &new_cfqq->ref); 2069 new_cfqq->ref += process_refs;
2069 } else { 2070 } else {
2070 new_cfqq->new_cfqq = cfqq; 2071 new_cfqq->new_cfqq = cfqq;
2071 atomic_add(new_process_refs, &cfqq->ref); 2072 cfqq->ref += new_process_refs;
2072 } 2073 }
2073} 2074}
2074 2075
@@ -2103,12 +2104,6 @@ static void choose_service_tree(struct cfq_data *cfqd, struct cfq_group *cfqg)
2103 unsigned group_slice; 2104 unsigned group_slice;
2104 enum wl_prio_t original_prio = cfqd->serving_prio; 2105 enum wl_prio_t original_prio = cfqd->serving_prio;
2105 2106
2106 if (!cfqg) {
2107 cfqd->serving_prio = IDLE_WORKLOAD;
2108 cfqd->workload_expires = jiffies + 1;
2109 return;
2110 }
2111
2112 /* Choose next priority. RT > BE > IDLE */ 2107 /* Choose next priority. RT > BE > IDLE */
2113 if (cfq_group_busy_queues_wl(RT_WORKLOAD, cfqd, cfqg)) 2108 if (cfq_group_busy_queues_wl(RT_WORKLOAD, cfqd, cfqg))
2114 cfqd->serving_prio = RT_WORKLOAD; 2109 cfqd->serving_prio = RT_WORKLOAD;
@@ -2538,9 +2533,10 @@ static void cfq_put_queue(struct cfq_queue *cfqq)
2538 struct cfq_data *cfqd = cfqq->cfqd; 2533 struct cfq_data *cfqd = cfqq->cfqd;
2539 struct cfq_group *cfqg, *orig_cfqg; 2534 struct cfq_group *cfqg, *orig_cfqg;
2540 2535
2541 BUG_ON(atomic_read(&cfqq->ref) <= 0); 2536 BUG_ON(cfqq->ref <= 0);
2542 2537
2543 if (!atomic_dec_and_test(&cfqq->ref)) 2538 cfqq->ref--;
2539 if (cfqq->ref)
2544 return; 2540 return;
2545 2541
2546 cfq_log_cfqq(cfqd, cfqq, "put_queue"); 2542 cfq_log_cfqq(cfqd, cfqq, "put_queue");
@@ -2843,7 +2839,7 @@ static void cfq_init_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq,
2843 RB_CLEAR_NODE(&cfqq->p_node); 2839 RB_CLEAR_NODE(&cfqq->p_node);
2844 INIT_LIST_HEAD(&cfqq->fifo); 2840 INIT_LIST_HEAD(&cfqq->fifo);
2845 2841
2846 atomic_set(&cfqq->ref, 0); 2842 cfqq->ref = 0;
2847 cfqq->cfqd = cfqd; 2843 cfqq->cfqd = cfqd;
2848 2844
2849 cfq_mark_cfqq_prio_changed(cfqq); 2845 cfq_mark_cfqq_prio_changed(cfqq);
@@ -2979,11 +2975,11 @@ cfq_get_queue(struct cfq_data *cfqd, bool is_sync, struct io_context *ioc,
2979 * pin the queue now that it's allocated, scheduler exit will prune it 2975 * pin the queue now that it's allocated, scheduler exit will prune it
2980 */ 2976 */
2981 if (!is_sync && !(*async_cfqq)) { 2977 if (!is_sync && !(*async_cfqq)) {
2982 atomic_inc(&cfqq->ref); 2978 cfqq->ref++;
2983 *async_cfqq = cfqq; 2979 *async_cfqq = cfqq;
2984 } 2980 }
2985 2981
2986 atomic_inc(&cfqq->ref); 2982 cfqq->ref++;
2987 return cfqq; 2983 return cfqq;
2988} 2984}
2989 2985
@@ -3685,13 +3681,13 @@ new_queue:
3685 } 3681 }
3686 3682
3687 cfqq->allocated[rw]++; 3683 cfqq->allocated[rw]++;
3688 atomic_inc(&cfqq->ref); 3684 cfqq->ref++;
3689
3690 spin_unlock_irqrestore(q->queue_lock, flags);
3691
3692 rq->elevator_private = cic; 3685 rq->elevator_private = cic;
3693 rq->elevator_private2 = cfqq; 3686 rq->elevator_private2 = cfqq;
3694 rq->elevator_private3 = cfq_ref_get_cfqg(cfqq->cfqg); 3687 rq->elevator_private3 = cfq_ref_get_cfqg(cfqq->cfqg);
3688
3689 spin_unlock_irqrestore(q->queue_lock, flags);
3690
3695 return 0; 3691 return 0;
3696 3692
3697queue_fail: 3693queue_fail:
@@ -3866,6 +3862,10 @@ static void *cfq_init_queue(struct request_queue *q)
3866 if (!cfqd) 3862 if (!cfqd)
3867 return NULL; 3863 return NULL;
3868 3864
3865 /*
3866 * Don't need take queue_lock in the routine, since we are
3867 * initializing the ioscheduler, and nobody is using cfqd
3868 */
3869 cfqd->cic_index = i; 3869 cfqd->cic_index = i;
3870 3870
3871 /* Init root service tree */ 3871 /* Init root service tree */
@@ -3885,7 +3885,7 @@ static void *cfq_init_queue(struct request_queue *q)
3885 * Take a reference to root group which we never drop. This is just 3885 * Take a reference to root group which we never drop. This is just
3886 * to make sure that cfq_put_cfqg() does not try to kfree root group 3886 * to make sure that cfq_put_cfqg() does not try to kfree root group
3887 */ 3887 */
3888 atomic_set(&cfqg->ref, 1); 3888 cfqg->ref = 1;
3889 rcu_read_lock(); 3889 rcu_read_lock();
3890 cfq_blkiocg_add_blkio_group(&blkio_root_cgroup, &cfqg->blkg, 3890 cfq_blkiocg_add_blkio_group(&blkio_root_cgroup, &cfqg->blkg,
3891 (void *)cfqd, 0); 3891 (void *)cfqd, 0);
@@ -3905,7 +3905,7 @@ static void *cfq_init_queue(struct request_queue *q)
3905 * will not attempt to free it. 3905 * will not attempt to free it.
3906 */ 3906 */
3907 cfq_init_cfqq(cfqd, &cfqd->oom_cfqq, 1, 0); 3907 cfq_init_cfqq(cfqd, &cfqd->oom_cfqq, 1, 0);
3908 atomic_inc(&cfqd->oom_cfqq.ref); 3908 cfqd->oom_cfqq.ref++;
3909 cfq_link_cfqq_cfqg(&cfqd->oom_cfqq, &cfqd->root_group); 3909 cfq_link_cfqq_cfqg(&cfqd->oom_cfqq, &cfqd->root_group);
3910 3910
3911 INIT_LIST_HEAD(&cfqd->cic_list); 3911 INIT_LIST_HEAD(&cfqd->cic_list);
diff --git a/block/genhd.c b/block/genhd.c
index 5465a824d489..6a5b772aa201 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -244,7 +244,7 @@ static struct blk_major_name {
244} *major_names[BLKDEV_MAJOR_HASH_SIZE]; 244} *major_names[BLKDEV_MAJOR_HASH_SIZE];
245 245
246/* index in the above - for now: assume no multimajor ranges */ 246/* index in the above - for now: assume no multimajor ranges */
247static inline int major_to_index(int major) 247static inline int major_to_index(unsigned major)
248{ 248{
249 return major % BLKDEV_MAJOR_HASH_SIZE; 249 return major % BLKDEV_MAJOR_HASH_SIZE;
250} 250}
@@ -828,7 +828,7 @@ static void *show_partition_start(struct seq_file *seqf, loff_t *pos)
828 static void *p; 828 static void *p;
829 829
830 p = disk_seqf_start(seqf, pos); 830 p = disk_seqf_start(seqf, pos);
831 if (!IS_ERR(p) && p && !*pos) 831 if (!IS_ERR_OR_NULL(p) && !*pos)
832 seq_puts(seqf, "major minor #blocks name\n\n"); 832 seq_puts(seqf, "major minor #blocks name\n\n");
833 return p; 833 return p;
834} 834}
@@ -1264,6 +1264,8 @@ struct gendisk *alloc_disk_node(int minors, int node_id)
1264 } 1264 }
1265 disk->part_tbl->part[0] = &disk->part0; 1265 disk->part_tbl->part[0] = &disk->part0;
1266 1266
1267 hd_ref_init(&disk->part0);
1268
1267 disk->minors = minors; 1269 disk->minors = minors;
1268 rand_initialize_disk(disk); 1270 rand_initialize_disk(disk);
1269 disk_to_dev(disk)->class = &block_class; 1271 disk_to_dev(disk)->class = &block_class;
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 7ea0bea2f7e3..44e18c073c44 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -395,11 +395,7 @@ lo_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
395 struct loop_device *lo = p->lo; 395 struct loop_device *lo = p->lo;
396 struct page *page = buf->page; 396 struct page *page = buf->page;
397 sector_t IV; 397 sector_t IV;
398 int size, ret; 398 int size;
399
400 ret = buf->ops->confirm(pipe, buf);
401 if (unlikely(ret))
402 return ret;
403 399
404 IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9)) + 400 IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9)) +
405 (buf->offset >> 9); 401 (buf->offset >> 9);
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 0a2b5516bc21..f48a2f359ac4 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -630,7 +630,7 @@ static void dec_pending(struct dm_io *io, int error)
630 queue_io(md, bio); 630 queue_io(md, bio);
631 } else { 631 } else {
632 /* done with normal IO or empty flush */ 632 /* done with normal IO or empty flush */
633 trace_block_bio_complete(md->queue, bio); 633 trace_block_bio_complete(md->queue, bio, io_error);
634 bio_endio(bio, io_error); 634 bio_endio(bio, io_error);
635 } 635 }
636 } 636 }
diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c
index 4d0ff5ee27b8..e49cce234c65 100644
--- a/fs/bio-integrity.c
+++ b/fs/bio-integrity.c
@@ -782,7 +782,12 @@ void __init bio_integrity_init(void)
782{ 782{
783 unsigned int i; 783 unsigned int i;
784 784
785 kintegrityd_wq = create_workqueue("kintegrityd"); 785 /*
786 * kintegrityd won't block much but may burn a lot of CPU cycles.
787 * Make it highpri CPU intensive wq with max concurrency of 1.
788 */
789 kintegrityd_wq = alloc_workqueue("kintegrityd", WQ_MEM_RECLAIM |
790 WQ_HIGHPRI | WQ_CPU_INTENSIVE, 1);
786 if (!kintegrityd_wq) 791 if (!kintegrityd_wq)
787 panic("Failed to create kintegrityd\n"); 792 panic("Failed to create kintegrityd\n");
788 793
diff --git a/fs/char_dev.c b/fs/char_dev.c
index e5b9df993b93..143f0207c7eb 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -59,7 +59,7 @@ static struct char_device_struct {
59} *chrdevs[CHRDEV_MAJOR_HASH_SIZE]; 59} *chrdevs[CHRDEV_MAJOR_HASH_SIZE];
60 60
61/* index in the above */ 61/* index in the above */
62static inline int major_to_index(int major) 62static inline int major_to_index(unsigned major)
63{ 63{
64 return major % CHRDEV_MAJOR_HASH_SIZE; 64 return major % CHRDEV_MAJOR_HASH_SIZE;
65} 65}
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 184938fcff04..106ed482f119 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -845,11 +845,6 @@ nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
845 struct page **pp = rqstp->rq_respages + rqstp->rq_resused; 845 struct page **pp = rqstp->rq_respages + rqstp->rq_resused;
846 struct page *page = buf->page; 846 struct page *page = buf->page;
847 size_t size; 847 size_t size;
848 int ret;
849
850 ret = buf->ops->confirm(pipe, buf);
851 if (unlikely(ret))
852 return ret;
853 848
854 size = sd->len; 849 size = sd->len;
855 850
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 9a48d65d9855..9c21119512b9 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -381,6 +381,11 @@ static void delete_partition_rcu_cb(struct rcu_head *head)
381 put_device(part_to_dev(part)); 381 put_device(part_to_dev(part));
382} 382}
383 383
384void __delete_partition(struct hd_struct *part)
385{
386 call_rcu(&part->rcu_head, delete_partition_rcu_cb);
387}
388
384void delete_partition(struct gendisk *disk, int partno) 389void delete_partition(struct gendisk *disk, int partno)
385{ 390{
386 struct disk_part_tbl *ptbl = disk->part_tbl; 391 struct disk_part_tbl *ptbl = disk->part_tbl;
@@ -399,7 +404,7 @@ void delete_partition(struct gendisk *disk, int partno)
399 kobject_put(part->holder_dir); 404 kobject_put(part->holder_dir);
400 device_del(part_to_dev(part)); 405 device_del(part_to_dev(part));
401 406
402 call_rcu(&part->rcu_head, delete_partition_rcu_cb); 407 hd_struct_put(part);
403} 408}
404 409
405static ssize_t whole_disk_show(struct device *dev, 410static ssize_t whole_disk_show(struct device *dev,
@@ -498,6 +503,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
498 if (!dev_get_uevent_suppress(ddev)) 503 if (!dev_get_uevent_suppress(ddev))
499 kobject_uevent(&pdev->kobj, KOBJ_ADD); 504 kobject_uevent(&pdev->kobj, KOBJ_ADD);
500 505
506 hd_ref_init(p);
501 return p; 507 return p;
502 508
503out_free_info: 509out_free_info:
diff --git a/fs/splice.c b/fs/splice.c
index 8f1dfaecc8f0..d2026382ac3e 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -682,19 +682,14 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe,
682{ 682{
683 struct file *file = sd->u.file; 683 struct file *file = sd->u.file;
684 loff_t pos = sd->pos; 684 loff_t pos = sd->pos;
685 int ret, more; 685 int more;
686
687 ret = buf->ops->confirm(pipe, buf);
688 if (!ret) {
689 more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len;
690 if (file->f_op && file->f_op->sendpage)
691 ret = file->f_op->sendpage(file, buf->page, buf->offset,
692 sd->len, &pos, more);
693 else
694 ret = -EINVAL;
695 }
696 686
697 return ret; 687 if (!likely(file->f_op && file->f_op->sendpage))
688 return -EINVAL;
689
690 more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len;
691 return file->f_op->sendpage(file, buf->page, buf->offset,
692 sd->len, &pos, more);
698} 693}
699 694
700/* 695/*
@@ -727,13 +722,6 @@ int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
727 void *fsdata; 722 void *fsdata;
728 int ret; 723 int ret;
729 724
730 /*
731 * make sure the data in this buffer is uptodate
732 */
733 ret = buf->ops->confirm(pipe, buf);
734 if (unlikely(ret))
735 return ret;
736
737 offset = sd->pos & ~PAGE_CACHE_MASK; 725 offset = sd->pos & ~PAGE_CACHE_MASK;
738 726
739 this_len = sd->len; 727 this_len = sd->len;
@@ -805,12 +793,17 @@ int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_desc *sd,
805 if (sd->len > sd->total_len) 793 if (sd->len > sd->total_len)
806 sd->len = sd->total_len; 794 sd->len = sd->total_len;
807 795
808 ret = actor(pipe, buf, sd); 796 ret = buf->ops->confirm(pipe, buf);
809 if (ret <= 0) { 797 if (unlikely(ret)) {
810 if (ret == -ENODATA) 798 if (ret == -ENODATA)
811 ret = 0; 799 ret = 0;
812 return ret; 800 return ret;
813 } 801 }
802
803 ret = actor(pipe, buf, sd);
804 if (ret <= 0)
805 return ret;
806
814 buf->offset += ret; 807 buf->offset += ret;
815 buf->len -= ret; 808 buf->len -= ret;
816 809
@@ -1044,10 +1037,6 @@ static int write_pipe_buf(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
1044 int ret; 1037 int ret;
1045 void *data; 1038 void *data;
1046 1039
1047 ret = buf->ops->confirm(pipe, buf);
1048 if (ret)
1049 return ret;
1050
1051 data = buf->ops->map(pipe, buf, 0); 1040 data = buf->ops->map(pipe, buf, 0);
1052 ret = kernel_write(sd->u.file, data + buf->offset, sd->len, sd->pos); 1041 ret = kernel_write(sd->u.file, data + buf->offset, sd->len, sd->pos);
1053 buf->ops->unmap(pipe, buf, data); 1042 buf->ops->unmap(pipe, buf, data);
@@ -1507,10 +1496,6 @@ static int pipe_to_user(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
1507 char *src; 1496 char *src;
1508 int ret; 1497 int ret;
1509 1498
1510 ret = buf->ops->confirm(pipe, buf);
1511 if (unlikely(ret))
1512 return ret;
1513
1514 /* 1499 /*
1515 * See if we can use the atomic maps, by prefaulting in the 1500 * See if we can use the atomic maps, by prefaulting in the
1516 * pages and doing an atomic copy 1501 * pages and doing an atomic copy
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 05667e6989f1..5730043eb15a 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -115,6 +115,7 @@ struct request {
115 void *elevator_private3; 115 void *elevator_private3;
116 116
117 struct gendisk *rq_disk; 117 struct gendisk *rq_disk;
118 struct hd_struct *part;
118 unsigned long start_time; 119 unsigned long start_time;
119#ifdef CONFIG_BLK_CGROUP 120#ifdef CONFIG_BLK_CGROUP
120 unsigned long long start_time_ns; 121 unsigned long long start_time_ns;
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 13893aa2ac9d..c0d5f6945c1e 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -115,6 +115,7 @@ struct hd_struct {
115#else 115#else
116 struct disk_stats dkstats; 116 struct disk_stats dkstats;
117#endif 117#endif
118 atomic_t ref;
118 struct rcu_head rcu_head; 119 struct rcu_head rcu_head;
119}; 120};
120 121
@@ -597,6 +598,7 @@ extern struct hd_struct * __must_check add_partition(struct gendisk *disk,
597 sector_t len, int flags, 598 sector_t len, int flags,
598 struct partition_meta_info 599 struct partition_meta_info
599 *info); 600 *info);
601extern void __delete_partition(struct hd_struct *);
600extern void delete_partition(struct gendisk *, int); 602extern void delete_partition(struct gendisk *, int);
601extern void printk_all_partitions(void); 603extern void printk_all_partitions(void);
602 604
@@ -625,6 +627,29 @@ extern ssize_t part_fail_store(struct device *dev,
625 const char *buf, size_t count); 627 const char *buf, size_t count);
626#endif /* CONFIG_FAIL_MAKE_REQUEST */ 628#endif /* CONFIG_FAIL_MAKE_REQUEST */
627 629
630static inline void hd_ref_init(struct hd_struct *part)
631{
632 atomic_set(&part->ref, 1);
633 smp_mb();
634}
635
636static inline void hd_struct_get(struct hd_struct *part)
637{
638 atomic_inc(&part->ref);
639 smp_mb__after_atomic_inc();
640}
641
642static inline int hd_struct_try_get(struct hd_struct *part)
643{
644 return atomic_inc_not_zero(&part->ref);
645}
646
647static inline void hd_struct_put(struct hd_struct *part)
648{
649 if (atomic_dec_and_test(&part->ref))
650 __delete_partition(part);
651}
652
628#else /* CONFIG_BLOCK */ 653#else /* CONFIG_BLOCK */
629 654
630static inline void printk_all_partitions(void) { } 655static inline void printk_all_partitions(void) { }
diff --git a/include/trace/events/block.h b/include/trace/events/block.h
index b56c65dc105d..aba421d68f6f 100644
--- a/include/trace/events/block.h
+++ b/include/trace/events/block.h
@@ -206,15 +206,16 @@ TRACE_EVENT(block_bio_bounce,
206 * block_bio_complete - completed all work on the block operation 206 * block_bio_complete - completed all work on the block operation
207 * @q: queue holding the block operation 207 * @q: queue holding the block operation
208 * @bio: block operation completed 208 * @bio: block operation completed
209 * @error: io error value
209 * 210 *
210 * This tracepoint indicates there is no further work to do on this 211 * This tracepoint indicates there is no further work to do on this
211 * block IO operation @bio. 212 * block IO operation @bio.
212 */ 213 */
213TRACE_EVENT(block_bio_complete, 214TRACE_EVENT(block_bio_complete,
214 215
215 TP_PROTO(struct request_queue *q, struct bio *bio), 216 TP_PROTO(struct request_queue *q, struct bio *bio, int error),
216 217
217 TP_ARGS(q, bio), 218 TP_ARGS(q, bio, error),
218 219
219 TP_STRUCT__entry( 220 TP_STRUCT__entry(
220 __field( dev_t, dev ) 221 __field( dev_t, dev )
@@ -228,6 +229,7 @@ TRACE_EVENT(block_bio_complete,
228 __entry->dev = bio->bi_bdev->bd_dev; 229 __entry->dev = bio->bi_bdev->bd_dev;
229 __entry->sector = bio->bi_sector; 230 __entry->sector = bio->bi_sector;
230 __entry->nr_sector = bio->bi_size >> 9; 231 __entry->nr_sector = bio->bi_size >> 9;
232 __entry->error = error;
231 blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size); 233 blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size);
232 ), 234 ),
233 235
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index 2b8e2ee7c0ef..153562d0b93c 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -758,53 +758,58 @@ static void blk_add_trace_rq_complete(void *ignore,
758 * @q: queue the io is for 758 * @q: queue the io is for
759 * @bio: the source bio 759 * @bio: the source bio
760 * @what: the action 760 * @what: the action
761 * @error: error, if any
761 * 762 *
762 * Description: 763 * Description:
763 * Records an action against a bio. Will log the bio offset + size. 764 * Records an action against a bio. Will log the bio offset + size.
764 * 765 *
765 **/ 766 **/
766static void blk_add_trace_bio(struct request_queue *q, struct bio *bio, 767static void blk_add_trace_bio(struct request_queue *q, struct bio *bio,
767 u32 what) 768 u32 what, int error)
768{ 769{
769 struct blk_trace *bt = q->blk_trace; 770 struct blk_trace *bt = q->blk_trace;
770 771
771 if (likely(!bt)) 772 if (likely(!bt))
772 return; 773 return;
773 774
775 if (!error && !bio_flagged(bio, BIO_UPTODATE))
776 error = EIO;
777
774 __blk_add_trace(bt, bio->bi_sector, bio->bi_size, bio->bi_rw, what, 778 __blk_add_trace(bt, bio->bi_sector, bio->bi_size, bio->bi_rw, what,
775 !bio_flagged(bio, BIO_UPTODATE), 0, NULL); 779 error, 0, NULL);
776} 780}
777 781
778static void blk_add_trace_bio_bounce(void *ignore, 782static void blk_add_trace_bio_bounce(void *ignore,
779 struct request_queue *q, struct bio *bio) 783 struct request_queue *q, struct bio *bio)
780{ 784{
781 blk_add_trace_bio(q, bio, BLK_TA_BOUNCE); 785 blk_add_trace_bio(q, bio, BLK_TA_BOUNCE, 0);
782} 786}
783 787
784static void blk_add_trace_bio_complete(void *ignore, 788static void blk_add_trace_bio_complete(void *ignore,
785 struct request_queue *q, struct bio *bio) 789 struct request_queue *q, struct bio *bio,
790 int error)
786{ 791{
787 blk_add_trace_bio(q, bio, BLK_TA_COMPLETE); 792 blk_add_trace_bio(q, bio, BLK_TA_COMPLETE, error);
788} 793}
789 794
790static void blk_add_trace_bio_backmerge(void *ignore, 795static void blk_add_trace_bio_backmerge(void *ignore,
791 struct request_queue *q, 796 struct request_queue *q,
792 struct bio *bio) 797 struct bio *bio)
793{ 798{
794 blk_add_trace_bio(q, bio, BLK_TA_BACKMERGE); 799 blk_add_trace_bio(q, bio, BLK_TA_BACKMERGE, 0);
795} 800}
796 801
797static void blk_add_trace_bio_frontmerge(void *ignore, 802static void blk_add_trace_bio_frontmerge(void *ignore,
798 struct request_queue *q, 803 struct request_queue *q,
799 struct bio *bio) 804 struct bio *bio)
800{ 805{
801 blk_add_trace_bio(q, bio, BLK_TA_FRONTMERGE); 806 blk_add_trace_bio(q, bio, BLK_TA_FRONTMERGE, 0);
802} 807}
803 808
804static void blk_add_trace_bio_queue(void *ignore, 809static void blk_add_trace_bio_queue(void *ignore,
805 struct request_queue *q, struct bio *bio) 810 struct request_queue *q, struct bio *bio)
806{ 811{
807 blk_add_trace_bio(q, bio, BLK_TA_QUEUE); 812 blk_add_trace_bio(q, bio, BLK_TA_QUEUE, 0);
808} 813}
809 814
810static void blk_add_trace_getrq(void *ignore, 815static void blk_add_trace_getrq(void *ignore,
@@ -812,7 +817,7 @@ static void blk_add_trace_getrq(void *ignore,
812 struct bio *bio, int rw) 817 struct bio *bio, int rw)
813{ 818{
814 if (bio) 819 if (bio)
815 blk_add_trace_bio(q, bio, BLK_TA_GETRQ); 820 blk_add_trace_bio(q, bio, BLK_TA_GETRQ, 0);
816 else { 821 else {
817 struct blk_trace *bt = q->blk_trace; 822 struct blk_trace *bt = q->blk_trace;
818 823
@@ -827,7 +832,7 @@ static void blk_add_trace_sleeprq(void *ignore,
827 struct bio *bio, int rw) 832 struct bio *bio, int rw)
828{ 833{
829 if (bio) 834 if (bio)
830 blk_add_trace_bio(q, bio, BLK_TA_SLEEPRQ); 835 blk_add_trace_bio(q, bio, BLK_TA_SLEEPRQ, 0);
831 else { 836 else {
832 struct blk_trace *bt = q->blk_trace; 837 struct blk_trace *bt = q->blk_trace;
833 838