4182 lines · 120.3 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-only/* * Copyright (C) 2010-2011 Neil Brown * Copyright (C) 2010-2018 Red Hat, Inc. All rights reserved. * * This file is released under the GPL. */ #include <linux/slab.h>#include <linux/module.h> #include "md.h"#include "raid1.h"#include "raid5.h"#include "raid10.h"#include "md-bitmap.h" #include <linux/device-mapper.h> #define DM_MSG_PREFIX "raid"#define	MAX_RAID_DEVICES	253 /* md-raid kernel limit */ /* * Minimum sectors of free reshape space per raid device */#define	MIN_FREE_RESHAPE_SPACE to_sector(4*4096) /* * Minimum journal space 4 MiB in sectors. */#define	MIN_RAID456_JOURNAL_SPACE (4*2048) static bool devices_handle_discard_safely; /* * The following flags are used by dm-raid to set up the array state. * They must be cleared before md_run is called. */#define FirstUse 10		/* rdev flag */ struct raid_dev {	/*	 * Two DM devices, one to hold metadata and one to hold the	 * actual data/parity.	The reason for this is to not confuse	 * ti->len and give more flexibility in altering size and	 * characteristics.	 *	 * While it is possible for this device to be associated	 * with a different physical device than the data_dev, it	 * is intended for it to be the same.	 *    |--------- Physical Device ---------|	 *    |- meta_dev -|------ data_dev ------|	 */	struct dm_dev *meta_dev;	struct dm_dev *data_dev;	struct md_rdev rdev;}; /* * Bits for establishing rs->ctr_flags * * 1 = no flag value * 2 = flag with value */#define __CTR_FLAG_SYNC			0  /* 1 */ /* Not with raid0! */#define __CTR_FLAG_NOSYNC		1  /* 1 */ /* Not with raid0! */#define __CTR_FLAG_REBUILD		2  /* 2 */ /* Not with raid0! */#define __CTR_FLAG_DAEMON_SLEEP		3  /* 2 */ /* Not with raid0! */#define __CTR_FLAG_MIN_RECOVERY_RATE	4  /* 2 */ /* Not with raid0! */#define __CTR_FLAG_MAX_RECOVERY_RATE	5  /* 2 */ /* Not with raid0! */#define __CTR_FLAG_MAX_WRITE_BEHIND	6  /* 2 */ /* Only with raid1! */#define __CTR_FLAG_WRITE_MOSTLY		7  /* 2 */ /* Only with raid1! */#define __CTR_FLAG_STRIPE_CACHE		8  /* 2 */ /* Only with raid4/5/6! */#define __CTR_FLAG_REGION_SIZE		9  /* 2 */ /* Not with raid0! */#define __CTR_FLAG_RAID10_COPIES	10 /* 2 */ /* Only with raid10 */#define __CTR_FLAG_RAID10_FORMAT	11 /* 2 */ /* Only with raid10 *//* New for v1.9.0 */#define __CTR_FLAG_DELTA_DISKS		12 /* 2 */ /* Only with reshapable raid1/4/5/6/10! */#define __CTR_FLAG_DATA_OFFSET		13 /* 2 */ /* Only with reshapable raid4/5/6/10! */#define __CTR_FLAG_RAID10_USE_NEAR_SETS 14 /* 2 */ /* Only with raid10! */ /* New for v1.10.0 */#define __CTR_FLAG_JOURNAL_DEV		15 /* 2 */ /* Only with raid4/5/6 (journal device)! */ /* New for v1.11.1 */#define __CTR_FLAG_JOURNAL_MODE		16 /* 2 */ /* Only with raid4/5/6 (journal mode)! */ /* * Flags for rs->ctr_flags field. */#define CTR_FLAG_SYNC			(1 << __CTR_FLAG_SYNC)#define CTR_FLAG_NOSYNC			(1 << __CTR_FLAG_NOSYNC)#define CTR_FLAG_REBUILD		(1 << __CTR_FLAG_REBUILD)#define CTR_FLAG_DAEMON_SLEEP		(1 << __CTR_FLAG_DAEMON_SLEEP)#define CTR_FLAG_MIN_RECOVERY_RATE	(1 << __CTR_FLAG_MIN_RECOVERY_RATE)#define CTR_FLAG_MAX_RECOVERY_RATE	(1 << __CTR_FLAG_MAX_RECOVERY_RATE)#define CTR_FLAG_MAX_WRITE_BEHIND	(1 << __CTR_FLAG_MAX_WRITE_BEHIND)#define CTR_FLAG_WRITE_MOSTLY		(1 << __CTR_FLAG_WRITE_MOSTLY)#define CTR_FLAG_STRIPE_CACHE		(1 << __CTR_FLAG_STRIPE_CACHE)#define CTR_FLAG_REGION_SIZE		(1 << __CTR_FLAG_REGION_SIZE)#define CTR_FLAG_RAID10_COPIES		(1 << __CTR_FLAG_RAID10_COPIES)#define CTR_FLAG_RAID10_FORMAT		(1 << __CTR_FLAG_RAID10_FORMAT)#define CTR_FLAG_DELTA_DISKS		(1 << __CTR_FLAG_DELTA_DISKS)#define CTR_FLAG_DATA_OFFSET		(1 << __CTR_FLAG_DATA_OFFSET)#define CTR_FLAG_RAID10_USE_NEAR_SETS	(1 << __CTR_FLAG_RAID10_USE_NEAR_SETS)#define CTR_FLAG_JOURNAL_DEV		(1 << __CTR_FLAG_JOURNAL_DEV)#define CTR_FLAG_JOURNAL_MODE		(1 << __CTR_FLAG_JOURNAL_MODE) /* * Definitions of various constructor flags to * be used in checks of valid / invalid flags * per raid level. *//* Define all any sync flags */#define	CTR_FLAGS_ANY_SYNC		(CTR_FLAG_SYNC | CTR_FLAG_NOSYNC) /* Define flags for options without argument (e.g. 'nosync') */#define	CTR_FLAG_OPTIONS_NO_ARGS	(CTR_FLAGS_ANY_SYNC | \					 CTR_FLAG_RAID10_USE_NEAR_SETS) /* Define flags for options with one argument (e.g. 'delta_disks +2') */#define CTR_FLAG_OPTIONS_ONE_ARG (CTR_FLAG_REBUILD | \				  CTR_FLAG_WRITE_MOSTLY | \				  CTR_FLAG_DAEMON_SLEEP | \				  CTR_FLAG_MIN_RECOVERY_RATE | \				  CTR_FLAG_MAX_RECOVERY_RATE | \				  CTR_FLAG_MAX_WRITE_BEHIND | \				  CTR_FLAG_STRIPE_CACHE | \				  CTR_FLAG_REGION_SIZE | \				  CTR_FLAG_RAID10_COPIES | \				  CTR_FLAG_RAID10_FORMAT | \				  CTR_FLAG_DELTA_DISKS | \				  CTR_FLAG_DATA_OFFSET | \				  CTR_FLAG_JOURNAL_DEV | \				  CTR_FLAG_JOURNAL_MODE) /* Valid options definitions per raid level... */ /* "raid0" does only accept data offset */#define RAID0_VALID_FLAGS	(CTR_FLAG_DATA_OFFSET) /* "raid1" does not accept stripe cache, data offset, delta_disks or any raid10 options */#define RAID1_VALID_FLAGS	(CTR_FLAGS_ANY_SYNC | \				 CTR_FLAG_REBUILD | \				 CTR_FLAG_WRITE_MOSTLY | \				 CTR_FLAG_DAEMON_SLEEP | \				 CTR_FLAG_MIN_RECOVERY_RATE | \				 CTR_FLAG_MAX_RECOVERY_RATE | \				 CTR_FLAG_MAX_WRITE_BEHIND | \				 CTR_FLAG_REGION_SIZE | \				 CTR_FLAG_DELTA_DISKS | \				 CTR_FLAG_DATA_OFFSET) /* "raid10" does not accept any raid1 or stripe cache options */#define RAID10_VALID_FLAGS	(CTR_FLAGS_ANY_SYNC | \				 CTR_FLAG_REBUILD | \				 CTR_FLAG_DAEMON_SLEEP | \				 CTR_FLAG_MIN_RECOVERY_RATE | \				 CTR_FLAG_MAX_RECOVERY_RATE | \				 CTR_FLAG_REGION_SIZE | \				 CTR_FLAG_RAID10_COPIES | \				 CTR_FLAG_RAID10_FORMAT | \				 CTR_FLAG_DELTA_DISKS | \				 CTR_FLAG_DATA_OFFSET | \				 CTR_FLAG_RAID10_USE_NEAR_SETS) /* * "raid4/5/6" do not accept any raid1 or raid10 specific options * * "raid6" does not accept "nosync", because it is not guaranteed * that both parity and q-syndrome are being written properly with * any writes */#define RAID45_VALID_FLAGS	(CTR_FLAGS_ANY_SYNC | \				 CTR_FLAG_REBUILD | \				 CTR_FLAG_DAEMON_SLEEP | \				 CTR_FLAG_MIN_RECOVERY_RATE | \				 CTR_FLAG_MAX_RECOVERY_RATE | \				 CTR_FLAG_STRIPE_CACHE | \				 CTR_FLAG_REGION_SIZE | \				 CTR_FLAG_DELTA_DISKS | \				 CTR_FLAG_DATA_OFFSET | \				 CTR_FLAG_JOURNAL_DEV | \				 CTR_FLAG_JOURNAL_MODE) #define RAID6_VALID_FLAGS	(CTR_FLAG_SYNC | \				 CTR_FLAG_REBUILD | \				 CTR_FLAG_DAEMON_SLEEP | \				 CTR_FLAG_MIN_RECOVERY_RATE | \				 CTR_FLAG_MAX_RECOVERY_RATE | \				 CTR_FLAG_STRIPE_CACHE | \				 CTR_FLAG_REGION_SIZE | \				 CTR_FLAG_DELTA_DISKS | \				 CTR_FLAG_DATA_OFFSET | \				 CTR_FLAG_JOURNAL_DEV | \				 CTR_FLAG_JOURNAL_MODE)/* ...valid options definitions per raid level */ /* * Flags for rs->runtime_flags field * (RT_FLAG prefix meaning "runtime flag") * * These are all internal and used to define runtime state, * e.g. to prevent another resume from preresume processing * the raid set all over again. */#define RT_FLAG_RS_PRERESUMED		0#define RT_FLAG_RS_RESUMED		1#define RT_FLAG_RS_BITMAP_LOADED	2#define RT_FLAG_UPDATE_SBS		3#define RT_FLAG_RESHAPE_RS		4#define RT_FLAG_RS_SUSPENDED		5#define RT_FLAG_RS_IN_SYNC		6#define RT_FLAG_RS_RESYNCING		7#define RT_FLAG_RS_GROW			8#define RT_FLAG_RS_FROZEN		9 /* Array elements of 64 bit needed for rebuild/failed disk bits */#define DISKS_ARRAY_ELEMS ((MAX_RAID_DEVICES + (sizeof(uint64_t) * 8 - 1)) / sizeof(uint64_t) / 8) /* * raid set level, layout and chunk sectors backup/restore */struct rs_layout {	int new_level;	int new_layout;	int new_chunk_sectors;}; struct raid_set {	struct dm_target *ti; 	uint32_t stripe_cache_entries;	unsigned long ctr_flags;	unsigned long runtime_flags; 	uint64_t rebuild_disks[DISKS_ARRAY_ELEMS]; 	int raid_disks;	int delta_disks;	int data_offset;	int raid10_copies;	int requested_bitmap_chunk_sectors; 	struct mddev md;	struct raid_type *raid_type; 	sector_t array_sectors;	sector_t dev_sectors; 	/* Optional raid4/5/6 journal device */	struct journal_dev {		struct dm_dev *dev;		struct md_rdev rdev;		int mode;	} journal_dev; 	struct raid_dev dev[] __counted_by(raid_disks);}; static void rs_config_backup(struct raid_set *rs, struct rs_layout *l){	struct mddev *mddev = &rs->md; 	l->new_level = mddev->new_level;	l->new_layout = mddev->new_layout;	l->new_chunk_sectors = mddev->new_chunk_sectors;} static void rs_config_restore(struct raid_set *rs, struct rs_layout *l){	struct mddev *mddev = &rs->md; 	mddev->new_level = l->new_level;	mddev->new_layout = l->new_layout;	mddev->new_chunk_sectors = l->new_chunk_sectors;} /* raid10 algorithms (i.e. formats) */#define	ALGORITHM_RAID10_DEFAULT	0#define	ALGORITHM_RAID10_NEAR		1#define	ALGORITHM_RAID10_OFFSET		2#define	ALGORITHM_RAID10_FAR		3 /* Supported raid types and properties. */static struct raid_type {	const char *name;		/* RAID algorithm. */	const char *descr;		/* Descriptor text for logging. */	const unsigned int parity_devs;	/* # of parity devices. */	const unsigned int minimal_devs;/* minimal # of devices in set. */	const unsigned int level;	/* RAID level. */	const unsigned int algorithm;	/* RAID algorithm. */} raid_types[] = {	{"raid0",	  "raid0 (striping)",			    0, 2, 0,  0 /* NONE */},	{"raid1",	  "raid1 (mirroring)",			    0, 2, 1,  0 /* NONE */},	{"raid10_far",	  "raid10 far (striped mirrors)",	    0, 2, 10, ALGORITHM_RAID10_FAR},	{"raid10_offset", "raid10 offset (striped mirrors)",	    0, 2, 10, ALGORITHM_RAID10_OFFSET},	{"raid10_near",	  "raid10 near (striped mirrors)",	    0, 2, 10, ALGORITHM_RAID10_NEAR},	{"raid10",	  "raid10 (striped mirrors)",		    0, 2, 10, ALGORITHM_RAID10_DEFAULT},	{"raid4",	  "raid4 (dedicated first parity disk)",    1, 2, 5,  ALGORITHM_PARITY_0}, /* raid4 layout = raid5_0 */	{"raid5_n",	  "raid5 (dedicated last parity disk)",	    1, 2, 5,  ALGORITHM_PARITY_N},	{"raid5_ls",	  "raid5 (left symmetric)",		    1, 2, 5,  ALGORITHM_LEFT_SYMMETRIC},	{"raid5_rs",	  "raid5 (right symmetric)",		    1, 2, 5,  ALGORITHM_RIGHT_SYMMETRIC},	{"raid5_la",	  "raid5 (left asymmetric)",		    1, 2, 5,  ALGORITHM_LEFT_ASYMMETRIC},	{"raid5_ra",	  "raid5 (right asymmetric)",		    1, 2, 5,  ALGORITHM_RIGHT_ASYMMETRIC},	{"raid6_zr",	  "raid6 (zero restart)",		    2, 4, 6,  ALGORITHM_ROTATING_ZERO_RESTART},	{"raid6_nr",	  "raid6 (N restart)",			    2, 4, 6,  ALGORITHM_ROTATING_N_RESTART},	{"raid6_nc",	  "raid6 (N continue)",			    2, 4, 6,  ALGORITHM_ROTATING_N_CONTINUE},	{"raid6_n_6",	  "raid6 (dedicated parity/Q n/6)",	    2, 4, 6,  ALGORITHM_PARITY_N_6},	{"raid6_ls_6",	  "raid6 (left symmetric dedicated Q 6)",   2, 4, 6,  ALGORITHM_LEFT_SYMMETRIC_6},	{"raid6_rs_6",	  "raid6 (right symmetric dedicated Q 6)",  2, 4, 6,  ALGORITHM_RIGHT_SYMMETRIC_6},	{"raid6_la_6",	  "raid6 (left asymmetric dedicated Q 6)",  2, 4, 6,  ALGORITHM_LEFT_ASYMMETRIC_6},	{"raid6_ra_6",	  "raid6 (right asymmetric dedicated Q 6)", 2, 4, 6,  ALGORITHM_RIGHT_ASYMMETRIC_6}}; /* True, if @v is in inclusive range [@min, @max] */static bool __within_range(long v, long min, long max){	return v >= min && v <= max;} /* All table line arguments are defined here */static struct arg_name_flag {	const unsigned long flag;	const char *name;} __arg_name_flags[] = {	{ CTR_FLAG_SYNC, "sync"},	{ CTR_FLAG_NOSYNC, "nosync"},	{ CTR_FLAG_REBUILD, "rebuild"},	{ CTR_FLAG_DAEMON_SLEEP, "daemon_sleep"},	{ CTR_FLAG_MIN_RECOVERY_RATE, "min_recovery_rate"},	{ CTR_FLAG_MAX_RECOVERY_RATE, "max_recovery_rate"},	{ CTR_FLAG_MAX_WRITE_BEHIND, "max_write_behind"},	{ CTR_FLAG_WRITE_MOSTLY, "write_mostly"},	{ CTR_FLAG_STRIPE_CACHE, "stripe_cache"},	{ CTR_FLAG_REGION_SIZE, "region_size"},	{ CTR_FLAG_RAID10_COPIES, "raid10_copies"},	{ CTR_FLAG_RAID10_FORMAT, "raid10_format"},	{ CTR_FLAG_DATA_OFFSET, "data_offset"},	{ CTR_FLAG_DELTA_DISKS, "delta_disks"},	{ CTR_FLAG_RAID10_USE_NEAR_SETS, "raid10_use_near_sets"},	{ CTR_FLAG_JOURNAL_DEV, "journal_dev" },	{ CTR_FLAG_JOURNAL_MODE, "journal_mode" },}; /* Return argument name string for given @flag */static const char *dm_raid_arg_name_by_flag(const uint32_t flag){	if (hweight32(flag) == 1) {		struct arg_name_flag *anf = __arg_name_flags + ARRAY_SIZE(__arg_name_flags); 		while (anf-- > __arg_name_flags)			if (flag & anf->flag)				return anf->name; 	} else		DMERR("%s called with more than one flag!", __func__); 	return NULL;} /* Define correlation of raid456 journal cache modes and dm-raid target line parameters */static struct {	const int mode;	const char *param;} _raid456_journal_mode[] = {	{ R5C_JOURNAL_MODE_WRITE_THROUGH, "writethrough" },	{ R5C_JOURNAL_MODE_WRITE_BACK,    "writeback" }}; /* Return MD raid4/5/6 journal mode for dm @journal_mode one */static int dm_raid_journal_mode_to_md(const char *mode){	int m = ARRAY_SIZE(_raid456_journal_mode); 	while (m--)		if (!strcasecmp(mode, _raid456_journal_mode[m].param))			return _raid456_journal_mode[m].mode; 	return -EINVAL;} /* Return dm-raid raid4/5/6 journal mode string for @mode */static const char *md_journal_mode_to_dm_raid(const int mode){	int m = ARRAY_SIZE(_raid456_journal_mode); 	while (m--)		if (mode == _raid456_journal_mode[m].mode)			return _raid456_journal_mode[m].param; 	return "unknown";} /* * Bool helpers to test for various raid levels of a raid set. * It's level as reported by the superblock rather than * the requested raid_type passed to the constructor. *//* Return true, if raid set in @rs is raid0 */static bool rs_is_raid0(struct raid_set *rs){	return !rs->md.level;} /* Return true, if raid set in @rs is raid1 */static bool rs_is_raid1(struct raid_set *rs){	return rs->md.level == 1;} /* Return true, if raid set in @rs is raid10 */static bool rs_is_raid10(struct raid_set *rs){	return rs->md.level == 10;} /* Return true, if raid set in @rs is level 6 */static bool rs_is_raid6(struct raid_set *rs){	return rs->md.level == 6;} /* Return true, if raid set in @rs is level 4, 5 or 6 */static bool rs_is_raid456(struct raid_set *rs){	return __within_range(rs->md.level, 4, 6);} /* Return true, if raid set in @rs is reshapable */static bool __is_raid10_far(int layout);static bool rs_is_reshapable(struct raid_set *rs){	return rs_is_raid456(rs) ||	       (rs_is_raid10(rs) && !__is_raid10_far(rs->md.new_layout));} /* Return true, if raid set in @rs is recovering */static bool rs_is_recovering(struct raid_set *rs){	return rs->md.resync_offset < rs->md.dev_sectors;} /* Return true, if raid set in @rs is reshaping */static bool rs_is_reshaping(struct raid_set *rs){	return rs->md.reshape_position != MaxSector;} /* * bool helpers to test for various raid levels of a raid type @rt */ /* Return true, if raid type in @rt is raid0 */static bool rt_is_raid0(struct raid_type *rt){	return !rt->level;} /* Return true, if raid type in @rt is raid1 */static bool rt_is_raid1(struct raid_type *rt){	return rt->level == 1;} /* Return true, if raid type in @rt is raid10 */static bool rt_is_raid10(struct raid_type *rt){	return rt->level == 10;} /* Return true, if raid type in @rt is raid4/5 */static bool rt_is_raid45(struct raid_type *rt){	return __within_range(rt->level, 4, 5);} /* Return true, if raid type in @rt is raid6 */static bool rt_is_raid6(struct raid_type *rt){	return rt->level == 6;} /* Return true, if raid type in @rt is raid4/5/6 */static bool rt_is_raid456(struct raid_type *rt){	return __within_range(rt->level, 4, 6);}/* END: raid level bools */ /* Return valid ctr flags for the raid level of @rs */static unsigned long __valid_flags(struct raid_set *rs){	if (rt_is_raid0(rs->raid_type))		return RAID0_VALID_FLAGS;	else if (rt_is_raid1(rs->raid_type))		return RAID1_VALID_FLAGS;	else if (rt_is_raid10(rs->raid_type))		return RAID10_VALID_FLAGS;	else if (rt_is_raid45(rs->raid_type))

Lines 1–500 of 4182.