aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2012-05-07 06:07:18 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-11-08 10:58:28 -0500
commita220d291804233e3a5e3425abf79fa1e62e7bd35 (patch)
tree1a1c851e0a21de3acbff2a780bfb2d3ce5dd8760 /drivers/block
parent5016b82a49eb06cbe2002db7bd8a5501ba4ef6d1 (diff)
drbd: allow bitmap to change during writeout from resync_finished
Symptom: messages similar to "FIXME asender in bm_change_bits_to, bitmap locked for 'write from resync_finished' by worker" If a resync or verify is finished (or aborted), a full bitmap writeout is triggered. If we have ongoing local IO, the bitmap may still change during that writeout, pending and not yet processed acks may cause bits to be cleared, while new writes may cause bits to be to be set. To fix this, introduce the drbd_bm_write_copy_pages() variant. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/drbd/drbd_bitmap.c16
-rw-r--r--drivers/block/drbd/drbd_int.h15
-rw-r--r--drivers/block/drbd/drbd_state.c4
3 files changed, 29 insertions, 6 deletions
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index e343817bc69e..ddd297708194 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -1191,6 +1191,22 @@ int drbd_bm_write_lazy(struct drbd_conf *mdev, unsigned upper_idx) __must_hold(l
1191} 1191}
1192 1192
1193/** 1193/**
1194 * drbd_bm_write_copy_pages() - Write the whole bitmap to its on disk location.
1195 * @mdev: DRBD device.
1196 *
1197 * Will only write pages that have changed since last IO.
1198 * In contrast to drbd_bm_write(), this will copy the bitmap pages
1199 * to temporary writeout pages. It is intended to trigger a full write-out
1200 * while still allowing the bitmap to change, for example if a resync or online
1201 * verify is aborted due to a failed peer disk, while local IO continues, or
1202 * pending resync acks are still being processed.
1203 */
1204int drbd_bm_write_copy_pages(struct drbd_conf *mdev) __must_hold(local)
1205{
1206 return bm_rw(mdev, WRITE, BM_AIO_COPY_PAGES, 0);
1207}
1208
1209/**
1194 * drbd_bm_write_hinted() - Write bitmap pages with "hint" marks, if they have changed. 1210 * drbd_bm_write_hinted() - Write bitmap pages with "hint" marks, if they have changed.
1195 * @mdev: DRBD device. 1211 * @mdev: DRBD device.
1196 */ 1212 */
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 976e78cadd3e..5b1789af6cdf 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -709,22 +709,28 @@ enum bm_flag {
709 BM_P_VMALLOCED = 0x10000, /* internal use only, will be masked out */ 709 BM_P_VMALLOCED = 0x10000, /* internal use only, will be masked out */
710 710
711 /* currently locked for bulk operation */ 711 /* currently locked for bulk operation */
712 BM_LOCKED_MASK = 0x7, 712 BM_LOCKED_MASK = 0xf,
713 713
714 /* in detail, that is: */ 714 /* in detail, that is: */
715 BM_DONT_CLEAR = 0x1, 715 BM_DONT_CLEAR = 0x1,
716 BM_DONT_SET = 0x2, 716 BM_DONT_SET = 0x2,
717 BM_DONT_TEST = 0x4, 717 BM_DONT_TEST = 0x4,
718 718
719 /* so we can mark it locked for bulk operation,
720 * and still allow all non-bulk operations */
721 BM_IS_LOCKED = 0x8,
722
719 /* (test bit, count bit) allowed (common case) */ 723 /* (test bit, count bit) allowed (common case) */
720 BM_LOCKED_TEST_ALLOWED = 0x3, 724 BM_LOCKED_TEST_ALLOWED = BM_DONT_CLEAR | BM_DONT_SET | BM_IS_LOCKED,
721 725
722 /* testing bits, as well as setting new bits allowed, but clearing bits 726 /* testing bits, as well as setting new bits allowed, but clearing bits
723 * would be unexpected. Used during bitmap receive. Setting new bits 727 * would be unexpected. Used during bitmap receive. Setting new bits
724 * requires sending of "out-of-sync" information, though. */ 728 * requires sending of "out-of-sync" information, though. */
725 BM_LOCKED_SET_ALLOWED = 0x1, 729 BM_LOCKED_SET_ALLOWED = BM_DONT_CLEAR | BM_IS_LOCKED,
726 730
727 /* clear is not expected while bitmap is locked for bulk operation */ 731 /* for drbd_bm_write_copy_pages, everything is allowed,
732 * only concurrent bulk operations are locked out. */
733 BM_LOCKED_CHANGE_ALLOWED = BM_IS_LOCKED,
728}; 734};
729 735
730struct drbd_work_queue { 736struct drbd_work_queue {
@@ -1306,6 +1312,7 @@ extern int drbd_bm_read(struct drbd_conf *mdev) __must_hold(local);
1306extern void drbd_bm_mark_for_writeout(struct drbd_conf *mdev, int page_nr); 1312extern void drbd_bm_mark_for_writeout(struct drbd_conf *mdev, int page_nr);
1307extern int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local); 1313extern int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local);
1308extern int drbd_bm_write_hinted(struct drbd_conf *mdev) __must_hold(local); 1314extern int drbd_bm_write_hinted(struct drbd_conf *mdev) __must_hold(local);
1315extern int drbd_bm_write_copy_pages(struct drbd_conf *mdev) __must_hold(local);
1309extern size_t drbd_bm_words(struct drbd_conf *mdev); 1316extern size_t drbd_bm_words(struct drbd_conf *mdev);
1310extern unsigned long drbd_bm_bits(struct drbd_conf *mdev); 1317extern unsigned long drbd_bm_bits(struct drbd_conf *mdev);
1311extern sector_t drbd_bm_capacity(struct drbd_conf *mdev); 1318extern sector_t drbd_bm_capacity(struct drbd_conf *mdev);
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 2673049df34c..dd618b5346f2 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -1421,8 +1421,8 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
1421 * No harm done if some bits change during this phase. 1421 * No harm done if some bits change during this phase.
1422 */ 1422 */
1423 if (os.conn > C_CONNECTED && ns.conn <= C_CONNECTED && get_ldev(mdev)) { 1423 if (os.conn > C_CONNECTED && ns.conn <= C_CONNECTED && get_ldev(mdev)) {
1424 drbd_queue_bitmap_io(mdev, &drbd_bm_write, NULL, 1424 drbd_queue_bitmap_io(mdev, &drbd_bm_write_copy_pages, NULL,
1425 "write from resync_finished", BM_LOCKED_SET_ALLOWED); 1425 "write from resync_finished", BM_LOCKED_CHANGE_ALLOWED);
1426 put_ldev(mdev); 1426 put_ldev(mdev);
1427 } 1427 }
1428 1428