diff options
Diffstat (limited to 'drivers/md/bitmap.c')
-rw-r--r-- | drivers/md/bitmap.c | 60 |
1 files changed, 36 insertions, 24 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index b1d94eee3346..f02551f50bb5 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -553,7 +553,6 @@ static int bitmap_read_sb(struct bitmap *bitmap) | |||
553 | unsigned long sectors_reserved = 0; | 553 | unsigned long sectors_reserved = 0; |
554 | int err = -EINVAL; | 554 | int err = -EINVAL; |
555 | struct page *sb_page; | 555 | struct page *sb_page; |
556 | int cluster_setup_done = 0; | ||
557 | 556 | ||
558 | if (!bitmap->storage.file && !bitmap->mddev->bitmap_info.offset) { | 557 | if (!bitmap->storage.file && !bitmap->mddev->bitmap_info.offset) { |
559 | chunksize = 128 * 1024 * 1024; | 558 | chunksize = 128 * 1024 * 1024; |
@@ -570,6 +569,18 @@ static int bitmap_read_sb(struct bitmap *bitmap) | |||
570 | bitmap->storage.sb_page = sb_page; | 569 | bitmap->storage.sb_page = sb_page; |
571 | 570 | ||
572 | re_read: | 571 | re_read: |
572 | /* If cluster_slot is set, the cluster is setup */ | ||
573 | if (bitmap->cluster_slot >= 0) { | ||
574 | long long bm_blocks; | ||
575 | |||
576 | bm_blocks = bitmap->mddev->resync_max_sectors / (bitmap->mddev->bitmap_info.chunksize >> 9); | ||
577 | bm_blocks = bm_blocks << 3; | ||
578 | bm_blocks = DIV_ROUND_UP(bm_blocks, 4096); | ||
579 | bitmap->mddev->bitmap_info.offset += bitmap->cluster_slot * (bm_blocks << 3); | ||
580 | pr_info("%s:%d bm slot: %d offset: %llu\n", __func__, __LINE__, | ||
581 | bitmap->cluster_slot, (unsigned long long)bitmap->mddev->bitmap_info.offset); | ||
582 | } | ||
583 | |||
573 | if (bitmap->storage.file) { | 584 | if (bitmap->storage.file) { |
574 | loff_t isize = i_size_read(bitmap->storage.file->f_mapping->host); | 585 | loff_t isize = i_size_read(bitmap->storage.file->f_mapping->host); |
575 | int bytes = isize > PAGE_SIZE ? PAGE_SIZE : isize; | 586 | int bytes = isize > PAGE_SIZE ? PAGE_SIZE : isize; |
@@ -650,14 +661,9 @@ re_read: | |||
650 | 661 | ||
651 | out: | 662 | out: |
652 | kunmap_atomic(sb); | 663 | kunmap_atomic(sb); |
653 | if (nodes && !cluster_setup_done) { | 664 | /* Assiging chunksize is required for "re_read" */ |
654 | sector_t bm_blocks; | 665 | bitmap->mddev->bitmap_info.chunksize = chunksize; |
655 | 666 | if (nodes && (bitmap->cluster_slot < 0)) { | |
656 | bm_blocks = sector_div(bitmap->mddev->resync_max_sectors, (chunksize >> 9)); | ||
657 | bm_blocks = bm_blocks << 3; | ||
658 | /* We have bitmap supers at 4k boundaries, hence this | ||
659 | * is hardcoded */ | ||
660 | bm_blocks = DIV_ROUND_UP(bm_blocks, 4096); | ||
661 | err = md_setup_cluster(bitmap->mddev, nodes); | 667 | err = md_setup_cluster(bitmap->mddev, nodes); |
662 | if (err) { | 668 | if (err) { |
663 | pr_err("%s: Could not setup cluster service (%d)\n", | 669 | pr_err("%s: Could not setup cluster service (%d)\n", |
@@ -665,12 +671,9 @@ out: | |||
665 | goto out_no_sb; | 671 | goto out_no_sb; |
666 | } | 672 | } |
667 | bitmap->cluster_slot = md_cluster_ops->slot_number(bitmap->mddev); | 673 | bitmap->cluster_slot = md_cluster_ops->slot_number(bitmap->mddev); |
668 | bitmap->mddev->bitmap_info.offset += | ||
669 | bitmap->cluster_slot * (bm_blocks << 3); | ||
670 | pr_info("%s:%d bm slot: %d offset: %llu\n", __func__, __LINE__, | 674 | pr_info("%s:%d bm slot: %d offset: %llu\n", __func__, __LINE__, |
671 | bitmap->cluster_slot, | 675 | bitmap->cluster_slot, |
672 | (unsigned long long)bitmap->mddev->bitmap_info.offset); | 676 | (unsigned long long)bitmap->mddev->bitmap_info.offset); |
673 | cluster_setup_done = 1; | ||
674 | goto re_read; | 677 | goto re_read; |
675 | } | 678 | } |
676 | 679 | ||
@@ -687,7 +690,7 @@ out_no_sb: | |||
687 | bitmap->mddev->bitmap_info.space = sectors_reserved; | 690 | bitmap->mddev->bitmap_info.space = sectors_reserved; |
688 | if (err) { | 691 | if (err) { |
689 | bitmap_print_sb(bitmap); | 692 | bitmap_print_sb(bitmap); |
690 | if (cluster_setup_done) | 693 | if (bitmap->cluster_slot < 0) |
691 | md_cluster_stop(bitmap->mddev); | 694 | md_cluster_stop(bitmap->mddev); |
692 | } | 695 | } |
693 | return err; | 696 | return err; |
@@ -1639,7 +1642,8 @@ static void bitmap_free(struct bitmap *bitmap) | |||
1639 | if (!bitmap) /* there was no bitmap */ | 1642 | if (!bitmap) /* there was no bitmap */ |
1640 | return; | 1643 | return; |
1641 | 1644 | ||
1642 | if (mddev_is_clustered(bitmap->mddev) && bitmap->mddev->cluster_info) | 1645 | if (mddev_is_clustered(bitmap->mddev) && bitmap->mddev->cluster_info && |
1646 | bitmap->cluster_slot == md_cluster_ops->slot_number(bitmap->mddev)) | ||
1643 | md_cluster_stop(bitmap->mddev); | 1647 | md_cluster_stop(bitmap->mddev); |
1644 | 1648 | ||
1645 | /* Shouldn't be needed - but just in case.... */ | 1649 | /* Shouldn't be needed - but just in case.... */ |
@@ -1687,7 +1691,7 @@ void bitmap_destroy(struct mddev *mddev) | |||
1687 | * initialize the bitmap structure | 1691 | * initialize the bitmap structure |
1688 | * if this returns an error, bitmap_destroy must be called to do clean up | 1692 | * if this returns an error, bitmap_destroy must be called to do clean up |
1689 | */ | 1693 | */ |
1690 | int bitmap_create(struct mddev *mddev) | 1694 | struct bitmap *bitmap_create(struct mddev *mddev, int slot) |
1691 | { | 1695 | { |
1692 | struct bitmap *bitmap; | 1696 | struct bitmap *bitmap; |
1693 | sector_t blocks = mddev->resync_max_sectors; | 1697 | sector_t blocks = mddev->resync_max_sectors; |
@@ -1701,7 +1705,7 @@ int bitmap_create(struct mddev *mddev) | |||
1701 | 1705 | ||
1702 | bitmap = kzalloc(sizeof(*bitmap), GFP_KERNEL); | 1706 | bitmap = kzalloc(sizeof(*bitmap), GFP_KERNEL); |
1703 | if (!bitmap) | 1707 | if (!bitmap) |
1704 | return -ENOMEM; | 1708 | return ERR_PTR(-ENOMEM); |
1705 | 1709 | ||
1706 | spin_lock_init(&bitmap->counts.lock); | 1710 | spin_lock_init(&bitmap->counts.lock); |
1707 | atomic_set(&bitmap->pending_writes, 0); | 1711 | atomic_set(&bitmap->pending_writes, 0); |
@@ -1710,6 +1714,7 @@ int bitmap_create(struct mddev *mddev) | |||
1710 | init_waitqueue_head(&bitmap->behind_wait); | 1714 | init_waitqueue_head(&bitmap->behind_wait); |
1711 | 1715 | ||
1712 | bitmap->mddev = mddev; | 1716 | bitmap->mddev = mddev; |
1717 | bitmap->cluster_slot = slot; | ||
1713 | 1718 | ||
1714 | if (mddev->kobj.sd) | 1719 | if (mddev->kobj.sd) |
1715 | bm = sysfs_get_dirent(mddev->kobj.sd, "bitmap"); | 1720 | bm = sysfs_get_dirent(mddev->kobj.sd, "bitmap"); |
@@ -1757,12 +1762,14 @@ int bitmap_create(struct mddev *mddev) | |||
1757 | printk(KERN_INFO "created bitmap (%lu pages) for device %s\n", | 1762 | printk(KERN_INFO "created bitmap (%lu pages) for device %s\n", |
1758 | bitmap->counts.pages, bmname(bitmap)); | 1763 | bitmap->counts.pages, bmname(bitmap)); |
1759 | 1764 | ||
1760 | mddev->bitmap = bitmap; | 1765 | err = test_bit(BITMAP_WRITE_ERROR, &bitmap->flags) ? -EIO : 0; |
1761 | return test_bit(BITMAP_WRITE_ERROR, &bitmap->flags) ? -EIO : 0; | 1766 | if (err) |
1767 | goto error; | ||
1762 | 1768 | ||
1769 | return bitmap; | ||
1763 | error: | 1770 | error: |
1764 | bitmap_free(bitmap); | 1771 | bitmap_free(bitmap); |
1765 | return err; | 1772 | return ERR_PTR(err); |
1766 | } | 1773 | } |
1767 | 1774 | ||
1768 | int bitmap_load(struct mddev *mddev) | 1775 | int bitmap_load(struct mddev *mddev) |
@@ -2073,13 +2080,18 @@ location_store(struct mddev *mddev, const char *buf, size_t len) | |||
2073 | return -EINVAL; | 2080 | return -EINVAL; |
2074 | mddev->bitmap_info.offset = offset; | 2081 | mddev->bitmap_info.offset = offset; |
2075 | if (mddev->pers) { | 2082 | if (mddev->pers) { |
2083 | struct bitmap *bitmap; | ||
2076 | mddev->pers->quiesce(mddev, 1); | 2084 | mddev->pers->quiesce(mddev, 1); |
2077 | rv = bitmap_create(mddev); | 2085 | bitmap = bitmap_create(mddev, -1); |
2078 | if (!rv) | 2086 | if (IS_ERR(bitmap)) |
2087 | rv = PTR_ERR(bitmap); | ||
2088 | else { | ||
2089 | mddev->bitmap = bitmap; | ||
2079 | rv = bitmap_load(mddev); | 2090 | rv = bitmap_load(mddev); |
2080 | if (rv) { | 2091 | if (rv) { |
2081 | bitmap_destroy(mddev); | 2092 | bitmap_destroy(mddev); |
2082 | mddev->bitmap_info.offset = 0; | 2093 | mddev->bitmap_info.offset = 0; |
2094 | } | ||
2083 | } | 2095 | } |
2084 | mddev->pers->quiesce(mddev, 0); | 2096 | mddev->pers->quiesce(mddev, 0); |
2085 | if (rv) | 2097 | if (rv) |