|
19 | 19 | #include "raid0.h" |
20 | 20 | #include "raid5.h" |
21 | 21 |
|
| 22 | +static int default_layout = 0; |
| 23 | +module_param(default_layout, int, 0644); |
| 24 | + |
22 | 25 | #define UNSUPPORTED_MDDEV_FLAGS \ |
23 | 26 | ((1L << MD_HAS_JOURNAL) | \ |
24 | 27 | (1L << MD_JOURNAL_CLEAN) | \ |
@@ -139,6 +142,19 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) |
139 | 142 | } |
140 | 143 | pr_debug("md/raid0:%s: FINAL %d zones\n", |
141 | 144 | mdname(mddev), conf->nr_strip_zones); |
| 145 | + |
| 146 | + if (conf->nr_strip_zones == 1) { |
| 147 | + conf->layout = RAID0_ORIG_LAYOUT; |
| 148 | + } else if (default_layout == RAID0_ORIG_LAYOUT || |
| 149 | + default_layout == RAID0_ALT_MULTIZONE_LAYOUT) { |
| 150 | + conf->layout = default_layout; |
| 151 | + } else { |
| 152 | + pr_err("md/raid0:%s: cannot assemble multi-zone RAID0 with default_layout setting\n", |
| 153 | + mdname(mddev)); |
| 154 | + pr_err("md/raid0: please set raid.default_layout to 1 or 2\n"); |
| 155 | + err = -ENOTSUPP; |
| 156 | + goto abort; |
| 157 | + } |
142 | 158 | /* |
143 | 159 | * now since we have the hard sector sizes, we can make sure |
144 | 160 | * chunk size is a multiple of that sector size |
@@ -547,10 +563,12 @@ static void raid0_handle_discard(struct mddev *mddev, struct bio *bio) |
547 | 563 |
|
548 | 564 | static bool raid0_make_request(struct mddev *mddev, struct bio *bio) |
549 | 565 | { |
| 566 | + struct r0conf *conf = mddev->private; |
550 | 567 | struct strip_zone *zone; |
551 | 568 | struct md_rdev *tmp_dev; |
552 | 569 | sector_t bio_sector; |
553 | 570 | sector_t sector; |
| 571 | + sector_t orig_sector; |
554 | 572 | unsigned chunk_sects; |
555 | 573 | unsigned sectors; |
556 | 574 |
|
@@ -584,8 +602,20 @@ static bool raid0_make_request(struct mddev *mddev, struct bio *bio) |
584 | 602 | bio = split; |
585 | 603 | } |
586 | 604 |
|
| 605 | + orig_sector = sector; |
587 | 606 | zone = find_zone(mddev->private, §or); |
588 | | - tmp_dev = map_sector(mddev, zone, sector, §or); |
| 607 | + switch (conf->layout) { |
| 608 | + case RAID0_ORIG_LAYOUT: |
| 609 | + tmp_dev = map_sector(mddev, zone, orig_sector, §or); |
| 610 | + break; |
| 611 | + case RAID0_ALT_MULTIZONE_LAYOUT: |
| 612 | + tmp_dev = map_sector(mddev, zone, sector, §or); |
| 613 | + break; |
| 614 | + default: |
| 615 | + WARN("md/raid0:%s: Invalid layout\n", mdname(mddev)); |
| 616 | + bio_io_error(bio); |
| 617 | + return true; |
| 618 | + } |
589 | 619 |
|
590 | 620 | if (unlikely(is_mddev_broken(tmp_dev, "raid0"))) { |
591 | 621 | bio_io_error(bio); |
|
0 commit comments