Merge branch 'for-linus' of git://neil.brown.name/md
* 'for-linus' of git://neil.brown.name/md: md: protect against NULL reference when waiting to start a raid10. md: fix bug with re-adding of partially recovered device. md: fix possible deadlock in handling flush requests. md: move code in to submit_flushes. md: remove handling of flush_pending in md_submit_flush_data
This commit is contained in:
commit
6d5e93c2aa
|
@ -371,10 +371,15 @@ static void md_end_flush(struct bio *bio, int err)
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void submit_flushes(mddev_t *mddev)
|
static void md_submit_flush_data(struct work_struct *ws);
|
||||||
|
|
||||||
|
static void submit_flushes(struct work_struct *ws)
|
||||||
{
|
{
|
||||||
|
mddev_t *mddev = container_of(ws, mddev_t, flush_work);
|
||||||
mdk_rdev_t *rdev;
|
mdk_rdev_t *rdev;
|
||||||
|
|
||||||
|
INIT_WORK(&mddev->flush_work, md_submit_flush_data);
|
||||||
|
atomic_set(&mddev->flush_pending, 1);
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
list_for_each_entry_rcu(rdev, &mddev->disks, same_set)
|
list_for_each_entry_rcu(rdev, &mddev->disks, same_set)
|
||||||
if (rdev->raid_disk >= 0 &&
|
if (rdev->raid_disk >= 0 &&
|
||||||
|
@ -397,6 +402,8 @@ static void submit_flushes(mddev_t *mddev)
|
||||||
rdev_dec_pending(rdev, mddev);
|
rdev_dec_pending(rdev, mddev);
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
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)
|
static void md_submit_flush_data(struct work_struct *ws)
|
||||||
|
@ -404,8 +411,6 @@ static void md_submit_flush_data(struct work_struct *ws)
|
||||||
mddev_t *mddev = container_of(ws, mddev_t, flush_work);
|
mddev_t *mddev = container_of(ws, mddev_t, flush_work);
|
||||||
struct bio *bio = mddev->flush_bio;
|
struct bio *bio = mddev->flush_bio;
|
||||||
|
|
||||||
atomic_set(&mddev->flush_pending, 1);
|
|
||||||
|
|
||||||
if (bio->bi_size == 0)
|
if (bio->bi_size == 0)
|
||||||
/* an empty barrier - all done */
|
/* an empty barrier - all done */
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio, 0);
|
||||||
|
@ -414,10 +419,9 @@ static void md_submit_flush_data(struct work_struct *ws)
|
||||||
if (mddev->pers->make_request(mddev, bio))
|
if (mddev->pers->make_request(mddev, bio))
|
||||||
generic_make_request(bio);
|
generic_make_request(bio);
|
||||||
}
|
}
|
||||||
if (atomic_dec_and_test(&mddev->flush_pending)) {
|
|
||||||
mddev->flush_bio = NULL;
|
mddev->flush_bio = NULL;
|
||||||
wake_up(&mddev->sb_wait);
|
wake_up(&mddev->sb_wait);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void md_flush_request(mddev_t *mddev, struct bio *bio)
|
void md_flush_request(mddev_t *mddev, struct bio *bio)
|
||||||
|
@ -429,12 +433,7 @@ void md_flush_request(mddev_t *mddev, struct bio *bio)
|
||||||
mddev->flush_bio = bio;
|
mddev->flush_bio = bio;
|
||||||
spin_unlock_irq(&mddev->write_lock);
|
spin_unlock_irq(&mddev->write_lock);
|
||||||
|
|
||||||
atomic_set(&mddev->flush_pending, 1);
|
INIT_WORK(&mddev->flush_work, submit_flushes);
|
||||||
INIT_WORK(&mddev->flush_work, md_submit_flush_data);
|
|
||||||
|
|
||||||
submit_flushes(mddev);
|
|
||||||
|
|
||||||
if (atomic_dec_and_test(&mddev->flush_pending))
|
|
||||||
queue_work(md_wq, &mddev->flush_work);
|
queue_work(md_wq, &mddev->flush_work);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(md_flush_request);
|
EXPORT_SYMBOL(md_flush_request);
|
||||||
|
@ -5160,7 +5159,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
|
||||||
PTR_ERR(rdev));
|
PTR_ERR(rdev));
|
||||||
return PTR_ERR(rdev);
|
return PTR_ERR(rdev);
|
||||||
}
|
}
|
||||||
/* set save_raid_disk if appropriate */
|
/* set saved_raid_disk if appropriate */
|
||||||
if (!mddev->persistent) {
|
if (!mddev->persistent) {
|
||||||
if (info->state & (1<<MD_DISK_SYNC) &&
|
if (info->state & (1<<MD_DISK_SYNC) &&
|
||||||
info->raid_disk < mddev->raid_disks)
|
info->raid_disk < mddev->raid_disks)
|
||||||
|
@ -5170,7 +5169,10 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
|
||||||
} else
|
} else
|
||||||
super_types[mddev->major_version].
|
super_types[mddev->major_version].
|
||||||
validate_super(mddev, rdev);
|
validate_super(mddev, rdev);
|
||||||
|
if (test_bit(In_sync, &rdev->flags))
|
||||||
rdev->saved_raid_disk = rdev->raid_disk;
|
rdev->saved_raid_disk = rdev->raid_disk;
|
||||||
|
else
|
||||||
|
rdev->saved_raid_disk = -1;
|
||||||
|
|
||||||
clear_bit(In_sync, &rdev->flags); /* just to be sure */
|
clear_bit(In_sync, &rdev->flags); /* just to be sure */
|
||||||
if (info->state & (1<<MD_DISK_WRITEMOSTLY))
|
if (info->state & (1<<MD_DISK_WRITEMOSTLY))
|
||||||
|
@ -6042,8 +6044,7 @@ static int md_thread(void * arg)
|
||||||
|| kthread_should_stop(),
|
|| kthread_should_stop(),
|
||||||
thread->timeout);
|
thread->timeout);
|
||||||
|
|
||||||
clear_bit(THREAD_WAKEUP, &thread->flags);
|
if (test_and_clear_bit(THREAD_WAKEUP, &thread->flags))
|
||||||
|
|
||||||
thread->run(thread->mddev);
|
thread->run(thread->mddev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2397,13 +2397,13 @@ static int run(mddev_t *mddev)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_free_conf:
|
out_free_conf:
|
||||||
|
md_unregister_thread(mddev->thread);
|
||||||
if (conf->r10bio_pool)
|
if (conf->r10bio_pool)
|
||||||
mempool_destroy(conf->r10bio_pool);
|
mempool_destroy(conf->r10bio_pool);
|
||||||
safe_put_page(conf->tmppage);
|
safe_put_page(conf->tmppage);
|
||||||
kfree(conf->mirrors);
|
kfree(conf->mirrors);
|
||||||
kfree(conf);
|
kfree(conf);
|
||||||
mddev->private = NULL;
|
mddev->private = NULL;
|
||||||
md_unregister_thread(mddev->thread);
|
|
||||||
out:
|
out:
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue