Commit 70df7092 authored by Lars Ellenberg's avatar Lars Ellenberg Committed by Philipp Reisner

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: default avatarPhilipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: default avatarLars Ellenberg <lars.ellenberg@linbit.com>
parent 44a4d551
...@@ -1294,6 +1294,13 @@ static unsigned int drbd_al_extents_max(struct drbd_backing_dev *bdev) ...@@ -1294,6 +1294,13 @@ static unsigned int drbd_al_extents_max(struct drbd_backing_dev *bdev)
return (al_size_4k - 1) * AL_CONTEXT_PER_TRANSACTION; return (al_size_4k - 1) * AL_CONTEXT_PER_TRANSACTION;
} }
static bool write_ordering_changed(struct disk_conf *a, struct disk_conf *b)
{
return a->disk_barrier != b->disk_barrier ||
a->disk_flushes != b->disk_flushes ||
a->disk_drain != b->disk_drain;
}
int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
{ {
struct drbd_config_context adm_ctx; struct drbd_config_context adm_ctx;
...@@ -1400,6 +1407,7 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) ...@@ -1400,6 +1407,7 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
else else
set_bit(MD_NO_FUA, &device->flags); set_bit(MD_NO_FUA, &device->flags);
if (write_ordering_changed(old_disk_conf, new_disk_conf))
drbd_bump_write_ordering(device->resource, NULL, WO_bdev_flush); drbd_bump_write_ordering(device->resource, NULL, WO_bdev_flush);
drbd_md_sync(device); drbd_md_sync(device);
......
...@@ -1290,6 +1290,7 @@ void drbd_bump_write_ordering(struct drbd_resource *resource, struct drbd_backin ...@@ -1290,6 +1290,7 @@ void drbd_bump_write_ordering(struct drbd_resource *resource, struct drbd_backin
}; };
pwo = resource->write_ordering; pwo = resource->write_ordering;
if (wo != WO_bdev_flush)
wo = min(pwo, wo); wo = min(pwo, wo);
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&resource->devices, device, vnr) { idr_for_each_entry(&resource->devices, device, vnr) {
...@@ -1300,11 +1301,12 @@ void drbd_bump_write_ordering(struct drbd_resource *resource, struct drbd_backin ...@@ -1300,11 +1301,12 @@ void drbd_bump_write_ordering(struct drbd_resource *resource, struct drbd_backin
put_ldev(device); put_ldev(device);
} }
} }
rcu_read_unlock();
if (bdev) if (bdev)
wo = max_allowed_wo(bdev, wo); wo = max_allowed_wo(bdev, wo);
rcu_read_unlock();
resource->write_ordering = wo; resource->write_ordering = wo;
if (pwo != resource->write_ordering || wo == WO_bdev_flush) if (pwo != resource->write_ordering || wo == WO_bdev_flush)
drbd_info(resource, "Method to ensure write ordering: %s\n", write_ordering_str[resource->write_ordering]); drbd_info(resource, "Method to ensure write ordering: %s\n", write_ordering_str[resource->write_ordering]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment