9266 lines · 241.3 KB · C
RawDownload
/*   md.c : Multiple Devices driver for Linux     Copyright (C) 1998, 1999, 2000 Ingo Molnar      completely rewritten, based on the MD driver code from Marc Zyngier    Changes:    - RAID-1/RAID-5 extensions by Miguel de Icaza, Gadi Oxman, Ingo Molnar   - RAID-6 extensions by H. Peter Anvin <hpa@zytor.com>   - boot support for linear and striped mode by Harald Hoyer <HarryH@Royal.Net>   - kerneld support by Boris Tobotras <boris@xtalk.msk.su>   - kmod support by: Cyrus Durgin   - RAID0 bugfixes: Mark Anthony Lisher <markal@iname.com>   - Devfs support by Richard Gooch <rgooch@atnf.csiro.au>    - lots of fixes and improvements to the RAID1/RAID5 and generic     RAID code (such as request based resynchronization):      Neil Brown <neilb@cse.unsw.edu.au>.    - persistent bitmap code     Copyright (C) 2003-2004, Paul Clements, SteelEye Technology, Inc.    This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2, or (at your option)   any later version.    You should have received a copy of the GNU General Public License   (for example /usr/src/linux/COPYING); if not, write to the Free   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.    Errors, Warnings, etc.   Please use:     pr_crit() for error conditions that risk data loss     pr_err() for error conditions that are unexpected, like an IO error         or internal inconsistency     pr_warn() for error conditions that could have been predicated, like         adding a device to an array when it has incompatible metadata     pr_info() for every interesting, very rare events, like an array starting         or stopping, or resync starting or stopping     pr_debug() for everything else. */ #include <linux/sched/signal.h>#include <linux/kthread.h>#include <linux/blkdev.h>#include <linux/badblocks.h>#include <linux/sysctl.h>#include <linux/seq_file.h>#include <linux/fs.h>#include <linux/poll.h>#include <linux/ctype.h>#include <linux/string.h>#include <linux/hdreg.h>#include <linux/proc_fs.h>#include <linux/random.h>#include <linux/module.h>#include <linux/reboot.h>#include <linux/file.h>#include <linux/compat.h>#include <linux/delay.h>#include <linux/raid/md_p.h>#include <linux/raid/md_u.h>#include <linux/slab.h>#include <linux/percpu-refcount.h> #include <trace/events/block.h>#include "md.h"#include "bitmap.h"#include "md-cluster.h" #ifndef MODULEstatic void autostart_arrays(int part);#endif /* pers_list is a list of registered personalities protected * by pers_lock. * pers_lock does extra service to protect accesses to * mddev->thread when the mutex cannot be held. */static LIST_HEAD(pers_list);static DEFINE_SPINLOCK(pers_lock); struct md_cluster_operations *md_cluster_ops;EXPORT_SYMBOL(md_cluster_ops);struct module *md_cluster_mod;EXPORT_SYMBOL(md_cluster_mod); static DECLARE_WAIT_QUEUE_HEAD(resync_wait);static struct workqueue_struct *md_wq;static struct workqueue_struct *md_misc_wq; static int remove_and_add_spares(struct mddev *mddev,				 struct md_rdev *this);static void mddev_detach(struct mddev *mddev); /* * Default number of read corrections we'll attempt on an rdev * before ejecting it from the array. We divide the read error * count by 2 for every hour elapsed between read errors. */#define MD_DEFAULT_MAX_CORRECTED_READ_ERRORS 20/* * Current RAID-1,4,5 parallel reconstruction 'guaranteed speed limit' * is 1000 KB/sec, so the extra system load does not show up that much. * Increase it if you want to have more _guaranteed_ speed. Note that * the RAID driver will use the maximum available bandwidth if the IO * subsystem is idle. There is also an 'absolute maximum' reconstruction * speed limit - in case reconstruction slows down your system despite * idle IO detection. * * you can change it via /proc/sys/dev/raid/speed_limit_min and _max. * or /sys/block/mdX/md/sync_speed_{min,max} */ static int sysctl_speed_limit_min = 1000;static int sysctl_speed_limit_max = 200000;static inline int speed_min(struct mddev *mddev){	return mddev->sync_speed_min ?		mddev->sync_speed_min : sysctl_speed_limit_min;} static inline int speed_max(struct mddev *mddev){	return mddev->sync_speed_max ?		mddev->sync_speed_max : sysctl_speed_limit_max;} static struct ctl_table_header *raid_table_header; static struct ctl_table raid_table[] = {	{		.procname	= "speed_limit_min",		.data		= &sysctl_speed_limit_min,		.maxlen		= sizeof(int),		.mode		= S_IRUGO|S_IWUSR,		.proc_handler	= proc_dointvec,	},	{		.procname	= "speed_limit_max",		.data		= &sysctl_speed_limit_max,		.maxlen		= sizeof(int),		.mode		= S_IRUGO|S_IWUSR,		.proc_handler	= proc_dointvec,	},	{ }}; static struct ctl_table raid_dir_table[] = {	{		.procname	= "raid",		.maxlen		= 0,		.mode		= S_IRUGO|S_IXUGO,		.child		= raid_table,	},	{ }}; static struct ctl_table raid_root_table[] = {	{		.procname	= "dev",		.maxlen		= 0,		.mode		= 0555,		.child		= raid_dir_table,	},	{  }}; static const struct block_device_operations md_fops; static int start_readonly; /* * The original mechanism for creating an md device is to create * a device node in /dev and to open it.  This causes races with device-close. * The preferred method is to write to the "new_array" module parameter. * This can avoid races. * Setting create_on_open to false disables the original mechanism * so all the races disappear. */static bool create_on_open = true; /* bio_clone_mddev * like bio_clone_bioset, but with a local bio set */ struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs,			    struct mddev *mddev){	struct bio *b; 	if (!mddev || !mddev->bio_set)		return bio_alloc(gfp_mask, nr_iovecs); 	b = bio_alloc_bioset(gfp_mask, nr_iovecs, mddev->bio_set);	if (!b)		return NULL;	return b;}EXPORT_SYMBOL_GPL(bio_alloc_mddev); static struct bio *md_bio_alloc_sync(struct mddev *mddev){	if (!mddev || !mddev->sync_set)		return bio_alloc(GFP_NOIO, 1); 	return bio_alloc_bioset(GFP_NOIO, 1, mddev->sync_set);} /* * We have a system wide 'event count' that is incremented * on any 'interesting' event, and readers of /proc/mdstat * can use 'poll' or 'select' to find out when the event * count increases. * * Events are: *  start array, stop array, error, add device, remove device, *  start build, activate spare */static DECLARE_WAIT_QUEUE_HEAD(md_event_waiters);static atomic_t md_event_count;void md_new_event(struct mddev *mddev){	atomic_inc(&md_event_count);	wake_up(&md_event_waiters);}EXPORT_SYMBOL_GPL(md_new_event); /* * Enables to iterate over all existing md arrays * all_mddevs_lock protects this list. */static LIST_HEAD(all_mddevs);static DEFINE_SPINLOCK(all_mddevs_lock); /* * iterates through all used mddevs in the system. * We take care to grab the all_mddevs_lock whenever navigating * the list, and to always hold a refcount when unlocked. * Any code which breaks out of this loop while own * a reference to the current mddev and must mddev_put it. */#define for_each_mddev(_mddev,_tmp)					\									\	for (({ spin_lock(&all_mddevs_lock);				\		_tmp = all_mddevs.next;					\		_mddev = NULL;});					\	     ({ if (_tmp != &all_mddevs)				\			mddev_get(list_entry(_tmp, struct mddev, all_mddevs));\		spin_unlock(&all_mddevs_lock);				\		if (_mddev) mddev_put(_mddev);				\		_mddev = list_entry(_tmp, struct mddev, all_mddevs);	\		_tmp != &all_mddevs;});					\	     ({ spin_lock(&all_mddevs_lock);				\		_tmp = _tmp->next;})					\		) /* Rather than calling directly into the personality make_request function, * IO requests come here first so that we can check if the device is * being suspended pending a reconfiguration. * We hold a refcount over the call to ->make_request.  By the time that * call has finished, the bio has been linked into some internal structure * and so is visible to ->quiesce(), so we don't need the refcount any more. */static blk_qc_t md_make_request(struct request_queue *q, struct bio *bio){	const int rw = bio_data_dir(bio);	struct mddev *mddev = q->queuedata;	unsigned int sectors;	int cpu; 	blk_queue_split(q, &bio); 	if (mddev == NULL || mddev->pers == NULL) {		bio_io_error(bio);		return BLK_QC_T_NONE;	}	if (mddev->ro == 1 && unlikely(rw == WRITE)) {		if (bio_sectors(bio) != 0)			bio->bi_status = BLK_STS_IOERR;		bio_endio(bio);		return BLK_QC_T_NONE;	}check_suspended:	rcu_read_lock();	if (mddev->suspended) {		DEFINE_WAIT(__wait);		for (;;) {			prepare_to_wait(&mddev->sb_wait, &__wait,					TASK_UNINTERRUPTIBLE);			if (!mddev->suspended)				break;			rcu_read_unlock();			schedule();			rcu_read_lock();		}		finish_wait(&mddev->sb_wait, &__wait);	}	atomic_inc(&mddev->active_io);	rcu_read_unlock(); 	/*	 * save the sectors now since our bio can	 * go away inside make_request	 */	sectors = bio_sectors(bio);	/* bio could be mergeable after passing to underlayer */	bio->bi_opf &= ~REQ_NOMERGE;	if (!mddev->pers->make_request(mddev, bio)) {		atomic_dec(&mddev->active_io);		wake_up(&mddev->sb_wait);		goto check_suspended;	} 	cpu = part_stat_lock();	part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]);	part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], sectors);	part_stat_unlock(); 	if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended)		wake_up(&mddev->sb_wait); 	return BLK_QC_T_NONE;} /* mddev_suspend makes sure no new requests are submitted * to the device, and that any requests that have been submitted * are completely handled. * Once mddev_detach() is called and completes, the module will be * completely unused. */void mddev_suspend(struct mddev *mddev){	WARN_ON_ONCE(mddev->thread && current == mddev->thread->tsk);	if (mddev->suspended++)		return;	synchronize_rcu();	wake_up(&mddev->sb_wait);	wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0);	mddev->pers->quiesce(mddev, 1); 	del_timer_sync(&mddev->safemode_timer);}EXPORT_SYMBOL_GPL(mddev_suspend); void mddev_resume(struct mddev *mddev){	if (--mddev->suspended)		return;	wake_up(&mddev->sb_wait);	mddev->pers->quiesce(mddev, 0); 	set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);	md_wakeup_thread(mddev->thread);	md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */}EXPORT_SYMBOL_GPL(mddev_resume); int mddev_congested(struct mddev *mddev, int bits){	struct md_personality *pers = mddev->pers;	int ret = 0; 	rcu_read_lock();	if (mddev->suspended)		ret = 1;	else if (pers && pers->congested)		ret = pers->congested(mddev, bits);	rcu_read_unlock();	return ret;}EXPORT_SYMBOL_GPL(mddev_congested);static int md_congested(void *data, int bits){	struct mddev *mddev = data;	return mddev_congested(mddev, bits);} /* * Generic flush handling for md */ static void md_end_flush(struct bio *bio){	struct md_rdev *rdev = bio->bi_private;	struct mddev *mddev = rdev->mddev; 	rdev_dec_pending(rdev, mddev); 	if (atomic_dec_and_test(&mddev->flush_pending)) {		/* The pre-request flush has finished */		queue_work(md_wq, &mddev->flush_work);	}	bio_put(bio);} static void md_submit_flush_data(struct work_struct *ws); static void submit_flushes(struct work_struct *ws){	struct mddev *mddev = container_of(ws, struct mddev, flush_work);	struct md_rdev *rdev; 	INIT_WORK(&mddev->flush_work, md_submit_flush_data);	atomic_set(&mddev->flush_pending, 1);	rcu_read_lock();	rdev_for_each_rcu(rdev, mddev)		if (rdev->raid_disk >= 0 &&		    !test_bit(Faulty, &rdev->flags)) {			/* Take two references, one is dropped			 * when request finishes, one after			 * we reclaim rcu_read_lock			 */			struct bio *bi;			atomic_inc(&rdev->nr_pending);			atomic_inc(&rdev->nr_pending);			rcu_read_unlock();			bi = bio_alloc_mddev(GFP_NOIO, 0, mddev);			bi->bi_end_io = md_end_flush;			bi->bi_private = rdev;			bi->bi_bdev = rdev->bdev;			bi->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;			atomic_inc(&mddev->flush_pending);			submit_bio(bi);			rcu_read_lock();			rdev_dec_pending(rdev, mddev);		}	rcu_read_unlock();	if (atomic_dec_and_test(&mddev->flush_pending))		queue_work(md_wq, &mddev->flush_work);} static void md_submit_flush_data(struct work_struct *ws){	struct mddev *mddev = container_of(ws, struct mddev, flush_work);	struct bio *bio = mddev->flush_bio; 	if (bio->bi_iter.bi_size == 0)		/* an empty barrier - all done */		bio_endio(bio);	else {		bio->bi_opf &= ~REQ_PREFLUSH;		mddev->pers->make_request(mddev, bio);	} 	mddev->flush_bio = NULL;	wake_up(&mddev->sb_wait);} void md_flush_request(struct mddev *mddev, struct bio *bio){	spin_lock_irq(&mddev->lock);	wait_event_lock_irq(mddev->sb_wait,			    !mddev->flush_bio,			    mddev->lock);	mddev->flush_bio = bio;	spin_unlock_irq(&mddev->lock); 	INIT_WORK(&mddev->flush_work, submit_flushes);	queue_work(md_wq, &mddev->flush_work);}EXPORT_SYMBOL(md_flush_request); static inline struct mddev *mddev_get(struct mddev *mddev){	atomic_inc(&mddev->active);	return mddev;} static void mddev_delayed_delete(struct work_struct *ws); static void mddev_put(struct mddev *mddev){	struct bio_set *bs = NULL, *sync_bs = NULL; 	if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock))		return;	if (!mddev->raid_disks && list_empty(&mddev->disks) &&	    mddev->ctime == 0 && !mddev->hold_active) {		/* Array is not configured at all, and not held active,		 * so destroy it */		list_del_init(&mddev->all_mddevs);		bs = mddev->bio_set;		sync_bs = mddev->sync_set;		mddev->bio_set = NULL;		mddev->sync_set = NULL;		if (mddev->gendisk) {			/* We did a probe so need to clean up.  Call			 * queue_work inside the spinlock so that			 * flush_workqueue() after mddev_find will			 * succeed in waiting for the work to be done.			 */			INIT_WORK(&mddev->del_work, mddev_delayed_delete);			queue_work(md_misc_wq, &mddev->del_work);		} else			kfree(mddev);

Lines 1–500 of 9266.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t