diff options
author | Lars Ellenberg <lars.ellenberg@linbit.com> | 2017-08-29 04:20:38 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2017-08-29 17:34:44 -0400 |
commit | 9de7e14a1a9c6bc4f9be6ccd9b951341a80dbd52 (patch) | |
tree | 5255e73d42a6d601041f1e82056b02da77fe9c8a | |
parent | c200d9868707150abd37853cb341b54f75461208 (diff) |
drbd: new disk-option disable-write-same
Some backend devices claim to support write-same,
but would fail actual write-same requests.
Allow to set (or toggle) whether or not DRBD tries to support write-same.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | drivers/block/drbd/drbd_nl.c | 15 | ||||
-rw-r--r-- | include/linux/drbd_genl.h | 3 | ||||
-rw-r--r-- | include/linux/drbd_limits.h | 8 |
3 files changed, 21 insertions, 5 deletions
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index ad0fcb43e45c..c383b6cf272a 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c | |||
@@ -1236,12 +1236,18 @@ static void fixup_discard_if_not_supported(struct request_queue *q) | |||
1236 | 1236 | ||
1237 | static void decide_on_write_same_support(struct drbd_device *device, | 1237 | static void decide_on_write_same_support(struct drbd_device *device, |
1238 | struct request_queue *q, | 1238 | struct request_queue *q, |
1239 | struct request_queue *b, struct o_qlim *o) | 1239 | struct request_queue *b, struct o_qlim *o, |
1240 | bool disable_write_same) | ||
1240 | { | 1241 | { |
1241 | struct drbd_peer_device *peer_device = first_peer_device(device); | 1242 | struct drbd_peer_device *peer_device = first_peer_device(device); |
1242 | struct drbd_connection *connection = peer_device->connection; | 1243 | struct drbd_connection *connection = peer_device->connection; |
1243 | bool can_do = b ? b->limits.max_write_same_sectors : true; | 1244 | bool can_do = b ? b->limits.max_write_same_sectors : true; |
1244 | 1245 | ||
1246 | if (can_do && disable_write_same) { | ||
1247 | can_do = false; | ||
1248 | drbd_info(peer_device, "WRITE_SAME disabled by config\n"); | ||
1249 | } | ||
1250 | |||
1245 | if (can_do && connection->cstate >= C_CONNECTED && !(connection->agreed_features & DRBD_FF_WSAME)) { | 1251 | if (can_do && connection->cstate >= C_CONNECTED && !(connection->agreed_features & DRBD_FF_WSAME)) { |
1246 | can_do = false; | 1252 | can_do = false; |
1247 | drbd_info(peer_device, "peer does not support WRITE_SAME\n"); | 1253 | drbd_info(peer_device, "peer does not support WRITE_SAME\n"); |
@@ -1302,6 +1308,7 @@ static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backi | |||
1302 | struct request_queue *b = NULL; | 1308 | struct request_queue *b = NULL; |
1303 | struct disk_conf *dc; | 1309 | struct disk_conf *dc; |
1304 | bool discard_zeroes_if_aligned = true; | 1310 | bool discard_zeroes_if_aligned = true; |
1311 | bool disable_write_same = false; | ||
1305 | 1312 | ||
1306 | if (bdev) { | 1313 | if (bdev) { |
1307 | b = bdev->backing_bdev->bd_disk->queue; | 1314 | b = bdev->backing_bdev->bd_disk->queue; |
@@ -1311,6 +1318,7 @@ static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backi | |||
1311 | dc = rcu_dereference(device->ldev->disk_conf); | 1318 | dc = rcu_dereference(device->ldev->disk_conf); |
1312 | max_segments = dc->max_bio_bvecs; | 1319 | max_segments = dc->max_bio_bvecs; |
1313 | discard_zeroes_if_aligned = dc->discard_zeroes_if_aligned; | 1320 | discard_zeroes_if_aligned = dc->discard_zeroes_if_aligned; |
1321 | disable_write_same = dc->disable_write_same; | ||
1314 | rcu_read_unlock(); | 1322 | rcu_read_unlock(); |
1315 | 1323 | ||
1316 | blk_set_stacking_limits(&q->limits); | 1324 | blk_set_stacking_limits(&q->limits); |
@@ -1321,7 +1329,7 @@ static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backi | |||
1321 | blk_queue_max_segments(q, max_segments ? max_segments : BLK_MAX_SEGMENTS); | 1329 | blk_queue_max_segments(q, max_segments ? max_segments : BLK_MAX_SEGMENTS); |
1322 | blk_queue_segment_boundary(q, PAGE_SIZE-1); | 1330 | blk_queue_segment_boundary(q, PAGE_SIZE-1); |
1323 | decide_on_discard_support(device, q, b, discard_zeroes_if_aligned); | 1331 | decide_on_discard_support(device, q, b, discard_zeroes_if_aligned); |
1324 | decide_on_write_same_support(device, q, b, o); | 1332 | decide_on_write_same_support(device, q, b, o, disable_write_same); |
1325 | 1333 | ||
1326 | if (b) { | 1334 | if (b) { |
1327 | blk_queue_stack_limits(q, b); | 1335 | blk_queue_stack_limits(q, b); |
@@ -1612,7 +1620,8 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) | |||
1612 | if (write_ordering_changed(old_disk_conf, new_disk_conf)) | 1620 | if (write_ordering_changed(old_disk_conf, new_disk_conf)) |
1613 | drbd_bump_write_ordering(device->resource, NULL, WO_BDEV_FLUSH); | 1621 | drbd_bump_write_ordering(device->resource, NULL, WO_BDEV_FLUSH); |
1614 | 1622 | ||
1615 | if (old_disk_conf->discard_zeroes_if_aligned != new_disk_conf->discard_zeroes_if_aligned) | 1623 | if (old_disk_conf->discard_zeroes_if_aligned != new_disk_conf->discard_zeroes_if_aligned |
1624 | || old_disk_conf->disable_write_same != new_disk_conf->disable_write_same) | ||
1616 | drbd_reconsider_queue_parameters(device, device->ldev, NULL); | 1625 | drbd_reconsider_queue_parameters(device, device->ldev, NULL); |
1617 | 1626 | ||
1618 | drbd_md_sync(device); | 1627 | drbd_md_sync(device); |
diff --git a/include/linux/drbd_genl.h b/include/linux/drbd_genl.h index 2896f93808ae..4e6d4d4c7056 100644 --- a/include/linux/drbd_genl.h +++ b/include/linux/drbd_genl.h | |||
@@ -132,7 +132,8 @@ GENL_struct(DRBD_NLA_DISK_CONF, 3, disk_conf, | |||
132 | __flg_field_def(18, DRBD_GENLA_F_MANDATORY, disk_drain, DRBD_DISK_DRAIN_DEF) | 132 | __flg_field_def(18, DRBD_GENLA_F_MANDATORY, disk_drain, DRBD_DISK_DRAIN_DEF) |
133 | __flg_field_def(19, DRBD_GENLA_F_MANDATORY, md_flushes, DRBD_MD_FLUSHES_DEF) | 133 | __flg_field_def(19, DRBD_GENLA_F_MANDATORY, md_flushes, DRBD_MD_FLUSHES_DEF) |
134 | __flg_field_def(23, 0 /* OPTIONAL */, al_updates, DRBD_AL_UPDATES_DEF) | 134 | __flg_field_def(23, 0 /* OPTIONAL */, al_updates, DRBD_AL_UPDATES_DEF) |
135 | __flg_field_def(24, 0 /* OPTIONAL */, discard_zeroes_if_aligned, DRBD_DISCARD_ZEROES_IF_ALIGNED) | 135 | __flg_field_def(24, 0 /* OPTIONAL */, discard_zeroes_if_aligned, DRBD_DISCARD_ZEROES_IF_ALIGNED_DEF) |
136 | __flg_field_def(26, 0 /* OPTIONAL */, disable_write_same, DRBD_DISABLE_WRITE_SAME_DEF) | ||
136 | ) | 137 | ) |
137 | 138 | ||
138 | GENL_struct(DRBD_NLA_RESOURCE_OPTS, 4, res_opts, | 139 | GENL_struct(DRBD_NLA_RESOURCE_OPTS, 4, res_opts, |
diff --git a/include/linux/drbd_limits.h b/include/linux/drbd_limits.h index ddac68422a96..24ae1b9b76c7 100644 --- a/include/linux/drbd_limits.h +++ b/include/linux/drbd_limits.h | |||
@@ -209,12 +209,18 @@ | |||
209 | #define DRBD_MD_FLUSHES_DEF 1 | 209 | #define DRBD_MD_FLUSHES_DEF 1 |
210 | #define DRBD_TCP_CORK_DEF 1 | 210 | #define DRBD_TCP_CORK_DEF 1 |
211 | #define DRBD_AL_UPDATES_DEF 1 | 211 | #define DRBD_AL_UPDATES_DEF 1 |
212 | |||
212 | /* We used to ignore the discard_zeroes_data setting. | 213 | /* We used to ignore the discard_zeroes_data setting. |
213 | * To not change established (and expected) behaviour, | 214 | * To not change established (and expected) behaviour, |
214 | * by default assume that, for discard_zeroes_data=0, | 215 | * by default assume that, for discard_zeroes_data=0, |
215 | * we can make that an effective discard_zeroes_data=1, | 216 | * we can make that an effective discard_zeroes_data=1, |
216 | * if we only explicitly zero-out unaligned partial chunks. */ | 217 | * if we only explicitly zero-out unaligned partial chunks. */ |
217 | #define DRBD_DISCARD_ZEROES_IF_ALIGNED 1 | 218 | #define DRBD_DISCARD_ZEROES_IF_ALIGNED_DEF 1 |
219 | |||
220 | /* Some backends pretend to support WRITE SAME, | ||
221 | * but fail such requests when they are actually submitted. | ||
222 | * This is to tell DRBD to not even try. */ | ||
223 | #define DRBD_DISABLE_WRITE_SAME_DEF 0 | ||
218 | 224 | ||
219 | #define DRBD_ALLOW_TWO_PRIMARIES_DEF 0 | 225 | #define DRBD_ALLOW_TWO_PRIMARIES_DEF 0 |
220 | #define DRBD_ALWAYS_ASBP_DEF 0 | 226 | #define DRBD_ALWAYS_ASBP_DEF 0 |