diff options
Diffstat (limited to 'drivers/md/bitmap.c')
-rw-r--r-- | drivers/md/bitmap.c | 49 |
1 files changed, 39 insertions, 10 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 719943763391..f8a9f7ab2cb8 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -16,6 +16,7 @@ | |||
16 | * wait if count gets too high, wake when it drops to half. | 16 | * wait if count gets too high, wake when it drops to half. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/blkdev.h> | ||
19 | #include <linux/module.h> | 20 | #include <linux/module.h> |
20 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
@@ -26,8 +27,8 @@ | |||
26 | #include <linux/file.h> | 27 | #include <linux/file.h> |
27 | #include <linux/mount.h> | 28 | #include <linux/mount.h> |
28 | #include <linux/buffer_head.h> | 29 | #include <linux/buffer_head.h> |
29 | #include <linux/raid/md.h> | 30 | #include "md.h" |
30 | #include <linux/raid/bitmap.h> | 31 | #include "bitmap.h" |
31 | 32 | ||
32 | /* debug macros */ | 33 | /* debug macros */ |
33 | 34 | ||
@@ -111,9 +112,10 @@ static int bitmap_checkpage(struct bitmap *bitmap, unsigned long page, int creat | |||
111 | unsigned char *mappage; | 112 | unsigned char *mappage; |
112 | 113 | ||
113 | if (page >= bitmap->pages) { | 114 | if (page >= bitmap->pages) { |
114 | printk(KERN_ALERT | 115 | /* This can happen if bitmap_start_sync goes beyond |
115 | "%s: invalid bitmap page request: %lu (> %lu)\n", | 116 | * End-of-device while looking for a whole page. |
116 | bmname(bitmap), page, bitmap->pages-1); | 117 | * It is harmless. |
118 | */ | ||
117 | return -EINVAL; | 119 | return -EINVAL; |
118 | } | 120 | } |
119 | 121 | ||
@@ -265,7 +267,6 @@ static mdk_rdev_t *next_active_rdev(mdk_rdev_t *rdev, mddev_t *mddev) | |||
265 | list_for_each_continue_rcu(pos, &mddev->disks) { | 267 | list_for_each_continue_rcu(pos, &mddev->disks) { |
266 | rdev = list_entry(pos, mdk_rdev_t, same_set); | 268 | rdev = list_entry(pos, mdk_rdev_t, same_set); |
267 | if (rdev->raid_disk >= 0 && | 269 | if (rdev->raid_disk >= 0 && |
268 | test_bit(In_sync, &rdev->flags) && | ||
269 | !test_bit(Faulty, &rdev->flags)) { | 270 | !test_bit(Faulty, &rdev->flags)) { |
270 | /* this is a usable devices */ | 271 | /* this is a usable devices */ |
271 | atomic_inc(&rdev->nr_pending); | 272 | atomic_inc(&rdev->nr_pending); |
@@ -297,7 +298,7 @@ static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait) | |||
297 | + size/512 > 0) | 298 | + size/512 > 0) |
298 | /* bitmap runs in to metadata */ | 299 | /* bitmap runs in to metadata */ |
299 | goto bad_alignment; | 300 | goto bad_alignment; |
300 | if (rdev->data_offset + mddev->size*2 | 301 | if (rdev->data_offset + mddev->dev_sectors |
301 | > rdev->sb_start + bitmap->offset) | 302 | > rdev->sb_start + bitmap->offset) |
302 | /* data runs in to bitmap */ | 303 | /* data runs in to bitmap */ |
303 | goto bad_alignment; | 304 | goto bad_alignment; |
@@ -570,7 +571,7 @@ static int bitmap_read_sb(struct bitmap *bitmap) | |||
570 | else if (le32_to_cpu(sb->version) < BITMAP_MAJOR_LO || | 571 | else if (le32_to_cpu(sb->version) < BITMAP_MAJOR_LO || |
571 | le32_to_cpu(sb->version) > BITMAP_MAJOR_HI) | 572 | le32_to_cpu(sb->version) > BITMAP_MAJOR_HI) |
572 | reason = "unrecognized superblock version"; | 573 | reason = "unrecognized superblock version"; |
573 | else if (chunksize < PAGE_SIZE) | 574 | else if (chunksize < 512) |
574 | reason = "bitmap chunksize too small"; | 575 | reason = "bitmap chunksize too small"; |
575 | else if ((1 << ffz(~chunksize)) != chunksize) | 576 | else if ((1 << ffz(~chunksize)) != chunksize) |
576 | reason = "bitmap chunksize not a power of 2"; | 577 | reason = "bitmap chunksize not a power of 2"; |
@@ -1306,6 +1307,9 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto | |||
1306 | PRINTK(KERN_DEBUG "dec write-behind count %d/%d\n", | 1307 | PRINTK(KERN_DEBUG "dec write-behind count %d/%d\n", |
1307 | atomic_read(&bitmap->behind_writes), bitmap->max_write_behind); | 1308 | atomic_read(&bitmap->behind_writes), bitmap->max_write_behind); |
1308 | } | 1309 | } |
1310 | if (bitmap->mddev->degraded) | ||
1311 | /* Never clear bits or update events_cleared when degraded */ | ||
1312 | success = 0; | ||
1309 | 1313 | ||
1310 | while (sectors) { | 1314 | while (sectors) { |
1311 | int blocks; | 1315 | int blocks; |
@@ -1345,8 +1349,8 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto | |||
1345 | } | 1349 | } |
1346 | } | 1350 | } |
1347 | 1351 | ||
1348 | int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks, | 1352 | static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks, |
1349 | int degraded) | 1353 | int degraded) |
1350 | { | 1354 | { |
1351 | bitmap_counter_t *bmc; | 1355 | bitmap_counter_t *bmc; |
1352 | int rv; | 1356 | int rv; |
@@ -1374,6 +1378,29 @@ int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks, | |||
1374 | return rv; | 1378 | return rv; |
1375 | } | 1379 | } |
1376 | 1380 | ||
1381 | int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks, | ||
1382 | int degraded) | ||
1383 | { | ||
1384 | /* bitmap_start_sync must always report on multiples of whole | ||
1385 | * pages, otherwise resync (which is very PAGE_SIZE based) will | ||
1386 | * get confused. | ||
1387 | * So call __bitmap_start_sync repeatedly (if needed) until | ||
1388 | * At least PAGE_SIZE>>9 blocks are covered. | ||
1389 | * Return the 'or' of the result. | ||
1390 | */ | ||
1391 | int rv = 0; | ||
1392 | int blocks1; | ||
1393 | |||
1394 | *blocks = 0; | ||
1395 | while (*blocks < (PAGE_SIZE>>9)) { | ||
1396 | rv |= __bitmap_start_sync(bitmap, offset, | ||
1397 | &blocks1, degraded); | ||
1398 | offset += blocks1; | ||
1399 | *blocks += blocks1; | ||
1400 | } | ||
1401 | return rv; | ||
1402 | } | ||
1403 | |||
1377 | void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted) | 1404 | void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted) |
1378 | { | 1405 | { |
1379 | bitmap_counter_t *bmc; | 1406 | bitmap_counter_t *bmc; |
@@ -1443,6 +1470,8 @@ void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector) | |||
1443 | wait_event(bitmap->mddev->recovery_wait, | 1470 | wait_event(bitmap->mddev->recovery_wait, |
1444 | atomic_read(&bitmap->mddev->recovery_active) == 0); | 1471 | atomic_read(&bitmap->mddev->recovery_active) == 0); |
1445 | 1472 | ||
1473 | bitmap->mddev->curr_resync_completed = bitmap->mddev->curr_resync; | ||
1474 | set_bit(MD_CHANGE_CLEAN, &bitmap->mddev->flags); | ||
1446 | sector &= ~((1ULL << CHUNK_BLOCK_SHIFT(bitmap)) - 1); | 1475 | sector &= ~((1ULL << CHUNK_BLOCK_SHIFT(bitmap)) - 1); |
1447 | s = 0; | 1476 | s = 0; |
1448 | while (s < sector && s < bitmap->mddev->resync_max_sectors) { | 1477 | while (s < sector && s < bitmap->mddev->resync_max_sectors) { |