aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2013-11-22 18:57:08 -0500
committerEric Paris <eparis@redhat.com>2013-11-22 18:57:54 -0500
commitfc582aef7dcc27a7120cf232c1e76c569c7b6eab (patch)
tree7d275dd4ceab6067b91e9a25a5f6338b425fbccd /block
parent9175c9d2aed528800175ef81c90569d00d23f9be (diff)
parent5e01dc7b26d9f24f39abace5da98ccbd6a5ceb52 (diff)
Merge tag 'v3.12'
Linux 3.12 Conflicts: fs/exec.c
Diffstat (limited to 'block')
-rw-r--r--block/Kconfig11
-rw-r--r--block/Makefile1
-rw-r--r--block/blk-cgroup.c74
-rw-r--r--block/blk-cgroup.h38
-rw-r--r--block/blk-core.c12
-rw-r--r--block/blk-exec.c4
-rw-r--r--block/blk-ioc.c2
-rw-r--r--block/blk-sysfs.c2
-rw-r--r--block/blk-throttle.c43
-rw-r--r--block/cfq-iosched.c94
-rw-r--r--block/cmdline-parser.c250
-rw-r--r--block/compat_ioctl.c2
-rw-r--r--block/deadline-iosched.c2
-rw-r--r--block/elevator.c2
-rw-r--r--block/genhd.c3
-rw-r--r--block/partitions/Kconfig7
-rw-r--r--block/partitions/Makefile1
-rw-r--r--block/partitions/check.c4
-rw-r--r--block/partitions/cmdline.c99
-rw-r--r--block/partitions/cmdline.h2
-rw-r--r--block/partitions/efi.c180
-rw-r--r--block/partitions/efi.h38
22 files changed, 649 insertions, 222 deletions
diff --git a/block/Kconfig b/block/Kconfig
index a7e40a7c8214..2429515c05c2 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -99,6 +99,17 @@ config BLK_DEV_THROTTLING
99 99
100 See Documentation/cgroups/blkio-controller.txt for more information. 100 See Documentation/cgroups/blkio-controller.txt for more information.
101 101
102config BLK_CMDLINE_PARSER
103 bool "Block device command line partition parser"
104 default n
105 ---help---
106 Enabling this option allows you to specify the partition layout from
107 the kernel boot args. This is typically of use for embedded devices
108 which don't otherwise have any standardized method for listing the
109 partitions on a block device.
110
111 See Documentation/block/cmdline-partition.txt for more information.
112
102menu "Partition Types" 113menu "Partition Types"
103 114
104source "block/partitions/Kconfig" 115source "block/partitions/Kconfig"
diff --git a/block/Makefile b/block/Makefile
index 39b76ba66ffd..671a83d063a5 100644
--- a/block/Makefile
+++ b/block/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o
18 18
19obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o 19obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o
20obj-$(CONFIG_BLK_DEV_INTEGRITY) += blk-integrity.o 20obj-$(CONFIG_BLK_DEV_INTEGRITY) += blk-integrity.o
21obj-$(CONFIG_BLK_CMDLINE_PARSER) += cmdline-parser.o
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index 290792a13e3c..4e491d9b5292 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -235,8 +235,13 @@ static struct blkcg_gq *blkg_create(struct blkcg *blkcg,
235 blkg->online = true; 235 blkg->online = true;
236 spin_unlock(&blkcg->lock); 236 spin_unlock(&blkcg->lock);
237 237
238 if (!ret) 238 if (!ret) {
239 if (blkcg == &blkcg_root) {
240 q->root_blkg = blkg;
241 q->root_rl.blkg = blkg;
242 }
239 return blkg; 243 return blkg;
244 }
240 245
241 /* @blkg failed fully initialized, use the usual release path */ 246 /* @blkg failed fully initialized, use the usual release path */
242 blkg_put(blkg); 247 blkg_put(blkg);
@@ -335,6 +340,15 @@ static void blkg_destroy(struct blkcg_gq *blkg)
335 rcu_assign_pointer(blkcg->blkg_hint, NULL); 340 rcu_assign_pointer(blkcg->blkg_hint, NULL);
336 341
337 /* 342 /*
343 * If root blkg is destroyed. Just clear the pointer since root_rl
344 * does not take reference on root blkg.
345 */
346 if (blkcg == &blkcg_root) {
347 blkg->q->root_blkg = NULL;
348 blkg->q->root_rl.blkg = NULL;
349 }
350
351 /*
338 * Put the reference taken at the time of creation so that when all 352 * Put the reference taken at the time of creation so that when all
339 * queues are gone, group can be destroyed. 353 * queues are gone, group can be destroyed.
340 */ 354 */
@@ -360,13 +374,6 @@ static void blkg_destroy_all(struct request_queue *q)
360 blkg_destroy(blkg); 374 blkg_destroy(blkg);
361 spin_unlock(&blkcg->lock); 375 spin_unlock(&blkcg->lock);
362 } 376 }
363
364 /*
365 * root blkg is destroyed. Just clear the pointer since
366 * root_rl does not take reference on root blkg.
367 */
368 q->root_blkg = NULL;
369 q->root_rl.blkg = NULL;
370} 377}
371 378
372/* 379/*
@@ -437,10 +444,10 @@ struct request_list *__blk_queue_next_rl(struct request_list *rl,
437 return &blkg->rl; 444 return &blkg->rl;
438} 445}
439 446
440static int blkcg_reset_stats(struct cgroup *cgroup, struct cftype *cftype, 447static int blkcg_reset_stats(struct cgroup_subsys_state *css,
441 u64 val) 448 struct cftype *cftype, u64 val)
442{ 449{
443 struct blkcg *blkcg = cgroup_to_blkcg(cgroup); 450 struct blkcg *blkcg = css_to_blkcg(css);
444 struct blkcg_gq *blkg; 451 struct blkcg_gq *blkg;
445 int i; 452 int i;
446 453
@@ -614,15 +621,13 @@ u64 blkg_stat_recursive_sum(struct blkg_policy_data *pd, int off)
614{ 621{
615 struct blkcg_policy *pol = blkcg_policy[pd->plid]; 622 struct blkcg_policy *pol = blkcg_policy[pd->plid];
616 struct blkcg_gq *pos_blkg; 623 struct blkcg_gq *pos_blkg;
617 struct cgroup *pos_cgrp; 624 struct cgroup_subsys_state *pos_css;
618 u64 sum; 625 u64 sum = 0;
619 626
620 lockdep_assert_held(pd->blkg->q->queue_lock); 627 lockdep_assert_held(pd->blkg->q->queue_lock);
621 628
622 sum = blkg_stat_read((void *)pd + off);
623
624 rcu_read_lock(); 629 rcu_read_lock();
625 blkg_for_each_descendant_pre(pos_blkg, pos_cgrp, pd_to_blkg(pd)) { 630 blkg_for_each_descendant_pre(pos_blkg, pos_css, pd_to_blkg(pd)) {
626 struct blkg_policy_data *pos_pd = blkg_to_pd(pos_blkg, pol); 631 struct blkg_policy_data *pos_pd = blkg_to_pd(pos_blkg, pol);
627 struct blkg_stat *stat = (void *)pos_pd + off; 632 struct blkg_stat *stat = (void *)pos_pd + off;
628 633
@@ -649,16 +654,14 @@ struct blkg_rwstat blkg_rwstat_recursive_sum(struct blkg_policy_data *pd,
649{ 654{
650 struct blkcg_policy *pol = blkcg_policy[pd->plid]; 655 struct blkcg_policy *pol = blkcg_policy[pd->plid];
651 struct blkcg_gq *pos_blkg; 656 struct blkcg_gq *pos_blkg;
652 struct cgroup *pos_cgrp; 657 struct cgroup_subsys_state *pos_css;
653 struct blkg_rwstat sum; 658 struct blkg_rwstat sum = { };
654 int i; 659 int i;
655 660
656 lockdep_assert_held(pd->blkg->q->queue_lock); 661 lockdep_assert_held(pd->blkg->q->queue_lock);
657 662
658 sum = blkg_rwstat_read((void *)pd + off);
659
660 rcu_read_lock(); 663 rcu_read_lock();
661 blkg_for_each_descendant_pre(pos_blkg, pos_cgrp, pd_to_blkg(pd)) { 664 blkg_for_each_descendant_pre(pos_blkg, pos_css, pd_to_blkg(pd)) {
662 struct blkg_policy_data *pos_pd = blkg_to_pd(pos_blkg, pol); 665 struct blkg_policy_data *pos_pd = blkg_to_pd(pos_blkg, pol);
663 struct blkg_rwstat *rwstat = (void *)pos_pd + off; 666 struct blkg_rwstat *rwstat = (void *)pos_pd + off;
664 struct blkg_rwstat tmp; 667 struct blkg_rwstat tmp;
@@ -765,18 +768,18 @@ struct cftype blkcg_files[] = {
765 768
766/** 769/**
767 * blkcg_css_offline - cgroup css_offline callback 770 * blkcg_css_offline - cgroup css_offline callback
768 * @cgroup: cgroup of interest 771 * @css: css of interest
769 * 772 *
770 * This function is called when @cgroup is about to go away and responsible 773 * This function is called when @css is about to go away and responsible
771 * for shooting down all blkgs associated with @cgroup. blkgs should be 774 * for shooting down all blkgs associated with @css. blkgs should be
772 * removed while holding both q and blkcg locks. As blkcg lock is nested 775 * removed while holding both q and blkcg locks. As blkcg lock is nested
773 * inside q lock, this function performs reverse double lock dancing. 776 * inside q lock, this function performs reverse double lock dancing.
774 * 777 *
775 * This is the blkcg counterpart of ioc_release_fn(). 778 * This is the blkcg counterpart of ioc_release_fn().
776 */ 779 */
777static void blkcg_css_offline(struct cgroup *cgroup) 780static void blkcg_css_offline(struct cgroup_subsys_state *css)
778{ 781{
779 struct blkcg *blkcg = cgroup_to_blkcg(cgroup); 782 struct blkcg *blkcg = css_to_blkcg(css);
780 783
781 spin_lock_irq(&blkcg->lock); 784 spin_lock_irq(&blkcg->lock);
782 785
@@ -798,21 +801,21 @@ static void blkcg_css_offline(struct cgroup *cgroup)
798 spin_unlock_irq(&blkcg->lock); 801 spin_unlock_irq(&blkcg->lock);
799} 802}
800 803
801static void blkcg_css_free(struct cgroup *cgroup) 804static void blkcg_css_free(struct cgroup_subsys_state *css)
802{ 805{
803 struct blkcg *blkcg = cgroup_to_blkcg(cgroup); 806 struct blkcg *blkcg = css_to_blkcg(css);
804 807
805 if (blkcg != &blkcg_root) 808 if (blkcg != &blkcg_root)
806 kfree(blkcg); 809 kfree(blkcg);
807} 810}
808 811
809static struct cgroup_subsys_state *blkcg_css_alloc(struct cgroup *cgroup) 812static struct cgroup_subsys_state *
813blkcg_css_alloc(struct cgroup_subsys_state *parent_css)
810{ 814{
811 static atomic64_t id_seq = ATOMIC64_INIT(0); 815 static atomic64_t id_seq = ATOMIC64_INIT(0);
812 struct blkcg *blkcg; 816 struct blkcg *blkcg;
813 struct cgroup *parent = cgroup->parent;
814 817
815 if (!parent) { 818 if (!parent_css) {
816 blkcg = &blkcg_root; 819 blkcg = &blkcg_root;
817 goto done; 820 goto done;
818 } 821 }
@@ -883,14 +886,15 @@ void blkcg_exit_queue(struct request_queue *q)
883 * of the main cic data structures. For now we allow a task to change 886 * of the main cic data structures. For now we allow a task to change
884 * its cgroup only if it's the only owner of its ioc. 887 * its cgroup only if it's the only owner of its ioc.
885 */ 888 */
886static int blkcg_can_attach(struct cgroup *cgrp, struct cgroup_taskset *tset) 889static int blkcg_can_attach(struct cgroup_subsys_state *css,
890 struct cgroup_taskset *tset)
887{ 891{
888 struct task_struct *task; 892 struct task_struct *task;
889 struct io_context *ioc; 893 struct io_context *ioc;
890 int ret = 0; 894 int ret = 0;
891 895
892 /* task_lock() is needed to avoid races with exit_io_context() */ 896 /* task_lock() is needed to avoid races with exit_io_context() */
893 cgroup_taskset_for_each(task, cgrp, tset) { 897 cgroup_taskset_for_each(task, css, tset) {
894 task_lock(task); 898 task_lock(task);
895 ioc = task->io_context; 899 ioc = task->io_context;
896 if (ioc && atomic_read(&ioc->nr_tasks) > 1) 900 if (ioc && atomic_read(&ioc->nr_tasks) > 1)
@@ -973,8 +977,6 @@ int blkcg_activate_policy(struct request_queue *q,
973 ret = PTR_ERR(blkg); 977 ret = PTR_ERR(blkg);
974 goto out_unlock; 978 goto out_unlock;
975 } 979 }
976 q->root_blkg = blkg;
977 q->root_rl.blkg = blkg;
978 980
979 list_for_each_entry(blkg, &q->blkg_list, q_node) 981 list_for_each_entry(blkg, &q->blkg_list, q_node)
980 cnt++; 982 cnt++;
@@ -1127,7 +1129,7 @@ void blkcg_policy_unregister(struct blkcg_policy *pol)
1127 1129
1128 /* kill the intf files first */ 1130 /* kill the intf files first */
1129 if (pol->cftypes) 1131 if (pol->cftypes)
1130 cgroup_rm_cftypes(&blkio_subsys, pol->cftypes); 1132 cgroup_rm_cftypes(pol->cftypes);
1131 1133
1132 /* unregister and update blkgs */ 1134 /* unregister and update blkgs */
1133 blkcg_policy[pol->plid] = NULL; 1135 blkcg_policy[pol->plid] = NULL;
diff --git a/block/blk-cgroup.h b/block/blk-cgroup.h
index 8056c03a3382..ae6969a7ffd4 100644
--- a/block/blk-cgroup.h
+++ b/block/blk-cgroup.h
@@ -179,22 +179,20 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
179void blkg_conf_finish(struct blkg_conf_ctx *ctx); 179void blkg_conf_finish(struct blkg_conf_ctx *ctx);
180 180
181 181
182static inline struct blkcg *cgroup_to_blkcg(struct cgroup *cgroup) 182static inline struct blkcg *css_to_blkcg(struct cgroup_subsys_state *css)
183{ 183{
184 return container_of(cgroup_subsys_state(cgroup, blkio_subsys_id), 184 return css ? container_of(css, struct blkcg, css) : NULL;
185 struct blkcg, css);
186} 185}
187 186
188static inline struct blkcg *task_blkcg(struct task_struct *tsk) 187static inline struct blkcg *task_blkcg(struct task_struct *tsk)
189{ 188{
190 return container_of(task_subsys_state(tsk, blkio_subsys_id), 189 return css_to_blkcg(task_css(tsk, blkio_subsys_id));
191 struct blkcg, css);
192} 190}
193 191
194static inline struct blkcg *bio_blkcg(struct bio *bio) 192static inline struct blkcg *bio_blkcg(struct bio *bio)
195{ 193{
196 if (bio && bio->bi_css) 194 if (bio && bio->bi_css)
197 return container_of(bio->bi_css, struct blkcg, css); 195 return css_to_blkcg(bio->bi_css);
198 return task_blkcg(current); 196 return task_blkcg(current);
199} 197}
200 198
@@ -206,9 +204,7 @@ static inline struct blkcg *bio_blkcg(struct bio *bio)
206 */ 204 */
207static inline struct blkcg *blkcg_parent(struct blkcg *blkcg) 205static inline struct blkcg *blkcg_parent(struct blkcg *blkcg)
208{ 206{
209 struct cgroup *pcg = blkcg->css.cgroup->parent; 207 return css_to_blkcg(css_parent(&blkcg->css));
210
211 return pcg ? cgroup_to_blkcg(pcg) : NULL;
212} 208}
213 209
214/** 210/**
@@ -288,32 +284,33 @@ struct blkcg_gq *__blkg_lookup(struct blkcg *blkcg, struct request_queue *q,
288/** 284/**
289 * blkg_for_each_descendant_pre - pre-order walk of a blkg's descendants 285 * blkg_for_each_descendant_pre - pre-order walk of a blkg's descendants
290 * @d_blkg: loop cursor pointing to the current descendant 286 * @d_blkg: loop cursor pointing to the current descendant
291 * @pos_cgrp: used for iteration 287 * @pos_css: used for iteration
292 * @p_blkg: target blkg to walk descendants of 288 * @p_blkg: target blkg to walk descendants of
293 * 289 *
294 * Walk @c_blkg through the descendants of @p_blkg. Must be used with RCU 290 * Walk @c_blkg through the descendants of @p_blkg. Must be used with RCU
295 * read locked. If called under either blkcg or queue lock, the iteration 291 * read locked. If called under either blkcg or queue lock, the iteration
296 * is guaranteed to include all and only online blkgs. The caller may 292 * is guaranteed to include all and only online blkgs. The caller may
297 * update @pos_cgrp by calling cgroup_rightmost_descendant() to skip 293 * update @pos_css by calling css_rightmost_descendant() to skip subtree.
298 * subtree. 294 * @p_blkg is included in the iteration and the first node to be visited.
299 */ 295 */
300#define blkg_for_each_descendant_pre(d_blkg, pos_cgrp, p_blkg) \ 296#define blkg_for_each_descendant_pre(d_blkg, pos_css, p_blkg) \
301 cgroup_for_each_descendant_pre((pos_cgrp), (p_blkg)->blkcg->css.cgroup) \ 297 css_for_each_descendant_pre((pos_css), &(p_blkg)->blkcg->css) \
302 if (((d_blkg) = __blkg_lookup(cgroup_to_blkcg(pos_cgrp), \ 298 if (((d_blkg) = __blkg_lookup(css_to_blkcg(pos_css), \
303 (p_blkg)->q, false))) 299 (p_blkg)->q, false)))
304 300
305/** 301/**
306 * blkg_for_each_descendant_post - post-order walk of a blkg's descendants 302 * blkg_for_each_descendant_post - post-order walk of a blkg's descendants
307 * @d_blkg: loop cursor pointing to the current descendant 303 * @d_blkg: loop cursor pointing to the current descendant
308 * @pos_cgrp: used for iteration 304 * @pos_css: used for iteration
309 * @p_blkg: target blkg to walk descendants of 305 * @p_blkg: target blkg to walk descendants of
310 * 306 *
311 * Similar to blkg_for_each_descendant_pre() but performs post-order 307 * Similar to blkg_for_each_descendant_pre() but performs post-order
312 * traversal instead. Synchronization rules are the same. 308 * traversal instead. Synchronization rules are the same. @p_blkg is
309 * included in the iteration and the last node to be visited.
313 */ 310 */
314#define blkg_for_each_descendant_post(d_blkg, pos_cgrp, p_blkg) \ 311#define blkg_for_each_descendant_post(d_blkg, pos_css, p_blkg) \
315 cgroup_for_each_descendant_post((pos_cgrp), (p_blkg)->blkcg->css.cgroup) \ 312 css_for_each_descendant_post((pos_css), &(p_blkg)->blkcg->css) \
316 if (((d_blkg) = __blkg_lookup(cgroup_to_blkcg(pos_cgrp), \ 313 if (((d_blkg) = __blkg_lookup(css_to_blkcg(pos_css), \
317 (p_blkg)->q, false))) 314 (p_blkg)->q, false)))
318 315
319/** 316/**
@@ -576,7 +573,6 @@ static inline int blkcg_activate_policy(struct request_queue *q,
576static inline void blkcg_deactivate_policy(struct request_queue *q, 573static inline void blkcg_deactivate_policy(struct request_queue *q,
577 const struct blkcg_policy *pol) { } 574 const struct blkcg_policy *pol) { }
578 575
579static inline struct blkcg *cgroup_to_blkcg(struct cgroup *cgroup) { return NULL; }
580static inline struct blkcg *bio_blkcg(struct bio *bio) { return NULL; } 576static inline struct blkcg *bio_blkcg(struct bio *bio) { return NULL; }
581 577
582static inline struct blkg_policy_data *blkg_to_pd(struct blkcg_gq *blkg, 578static inline struct blkg_policy_data *blkg_to_pd(struct blkcg_gq *blkg,
diff --git a/block/blk-core.c b/block/blk-core.c
index 93a18d1d3da8..0a00e4ecf87c 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1549,11 +1549,9 @@ get_rq:
1549 if (plug) { 1549 if (plug) {
1550 /* 1550 /*
1551 * If this is the first request added after a plug, fire 1551 * If this is the first request added after a plug, fire
1552 * of a plug trace. If others have been added before, check 1552 * of a plug trace.
1553 * if we have multiple devices in this plug. If so, make a
1554 * note to sort the list before dispatch.
1555 */ 1553 */
1556 if (list_empty(&plug->list)) 1554 if (!request_count)
1557 trace_block_plug(q); 1555 trace_block_plug(q);
1558 else { 1556 else {
1559 if (request_count >= BLK_MAX_REQUEST_COUNT) { 1557 if (request_count >= BLK_MAX_REQUEST_COUNT) {
@@ -2318,6 +2316,12 @@ bool blk_update_request(struct request *req, int error, unsigned int nr_bytes)
2318 case -ETIMEDOUT: 2316 case -ETIMEDOUT:
2319 error_type = "timeout"; 2317 error_type = "timeout";
2320 break; 2318 break;
2319 case -ENOSPC:
2320 error_type = "critical space allocation";
2321 break;
2322 case -ENODATA:
2323 error_type = "critical medium";
2324 break;
2321 case -EIO: 2325 case -EIO:
2322 default: 2326 default:
2323 error_type = "I/O"; 2327 error_type = "I/O";
diff --git a/block/blk-exec.c b/block/blk-exec.c
index e70621396129..ae4f27d7944e 100644
--- a/block/blk-exec.c
+++ b/block/blk-exec.c
@@ -68,9 +68,9 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
68 spin_lock_irq(q->queue_lock); 68 spin_lock_irq(q->queue_lock);
69 69
70 if (unlikely(blk_queue_dying(q))) { 70 if (unlikely(blk_queue_dying(q))) {
71 rq->cmd_flags |= REQ_QUIET;
71 rq->errors = -ENXIO; 72 rq->errors = -ENXIO;
72 if (rq->end_io) 73 __blk_end_request_all(rq, rq->errors);
73 rq->end_io(rq, rq->errors);
74 spin_unlock_irq(q->queue_lock); 74 spin_unlock_irq(q->queue_lock);
75 return; 75 return;
76 } 76 }
diff --git a/block/blk-ioc.c b/block/blk-ioc.c
index 4464c823cff2..46cd7bd18b34 100644
--- a/block/blk-ioc.c
+++ b/block/blk-ioc.c
@@ -367,7 +367,7 @@ struct io_cq *ioc_create_icq(struct io_context *ioc, struct request_queue *q,
367 if (!icq) 367 if (!icq)
368 return NULL; 368 return NULL;
369 369
370 if (radix_tree_preload(gfp_mask) < 0) { 370 if (radix_tree_maybe_preload(gfp_mask) < 0) {
371 kmem_cache_free(et->icq_cache, icq); 371 kmem_cache_free(et->icq_cache, icq);
372 return NULL; 372 return NULL;
373 } 373 }
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 5efc5a647183..3aa5b195f4dd 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -29,7 +29,7 @@ queue_var_store(unsigned long *var, const char *page, size_t count)
29 int err; 29 int err;
30 unsigned long v; 30 unsigned long v;
31 31
32 err = strict_strtoul(page, 10, &v); 32 err = kstrtoul(page, 10, &v);
33 if (err || v > UINT_MAX) 33 if (err || v > UINT_MAX)
34 return -EINVAL; 34 return -EINVAL;
35 35
diff --git a/block/blk-throttle.c b/block/blk-throttle.c
index 08a32dfd3844..8331aba9426f 100644
--- a/block/blk-throttle.c
+++ b/block/blk-throttle.c
@@ -1293,10 +1293,10 @@ static u64 tg_prfill_cpu_rwstat(struct seq_file *sf,
1293 return __blkg_prfill_rwstat(sf, pd, &rwstat); 1293 return __blkg_prfill_rwstat(sf, pd, &rwstat);
1294} 1294}
1295 1295
1296static int tg_print_cpu_rwstat(struct cgroup *cgrp, struct cftype *cft, 1296static int tg_print_cpu_rwstat(struct cgroup_subsys_state *css,
1297 struct seq_file *sf) 1297 struct cftype *cft, struct seq_file *sf)
1298{ 1298{
1299 struct blkcg *blkcg = cgroup_to_blkcg(cgrp); 1299 struct blkcg *blkcg = css_to_blkcg(css);
1300 1300
1301 blkcg_print_blkgs(sf, blkcg, tg_prfill_cpu_rwstat, &blkcg_policy_throtl, 1301 blkcg_print_blkgs(sf, blkcg, tg_prfill_cpu_rwstat, &blkcg_policy_throtl,
1302 cft->private, true); 1302 cft->private, true);
@@ -1325,31 +1325,31 @@ static u64 tg_prfill_conf_uint(struct seq_file *sf, struct blkg_policy_data *pd,
1325 return __blkg_prfill_u64(sf, pd, v); 1325 return __blkg_prfill_u64(sf, pd, v);
1326} 1326}
1327 1327
1328static int tg_print_conf_u64(struct cgroup *cgrp, struct cftype *cft, 1328static int tg_print_conf_u64(struct cgroup_subsys_state *css,
1329 struct seq_file *sf) 1329 struct cftype *cft, struct seq_file *sf)
1330{ 1330{
1331 blkcg_print_blkgs(sf, cgroup_to_blkcg(cgrp), tg_prfill_conf_u64, 1331 blkcg_print_blkgs(sf, css_to_blkcg(css), tg_prfill_conf_u64,
1332 &blkcg_policy_throtl, cft->private, false); 1332 &blkcg_policy_throtl, cft->private, false);
1333 return 0; 1333 return 0;
1334} 1334}
1335 1335
1336static int tg_print_conf_uint(struct cgroup *cgrp, struct cftype *cft, 1336static int tg_print_conf_uint(struct cgroup_subsys_state *css,
1337 struct seq_file *sf) 1337 struct cftype *cft, struct seq_file *sf)
1338{ 1338{
1339 blkcg_print_blkgs(sf, cgroup_to_blkcg(cgrp), tg_prfill_conf_uint, 1339 blkcg_print_blkgs(sf, css_to_blkcg(css), tg_prfill_conf_uint,
1340 &blkcg_policy_throtl, cft->private, false); 1340 &blkcg_policy_throtl, cft->private, false);
1341 return 0; 1341 return 0;
1342} 1342}
1343 1343
1344static int tg_set_conf(struct cgroup *cgrp, struct cftype *cft, const char *buf, 1344static int tg_set_conf(struct cgroup_subsys_state *css, struct cftype *cft,
1345 bool is_u64) 1345 const char *buf, bool is_u64)
1346{ 1346{
1347 struct blkcg *blkcg = cgroup_to_blkcg(cgrp); 1347 struct blkcg *blkcg = css_to_blkcg(css);
1348 struct blkg_conf_ctx ctx; 1348 struct blkg_conf_ctx ctx;
1349 struct throtl_grp *tg; 1349 struct throtl_grp *tg;
1350 struct throtl_service_queue *sq; 1350 struct throtl_service_queue *sq;
1351 struct blkcg_gq *blkg; 1351 struct blkcg_gq *blkg;
1352 struct cgroup *pos_cgrp; 1352 struct cgroup_subsys_state *pos_css;
1353 int ret; 1353 int ret;
1354 1354
1355 ret = blkg_conf_prep(blkcg, &blkcg_policy_throtl, buf, &ctx); 1355 ret = blkg_conf_prep(blkcg, &blkcg_policy_throtl, buf, &ctx);
@@ -1379,8 +1379,7 @@ static int tg_set_conf(struct cgroup *cgrp, struct cftype *cft, const char *buf,
1379 * restrictions in the whole hierarchy and allows them to bypass 1379 * restrictions in the whole hierarchy and allows them to bypass
1380 * blk-throttle. 1380 * blk-throttle.
1381 */ 1381 */
1382 tg_update_has_rules(tg); 1382 blkg_for_each_descendant_pre(blkg, pos_css, ctx.blkg)
1383 blkg_for_each_descendant_pre(blkg, pos_cgrp, ctx.blkg)
1384 tg_update_has_rules(blkg_to_tg(blkg)); 1383 tg_update_has_rules(blkg_to_tg(blkg));
1385 1384
1386 /* 1385 /*
@@ -1403,16 +1402,16 @@ static int tg_set_conf(struct cgroup *cgrp, struct cftype *cft, const char *buf,
1403 return 0; 1402 return 0;
1404} 1403}
1405 1404
1406static int tg_set_conf_u64(struct cgroup *cgrp, struct cftype *cft, 1405static int tg_set_conf_u64(struct cgroup_subsys_state *css, struct cftype *cft,
1407 const char *buf) 1406 const char *buf)
1408{ 1407{
1409 return tg_set_conf(cgrp, cft, buf, true); 1408 return tg_set_conf(css, cft, buf, true);
1410} 1409}
1411 1410
1412static int tg_set_conf_uint(struct cgroup *cgrp, struct cftype *cft, 1411static int tg_set_conf_uint(struct cgroup_subsys_state *css, struct cftype *cft,
1413 const char *buf) 1412 const char *buf)
1414{ 1413{
1415 return tg_set_conf(cgrp, cft, buf, false); 1414 return tg_set_conf(css, cft, buf, false);
1416} 1415}
1417 1416
1418static struct cftype throtl_files[] = { 1417static struct cftype throtl_files[] = {
@@ -1623,7 +1622,7 @@ void blk_throtl_drain(struct request_queue *q)
1623{ 1622{
1624 struct throtl_data *td = q->td; 1623 struct throtl_data *td = q->td;
1625 struct blkcg_gq *blkg; 1624 struct blkcg_gq *blkg;
1626 struct cgroup *pos_cgrp; 1625 struct cgroup_subsys_state *pos_css;
1627 struct bio *bio; 1626 struct bio *bio;
1628 int rw; 1627 int rw;
1629 1628
@@ -1636,11 +1635,9 @@ void blk_throtl_drain(struct request_queue *q)
1636 * better to walk service_queue tree directly but blkg walk is 1635 * better to walk service_queue tree directly but blkg walk is
1637 * easier. 1636 * easier.
1638 */ 1637 */
1639 blkg_for_each_descendant_post(blkg, pos_cgrp, td->queue->root_blkg) 1638 blkg_for_each_descendant_post(blkg, pos_css, td->queue->root_blkg)
1640 tg_drain_bios(&blkg_to_tg(blkg)->service_queue); 1639 tg_drain_bios(&blkg_to_tg(blkg)->service_queue);
1641 1640
1642 tg_drain_bios(&td_root_tg(td)->service_queue);
1643
1644 /* finally, transfer bios from top-level tg's into the td */ 1641 /* finally, transfer bios from top-level tg's into the td */
1645 tg_drain_bios(&td->service_queue); 1642 tg_drain_bios(&td->service_queue);
1646 1643
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index d5bbdcfd0dab..434944cbd761 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -1607,12 +1607,11 @@ static u64 cfqg_prfill_weight_device(struct seq_file *sf,
1607 return __blkg_prfill_u64(sf, pd, cfqg->dev_weight); 1607 return __blkg_prfill_u64(sf, pd, cfqg->dev_weight);
1608} 1608}
1609 1609
1610static int cfqg_print_weight_device(struct cgroup *cgrp, struct cftype *cft, 1610static int cfqg_print_weight_device(struct cgroup_subsys_state *css,
1611 struct seq_file *sf) 1611 struct cftype *cft, struct seq_file *sf)
1612{ 1612{
1613 blkcg_print_blkgs(sf, cgroup_to_blkcg(cgrp), 1613 blkcg_print_blkgs(sf, css_to_blkcg(css), cfqg_prfill_weight_device,
1614 cfqg_prfill_weight_device, &blkcg_policy_cfq, 0, 1614 &blkcg_policy_cfq, 0, false);
1615 false);
1616 return 0; 1615 return 0;
1617} 1616}
1618 1617
@@ -1626,35 +1625,34 @@ static u64 cfqg_prfill_leaf_weight_device(struct seq_file *sf,
1626 return __blkg_prfill_u64(sf, pd, cfqg->dev_leaf_weight); 1625 return __blkg_prfill_u64(sf, pd, cfqg->dev_leaf_weight);
1627} 1626}
1628 1627
1629static int cfqg_print_leaf_weight_device(struct cgroup *cgrp, 1628static int cfqg_print_leaf_weight_device(struct cgroup_subsys_state *css,
1630 struct cftype *cft, 1629 struct cftype *cft,
1631 struct seq_file *sf) 1630 struct seq_file *sf)
1632{ 1631{
1633 blkcg_print_blkgs(sf, cgroup_to_blkcg(cgrp), 1632 blkcg_print_blkgs(sf, css_to_blkcg(css), cfqg_prfill_leaf_weight_device,
1634 cfqg_prfill_leaf_weight_device, &blkcg_policy_cfq, 0, 1633 &blkcg_policy_cfq, 0, false);
1635 false);
1636 return 0; 1634 return 0;
1637} 1635}
1638 1636
1639static int cfq_print_weight(struct cgroup *cgrp, struct cftype *cft, 1637static int cfq_print_weight(struct cgroup_subsys_state *css, struct cftype *cft,
1640 struct seq_file *sf) 1638 struct seq_file *sf)
1641{ 1639{
1642 seq_printf(sf, "%u\n", cgroup_to_blkcg(cgrp)->cfq_weight); 1640 seq_printf(sf, "%u\n", css_to_blkcg(css)->cfq_weight);
1643 return 0; 1641 return 0;
1644} 1642}
1645 1643
1646static int cfq_print_leaf_weight(struct cgroup *cgrp, struct cftype *cft, 1644static int cfq_print_leaf_weight(struct cgroup_subsys_state *css,
1647 struct seq_file *sf) 1645 struct cftype *cft, struct seq_file *sf)
1648{ 1646{
1649 seq_printf(sf, "%u\n", 1647 seq_printf(sf, "%u\n", css_to_blkcg(css)->cfq_leaf_weight);
1650 cgroup_to_blkcg(cgrp)->cfq_leaf_weight);
1651 return 0; 1648 return 0;
1652} 1649}
1653 1650
1654static int __cfqg_set_weight_device(struct cgroup *cgrp, struct cftype *cft, 1651static int __cfqg_set_weight_device(struct cgroup_subsys_state *css,
1655 const char *buf, bool is_leaf_weight) 1652 struct cftype *cft, const char *buf,
1653 bool is_leaf_weight)
1656{ 1654{
1657 struct blkcg *blkcg = cgroup_to_blkcg(cgrp); 1655 struct blkcg *blkcg = css_to_blkcg(css);
1658 struct blkg_conf_ctx ctx; 1656 struct blkg_conf_ctx ctx;
1659 struct cfq_group *cfqg; 1657 struct cfq_group *cfqg;
1660 int ret; 1658 int ret;
@@ -1680,22 +1678,22 @@ static int __cfqg_set_weight_device(struct cgroup *cgrp, struct cftype *cft,
1680 return ret; 1678 return ret;
1681} 1679}
1682 1680
1683static int cfqg_set_weight_device(struct cgroup *cgrp, struct cftype *cft, 1681static int cfqg_set_weight_device(struct cgroup_subsys_state *css,
1684 const char *buf) 1682 struct cftype *cft, const char *buf)
1685{ 1683{
1686 return __cfqg_set_weight_device(cgrp, cft, buf, false); 1684 return __cfqg_set_weight_device(css, cft, buf, false);
1687} 1685}
1688 1686
1689static int cfqg_set_leaf_weight_device(struct cgroup *cgrp, struct cftype *cft, 1687static int cfqg_set_leaf_weight_device(struct cgroup_subsys_state *css,
1690 const char *buf) 1688 struct cftype *cft, const char *buf)
1691{ 1689{
1692 return __cfqg_set_weight_device(cgrp, cft, buf, true); 1690 return __cfqg_set_weight_device(css, cft, buf, true);
1693} 1691}
1694 1692
1695static int __cfq_set_weight(struct cgroup *cgrp, struct cftype *cft, u64 val, 1693static int __cfq_set_weight(struct cgroup_subsys_state *css, struct cftype *cft,
1696 bool is_leaf_weight) 1694 u64 val, bool is_leaf_weight)
1697{ 1695{
1698 struct blkcg *blkcg = cgroup_to_blkcg(cgrp); 1696 struct blkcg *blkcg = css_to_blkcg(css);
1699 struct blkcg_gq *blkg; 1697 struct blkcg_gq *blkg;
1700 1698
1701 if (val < CFQ_WEIGHT_MIN || val > CFQ_WEIGHT_MAX) 1699 if (val < CFQ_WEIGHT_MIN || val > CFQ_WEIGHT_MAX)
@@ -1727,30 +1725,32 @@ static int __cfq_set_weight(struct cgroup *cgrp, struct cftype *cft, u64 val,
1727 return 0; 1725 return 0;
1728} 1726}
1729 1727
1730static int cfq_set_weight(struct cgroup *cgrp, struct cftype *cft, u64 val) 1728static int cfq_set_weight(struct cgroup_subsys_state *css, struct cftype *cft,
1729 u64 val)
1731{ 1730{
1732 return __cfq_set_weight(cgrp, cft, val, false); 1731 return __cfq_set_weight(css, cft, val, false);
1733} 1732}
1734 1733
1735static int cfq_set_leaf_weight(struct cgroup *cgrp, struct cftype *cft, u64 val) 1734static int cfq_set_leaf_weight(struct cgroup_subsys_state *css,
1735 struct cftype *cft, u64 val)
1736{ 1736{
1737 return __cfq_set_weight(cgrp, cft, val, true); 1737 return __cfq_set_weight(css, cft, val, true);
1738} 1738}
1739 1739
1740static int cfqg_print_stat(struct cgroup *cgrp, struct cftype *cft, 1740static int cfqg_print_stat(struct cgroup_subsys_state *css, struct cftype *cft,
1741 struct seq_file *sf) 1741 struct seq_file *sf)
1742{ 1742{
1743 struct blkcg *blkcg = cgroup_to_blkcg(cgrp); 1743 struct blkcg *blkcg = css_to_blkcg(css);
1744 1744
1745 blkcg_print_blkgs(sf, blkcg, blkg_prfill_stat, &blkcg_policy_cfq, 1745 blkcg_print_blkgs(sf, blkcg, blkg_prfill_stat, &blkcg_policy_cfq,
1746 cft->private, false); 1746 cft->private, false);
1747 return 0; 1747 return 0;
1748} 1748}
1749 1749
1750static int cfqg_print_rwstat(struct cgroup *cgrp, struct cftype *cft, 1750static int cfqg_print_rwstat(struct cgroup_subsys_state *css,
1751 struct seq_file *sf) 1751 struct cftype *cft, struct seq_file *sf)
1752{ 1752{
1753 struct blkcg *blkcg = cgroup_to_blkcg(cgrp); 1753 struct blkcg *blkcg = css_to_blkcg(css);
1754 1754
1755 blkcg_print_blkgs(sf, blkcg, blkg_prfill_rwstat, &blkcg_policy_cfq, 1755 blkcg_print_blkgs(sf, blkcg, blkg_prfill_rwstat, &blkcg_policy_cfq,
1756 cft->private, true); 1756 cft->private, true);
@@ -1773,20 +1773,20 @@ static u64 cfqg_prfill_rwstat_recursive(struct seq_file *sf,
1773 return __blkg_prfill_rwstat(sf, pd, &sum); 1773 return __blkg_prfill_rwstat(sf, pd, &sum);
1774} 1774}
1775 1775
1776static int cfqg_print_stat_recursive(struct cgroup *cgrp, struct cftype *cft, 1776static int cfqg_print_stat_recursive(struct cgroup_subsys_state *css,
1777 struct seq_file *sf) 1777 struct cftype *cft, struct seq_file *sf)
1778{ 1778{
1779 struct blkcg *blkcg = cgroup_to_blkcg(cgrp); 1779 struct blkcg *blkcg = css_to_blkcg(css);
1780 1780
1781 blkcg_print_blkgs(sf, blkcg, cfqg_prfill_stat_recursive, 1781 blkcg_print_blkgs(sf, blkcg, cfqg_prfill_stat_recursive,
1782 &blkcg_policy_cfq, cft->private, false); 1782 &blkcg_policy_cfq, cft->private, false);
1783 return 0; 1783 return 0;
1784} 1784}
1785 1785
1786static int cfqg_print_rwstat_recursive(struct cgroup *cgrp, struct cftype *cft, 1786static int cfqg_print_rwstat_recursive(struct cgroup_subsys_state *css,
1787 struct seq_file *sf) 1787 struct cftype *cft, struct seq_file *sf)
1788{ 1788{
1789 struct blkcg *blkcg = cgroup_to_blkcg(cgrp); 1789 struct blkcg *blkcg = css_to_blkcg(css);
1790 1790
1791 blkcg_print_blkgs(sf, blkcg, cfqg_prfill_rwstat_recursive, 1791 blkcg_print_blkgs(sf, blkcg, cfqg_prfill_rwstat_recursive,
1792 &blkcg_policy_cfq, cft->private, true); 1792 &blkcg_policy_cfq, cft->private, true);
@@ -1803,17 +1803,17 @@ static u64 cfqg_prfill_avg_queue_size(struct seq_file *sf,
1803 1803
1804 if (samples) { 1804 if (samples) {
1805 v = blkg_stat_read(&cfqg->stats.avg_queue_size_sum); 1805 v = blkg_stat_read(&cfqg->stats.avg_queue_size_sum);
1806 do_div(v, samples); 1806 v = div64_u64(v, samples);
1807 } 1807 }
1808 __blkg_prfill_u64(sf, pd, v); 1808 __blkg_prfill_u64(sf, pd, v);
1809 return 0; 1809 return 0;
1810} 1810}
1811 1811
1812/* print avg_queue_size */ 1812/* print avg_queue_size */
1813static int cfqg_print_avg_queue_size(struct cgroup *cgrp, struct cftype *cft, 1813static int cfqg_print_avg_queue_size(struct cgroup_subsys_state *css,
1814 struct seq_file *sf) 1814 struct cftype *cft, struct seq_file *sf)
1815{ 1815{
1816 struct blkcg *blkcg = cgroup_to_blkcg(cgrp); 1816 struct blkcg *blkcg = css_to_blkcg(css);
1817 1817
1818 blkcg_print_blkgs(sf, blkcg, cfqg_prfill_avg_queue_size, 1818 blkcg_print_blkgs(sf, blkcg, cfqg_prfill_avg_queue_size,
1819 &blkcg_policy_cfq, 0, false); 1819 &blkcg_policy_cfq, 0, false);
@@ -4358,7 +4358,7 @@ static int cfq_init_queue(struct request_queue *q, struct elevator_type *e)
4358 if (!eq) 4358 if (!eq)
4359 return -ENOMEM; 4359 return -ENOMEM;
4360 4360
4361 cfqd = kmalloc_node(sizeof(*cfqd), GFP_KERNEL | __GFP_ZERO, q->node); 4361 cfqd = kzalloc_node(sizeof(*cfqd), GFP_KERNEL, q->node);
4362 if (!cfqd) { 4362 if (!cfqd) {
4363 kobject_put(&eq->kobj); 4363 kobject_put(&eq->kobj);
4364 return -ENOMEM; 4364 return -ENOMEM;
diff --git a/block/cmdline-parser.c b/block/cmdline-parser.c
new file mode 100644
index 000000000000..cc2637f8674e
--- /dev/null
+++ b/block/cmdline-parser.c
@@ -0,0 +1,250 @@
1/*
2 * Parse command line, get partition information
3 *
4 * Written by Cai Zhiyong <caizhiyong@huawei.com>
5 *
6 */
7#include <linux/buffer_head.h>
8#include <linux/module.h>
9#include <linux/cmdline-parser.h>
10
11static int parse_subpart(struct cmdline_subpart **subpart, char *partdef)
12{
13 int ret = 0;
14 struct cmdline_subpart *new_subpart;
15
16 *subpart = NULL;
17
18 new_subpart = kzalloc(sizeof(struct cmdline_subpart), GFP_KERNEL);
19 if (!new_subpart)
20 return -ENOMEM;
21
22 if (*partdef == '-') {
23 new_subpart->size = (sector_t)(~0ULL);
24 partdef++;
25 } else {
26 new_subpart->size = (sector_t)memparse(partdef, &partdef);
27 if (new_subpart->size < (sector_t)PAGE_SIZE) {
28 pr_warn("cmdline partition size is invalid.");
29 ret = -EINVAL;
30 goto fail;
31 }
32 }
33
34 if (*partdef == '@') {
35 partdef++;
36 new_subpart->from = (sector_t)memparse(partdef, &partdef);
37 } else {
38 new_subpart->from = (sector_t)(~0ULL);
39 }
40
41 if (*partdef == '(') {
42 int length;
43 char *next = strchr(++partdef, ')');
44
45 if (!next) {
46 pr_warn("cmdline partition format is invalid.");
47 ret = -EINVAL;
48 goto fail;
49 }
50
51 length = min_t(int, next - partdef,
52 sizeof(new_subpart->name) - 1);
53 strncpy(new_subpart->name, partdef, length);
54 new_subpart->name[length] = '\0';
55
56 partdef = ++next;
57 } else
58 new_subpart->name[0] = '\0';
59
60 new_subpart->flags = 0;
61
62 if (!strncmp(partdef, "ro", 2)) {
63 new_subpart->flags |= PF_RDONLY;
64 partdef += 2;
65 }
66
67 if (!strncmp(partdef, "lk", 2)) {
68 new_subpart->flags |= PF_POWERUP_LOCK;
69 partdef += 2;
70 }
71
72 *subpart = new_subpart;
73 return 0;
74fail:
75 kfree(new_subpart);
76 return ret;
77}
78
79static void free_subpart(struct cmdline_parts *parts)
80{
81 struct cmdline_subpart *subpart;
82
83 while (parts->subpart) {
84 subpart = parts->subpart;
85 parts->subpart = subpart->next_subpart;
86 kfree(subpart);
87 }
88}
89
90static int parse_parts(struct cmdline_parts **parts, const char *bdevdef)
91{
92 int ret = -EINVAL;
93 char *next;
94 int length;
95 struct cmdline_subpart **next_subpart;
96 struct cmdline_parts *newparts;
97 char buf[BDEVNAME_SIZE + 32 + 4];
98
99 *parts = NULL;
100
101 newparts = kzalloc(sizeof(struct cmdline_parts), GFP_KERNEL);
102 if (!newparts)
103 return -ENOMEM;
104
105 next = strchr(bdevdef, ':');
106 if (!next) {
107 pr_warn("cmdline partition has no block device.");
108 goto fail;
109 }
110
111 length = min_t(int, next - bdevdef, sizeof(newparts->name) - 1);
112 strncpy(newparts->name, bdevdef, length);
113 newparts->name[length] = '\0';
114 newparts->nr_subparts = 0;
115
116 next_subpart = &newparts->subpart;
117
118 while (next && *(++next)) {
119 bdevdef = next;
120 next = strchr(bdevdef, ',');
121
122 length = (!next) ? (sizeof(buf) - 1) :
123 min_t(int, next - bdevdef, sizeof(buf) - 1);
124
125 strncpy(buf, bdevdef, length);
126 buf[length] = '\0';
127
128 ret = parse_subpart(next_subpart, buf);
129 if (ret)
130 goto fail;
131
132 newparts->nr_subparts++;
133 next_subpart = &(*next_subpart)->next_subpart;
134 }
135
136 if (!newparts->subpart) {
137 pr_warn("cmdline partition has no valid partition.");
138 ret = -EINVAL;
139 goto fail;
140 }
141
142 *parts = newparts;
143
144 return 0;
145fail:
146 free_subpart(newparts);
147 kfree(newparts);
148 return ret;
149}
150
151void cmdline_parts_free(struct cmdline_parts **parts)
152{
153 struct cmdline_parts *next_parts;
154
155 while (*parts) {
156 next_parts = (*parts)->next_parts;
157 free_subpart(*parts);
158 kfree(*parts);
159 *parts = next_parts;
160 }
161}
162
163int cmdline_parts_parse(struct cmdline_parts **parts, const char *cmdline)
164{
165 int ret;
166 char *buf;
167 char *pbuf;
168 char *next;
169 struct cmdline_parts **next_parts;
170
171 *parts = NULL;
172
173 next = pbuf = buf = kstrdup(cmdline, GFP_KERNEL);
174 if (!buf)
175 return -ENOMEM;
176
177 next_parts = parts;
178
179 while (next && *pbuf) {
180 next = strchr(pbuf, ';');
181 if (next)
182 *next = '\0';
183
184 ret = parse_parts(next_parts, pbuf);
185 if (ret)
186 goto fail;
187
188 if (next)
189 pbuf = ++next;
190
191 next_parts = &(*next_parts)->next_parts;
192 }
193
194 if (!*parts) {
195 pr_warn("cmdline partition has no valid partition.");
196 ret = -EINVAL;
197 goto fail;
198 }
199
200 ret = 0;
201done:
202 kfree(buf);
203 return ret;
204
205fail:
206 cmdline_parts_free(parts);
207 goto done;
208}
209
210struct cmdline_parts *cmdline_parts_find(struct cmdline_parts *parts,
211 const char *bdev)
212{
213 while (parts && strncmp(bdev, parts->name, sizeof(parts->name)))
214 parts = parts->next_parts;
215 return parts;
216}
217
218/*
219 * add_part()
220 * 0 success.
221 * 1 can not add so many partitions.
222 */
223void cmdline_parts_set(struct cmdline_parts *parts, sector_t disk_size,
224 int slot,
225 int (*add_part)(int, struct cmdline_subpart *, void *),
226 void *param)
227
228{
229 sector_t from = 0;
230 struct cmdline_subpart *subpart;
231
232 for (subpart = parts->subpart; subpart;
233 subpart = subpart->next_subpart, slot++) {
234 if (subpart->from == (sector_t)(~0ULL))
235 subpart->from = from;
236 else
237 from = subpart->from;
238
239 if (from >= disk_size)
240 break;
241
242 if (subpart->size > (disk_size - from))
243 subpart->size = disk_size - from;
244
245 from += subpart->size;
246
247 if (add_part(slot, subpart, param))
248 break;
249 }
250}
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index 7e5d474dc6ba..fbd5a67cb773 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -70,7 +70,7 @@ static int compat_hdio_getgeo(struct gendisk *disk, struct block_device *bdev,
70 return ret; 70 return ret;
71 71
72 ret = copy_to_user(ugeo, &geo, 4); 72 ret = copy_to_user(ugeo, &geo, 4);
73 ret |= __put_user(geo.start, &ugeo->start); 73 ret |= put_user(geo.start, &ugeo->start);
74 if (ret) 74 if (ret)
75 ret = -EFAULT; 75 ret = -EFAULT;
76 76
diff --git a/block/deadline-iosched.c b/block/deadline-iosched.c
index 20614a332362..9ef66406c625 100644
--- a/block/deadline-iosched.c
+++ b/block/deadline-iosched.c
@@ -346,7 +346,7 @@ static int deadline_init_queue(struct request_queue *q, struct elevator_type *e)
346 if (!eq) 346 if (!eq)
347 return -ENOMEM; 347 return -ENOMEM;
348 348
349 dd = kmalloc_node(sizeof(*dd), GFP_KERNEL | __GFP_ZERO, q->node); 349 dd = kzalloc_node(sizeof(*dd), GFP_KERNEL, q->node);
350 if (!dd) { 350 if (!dd) {
351 kobject_put(&eq->kobj); 351 kobject_put(&eq->kobj);
352 return -ENOMEM; 352 return -ENOMEM;
diff --git a/block/elevator.c b/block/elevator.c
index 668394d18588..2bcbd8cc14d4 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -155,7 +155,7 @@ struct elevator_queue *elevator_alloc(struct request_queue *q,
155{ 155{
156 struct elevator_queue *eq; 156 struct elevator_queue *eq;
157 157
158 eq = kmalloc_node(sizeof(*eq), GFP_KERNEL | __GFP_ZERO, q->node); 158 eq = kzalloc_node(sizeof(*eq), GFP_KERNEL, q->node);
159 if (unlikely(!eq)) 159 if (unlikely(!eq))
160 goto err; 160 goto err;
161 161
diff --git a/block/genhd.c b/block/genhd.c
index dadf42b454a3..791f41943132 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -1252,8 +1252,7 @@ struct gendisk *alloc_disk_node(int minors, int node_id)
1252{ 1252{
1253 struct gendisk *disk; 1253 struct gendisk *disk;
1254 1254
1255 disk = kmalloc_node(sizeof(struct gendisk), 1255 disk = kzalloc_node(sizeof(struct gendisk), GFP_KERNEL, node_id);
1256 GFP_KERNEL | __GFP_ZERO, node_id);
1257 if (disk) { 1256 if (disk) {
1258 if (!init_part_stats(&disk->part0)) { 1257 if (!init_part_stats(&disk->part0)) {
1259 kfree(disk); 1258 kfree(disk);
diff --git a/block/partitions/Kconfig b/block/partitions/Kconfig
index 4cebb2f0d2f4..9b29a996c311 100644
--- a/block/partitions/Kconfig
+++ b/block/partitions/Kconfig
@@ -260,3 +260,10 @@ config SYSV68_PARTITION
260 partition table format used by Motorola Delta machines (using 260 partition table format used by Motorola Delta machines (using
261 sysv68). 261 sysv68).
262 Otherwise, say N. 262 Otherwise, say N.
263
264config CMDLINE_PARTITION
265 bool "Command line partition support" if PARTITION_ADVANCED
266 select BLK_CMDLINE_PARSER
267 help
268 Say Y here if you want to read the partition table from bootargs.
269 The format for the command line is just like mtdparts.
diff --git a/block/partitions/Makefile b/block/partitions/Makefile
index 2be4d7ba4e3a..37a95270503c 100644
--- a/block/partitions/Makefile
+++ b/block/partitions/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_ACORN_PARTITION) += acorn.o
8obj-$(CONFIG_AMIGA_PARTITION) += amiga.o 8obj-$(CONFIG_AMIGA_PARTITION) += amiga.o
9obj-$(CONFIG_ATARI_PARTITION) += atari.o 9obj-$(CONFIG_ATARI_PARTITION) += atari.o
10obj-$(CONFIG_AIX_PARTITION) += aix.o 10obj-$(CONFIG_AIX_PARTITION) += aix.o
11obj-$(CONFIG_CMDLINE_PARTITION) += cmdline.o
11obj-$(CONFIG_MAC_PARTITION) += mac.o 12obj-$(CONFIG_MAC_PARTITION) += mac.o
12obj-$(CONFIG_LDM_PARTITION) += ldm.o 13obj-$(CONFIG_LDM_PARTITION) += ldm.o
13obj-$(CONFIG_MSDOS_PARTITION) += msdos.o 14obj-$(CONFIG_MSDOS_PARTITION) += msdos.o
diff --git a/block/partitions/check.c b/block/partitions/check.c
index 19ba207ea7d1..9ac1df74f699 100644
--- a/block/partitions/check.c
+++ b/block/partitions/check.c
@@ -34,6 +34,7 @@
34#include "efi.h" 34#include "efi.h"
35#include "karma.h" 35#include "karma.h"
36#include "sysv68.h" 36#include "sysv68.h"
37#include "cmdline.h"
37 38
38int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/ 39int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/
39 40
@@ -65,6 +66,9 @@ static int (*check_part[])(struct parsed_partitions *) = {
65 adfspart_check_ADFS, 66 adfspart_check_ADFS,
66#endif 67#endif
67 68
69#ifdef CONFIG_CMDLINE_PARTITION
70 cmdline_partition,
71#endif
68#ifdef CONFIG_EFI_PARTITION 72#ifdef CONFIG_EFI_PARTITION
69 efi_partition, /* this must come before msdos */ 73 efi_partition, /* this must come before msdos */
70#endif 74#endif
diff --git a/block/partitions/cmdline.c b/block/partitions/cmdline.c
new file mode 100644
index 000000000000..5141b563adf1
--- /dev/null
+++ b/block/partitions/cmdline.c
@@ -0,0 +1,99 @@
1/*
2 * Copyright (C) 2013 HUAWEI
3 * Author: Cai Zhiyong <caizhiyong@huawei.com>
4 *
5 * Read block device partition table from the command line.
6 * Typically used for fixed block (eMMC) embedded devices.
7 * It has no MBR, so saves storage space. Bootloader can be easily accessed
8 * by absolute address of data on the block device.
9 * Users can easily change the partition.
10 *
11 * The format for the command line is just like mtdparts.
12 *
13 * For further information, see "Documentation/block/cmdline-partition.txt"
14 *
15 */
16
17#include <linux/cmdline-parser.h>
18
19#include "check.h"
20#include "cmdline.h"
21
22static char *cmdline;
23static struct cmdline_parts *bdev_parts;
24
25static int add_part(int slot, struct cmdline_subpart *subpart, void *param)
26{
27 int label_min;
28 struct partition_meta_info *info;
29 char tmp[sizeof(info->volname) + 4];
30 struct parsed_partitions *state = (struct parsed_partitions *)param;
31
32 if (slot >= state->limit)
33 return 1;
34
35 put_partition(state, slot, subpart->from >> 9,
36 subpart->size >> 9);
37
38 info = &state->parts[slot].info;
39
40 label_min = min_t(int, sizeof(info->volname) - 1,
41 sizeof(subpart->name));
42 strncpy(info->volname, subpart->name, label_min);
43 info->volname[label_min] = '\0';
44
45 snprintf(tmp, sizeof(tmp), "(%s)", info->volname);
46 strlcat(state->pp_buf, tmp, PAGE_SIZE);
47
48 state->parts[slot].has_info = true;
49
50 return 0;
51}
52
53static int __init cmdline_parts_setup(char *s)
54{
55 cmdline = s;
56 return 1;
57}
58__setup("blkdevparts=", cmdline_parts_setup);
59
60/*
61 * Purpose: allocate cmdline partitions.
62 * Returns:
63 * -1 if unable to read the partition table
64 * 0 if this isn't our partition table
65 * 1 if successful
66 */
67int cmdline_partition(struct parsed_partitions *state)
68{
69 sector_t disk_size;
70 char bdev[BDEVNAME_SIZE];
71 struct cmdline_parts *parts;
72
73 if (cmdline) {
74 if (bdev_parts)
75 cmdline_parts_free(&bdev_parts);
76
77 if (cmdline_parts_parse(&bdev_parts, cmdline)) {
78 cmdline = NULL;
79 return -1;
80 }
81 cmdline = NULL;
82 }
83
84 if (!bdev_parts)
85 return 0;
86
87 bdevname(state->bdev, bdev);
88 parts = cmdline_parts_find(bdev_parts, bdev);
89 if (!parts)
90 return 0;
91
92 disk_size = get_capacity(state->bdev->bd_disk) << 9;
93
94 cmdline_parts_set(parts, disk_size, 1, add_part, (void *)state);
95
96 strlcat(state->pp_buf, "\n", PAGE_SIZE);
97
98 return 1;
99}
diff --git a/block/partitions/cmdline.h b/block/partitions/cmdline.h
new file mode 100644
index 000000000000..26e0f8da1414
--- /dev/null
+++ b/block/partitions/cmdline.h
@@ -0,0 +1,2 @@
1
2int cmdline_partition(struct parsed_partitions *state);
diff --git a/block/partitions/efi.c b/block/partitions/efi.c
index c85fc895ecdb..a8287b49d062 100644
--- a/block/partitions/efi.c
+++ b/block/partitions/efi.c
@@ -25,6 +25,9 @@
25 * TODO: 25 * TODO:
26 * 26 *
27 * Changelog: 27 * Changelog:
28 * Mon August 5th, 2013 Davidlohr Bueso <davidlohr@hp.com>
29 * - detect hybrid MBRs, tighter pMBR checking & cleanups.
30 *
28 * Mon Nov 09 2004 Matt Domsch <Matt_Domsch@dell.com> 31 * Mon Nov 09 2004 Matt Domsch <Matt_Domsch@dell.com>
29 * - test for valid PMBR and valid PGPT before ever reading 32 * - test for valid PMBR and valid PGPT before ever reading
30 * AGPT, allow override with 'gpt' kernel command line option. 33 * AGPT, allow override with 'gpt' kernel command line option.
@@ -149,34 +152,89 @@ static u64 last_lba(struct block_device *bdev)
149 bdev_logical_block_size(bdev)) - 1ULL; 152 bdev_logical_block_size(bdev)) - 1ULL;
150} 153}
151 154
152static inline int 155static inline int pmbr_part_valid(gpt_mbr_record *part)
153pmbr_part_valid(struct partition *part)
154{ 156{
155 if (part->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT && 157 if (part->os_type != EFI_PMBR_OSTYPE_EFI_GPT)
156 le32_to_cpu(part->start_sect) == 1UL) 158 goto invalid;
157 return 1; 159
158 return 0; 160 /* set to 0x00000001 (i.e., the LBA of the GPT Partition Header) */
161 if (le32_to_cpu(part->starting_lba) != GPT_PRIMARY_PARTITION_TABLE_LBA)
162 goto invalid;
163
164 return GPT_MBR_PROTECTIVE;
165invalid:
166 return 0;
159} 167}
160 168
161/** 169/**
162 * is_pmbr_valid(): test Protective MBR for validity 170 * is_pmbr_valid(): test Protective MBR for validity
163 * @mbr: pointer to a legacy mbr structure 171 * @mbr: pointer to a legacy mbr structure
172 * @total_sectors: amount of sectors in the device
164 * 173 *
165 * Description: Returns 1 if PMBR is valid, 0 otherwise. 174 * Description: Checks for a valid protective or hybrid
166 * Validity depends on two things: 175 * master boot record (MBR). The validity of a pMBR depends
176 * on all of the following properties:
167 * 1) MSDOS signature is in the last two bytes of the MBR 177 * 1) MSDOS signature is in the last two bytes of the MBR
168 * 2) One partition of type 0xEE is found 178 * 2) One partition of type 0xEE is found
179 *
180 * In addition, a hybrid MBR will have up to three additional
181 * primary partitions, which point to the same space that's
182 * marked out by up to three GPT partitions.
183 *
184 * Returns 0 upon invalid MBR, or GPT_MBR_PROTECTIVE or
185 * GPT_MBR_HYBRID depending on the device layout.
169 */ 186 */
170static int 187static int is_pmbr_valid(legacy_mbr *mbr, sector_t total_sectors)
171is_pmbr_valid(legacy_mbr *mbr)
172{ 188{
173 int i; 189 uint32_t sz = 0;
190 int i, part = 0, ret = 0; /* invalid by default */
191
174 if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE) 192 if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE)
175 return 0; 193 goto done;
194
195 for (i = 0; i < 4; i++) {
196 ret = pmbr_part_valid(&mbr->partition_record[i]);
197 if (ret == GPT_MBR_PROTECTIVE) {
198 part = i;
199 /*
200 * Ok, we at least know that there's a protective MBR,
201 * now check if there are other partition types for
202 * hybrid MBR.
203 */
204 goto check_hybrid;
205 }
206 }
207
208 if (ret != GPT_MBR_PROTECTIVE)
209 goto done;
210check_hybrid:
176 for (i = 0; i < 4; i++) 211 for (i = 0; i < 4; i++)
177 if (pmbr_part_valid(&mbr->partition_record[i])) 212 if ((mbr->partition_record[i].os_type !=
178 return 1; 213 EFI_PMBR_OSTYPE_EFI_GPT) &&
179 return 0; 214 (mbr->partition_record[i].os_type != 0x00))
215 ret = GPT_MBR_HYBRID;
216
217 /*
218 * Protective MBRs take up the lesser of the whole disk
219 * or 2 TiB (32bit LBA), ignoring the rest of the disk.
220 * Some partitioning programs, nonetheless, choose to set
221 * the size to the maximum 32-bit limitation, disregarding
222 * the disk size.
223 *
224 * Hybrid MBRs do not necessarily comply with this.
225 *
226 * Consider a bad value here to be a warning to support dd'ing
227 * an image from a smaller disk to a larger disk.
228 */
229 if (ret == GPT_MBR_PROTECTIVE) {
230 sz = le32_to_cpu(mbr->partition_record[part].size_in_lba);
231 if (sz != (uint32_t) total_sectors - 1 && sz != 0xFFFFFFFF)
232 pr_debug("GPT: mbr size in lba (%u) different than whole disk (%u).\n",
233 sz, min_t(uint32_t,
234 total_sectors - 1, 0xFFFFFFFF));
235 }
236done:
237 return ret;
180} 238}
181 239
182/** 240/**
@@ -243,8 +301,7 @@ static gpt_entry *alloc_read_gpt_entries(struct parsed_partitions *state,
243 return NULL; 301 return NULL;
244 302
245 if (read_lba(state, le64_to_cpu(gpt->partition_entry_lba), 303 if (read_lba(state, le64_to_cpu(gpt->partition_entry_lba),
246 (u8 *) pte, 304 (u8 *) pte, count) < count) {
247 count) < count) {
248 kfree(pte); 305 kfree(pte);
249 pte=NULL; 306 pte=NULL;
250 return NULL; 307 return NULL;
@@ -364,7 +421,12 @@ static int is_gpt_valid(struct parsed_partitions *state, u64 lba,
364 (unsigned long long)lastlba); 421 (unsigned long long)lastlba);
365 goto fail; 422 goto fail;
366 } 423 }
367 424 if (le64_to_cpu((*gpt)->last_usable_lba) < le64_to_cpu((*gpt)->first_usable_lba)) {
425 pr_debug("GPT: last_usable_lba incorrect: %lld > %lld\n",
426 (unsigned long long)le64_to_cpu((*gpt)->last_usable_lba),
427 (unsigned long long)le64_to_cpu((*gpt)->first_usable_lba));
428 goto fail;
429 }
368 /* Check that sizeof_partition_entry has the correct value */ 430 /* Check that sizeof_partition_entry has the correct value */
369 if (le32_to_cpu((*gpt)->sizeof_partition_entry) != sizeof(gpt_entry)) { 431 if (le32_to_cpu((*gpt)->sizeof_partition_entry) != sizeof(gpt_entry)) {
370 pr_debug("GUID Partitition Entry Size check failed.\n"); 432 pr_debug("GUID Partitition Entry Size check failed.\n");
@@ -429,44 +491,42 @@ compare_gpts(gpt_header *pgpt, gpt_header *agpt, u64 lastlba)
429 if (!pgpt || !agpt) 491 if (!pgpt || !agpt)
430 return; 492 return;
431 if (le64_to_cpu(pgpt->my_lba) != le64_to_cpu(agpt->alternate_lba)) { 493 if (le64_to_cpu(pgpt->my_lba) != le64_to_cpu(agpt->alternate_lba)) {
432 printk(KERN_WARNING 494 pr_warn("GPT:Primary header LBA != Alt. header alternate_lba\n");
433 "GPT:Primary header LBA != Alt. header alternate_lba\n"); 495 pr_warn("GPT:%lld != %lld\n",
434 printk(KERN_WARNING "GPT:%lld != %lld\n",
435 (unsigned long long)le64_to_cpu(pgpt->my_lba), 496 (unsigned long long)le64_to_cpu(pgpt->my_lba),
436 (unsigned long long)le64_to_cpu(agpt->alternate_lba)); 497 (unsigned long long)le64_to_cpu(agpt->alternate_lba));
437 error_found++; 498 error_found++;
438 } 499 }
439 if (le64_to_cpu(pgpt->alternate_lba) != le64_to_cpu(agpt->my_lba)) { 500 if (le64_to_cpu(pgpt->alternate_lba) != le64_to_cpu(agpt->my_lba)) {
440 printk(KERN_WARNING 501 pr_warn("GPT:Primary header alternate_lba != Alt. header my_lba\n");
441 "GPT:Primary header alternate_lba != Alt. header my_lba\n"); 502 pr_warn("GPT:%lld != %lld\n",
442 printk(KERN_WARNING "GPT:%lld != %lld\n",
443 (unsigned long long)le64_to_cpu(pgpt->alternate_lba), 503 (unsigned long long)le64_to_cpu(pgpt->alternate_lba),
444 (unsigned long long)le64_to_cpu(agpt->my_lba)); 504 (unsigned long long)le64_to_cpu(agpt->my_lba));
445 error_found++; 505 error_found++;
446 } 506 }
447 if (le64_to_cpu(pgpt->first_usable_lba) != 507 if (le64_to_cpu(pgpt->first_usable_lba) !=
448 le64_to_cpu(agpt->first_usable_lba)) { 508 le64_to_cpu(agpt->first_usable_lba)) {
449 printk(KERN_WARNING "GPT:first_usable_lbas don't match.\n"); 509 pr_warn("GPT:first_usable_lbas don't match.\n");
450 printk(KERN_WARNING "GPT:%lld != %lld\n", 510 pr_warn("GPT:%lld != %lld\n",
451 (unsigned long long)le64_to_cpu(pgpt->first_usable_lba), 511 (unsigned long long)le64_to_cpu(pgpt->first_usable_lba),
452 (unsigned long long)le64_to_cpu(agpt->first_usable_lba)); 512 (unsigned long long)le64_to_cpu(agpt->first_usable_lba));
453 error_found++; 513 error_found++;
454 } 514 }
455 if (le64_to_cpu(pgpt->last_usable_lba) != 515 if (le64_to_cpu(pgpt->last_usable_lba) !=
456 le64_to_cpu(agpt->last_usable_lba)) { 516 le64_to_cpu(agpt->last_usable_lba)) {
457 printk(KERN_WARNING "GPT:last_usable_lbas don't match.\n"); 517 pr_warn("GPT:last_usable_lbas don't match.\n");
458 printk(KERN_WARNING "GPT:%lld != %lld\n", 518 pr_warn("GPT:%lld != %lld\n",
459 (unsigned long long)le64_to_cpu(pgpt->last_usable_lba), 519 (unsigned long long)le64_to_cpu(pgpt->last_usable_lba),
460 (unsigned long long)le64_to_cpu(agpt->last_usable_lba)); 520 (unsigned long long)le64_to_cpu(agpt->last_usable_lba));
461 error_found++; 521 error_found++;
462 } 522 }
463 if (efi_guidcmp(pgpt->disk_guid, agpt->disk_guid)) { 523 if (efi_guidcmp(pgpt->disk_guid, agpt->disk_guid)) {
464 printk(KERN_WARNING "GPT:disk_guids don't match.\n"); 524 pr_warn("GPT:disk_guids don't match.\n");
465 error_found++; 525 error_found++;
466 } 526 }
467 if (le32_to_cpu(pgpt->num_partition_entries) != 527 if (le32_to_cpu(pgpt->num_partition_entries) !=
468 le32_to_cpu(agpt->num_partition_entries)) { 528 le32_to_cpu(agpt->num_partition_entries)) {
469 printk(KERN_WARNING "GPT:num_partition_entries don't match: " 529 pr_warn("GPT:num_partition_entries don't match: "
470 "0x%x != 0x%x\n", 530 "0x%x != 0x%x\n",
471 le32_to_cpu(pgpt->num_partition_entries), 531 le32_to_cpu(pgpt->num_partition_entries),
472 le32_to_cpu(agpt->num_partition_entries)); 532 le32_to_cpu(agpt->num_partition_entries));
@@ -474,8 +534,7 @@ compare_gpts(gpt_header *pgpt, gpt_header *agpt, u64 lastlba)
474 } 534 }
475 if (le32_to_cpu(pgpt->sizeof_partition_entry) != 535 if (le32_to_cpu(pgpt->sizeof_partition_entry) !=
476 le32_to_cpu(agpt->sizeof_partition_entry)) { 536 le32_to_cpu(agpt->sizeof_partition_entry)) {
477 printk(KERN_WARNING 537 pr_warn("GPT:sizeof_partition_entry values don't match: "
478 "GPT:sizeof_partition_entry values don't match: "
479 "0x%x != 0x%x\n", 538 "0x%x != 0x%x\n",
480 le32_to_cpu(pgpt->sizeof_partition_entry), 539 le32_to_cpu(pgpt->sizeof_partition_entry),
481 le32_to_cpu(agpt->sizeof_partition_entry)); 540 le32_to_cpu(agpt->sizeof_partition_entry));
@@ -483,34 +542,30 @@ compare_gpts(gpt_header *pgpt, gpt_header *agpt, u64 lastlba)
483 } 542 }
484 if (le32_to_cpu(pgpt->partition_entry_array_crc32) != 543 if (le32_to_cpu(pgpt->partition_entry_array_crc32) !=
485 le32_to_cpu(agpt->partition_entry_array_crc32)) { 544 le32_to_cpu(agpt->partition_entry_array_crc32)) {
486 printk(KERN_WARNING 545 pr_warn("GPT:partition_entry_array_crc32 values don't match: "
487 "GPT:partition_entry_array_crc32 values don't match: "
488 "0x%x != 0x%x\n", 546 "0x%x != 0x%x\n",
489 le32_to_cpu(pgpt->partition_entry_array_crc32), 547 le32_to_cpu(pgpt->partition_entry_array_crc32),
490 le32_to_cpu(agpt->partition_entry_array_crc32)); 548 le32_to_cpu(agpt->partition_entry_array_crc32));
491 error_found++; 549 error_found++;
492 } 550 }
493 if (le64_to_cpu(pgpt->alternate_lba) != lastlba) { 551 if (le64_to_cpu(pgpt->alternate_lba) != lastlba) {
494 printk(KERN_WARNING 552 pr_warn("GPT:Primary header thinks Alt. header is not at the end of the disk.\n");
495 "GPT:Primary header thinks Alt. header is not at the end of the disk.\n"); 553 pr_warn("GPT:%lld != %lld\n",
496 printk(KERN_WARNING "GPT:%lld != %lld\n",
497 (unsigned long long)le64_to_cpu(pgpt->alternate_lba), 554 (unsigned long long)le64_to_cpu(pgpt->alternate_lba),
498 (unsigned long long)lastlba); 555 (unsigned long long)lastlba);
499 error_found++; 556 error_found++;
500 } 557 }
501 558
502 if (le64_to_cpu(agpt->my_lba) != lastlba) { 559 if (le64_to_cpu(agpt->my_lba) != lastlba) {
503 printk(KERN_WARNING 560 pr_warn("GPT:Alternate GPT header not at the end of the disk.\n");
504 "GPT:Alternate GPT header not at the end of the disk.\n"); 561 pr_warn("GPT:%lld != %lld\n",
505 printk(KERN_WARNING "GPT:%lld != %lld\n",
506 (unsigned long long)le64_to_cpu(agpt->my_lba), 562 (unsigned long long)le64_to_cpu(agpt->my_lba),
507 (unsigned long long)lastlba); 563 (unsigned long long)lastlba);
508 error_found++; 564 error_found++;
509 } 565 }
510 566
511 if (error_found) 567 if (error_found)
512 printk(KERN_WARNING 568 pr_warn("GPT: Use GNU Parted to correct GPT errors.\n");
513 "GPT: Use GNU Parted to correct GPT errors.\n");
514 return; 569 return;
515} 570}
516 571
@@ -536,6 +591,7 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt,
536 gpt_header *pgpt = NULL, *agpt = NULL; 591 gpt_header *pgpt = NULL, *agpt = NULL;
537 gpt_entry *pptes = NULL, *aptes = NULL; 592 gpt_entry *pptes = NULL, *aptes = NULL;
538 legacy_mbr *legacymbr; 593 legacy_mbr *legacymbr;
594 sector_t total_sectors = i_size_read(state->bdev->bd_inode) >> 9;
539 u64 lastlba; 595 u64 lastlba;
540 596
541 if (!ptes) 597 if (!ptes)
@@ -543,17 +599,22 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt,
543 599
544 lastlba = last_lba(state->bdev); 600 lastlba = last_lba(state->bdev);
545 if (!force_gpt) { 601 if (!force_gpt) {
546 /* This will be added to the EFI Spec. per Intel after v1.02. */ 602 /* This will be added to the EFI Spec. per Intel after v1.02. */
547 legacymbr = kzalloc(sizeof (*legacymbr), GFP_KERNEL); 603 legacymbr = kzalloc(sizeof(*legacymbr), GFP_KERNEL);
548 if (legacymbr) { 604 if (!legacymbr)
549 read_lba(state, 0, (u8 *) legacymbr, 605 goto fail;
550 sizeof (*legacymbr)); 606
551 good_pmbr = is_pmbr_valid(legacymbr); 607 read_lba(state, 0, (u8 *)legacymbr, sizeof(*legacymbr));
552 kfree(legacymbr); 608 good_pmbr = is_pmbr_valid(legacymbr, total_sectors);
553 } 609 kfree(legacymbr);
554 if (!good_pmbr) 610
555 goto fail; 611 if (!good_pmbr)
556 } 612 goto fail;
613
614 pr_debug("Device has a %s MBR\n",
615 good_pmbr == GPT_MBR_PROTECTIVE ?
616 "protective" : "hybrid");
617 }
557 618
558 good_pgpt = is_gpt_valid(state, GPT_PRIMARY_PARTITION_TABLE_LBA, 619 good_pgpt = is_gpt_valid(state, GPT_PRIMARY_PARTITION_TABLE_LBA,
559 &pgpt, &pptes); 620 &pgpt, &pptes);
@@ -576,11 +637,8 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt,
576 *ptes = pptes; 637 *ptes = pptes;
577 kfree(agpt); 638 kfree(agpt);
578 kfree(aptes); 639 kfree(aptes);
579 if (!good_agpt) { 640 if (!good_agpt)
580 printk(KERN_WARNING 641 pr_warn("Alternate GPT is invalid, using primary GPT.\n");
581 "Alternate GPT is invalid, "
582 "using primary GPT.\n");
583 }
584 return 1; 642 return 1;
585 } 643 }
586 else if (good_agpt) { 644 else if (good_agpt) {
@@ -588,8 +646,7 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt,
588 *ptes = aptes; 646 *ptes = aptes;
589 kfree(pgpt); 647 kfree(pgpt);
590 kfree(pptes); 648 kfree(pptes);
591 printk(KERN_WARNING 649 pr_warn("Primary GPT is invalid, using alternate GPT.\n");
592 "Primary GPT is invalid, using alternate GPT.\n");
593 return 1; 650 return 1;
594 } 651 }
595 652
@@ -651,8 +708,7 @@ int efi_partition(struct parsed_partitions *state)
651 put_partition(state, i+1, start * ssz, size * ssz); 708 put_partition(state, i+1, start * ssz, size * ssz);
652 709
653 /* If this is a RAID volume, tell md */ 710 /* If this is a RAID volume, tell md */
654 if (!efi_guidcmp(ptes[i].partition_type_guid, 711 if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_RAID_GUID))
655 PARTITION_LINUX_RAID_GUID))
656 state->parts[i + 1].flags = ADDPART_FLAG_RAID; 712 state->parts[i + 1].flags = ADDPART_FLAG_RAID;
657 713
658 info = &state->parts[i + 1].info; 714 info = &state->parts[i + 1].info;
diff --git a/block/partitions/efi.h b/block/partitions/efi.h
index b69ab729558f..4efcafba7e64 100644
--- a/block/partitions/efi.h
+++ b/block/partitions/efi.h
@@ -37,6 +37,9 @@
37#define EFI_PMBR_OSTYPE_EFI 0xEF 37#define EFI_PMBR_OSTYPE_EFI 0xEF
38#define EFI_PMBR_OSTYPE_EFI_GPT 0xEE 38#define EFI_PMBR_OSTYPE_EFI_GPT 0xEE
39 39
40#define GPT_MBR_PROTECTIVE 1
41#define GPT_MBR_HYBRID 2
42
40#define GPT_HEADER_SIGNATURE 0x5452415020494645ULL 43#define GPT_HEADER_SIGNATURE 0x5452415020494645ULL
41#define GPT_HEADER_REVISION_V1 0x00010000 44#define GPT_HEADER_REVISION_V1 0x00010000
42#define GPT_PRIMARY_PARTITION_TABLE_LBA 1 45#define GPT_PRIMARY_PARTITION_TABLE_LBA 1
@@ -101,11 +104,25 @@ typedef struct _gpt_entry {
101 efi_char16_t partition_name[72 / sizeof (efi_char16_t)]; 104 efi_char16_t partition_name[72 / sizeof (efi_char16_t)];
102} __attribute__ ((packed)) gpt_entry; 105} __attribute__ ((packed)) gpt_entry;
103 106
107typedef struct _gpt_mbr_record {
108 u8 boot_indicator; /* unused by EFI, set to 0x80 for bootable */
109 u8 start_head; /* unused by EFI, pt start in CHS */
110 u8 start_sector; /* unused by EFI, pt start in CHS */
111 u8 start_track;
112 u8 os_type; /* EFI and legacy non-EFI OS types */
113 u8 end_head; /* unused by EFI, pt end in CHS */
114 u8 end_sector; /* unused by EFI, pt end in CHS */
115 u8 end_track; /* unused by EFI, pt end in CHS */
116 __le32 starting_lba; /* used by EFI - start addr of the on disk pt */
117 __le32 size_in_lba; /* used by EFI - size of pt in LBA */
118} __packed gpt_mbr_record;
119
120
104typedef struct _legacy_mbr { 121typedef struct _legacy_mbr {
105 u8 boot_code[440]; 122 u8 boot_code[440];
106 __le32 unique_mbr_signature; 123 __le32 unique_mbr_signature;
107 __le16 unknown; 124 __le16 unknown;
108 struct partition partition_record[4]; 125 gpt_mbr_record partition_record[4];
109 __le16 signature; 126 __le16 signature;
110} __attribute__ ((packed)) legacy_mbr; 127} __attribute__ ((packed)) legacy_mbr;
111 128
@@ -113,22 +130,3 @@ typedef struct _legacy_mbr {
113extern int efi_partition(struct parsed_partitions *state); 130extern int efi_partition(struct parsed_partitions *state);
114 131
115#endif 132#endif
116
117/*
118 * Overrides for Emacs so that we follow Linus's tabbing style.
119 * Emacs will notice this stuff at the end of the file and automatically
120 * adjust the settings for this buffer only. This must remain at the end
121 * of the file.
122 * --------------------------------------------------------------------------
123 * Local variables:
124 * c-indent-level: 4
125 * c-brace-imaginary-offset: 0
126 * c-brace-offset: -4
127 * c-argdecl-indent: 4
128 * c-label-offset: -4
129 * c-continued-statement-offset: 4
130 * c-continued-brace-offset: 0
131 * indent-tabs-mode: nil
132 * tab-width: 8
133 * End:
134 */