diff options
author | Philipp Reisner <philipp.reisner@linbit.com> | 2016-06-13 18:26:15 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2016-06-13 23:43:04 -0400 |
commit | 92d94ae66aebda5e4832d96e96b95117c44693b5 (patch) | |
tree | 08266c08a393aa5ca014d38d9813f61f74f5ae81 | |
parent | a5ca66c419410b4a26ab47b120d5424bd1d33700 (diff) |
drbd: Create the protocol feature THIN_RESYNC
If thinly provisioned volumes are used, during a resync the sync source
tries to find out if a block is deallocated. If it is deallocated, then
the resync target uses block_dev_issue_zeroout() on the range in
question.
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>
-rw-r--r-- | drivers/block/drbd/drbd_protocol.h | 1 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 5 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_worker.c | 13 |
3 files changed, 17 insertions, 2 deletions
diff --git a/drivers/block/drbd/drbd_protocol.h b/drivers/block/drbd/drbd_protocol.h index ce0e72ca47ec..95ca4586af59 100644 --- a/drivers/block/drbd/drbd_protocol.h +++ b/drivers/block/drbd/drbd_protocol.h | |||
@@ -165,6 +165,7 @@ struct p_block_req { | |||
165 | */ | 165 | */ |
166 | 166 | ||
167 | #define FF_TRIM 1 | 167 | #define FF_TRIM 1 |
168 | #define FF_THIN_RESYNC 2 | ||
168 | 169 | ||
169 | struct p_connection_features { | 170 | struct p_connection_features { |
170 | u32 protocol_min; | 171 | u32 protocol_min; |
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index f5eef97ec47d..a50cc99aaf3b 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -48,7 +48,7 @@ | |||
48 | #include "drbd_req.h" | 48 | #include "drbd_req.h" |
49 | #include "drbd_vli.h" | 49 | #include "drbd_vli.h" |
50 | 50 | ||
51 | #define PRO_FEATURES (FF_TRIM) | 51 | #define PRO_FEATURES (FF_TRIM | FF_THIN_RESYNC) |
52 | 52 | ||
53 | struct packet_info { | 53 | struct packet_info { |
54 | enum drbd_packet cmd; | 54 | enum drbd_packet cmd; |
@@ -4991,6 +4991,9 @@ static int drbd_do_features(struct drbd_connection *connection) | |||
4991 | drbd_info(connection, "Agreed to%ssupport TRIM on protocol level\n", | 4991 | drbd_info(connection, "Agreed to%ssupport TRIM on protocol level\n", |
4992 | connection->agreed_features & FF_TRIM ? " " : " not "); | 4992 | connection->agreed_features & FF_TRIM ? " " : " not "); |
4993 | 4993 | ||
4994 | drbd_info(connection, "Agreed to%ssupport THIN_RESYNC on protocol level\n", | ||
4995 | connection->agreed_features & FF_THIN_RESYNC ? " " : " not "); | ||
4996 | |||
4994 | return 1; | 4997 | return 1; |
4995 | 4998 | ||
4996 | incompat: | 4999 | incompat: |
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index dd85433315d2..154dbfc61aff 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c | |||
@@ -583,6 +583,7 @@ static int make_resync_request(struct drbd_device *const device, int cancel) | |||
583 | int number, rollback_i, size; | 583 | int number, rollback_i, size; |
584 | int align, requeue = 0; | 584 | int align, requeue = 0; |
585 | int i = 0; | 585 | int i = 0; |
586 | int discard_granularity = 0; | ||
586 | 587 | ||
587 | if (unlikely(cancel)) | 588 | if (unlikely(cancel)) |
588 | return 0; | 589 | return 0; |
@@ -602,6 +603,12 @@ static int make_resync_request(struct drbd_device *const device, int cancel) | |||
602 | return 0; | 603 | return 0; |
603 | } | 604 | } |
604 | 605 | ||
606 | if (connection->agreed_features & FF_THIN_RESYNC) { | ||
607 | rcu_read_lock(); | ||
608 | discard_granularity = rcu_dereference(device->ldev->disk_conf)->rs_discard_granularity; | ||
609 | rcu_read_unlock(); | ||
610 | } | ||
611 | |||
605 | max_bio_size = queue_max_hw_sectors(device->rq_queue) << 9; | 612 | max_bio_size = queue_max_hw_sectors(device->rq_queue) << 9; |
606 | number = drbd_rs_number_requests(device); | 613 | number = drbd_rs_number_requests(device); |
607 | if (number <= 0) | 614 | if (number <= 0) |
@@ -666,6 +673,9 @@ next_sector: | |||
666 | if (sector & ((1<<(align+3))-1)) | 673 | if (sector & ((1<<(align+3))-1)) |
667 | break; | 674 | break; |
668 | 675 | ||
676 | if (discard_granularity && size == discard_granularity) | ||
677 | break; | ||
678 | |||
669 | /* do not cross extent boundaries */ | 679 | /* do not cross extent boundaries */ |
670 | if (((bit+1) & BM_BLOCKS_PER_BM_EXT_MASK) == 0) | 680 | if (((bit+1) & BM_BLOCKS_PER_BM_EXT_MASK) == 0) |
671 | break; | 681 | break; |
@@ -712,7 +722,8 @@ next_sector: | |||
712 | int err; | 722 | int err; |
713 | 723 | ||
714 | inc_rs_pending(device); | 724 | inc_rs_pending(device); |
715 | err = drbd_send_drequest(peer_device, P_RS_DATA_REQUEST, | 725 | err = drbd_send_drequest(peer_device, |
726 | size == discard_granularity ? P_RS_THIN_REQ : P_RS_DATA_REQUEST, | ||
716 | sector, size, ID_SYNCER); | 727 | sector, size, ID_SYNCER); |
717 | if (err) { | 728 | if (err) { |
718 | drbd_err(device, "drbd_send_drequest() failed, aborting...\n"); | 729 | drbd_err(device, "drbd_send_drequest() failed, aborting...\n"); |