aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2012-08-14 05:46:59 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-11-09 08:05:51 -0500
commitfef45d297e447d710abcf0cd0bdbf8738ff469eb (patch)
treed4200c3cb2b5168d33566d6f9bf48da36d91f231
parent5af2e8ce2b463c2cc8e4a074f9d8f660ae7c1d8f (diff)
drbd: Write all pages of the bitmap after an online resize
We need to write the whole bitmap after we moved the meta data due to an online resize operation. With the support for one peta byte devices bitmap IO was optimized to only write out touched pages. This optimization must be turned off when writing the bitmap after an online resize. This issue was introduced with drbd-8.3.10. The impact of this bug is that after an online resize, the next resync could become larger than expected. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
-rw-r--r--drivers/block/drbd/drbd_bitmap.c16
-rw-r--r--drivers/block/drbd/drbd_int.h1
-rw-r--r--drivers/block/drbd/drbd_nl.c4
3 files changed, 18 insertions, 3 deletions
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index 33626e34c92a..4a076b2553e6 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -922,6 +922,7 @@ struct bm_aio_ctx {
922 unsigned flags; 922 unsigned flags;
923#define BM_AIO_COPY_PAGES 1 923#define BM_AIO_COPY_PAGES 1
924#define BM_AIO_WRITE_HINTED 2 924#define BM_AIO_WRITE_HINTED 2
925#define BM_WRITE_ALL_PAGES 4
925 int error; 926 int error;
926 struct kref kref; 927 struct kref kref;
927}; 928};
@@ -1096,7 +1097,9 @@ static int bm_rw(struct drbd_conf *mdev, int rw, unsigned flags, unsigned lazy_w
1096 !test_and_clear_bit(BM_PAGE_HINT_WRITEOUT, 1097 !test_and_clear_bit(BM_PAGE_HINT_WRITEOUT,
1097 &page_private(b->bm_pages[i]))) 1098 &page_private(b->bm_pages[i])))
1098 continue; 1099 continue;
1099 if (bm_test_page_unchanged(b->bm_pages[i])) { 1100
1101 if (!(flags & BM_WRITE_ALL_PAGES) &&
1102 bm_test_page_unchanged(b->bm_pages[i])) {
1100 dynamic_dev_dbg(DEV, "skipped bm write for idx %u\n", i); 1103 dynamic_dev_dbg(DEV, "skipped bm write for idx %u\n", i);
1101 continue; 1104 continue;
1102 } 1105 }
@@ -1181,6 +1184,17 @@ int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local)
1181} 1184}
1182 1185
1183/** 1186/**
1187 * drbd_bm_write_all() - Write the whole bitmap to its on disk location.
1188 * @mdev: DRBD device.
1189 *
1190 * Will write all pages.
1191 */
1192int drbd_bm_write_all(struct drbd_conf *mdev) __must_hold(local)
1193{
1194 return bm_rw(mdev, WRITE, BM_WRITE_ALL_PAGES, 0);
1195}
1196
1197/**
1184 * drbd_bm_lazy_write_out() - Write bitmap pages 0 to @upper_idx-1, if they have changed. 1198 * drbd_bm_lazy_write_out() - Write bitmap pages 0 to @upper_idx-1, if they have changed.
1185 * @mdev: DRBD device. 1199 * @mdev: DRBD device.
1186 * @upper_idx: 0: write all changed pages; +ve: page index to stop scanning for changed pages 1200 * @upper_idx: 0: write all changed pages; +ve: page index to stop scanning for changed pages
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 813f50dbe5ca..d8b3c88d6f1c 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1329,6 +1329,7 @@ extern int drbd_bm_read(struct drbd_conf *mdev) __must_hold(local);
1329extern void drbd_bm_mark_for_writeout(struct drbd_conf *mdev, int page_nr); 1329extern void drbd_bm_mark_for_writeout(struct drbd_conf *mdev, int page_nr);
1330extern int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local); 1330extern int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local);
1331extern int drbd_bm_write_hinted(struct drbd_conf *mdev) __must_hold(local); 1331extern int drbd_bm_write_hinted(struct drbd_conf *mdev) __must_hold(local);
1332extern int drbd_bm_write_all(struct drbd_conf *mdev) __must_hold(local);
1332extern int drbd_bm_write_copy_pages(struct drbd_conf *mdev) __must_hold(local); 1333extern int drbd_bm_write_copy_pages(struct drbd_conf *mdev) __must_hold(local);
1333extern size_t drbd_bm_words(struct drbd_conf *mdev); 1334extern size_t drbd_bm_words(struct drbd_conf *mdev);
1334extern unsigned long drbd_bm_bits(struct drbd_conf *mdev); 1335extern unsigned long drbd_bm_bits(struct drbd_conf *mdev);
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index d1073705bf1f..c02d5265c397 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -894,8 +894,8 @@ enum determine_dev_size drbd_determine_dev_size(struct drbd_conf *mdev, enum dds
894 la_size_changed && md_moved ? "size changed and md moved" : 894 la_size_changed && md_moved ? "size changed and md moved" :
895 la_size_changed ? "size changed" : "md moved"); 895 la_size_changed ? "size changed" : "md moved");
896 /* next line implicitly does drbd_suspend_io()+drbd_resume_io() */ 896 /* next line implicitly does drbd_suspend_io()+drbd_resume_io() */
897 err = drbd_bitmap_io(mdev, &drbd_bm_write, 897 err = drbd_bitmap_io(mdev, md_moved ? &drbd_bm_write_all : &drbd_bm_write,
898 "size changed", BM_LOCKED_MASK); 898 "size changed", BM_LOCKED_MASK);
899 if (err) { 899 if (err) {
900 rv = dev_size_error; 900 rv = dev_size_error;
901 goto out; 901 goto out;