diff options
Diffstat (limited to 'drivers/md/bitmap.c')
-rw-r--r-- | drivers/md/bitmap.c | 104 |
1 files changed, 92 insertions, 12 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 70bd738b8b99..574b09afedd3 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -534,6 +534,82 @@ void bitmap_print_sb(struct bitmap *bitmap) | |||
534 | kunmap_atomic(sb, KM_USER0); | 534 | kunmap_atomic(sb, KM_USER0); |
535 | } | 535 | } |
536 | 536 | ||
537 | /* | ||
538 | * bitmap_new_disk_sb | ||
539 | * @bitmap | ||
540 | * | ||
541 | * This function is somewhat the reverse of bitmap_read_sb. bitmap_read_sb | ||
542 | * reads and verifies the on-disk bitmap superblock and populates bitmap_info. | ||
543 | * This function verifies 'bitmap_info' and populates the on-disk bitmap | ||
544 | * structure, which is to be written to disk. | ||
545 | * | ||
546 | * Returns: 0 on success, -Exxx on error | ||
547 | */ | ||
548 | static int bitmap_new_disk_sb(struct bitmap *bitmap) | ||
549 | { | ||
550 | bitmap_super_t *sb; | ||
551 | unsigned long chunksize, daemon_sleep, write_behind; | ||
552 | int err = -EINVAL; | ||
553 | |||
554 | bitmap->sb_page = alloc_page(GFP_KERNEL); | ||
555 | if (IS_ERR(bitmap->sb_page)) { | ||
556 | err = PTR_ERR(bitmap->sb_page); | ||
557 | bitmap->sb_page = NULL; | ||
558 | return err; | ||
559 | } | ||
560 | bitmap->sb_page->index = 0; | ||
561 | |||
562 | sb = kmap_atomic(bitmap->sb_page, KM_USER0); | ||
563 | |||
564 | sb->magic = cpu_to_le32(BITMAP_MAGIC); | ||
565 | sb->version = cpu_to_le32(BITMAP_MAJOR_HI); | ||
566 | |||
567 | chunksize = bitmap->mddev->bitmap_info.chunksize; | ||
568 | BUG_ON(!chunksize); | ||
569 | if (!is_power_of_2(chunksize)) { | ||
570 | kunmap_atomic(sb, KM_USER0); | ||
571 | printk(KERN_ERR "bitmap chunksize not a power of 2\n"); | ||
572 | return -EINVAL; | ||
573 | } | ||
574 | sb->chunksize = cpu_to_le32(chunksize); | ||
575 | |||
576 | daemon_sleep = bitmap->mddev->bitmap_info.daemon_sleep; | ||
577 | if (!daemon_sleep || | ||
578 | (daemon_sleep < 1) || (daemon_sleep > MAX_SCHEDULE_TIMEOUT)) { | ||
579 | printk(KERN_INFO "Choosing daemon_sleep default (5 sec)\n"); | ||
580 | daemon_sleep = 5 * HZ; | ||
581 | } | ||
582 | sb->daemon_sleep = cpu_to_le32(daemon_sleep); | ||
583 | bitmap->mddev->bitmap_info.daemon_sleep = daemon_sleep; | ||
584 | |||
585 | /* | ||
586 | * FIXME: write_behind for RAID1. If not specified, what | ||
587 | * is a good choice? We choose COUNTER_MAX / 2 arbitrarily. | ||
588 | */ | ||
589 | write_behind = bitmap->mddev->bitmap_info.max_write_behind; | ||
590 | if (write_behind > COUNTER_MAX) | ||
591 | write_behind = COUNTER_MAX / 2; | ||
592 | sb->write_behind = cpu_to_le32(write_behind); | ||
593 | bitmap->mddev->bitmap_info.max_write_behind = write_behind; | ||
594 | |||
595 | /* keep the array size field of the bitmap superblock up to date */ | ||
596 | sb->sync_size = cpu_to_le64(bitmap->mddev->resync_max_sectors); | ||
597 | |||
598 | memcpy(sb->uuid, bitmap->mddev->uuid, 16); | ||
599 | |||
600 | bitmap->flags |= BITMAP_STALE; | ||
601 | sb->state |= cpu_to_le32(BITMAP_STALE); | ||
602 | bitmap->events_cleared = bitmap->mddev->events; | ||
603 | sb->events_cleared = cpu_to_le64(bitmap->mddev->events); | ||
604 | |||
605 | bitmap->flags |= BITMAP_HOSTENDIAN; | ||
606 | sb->version = cpu_to_le32(BITMAP_MAJOR_HOSTENDIAN); | ||
607 | |||
608 | kunmap_atomic(sb, KM_USER0); | ||
609 | |||
610 | return 0; | ||
611 | } | ||
612 | |||
537 | /* read the superblock from the bitmap file and initialize some bitmap fields */ | 613 | /* read the superblock from the bitmap file and initialize some bitmap fields */ |
538 | static int bitmap_read_sb(struct bitmap *bitmap) | 614 | static int bitmap_read_sb(struct bitmap *bitmap) |
539 | { | 615 | { |
@@ -575,7 +651,7 @@ static int bitmap_read_sb(struct bitmap *bitmap) | |||
575 | reason = "unrecognized superblock version"; | 651 | reason = "unrecognized superblock version"; |
576 | else if (chunksize < 512) | 652 | else if (chunksize < 512) |
577 | reason = "bitmap chunksize too small"; | 653 | reason = "bitmap chunksize too small"; |
578 | else if ((1 << ffz(~chunksize)) != chunksize) | 654 | else if (!is_power_of_2(chunksize)) |
579 | reason = "bitmap chunksize not a power of 2"; | 655 | reason = "bitmap chunksize not a power of 2"; |
580 | else if (daemon_sleep < 1 || daemon_sleep > MAX_SCHEDULE_TIMEOUT) | 656 | else if (daemon_sleep < 1 || daemon_sleep > MAX_SCHEDULE_TIMEOUT) |
581 | reason = "daemon sleep period out of range"; | 657 | reason = "daemon sleep period out of range"; |
@@ -1076,8 +1152,8 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) | |||
1076 | } | 1152 | } |
1077 | 1153 | ||
1078 | printk(KERN_INFO "%s: bitmap initialized from disk: " | 1154 | printk(KERN_INFO "%s: bitmap initialized from disk: " |
1079 | "read %lu/%lu pages, set %lu bits\n", | 1155 | "read %lu/%lu pages, set %lu of %lu bits\n", |
1080 | bmname(bitmap), bitmap->file_pages, num_pages, bit_cnt); | 1156 | bmname(bitmap), bitmap->file_pages, num_pages, bit_cnt, chunks); |
1081 | 1157 | ||
1082 | return 0; | 1158 | return 0; |
1083 | 1159 | ||
@@ -1332,7 +1408,7 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect | |||
1332 | return 0; | 1408 | return 0; |
1333 | } | 1409 | } |
1334 | 1410 | ||
1335 | if (unlikely((*bmc & COUNTER_MAX) == COUNTER_MAX)) { | 1411 | if (unlikely(COUNTER(*bmc) == COUNTER_MAX)) { |
1336 | DEFINE_WAIT(__wait); | 1412 | DEFINE_WAIT(__wait); |
1337 | /* note that it is safe to do the prepare_to_wait | 1413 | /* note that it is safe to do the prepare_to_wait |
1338 | * after the test as long as we do it before dropping | 1414 | * after the test as long as we do it before dropping |
@@ -1404,10 +1480,10 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto | |||
1404 | sysfs_notify_dirent_safe(bitmap->sysfs_can_clear); | 1480 | sysfs_notify_dirent_safe(bitmap->sysfs_can_clear); |
1405 | } | 1481 | } |
1406 | 1482 | ||
1407 | if (!success && ! (*bmc & NEEDED_MASK)) | 1483 | if (!success && !NEEDED(*bmc)) |
1408 | *bmc |= NEEDED_MASK; | 1484 | *bmc |= NEEDED_MASK; |
1409 | 1485 | ||
1410 | if ((*bmc & COUNTER_MAX) == COUNTER_MAX) | 1486 | if (COUNTER(*bmc) == COUNTER_MAX) |
1411 | wake_up(&bitmap->overflow_wait); | 1487 | wake_up(&bitmap->overflow_wait); |
1412 | 1488 | ||
1413 | (*bmc)--; | 1489 | (*bmc)--; |
@@ -1728,9 +1804,16 @@ int bitmap_create(mddev_t *mddev) | |||
1728 | vfs_fsync(file, 1); | 1804 | vfs_fsync(file, 1); |
1729 | } | 1805 | } |
1730 | /* read superblock from bitmap file (this sets mddev->bitmap_info.chunksize) */ | 1806 | /* read superblock from bitmap file (this sets mddev->bitmap_info.chunksize) */ |
1731 | if (!mddev->bitmap_info.external) | 1807 | if (!mddev->bitmap_info.external) { |
1732 | err = bitmap_read_sb(bitmap); | 1808 | /* |
1733 | else { | 1809 | * If 'MD_ARRAY_FIRST_USE' is set, then device-mapper is |
1810 | * instructing us to create a new on-disk bitmap instance. | ||
1811 | */ | ||
1812 | if (test_and_clear_bit(MD_ARRAY_FIRST_USE, &mddev->flags)) | ||
1813 | err = bitmap_new_disk_sb(bitmap); | ||
1814 | else | ||
1815 | err = bitmap_read_sb(bitmap); | ||
1816 | } else { | ||
1734 | err = 0; | 1817 | err = 0; |
1735 | if (mddev->bitmap_info.chunksize == 0 || | 1818 | if (mddev->bitmap_info.chunksize == 0 || |
1736 | mddev->bitmap_info.daemon_sleep == 0) | 1819 | mddev->bitmap_info.daemon_sleep == 0) |
@@ -1754,9 +1837,6 @@ int bitmap_create(mddev_t *mddev) | |||
1754 | bitmap->chunks = chunks; | 1837 | bitmap->chunks = chunks; |
1755 | bitmap->pages = pages; | 1838 | bitmap->pages = pages; |
1756 | bitmap->missing_pages = pages; | 1839 | bitmap->missing_pages = pages; |
1757 | bitmap->counter_bits = COUNTER_BITS; | ||
1758 | |||
1759 | bitmap->syncchunk = ~0UL; | ||
1760 | 1840 | ||
1761 | #ifdef INJECT_FATAL_FAULT_1 | 1841 | #ifdef INJECT_FATAL_FAULT_1 |
1762 | bitmap->bp = NULL; | 1842 | bitmap->bp = NULL; |