Skip to content

Commit

Permalink
Merge tag 'md-3.5-fixes' of git://neil.brown.name/md
Browse files Browse the repository at this point in the history
Pull md fixes from NeilBrown:
 "md: collection of bug fixes for 3.5

  You go away for 2 weeks vacation and what do you get when you come
  back? Piles of bugs :-)

  Some found by inspection, some by testing, some during use in the
  field, and some while developing for the next window..."

* tag 'md-3.5-fixes' of git://neil.brown.name/md:
  md: fix up plugging (again).
  md: support re-add of recovering devices.
  md/raid1: fix bug in read_balance introduced by hot-replace
  raid5: delayed stripe fix
  md/raid456: When read error cannot be recovered, record bad block
  md: make 'name' arg to md_register_thread non-optional.
  md/raid10: fix failure when trying to repair a read error.
  md/raid5: fix refcount problem when blocked_rdev is set.
  md:Add blk_plug in sync_thread.
  md/raid5: In ops_run_io, inc nr_pending before calling md_wait_for_blocked_rdev
  md/raid5: Do not add data_offset before call to is_badblock
  md/raid5: prefer replacing failed devices over want-replacement devices.
  md/raid10: Don't try to recovery unmatched (and unused) chunks.
  • Loading branch information
Linus Torvalds committed Jul 3, 2012
2 parents 3bfd245 + b357f04 commit 2fb748d
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 42 deletions.
8 changes: 5 additions & 3 deletions drivers/md/md.c
Original file line number Diff line number Diff line change
Expand Up @@ -5784,8 +5784,7 @@ static int add_new_disk(struct mddev * mddev, mdu_disk_info_t *info)
super_types[mddev->major_version].
validate_super(mddev, rdev);
if ((info->state & (1<<MD_DISK_SYNC)) &&
(!test_bit(In_sync, &rdev->flags) ||
rdev->raid_disk != info->raid_disk)) {
rdev->raid_disk != info->raid_disk) {
/* This was a hot-add request, but events doesn't
* match, so reject it.
*/
Expand Down Expand Up @@ -6751,7 +6750,7 @@ struct md_thread *md_register_thread(void (*run) (struct mddev *), struct mddev
thread->tsk = kthread_run(md_thread, thread,
"%s_%s",
mdname(thread->mddev),
name ?: mddev->pers->name);
name);
if (IS_ERR(thread->tsk)) {
kfree(thread);
return NULL;
Expand Down Expand Up @@ -7298,6 +7297,7 @@ void md_do_sync(struct mddev *mddev)
int skipped = 0;
struct md_rdev *rdev;
char *desc;
struct blk_plug plug;

/* just incase thread restarts... */
if (test_bit(MD_RECOVERY_DONE, &mddev->recovery))
Expand Down Expand Up @@ -7447,6 +7447,7 @@ void md_do_sync(struct mddev *mddev)
}
mddev->curr_resync_completed = j;

blk_start_plug(&plug);
while (j < max_sectors) {
sector_t sectors;

Expand Down Expand Up @@ -7552,6 +7553,7 @@ void md_do_sync(struct mddev *mddev)
* this also signals 'finished resyncing' to md_stop
*/
out:
blk_finish_plug(&plug);
wait_event(mddev->recovery_wait, !atomic_read(&mddev->recovery_active));

/* tell personality that we are finished */
Expand Down
3 changes: 2 additions & 1 deletion drivers/md/multipath.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,8 @@ static int multipath_run (struct mddev *mddev)
}

{
mddev->thread = md_register_thread(multipathd, mddev, NULL);
mddev->thread = md_register_thread(multipathd, mddev,
"multipath");
if (!mddev->thread) {
printk(KERN_ERR "multipath: couldn't allocate thread"
" for %s\n", mdname(mddev));
Expand Down
13 changes: 5 additions & 8 deletions drivers/md/raid1.c
Original file line number Diff line number Diff line change
Expand Up @@ -517,8 +517,8 @@ static int read_balance(struct r1conf *conf, struct r1bio *r1_bio, int *max_sect
int bad_sectors;

int disk = start_disk + i;
if (disk >= conf->raid_disks)
disk -= conf->raid_disks;
if (disk >= conf->raid_disks * 2)
disk -= conf->raid_disks * 2;

rdev = rcu_dereference(conf->mirrors[disk].rdev);
if (r1_bio->bios[disk] == IO_BLOCKED
Expand Down Expand Up @@ -883,7 +883,6 @@ static void make_request(struct mddev *mddev, struct bio * bio)
const unsigned long do_sync = (bio->bi_rw & REQ_SYNC);
const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA));
struct md_rdev *blocked_rdev;
int plugged;
int first_clone;
int sectors_handled;
int max_sectors;
Expand Down Expand Up @@ -1034,7 +1033,6 @@ static void make_request(struct mddev *mddev, struct bio * bio)
* the bad blocks. Each set of writes gets it's own r1bio
* with a set of bios attached.
*/
plugged = mddev_check_plugged(mddev);

disks = conf->raid_disks * 2;
retry_write:
Expand Down Expand Up @@ -1191,6 +1189,8 @@ static void make_request(struct mddev *mddev, struct bio * bio)
bio_list_add(&conf->pending_bio_list, mbio);
conf->pending_count++;
spin_unlock_irqrestore(&conf->device_lock, flags);
if (!mddev_check_plugged(mddev))
md_wakeup_thread(mddev->thread);
}
/* Mustn't call r1_bio_write_done before this next test,
* as it could result in the bio being freed.
Expand All @@ -1213,9 +1213,6 @@ static void make_request(struct mddev *mddev, struct bio * bio)

/* In case raid1d snuck in to freeze_array */
wake_up(&conf->wait_barrier);

if (do_sync || !bitmap || !plugged)
md_wakeup_thread(mddev->thread);
}

static void status(struct seq_file *seq, struct mddev *mddev)
Expand Down Expand Up @@ -2621,7 +2618,7 @@ static struct r1conf *setup_conf(struct mddev *mddev)
goto abort;
}
err = -ENOMEM;
conf->thread = md_register_thread(raid1d, mddev, NULL);
conf->thread = md_register_thread(raid1d, mddev, "raid1");
if (!conf->thread) {
printk(KERN_ERR
"md/raid1:%s: couldn't allocate thread\n",
Expand Down
26 changes: 16 additions & 10 deletions drivers/md/raid10.c
Original file line number Diff line number Diff line change
Expand Up @@ -1039,7 +1039,6 @@ static void make_request(struct mddev *mddev, struct bio * bio)
const unsigned long do_fua = (bio->bi_rw & REQ_FUA);
unsigned long flags;
struct md_rdev *blocked_rdev;
int plugged;
int sectors_handled;
int max_sectors;
int sectors;
Expand Down Expand Up @@ -1239,7 +1238,6 @@ static void make_request(struct mddev *mddev, struct bio * bio)
* of r10_bios is recored in bio->bi_phys_segments just as with
* the read case.
*/
plugged = mddev_check_plugged(mddev);

r10_bio->read_slot = -1; /* make sure repl_bio gets freed */
raid10_find_phys(conf, r10_bio);
Expand Down Expand Up @@ -1396,6 +1394,8 @@ static void make_request(struct mddev *mddev, struct bio * bio)
bio_list_add(&conf->pending_bio_list, mbio);
conf->pending_count++;
spin_unlock_irqrestore(&conf->device_lock, flags);
if (!mddev_check_plugged(mddev, 0, 0))
md_wakeup_thread(mddev->thread);

if (!r10_bio->devs[i].repl_bio)
continue;
Expand Down Expand Up @@ -1423,6 +1423,8 @@ static void make_request(struct mddev *mddev, struct bio * bio)
bio_list_add(&conf->pending_bio_list, mbio);
conf->pending_count++;
spin_unlock_irqrestore(&conf->device_lock, flags);
if (!mddev_check_plugged(mddev))
md_wakeup_thread(mddev->thread);
}

/* Don't remove the bias on 'remaining' (one_write_done) until
Expand All @@ -1448,9 +1450,6 @@ static void make_request(struct mddev *mddev, struct bio * bio)

/* In case raid10d snuck in to freeze_array */
wake_up(&conf->wait_barrier);

if (do_sync || !mddev->bitmap || !plugged)
md_wakeup_thread(mddev->thread);
}

