aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2013-12-20 05:17:02 -0500
committerPhilipp Reisner <philipp.reisner@linbit.com>2014-07-10 09:22:22 -0400
commit70df70927b75eb86f12b14167c398b99dc3a56e4 (patch)
tree81225e07ec255438893b727d99937ffa16cdc732 /drivers/block/drbd
parent44a4d551846b8c61aa430b9432c1fcdf88444708 (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.c10
-rw-r--r--drivers/block/drbd/drbd_receiver.c6
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
1297static 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
1297int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) 1304int 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]);