Commit f57252ba authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[PATCH] md: assorted minor md/raid1 fixes

1/ rationalise read_balance and "map" in raid1.  Discard map and
   tidyup the interface to read_balance so it can be used instead.

2/ use offsetof rather than a caclulation to find the size of an
   structure with a var-length array at the end.

3/ remove some meaningless #defines 

4/ use printk_ratelimit to limit reports of failed sectors being redirected.
Signed-off-by: default avatarNeil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 32c31806
...@@ -24,10 +24,6 @@ ...@@ -24,10 +24,6 @@
#include <linux/raid/raid1.h> #include <linux/raid/raid1.h>
#define MAJOR_NR MD_MAJOR
#define MD_DRIVER
#define MD_PERSONALITY
/* /*
* Number of guaranteed r1bios in case of extreme VM load: * Number of guaranteed r1bios in case of extreme VM load:
*/ */
...@@ -44,13 +40,12 @@ static void * r1bio_pool_alloc(int gfp_flags, void *data) ...@@ -44,13 +40,12 @@ static void * r1bio_pool_alloc(int gfp_flags, void *data)
{ {
struct pool_info *pi = data; struct pool_info *pi = data;
r1bio_t *r1_bio; r1bio_t *r1_bio;
int size = offsetof(r1bio_t, bios[pi->raid_disks]);
/* allocate a r1bio with room for raid_disks entries in the bios array */ /* allocate a r1bio with room for raid_disks entries in the bios array */
r1_bio = kmalloc(sizeof(r1bio_t) + sizeof(struct bio*)*pi->raid_disks, r1_bio = kmalloc(size, gfp_flags);
gfp_flags);
if (r1_bio) if (r1_bio)
memset(r1_bio, 0, sizeof(*r1_bio) + memset(r1_bio, 0, size);
sizeof(struct bio*) * pi->raid_disks);
else else
unplug_slaves(pi->mddev); unplug_slaves(pi->mddev);
...@@ -104,7 +99,7 @@ static void * r1buf_pool_alloc(int gfp_flags, void *data) ...@@ -104,7 +99,7 @@ static void * r1buf_pool_alloc(int gfp_flags, void *data)
bio->bi_io_vec[i].bv_page = page; bio->bi_io_vec[i].bv_page = page;
} }
r1_bio->master_bio = bio; r1_bio->master_bio = NULL;
return r1_bio; return r1_bio;
...@@ -189,32 +184,6 @@ static inline void put_buf(r1bio_t *r1_bio) ...@@ -189,32 +184,6 @@ static inline void put_buf(r1bio_t *r1_bio)
spin_unlock_irqrestore(&conf->resync_lock, flags); spin_unlock_irqrestore(&conf->resync_lock, flags);
} }
static int map(mddev_t *mddev, mdk_rdev_t **rdevp)
{
conf_t *conf = mddev_to_conf(mddev);
int i, disks = conf->raid_disks;
/*
* Later we do read balancing on the read side
* now we use the first available disk.
*/
spin_lock_irq(&conf->device_lock);
for (i = 0; i < disks; i++) {
mdk_rdev_t *rdev = conf->mirrors[i].rdev;
if (rdev && rdev->in_sync) {
*rdevp = rdev;
atomic_inc(&rdev->nr_pending);
spin_unlock_irq(&conf->device_lock);
return i;
}
}
spin_unlock_irq(&conf->device_lock);
printk(KERN_ERR "raid1_map(): huh, no more operational devices?\n");
return -1;
}
static void reschedule_retry(r1bio_t *r1_bio) static void reschedule_retry(r1bio_t *r1_bio)
{ {
unsigned long flags; unsigned long flags;
...@@ -292,8 +261,9 @@ static int raid1_end_read_request(struct bio *bio, unsigned int bytes_done, int ...@@ -292,8 +261,9 @@ static int raid1_end_read_request(struct bio *bio, unsigned int bytes_done, int
* oops, read error: * oops, read error:
*/ */
char b[BDEVNAME_SIZE]; char b[BDEVNAME_SIZE];
printk(KERN_ERR "raid1: %s: rescheduling sector %llu\n", if (printk_ratelimit())
bdevname(conf->mirrors[mirror].rdev->bdev,b), (unsigned long long)r1_bio->sector); printk(KERN_ERR "raid1: %s: rescheduling sector %llu\n",
bdevname(conf->mirrors[mirror].rdev->bdev,b), (unsigned long long)r1_bio->sector);
reschedule_retry(r1_bio); reschedule_retry(r1_bio);
} }
...@@ -363,11 +333,11 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int ...@@ -363,11 +333,11 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
* *
* The rdev for the device selected will have nr_pending incremented. * The rdev for the device selected will have nr_pending incremented.
*/ */
static int read_balance(conf_t *conf, struct bio *bio, r1bio_t *r1_bio) static int read_balance(conf_t *conf, r1bio_t *r1_bio)
{ {
const unsigned long this_sector = r1_bio->sector; const unsigned long this_sector = r1_bio->sector;
int new_disk = conf->last_used, disk = new_disk; int new_disk = conf->last_used, disk = new_disk;
const int sectors = bio->bi_size >> 9; const int sectors = r1_bio->sectors;
sector_t new_distance, current_distance; sector_t new_distance, current_distance;
spin_lock_irq(&conf->device_lock); spin_lock_irq(&conf->device_lock);
...@@ -378,14 +348,14 @@ static int read_balance(conf_t *conf, struct bio *bio, r1bio_t *r1_bio) ...@@ -378,14 +348,14 @@ static int read_balance(conf_t *conf, struct bio *bio, r1bio_t *r1_bio)
*/ */
if (conf->mddev->recovery_cp < MaxSector && if (conf->mddev->recovery_cp < MaxSector &&
(this_sector + sectors >= conf->next_resync)) { (this_sector + sectors >= conf->next_resync)) {
/* make sure that disk is operational */ /* Choose the first operation device, for consistancy */
new_disk = 0; new_disk = 0;
while (!conf->mirrors[new_disk].rdev || while (!conf->mirrors[new_disk].rdev ||
!conf->mirrors[new_disk].rdev->in_sync) { !conf->mirrors[new_disk].rdev->in_sync) {
new_disk++; new_disk++;
if (new_disk == conf->raid_disks) { if (new_disk == conf->raid_disks) {
new_disk = 0; new_disk = -1;
break; break;
} }
} }
...@@ -400,7 +370,7 @@ static int read_balance(conf_t *conf, struct bio *bio, r1bio_t *r1_bio) ...@@ -400,7 +370,7 @@ static int read_balance(conf_t *conf, struct bio *bio, r1bio_t *r1_bio)
new_disk = conf->raid_disks; new_disk = conf->raid_disks;
new_disk--; new_disk--;
if (new_disk == disk) { if (new_disk == disk) {
new_disk = conf->last_used; new_disk = -1;
goto rb_out; goto rb_out;
} }
} }
...@@ -440,13 +410,13 @@ static int read_balance(conf_t *conf, struct bio *bio, r1bio_t *r1_bio) ...@@ -440,13 +410,13 @@ static int read_balance(conf_t *conf, struct bio *bio, r1bio_t *r1_bio)
} while (disk != conf->last_used); } while (disk != conf->last_used);
rb_out: rb_out:
r1_bio->read_disk = new_disk;
conf->next_seq_sect = this_sector + sectors;
conf->last_used = new_disk;
if (conf->mirrors[new_disk].rdev) if (new_disk >= 0) {
conf->next_seq_sect = this_sector + sectors;
conf->last_used = new_disk;
atomic_inc(&conf->mirrors[new_disk].rdev->nr_pending); atomic_inc(&conf->mirrors[new_disk].rdev->nr_pending);
}
spin_unlock_irq(&conf->device_lock); spin_unlock_irq(&conf->device_lock);
return new_disk; return new_disk;
...@@ -571,15 +541,26 @@ static int make_request(request_queue_t *q, struct bio * bio) ...@@ -571,15 +541,26 @@ static int make_request(request_queue_t *q, struct bio * bio)
r1_bio->mddev = mddev; r1_bio->mddev = mddev;
r1_bio->sector = bio->bi_sector; r1_bio->sector = bio->bi_sector;
r1_bio->state = 0;
if (bio_data_dir(bio) == READ) { if (bio_data_dir(bio) == READ) {
/* /*
* read balancing logic: * read balancing logic:
*/ */
mirror = conf->mirrors + read_balance(conf, bio, r1_bio); int rdisk = read_balance(conf, r1_bio);
if (rdisk < 0) {
/* couldn't find anywhere to read from */
raid_end_bio_io(r1_bio);
return 0;
}
mirror = conf->mirrors + rdisk;
r1_bio->read_disk = rdisk;
read_bio = bio_clone(bio, GFP_NOIO); read_bio = bio_clone(bio, GFP_NOIO);
r1_bio->bios[r1_bio->read_disk] = read_bio; r1_bio->bios[rdisk] = read_bio;
read_bio->bi_sector = r1_bio->sector + mirror->rdev->data_offset; read_bio->bi_sector = r1_bio->sector + mirror->rdev->data_offset;
read_bio->bi_bdev = mirror->rdev->bdev; read_bio->bi_bdev = mirror->rdev->bdev;
...@@ -951,7 +932,7 @@ static void raid1d(mddev_t *mddev) ...@@ -951,7 +932,7 @@ static void raid1d(mddev_t *mddev)
} else { } else {
int disk; int disk;
bio = r1_bio->bios[r1_bio->read_disk]; bio = r1_bio->bios[r1_bio->read_disk];
if ((disk=map(mddev, &rdev)) == -1) { if ((disk=read_balance(conf, r1_bio)) == -1) {
printk(KERN_ALERT "raid1: %s: unrecoverable I/O" printk(KERN_ALERT "raid1: %s: unrecoverable I/O"
" read error for block %llu\n", " read error for block %llu\n",
bdevname(bio->bi_bdev,b), bdevname(bio->bi_bdev,b),
...@@ -961,10 +942,12 @@ static void raid1d(mddev_t *mddev) ...@@ -961,10 +942,12 @@ static void raid1d(mddev_t *mddev)
r1_bio->bios[r1_bio->read_disk] = NULL; r1_bio->bios[r1_bio->read_disk] = NULL;
r1_bio->read_disk = disk; r1_bio->read_disk = disk;
r1_bio->bios[r1_bio->read_disk] = bio; r1_bio->bios[r1_bio->read_disk] = bio;
printk(KERN_ERR "raid1: %s: redirecting sector %llu to" rdev = conf->mirrors[disk].rdev;
" another mirror\n", if (printk_ratelimit())
bdevname(rdev->bdev,b), printk(KERN_ERR "raid1: %s: redirecting sector %llu to"
(unsigned long long)r1_bio->sector); " another mirror\n",
bdevname(rdev->bdev,b),
(unsigned long long)r1_bio->sector);
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;
......
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