aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/bitmap.c')
-rw-r--r--drivers/md/bitmap.c49
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
1348int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks, 1352static 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
1381int 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
1377void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted) 1404void 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) {