|
|
@@ -26,6 +26,9 @@
|
|
|
#include "raid0.h"
|
|
|
#include "raid5.h"
|
|
|
|
|
|
+static int default_layout = 0;
|
|
|
+module_param(default_layout, int, 0644);
|
|
|
+
|
|
|
#define UNSUPPORTED_MDDEV_FLAGS \
|
|
|
((1L << MD_HAS_JOURNAL) | \
|
|
|
(1L << MD_JOURNAL_CLEAN) | \
|
|
|
@@ -146,6 +149,19 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf)
|
|
|
}
|
|
|
pr_debug("md/raid0:%s: FINAL %d zones\n",
|
|
|
mdname(mddev), conf->nr_strip_zones);
|
|
|
+
|
|
|
+ if (conf->nr_strip_zones == 1) {
|
|
|
+ conf->layout = RAID0_ORIG_LAYOUT;
|
|
|
+ } else if (default_layout == RAID0_ORIG_LAYOUT ||
|
|
|
+ default_layout == RAID0_ALT_MULTIZONE_LAYOUT) {
|
|
|
+ conf->layout = default_layout;
|
|
|
+ } else {
|
|
|
+ pr_err("md/raid0:%s: cannot assemble multi-zone RAID0 with default_layout setting\n",
|
|
|
+ mdname(mddev));
|
|
|
+ pr_err("md/raid0: please set raid.default_layout to 1 or 2\n");
|
|
|
+ err = -ENOTSUPP;
|
|
|
+ goto abort;
|
|
|
+ }
|
|
|
/*
|
|
|
* now since we have the hard sector sizes, we can make sure
|
|
|
* chunk size is a multiple of that sector size
|
|
|
@@ -555,10 +571,12 @@ static void raid0_handle_discard(struct mddev *mddev, struct bio *bio)
|
|
|
|
|
|
static bool raid0_make_request(struct mddev *mddev, struct bio *bio)
|
|
|
{
|
|
|
+ struct r0conf *conf = mddev->private;
|
|
|
struct strip_zone *zone;
|
|
|
struct md_rdev *tmp_dev;
|
|
|
sector_t bio_sector;
|
|
|
sector_t sector;
|
|
|
+ sector_t orig_sector;
|
|
|
unsigned chunk_sects;
|
|
|
unsigned sectors;
|
|
|
|
|
|
@@ -592,8 +610,21 @@ static bool raid0_make_request(struct mddev *mddev, struct bio *bio)
|
|
|
bio = split;
|
|
|
}
|
|
|
|
|
|
+ orig_sector = sector;
|
|
|
zone = find_zone(mddev->private, §or);
|
|
|
- tmp_dev = map_sector(mddev, zone, sector, §or);
|
|
|
+ switch (conf->layout) {
|
|
|
+ case RAID0_ORIG_LAYOUT:
|
|
|
+ tmp_dev = map_sector(mddev, zone, orig_sector, §or);
|
|
|
+ break;
|
|
|
+ case RAID0_ALT_MULTIZONE_LAYOUT:
|
|
|
+ tmp_dev = map_sector(mddev, zone, sector, §or);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ WARN("md/raid0:%s: Invalid layout\n", mdname(mddev));
|
|
|
+ bio_io_error(bio);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
bio_set_dev(bio, tmp_dev->bdev);
|
|
|
bio->bi_iter.bi_sector = sector + zone->dev_start +
|
|
|
tmp_dev->data_offset;
|