Commit 92d94ae6 authored by Philipp Reisner's avatar Philipp Reisner Committed by Jens Axboe

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: default avatarPhilipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: default avatarLars Ellenberg <lars.ellenberg@linbit.com>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent a5ca66c4
...@@ -165,6 +165,7 @@ struct p_block_req { ...@@ -165,6 +165,7 @@ struct p_block_req {
*/ */
#define FF_TRIM 1 #define FF_TRIM 1
#define FF_THIN_RESYNC 2
struct p_connection_features { struct p_connection_features {
u32 protocol_min; u32 protocol_min;
......
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
#include "drbd_req.h" #include "drbd_req.h"
#include "drbd_vli.h" #include "drbd_vli.h"
#define PRO_FEATURES (FF_TRIM) #define PRO_FEATURES (FF_TRIM | FF_THIN_RESYNC)
struct packet_info { struct packet_info {
enum drbd_packet cmd; enum drbd_packet cmd;
...@@ -4991,6 +4991,9 @@ static int drbd_do_features(struct drbd_connection *connection) ...@@ -4991,6 +4991,9 @@ static int drbd_do_features(struct drbd_connection *connection)
drbd_info(connection, "Agreed to%ssupport TRIM on protocol level\n", drbd_info(connection, "Agreed to%ssupport TRIM on protocol level\n",
connection->agreed_features & FF_TRIM ? " " : " not "); connection->agreed_features & FF_TRIM ? " " : " not ");
drbd_info(connection, "Agreed to%ssupport THIN_RESYNC on protocol level\n",
connection->agreed_features & FF_THIN_RESYNC ? " " : " not ");
return 1; return 1;
incompat: incompat:
......
...@@ -583,6 +583,7 @@ static int make_resync_request(struct drbd_device *const device, int cancel) ...@@ -583,6 +583,7 @@ static int make_resync_request(struct drbd_device *const device, int cancel)
int number, rollback_i, size; int number, rollback_i, size;
int align, requeue = 0; int align, requeue = 0;
int i = 0; int i = 0;
int discard_granularity = 0;
if (unlikely(cancel)) if (unlikely(cancel))
return 0; return 0;
...@@ -602,6 +603,12 @@ static int make_resync_request(struct drbd_device *const device, int cancel) ...@@ -602,6 +603,12 @@ static int make_resync_request(struct drbd_device *const device, int cancel)
return 0; return 0;
} }
if (connection->agreed_features & FF_THIN_RESYNC) {
rcu_read_lock();
discard_granularity = rcu_dereference(device->ldev->disk_conf)->rs_discard_granularity;
rcu_read_unlock();
}
max_bio_size = queue_max_hw_sectors(device->rq_queue) << 9; max_bio_size = queue_max_hw_sectors(device->rq_queue) << 9;
number = drbd_rs_number_requests(device); number = drbd_rs_number_requests(device);
if (number <= 0) if (number <= 0)
...@@ -666,6 +673,9 @@ static int make_resync_request(struct drbd_device *const device, int cancel) ...@@ -666,6 +673,9 @@ static int make_resync_request(struct drbd_device *const device, int cancel)
if (sector & ((1<<(align+3))-1)) if (sector & ((1<<(align+3))-1))
break; break;
if (discard_granularity && size == discard_granularity)
break;
/* do not cross extent boundaries */ /* do not cross extent boundaries */
if (((bit+1) & BM_BLOCKS_PER_BM_EXT_MASK) == 0) if (((bit+1) & BM_BLOCKS_PER_BM_EXT_MASK) == 0)
break; break;
...@@ -712,7 +722,8 @@ static int make_resync_request(struct drbd_device *const device, int cancel) ...@@ -712,7 +722,8 @@ static int make_resync_request(struct drbd_device *const device, int cancel)
int err; int err;
inc_rs_pending(device); inc_rs_pending(device);
err = drbd_send_drequest(peer_device, P_RS_DATA_REQUEST, err = drbd_send_drequest(peer_device,
size == discard_granularity ? P_RS_THIN_REQ : P_RS_DATA_REQUEST,
sector, size, ID_SYNCER); sector, size, ID_SYNCER);
if (err) { if (err) {
drbd_err(device, "drbd_send_drequest() failed, aborting...\n"); drbd_err(device, "drbd_send_drequest() failed, aborting...\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment