diff options
author | David S. Miller <davem@davemloft.net> | 2008-06-10 02:22:26 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-06-10 02:22:26 -0700 |
commit | 65b53e4cc90e59936733b3b95b9451d2ca47528d (patch) | |
tree | 29932718192962671c48c3fd1ea017a6112459e8 /drivers/md/raid1.c | |
parent | 788c0a53164c05c5ccdb1472474372b72ba74644 (diff) | |
parent | 2e761e0532a784816e7e822dbaaece8c5d4be14d (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
drivers/net/tg3.c
drivers/net/wireless/rt2x00/rt2x00dev.c
net/mac80211/ieee80211_i.h
Diffstat (limited to 'drivers/md/raid1.c')
-rw-r--r-- | drivers/md/raid1.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index ac409b7d83f5..c610b947218a 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -773,7 +773,7 @@ static int make_request(struct request_queue *q, struct bio * bio) r1bio_t *r1_bio; struct bio *read_bio; int i, targets = 0, disks; - struct bitmap *bitmap = mddev->bitmap; + struct bitmap *bitmap; unsigned long flags; struct bio_list bl; struct page **behind_pages = NULL; @@ -802,6 +802,8 @@ static int make_request(struct request_queue *q, struct bio * bio) wait_barrier(conf); + bitmap = mddev->bitmap; + disk_stat_inc(mddev->gendisk, ios[rw]); disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio)); @@ -1025,7 +1027,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) /* * if recovery is running, make sure it aborts. */ - set_bit(MD_RECOVERY_ERR, &mddev->recovery); + set_bit(MD_RECOVERY_INTR, &mddev->recovery); } else set_bit(Faulty, &rdev->flags); set_bit(MD_CHANGE_DEVS, &mddev->flags); @@ -1146,6 +1148,14 @@ static int raid1_remove_disk(mddev_t *mddev, int number) err = -EBUSY; goto abort; } + /* Only remove non-faulty devices is recovery + * is not possible. + */ + if (!test_bit(Faulty, &rdev->flags) && + mddev->degraded < conf->raid_disks) { + err = -EBUSY; + goto abort; + } p->rdev = NULL; synchronize_rcu(); if (atomic_read(&rdev->nr_pending)) { @@ -1282,6 +1292,7 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) rdev_dec_pending(conf->mirrors[i].rdev, mddev); } else { /* fixup the bio for reuse */ + int size; sbio->bi_vcnt = vcnt; sbio->bi_size = r1_bio->sectors << 9; sbio->bi_idx = 0; @@ -1295,10 +1306,20 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) sbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset; sbio->bi_bdev = conf->mirrors[i].rdev->bdev; - for (j = 0; j < vcnt ; j++) - memcpy(page_address(sbio->bi_io_vec[j].bv_page), + size = sbio->bi_size; + for (j = 0; j < vcnt ; j++) { + struct bio_vec *bi; + bi = &sbio->bi_io_vec[j]; + bi->bv_offset = 0; + if (size > PAGE_SIZE) + bi->bv_len = PAGE_SIZE; + else + bi->bv_len = size; + size -= PAGE_SIZE; + memcpy(page_address(bi->bv_page), page_address(pbio->bi_io_vec[j].bv_page), PAGE_SIZE); + } } } |