diff options
Diffstat (limited to 'block')
-rw-r--r-- | block/bio.c | 18 | ||||
-rw-r--r-- | block/blk-core.c | 2 | ||||
-rw-r--r-- | block/blk-flush.c | 9 | ||||
-rw-r--r-- | block/partitions/cmdline.c | 57 |
4 files changed, 82 insertions, 4 deletions
diff --git a/block/bio.c b/block/bio.c index 5f75635..db9a40e 100644 --- a/block/bio.c +++ b/block/bio.c @@ -1997,6 +1997,24 @@ bad: } EXPORT_SYMBOL(bioset_init); +/* + * Initialize and setup a new bio_set, based on the settings from + * another bio_set. + */ +int bioset_init_from_src(struct bio_set *bs, struct bio_set *src) +{ + int flags; + + flags = 0; + if (src->bvec_pool.min_nr) + flags |= BIOSET_NEED_BVECS; + if (src->rescue_workqueue) + flags |= BIOSET_NEED_RESCUER; + + return bioset_init(bs, src->bio_pool.min_nr, src->front_pad, flags); +} +EXPORT_SYMBOL(bioset_init_from_src); + #ifdef CONFIG_BLK_CGROUP /** diff --git a/block/blk-core.c b/block/blk-core.c index 3f56be1..cf0ee76 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -2220,10 +2220,10 @@ static inline int blk_partition_remap(struct bio *bio) if (bio_check_eod(bio, part_nr_sects_read(p))) goto out; bio->bi_iter.bi_sector += p->start_sect; - bio->bi_partno = 0; trace_block_bio_remap(bio->bi_disk->queue, bio, part_devt(p), bio->bi_iter.bi_sector - p->start_sect); } + bio->bi_partno = 0; ret = 0; out: rcu_read_unlock(); diff --git a/block/blk-flush.c b/block/blk-flush.c index f171706..058abdb 100644 --- a/block/blk-flush.c +++ b/block/blk-flush.c @@ -94,7 +94,7 @@ enum { }; static bool blk_kick_flush(struct request_queue *q, - struct blk_flush_queue *fq); + struct blk_flush_queue *fq, unsigned int flags); static unsigned int blk_flush_policy(unsigned long fflags, struct request *rq) { @@ -212,7 +212,7 @@ static bool blk_flush_complete_seq(struct request *rq, BUG(); } - kicked = blk_kick_flush(q, fq); + kicked = blk_kick_flush(q, fq, rq->cmd_flags); return kicked | queued; } @@ -281,6 +281,7 @@ static void flush_end_io(struct request *flush_rq, blk_status_t error) * blk_kick_flush - consider issuing flush request * @q: request_queue being kicked * @fq: flush queue + * @flags: cmd_flags of the original request * * Flush related states of @q have changed, consider issuing flush request. * Please read the comment at the top of this file for more info. @@ -291,7 +292,8 @@ static void flush_end_io(struct request *flush_rq, blk_status_t error) * RETURNS: * %true if flush was issued, %false otherwise. */ -static bool blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq) +static bool blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq, + unsigned int flags) { struct list_head *pending = &fq->flush_queue[fq->flush_pending_idx]; struct request *first_rq = @@ -346,6 +348,7 @@ static bool blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq) } flush_rq->cmd_flags = REQ_OP_FLUSH | REQ_PREFLUSH; + flush_rq->cmd_flags |= (flags & REQ_DRV) | (flags & REQ_FAILFAST_MASK); flush_rq->rq_flags |= RQF_FLUSH_SEQ; flush_rq->rq_disk = first_rq->rq_disk; flush_rq->end_io = flush_end_io; diff --git a/block/partitions/cmdline.c b/block/partitions/cmdline.c index e333583..60fb3df 100644 --- a/block/partitions/cmdline.c +++ b/block/partitions/cmdline.c @@ -58,6 +58,62 @@ static int __init cmdline_parts_setup(char *s) } __setup("blkdevparts=", cmdline_parts_setup); +static bool has_overlaps(sector_t from, sector_t size, + sector_t from2, sector_t size2) +{ + sector_t end = from + size; + sector_t end2 = from2 + size2; + + if (from >= from2 && from < end2) + return true; + + if (end > from2 && end <= end2) + return true; + + if (from2 >= from && from2 < end) + return true; + + if (end2 > from && end2 <= end) + return true; + + return false; +} + +static inline void overlaps_warns_header(void) +{ + pr_warn("Overlapping partitions are used in command line partitions."); + pr_warn("Don't use filesystems on overlapping partitions:"); +} + +static void cmdline_parts_verifier(int slot, struct parsed_partitions *state) +{ + int i; + bool header = true; + + for (; slot < state->limit && state->parts[slot].has_info; slot++) { + for (i = slot+1; i < state->limit && state->parts[i].has_info; + i++) { + if (has_overlaps(state->parts[slot].from, + state->parts[slot].size, + state->parts[i].from, + state->parts[i].size)) { + if (header) { + header = false; + overlaps_warns_header(); + } + pr_warn("%s[%llu,%llu] overlaps with " + "%s[%llu,%llu].", + state->parts[slot].info.volname, + (u64)state->parts[slot].from << 9, + (u64)state->parts[slot].size << 9, + state->parts[i].info.volname, + (u64)state->parts[i].from << 9, + (u64)state->parts[i].size << 9); + } + } + } +} + /* * Purpose: allocate cmdline partitions. * Returns: @@ -93,6 +149,7 @@ int cmdline_partition(struct parsed_partitions *state) disk_size = get_capacity(state->bdev->bd_disk) << 9; cmdline_parts_set(parts, disk_size, 1, add_part, (void *)state); + cmdline_parts_verifier(1, state); strlcat(state->pp_buf, "\n", PAGE_SIZE); |