Skip to content

Commit 92d94ae

Browse files
Philipp-Reisneraxboe
authored andcommitted
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 <[email protected]> Signed-off-by: Lars Ellenberg <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent a5ca66c commit 92d94ae

File tree

3 files changed

+17
-2
lines changed

3 files changed

+17
-2
lines changed

drivers/block/drbd/drbd_protocol.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ struct p_block_req {
165165
*/
166166

167167
#define FF_TRIM 1
168+
#define FF_THIN_RESYNC 2
168169

169170
struct p_connection_features {
170171
u32 protocol_min;

drivers/block/drbd/drbd_receiver.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
#include "drbd_req.h"
4949
#include "drbd_vli.h"
5050

51-
#define PRO_FEATURES (FF_TRIM)
51+
#define PRO_FEATURES (FF_TRIM | FF_THIN_RESYNC)
5252

5353
struct packet_info {
5454
enum drbd_packet cmd;
@@ -4991,6 +4991,9 @@ static int drbd_do_features(struct drbd_connection *connection)
49914991
drbd_info(connection, "Agreed to%ssupport TRIM on protocol level\n",
49924992
connection->agreed_features & FF_TRIM ? " " : " not ");
49934993

4994+
drbd_info(connection, "Agreed to%ssupport THIN_RESYNC on protocol level\n",
4995+
connection->agreed_features & FF_THIN_RESYNC ? " " : " not ");
4996+
49944997
return 1;
49954998

49964999
incompat:

drivers/block/drbd/drbd_worker.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,7 @@ static int make_resync_request(struct drbd_device *const device, int cancel)
583583
int number, rollback_i, size;
584584
int align, requeue = 0;
585585
int i = 0;
586+
int discard_granularity = 0;
586587

587588
if (unlikely(cancel))
588589
return 0;
@@ -602,6 +603,12 @@ static int make_resync_request(struct drbd_device *const device, int cancel)
602603
return 0;
603604
}
604605

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+
605612
max_bio_size = queue_max_hw_sectors(device->rq_queue) << 9;
606613
number = drbd_rs_number_requests(device);
607614
if (number <= 0)
@@ -666,6 +673,9 @@ static int make_resync_request(struct drbd_device *const device, int cancel)
666673
if (sector & ((1<<(align+3))-1))
667674
break;
668675

676+
if (discard_granularity && size == discard_granularity)
677+
break;
678+
669679
/* do not cross extent boundaries */
670680
if (((bit+1) & BM_BLOCKS_PER_BM_EXT_MASK) == 0)
671681
break;
@@ -712,7 +722,8 @@ static int make_resync_request(struct drbd_device *const device, int cancel)
712722
int err;
713723

714724
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,
716727
sector, size, ID_SYNCER);
717728
if (err) {
718729
drbd_err(device, "drbd_send_drequest() failed, aborting...\n");

0 commit comments

Comments
 (0)