diff options
author | Lars Ellenberg <lars.ellenberg@linbit.com> | 2013-12-20 05:17:02 -0500 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2014-07-10 09:22:22 -0400 |
commit | 70df70927b75eb86f12b14167c398b99dc3a56e4 (patch) | |
tree | 81225e07ec255438893b727d99937ffa16cdc732 /drivers/block/drbd | |
parent | 44a4d551846b8c61aa430b9432c1fcdf88444708 (diff) |
drbd: allow write-ordering policy to be bumped up again
Previously, once you disabled flushes as a means of enforcing
write-ordering, you'd need to detach/re-attach to enable them again.
Allow drbdsetup disk-options to re-enable previously disabled
write-ordering policy options at runtime.
While at it fix RCU in drbd_bump_write_ordering()
max_allowed_wo() uses rcu_dereference, therefore it must
be called within rcu_read_lock()/rcu_read_unlock()
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd')
-rw-r--r-- | drivers/block/drbd/drbd_nl.c | 10 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 6 |
2 files changed, 13 insertions, 3 deletions
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 0bf8a6082bb8..66065e60fdbc 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c | |||
@@ -1294,6 +1294,13 @@ static unsigned int drbd_al_extents_max(struct drbd_backing_dev *bdev) | |||
1294 | return (al_size_4k - 1) * AL_CONTEXT_PER_TRANSACTION; | 1294 | return (al_size_4k - 1) * AL_CONTEXT_PER_TRANSACTION; |
1295 | } | 1295 | } |
1296 | 1296 | ||
1297 | static bool write_ordering_changed(struct disk_conf *a, struct disk_conf *b) | ||
1298 | { | ||
1299 | return a->disk_barrier != b->disk_barrier || | ||
1300 | a->disk_flushes != b->disk_flushes || | ||
1301 | a->disk_drain != b->disk_drain; | ||
1302 | } | ||
1303 | |||
1297 | int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) | 1304 | int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) |
1298 | { | 1305 | { |
1299 | struct drbd_config_context adm_ctx; | 1306 | struct drbd_config_context adm_ctx; |
@@ -1400,7 +1407,8 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) | |||
1400 | else | 1407 | else |
1401 | set_bit(MD_NO_FUA, &device->flags); | 1408 | set_bit(MD_NO_FUA, &device->flags); |
1402 | 1409 | ||
1403 | drbd_bump_write_ordering(device->resource, NULL, WO_bdev_flush); | 1410 | if (write_ordering_changed(old_disk_conf, new_disk_conf)) |
1411 | drbd_bump_write_ordering(device->resource, NULL, WO_bdev_flush); | ||
1404 | 1412 | ||
1405 | drbd_md_sync(device); | 1413 | drbd_md_sync(device); |
1406 | 1414 | ||
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index bb1434dfec8a..8d8a6b7f8f5d 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -1290,7 +1290,8 @@ void drbd_bump_write_ordering(struct drbd_resource *resource, struct drbd_backin | |||
1290 | }; | 1290 | }; |
1291 | 1291 | ||
1292 | pwo = resource->write_ordering; | 1292 | pwo = resource->write_ordering; |
1293 | wo = min(pwo, wo); | 1293 | if (wo != WO_bdev_flush) |
1294 | wo = min(pwo, wo); | ||
1294 | rcu_read_lock(); | 1295 | rcu_read_lock(); |
1295 | idr_for_each_entry(&resource->devices, device, vnr) { | 1296 | idr_for_each_entry(&resource->devices, device, vnr) { |
1296 | if (get_ldev(device)) { | 1297 | if (get_ldev(device)) { |
@@ -1300,11 +1301,12 @@ void drbd_bump_write_ordering(struct drbd_resource *resource, struct drbd_backin | |||
1300 | put_ldev(device); | 1301 | put_ldev(device); |
1301 | } | 1302 | } |
1302 | } | 1303 | } |
1303 | rcu_read_unlock(); | ||
1304 | 1304 | ||
1305 | if (bdev) | 1305 | if (bdev) |
1306 | wo = max_allowed_wo(bdev, wo); | 1306 | wo = max_allowed_wo(bdev, wo); |
1307 | 1307 | ||
1308 | rcu_read_unlock(); | ||
1309 | |||
1308 | resource->write_ordering = wo; | 1310 | resource->write_ordering = wo; |
1309 | if (pwo != resource->write_ordering || wo == WO_bdev_flush) | 1311 | if (pwo != resource->write_ordering || wo == WO_bdev_flush) |
1310 | drbd_info(resource, "Method to ensure write ordering: %s\n", write_ordering_str[resource->write_ordering]); | 1312 | drbd_info(resource, "Method to ensure write ordering: %s\n", write_ordering_str[resource->write_ordering]); |