summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2017-08-29 04:20:38 -0400
committerJens Axboe <axboe@kernel.dk>2017-08-29 17:34:44 -0400
commit9de7e14a1a9c6bc4f9be6ccd9b951341a80dbd52 (patch)
tree5255e73d42a6d601041f1e82056b02da77fe9c8a
parentc200d9868707150abd37853cb341b54f75461208 (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.c15
-rw-r--r--include/linux/drbd_genl.h3
-rw-r--r--include/linux/drbd_limits.h8
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
1237static void decide_on_write_same_support(struct drbd_device *device, 1237static 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
138GENL_struct(DRBD_NLA_RESOURCE_OPTS, 4, res_opts, 139GENL_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