1110 lines · 34.6 KB · C
RawDownload
/* SPDX-License-Identifier: GPL-2.0-or-later *//*   md.h : kernel internal structure of the Linux MD driver          Copyright (C) 1996-98 Ingo Molnar, Gadi Oxman */ #ifndef _MD_MD_H#define _MD_MD_H #include <linux/blkdev.h>#include <linux/backing-dev.h>#include <linux/badblocks.h>#include <linux/kobject.h>#include <linux/list.h>#include <linux/mm.h>#include <linux/mutex.h>#include <linux/timer.h>#include <linux/wait.h>#include <linux/workqueue.h>#include <linux/raid/md_u.h>#include <trace/events/block.h> #define MaxSector (~(sector_t)0)/* * Number of guaranteed raid bios in case of extreme VM load: */#define	NR_RAID_BIOS 256 enum md_submodule_type {	MD_PERSONALITY = 0,	MD_CLUSTER,	MD_BITMAP,}; enum md_submodule_id {	ID_LINEAR	= LEVEL_LINEAR,	ID_RAID0	= 0,	ID_RAID1	= 1,	ID_RAID4	= 4,	ID_RAID5	= 5,	ID_RAID6	= 6,	ID_RAID10	= 10,	ID_CLUSTER,	ID_BITMAP,	ID_LLBITMAP,	ID_BITMAP_NONE,}; struct md_submodule_head {	enum md_submodule_type	type;	enum md_submodule_id	id;	const char		*name;	struct module		*owner;}; /* * These flags should really be called "NO_RETRY" rather than * "FAILFAST" because they don't make any promise about time lapse, * only about the number of retries, which will be zero. * REQ_FAILFAST_DRIVER is not included because * Commit: 4a27446f3e39 ("[SCSI] modify scsi to handle new fail fast flags.") * seems to suggest that the errors it avoids retrying should usually * be retried. */#define	MD_FAILFAST	(REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT) /* Status of sync thread. */enum sync_action {	/*	 * Represent by MD_RECOVERY_SYNC, start when:	 * 1) after assemble, sync data from first rdev to other copies, this	 * must be done first before other sync actions and will only execute	 * once;	 * 2) resize the array(notice that this is not reshape), sync data for	 * the new range;	 */	ACTION_RESYNC,	/*	 * Represent by MD_RECOVERY_RECOVER, start when:	 * 1) for new replacement, sync data based on the replace rdev or	 * available copies from other rdev;	 * 2) for new member disk while the array is degraded, sync data from	 * other rdev;	 * 3) reassemble after power failure or re-add a hot removed rdev, sync	 * data from first rdev to other copies based on bitmap;	 */	ACTION_RECOVER,	/*	 * Represent by MD_RECOVERY_SYNC | MD_RECOVERY_REQUESTED |	 * MD_RECOVERY_CHECK, start when user echo "check" to sysfs api	 * sync_action, used to check if data copies from differenct rdev are	 * the same. The number of mismatch sectors will be exported to user	 * by sysfs api mismatch_cnt;	 */	ACTION_CHECK,	/*	 * Represent by MD_RECOVERY_SYNC | MD_RECOVERY_REQUESTED, start when	 * user echo "repair" to sysfs api sync_action, usually paired with	 * ACTION_CHECK, used to force syncing data once user found that there	 * are inconsistent data,	 */	ACTION_REPAIR,	/*	 * Represent by MD_RECOVERY_RESHAPE, start when new member disk is added	 * to the conf, notice that this is different from spares or	 * replacement;	 */	ACTION_RESHAPE,	/*	 * Represent by MD_RECOVERY_FROZEN, can be set by sysfs api sync_action	 * or internal usage like setting the array read-only, will forbid above	 * actions.	 */	ACTION_FROZEN,	/*	 * All above actions don't match.	 */	ACTION_IDLE,	NR_SYNC_ACTIONS,}; /* * The struct embedded in rdev is used to serialize IO. */struct serial_in_rdev {	struct rb_root_cached serial_rb;	spinlock_t serial_lock;}; /* * MD's 'extended' device */struct md_rdev {	struct list_head same_set;	/* RAID devices within the same set */ 	sector_t sectors;		/* Device size (in 512bytes sectors) */	struct mddev *mddev;		/* RAID array if running */	unsigned long last_events;	/* IO event timestamp */ 	/*	 * If meta_bdev is non-NULL, it means that a separate device is	 * being used to store the metadata (superblock/bitmap) which	 * would otherwise be contained on the same device as the data (bdev).	 */	struct block_device *meta_bdev;	struct block_device *bdev;	/* block device handle */	struct file *bdev_file;		/* Handle from open for bdev */ 	struct page	*sb_page, *bb_page;	int		sb_loaded;	__u64		sb_events;	sector_t	data_offset;	/* start of data in array */	sector_t	new_data_offset;/* only relevant while reshaping */	sector_t	sb_start;	/* offset of the super block (in 512byte sectors) */	int		sb_size;	/* bytes in the superblock */	int		preferred_minor;	/* autorun support */ 	struct kobject	kobj; 	/* A device can be in one of three states based on two flags:	 * Not working:   faulty==1 in_sync==0	 * Fully working: faulty==0 in_sync==1	 * Working, but not	 * in sync with array	 *                faulty==0 in_sync==0	 *	 * It can never have faulty==1, in_sync==1	 * This reduces the burden of testing multiple flags in many cases	 */ 	unsigned long	flags;	/* bit set of 'enum flag_bits' bits. */	wait_queue_head_t blocked_wait; 	int desc_nr;			/* descriptor index in the superblock */	int raid_disk;			/* role of device in array */	int new_raid_disk;		/* role that the device will have in					 * the array after a level-change completes.					 */	int saved_raid_disk;		/* role that device used to have in the					 * array and could again if we did a partial					 * resync from the bitmap					 */	union {		sector_t recovery_offset;/* If this device has been partially					 * recovered, this is where we were					 * up to.					 */		sector_t journal_tail;	/* If this device is a journal device,					 * this is the journal tail (journal					 * recovery start point)					 */	}; 	atomic_t	nr_pending;	/* number of pending requests.					 * only maintained for arrays that					 * support hot removal					 */	atomic_t	read_errors;	/* number of consecutive read errors that					 * we have tried to ignore.					 */	time64_t	last_read_error;	/* monotonic time since our						 * last read error						 */	atomic_t	corrected_errors; /* number of corrected read errors,					   * for reporting to userspace and storing					   * in superblock.					   */ 	struct serial_in_rdev *serial;  /* used for raid1 io serialization */ 	struct kernfs_node *sysfs_state; /* handle for 'state'					   * sysfs entry */	/* handle for 'unacknowledged_bad_blocks' sysfs dentry */	struct kernfs_node *sysfs_unack_badblocks;	/* handle for 'bad_blocks' sysfs dentry */	struct kernfs_node *sysfs_badblocks;	struct badblocks badblocks; 	struct {		short offset;	/* Offset from superblock to start of PPL.				 * Not used by external metadata. */		unsigned int size;	/* Size in sectors of the PPL space */		sector_t sector;	/* First sector of the PPL space */	} ppl;};enum flag_bits {	Faulty,			/* device is known to have a fault */	In_sync,		/* device is in_sync with rest of array */	Bitmap_sync,		/* ..actually, not quite In_sync.  Need a				 * bitmap-based recovery to get fully in sync.				 * The bit is only meaningful before device				 * has been passed to pers->hot_add_disk.				 */	WriteMostly,		/* Avoid reading if at all possible */	AutoDetected,		/* added by auto-detect */	Blocked,		/* An error occurred but has not yet				 * been acknowledged by the metadata				 * handler, so don't allow writes				 * until it is cleared */	WriteErrorSeen,		/* A write error has been seen on this				 * device				 */	FaultRecorded,		/* Intermediate state for clearing				 * Blocked.  The Fault is/will-be				 * recorded in the metadata, but that				 * metadata hasn't been stored safely				 * on disk yet.				 */	BlockedBadBlocks,	/* A writer is blocked because they				 * found an unacknowledged bad-block.				 * This can safely be cleared at any				 * time, and the writer will re-check.				 * It may be set at any time, and at				 * worst the writer will timeout and				 * re-check.  So setting it as				 * accurately as possible is good, but				 * not absolutely critical.				 */	WantReplacement,	/* This device is a candidate to be				 * hot-replaced, either because it has				 * reported some faults, or because				 * of explicit request.				 */	Replacement,		/* This device is a replacement for				 * a want_replacement device with same				 * raid_disk number.				 */	Candidate,		/* For clustered environments only:				 * This device is seen locally but not				 * by the whole cluster				 */	Journal,		/* This device is used as journal for				 * raid-5/6.				 * Usually, this device should be faster				 * than other devices in the array				 */	ClusterRemove,	ExternalBbl,            /* External metadata provides bad				 * block management for a disk				 */	FailFast,		/* Minimal retries should be attempted on				 * this device, so use REQ_FAILFAST_DEV.				 * Also don't try to repair failed reads.				 * It is expects that no bad block log				 * is present.				 */	LastDev,		/* Seems to be the last working dev as				 * it didn't fail, so don't use FailFast				 * any more for metadata				 */	CollisionCheck,		/*				 * check if there is collision between raid1				 * serial bios.				 */	Nonrot,			/* non-rotational device (SSD) */}; static inline int is_badblock(struct md_rdev *rdev, sector_t s, sector_t sectors,			      sector_t *first_bad, sector_t *bad_sectors){	if (unlikely(rdev->badblocks.count)) {		int rv = badblocks_check(&rdev->badblocks, rdev->data_offset + s,					sectors,					first_bad, bad_sectors);		if (rv)			*first_bad -= rdev->data_offset;		return rv;	}	return 0;} static inline int rdev_has_badblock(struct md_rdev *rdev, sector_t s,				    sector_t sectors){	sector_t first_bad;	sector_t bad_sectors; 	return is_badblock(rdev, s, sectors, &first_bad, &bad_sectors);} extern bool rdev_set_badblocks(struct md_rdev *rdev, sector_t s, sector_t sectors,			       int is_new);extern void rdev_clear_badblocks(struct md_rdev *rdev, sector_t s, sector_t sectors,				 int is_new);struct md_cluster_info;struct md_cluster_operations; /** * enum mddev_flags - md device flags. * @MD_ARRAY_FIRST_USE: First use of array, needs initialization. * @MD_CLOSING: If set, we are closing the array, do not open it then. * @MD_JOURNAL_CLEAN: A raid with journal is already clean. * @MD_HAS_JOURNAL: The raid array has journal feature set. * @MD_CLUSTER_RESYNC_LOCKED: cluster raid only, which means node, already took *			       resync lock, need to release the lock. * @MD_FAILFAST_SUPPORTED: Using MD_FAILFAST on metadata writes is supported as *			    calls to md_error() will never cause the array to *			    become failed. * @MD_HAS_PPL:  The raid array has PPL feature set. * @MD_HAS_MULTIPLE_PPLS: The raid array has multiple PPLs feature set. * @MD_NOT_READY: do_md_run() is active, so 'array_state', ust not report that *		   array is ready yet. * @MD_BROKEN: This is used to stop writes and mark array as failed. * @MD_DELETED: This device is being deleted * @MD_HAS_SUPERBLOCK: There is persistence sb in member disks. * @MD_FAILLAST_DEV: Allow last rdev to be removed. * @MD_SERIALIZE_POLICY: Enforce write IO is not reordered, just used by raid1. * @MD_DM_SUSPENDING: This DM raid device is suspending. * * change UNSUPPORTED_MDDEV_FLAGS for each array type if new flag is added */enum mddev_flags {	MD_ARRAY_FIRST_USE,	MD_CLOSING,	MD_JOURNAL_CLEAN,	MD_HAS_JOURNAL,	MD_CLUSTER_RESYNC_LOCKED,	MD_FAILFAST_SUPPORTED,	MD_HAS_PPL,	MD_HAS_MULTIPLE_PPLS,	MD_NOT_READY,	MD_BROKEN,	MD_DO_DELETE,	MD_DELETED,	MD_HAS_SUPERBLOCK,	MD_FAILLAST_DEV,	MD_SERIALIZE_POLICY,	MD_DM_SUSPENDING,}; enum mddev_sb_flags {	MD_SB_CHANGE_DEVS,		/* Some device status has changed */	MD_SB_CHANGE_CLEAN,	/* transition to or from 'clean' */	MD_SB_CHANGE_PENDING,	/* switch from 'clean' to 'active' in progress */	MD_SB_NEED_REWRITE,	/* metadata write needs to be repeated */}; #define NR_SERIAL_INFOS		8/* record current range of serialize IOs */struct serial_info {	struct rb_node node;	sector_t start;		/* start sector of rb node */	sector_t last;		/* end sector of rb node */	sector_t wnode_start; /* address of waiting nodes on the same list */	sector_t _subtree_last; /* highest sector in subtree of rb node */	struct list_head	list_node;	struct list_head	waiters;	struct completion	ready;}; /* * mddev->curr_resync stores the current sector of the resync but * also has some overloaded values. */enum {	/* No resync in progress */	MD_RESYNC_NONE = 0,	/* Yielded to allow another conflicting resync to commence */	MD_RESYNC_YIELDED = 1,	/* Delayed to check that there is no conflict with another sync */	MD_RESYNC_DELAYED = 2,	/* Any value greater than or equal to this is in an active resync */	MD_RESYNC_ACTIVE = 3,}; struct mddev {	void				*private;	struct md_personality		*pers;	dev_t				unit;	int				md_minor;	struct list_head		disks;	unsigned long			flags;	unsigned long			sb_flags; 	int				suspended;	struct mutex			suspend_mutex;	struct percpu_ref		active_io;	int				ro;	int				sysfs_active; /* set when sysfs deletes						       * are happening, so run/						       * takeover/stop are not safe						       */	struct gendisk			*gendisk;    /* mdraid gendisk */	struct gendisk			*dm_gendisk; /* dm-raid gendisk */ 	struct kobject			kobj;	int				hold_active;#define	UNTIL_IOCTL	1#define	UNTIL_STOP	2 	/* Superblock information */	int				major_version,					minor_version,					patch_version;	int				persistent;	int				external;	/* metadata is							 * managed externally */	char				metadata_type[17]; /* externally set*/	int				chunk_sectors;	time64_t			ctime, utime;	int				level, layout;	char				clevel[16];	int				raid_disks;	int				max_disks;	sector_t			dev_sectors;	/* used size of							 * component devices */	sector_t			array_sectors; /* exported array size */	int				external_size; /* size managed							* externally */	unsigned int			logical_block_size;	__u64				events;	/* If the last 'event' was simply a clean->dirty transition, and	 * we didn't write it to the spares, then it is safe and simple	 * to just decrement the event count on a dirty->clean transition.	 * So we record that possibility here.	 */	int				can_decrease_events; 	char				uuid[16]; 	/* If the array is being reshaped, we need to record the	 * new shape and an indication of where we are up to.	 * This is written to the superblock.	 * If reshape_position is MaxSector, then no reshape is happening (yet).	 */	sector_t			reshape_position;	int				delta_disks, new_level, new_layout;	int				new_chunk_sectors;	int				reshape_backwards; 	struct md_thread __rcu		*thread;	/* management thread */	struct md_thread __rcu		*sync_thread;	/* doing resync or reconstruct */ 	/*	 * Set when a sync operation is started. It holds this value even	 * when the sync thread is "frozen" (interrupted) or "idle" (stopped	 * or finished). It is overwritten when a new sync operation is begun.	 */	enum sync_action		last_sync_action;	sector_t			curr_resync;	/* last block scheduled */	/* As resync requests can complete out of order, we cannot easily track	 * how much resync has been completed.  So we occasionally pause until	 * everything completes, then set curr_resync_completed to curr_resync.	 * As such it may be well behind the real resync mark, but it is a value	 * we are certain of.	 */	sector_t			curr_resync_completed;	unsigned long			resync_mark;	/* a recent timestamp */	sector_t			resync_mark_cnt;/* blocks written at resync_mark */	sector_t			curr_mark_cnt; /* blocks scheduled now */ 	sector_t			resync_max_sectors; /* may be set by personality */ 	atomic64_t			resync_mismatches; /* count of sectors where							    * parity/replica mismatch found							    */ 	/* allow user-space to request suspension of IO to regions of the array */	sector_t			suspend_lo;

Lines 1–500 of 1110.