831 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 raid0.c : Multiple Devices driver for Linux4 Copyright (C) 1994-96 Marc ZYNGIER5 <zyngier@ufr-info-p7.ibp.fr> or6 <maz@gloups.fdn.fr>7 Copyright (C) 1999, 2000 Ingo Molnar, Red Hat8 9 RAID-0 management functions.10 11*/12 13#include <linux/blkdev.h>14#include <linux/seq_file.h>15#include <linux/module.h>16#include <linux/slab.h>17#include <trace/events/block.h>18#include "md.h"19#include "raid0.h"20#include "raid5.h"21 22static int default_layout = 0;23module_param(default_layout, int, 0644);24 25#define UNSUPPORTED_MDDEV_FLAGS \26 ((1L << MD_HAS_JOURNAL) | \27 (1L << MD_JOURNAL_CLEAN) | \28 (1L << MD_FAILFAST_SUPPORTED) |\29 (1L << MD_HAS_PPL) | \30 (1L << MD_HAS_MULTIPLE_PPLS))31 32/*33 * inform the user of the raid configuration34*/35static void dump_zones(struct mddev *mddev)36{37 int j, k;38 sector_t zone_size = 0;39 sector_t zone_start = 0;40 struct r0conf *conf = mddev->private;41 int raid_disks = conf->strip_zone[0].nb_dev;42 pr_debug("md: RAID0 configuration for %s - %d zone%s\n",43 mdname(mddev),44 conf->nr_strip_zones, conf->nr_strip_zones==1?"":"s");45 for (j = 0; j < conf->nr_strip_zones; j++) {46 char line[200];47 int len = 0;48 49 for (k = 0; k < conf->strip_zone[j].nb_dev; k++)50 len += scnprintf(line+len, 200-len, "%s%pg", k?"/":"",51 conf->devlist[j * raid_disks + k]->bdev);52 pr_debug("md: zone%d=[%s]\n", j, line);53 54 zone_size = conf->strip_zone[j].zone_end - zone_start;55 pr_debug(" zone-offset=%10lluKB, device-offset=%10lluKB, size=%10lluKB\n",56 (unsigned long long)zone_start>>1,57 (unsigned long long)conf->strip_zone[j].dev_start>>1,58 (unsigned long long)zone_size>>1);59 zone_start = conf->strip_zone[j].zone_end;60 }61}62 63static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf)64{65 int i, c, err;66 sector_t curr_zone_end, sectors;67 struct md_rdev *smallest, *rdev1, *rdev2, *rdev, **dev;68 struct strip_zone *zone;69 int cnt;70 struct r0conf *conf = kzalloc(sizeof(*conf), GFP_KERNEL);71 unsigned blksize = 512;72 73 *private_conf = ERR_PTR(-ENOMEM);74 if (!conf)75 return -ENOMEM;76 rdev_for_each(rdev1, mddev) {77 pr_debug("md/raid0:%s: looking at %pg\n",78 mdname(mddev),79 rdev1->bdev);80 c = 0;81 82 /* round size to chunk_size */83 sectors = rdev1->sectors;84 sector_div(sectors, mddev->chunk_sectors);85 rdev1->sectors = sectors * mddev->chunk_sectors;86 87 blksize = max(blksize, queue_logical_block_size(88 rdev1->bdev->bd_disk->queue));89 90 rdev_for_each(rdev2, mddev) {91 pr_debug("md/raid0:%s: comparing %pg(%llu)"92 " with %pg(%llu)\n",93 mdname(mddev),94 rdev1->bdev,95 (unsigned long long)rdev1->sectors,96 rdev2->bdev,97 (unsigned long long)rdev2->sectors);98 if (rdev2 == rdev1) {99 pr_debug("md/raid0:%s: END\n",100 mdname(mddev));101 break;102 }103 if (rdev2->sectors == rdev1->sectors) {104 /*105 * Not unique, don't count it as a new106 * group107 */108 pr_debug("md/raid0:%s: EQUAL\n",109 mdname(mddev));110 c = 1;111 break;112 }113 pr_debug("md/raid0:%s: NOT EQUAL\n",114 mdname(mddev));115 }116 if (!c) {117 pr_debug("md/raid0:%s: ==> UNIQUE\n",118 mdname(mddev));119 conf->nr_strip_zones++;120 pr_debug("md/raid0:%s: %d zones\n",121 mdname(mddev), conf->nr_strip_zones);122 }123 }124 pr_debug("md/raid0:%s: FINAL %d zones\n",125 mdname(mddev), conf->nr_strip_zones);126 127 /*128 * now since we have the hard sector sizes, we can make sure129 * chunk size is a multiple of that sector size130 */131 if ((mddev->chunk_sectors << 9) % blksize) {132 pr_warn("md/raid0:%s: chunk_size of %d not multiple of block size %d\n",133 mdname(mddev),134 mddev->chunk_sectors << 9, blksize);135 err = -EINVAL;136 goto abort;137 }138 139 err = -ENOMEM;140 conf->strip_zone = kcalloc(conf->nr_strip_zones,141 sizeof(struct strip_zone),142 GFP_KERNEL);143 if (!conf->strip_zone)144 goto abort;145 conf->devlist = kzalloc(array3_size(sizeof(struct md_rdev *),146 conf->nr_strip_zones,147 mddev->raid_disks),148 GFP_KERNEL);149 if (!conf->devlist)150 goto abort;151 152 /* The first zone must contain all devices, so here we check that153 * there is a proper alignment of slots to devices and find them all154 */155 zone = &conf->strip_zone[0];156 cnt = 0;157 smallest = NULL;158 dev = conf->devlist;159 err = -EINVAL;160 rdev_for_each(rdev1, mddev) {161 int j = rdev1->raid_disk;162 163 if (mddev->level == 10) {164 /* taking over a raid10-n2 array */165 j /= 2;166 rdev1->new_raid_disk = j;167 }168 169 if (mddev->level == 1) {170 /* taiking over a raid1 array-171 * we have only one active disk172 */173 j = 0;174 rdev1->new_raid_disk = j;175 }176 177 if (j < 0) {178 pr_warn("md/raid0:%s: remove inactive devices before converting to RAID0\n",179 mdname(mddev));180 goto abort;181 }182 if (j >= mddev->raid_disks) {183 pr_warn("md/raid0:%s: bad disk number %d - aborting!\n",184 mdname(mddev), j);185 goto abort;186 }187 if (dev[j]) {188 pr_warn("md/raid0:%s: multiple devices for %d - aborting!\n",189 mdname(mddev), j);190 goto abort;191 }192 dev[j] = rdev1;193 194 if (!smallest || (rdev1->sectors < smallest->sectors))195 smallest = rdev1;196 cnt++;197 }198 if (cnt != mddev->raid_disks) {199 pr_warn("md/raid0:%s: too few disks (%d of %d) - aborting!\n",200 mdname(mddev), cnt, mddev->raid_disks);201 goto abort;202 }203 zone->nb_dev = cnt;204 zone->zone_end = smallest->sectors * cnt;205 206 curr_zone_end = zone->zone_end;207 208 /* now do the other zones */209 for (i = 1; i < conf->nr_strip_zones; i++)210 {211 int j;212 213 zone = conf->strip_zone + i;214 dev = conf->devlist + i * mddev->raid_disks;215 216 pr_debug("md/raid0:%s: zone %d\n", mdname(mddev), i);217 zone->dev_start = smallest->sectors;218 smallest = NULL;219 c = 0;220 221 for (j=0; j<cnt; j++) {222 rdev = conf->devlist[j];223 if (rdev->sectors <= zone->dev_start) {224 pr_debug("md/raid0:%s: checking %pg ... nope\n",225 mdname(mddev),226 rdev->bdev);227 continue;228 }229 pr_debug("md/raid0:%s: checking %pg ..."230 " contained as device %d\n",231 mdname(mddev),232 rdev->bdev, c);233 dev[c] = rdev;234 c++;235 if (!smallest || rdev->sectors < smallest->sectors) {236 smallest = rdev;237 pr_debug("md/raid0:%s: (%llu) is smallest!.\n",238 mdname(mddev),239 (unsigned long long)rdev->sectors);240 }241 }242 243 zone->nb_dev = c;244 sectors = (smallest->sectors - zone->dev_start) * c;245 pr_debug("md/raid0:%s: zone->nb_dev: %d, sectors: %llu\n",246 mdname(mddev),247 zone->nb_dev, (unsigned long long)sectors);248 249 curr_zone_end += sectors;250 zone->zone_end = curr_zone_end;251 252 pr_debug("md/raid0:%s: current zone start: %llu\n",253 mdname(mddev),254 (unsigned long long)smallest->sectors);255 }256 257 if (conf->nr_strip_zones == 1 || conf->strip_zone[1].nb_dev == 1) {258 conf->layout = RAID0_ORIG_LAYOUT;259 } else if (mddev->layout == RAID0_ORIG_LAYOUT ||260 mddev->layout == RAID0_ALT_MULTIZONE_LAYOUT) {261 conf->layout = mddev->layout;262 } else if (default_layout == RAID0_ORIG_LAYOUT ||263 default_layout == RAID0_ALT_MULTIZONE_LAYOUT) {264 conf->layout = default_layout;265 } else {266 pr_err("md/raid0:%s: cannot assemble multi-zone RAID0 with default_layout setting\n",267 mdname(mddev));268 pr_err("md/raid0: please set raid0.default_layout to 1 or 2\n");269 err = -EOPNOTSUPP;270 goto abort;271 }272 273 if (conf->layout == RAID0_ORIG_LAYOUT) {274 for (i = 1; i < conf->nr_strip_zones; i++) {275 sector_t first_sector = conf->strip_zone[i-1].zone_end;276 277 sector_div(first_sector, mddev->chunk_sectors);278 zone = conf->strip_zone + i;279 /* disk_shift is first disk index used in the zone */280 zone->disk_shift = sector_div(first_sector,281 zone->nb_dev);282 }283 }284 285 pr_debug("md/raid0:%s: done.\n", mdname(mddev));286 *private_conf = conf;287 288 return 0;289abort:290 kfree(conf->strip_zone);291 kfree(conf->devlist);292 kfree(conf);293 *private_conf = ERR_PTR(err);294 return err;295}296 297/* Find the zone which holds a particular offset298 * Update *sectorp to be an offset in that zone299 */300static struct strip_zone *find_zone(struct r0conf *conf,301 sector_t *sectorp)302{303 int i;304 struct strip_zone *z = conf->strip_zone;305 sector_t sector = *sectorp;306 307 for (i = 0; i < conf->nr_strip_zones; i++)308 if (sector < z[i].zone_end) {309 if (i)310 *sectorp = sector - z[i-1].zone_end;311 return z + i;312 }313 BUG();314}315 316/*317 * remaps the bio to the target device. we separate two flows.318 * power 2 flow and a general flow for the sake of performance319*/320static struct md_rdev *map_sector(struct mddev *mddev, struct strip_zone *zone,321 sector_t sector, sector_t *sector_offset)322{323 unsigned int sect_in_chunk;324 sector_t chunk;325 struct r0conf *conf = mddev->private;326 int raid_disks = conf->strip_zone[0].nb_dev;327 unsigned int chunk_sects = mddev->chunk_sectors;328 329 if (is_power_of_2(chunk_sects)) {330 int chunksect_bits = ffz(~chunk_sects);331 /* find the sector offset inside the chunk */332 sect_in_chunk = sector & (chunk_sects - 1);333 sector >>= chunksect_bits;334 /* chunk in zone */335 chunk = *sector_offset;336 /* quotient is the chunk in real device*/337 sector_div(chunk, zone->nb_dev << chunksect_bits);338 } else{339 sect_in_chunk = sector_div(sector, chunk_sects);340 chunk = *sector_offset;341 sector_div(chunk, chunk_sects * zone->nb_dev);342 }343 /*344 * position the bio over the real device345 * real sector = chunk in device + starting of zone346 * + the position in the chunk347 */348 *sector_offset = (chunk * chunk_sects) + sect_in_chunk;349 return conf->devlist[(zone - conf->strip_zone)*raid_disks350 + sector_div(sector, zone->nb_dev)];351}352 353static sector_t raid0_size(struct mddev *mddev, sector_t sectors, int raid_disks)354{355 sector_t array_sectors = 0;356 struct md_rdev *rdev;357 358 WARN_ONCE(sectors || raid_disks,359 "%s does not support generic reshape\n", __func__);360 361 rdev_for_each(rdev, mddev)362 array_sectors += (rdev->sectors &363 ~(sector_t)(mddev->chunk_sectors-1));364 365 return array_sectors;366}367 368static void raid0_free(struct mddev *mddev, void *priv)369{370 struct r0conf *conf = priv;371 372 kfree(conf->strip_zone);373 kfree(conf->devlist);374 kfree(conf);375}376 377static int raid0_set_limits(struct mddev *mddev)378{379 struct queue_limits lim;380 int err;381 382 md_init_stacking_limits(&lim);383 lim.max_hw_sectors = mddev->chunk_sectors;384 lim.max_write_zeroes_sectors = mddev->chunk_sectors;385 lim.io_min = mddev->chunk_sectors << 9;386 lim.io_opt = lim.io_min * mddev->raid_disks;387 err = mddev_stack_rdev_limits(mddev, &lim, MDDEV_STACK_INTEGRITY);388 if (err) {389 queue_limits_cancel_update(mddev->gendisk->queue);390 return err;391 }392 return queue_limits_set(mddev->gendisk->queue, &lim);393}394 395static int raid0_run(struct mddev *mddev)396{397 struct r0conf *conf;398 int ret;399 400 if (mddev->chunk_sectors == 0) {401 pr_warn("md/raid0:%s: chunk size must be set.\n", mdname(mddev));402 return -EINVAL;403 }404 if (md_check_no_bitmap(mddev))405 return -EINVAL;406 407 /* if private is not null, we are here after takeover */408 if (mddev->private == NULL) {409 ret = create_strip_zones(mddev, &conf);410 if (ret < 0)411 return ret;412 mddev->private = conf;413 }414 conf = mddev->private;415 if (!mddev_is_dm(mddev)) {416 ret = raid0_set_limits(mddev);417 if (ret)418 return ret;419 }420 421 /* calculate array device size */422 md_set_array_sectors(mddev, raid0_size(mddev, 0, 0));423 424 pr_debug("md/raid0:%s: md_size is %llu sectors.\n",425 mdname(mddev),426 (unsigned long long)mddev->array_sectors);427 428 dump_zones(mddev);429 430 return md_integrity_register(mddev);431}432 433/*434 * Convert disk_index to the disk order in which it is read/written.435 * For example, if we have 4 disks, they are numbered 0,1,2,3. If we436 * write the disks starting at disk 3, then the read/write order would437 * be disk 3, then 0, then 1, and then disk 2 and we want map_disk_shift()438 * to map the disks as follows 0,1,2,3 => 1,2,3,0. So disk 0 would map439 * to 1, 1 to 2, 2 to 3, and 3 to 0. That way we can compare disks in440 * that 'output' space to understand the read/write disk ordering.441 */442static int map_disk_shift(int disk_index, int num_disks, int disk_shift)443{444 return ((disk_index + num_disks - disk_shift) % num_disks);445}446 447static void raid0_handle_discard(struct mddev *mddev, struct bio *bio)448{449 struct r0conf *conf = mddev->private;450 struct strip_zone *zone;451 sector_t start = bio->bi_iter.bi_sector;452 sector_t end;453 unsigned int stripe_size;454 sector_t first_stripe_index, last_stripe_index;455 sector_t start_disk_offset;456 unsigned int start_disk_index;457 sector_t end_disk_offset;458 unsigned int end_disk_index;459 unsigned int disk;460 sector_t orig_start, orig_end;461 462 orig_start = start;463 zone = find_zone(conf, &start);464 465 if (bio_end_sector(bio) > zone->zone_end) {466 struct bio *split = bio_split(bio,467 zone->zone_end - bio->bi_iter.bi_sector, GFP_NOIO,468 &mddev->bio_set);469 bio_chain(split, bio);470 submit_bio_noacct(bio);471 bio = split;472 end = zone->zone_end;473 } else474 end = bio_end_sector(bio);475 476 orig_end = end;477 if (zone != conf->strip_zone)478 end = end - zone[-1].zone_end;479 480 /* Now start and end is the offset in zone */481 stripe_size = zone->nb_dev * mddev->chunk_sectors;482 483 first_stripe_index = start;484 sector_div(first_stripe_index, stripe_size);485 last_stripe_index = end;486 sector_div(last_stripe_index, stripe_size);487 488 /* In the first zone the original and alternate layouts are the same */489 if ((conf->layout == RAID0_ORIG_LAYOUT) && (zone != conf->strip_zone)) {490 sector_div(orig_start, mddev->chunk_sectors);491 start_disk_index = sector_div(orig_start, zone->nb_dev);492 start_disk_index = map_disk_shift(start_disk_index,493 zone->nb_dev,494 zone->disk_shift);495 sector_div(orig_end, mddev->chunk_sectors);496 end_disk_index = sector_div(orig_end, zone->nb_dev);497 end_disk_index = map_disk_shift(end_disk_index,498 zone->nb_dev, zone->disk_shift);499 } else {500 start_disk_index = (int)(start - first_stripe_index * stripe_size) /501 mddev->chunk_sectors;502 end_disk_index = (int)(end - last_stripe_index * stripe_size) /503 mddev->chunk_sectors;504 }505 start_disk_offset = ((int)(start - first_stripe_index * stripe_size) %506 mddev->chunk_sectors) +507 first_stripe_index * mddev->chunk_sectors;508 end_disk_offset = ((int)(end - last_stripe_index * stripe_size) %509 mddev->chunk_sectors) +510 last_stripe_index * mddev->chunk_sectors;511 512 for (disk = 0; disk < zone->nb_dev; disk++) {513 sector_t dev_start, dev_end;514 struct md_rdev *rdev;515 int compare_disk;516 517 compare_disk = map_disk_shift(disk, zone->nb_dev,518 zone->disk_shift);519 520 if (compare_disk < start_disk_index)521 dev_start = (first_stripe_index + 1) *522 mddev->chunk_sectors;523 else if (compare_disk > start_disk_index)524 dev_start = first_stripe_index * mddev->chunk_sectors;525 else526 dev_start = start_disk_offset;527 528 if (compare_disk < end_disk_index)529 dev_end = (last_stripe_index + 1) * mddev->chunk_sectors;530 else if (compare_disk > end_disk_index)531 dev_end = last_stripe_index * mddev->chunk_sectors;532 else533 dev_end = end_disk_offset;534 535 if (dev_end <= dev_start)536 continue;537 538 rdev = conf->devlist[(zone - conf->strip_zone) *539 conf->strip_zone[0].nb_dev + disk];540 md_submit_discard_bio(mddev, rdev, bio,541 dev_start + zone->dev_start + rdev->data_offset,542 dev_end - dev_start);543 }544 bio_endio(bio);545}546 547static void raid0_map_submit_bio(struct mddev *mddev, struct bio *bio)548{549 struct r0conf *conf = mddev->private;550 struct strip_zone *zone;551 struct md_rdev *tmp_dev;552 sector_t bio_sector = bio->bi_iter.bi_sector;553 sector_t sector = bio_sector;554 555 md_account_bio(mddev, &bio);556 557 zone = find_zone(mddev->private, §or);558 switch (conf->layout) {559 case RAID0_ORIG_LAYOUT:560 tmp_dev = map_sector(mddev, zone, bio_sector, §or);561 break;562 case RAID0_ALT_MULTIZONE_LAYOUT:563 tmp_dev = map_sector(mddev, zone, sector, §or);564 break;565 default:566 WARN(1, "md/raid0:%s: Invalid layout\n", mdname(mddev));567 bio_io_error(bio);568 return;569 }570 571 if (unlikely(is_rdev_broken(tmp_dev))) {572 bio_io_error(bio);573 md_error(mddev, tmp_dev);574 return;575 }576 577 bio_set_dev(bio, tmp_dev->bdev);578 bio->bi_iter.bi_sector = sector + zone->dev_start +579 tmp_dev->data_offset;580 mddev_trace_remap(mddev, bio, bio_sector);581 mddev_check_write_zeroes(mddev, bio);582 submit_bio_noacct(bio);583}584 585static bool raid0_make_request(struct mddev *mddev, struct bio *bio)586{587 sector_t sector;588 unsigned chunk_sects;589 unsigned sectors;590 591 if (unlikely(bio->bi_opf & REQ_PREFLUSH)592 && md_flush_request(mddev, bio))593 return true;594 595 if (unlikely((bio_op(bio) == REQ_OP_DISCARD))) {596 raid0_handle_discard(mddev, bio);597 return true;598 }599 600 sector = bio->bi_iter.bi_sector;601 chunk_sects = mddev->chunk_sectors;602 603 sectors = chunk_sects -604 (likely(is_power_of_2(chunk_sects))605 ? (sector & (chunk_sects-1))606 : sector_div(sector, chunk_sects));607 608 if (sectors < bio_sectors(bio)) {609 struct bio *split = bio_split(bio, sectors, GFP_NOIO,610 &mddev->bio_set);611 bio_chain(split, bio);612 raid0_map_submit_bio(mddev, bio);613 bio = split;614 }615 616 raid0_map_submit_bio(mddev, bio);617 return true;618}619 620static void raid0_status(struct seq_file *seq, struct mddev *mddev)621{622 seq_printf(seq, " %dk chunks", mddev->chunk_sectors / 2);623 return;624}625 626static void raid0_error(struct mddev *mddev, struct md_rdev *rdev)627{628 if (!test_and_set_bit(MD_BROKEN, &mddev->flags)) {629 char *md_name = mdname(mddev);630 631 pr_crit("md/raid0%s: Disk failure on %pg detected, failing array.\n",632 md_name, rdev->bdev);633 }634}635 636static void *raid0_takeover_raid45(struct mddev *mddev)637{638 struct md_rdev *rdev;639 struct r0conf *priv_conf;640 641 if (mddev->degraded != 1) {642 pr_warn("md/raid0:%s: raid5 must be degraded! Degraded disks: %d\n",643 mdname(mddev),644 mddev->degraded);645 return ERR_PTR(-EINVAL);646 }647 648 rdev_for_each(rdev, mddev) {649 /* check slot number for a disk */650 if (rdev->raid_disk == mddev->raid_disks-1) {651 pr_warn("md/raid0:%s: raid5 must have missing parity disk!\n",652 mdname(mddev));653 return ERR_PTR(-EINVAL);654 }655 rdev->sectors = mddev->dev_sectors;656 }657 658 /* Set new parameters */659 mddev->new_level = 0;660 mddev->new_layout = 0;661 mddev->new_chunk_sectors = mddev->chunk_sectors;662 mddev->raid_disks--;663 mddev->delta_disks = -1;664 /* make sure it will be not marked as dirty */665 mddev->recovery_cp = MaxSector;666 mddev_clear_unsupported_flags(mddev, UNSUPPORTED_MDDEV_FLAGS);667 668 create_strip_zones(mddev, &priv_conf);669 670 return priv_conf;671}672 673static void *raid0_takeover_raid10(struct mddev *mddev)674{675 struct r0conf *priv_conf;676 677 /* Check layout:678 * - far_copies must be 1679 * - near_copies must be 2680 * - disks number must be even681 * - all mirrors must be already degraded682 */683 if (mddev->layout != ((1 << 8) + 2)) {684 pr_warn("md/raid0:%s:: Raid0 cannot takeover layout: 0x%x\n",685 mdname(mddev),686 mddev->layout);687 return ERR_PTR(-EINVAL);688 }689 if (mddev->raid_disks & 1) {690 pr_warn("md/raid0:%s: Raid0 cannot takeover Raid10 with odd disk number.\n",691 mdname(mddev));692 return ERR_PTR(-EINVAL);693 }694 if (mddev->degraded != (mddev->raid_disks>>1)) {695 pr_warn("md/raid0:%s: All mirrors must be already degraded!\n",696 mdname(mddev));697 return ERR_PTR(-EINVAL);698 }699 700 /* Set new parameters */701 mddev->new_level = 0;702 mddev->new_layout = 0;703 mddev->new_chunk_sectors = mddev->chunk_sectors;704 mddev->delta_disks = - mddev->raid_disks / 2;705 mddev->raid_disks += mddev->delta_disks;706 mddev->degraded = 0;707 /* make sure it will be not marked as dirty */708 mddev->recovery_cp = MaxSector;709 mddev_clear_unsupported_flags(mddev, UNSUPPORTED_MDDEV_FLAGS);710 711 create_strip_zones(mddev, &priv_conf);712 return priv_conf;713}714 715static void *raid0_takeover_raid1(struct mddev *mddev)716{717 struct r0conf *priv_conf;718 int chunksect;719 720 /* Check layout:721 * - (N - 1) mirror drives must be already faulty722 */723 if ((mddev->raid_disks - 1) != mddev->degraded) {724 pr_err("md/raid0:%s: (N - 1) mirrors drives must be already faulty!\n",725 mdname(mddev));726 return ERR_PTR(-EINVAL);727 }728 729 /*730 * a raid1 doesn't have the notion of chunk size, so731 * figure out the largest suitable size we can use.732 */733 chunksect = 64 * 2; /* 64K by default */734 735 /* The array must be an exact multiple of chunksize */736 while (chunksect && (mddev->array_sectors & (chunksect - 1)))737 chunksect >>= 1;738 739 if ((chunksect << 9) < PAGE_SIZE)740 /* array size does not allow a suitable chunk size */741 return ERR_PTR(-EINVAL);742 743 /* Set new parameters */744 mddev->new_level = 0;745 mddev->new_layout = 0;746 mddev->new_chunk_sectors = chunksect;747 mddev->chunk_sectors = chunksect;748 mddev->delta_disks = 1 - mddev->raid_disks;749 mddev->raid_disks = 1;750 /* make sure it will be not marked as dirty */751 mddev->recovery_cp = MaxSector;752 mddev_clear_unsupported_flags(mddev, UNSUPPORTED_MDDEV_FLAGS);753 754 create_strip_zones(mddev, &priv_conf);755 return priv_conf;756}757 758static void *raid0_takeover(struct mddev *mddev)759{760 /* raid0 can take over:761 * raid4 - if all data disks are active.762 * raid5 - providing it is Raid4 layout and one disk is faulty763 * raid10 - assuming we have all necessary active disks764 * raid1 - with (N -1) mirror drives faulty765 */766 767 if (mddev->bitmap) {768 pr_warn("md/raid0: %s: cannot takeover array with bitmap\n",769 mdname(mddev));770 return ERR_PTR(-EBUSY);771 }772 if (mddev->level == 4)773 return raid0_takeover_raid45(mddev);774 775 if (mddev->level == 5) {776 if (mddev->layout == ALGORITHM_PARITY_N)777 return raid0_takeover_raid45(mddev);778 779 pr_warn("md/raid0:%s: Raid can only takeover Raid5 with layout: %d\n",780 mdname(mddev), ALGORITHM_PARITY_N);781 }782 783 if (mddev->level == 10)784 return raid0_takeover_raid10(mddev);785 786 if (mddev->level == 1)787 return raid0_takeover_raid1(mddev);788 789 pr_warn("Takeover from raid%i to raid0 not supported\n",790 mddev->level);791 792 return ERR_PTR(-EINVAL);793}794 795static void raid0_quiesce(struct mddev *mddev, int quiesce)796{797}798 799static struct md_personality raid0_personality=800{801 .name = "raid0",802 .level = 0,803 .owner = THIS_MODULE,804 .make_request = raid0_make_request,805 .run = raid0_run,806 .free = raid0_free,807 .status = raid0_status,808 .size = raid0_size,809 .takeover = raid0_takeover,810 .quiesce = raid0_quiesce,811 .error_handler = raid0_error,812};813 814static int __init raid0_init (void)815{816 return register_md_personality (&raid0_personality);817}818 819static void raid0_exit (void)820{821 unregister_md_personality (&raid0_personality);822}823 824module_init(raid0_init);825module_exit(raid0_exit);826MODULE_LICENSE("GPL");827MODULE_DESCRIPTION("RAID0 (striping) personality for MD");828MODULE_ALIAS("md-personality-2"); /* RAID0 */829MODULE_ALIAS("md-raid0");830MODULE_ALIAS("md-level-0");831