static void status(struct seq_file *seq, struct mddev *mddev)
Expand Down Expand Up @@ -2310,7 +2309,7 @@ static void fix_read_error(struct r10conf *conf, struct mddev *mddev, struct r10
if (r10_sync_page_io(rdev,
r10_bio->devs[sl].addr +
sect,
s<<9, conf->tmppage, WRITE)
s, conf->tmppage, WRITE)
== 0) {
/* Well, this device is dead */
printk(KERN_NOTICE
Expand Down Expand Up @@ -2349,7 +2348,7 @@ static void fix_read_error(struct r10conf *conf, struct mddev *mddev, struct r10
switch (r10_sync_page_io(rdev,
r10_bio->devs[sl].addr +
sect,
s<<9, conf->tmppage,
s, conf->tmppage,
READ)) {
case 0:
/* Well, this device is dead */
Expand Down Expand Up @@ -2512,7 +2511,7 @@ static void handle_read_error(struct mddev *mddev, struct r10bio *r10_bio)
slot = r10_bio->read_slot;
printk_ratelimited(
KERN_ERR
"md/raid10:%s: %s: redirecting"
"md/raid10:%s: %s: redirecting "
"sector %llu to another mirror\n",
mdname(mddev),
bdevname(rdev->bdev, b),
Expand Down Expand Up @@ -2661,7 +2660,8 @@ static void raid10d(struct mddev *mddev)
blk_start_plug(&plug);
for (;;) {

flush_pending_writes(conf);
if (atomic_read(&mddev->plug_cnt) == 0)
flush_pending_writes(conf);

spin_lock_irqsave(&conf->device_lock, flags);
if (list_empty(head)) {
Expand Down Expand Up @@ -2890,6 +2890,12 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
/* want to reconstruct this device */
rb2 = r10_bio;
sect = raid10_find_virt(conf, sector_nr, i);
if (sect >= mddev->resync_max_sectors) {
/* last stripe is not complete - don't
* try to recover this sector.
*/
continue;
}
/* Unless we are doing a full sync, or a replacement
* we only need to recover the block if it is set in
* the bitmap
Expand Down Expand Up @@ -3421,7 +3427,7 @@ static struct r10conf *setup_conf(struct mddev *mddev)
spin_lock_init(&conf->resync_lock);
init_waitqueue_head(&conf->wait_barrier);

conf->thread = md_register_thread(raid10d, mddev, NULL);
conf->thread = md_register_thread(raid10d, mddev, "raid10");
if (!conf->thread)
goto out;

Expand Down
Loading

0 comments on commit 2fb748d

Please sign in to comment.