Commit 66db15b4 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] unplugging: md update

From: Neil Brown <neilb@cse.unsw.edu.au>

I've made a bunch of changes to the 'md' bits - largely moving the
unplugging into the individual personalities which know more about which
drives are actually in use.
parent b1c72a96
...@@ -80,6 +80,20 @@ static int linear_mergeable_bvec(request_queue_t *q, struct bio *bio, struct bio ...@@ -80,6 +80,20 @@ static int linear_mergeable_bvec(request_queue_t *q, struct bio *bio, struct bio
return maxsectors << 9; return maxsectors << 9;
} }
static void linear_unplug(request_queue_t *q)
{
mddev_t *mddev = q->queuedata;
linear_conf_t *conf = mddev_to_conf(mddev);
int i;
for (i=0; i < mddev->raid_disks; i++) {
request_queue_t *r_queue = bdev_get_queue(conf->disks[i].rdev->bdev);
if (r_queue->unplug_fn)
r_queue->unplug_fn(r_queue);
}
}
static int linear_run (mddev_t *mddev) static int linear_run (mddev_t *mddev)
{ {
linear_conf_t *conf; linear_conf_t *conf;
...@@ -185,6 +199,7 @@ static int linear_run (mddev_t *mddev) ...@@ -185,6 +199,7 @@ static int linear_run (mddev_t *mddev)
BUG(); BUG();
blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec); blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec);
mddev->queue->unplug_fn = linear_unplug;
return 0; return 0;
out: out:
......
...@@ -160,30 +160,6 @@ static int md_fail_request (request_queue_t *q, struct bio *bio) ...@@ -160,30 +160,6 @@ static int md_fail_request (request_queue_t *q, struct bio *bio)
return 0; return 0;
} }
void md_unplug_mddev(mddev_t *mddev)
{
struct list_head *tmp;
mdk_rdev_t *rdev;
/*
* this list iteration is done without any locking in md?!
*/
ITERATE_RDEV(mddev, rdev, tmp) {
request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
if (r_queue->unplug_fn)
r_queue->unplug_fn(r_queue);
}
}
EXPORT_SYMBOL(md_unplug_mddev);
static void md_unplug_all(request_queue_t *q)
{
mddev_t *mddev = q->queuedata;
md_unplug_mddev(mddev);
}
static inline mddev_t *mddev_get(mddev_t *mddev) static inline mddev_t *mddev_get(mddev_t *mddev)
{ {
atomic_inc(&mddev->active); atomic_inc(&mddev->active);
...@@ -1669,7 +1645,6 @@ static int do_md_run(mddev_t * mddev) ...@@ -1669,7 +1645,6 @@ static int do_md_run(mddev_t * mddev)
*/ */
mddev->queue->queuedata = mddev; mddev->queue->queuedata = mddev;
mddev->queue->make_request_fn = mddev->pers->make_request; mddev->queue->make_request_fn = mddev->pers->make_request;
mddev->queue->unplug_fn = md_unplug_all;
mddev->changed = 1; mddev->changed = 1;
return 0; return 0;
...@@ -2742,10 +2717,9 @@ int md_thread(void * arg) ...@@ -2742,10 +2717,9 @@ int md_thread(void * arg)
clear_bit(THREAD_WAKEUP, &thread->flags); clear_bit(THREAD_WAKEUP, &thread->flags);
run = thread->run; run = thread->run;
if (run) { if (run)
run(thread->mddev); run(thread->mddev);
md_unplug_mddev(thread->mddev);
}
if (signal_pending(current)) if (signal_pending(current))
flush_signals(current); flush_signals(current);
} }
...@@ -3313,8 +3287,6 @@ static void md_do_sync(mddev_t *mddev) ...@@ -3313,8 +3287,6 @@ static void md_do_sync(mddev_t *mddev)
test_bit(MD_RECOVERY_ERR, &mddev->recovery)) test_bit(MD_RECOVERY_ERR, &mddev->recovery))
break; break;
md_unplug_mddev(mddev);
repeat: repeat:
if (jiffies >= mark[last_mark] + SYNC_MARK_STEP ) { if (jiffies >= mark[last_mark] + SYNC_MARK_STEP ) {
/* step marks */ /* step marks */
...@@ -3347,6 +3319,7 @@ static void md_do_sync(mddev_t *mddev) ...@@ -3347,6 +3319,7 @@ static void md_do_sync(mddev_t *mddev)
* about not overloading the IO subsystem. (things like an * about not overloading the IO subsystem. (things like an
* e2fsck being done on the RAID array should execute fast) * e2fsck being done on the RAID array should execute fast)
*/ */
mddev->queue->unplug_fn(mddev->queue);
cond_resched(); cond_resched();
currspeed = ((unsigned long)(j-mddev->resync_mark_cnt))/2/((jiffies-mddev->resync_mark)/HZ +1) +1; currspeed = ((unsigned long)(j-mddev->resync_mark_cnt))/2/((jiffies-mddev->resync_mark)/HZ +1) +1;
...@@ -3365,6 +3338,8 @@ static void md_do_sync(mddev_t *mddev) ...@@ -3365,6 +3338,8 @@ static void md_do_sync(mddev_t *mddev)
* this also signals 'finished resyncing' to md_stop * this also signals 'finished resyncing' to md_stop
*/ */
out: out:
mddev->queue->unplug_fn(mddev->queue);
wait_event(mddev->recovery_wait, !atomic_read(&mddev->recovery_active)); wait_event(mddev->recovery_wait, !atomic_read(&mddev->recovery_active));
/* tell personality that we are finished */ /* tell personality that we are finished */
......
...@@ -155,6 +155,27 @@ static int multipath_read_balance (multipath_conf_t *conf) ...@@ -155,6 +155,27 @@ static int multipath_read_balance (multipath_conf_t *conf)
return 0; return 0;
} }
static void unplug_slaves(mddev_t *mddev)
{
multipath_conf_t *conf = mddev_to_conf(mddev);
int i;
for (i=0; i<mddev->raid_disks; i++) {
mdk_rdev_t *rdev = conf->multipaths[i].rdev;
if (rdev && !rdev->faulty) {
request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
if (r_queue->unplug_fn)
r_queue->unplug_fn(r_queue);
}
}
}
static void multipath_unplug(request_queue_t *q)
{
unplug_slaves(q->queuedata);
}
static int multipath_make_request (request_queue_t *q, struct bio * bio) static int multipath_make_request (request_queue_t *q, struct bio * bio)
{ {
mddev_t *mddev = q->queuedata; mddev_t *mddev = q->queuedata;
...@@ -419,6 +440,8 @@ static int multipath_run (mddev_t *mddev) ...@@ -419,6 +440,8 @@ static int multipath_run (mddev_t *mddev)
} }
memset(conf->multipaths, 0, sizeof(struct multipath_info)*mddev->raid_disks); memset(conf->multipaths, 0, sizeof(struct multipath_info)*mddev->raid_disks);
mddev->queue->unplug_fn = multipath_unplug;
conf->working_disks = 0; conf->working_disks = 0;
ITERATE_RDEV(mddev,rdev,tmp) { ITERATE_RDEV(mddev,rdev,tmp) {
disk_idx = rdev->raid_disk; disk_idx = rdev->raid_disk;
......
...@@ -25,6 +25,21 @@ ...@@ -25,6 +25,21 @@
#define MD_DRIVER #define MD_DRIVER
#define MD_PERSONALITY #define MD_PERSONALITY
static void raid0_unplug(request_queue_t *q)
{
mddev_t *mddev = q->queuedata;
raid0_conf_t *conf = mddev_to_conf(mddev);
mdk_rdev_t **devlist = conf->strip_zone[0].dev;
int i;
for (i=0; i<mddev->raid_disks; i++) {
request_queue_t *r_queue = bdev_get_queue(devlist[i]->bdev);
if (r_queue->unplug_fn)
r_queue->unplug_fn(r_queue);
}
}
static int create_strip_zones (mddev_t *mddev) static int create_strip_zones (mddev_t *mddev)
{ {
int i, c, j; int i, c, j;
...@@ -202,6 +217,8 @@ static int create_strip_zones (mddev_t *mddev) ...@@ -202,6 +217,8 @@ static int create_strip_zones (mddev_t *mddev)
conf->hash_spacing = sz; conf->hash_spacing = sz;
} }
mddev->queue->unplug_fn = raid0_unplug;
printk("raid0: done.\n"); printk("raid0: done.\n");
return 0; return 0;
abort: abort:
......
...@@ -37,6 +37,9 @@ static mdk_personality_t raid1_personality; ...@@ -37,6 +37,9 @@ static mdk_personality_t raid1_personality;
static spinlock_t retry_list_lock = SPIN_LOCK_UNLOCKED; static spinlock_t retry_list_lock = SPIN_LOCK_UNLOCKED;
static LIST_HEAD(retry_list_head); static LIST_HEAD(retry_list_head);
static void unplug_slaves(mddev_t *mddev);
static void * r1bio_pool_alloc(int gfp_flags, void *data) static void * r1bio_pool_alloc(int gfp_flags, void *data)
{ {
mddev_t *mddev = data; mddev_t *mddev = data;
...@@ -47,6 +50,8 @@ static void * r1bio_pool_alloc(int gfp_flags, void *data) ...@@ -47,6 +50,8 @@ static void * r1bio_pool_alloc(int gfp_flags, void *data)
gfp_flags); gfp_flags);
if (r1_bio) if (r1_bio)
memset(r1_bio, 0, sizeof(*r1_bio) + sizeof(struct bio*)*mddev->raid_disks); memset(r1_bio, 0, sizeof(*r1_bio) + sizeof(struct bio*)*mddev->raid_disks);
else
unplug_slaves(mddev);
return r1_bio; return r1_bio;
} }
...@@ -71,8 +76,10 @@ static void * r1buf_pool_alloc(int gfp_flags, void *data) ...@@ -71,8 +76,10 @@ static void * r1buf_pool_alloc(int gfp_flags, void *data)
int i, j; int i, j;
r1_bio = r1bio_pool_alloc(gfp_flags, conf->mddev); r1_bio = r1bio_pool_alloc(gfp_flags, conf->mddev);
if (!r1_bio) if (!r1_bio) {
unplug_slaves(conf->mddev);
return NULL; return NULL;
}
/* /*
* Allocate bios : 1 for reading, n-1 for writing * Allocate bios : 1 for reading, n-1 for writing
...@@ -443,6 +450,29 @@ static int read_balance(conf_t *conf, struct bio *bio, r1bio_t *r1_bio) ...@@ -443,6 +450,29 @@ static int read_balance(conf_t *conf, struct bio *bio, r1bio_t *r1_bio)
return new_disk; return new_disk;
} }
static void unplug_slaves(mddev_t *mddev)
{
conf_t *conf = mddev_to_conf(mddev);
int i;
unsigned long flags;
spin_lock_irqsave(&conf->device_lock, flags);
for (i=0; i<mddev->raid_disks; i++) {
mdk_rdev_t *rdev = conf->mirrors[i].rdev;
if (rdev && !rdev->faulty) {
request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
if (r_queue->unplug_fn)
r_queue->unplug_fn(r_queue);
}
}
spin_unlock_irqrestore(&conf->device_lock, flags);
}
static void raid1_unplug(request_queue_t *q)
{
unplug_slaves(q->queuedata);
}
/* /*
* Throttle resync depth, so that we can both get proper overlapping of * Throttle resync depth, so that we can both get proper overlapping of
* requests, but are still able to handle normal requests quickly. * requests, but are still able to handle normal requests quickly.
...@@ -451,16 +481,18 @@ static int read_balance(conf_t *conf, struct bio *bio, r1bio_t *r1_bio) ...@@ -451,16 +481,18 @@ static int read_balance(conf_t *conf, struct bio *bio, r1bio_t *r1_bio)
static void device_barrier(conf_t *conf, sector_t sect) static void device_barrier(conf_t *conf, sector_t sect)
{ {
md_unplug_mddev(conf->mddev);
spin_lock_irq(&conf->resync_lock); spin_lock_irq(&conf->resync_lock);
wait_event_lock_irq(conf->wait_idle, !waitqueue_active(&conf->wait_resume), conf->resync_lock); wait_event_lock_irq(conf->wait_idle, !waitqueue_active(&conf->wait_resume),
conf->resync_lock, unplug_slaves(conf->mddev));
if (!conf->barrier++) { if (!conf->barrier++) {
wait_event_lock_irq(conf->wait_idle, !conf->nr_pending, conf->resync_lock); wait_event_lock_irq(conf->wait_idle, !conf->nr_pending,
conf->resync_lock, unplug_slaves(conf->mddev));
if (conf->nr_pending) if (conf->nr_pending)
BUG(); BUG();
} }
wait_event_lock_irq(conf->wait_resume, conf->barrier < RESYNC_DEPTH, conf->resync_lock); wait_event_lock_irq(conf->wait_resume, conf->barrier < RESYNC_DEPTH,
conf->resync_lock, unplug_slaves(conf->mddev));
conf->next_resync = sect; conf->next_resync = sect;
spin_unlock_irq(&conf->resync_lock); spin_unlock_irq(&conf->resync_lock);
} }
...@@ -479,9 +511,8 @@ static int make_request(request_queue_t *q, struct bio * bio) ...@@ -479,9 +511,8 @@ static int make_request(request_queue_t *q, struct bio * bio)
* thread has put up a bar for new requests. * thread has put up a bar for new requests.
* Continue immediately if no resync is active currently. * Continue immediately if no resync is active currently.
*/ */
md_unplug_mddev(conf->mddev);
spin_lock_irq(&conf->resync_lock); spin_lock_irq(&conf->resync_lock);
wait_event_lock_irq(conf->wait_resume, !conf->barrier, conf->resync_lock); wait_event_lock_irq(conf->wait_resume, !conf->barrier, conf->resync_lock, );
conf->nr_pending++; conf->nr_pending++;
spin_unlock_irq(&conf->resync_lock); spin_unlock_irq(&conf->resync_lock);
...@@ -646,9 +677,9 @@ static void print_conf(conf_t *conf) ...@@ -646,9 +677,9 @@ static void print_conf(conf_t *conf)
static void close_sync(conf_t *conf) static void close_sync(conf_t *conf)
{ {
md_unplug_mddev(conf->mddev);
spin_lock_irq(&conf->resync_lock); spin_lock_irq(&conf->resync_lock);
wait_event_lock_irq(conf->wait_resume, !conf->barrier, conf->resync_lock); wait_event_lock_irq(conf->wait_resume, !conf->barrier,
conf->resync_lock, unplug_slaves(conf->mddev));
spin_unlock_irq(&conf->resync_lock); spin_unlock_irq(&conf->resync_lock);
if (conf->barrier) BUG(); if (conf->barrier) BUG();
...@@ -862,6 +893,7 @@ static void raid1d(mddev_t *mddev) ...@@ -862,6 +893,7 @@ static void raid1d(mddev_t *mddev)
struct bio *bio; struct bio *bio;
unsigned long flags; unsigned long flags;
conf_t *conf = mddev_to_conf(mddev); conf_t *conf = mddev_to_conf(mddev);
int unplug=0;
mdk_rdev_t *rdev; mdk_rdev_t *rdev;
md_check_recovery(mddev); md_check_recovery(mddev);
...@@ -881,6 +913,7 @@ static void raid1d(mddev_t *mddev) ...@@ -881,6 +913,7 @@ static void raid1d(mddev_t *mddev)
bio = r1_bio->master_bio; bio = r1_bio->master_bio;
if (test_bit(R1BIO_IsSync, &r1_bio->state)) { if (test_bit(R1BIO_IsSync, &r1_bio->state)) {
sync_request_write(mddev, r1_bio); sync_request_write(mddev, r1_bio);
unplug = 1;
} else { } else {
if (map(mddev, &rdev) == -1) { if (map(mddev, &rdev) == -1) {
printk(KERN_ALERT "raid1: %s: unrecoverable I/O" printk(KERN_ALERT "raid1: %s: unrecoverable I/O"
...@@ -896,12 +929,14 @@ static void raid1d(mddev_t *mddev) ...@@ -896,12 +929,14 @@ static void raid1d(mddev_t *mddev)
bio->bi_bdev = rdev->bdev; bio->bi_bdev = rdev->bdev;
bio->bi_sector = r1_bio->sector + rdev->data_offset; bio->bi_sector = r1_bio->sector + rdev->data_offset;
bio->bi_rw = READ; bio->bi_rw = READ;
unplug = 1;
generic_make_request(bio); generic_make_request(bio);
} }
} }
} }
spin_unlock_irqrestore(&retry_list_lock, flags); spin_unlock_irqrestore(&retry_list_lock, flags);
if (unplug)
unplug_slaves(mddev);
} }
...@@ -1104,6 +1139,7 @@ static int run(mddev_t *mddev) ...@@ -1104,6 +1139,7 @@ static int run(mddev_t *mddev)
mdname(mddev)); mdname(mddev));
goto out_free_conf; goto out_free_conf;
} }
mddev->queue->unplug_fn = raid1_unplug;
ITERATE_RDEV(mddev, rdev, tmp) { ITERATE_RDEV(mddev, rdev, tmp) {
......
...@@ -231,6 +231,8 @@ static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector) ...@@ -231,6 +231,8 @@ static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector)
return NULL; return NULL;
} }
static void unplug_slaves(mddev_t *mddev);
static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector, static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector,
int pd_idx, int noblock) int pd_idx, int noblock)
{ {
...@@ -249,12 +251,13 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector ...@@ -249,12 +251,13 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector
break; break;
if (!sh) { if (!sh) {
conf->inactive_blocked = 1; conf->inactive_blocked = 1;
md_unplug_mddev(conf->mddev);
wait_event_lock_irq(conf->wait_for_stripe, wait_event_lock_irq(conf->wait_for_stripe,
!list_empty(&conf->inactive_list) && !list_empty(&conf->inactive_list) &&
(atomic_read(&conf->active_stripes) < (NR_STRIPES *3/4) (atomic_read(&conf->active_stripes) < (NR_STRIPES *3/4)
|| !conf->inactive_blocked), || !conf->inactive_blocked),
conf->device_lock); conf->device_lock,
unplug_slaves(conf->mddev);
);
conf->inactive_blocked = 0; conf->inactive_blocked = 0;
} else } else
init_stripe(sh, sector, pd_idx); init_stripe(sh, sector, pd_idx);
...@@ -1293,6 +1296,25 @@ static inline void raid5_activate_delayed(raid5_conf_t *conf) ...@@ -1293,6 +1296,25 @@ static inline void raid5_activate_delayed(raid5_conf_t *conf)
} }
} }
} }
static void unplug_slaves(mddev_t *mddev)
{
raid5_conf_t *conf = mddev_to_conf(mddev);
int i;
for (i=0; i<mddev->raid_disks; i++) {
mdk_rdev_t *rdev = conf->disks[i].rdev;
if (rdev && !rdev->faulty) {
struct block_device *bdev = rdev->bdev;
if (bdev) {
request_queue_t *r_queue = bdev_get_queue(bdev);
if (r_queue && r_queue->unplug_fn)
r_queue->unplug_fn(r_queue);
}
}
}
}
static void raid5_unplug_device(request_queue_t *q) static void raid5_unplug_device(request_queue_t *q)
{ {
mddev_t *mddev = q->queuedata; mddev_t *mddev = q->queuedata;
...@@ -1306,6 +1328,8 @@ static void raid5_unplug_device(request_queue_t *q) ...@@ -1306,6 +1328,8 @@ static void raid5_unplug_device(request_queue_t *q)
md_wakeup_thread(mddev->thread); md_wakeup_thread(mddev->thread);
spin_unlock_irqrestore(&conf->device_lock, flags); spin_unlock_irqrestore(&conf->device_lock, flags);
unplug_slaves(mddev);
} }
static inline void raid5_plug_device(raid5_conf_t *conf) static inline void raid5_plug_device(raid5_conf_t *conf)
...@@ -1392,9 +1416,11 @@ static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster) ...@@ -1392,9 +1416,11 @@ static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster)
int raid_disks = conf->raid_disks; int raid_disks = conf->raid_disks;
int data_disks = raid_disks-1; int data_disks = raid_disks-1;
if (sector_nr >= mddev->size <<1) if (sector_nr >= mddev->size <<1) {
/* just being told to finish up .. nothing to do */ /* just being told to finish up .. nothing much to do */
unplug_slaves(mddev);
return 0; return 0;
}
x = sector_nr; x = sector_nr;
chunk_offset = sector_div(x, sectors_per_chunk); chunk_offset = sector_div(x, sectors_per_chunk);
...@@ -1474,6 +1500,8 @@ static void raid5d (mddev_t *mddev) ...@@ -1474,6 +1500,8 @@ static void raid5d (mddev_t *mddev)
spin_unlock_irq(&conf->device_lock); spin_unlock_irq(&conf->device_lock);
unplug_slaves(mddev);
PRINTK("--- raid5d inactive\n"); PRINTK("--- raid5d inactive\n");
} }
......
...@@ -250,6 +250,8 @@ static struct stripe_head *__find_stripe(raid6_conf_t *conf, sector_t sector) ...@@ -250,6 +250,8 @@ static struct stripe_head *__find_stripe(raid6_conf_t *conf, sector_t sector)
return NULL; return NULL;
} }
static void unplug_slaves(mddev_t *mddev);
static struct stripe_head *get_active_stripe(raid6_conf_t *conf, sector_t sector, static struct stripe_head *get_active_stripe(raid6_conf_t *conf, sector_t sector,
int pd_idx, int noblock) int pd_idx, int noblock)
{ {
...@@ -272,7 +274,9 @@ static struct stripe_head *get_active_stripe(raid6_conf_t *conf, sector_t sector ...@@ -272,7 +274,9 @@ static struct stripe_head *get_active_stripe(raid6_conf_t *conf, sector_t sector
!list_empty(&conf->inactive_list) && !list_empty(&conf->inactive_list) &&
(atomic_read(&conf->active_stripes) < (NR_STRIPES *3/4) (atomic_read(&conf->active_stripes) < (NR_STRIPES *3/4)
|| !conf->inactive_blocked), || !conf->inactive_blocked),
conf->device_lock); conf->device_lock,
unplug_slaves(conf->mddev);
);
conf->inactive_blocked = 0; conf->inactive_blocked = 0;
} else } else
init_stripe(sh, sector, pd_idx); init_stripe(sh, sector, pd_idx);
...@@ -1454,6 +1458,26 @@ static inline void raid6_activate_delayed(raid6_conf_t *conf) ...@@ -1454,6 +1458,26 @@ static inline void raid6_activate_delayed(raid6_conf_t *conf)
} }
} }
} }
static void unplug_slaves(mddev_t *mddev)
{
/* note: this is always called with device_lock held */
raid6_conf_t *conf = mddev_to_conf(mddev);
int i;
for (i=0; i<mddev->raid_disks; i++) {
mdk_rdev_t *rdev = conf->disks[i].rdev;
if (rdev && !rdev->faulty) {
struct block_device *bdev = rdev->bdev;
if (bdev) {
request_queue_t *r_queue = bdev_get_queue(bdev);
if (r_queue && r_queue->unplug_fn)
r_queue->unplug_fn(r_queue);
}
}
}
}
static void raid6_unplug_device(request_queue_t *q) static void raid6_unplug_device(request_queue_t *q)
{ {
mddev_t *mddev = q->queuedata; mddev_t *mddev = q->queuedata;
...@@ -1467,6 +1491,8 @@ static void raid6_unplug_device(request_queue_t *q) ...@@ -1467,6 +1491,8 @@ static void raid6_unplug_device(request_queue_t *q)
md_wakeup_thread(mddev->thread); md_wakeup_thread(mddev->thread);
spin_unlock_irqrestore(&conf->device_lock, flags); spin_unlock_irqrestore(&conf->device_lock, flags);
unplug_slaves(mddev);
} }
static inline void raid6_plug_device(raid6_conf_t *conf) static inline void raid6_plug_device(raid6_conf_t *conf)
...@@ -1553,9 +1579,11 @@ static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster) ...@@ -1553,9 +1579,11 @@ static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster)
int raid_disks = conf->raid_disks; int raid_disks = conf->raid_disks;
int data_disks = raid_disks - 2; int data_disks = raid_disks - 2;
if (sector_nr >= mddev->size <<1) if (sector_nr >= mddev->size <<1) {
/* just being told to finish up .. nothing to do */ /* just being told to finish up .. nothing much to do */
unplug_slaves(mddev);
return 0; return 0;
}
x = sector_nr; x = sector_nr;
chunk_offset = sector_div(x, sectors_per_chunk); chunk_offset = sector_div(x, sectors_per_chunk);
...@@ -1635,6 +1663,8 @@ static void raid6d (mddev_t *mddev) ...@@ -1635,6 +1663,8 @@ static void raid6d (mddev_t *mddev)
spin_unlock_irq(&conf->device_lock); spin_unlock_irq(&conf->device_lock);
unplug_slaves(mddev);
PRINTK("--- raid6d inactive\n"); PRINTK("--- raid6d inactive\n");
} }
......
...@@ -315,7 +315,7 @@ typedef struct mdk_thread_s { ...@@ -315,7 +315,7 @@ typedef struct mdk_thread_s {
#define THREAD_WAKEUP 0 #define THREAD_WAKEUP 0
#define __wait_event_lock_irq(wq, condition, lock) \ #define __wait_event_lock_irq(wq, condition, lock, cmd) \
do { \ do { \
wait_queue_t __wait; \ wait_queue_t __wait; \
init_waitqueue_entry(&__wait, current); \ init_waitqueue_entry(&__wait, current); \
...@@ -326,6 +326,7 @@ do { \ ...@@ -326,6 +326,7 @@ do { \
if (condition) \ if (condition) \
break; \ break; \
spin_unlock_irq(&lock); \ spin_unlock_irq(&lock); \
cmd; \
schedule(); \ schedule(); \
spin_lock_irq(&lock); \ spin_lock_irq(&lock); \
} \ } \
...@@ -333,11 +334,11 @@ do { \ ...@@ -333,11 +334,11 @@ do { \
remove_wait_queue(&wq, &__wait); \ remove_wait_queue(&wq, &__wait); \
} while (0) } while (0)
#define wait_event_lock_irq(wq, condition, lock) \ #define wait_event_lock_irq(wq, condition, lock, cmd) \
do { \ do { \
if (condition) \ if (condition) \
break; \ break; \
__wait_event_lock_irq(wq, condition, lock); \ __wait_event_lock_irq(wq, condition, lock, cmd); \
} while (0) } while (0)
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment