brintos

brintos / linux-shallow public Read only

0
0
Text · 21.7 KiB · 32d5875 Raw
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, &sector);558	switch (conf->layout) {559	case RAID0_ORIG_LAYOUT:560		tmp_dev = map_sector(mddev, zone, bio_sector, &sector);561		break;562	case RAID0_ALT_MULTIZONE_LAYOUT:563		tmp_dev = map_sector(mddev, zone, sector, &sector);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