aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@linbit.com>2011-05-12 05:15:34 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-11-08 10:55:51 -0500
commit95f8efd08bcce65df994049a292b94e56c7ada67 (patch)
treea4a943aea52b65adc4ddabf736a30f66f83f6ed0
parent69ef82dea4c34e4a0541fc3f415b0fef70fe12b0 (diff)
drbd: Fix the upper limit of resync-after
The 32-bit resync_after netlink field takes a device minor number as parameter, which is no longer limited to 255. We cannot statically verify which device numbers are valid, so set the ummer limit to the highest possible signed 32-bit integer. 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_int.h4
-rw-r--r--drivers/block/drbd/drbd_nl.c4
-rw-r--r--drivers/block/drbd/drbd_worker.c26
-rw-r--r--include/linux/drbd.h4
-rw-r--r--include/linux/drbd_genl.h2
-rw-r--r--include/linux/drbd_limits.h7
6 files changed, 24 insertions, 23 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 8026adacd3d..e1672284076 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1408,8 +1408,8 @@ extern int drbd_khelper(struct drbd_conf *mdev, char *cmd);
1408 1408
1409/* drbd_worker.c */ 1409/* drbd_worker.c */
1410extern int drbd_worker(struct drbd_thread *thi); 1410extern int drbd_worker(struct drbd_thread *thi);
1411enum drbd_ret_code drbd_sync_after_valid(struct drbd_conf *mdev, int o_minor); 1411enum drbd_ret_code drbd_resync_after_valid(struct drbd_conf *mdev, int o_minor);
1412void drbd_sync_after_changed(struct drbd_conf *mdev); 1412void drbd_resync_after_changed(struct drbd_conf *mdev);
1413extern void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side); 1413extern void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side);
1414extern void resume_next_sg(struct drbd_conf *mdev); 1414extern void resume_next_sg(struct drbd_conf *mdev);
1415extern void suspend_other_sg(struct drbd_conf *mdev); 1415extern void suspend_other_sg(struct drbd_conf *mdev);
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 9a82306adf9..74c27f1507f 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1183,10 +1183,10 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
1183 } 1183 }
1184 1184
1185 write_lock_irq(&global_state_lock); 1185 write_lock_irq(&global_state_lock);
1186 retcode = drbd_sync_after_valid(mdev, new_disk_conf->resync_after); 1186 retcode = drbd_resync_after_valid(mdev, new_disk_conf->resync_after);
1187 if (retcode == NO_ERROR) { 1187 if (retcode == NO_ERROR) {
1188 rcu_assign_pointer(mdev->ldev->disk_conf, new_disk_conf); 1188 rcu_assign_pointer(mdev->ldev->disk_conf, new_disk_conf);
1189 drbd_sync_after_changed(mdev); 1189 drbd_resync_after_changed(mdev);
1190 } 1190 }
1191 write_unlock_irq(&global_state_lock); 1191 write_unlock_irq(&global_state_lock);
1192 1192
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index ec8f4245ef9..6410c55831e 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -57,7 +57,7 @@ static int w_make_ov_request(struct drbd_work *w, int cancel);
57 57
58/* About the global_state_lock 58/* About the global_state_lock
59 Each state transition on an device holds a read lock. In case we have 59 Each state transition on an device holds a read lock. In case we have
60 to evaluate the sync after dependencies, we grab a write lock, because 60 to evaluate the resync after dependencies, we grab a write lock, because
61 we need stable states on all devices for that. */ 61 we need stable states on all devices for that. */
62rwlock_t global_state_lock; 62rwlock_t global_state_lock;
63 63
@@ -1340,17 +1340,17 @@ int w_restart_disk_io(struct drbd_work *w, int cancel)
1340static int _drbd_may_sync_now(struct drbd_conf *mdev) 1340static int _drbd_may_sync_now(struct drbd_conf *mdev)
1341{ 1341{
1342 struct drbd_conf *odev = mdev; 1342 struct drbd_conf *odev = mdev;
1343 int ra; 1343 int resync_after;
1344 1344
1345 while (1) { 1345 while (1) {
1346 if (!odev->ldev) 1346 if (!odev->ldev)
1347 return 1; 1347 return 1;
1348 rcu_read_lock(); 1348 rcu_read_lock();
1349 ra = rcu_dereference(odev->ldev->disk_conf)->resync_after; 1349 resync_after = rcu_dereference(odev->ldev->disk_conf)->resync_after;
1350 rcu_read_unlock(); 1350 rcu_read_unlock();
1351 if (ra == -1) 1351 if (resync_after == -1)
1352 return 1; 1352 return 1;
1353 odev = minor_to_mdev(ra); 1353 odev = minor_to_mdev(resync_after);
1354 if (!expect(odev)) 1354 if (!expect(odev))
1355 return 1; 1355 return 1;
1356 if ((odev->state.conn >= C_SYNC_SOURCE && 1356 if ((odev->state.conn >= C_SYNC_SOURCE &&
@@ -1426,36 +1426,36 @@ void suspend_other_sg(struct drbd_conf *mdev)
1426} 1426}
1427 1427
1428/* caller must hold global_state_lock */ 1428/* caller must hold global_state_lock */
1429enum drbd_ret_code drbd_sync_after_valid(struct drbd_conf *mdev, int o_minor) 1429enum drbd_ret_code drbd_resync_after_valid(struct drbd_conf *mdev, int o_minor)
1430{ 1430{
1431 struct drbd_conf *odev; 1431 struct drbd_conf *odev;
1432 int ra; 1432 int resync_after;
1433 1433
1434 if (o_minor == -1) 1434 if (o_minor == -1)
1435 return NO_ERROR; 1435 return NO_ERROR;
1436 if (o_minor < -1 || minor_to_mdev(o_minor) == NULL) 1436 if (o_minor < -1 || minor_to_mdev(o_minor) == NULL)
1437 return ERR_SYNC_AFTER; 1437 return ERR_RESYNC_AFTER;
1438 1438
1439 /* check for loops */ 1439 /* check for loops */
1440 odev = minor_to_mdev(o_minor); 1440 odev = minor_to_mdev(o_minor);
1441 while (1) { 1441 while (1) {
1442 if (odev == mdev) 1442 if (odev == mdev)
1443 return ERR_SYNC_AFTER_CYCLE; 1443 return ERR_RESYNC_AFTER_CYCLE;
1444 1444
1445 rcu_read_lock(); 1445 rcu_read_lock();
1446 ra = rcu_dereference(odev->ldev->disk_conf)->resync_after; 1446 resync_after = rcu_dereference(odev->ldev->disk_conf)->resync_after;
1447 rcu_read_unlock(); 1447 rcu_read_unlock();
1448 /* dependency chain ends here, no cycles. */ 1448 /* dependency chain ends here, no cycles. */
1449 if (ra == -1) 1449 if (resync_after == -1)
1450 return NO_ERROR; 1450 return NO_ERROR;
1451 1451
1452 /* follow the dependency chain */ 1452 /* follow the dependency chain */
1453 odev = minor_to_mdev(ra); 1453 odev = minor_to_mdev(resync_after);
1454 } 1454 }
1455} 1455}
1456 1456
1457/* caller must hold global_state_lock */ 1457/* caller must hold global_state_lock */
1458void drbd_sync_after_changed(struct drbd_conf *mdev) 1458void drbd_resync_after_changed(struct drbd_conf *mdev)
1459{ 1459{
1460 int changes; 1460 int changes;
1461 1461
diff --git a/include/linux/drbd.h b/include/linux/drbd.h
index 6c7c85d8fc4..05063e6db81 100644
--- a/include/linux/drbd.h
+++ b/include/linux/drbd.h
@@ -130,8 +130,8 @@ enum drbd_ret_code {
130 ERR_INTR = 129, /* EINTR */ 130 ERR_INTR = 129, /* EINTR */
131 ERR_RESIZE_RESYNC = 130, 131 ERR_RESIZE_RESYNC = 130,
132 ERR_NO_PRIMARY = 131, 132 ERR_NO_PRIMARY = 131,
133 ERR_SYNC_AFTER = 132, 133 ERR_RESYNC_AFTER = 132,
134 ERR_SYNC_AFTER_CYCLE = 133, 134 ERR_RESYNC_AFTER_CYCLE = 133,
135 ERR_PAUSE_IS_SET = 134, 135 ERR_PAUSE_IS_SET = 134,
136 ERR_PAUSE_IS_CLEAR = 135, 136 ERR_PAUSE_IS_CLEAR = 135,
137 ERR_PACKET_NR = 137, 137 ERR_PACKET_NR = 137,
diff --git a/include/linux/drbd_genl.h b/include/linux/drbd_genl.h
index 67c816c0fc2..a59466f7f66 100644
--- a/include/linux/drbd_genl.h
+++ b/include/linux/drbd_genl.h
@@ -114,7 +114,7 @@ GENL_struct(DRBD_NLA_DISK_CONF, 3, disk_conf,
114 __u32_field_def(7, GENLA_F_MANDATORY, fencing, DRBD_FENCING_DEF) 114 __u32_field_def(7, GENLA_F_MANDATORY, fencing, DRBD_FENCING_DEF)
115 115
116 __u32_field_def(8, GENLA_F_MANDATORY, resync_rate, DRBD_RESYNC_RATE_DEF) 116 __u32_field_def(8, GENLA_F_MANDATORY, resync_rate, DRBD_RESYNC_RATE_DEF)
117 __u32_field_def(9, GENLA_F_MANDATORY, resync_after, DRBD_AFTER_DEF) 117 __u32_field_def(9, GENLA_F_MANDATORY, resync_after, DRBD_RESYNC_AFTER_DEF)
118 __u32_field_def(10, GENLA_F_MANDATORY, al_extents, DRBD_AL_EXTENTS_DEF) 118 __u32_field_def(10, GENLA_F_MANDATORY, al_extents, DRBD_AL_EXTENTS_DEF)
119 __u32_field_def(11, GENLA_F_MANDATORY, c_plan_ahead, DRBD_C_PLAN_AHEAD_DEF) 119 __u32_field_def(11, GENLA_F_MANDATORY, c_plan_ahead, DRBD_C_PLAN_AHEAD_DEF)
120 __u32_field_def(12, GENLA_F_MANDATORY, c_delay_target, DRBD_C_DELAY_TARGET_DEF) 120 __u32_field_def(12, GENLA_F_MANDATORY, c_delay_target, DRBD_C_DELAY_TARGET_DEF)
diff --git a/include/linux/drbd_limits.h b/include/linux/drbd_limits.h
index 48339ae69d5..c4a8f0fef7b 100644
--- a/include/linux/drbd_limits.h
+++ b/include/linux/drbd_limits.h
@@ -113,9 +113,10 @@
113#define DRBD_AL_EXTENTS_MAX 6433 113#define DRBD_AL_EXTENTS_MAX 6433
114#define DRBD_AL_EXTENTS_DEF 127 114#define DRBD_AL_EXTENTS_DEF 127
115 115
116#define DRBD_AFTER_MIN -1 116#define DRBD_RESYNC_AFTER_MIN -1
117#define DRBD_AFTER_MAX 255 117#define DRBD_RESYNC_AFTER_MAX (1<<30)
118#define DRBD_AFTER_DEF -1 118#define DRBD_RESYNC_AFTER_DEF -1
119#define DRBD_RESYNC_AFTER_SCALE '1'
119 120
120/* } */ 121/* } */
121 122