aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_int.h
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2010-09-03 04:00:09 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2010-10-14 12:38:30 -0400
commitee15b038164fcf19b798021762dee3cf5cbc6433 (patch)
tree8d2cca781af96296a591a14928ece247fc682ef3 /drivers/block/drbd/drbd_int.h
parent63106d3c6c769b6219bd04edde513b12abae3f61 (diff)
drbd: fix race on meta-data update, addendum
addendum to baa33ae4eaa4477b60af7c434c0ddd1d182c1ae7 The race: drbd_md_sync() if (!test_and_clear_bit(MD_DIRTY, &mdev->flags)) return; ==> RACE with drbd_md_mark_dirty() rearming the timer. del_timer(&mdev->md_sync_timer); Fixed by moving the del_timer before the test_and_clear_bit. Additionally only rearm the timer in drbd_md_mark_dirty, if MD_DIRTY was not already set, reduce the grace period from five to one second, and add an ifdef'ed debuging aid to find code paths missing an explicit drbd_md_sync, if any, as those are the only relevant ones for this race. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd/drbd_int.h')
-rw-r--r--drivers/block/drbd/drbd_int.h12
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index d5e38de83a19..f9b75fc30569 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -975,6 +975,12 @@ struct drbd_conf {
975 md_sync_work; 975 md_sync_work;
976 struct timer_list resync_timer; 976 struct timer_list resync_timer;
977 struct timer_list md_sync_timer; 977 struct timer_list md_sync_timer;
978#ifdef DRBD_DEBUG_MD_SYNC
979 struct {
980 unsigned int line;
981 const char* func;
982 } last_md_mark_dirty;
983#endif
978 984
979 /* Used after attach while negotiating new disk state. */ 985 /* Used after attach while negotiating new disk state. */
980 union drbd_state new_state_tmp; 986 union drbd_state new_state_tmp;
@@ -1253,7 +1259,13 @@ extern void drbd_uuid_set_bm(struct drbd_conf *mdev, u64 val) __must_hold(local)
1253extern void drbd_md_set_flag(struct drbd_conf *mdev, int flags) __must_hold(local); 1259extern void drbd_md_set_flag(struct drbd_conf *mdev, int flags) __must_hold(local);
1254extern void drbd_md_clear_flag(struct drbd_conf *mdev, int flags)__must_hold(local); 1260extern void drbd_md_clear_flag(struct drbd_conf *mdev, int flags)__must_hold(local);
1255extern int drbd_md_test_flag(struct drbd_backing_dev *, int); 1261extern int drbd_md_test_flag(struct drbd_backing_dev *, int);
1262#ifndef DRBD_DEBUG_MD_SYNC
1256extern void drbd_md_mark_dirty(struct drbd_conf *mdev); 1263extern void drbd_md_mark_dirty(struct drbd_conf *mdev);
1264#else
1265#define drbd_md_mark_dirty(m) drbd_md_mark_dirty_(m, __LINE__ , __func__ )
1266extern void drbd_md_mark_dirty_(struct drbd_conf *mdev,
1267 unsigned int line, const char *func);
1268#endif
1257extern void drbd_queue_bitmap_io(struct drbd_conf *mdev, 1269extern void drbd_queue_bitmap_io(struct drbd_conf *mdev,
1258 int (*io_fn)(struct drbd_conf *), 1270 int (*io_fn)(struct drbd_conf *),
1259 void (*done)(struct drbd_conf *, int), 1271 void (*done)(struct drbd_conf *, int),