From: Linus Torvalds Date: Mon, 30 Mar 2020 18:20:13 +0000 (-0700) Subject: Merge tag 'for-5.7/block-2020-03-29' of git://git.kernel.dk/linux-block X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=10f36b1e80a9f7afdaefe6f0b06dcdf89715eed7;p=linux.git Merge tag 'for-5.7/block-2020-03-29' of git://git.kernel.dk/linux-block Pull block updates from Jens Axboe: - Online capacity resizing (Balbir) - Number of hardware queue change fixes (Bart) - null_blk fault injection addition (Bart) - Cleanup of queue allocation, unifying the node/no-node API (Christoph) - Cleanup of genhd, moving code to where it makes sense (Christoph) - Cleanup of the partition handling code (Christoph) - disk stat fixes/improvements (Konstantin) - BFQ improvements (Paolo) - Various fixes and improvements * tag 'for-5.7/block-2020-03-29' of git://git.kernel.dk/linux-block: (72 commits) block: return NULL in blk_alloc_queue() on error block: move bio_map_* to blk-map.c Revert "blkdev: check for valid request queue before issuing flush" block: simplify queue allocation bcache: pass the make_request methods to blk_queue_make_request null_blk: use blk_mq_init_queue_data block: add a blk_mq_init_queue_data helper block: move the ->devnode callback to struct block_device_operations block: move the part_stat* helpers from genhd.h to a new header block: move block layer internals out of include/linux/genhd.h block: move guard_bio_eod to bio.c block: unexport get_gendisk block: unexport disk_map_sector_rcu block: unexport disk_get_part block: mark part_in_flight and part_in_flight_rw static block: mark block_depr static block: factor out requeue handling from dispatch code block/diskstats: replace time_in_queue with sum of request times block/diskstats: accumulate all per-cpu counters in one pass block/diskstats: more accurate approximation of io_ticks for slow disks ... --- 10f36b1e80a9f7afdaefe6f0b06dcdf89715eed7 diff --cc block/genhd.c index 9c2e13ce0d195,14cf395a14795..06b642b23a077 --- a/block/genhd.c +++ b/block/genhd.c @@@ -299,44 -372,7 +372,43 @@@ struct hd_struct *disk_map_sector_rcu(s } return &disk->part0; } - EXPORT_SYMBOL_GPL(disk_map_sector_rcu); +/** + * disk_has_partitions + * @disk: gendisk of interest + * + * Walk through the partition table and check if valid partition exists. + * + * CONTEXT: + * Don't care. + * + * RETURNS: + * True if the gendisk has at least one valid non-zero size partition. + * Otherwise false. + */ +bool disk_has_partitions(struct gendisk *disk) +{ + struct disk_part_tbl *ptbl; + int i; + bool ret = false; + + rcu_read_lock(); + ptbl = rcu_dereference(disk->part_tbl); + + /* Iterate partitions skipping the whole device at index 0 */ + for (i = 1; i < ptbl->len; i++) { + if (rcu_dereference(ptbl->part[i])) { + ret = true; + break; + } + } + + rcu_read_unlock(); + + return ret; +} +EXPORT_SYMBOL_GPL(disk_has_partitions); + /* * Can be deleted altogether. Later. * diff --cc include/linux/genhd.h index 07dc91835b989,85b9e253cd398..9b3fffdf40116 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@@ -283,144 -296,6 +284,7 @@@ extern void disk_part_iter_init(struct struct gendisk *disk, unsigned int flags); extern struct hd_struct *disk_part_iter_next(struct disk_part_iter *piter); extern void disk_part_iter_exit(struct disk_part_iter *piter); - - extern struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, - sector_t sector); - bool disk_has_partitions(struct gendisk *disk); - - /* - * Macros to operate on percpu disk statistics: - * - * {disk|part|all}_stat_{add|sub|inc|dec}() modify the stat counters - * and should be called between disk_stat_lock() and - * disk_stat_unlock(). - * - * part_stat_read() can be called at any time. - * - * part_stat_{add|set_all}() and {init|free}_part_stats are for - * internal use only. - */ - #ifdef CONFIG_SMP - #define part_stat_lock() ({ rcu_read_lock(); get_cpu(); }) - #define part_stat_unlock() do { put_cpu(); rcu_read_unlock(); } while (0) - - #define part_stat_get_cpu(part, field, cpu) \ - (per_cpu_ptr((part)->dkstats, (cpu))->field) - - #define part_stat_get(part, field) \ - part_stat_get_cpu(part, field, smp_processor_id()) - - #define part_stat_read(part, field) \ - ({ \ - typeof((part)->dkstats->field) res = 0; \ - unsigned int _cpu; \ - for_each_possible_cpu(_cpu) \ - res += per_cpu_ptr((part)->dkstats, _cpu)->field; \ - res; \ - }) - - static inline void part_stat_set_all(struct hd_struct *part, int value) - { - int i; - - for_each_possible_cpu(i) - memset(per_cpu_ptr(part->dkstats, i), value, - sizeof(struct disk_stats)); - } - - static inline int init_part_stats(struct hd_struct *part) - { - part->dkstats = alloc_percpu(struct disk_stats); - if (!part->dkstats) - return 0; - return 1; - } - - static inline void free_part_stats(struct hd_struct *part) - { - free_percpu(part->dkstats); - } - - #else /* !CONFIG_SMP */ - #define part_stat_lock() ({ rcu_read_lock(); 0; }) - #define part_stat_unlock() rcu_read_unlock() - - #define part_stat_get(part, field) ((part)->dkstats.field) - #define part_stat_get_cpu(part, field, cpu) part_stat_get(part, field) - #define part_stat_read(part, field) part_stat_get(part, field) - - static inline void part_stat_set_all(struct hd_struct *part, int value) - { - memset(&part->dkstats, value, sizeof(struct disk_stats)); - } - - static inline int init_part_stats(struct hd_struct *part) - { - return 1; - } - - static inline void free_part_stats(struct hd_struct *part) - { - } - - #endif /* CONFIG_SMP */ - - #define part_stat_read_msecs(part, which) \ - div_u64(part_stat_read(part, nsecs[which]), NSEC_PER_MSEC) - - #define part_stat_read_accum(part, field) \ - (part_stat_read(part, field[STAT_READ]) + \ - part_stat_read(part, field[STAT_WRITE]) + \ - part_stat_read(part, field[STAT_DISCARD])) - - #define __part_stat_add(part, field, addnd) \ - (part_stat_get(part, field) += (addnd)) - - #define part_stat_add(part, field, addnd) do { \ - __part_stat_add((part), field, addnd); \ - if ((part)->partno) \ - __part_stat_add(&part_to_disk((part))->part0, \ - field, addnd); \ - } while (0) - - #define part_stat_dec(gendiskp, field) \ - part_stat_add(gendiskp, field, -1) - #define part_stat_inc(gendiskp, field) \ - part_stat_add(gendiskp, field, 1) - #define part_stat_sub(gendiskp, field, subnd) \ - part_stat_add(gendiskp, field, -subnd) - - #define part_stat_local_dec(gendiskp, field) \ - local_dec(&(part_stat_get(gendiskp, field))) - #define part_stat_local_inc(gendiskp, field) \ - local_inc(&(part_stat_get(gendiskp, field))) - #define part_stat_local_read(gendiskp, field) \ - local_read(&(part_stat_get(gendiskp, field))) - #define part_stat_local_read_cpu(gendiskp, field, cpu) \ - local_read(&(part_stat_get_cpu(gendiskp, field, cpu))) - - unsigned int part_in_flight(struct request_queue *q, struct hd_struct *part); - void part_in_flight_rw(struct request_queue *q, struct hd_struct *part, - unsigned int inflight[2]); - void part_dec_in_flight(struct request_queue *q, struct hd_struct *part, - int rw); - void part_inc_in_flight(struct request_queue *q, struct hd_struct *part, - int rw); - - static inline struct partition_meta_info *alloc_part_info(struct gendisk *disk) - { - if (disk) - return kzalloc_node(sizeof(struct partition_meta_info), - GFP_KERNEL, disk->node_id); - return kzalloc(sizeof(struct partition_meta_info), GFP_KERNEL); - } - - static inline void free_part_info(struct hd_struct *part) - { - kfree(part->info); - } - - void update_io_ticks(struct hd_struct *part, unsigned long now); ++extern bool disk_has_partitions(struct gendisk *disk); /* block/genhd.c */ extern void device_add_disk(struct device *parent, struct gendisk *disk,