diff options
| author | Philipp Reisner <philipp.reisner@linbit.com> | 2016-06-13 18:26:14 -0400 |
|---|---|---|
| committer | Jens Axboe <axboe@fb.com> | 2016-06-13 23:43:04 -0400 |
| commit | a5ca66c419410b4a26ab47b120d5424bd1d33700 (patch) | |
| tree | e8bcf9de1ec9ec9b51f2863c3e1ab9a7286d33ef /drivers/block/drbd | |
| parent | 700ca8c04a0f4402f379055eec97351e0d6c0087 (diff) | |
drbd: Introduce new disk config option rs-discard-granularity
As long as the value is 0 the feature is disabled. With setting
it to a positive value, DRBD limits and aligns its resync requests
to the rs-discard-granularity setting. If the sync source detects
all zeros in such a block, the resync target discards the range
on disk.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/block/drbd')
| -rw-r--r-- | drivers/block/drbd/drbd_nl.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index fad03e4feef6..99339dfe4389 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c | |||
| @@ -1348,12 +1348,38 @@ static bool write_ordering_changed(struct disk_conf *a, struct disk_conf *b) | |||
| 1348 | a->disk_drain != b->disk_drain; | 1348 | a->disk_drain != b->disk_drain; |
| 1349 | } | 1349 | } |
| 1350 | 1350 | ||
| 1351 | static void sanitize_disk_conf(struct disk_conf *disk_conf, struct drbd_backing_dev *nbc) | 1351 | static void sanitize_disk_conf(struct drbd_device *device, struct disk_conf *disk_conf, |
| 1352 | struct drbd_backing_dev *nbc) | ||
| 1352 | { | 1353 | { |
| 1354 | struct request_queue * const q = nbc->backing_bdev->bd_disk->queue; | ||
| 1355 | |||
| 1353 | if (disk_conf->al_extents < DRBD_AL_EXTENTS_MIN) | 1356 | if (disk_conf->al_extents < DRBD_AL_EXTENTS_MIN) |
| 1354 | disk_conf->al_extents = DRBD_AL_EXTENTS_MIN; | 1357 | disk_conf->al_extents = DRBD_AL_EXTENTS_MIN; |
| 1355 | if (disk_conf->al_extents > drbd_al_extents_max(nbc)) | 1358 | if (disk_conf->al_extents > drbd_al_extents_max(nbc)) |
| 1356 | disk_conf->al_extents = drbd_al_extents_max(nbc); | 1359 | disk_conf->al_extents = drbd_al_extents_max(nbc); |
| 1360 | |||
| 1361 | if (!blk_queue_discard(q) || !q->limits.discard_zeroes_data) { | ||
| 1362 | disk_conf->rs_discard_granularity = 0; /* disable feature */ | ||
| 1363 | drbd_info(device, "rs_discard_granularity feature disabled\n"); | ||
| 1364 | } | ||
| 1365 | |||
| 1366 | if (disk_conf->rs_discard_granularity) { | ||
| 1367 | int orig_value = disk_conf->rs_discard_granularity; | ||
| 1368 | int remainder; | ||
| 1369 | |||
| 1370 | if (q->limits.discard_granularity > disk_conf->rs_discard_granularity) | ||
| 1371 | disk_conf->rs_discard_granularity = q->limits.discard_granularity; | ||
| 1372 | |||
| 1373 | remainder = disk_conf->rs_discard_granularity % q->limits.discard_granularity; | ||
| 1374 | disk_conf->rs_discard_granularity += remainder; | ||
| 1375 | |||
| 1376 | if (disk_conf->rs_discard_granularity > q->limits.max_discard_sectors << 9) | ||
| 1377 | disk_conf->rs_discard_granularity = q->limits.max_discard_sectors << 9; | ||
| 1378 | |||
| 1379 | if (disk_conf->rs_discard_granularity != orig_value) | ||
| 1380 | drbd_info(device, "rs_discard_granularity changed to %d\n", | ||
| 1381 | disk_conf->rs_discard_granularity); | ||
| 1382 | } | ||
| 1357 | } | 1383 | } |
| 1358 | 1384 | ||
| 1359 | int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) | 1385 | int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) |
| @@ -1403,7 +1429,7 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) | |||
| 1403 | if (!expect(new_disk_conf->resync_rate >= 1)) | 1429 | if (!expect(new_disk_conf->resync_rate >= 1)) |
| 1404 | new_disk_conf->resync_rate = 1; | 1430 | new_disk_conf->resync_rate = 1; |
| 1405 | 1431 | ||
| 1406 | sanitize_disk_conf(new_disk_conf, device->ldev); | 1432 | sanitize_disk_conf(device, new_disk_conf, device->ldev); |
| 1407 | 1433 | ||
| 1408 | if (new_disk_conf->c_plan_ahead > DRBD_C_PLAN_AHEAD_MAX) | 1434 | if (new_disk_conf->c_plan_ahead > DRBD_C_PLAN_AHEAD_MAX) |
| 1409 | new_disk_conf->c_plan_ahead = DRBD_C_PLAN_AHEAD_MAX; | 1435 | new_disk_conf->c_plan_ahead = DRBD_C_PLAN_AHEAD_MAX; |
| @@ -1698,7 +1724,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) | |||
| 1698 | if (retcode != NO_ERROR) | 1724 | if (retcode != NO_ERROR) |
| 1699 | goto fail; | 1725 | goto fail; |
| 1700 | 1726 | ||
| 1701 | sanitize_disk_conf(new_disk_conf, nbc); | 1727 | sanitize_disk_conf(device, new_disk_conf, nbc); |
| 1702 | 1728 | ||
| 1703 | if (drbd_get_max_capacity(nbc) < new_disk_conf->disk_size) { | 1729 | if (drbd_get_max_capacity(nbc) < new_disk_conf->disk_size) { |
| 1704 | drbd_err(device, "max capacity %llu smaller than disk size %llu\n", | 1730 | drbd_err(device, "max capacity %llu smaller than disk size %llu\n", |
