static int sync_page_io(struct block_device *bdev, sector_t sector, int size,
struct page *page, int rw)
{
- struct bio *bio = bio_alloc(GFP_KERNEL, 1);
+ struct bio *bio = bio_alloc(GFP_NOIO, 1);
struct completion event;
int ret;
rdev->preferred_minor = sb->md_minor;
rdev->data_offset = 0;
- if (sb->level == MULTIPATH)
+ if (sb->level == LEVEL_MULTIPATH)
rdev->desc_nr = -1;
else
rdev->desc_nr = sb->this_disk.number;
sb->max_dev = cpu_to_le32(max_dev);
for (i=0; i<max_dev;i++)
- sb->dev_roles[max_dev] = cpu_to_le16(0xfffe);
+ sb->dev_roles[i] = cpu_to_le16(0xfffe);
ITERATE_RDEV(mddev,rdev2,tmp) {
i = rdev2->desc_nr;
}
-struct super_type super_types[] = {
+static struct super_type super_types[] = {
[0] = {
.name = "0.90.0",
.owner = THIS_MODULE,
*/
-static int analyze_sbs(mddev_t * mddev)
+static void analyze_sbs(mddev_t * mddev)
{
int i;
struct list_head *tmp;
- if ((mddev->recovery_cp != MaxSector) &&
- ((mddev->level == 1) ||
- ((mddev->level >= 4) && (mddev->level <= 6))))
+ if (mddev->recovery_cp != MaxSector &&
+ mddev->level >= 1)
printk(KERN_ERR "md: %s: raid array is not clean"
" -- starting background reconstruction\n",
mdname(mddev));
- return 0;
}
int mdp_major = 0;
struct gendisk *disk;
char b[BDEVNAME_SIZE];
- if (list_empty(&mddev->disks)) {
- MD_BUG();
+ if (list_empty(&mddev->disks))
+ /* cannot run an array with no devices.. */
return -EINVAL;
- }
if (mddev->pers)
return -EBUSY;
/*
* Analyze all RAID superblock(s)
*/
- if (!mddev->raid_disks && analyze_sbs(mddev)) {
- MD_BUG();
- return -EINVAL;
- }
+ if (!mddev->raid_disks)
+ analyze_sbs(mddev);
chunk_size = mddev->chunk_size;
pnum = level_to_pers(mddev->level);
* chunk-size has to be a power of 2 and multiples of PAGE_SIZE
*/
if ( (1 << ffz(~chunk_size)) != chunk_size) {
- MD_BUG();
+ printk(KERN_ERR "chunk_size of %d not valid\n", chunk_size);
return -EINVAL;
}
if (chunk_size < PAGE_SIZE) {
}
}
- if (pnum >= MAX_PERSONALITY) {
- MD_BUG();
- return -EINVAL;
- }
-
#ifdef CONFIG_KMOD
if (!pers[pnum])
{
struct list_head *tmp;
int err;
- if (list_empty(&mddev->disks)) {
- MD_BUG();
+ if (list_empty(&mddev->disks))
return;
- }
printk(KERN_INFO "md: running: ");
.revalidate_disk= md_revalidate,
};
-int md_thread(void * arg)
+static int md_thread(void * arg)
{
mdk_thread_t *thread = arg;
return thread;
}
-static void md_interrupt_thread(mdk_thread_t *thread)
-{
- if (!thread->tsk) {
- MD_BUG();
- return;
- }
- dprintk("interrupting MD-thread pid %d\n", thread->tsk->pid);
- send_sig(SIGKILL, thread->tsk, 1);
-}
-
void md_unregister_thread(mdk_thread_t *thread)
{
struct completion event;
init_completion(&event);
thread->event = &event;
+
+ /* As soon as ->run is set to NULL, the task could disappear,
+ * so we need to hold tasklist_lock until we have sent the signal
+ */
+ dprintk("interrupting MD-thread pid %d\n", thread->tsk->pid);
+ read_lock(&tasklist_lock);
thread->run = NULL;
- thread->name = NULL;
- md_interrupt_thread(thread);
+ send_sig(SIGKILL, thread->tsk, 1);
+ read_unlock(&tasklist_lock);
wait_for_completion(&event);
kfree(thread);
}
spin_lock(&pers_lock);
if (pers[pnum]) {
spin_unlock(&pers_lock);
- MD_BUG();
return -EBUSY;
}
int unregister_md_personality(int pnum)
{
- if (pnum >= MAX_PERSONALITY) {
- MD_BUG();
+ if (pnum >= MAX_PERSONALITY)
return -EINVAL;
- }
printk(KERN_INFO "md: %s personality unregistered\n", pers[pnum]->name);
spin_lock(&pers_lock);
}
-DECLARE_WAIT_QUEUE_HEAD(resync_wait);
+static DECLARE_WAIT_QUEUE_HEAD(resync_wait);
#define SYNC_MARKS 10
#define SYNC_MARK_STEP (3*HZ)
/* no recovery is running.
* remove any failed drives, then
- * add spares if possible
+ * add spares if possible.
+ * Spare are also removed and re-added, to allow
+ * the personality to fail the re-add.
*/
- ITERATE_RDEV(mddev,rdev,rtmp) {
+ ITERATE_RDEV(mddev,rdev,rtmp)
if (rdev->raid_disk >= 0 &&
- rdev->faulty &&
+ (rdev->faulty || ! rdev->in_sync) &&
atomic_read(&rdev->nr_pending)==0) {
if (mddev->pers->hot_remove_disk(mddev, rdev->raid_disk)==0)
rdev->raid_disk = -1;
}
- if (!rdev->faulty && rdev->raid_disk >= 0 && !rdev->in_sync)
- spares++;
- }
+
if (mddev->degraded) {
ITERATE_RDEV(mddev,rdev,rtmp)
if (rdev->raid_disk < 0
}
}
-int md_notify_reboot(struct notifier_block *this,
- unsigned long code, void *x)
+static int md_notify_reboot(struct notifier_block *this,
+ unsigned long code, void *x)
{
struct list_head *tmp;
mddev_t *mddev;
return NOTIFY_DONE;
}
-struct notifier_block md_notifier = {
+static struct notifier_block md_notifier = {
.notifier_call = md_notify_reboot,
.next = NULL,
.priority = INT_MAX, /* before any real devices */
p->proc_fops = &md_seq_fops;
}
-int __init md_init(void)
+static int __init md_init(void)
{
int minor;