summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@cse.unsw.edu.au>2005-07-15 03:56:35 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-15 09:54:51 -0700
commit6a806c510de490318846b53bbfec463d02ca274b (patch)
tree7018abfd9db7856708bc2c578f48c30eab8855b1
parenta1287ba1ba810aae1f8b81e32560d5d3bf3ff9f0 (diff)
[PATCH] md/raid1: clear bitmap when fullsync completes
We need to be careful differentiating between a resync of a complete array, in which we can clear the bitmap, and a resync of a degraded array, in which we cannot. This patch cleans all that up. Cc: Paul Clements <paul.clements@steeleye.com> Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/md/bitmap.c9
-rw-r--r--drivers/md/raid1.c37
-rw-r--r--include/linux/raid/bitmap.h2
3 files changed, 25 insertions, 23 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 95980ad6b27..0c2ed99a383 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1345,7 +1345,8 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto
}
}
-int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks)
+int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
+ int degraded)
{
bitmap_counter_t *bmc;
int rv;
@@ -1362,8 +1363,10 @@ int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks)
rv = 1;
else if (NEEDED(*bmc)) {
rv = 1;
- *bmc |= RESYNC_MASK;
- *bmc &= ~NEEDED_MASK;
+ if (!degraded) { /* don't set/clear bits if degraded */
+ *bmc |= RESYNC_MASK;
+ *bmc &= ~NEEDED_MASK;
+ }
}
}
spin_unlock_irq(&bitmap->lock);
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index ff1dbec864a..5f253ee536b 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1126,21 +1126,19 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
* only be one in raid1 resync.
* We can find the current addess in mddev->curr_resync
*/
- if (!conf->fullsync) {
- if (mddev->curr_resync < max_sector)
- bitmap_end_sync(mddev->bitmap,
- mddev->curr_resync,
+ if (mddev->curr_resync < max_sector) /* aborted */
+ bitmap_end_sync(mddev->bitmap, mddev->curr_resync,
&sync_blocks, 1);
- bitmap_close_sync(mddev->bitmap);
- }
- if (mddev->curr_resync >= max_sector)
+ else /* completed sync */
conf->fullsync = 0;
+
+ bitmap_close_sync(mddev->bitmap);
close_sync(conf);
return 0;
}
- if (!conf->fullsync &&
- !bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks)) {
+ if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, mddev->degraded) &&
+ !conf->fullsync) {
/* We can skip this block, and probably several more */
*skipped = 1;
return sync_blocks;
@@ -1243,15 +1241,15 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
len = (max_sector - sector_nr) << 9;
if (len == 0)
break;
- if (!conf->fullsync) {
- if (sync_blocks == 0) {
- if (!bitmap_start_sync(mddev->bitmap,
- sector_nr, &sync_blocks))
- break;
- if (sync_blocks < (PAGE_SIZE>>9))
- BUG();
- if (len > (sync_blocks<<9)) len = sync_blocks<<9;
- }
+ if (sync_blocks == 0) {
+ if (!bitmap_start_sync(mddev->bitmap, sector_nr,
+ &sync_blocks, mddev->degraded) &&
+ !conf->fullsync)
+ break;
+ if (sync_blocks < (PAGE_SIZE>>9))
+ BUG();
+ if (len > (sync_blocks<<9))
+ len = sync_blocks<<9;
}
for (i=0 ; i < conf->raid_disks; i++) {
@@ -1264,7 +1262,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
while (i > 0) {
i--;
bio = r1_bio->bios[i];
- if (bio->bi_end_io==NULL) continue;
+ if (bio->bi_end_io==NULL)
+ continue;
/* remove last page from this bio */
bio->bi_vcnt--;
bio->bi_size -= len;
diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h
index e24b74b1115..6213e976ead 100644
--- a/include/linux/raid/bitmap.h
+++ b/include/linux/raid/bitmap.h
@@ -262,7 +262,7 @@ void bitmap_write_all(struct bitmap *bitmap);
int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors);
void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors,
int success);
-int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks);
+int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int degraded);
void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted);
void bitmap_close_sync(struct bitmap *bitmap);