diff options
-rw-r--r-- | drivers/md/bitmap.c | 60 | ||||
-rw-r--r-- | drivers/md/bitmap.h | 2 | ||||
-rw-r--r-- | drivers/md/md.c | 25 |
3 files changed, 56 insertions, 31 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) |
diff --git a/drivers/md/bitmap.h b/drivers/md/bitmap.h index 4e9acb08bbe0..67c7f77c67dd 100644 --- a/drivers/md/bitmap.h +++ b/drivers/md/bitmap.h | |||
@@ -233,7 +233,7 @@ struct bitmap { | |||
233 | /* the bitmap API */ | 233 | /* the bitmap API */ |
234 | 234 | ||
235 | /* these are used only by md/bitmap */ | 235 | /* these are used only by md/bitmap */ |
236 | int bitmap_create(struct mddev *mddev); | 236 | struct bitmap *bitmap_create(struct mddev *mddev, int slot); |
237 | int bitmap_load(struct mddev *mddev); | 237 | int bitmap_load(struct mddev *mddev); |
238 | void bitmap_flush(struct mddev *mddev); | 238 | void bitmap_flush(struct mddev *mddev); |
239 | void bitmap_destroy(struct mddev *mddev); | 239 | void bitmap_destroy(struct mddev *mddev); |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 71f655015385..630a9142a819 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -5076,10 +5076,16 @@ int md_run(struct mddev *mddev) | |||
5076 | } | 5076 | } |
5077 | if (err == 0 && pers->sync_request && | 5077 | if (err == 0 && pers->sync_request && |
5078 | (mddev->bitmap_info.file || mddev->bitmap_info.offset)) { | 5078 | (mddev->bitmap_info.file || mddev->bitmap_info.offset)) { |
5079 | err = bitmap_create(mddev); | 5079 | struct bitmap *bitmap; |
5080 | if (err) | 5080 | |
5081 | bitmap = bitmap_create(mddev, -1); | ||
5082 | if (IS_ERR(bitmap)) { | ||
5083 | err = PTR_ERR(bitmap); | ||
5081 | printk(KERN_ERR "%s: failed to create bitmap (%d)\n", | 5084 | printk(KERN_ERR "%s: failed to create bitmap (%d)\n", |
5082 | mdname(mddev), err); | 5085 | mdname(mddev), err); |
5086 | } else | ||
5087 | mddev->bitmap = bitmap; | ||
5088 | |||
5083 | } | 5089 | } |
5084 | if (err) { | 5090 | if (err) { |
5085 | mddev_detach(mddev); | 5091 | mddev_detach(mddev); |
@@ -6039,9 +6045,13 @@ static int set_bitmap_file(struct mddev *mddev, int fd) | |||
6039 | if (mddev->pers) { | 6045 | if (mddev->pers) { |
6040 | mddev->pers->quiesce(mddev, 1); | 6046 | mddev->pers->quiesce(mddev, 1); |
6041 | if (fd >= 0) { | 6047 | if (fd >= 0) { |
6042 | err = bitmap_create(mddev); | 6048 | struct bitmap *bitmap; |
6043 | if (!err) | 6049 | |
6050 | bitmap = bitmap_create(mddev, -1); | ||
6051 | if (!IS_ERR(bitmap)) { | ||
6052 | mddev->bitmap = bitmap; | ||
6044 | err = bitmap_load(mddev); | 6053 | err = bitmap_load(mddev); |
6054 | } | ||
6045 | } | 6055 | } |
6046 | if (fd < 0 || err) { | 6056 | if (fd < 0 || err) { |
6047 | bitmap_destroy(mddev); | 6057 | bitmap_destroy(mddev); |
@@ -6306,6 +6316,7 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info) | |||
6306 | if (mddev->recovery || mddev->sync_thread) | 6316 | if (mddev->recovery || mddev->sync_thread) |
6307 | return -EBUSY; | 6317 | return -EBUSY; |
6308 | if (info->state & (1<<MD_SB_BITMAP_PRESENT)) { | 6318 | if (info->state & (1<<MD_SB_BITMAP_PRESENT)) { |
6319 | struct bitmap *bitmap; | ||
6309 | /* add the bitmap */ | 6320 | /* add the bitmap */ |
6310 | if (mddev->bitmap) | 6321 | if (mddev->bitmap) |
6311 | return -EEXIST; | 6322 | return -EEXIST; |
@@ -6316,9 +6327,11 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info) | |||
6316 | mddev->bitmap_info.space = | 6327 | mddev->bitmap_info.space = |
6317 | mddev->bitmap_info.default_space; | 6328 | mddev->bitmap_info.default_space; |
6318 | mddev->pers->quiesce(mddev, 1); | 6329 | mddev->pers->quiesce(mddev, 1); |
6319 | rv = bitmap_create(mddev); | 6330 | bitmap = bitmap_create(mddev, -1); |
6320 | if (!rv) | 6331 | if (!IS_ERR(bitmap)) { |
6332 | mddev->bitmap = bitmap; | ||
6321 | rv = bitmap_load(mddev); | 6333 | rv = bitmap_load(mddev); |
6334 | } | ||
6322 | if (rv) | 6335 | if (rv) |
6323 | bitmap_destroy(mddev); | 6336 | bitmap_destroy(mddev); |
6324 | mddev->pers->quiesce(mddev, 0); | 6337 | mddev->pers->quiesce(mddev, 0); |