aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2016-06-13 18:26:15 -0400
committerJens Axboe <axboe@fb.com>2016-06-13 23:43:04 -0400
commit92d94ae66aebda5e4832d96e96b95117c44693b5 (patch)
tree08266c08a393aa5ca014d38d9813f61f74f5ae81
parenta5ca66c419410b4a26ab47b120d5424bd1d33700 (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.h1
-rw-r--r--drivers/block/drbd/drbd_receiver.c5
-rw-r--r--drivers/block/drbd/drbd_worker.c13
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
169struct p_connection_features { 170struct 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
53struct packet_info { 53struct 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");