Accepting request 389406 from home:wanghaisu:branches:network:ha-clustering:Factory

Update to drbd9.

OBS-URL: https://build.opensuse.org/request/show/389406
OBS-URL: https://build.opensuse.org/package/show/network:ha-clustering:Factory/drbd?expand=0&rev=31
This commit is contained in:
nick wang 2016-04-13 12:42:42 +00:00 committed by Git OBS Bridge
parent 6a9bae1c9e
commit f9dc362b8e
15 changed files with 224 additions and 2249 deletions

View File

@ -1,529 +0,0 @@
From e15ba3799caf4cdcdf151078efe01e9a3f3ab206 Mon Sep 17 00:00:00 2001
From: Nick Wang <nwang@suse.com>
Date: Fri, 10 Jul 2015 17:28:18 +0800
Subject: [PATCH] drbd: Support zeroout device instead of initial full sync
Patch set for zeroing out device on both side
instead of initial full sync. Useful for high
latency network environment.
Implement --zeroout-devices and --discard-devices
for new-current-uuid
---
drbd/drbd_int.h | 15 +++++++
drbd/drbd_main.c | 60 +++++++++++++++++++++++++++-
drbd/drbd_nl.c | 41 +++++++++++++++++--
drbd/drbd_protocol.h | 2 +
drbd/drbd_receiver.c | 86 +++++++++++++++++++++++++++++++++++++++-
drbd/drbd_worker.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++
drbd/linux/drbd_genl.h | 2 +
7 files changed, 305 insertions(+), 6 deletions(-)
diff --git a/drbd/drbd_int.h b/drbd/drbd_int.h
index d1e2bc0..555b24c 100644
--- a/drbd/drbd_int.h
+++ b/drbd/drbd_int.h
@@ -621,6 +621,13 @@ enum {
RS_START, /* tell worker to start resync/OV */
RS_PROGRESS, /* tell worker that resync made significant progress */
RS_DONE, /* tell worker that resync is done */
+ P_ZERO_START, /* tell worker to zero out device */
+ S_ZERO_START, /* tell worker to zero out device as requested*/
+
+ /* used for zero out/discard device */
+ DISCARD_DISK, /* flag to discard device */
+ ZERO_DONE, /* succeed on zero out a device */
+ ZERO_FAIL, /* fail to zero out a device */
};
struct drbd_bitmap; /* opaque for drbd_device */
@@ -1204,6 +1211,11 @@ extern int __drbd_send_protocol(struct drbd_connection *connection, enum drbd_pa
extern int drbd_send_protocol(struct drbd_connection *connection);
extern int drbd_send_uuids(struct drbd_peer_device *);
extern int drbd_send_uuids_skip_initial_sync(struct drbd_peer_device *);
+extern int drbd_send_zeroout_start(struct drbd_peer_device *);
+extern int drbd_send_discard_start(struct drbd_peer_device *);
+extern int drbd_send_zeroout_finish(struct drbd_peer_device *);
+extern int drbd_send_zeroout_ok(struct drbd_peer_device *);
+extern int drbd_send_zeroout_fail(struct drbd_peer_device *);
extern void drbd_gen_and_send_sync_uuid(struct drbd_peer_device *);
extern int drbd_send_sizes(struct drbd_peer_device *peer_device, int trigger_reply, enum dds_flags flags);
extern int drbd_send_state(struct drbd_peer_device *, union drbd_state);
@@ -1661,6 +1673,9 @@ extern void drbd_send_acks_wf(struct work_struct *ws);
extern bool drbd_rs_c_min_rate_throttle(struct drbd_device *device);
extern bool drbd_rs_should_slow_down(struct drbd_device *device, sector_t sector,
bool throttle_if_app_is_waiting);
+extern int zeroout_local_device(struct drbd_device *device, bool discard);
+extern void require_zeroout_local_device(struct drbd_device *device);
+extern void receive_zeroout_local_device(struct drbd_device *device);
extern int drbd_submit_peer_request(struct drbd_device *,
struct drbd_peer_request *, const unsigned,
const int);
diff --git a/drbd/drbd_main.c b/drbd/drbd_main.c
index 31bf43f..badc719 100644
--- a/drbd/drbd_main.c
+++ b/drbd/drbd_main.c
@@ -908,6 +908,62 @@ int drbd_send_uuids_skip_initial_sync(struct drbd_peer_device *peer_device)
return _drbd_send_uuids(peer_device, 8);
}
+
+/**
+ * drbd_send_zeroout_start() - Notify peer node to zeroout device
+ * @peer_device: DRBD peer device.
+ */
+int drbd_send_zeroout_start(struct drbd_peer_device *peer_device)
+{
+ return _drbd_send_uuids(peer_device, 16);
+}
+
+/**
+ * drbd_send_discard_start() - Notify peer node to discard device
+ * @peer_device: DRBD peer device.
+ */
+int drbd_send_discard_start(struct drbd_peer_device *peer_device)
+{
+ return _drbd_send_uuids(peer_device, 32);
+}
+
+/**
+ * drbd_send_zeroout_finish() - Notify both node finished zeroing out
+ * @peer_device: DRBD peer device.
+ */
+int drbd_send_zeroout_finish(struct drbd_peer_device *peer_device)
+{
+ return _drbd_send_uuids(peer_device, 64);
+}
+
+/**
+ * _drbd_send_zeroout_state() - Sends the drbd state to the peer
+ * @peer_device: DRBD peer device.
+ * @state: Device zero out status.
+ */
+static int _drbd_send_zeroout_state(struct drbd_peer_device *peer_device, unsigned int status)
+{
+ struct drbd_socket *sock;
+ struct p_state *p;
+
+ sock = &peer_device->connection->data;
+ p = drbd_prepare_command(peer_device, sock);
+ if (!p)
+ return -EIO;
+ p->state = cpu_to_be32(status);
+ return drbd_send_command(peer_device, sock, P_ZERO_OUT, sizeof(*p), NULL, 0);
+}
+
+int drbd_send_zeroout_ok(struct drbd_peer_device *peer_device)
+{
+ return _drbd_send_zeroout_state(peer_device, 0);
+}
+
+int drbd_send_zeroout_fail(struct drbd_peer_device *peer_device)
+{
+ return _drbd_send_zeroout_state(peer_device, 1);
+}
+
void drbd_print_uuids(struct drbd_device *device, const char *text)
{
if (get_ldev_if_state(device, D_NEGOTIATING)) {
@@ -3466,8 +3522,8 @@ void drbd_uuid_move_history(struct drbd_device *device) __must_hold(local)
{
int i;
- for (i = UI_HISTORY_START; i < UI_HISTORY_END; i++)
- device->ldev->md.uuid[i+1] = device->ldev->md.uuid[i];
+ for (i = UI_HISTORY_END; i > UI_HISTORY_START; i--)
+ device->ldev->md.uuid[i] = device->ldev->md.uuid[i-1];
}
void __drbd_uuid_set(struct drbd_device *device, int idx, u64 val) __must_hold(local)
diff --git a/drbd/drbd_nl.c b/drbd/drbd_nl.c
index bb7e1b0..dc2bfec 100644
--- a/drbd/drbd_nl.c
+++ b/drbd/drbd_nl.c
@@ -4015,8 +4015,11 @@ int drbd_adm_new_c_uuid(struct sk_buff *skb, struct genl_info *info)
{
struct drbd_config_context adm_ctx;
struct drbd_device *device;
+ struct drbd_peer_device *peer_device = NULL;
enum drbd_ret_code retcode;
int skip_initial_sync = 0;
+ int zeroout_devices = 0;
+ int discard_devices = 0;
int err;
struct new_c_uuid_parms args;
@@ -4045,12 +4048,28 @@ int drbd_adm_new_c_uuid(struct sk_buff *skb, struct genl_info *info)
goto out;
}
+ peer_device = first_peer_device(device);
+
/* this is "skip initial sync", assume to be clean */
if (device->state.conn == C_CONNECTED &&
- first_peer_device(device)->connection->agreed_pro_version >= 90 &&
+ peer_device->connection->agreed_pro_version >= 90 &&
device->ldev->md.uuid[UI_CURRENT] == UUID_JUST_CREATED && args.clear_bm) {
drbd_info(device, "Preparing to skip initial sync\n");
skip_initial_sync = 1;
+ /* this is "zero out/discard" devices to make it all zero.
+ * ignore "zero out" if both "clear_bm" and "zeroout_devices/discard_devices" set. */
+ } else if (device->state.conn == C_CONNECTED &&
+ peer_device->connection->agreed_features & FF_DISCARD &&
+ device->ldev->md.uuid[UI_CURRENT] == UUID_JUST_CREATED &&
+ args.zeroout_devices) {
+ drbd_info(device, "Preparing to zero out devices, will take a long time\n");
+ zeroout_devices = 1;
+ } else if (device->state.conn == C_CONNECTED &&
+ peer_device->connection->agreed_features & FF_DISCARD &&
+ device->ldev->md.uuid[UI_CURRENT] == UUID_JUST_CREATED &&
+ args.discard_devices) {
+ drbd_info(device, "Preparing to discard devices, will take a long time\n");
+ discard_devices = 1;
} else if (device->state.conn != C_STANDALONE) {
retcode = ERR_CONNECTED;
goto out_dec;
@@ -4059,7 +4078,7 @@ int drbd_adm_new_c_uuid(struct sk_buff *skb, struct genl_info *info)
drbd_uuid_set(device, UI_BITMAP, 0); /* Rotate UI_BITMAP to History 1, etc... */
drbd_uuid_new_current(device); /* New current, previous to UI_BITMAP */
- if (args.clear_bm) {
+ if (args.clear_bm || args.zeroout_devices || args.discard_devices) {
err = drbd_bitmap_io(device, &drbd_bmio_clear_n_write,
"clear_n_write from new_c_uuid", BM_LOCKED_MASK);
if (err) {
@@ -4067,7 +4086,7 @@ int drbd_adm_new_c_uuid(struct sk_buff *skb, struct genl_info *info)
retcode = ERR_IO_MD_DISK;
}
if (skip_initial_sync) {
- drbd_send_uuids_skip_initial_sync(first_peer_device(device));
+ drbd_send_uuids_skip_initial_sync(peer_device);
_drbd_uuid_set(device, UI_BITMAP, 0);
drbd_print_uuids(device, "cleared bitmap UUID");
spin_lock_irq(&device->resource->req_lock);
@@ -4075,6 +4094,22 @@ int drbd_adm_new_c_uuid(struct sk_buff *skb, struct genl_info *info)
CS_VERBOSE, NULL);
spin_unlock_irq(&device->resource->req_lock);
}
+ if (zeroout_devices || discard_devices) {
+ if (discard_devices) {
+ drbd_send_discard_start(peer_device);
+ set_bit(DISCARD_DISK, &device->flags);
+ } else {
+ drbd_send_zeroout_start(peer_device);
+ clear_bit(DISCARD_DISK, &device->flags);
+ }
+ _drbd_uuid_set(device, UI_BITMAP, 0);
+ drbd_print_uuids(device, "cleared bitmap UUID for zeroing device");
+
+ /* CLear bit flag of zero out */
+ clear_bit(ZERO_DONE, &device->flags);
+ clear_bit(ZERO_FAIL, &device->flags);
+ drbd_device_post_work(device, P_ZERO_START);
+ }
}
drbd_md_sync(device);
diff --git a/drbd/drbd_protocol.h b/drbd/drbd_protocol.h
index 405b181..d9db0ce 100644
--- a/drbd/drbd_protocol.h
+++ b/drbd/drbd_protocol.h
@@ -59,6 +59,7 @@ enum drbd_packet {
/* REQ_DISCARD. We used "discard" in different contexts before,
* which is why I chose TRIM here, to disambiguate. */
P_TRIM = 0x31,
+ P_ZERO_OUT = 0x32,
P_MAY_IGNORE = 0x100, /* Flag to test if (cmd > P_MAY_IGNORE) ... */
P_MAX_OPT_CMD = 0x101,
@@ -161,6 +162,7 @@ struct p_block_req {
*/
#define FF_TRIM 1
+#define FF_DISCARD 4
struct p_connection_features {
u32 protocol_min;
diff --git a/drbd/drbd_receiver.c b/drbd/drbd_receiver.c
index 06e5667..ec324ef 100644
--- a/drbd/drbd_receiver.c
+++ b/drbd/drbd_receiver.c
@@ -47,7 +47,7 @@
#include "drbd_vli.h"
#include <linux/scatterlist.h>
-#define PRO_FEATURES (FF_TRIM)
+#define PRO_FEATURES (FF_TRIM | FF_DISCARD)
struct flush_work {
struct drbd_work w;
@@ -4317,6 +4317,20 @@ static int receive_uuids(struct drbd_connection *connection, struct packet_info
peer_device->connection->agreed_pro_version >= 90 &&
device->ldev->md.uuid[UI_CURRENT] == UUID_JUST_CREATED &&
(p_uuid[UI_FLAGS] & 8);
+ int zeroout_devices =
+ device->state.conn == C_CONNECTED &&
+ peer_device->connection->agreed_pro_version >= 90 &&
+ device->ldev->md.uuid[UI_CURRENT] == UUID_JUST_CREATED &&
+ (p_uuid[UI_FLAGS] & 16);
+ int discard_devices =
+ device->state.conn == C_CONNECTED &&
+ peer_device->connection->agreed_pro_version >= 90 &&
+ device->ldev->md.uuid[UI_CURRENT] == UUID_JUST_CREATED &&
+ (p_uuid[UI_FLAGS] & 32);
+ int zeroout_finish =
+ device->state.conn == C_CONNECTED &&
+ peer_device->connection->agreed_pro_version >= 90 &&
+ (p_uuid[UI_FLAGS] & 64);
if (skip_initial_sync) {
drbd_info(device, "Accepted new current UUID, preparing to skip initial sync\n");
drbd_bitmap_io(device, &drbd_bmio_clear_n_write,
@@ -4324,11 +4338,42 @@ static int receive_uuids(struct drbd_connection *connection, struct packet_info
BM_LOCKED_TEST_ALLOWED);
_drbd_uuid_set(device, UI_CURRENT, p_uuid[UI_CURRENT]);
_drbd_uuid_set(device, UI_BITMAP, 0);
+ spin_lock_irq(&device->resource->req_lock);
_drbd_set_state(_NS2(device, disk, D_UP_TO_DATE, pdsk, D_UP_TO_DATE),
CS_VERBOSE, NULL);
+ spin_unlock_irq(&device->resource->req_lock);
drbd_md_sync(device);
updated_uuids = 1;
}
+
+ if (zeroout_devices || discard_devices) {
+ if (discard_devices) {
+ drbd_info(device, "Accepted to discard devices, will take a long time\n");
+ set_bit(DISCARD_DISK, &device->flags);
+ } else {
+ drbd_info(device, "Accepted to zeroout devices, will take a long time\n");
+ clear_bit(DISCARD_DISK, &device->flags);
+ }
+
+ drbd_bitmap_io(device, &drbd_bmio_clear_n_write,
+ "clear_n_write from receive_uuids",
+ BM_LOCKED_TEST_ALLOWED);
+ _drbd_uuid_set(device, UI_CURRENT, p_uuid[UI_CURRENT]);
+ _drbd_uuid_set(device, UI_BITMAP, 0);
+ drbd_print_uuids(device, "cleared bitmap UUID for zeroing device");
+
+ drbd_device_post_work(device, S_ZERO_START);
+ updated_uuids = 1;
+ }
+
+ if (zeroout_finish) {
+ drbd_info(device, "Both side finished zero out devices.\n");
+ spin_lock_irq(&device->resource->req_lock);
+ _drbd_set_state(_NS2(device, disk, D_UP_TO_DATE, pdsk, D_UP_TO_DATE),
+ CS_VERBOSE, NULL);
+ spin_unlock_irq(&device->resource->req_lock);
+ }
+
put_ldev(device);
} else if (device->state.disk < D_INCONSISTENT &&
device->state.role == R_PRIMARY) {
@@ -4383,6 +4428,41 @@ static union drbd_state convert_state(union drbd_state ps)
return ms;
}
+static int receive_zeroout_state(struct drbd_connection *connection, struct packet_info *pi)
+{
+ struct drbd_peer_device *peer_device;
+ struct drbd_device *device;
+ struct p_state *p = pi->data;
+ unsigned int isfail;
+
+ peer_device = conn_peer_device(connection, pi->vnr);
+ if (!peer_device)
+ return -EIO;
+ device = peer_device->device;
+
+ isfail = be32_to_cpu(p->state);
+
+ if (isfail) {
+ drbd_info(device, "Failed to zero out peer device\n");
+ set_bit(ZERO_FAIL, &device->flags);
+ } else {
+ drbd_info(device, "Finished zero out peer device\n");
+ if (test_and_clear_bit(ZERO_DONE, &device->flags)) {
+ drbd_info(device, "Both side finished zeroing.\n");
+ spin_lock_irq(&device->resource->req_lock);
+ _drbd_set_state(_NS2(device, disk, D_UP_TO_DATE,
+ pdsk, D_UP_TO_DATE), CS_VERBOSE, NULL);
+ spin_unlock_irq(&device->resource->req_lock);
+ drbd_send_zeroout_finish(peer_device);
+ } else {
+ /* waiting for local device finished */
+ set_bit(ZERO_DONE, &device->flags);
+ }
+ }
+
+ return 0;
+}
+
static int receive_req_state(struct drbd_connection *connection, struct packet_info *pi)
{
struct drbd_peer_device *peer_device;
@@ -5008,6 +5088,7 @@ static struct data_cmd drbd_cmd_handler[] = {
[P_CONN_ST_CHG_REQ] = { 0, sizeof(struct p_req_state), receive_req_conn_state },
[P_PROTOCOL_UPDATE] = { 1, sizeof(struct p_protocol), receive_protocol },
[P_TRIM] = { 0, sizeof(struct p_trim), receive_Data },
+ [P_ZERO_OUT] = { 0, sizeof(struct p_state), receive_zeroout_state },
};
static void drbdd(struct drbd_connection *connection)
@@ -5287,6 +5368,9 @@ static int drbd_do_features(struct drbd_connection *connection)
drbd_info(connection, "Agreed to%ssupport TRIM on protocol level\n",
connection->agreed_features & FF_TRIM ? " " : " not ");
+ drbd_info(connection, "Agreed to%ssupport DISCARD DEVICE on protocol level\n",
+ connection->agreed_features & FF_DISCARD ? " " : " not ");
+
return 1;
incompat:
diff --git a/drbd/drbd_worker.c b/drbd/drbd_worker.c
index 2a15aeb..a8e231f 100644
--- a/drbd/drbd_worker.c
+++ b/drbd/drbd_worker.c
@@ -1653,6 +1653,105 @@ void drbd_rs_controller_reset(struct drbd_device *device)
rcu_read_unlock();
}
+/**
+ * zeroout_local_device()
+ * @device: DRBD device.
+ * @discard: whether to discard the block range.
+ *
+ * Description:
+ * Zero out drbd backing device when creating new uuid.
+ *
+**/
+int zeroout_local_device(struct drbd_device *device, bool discard)
+{
+ struct block_device *bdev;
+
+ bdev = device->ldev->backing_bdev;
+ if (device->ldev->known_size != drbd_get_capacity(bdev))
+ device->ldev->known_size = drbd_get_capacity(bdev);
+
+ if (discard){
+ /* zero out the backing device by discarding blocks */
+ return blkdev_issue_zeroout(bdev, 0,
+ device->ldev->known_size, GFP_NOIO, true);
+ } else {
+ /* zero out the backing device with WRITE call*/
+ return blkdev_issue_zeroout(bdev, 0,
+ device->ldev->known_size, GFP_NOIO, false);
+ }
+}
+
+/**
+ * require_zeroout_local_device()
+ * @device: DRBD device.
+ *
+ * Description:
+ * Start to zero out local device. Update
+ * status if peer node (secondary) finished
+ * zeroing.
+ *
+**/
+void require_zeroout_local_device(struct drbd_device *device)
+{
+ int zeroout_err = 0;
+
+ if (test_and_clear_bit(DISCARD_DISK, &device->flags)) {
+ zeroout_err = zeroout_local_device(device, true);
+ } else {
+ zeroout_err = zeroout_local_device(device, false);
+ }
+
+ if (zeroout_err) {
+ drbd_err(device, "Failed to zero out local device\n");
+ set_bit(ZERO_FAIL, &device->flags);
+ drbd_chk_io_error(device, 1, DRBD_WRITE_ERROR);
+ } else {
+ drbd_info(device, "Finished zero out local device.\n");
+
+ if (test_and_clear_bit(ZERO_DONE, &device->flags)) {
+ spin_lock_irq(&device->resource->req_lock);
+ _drbd_set_state(_NS2(device, disk, D_UP_TO_DATE,
+ pdsk, D_UP_TO_DATE), CS_VERBOSE, NULL);
+ spin_unlock_irq(&device->resource->req_lock);
+ drbd_send_zeroout_finish(first_peer_device(device));
+ } else if (test_and_clear_bit(ZERO_FAIL, &device->flags)) {
+ drbd_info(device, "Peer device has already failed on zero out\n");
+ } else {
+ /* waiting for peer device finished */
+ set_bit(ZERO_DONE, &device->flags);
+ }
+ }
+}
+
+/**
+ * receive_zeroout_local_device()
+ * @device: DRBD device.
+ *
+ * Description:
+ * Start to zero out local device.
+ * Notify peer node the zeroing result.
+ *
+**/
+void receive_zeroout_local_device(struct drbd_device *device)
+{
+ int zeroout_err = 0;
+ struct drbd_peer_device *const peer_device = first_peer_device(device);
+
+ if (test_and_clear_bit(DISCARD_DISK, &device->flags)) {
+ zeroout_err = zeroout_local_device(device, true);
+ } else {
+ zeroout_err = zeroout_local_device(device, false);
+ }
+ if (zeroout_err) {
+ drbd_err(device, "Failed to zero out local device\n");
+ drbd_send_zeroout_fail(peer_device);
+ drbd_chk_io_error(device, 1, DRBD_WRITE_ERROR);
+ } else {
+ drbd_info(device, "Finished zero out local device.\n");
+ drbd_send_zeroout_ok(peer_device);
+ }
+}
+
void start_resync_timer_fn(unsigned long data)
{
struct drbd_device *device = (struct drbd_device *) data;
@@ -1986,6 +2085,10 @@ static void do_device_work(struct drbd_device *device, const unsigned long todo)
drbd_ldev_destroy(device);
if (test_bit(RS_START, &todo))
do_start_resync(device);
+ if (test_bit(P_ZERO_START, &todo))
+ require_zeroout_local_device(device);
+ if (test_bit(S_ZERO_START, &todo))
+ receive_zeroout_local_device(device);
}
#define DRBD_DEVICE_WORK_MASK \
@@ -1995,6 +2098,8 @@ static void do_device_work(struct drbd_device *device, const unsigned long todo)
|(1UL << RS_START) \
|(1UL << RS_PROGRESS) \
|(1UL << RS_DONE) \
+ |(1UL << P_ZERO_START) \
+ |(1UL << S_ZERO_START) \
)
static unsigned long get_work_bits(unsigned long *flags)
diff --git a/drbd/linux/drbd_genl.h b/drbd/linux/drbd_genl.h
index 5db53f5..5a31a5c 100644
--- a/drbd/linux/drbd_genl.h
+++ b/drbd/linux/drbd_genl.h
@@ -240,6 +240,8 @@ GENL_struct(DRBD_NLA_START_OV_PARMS, 9, start_ov_parms,
GENL_struct(DRBD_NLA_NEW_C_UUID_PARMS, 10, new_c_uuid_parms,
__flg_field(1, DRBD_GENLA_F_MANDATORY, clear_bm)
+ __flg_field(2, 0, zeroout_devices)
+ __flg_field(3, 0, discard_devices)
)
GENL_struct(DRBD_NLA_TIMEOUT_PARMS, 11, timeout_parms,
--
2.1.4

View File

@ -1 +1,2 @@
updates/drbd.ko
updates/drbd_transport_tcp.ko

24
_service Normal file
View File

@ -0,0 +1,24 @@
<services>
<service name="tar_scm">
<param name="url">git://git.linbit.com/drbd-9.0.git</param>
<param name="scm">git</param>
<param name="filename">drbd</param>
<!--
To update to a new release, change "revision" to the desired
git commit hash and bump "version" if necessary
<param name="version">9.0.1</param>
-->
<param name="versionformat">9.0.1+git.%h</param>
<param name="revision">86e443973082570aeb651848db89e0c7b995c306</param>
</service>
<service name="recompress">
<param name="file">*drbd*.tar</param>
<param name="compression">bz2</param>
</service>
<service name="set_version">
<param name="basename">drbd</param>
</service>
</services>

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:35e160ffffed266f54e50db947cf103a544261b7a416cb1b55aa346ea04bf90b
size 282912

View File

@ -0,0 +1,113 @@
#
# spec file for package drbd
#
# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
# Please submit bugfixes or comments via http://bugs.opensuse.org/
#
# needssslcertforbuild
%ifarch x86_64
%define buildrt 0
%endif
Name: drbd
Version: 9.0.1+git.86e4439
Release: 0
Summary: DRBD driver for Linux
License: GPL-2.0
Group: Productivity/Clustering/HA
Url: http://drbd.linbit.com/
Source: %{name}-%{version}.tar.bz2
Source1: preamble
#In kernel is: kernel/drivers/block/drbd/drbd.ko
Source2: Module.supported
Source3: drbd_git_revision
Patch0: kernel-4.5-compat.patch
BuildRequires: kernel-source
BuildRequires: kernel-syms
BuildRequires: module-init-tools
%if 0%{?buildrt} == 1
BuildRequires: kernel-source-rt
BuildRequires: kernel-syms-rt
%endif
Requires: drbd-utils >= 8.9.6
Supplements: drbd-utils >= 8.9.6
Obsoletes: drbd-kmp < %{version}
BuildRoot: %{_tmppath}/%{name}-%{version}-build
ExcludeArch: i586 s390
%kernel_module_package -n drbd -p %_sourcedir/preamble
%description
Drbd is a distributed replicated block device. It mirrors a block
device over the network to another machine. Think of it as networked
raid 1. It is a building block for setting up clusters.
%package KMP
Summary: Kernel driver for DRBD
Group: Productivity/Clustering/HA
%description KMP
This module is the kernel-dependent driver for DRBD. This is split out so
that multiple kernel driver versions can be installed, one for each
installed kernel.
%prep
%setup -q -n drbd-%{version}
%patch0 -p1
mkdir source
cp -a drbd/. source/. || :
cp $RPM_SOURCE_DIR/drbd_git_revision source/.drbd_git_revision
%build
rm -rf obj
mkdir obj
ln -s ../scripts obj/
export CONFIG_BLK_DEV_DRBD=m
export EXTRA_CFLAGS='-DVERSION=\"%{version}\"'
for flavor in %flavors_to_build; do
rm -rf $flavor
cp -r source $flavor
cp %_sourcedir/Module.supported $flavor
export DRBDSRC="$PWD/obj/$flavor"
make -C %{kernel_source $flavor} modules M=$PWD/$flavor
done
%install
export INSTALL_MOD_PATH=%{buildroot}
export INSTALL_MOD_DIR=updates
for flavor in %{flavors_to_build}; do
make -C %{kernel_source $flavor} modules_install M=$PWD/$flavor
done
mkdir -p %{buildroot}/%{_sbindir}
%{__ln_s} -f %{_sbindir}/service %{buildroot}/%{_sbindir}/rc%{name}
rm -f drbd.conf
%clean
rm -rf %{buildroot}
%files
%defattr(-,root,root)
%doc COPYING
%doc ChangeLog
%{_sbindir}/rc%{name}
%changelog

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c10c4d7a5389a9194eb2f7c094a3c1685b87f52513ae0af15fdc1df6a091d014
size 321974

View File

@ -1,15 +0,0 @@
---
drbd/Kbuild | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: drbd-8.4.6/drbd/Kbuild
===================================================================
--- drbd-8.4.6.orig/drbd/Kbuild
+++ drbd-8.4.6/drbd/Kbuild
@@ -134,5 +134,5 @@ $(obj)/drbd_buildtag.c: $(filter-out drb
echo >&2 "Your DRBD source tree is broken. Unpack again."; \
exit 1; \
fi ; \
- echo -e "\t\t\" build by $$USER@$$HOSTNAME, `date "+%F %T"`\";\n}"; \
+ echo -e "\t\t\" build by $$USER\";\n}"; \
mv --force $@.new $@

View File

@ -1,8 +1,23 @@
-------------------------------------------------------------------
Mon Mar 7 14:23:53 UTC 2016 - olaf@aepfle.de
Fri Apr 8 14:44:21 UTC 2016 - nwang@suse.com
- Remove timstamp from binaries
Add patch drbd-buildcompare.patch
- Compat with kernel 4.5
- Add patch kernel-4.5-compat.patch
-------------------------------------------------------------------
Mon Mar 7 08:42:41 UTC 2016 - nwang@suse.com
- Update to release drbd-9.0.1
- Depend on drbd-utils >= 8.9.6
-------------------------------------------------------------------
Mon Nov 30 14:31:22 UTC 2015 - nwang@suse.com
- Update to released drbd-9.0.0
- Remove patch 0001-Support-zeroout-device-in-initial-sync.patch
- Remove patch update-to-8.4.6-5.patch
- Remove patch rename-GFP_WAIT-to-GFP_RECLAIM.patch
- Remove patch new-bio-struct.patch
-------------------------------------------------------------------
Fri Nov 20 06:50:29 UTC 2015 - nwang@suse.com

View File

@ -21,38 +21,31 @@
%ifarch x86_64
%define buildrt 0
%endif
Name: drbd
Version: 8.4.6
Version: @VERSION@
Release: 0
Summary: Distributed Replicated Block Device
License: GPL-2.0+
Summary: DRBD driver for Linux
License: GPL-2.0
Group: Productivity/Clustering/HA
Url: http://www.drbd.org/
Source: http://oss.linbit.com/drbd/8.4/%{name}-%{version}.tar.gz
Url: http://drbd.linbit.com/
Source: %{name}-%{version}.tar.bz2
Source1: preamble
#In kernel is: kernel/drivers/block/drbd/drbd.ko
Source2: Module.supported
Patch1: update-to-8.4.6-5.patch
#Patch for supporting drbd KMP after kernel4.3
#This patch can be removed when using in-tree 4.3
Patch2: new-bio-struct.patch
#Patch for fate: https://fate.suse.com/317940
#Whether can merge into linbit is under discussion
Patch3: 0001-Support-zeroout-device-in-initial-sync.patch
Patch4: rename-GFP_WAIT-to-GFP_RECLAIM.patch
Patch5: drbd-buildcompare.patch
Source3: drbd_git_revision
Patch0: kernel-4.5-compat.patch
BuildRequires: kernel-source
BuildRequires: kernel-syms
BuildRequires: module-init-tools
%if 0%{?buildrt} == 1
BuildRequires: kernel-source-rt
BuildRequires: kernel-syms-rt
%endif
Requires: drbd-utils >= 8.9.0
Supplements: drbd-utils >= 8.9.0
Requires: drbd-utils >= 8.9.6
Supplements: drbd-utils >= 8.9.6
Obsoletes: drbd-kmp < %{version}
BuildRoot: %{_tmppath}/%{name}-%{version}-build
ExcludeArch: i586 s390
@ -75,33 +68,33 @@ installed kernel.
%prep
%setup -q -n drbd-%{version}
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch0 -p1
mkdir source
cp -a drbd/. source/. || :
cp $RPM_SOURCE_DIR/drbd_git_revision source/.drbd_git_revision
%build
rm -rf obj
mkdir obj
ln -s ../scripts obj/
for flavor in %{flavors_to_build}; do
cp -r drbd obj/$flavor
cp %_sourcedir/Module.supported obj/$flavor
#make -C %{kernel_source $flavor} modules M=$PWD/obj/$flavor
make -C obj/$flavor %{_smp_mflags} all KDIR=%{kernel_source $flavor}
export CONFIG_BLK_DEV_DRBD=m
export EXTRA_CFLAGS='-DVERSION=\"%{version}\"'
for flavor in %flavors_to_build; do
rm -rf $flavor
cp -r source $flavor
cp %_sourcedir/Module.supported $flavor
export DRBDSRC="$PWD/obj/$flavor"
make -C %{kernel_source $flavor} modules M=$PWD/$flavor
done
%install
export INSTALL_MOD_PATH=%{buildroot}
export INSTALL_MOD_DIR=updates
for flavor in %{flavors_to_build} ; do
make -C %{kernel_source $flavor} modules_install M=$PWD/obj/$flavor
#From upstream file: drbd-kernel.spec
#kernelrelease=$(cat %{kernel_source $flavor}/include/config/kernel.release || make -s -C %{kernel_source $flavor} kernelrelease)
#mv obj/$flavor/.kernel.config.gz obj/k-config-$kernelrelease.gz
for flavor in %{flavors_to_build}; do
make -C %{kernel_source $flavor} modules_install M=$PWD/$flavor
done
mkdir -p %{buildroot}/%{_sbindir}

1
drbd_git_revision Normal file
View File

@ -0,0 +1 @@
GIT-hash: 86e443973082570aeb651848db89e0c7b995c306

35
kernel-4.5-compat.patch Normal file
View File

@ -0,0 +1,35 @@
diff -Naur drbd-9.0.1+git.86e4439.orig/drbd/drbd-kernel-compat/drbd_wrappers.h drbd-9.0.1+git.86e4439/drbd/drbd-kernel-compat/drbd_wrappers.h
--- drbd-9.0.1+git.86e4439.orig/drbd/drbd-kernel-compat/drbd_wrappers.h 2016-04-08 21:56:02.872683041 +0800
+++ drbd-9.0.1+git.86e4439/drbd/drbd-kernel-compat/drbd_wrappers.h 2016-04-08 22:03:05.732665258 +0800
@@ -1529,31 +1529,6 @@
}
#endif
-#ifndef COMPAT_HAVE_IB_CQ_INIT_ATTR
-#include <rdma/ib_verbs.h>
-
-struct ib_cq_init_attr {
- unsigned int cqe;
- int comp_vector;
- u32 flags;
-};
-
-static inline struct ib_cq *
-drbd_ib_create_cq(struct ib_device *device,
- ib_comp_handler comp_handler,
- void (*event_handler)(struct ib_event *, void *),
- void *cq_context,
- const struct ib_cq_init_attr *cq_attr)
-{
- return ib_create_cq(device, comp_handler, event_handler, cq_context,
- cq_attr->cqe, cq_attr->comp_vector);
-}
-
-#define ib_create_cq(DEV, COMP_H, EVENT_H, CTX, ATTR) \
- drbd_ib_create_cq(DEV, COMP_H, EVENT_H, CTX, ATTR)
-#endif
-
-
#ifndef COMPAT_RDMA_CREATE_ID_HAS_NET_NS
/* Since linux v4.4 it has a network namespace as first argument */
#define rdma_create_id(NS, H, C, P, T) rdma_create_id(H, C, P, T)

View File

@ -1,391 +0,0 @@
From 641de14e15547788055e15b1db4601a436f048bb Mon Sep 17 00:00:00 2001
From: Nick Wang <nwang@suse.com>
Date: Fri, 16 Oct 2015 10:16:47 +0800
Subject: [PATCH] fix failure with new bi_error field of bio
drbd fail to build with new bio structure and interface
after 4.3.0, see 4246a0b63bd8f56a1469b12eafeb875b1041a451
A new bi_error field to store an errno value directly in
struct bio and remove the existing mechanisms to clean
all this up.
With 8ae126660fddbeebb9251a174e6fa45b6ad8f932,
generic_make_request() is now able to handle arbitrarily
sized bios,it's no longer need to define its merge_bvec_fn.
This patch delete merge_bvec_fn and support new bio struct.
---
drbd/drbd_actlog.c | 4 ++
drbd/drbd_bitmap.c | 46 +++++++++++++++++++++
drbd/drbd_int.h | 2 +
drbd/drbd_main.c | 2 +
drbd/drbd_req.c | 4 +-
drbd/drbd_worker.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++
drbd/drbd_wrappers.h | 31 +++++++++++++-
7 files changed, 201 insertions(+), 2 deletions(-)
diff --git a/drbd/drbd_actlog.c b/drbd/drbd_actlog.c
index 1a274c5..c73bb32 100644
--- a/drbd/drbd_actlog.c
+++ b/drbd/drbd_actlog.c
@@ -184,7 +184,11 @@ static int _drbd_md_sync_page_io(struct drbd_device *device,
else
submit_bio(rw, bio);
wait_until_done_or_force_detached(device, bdev, &device->md_io.done);
+#ifdef NO_ERROR_BIO_END_IO
+ if (bio->bi_error)
+#else
if (bio_flagged(bio, BIO_UPTODATE))
+#endif
err = device->md_io.error;
#ifndef REQ_FLUSH
diff --git a/drbd/drbd_bitmap.c b/drbd/drbd_bitmap.c
index abf1bc1..2e16bc8 100644
--- a/drbd/drbd_bitmap.c
+++ b/drbd/drbd_bitmap.c
@@ -960,6 +960,51 @@ static void drbd_bm_aio_ctx_destroy(struct kref *kref)
}
/* bv_page may be a copy, or may be the original */
+#ifdef NO_ERROR_BIO_END_IO
+static BIO_ENDIO_TYPE drbd_bm_endio BIO_ENDIO_ARGS(struct bio *bio)
+{
+ struct drbd_bm_aio_ctx *ctx = bio->bi_private;
+ struct drbd_device *device = ctx->device;
+ struct drbd_bitmap *b = device->bitmap;
+ unsigned int idx = bm_page_to_idx(bio->bi_io_vec[0].bv_page);
+
+ BIO_ENDIO_FN_START;
+
+ if ((ctx->flags & BM_AIO_COPY_PAGES) == 0 &&
+ !bm_test_page_unchanged(b->bm_pages[idx]))
+ drbd_warn(device, "bitmap page idx %u changed during IO!\n", idx);
+
+ if (bio->bi_error) {
+ /* ctx error will hold the completed-last non-zero error code,
+ * in case error codes differ. */
+ ctx->error = bio->bi_error;
+ bm_set_page_io_err(b->bm_pages[idx]);
+ /* Not identical to on disk version of it.
+ * Is BM_PAGE_IO_ERROR enough? */
+ if (DRBD_ratelimit(5*HZ, 5))
+ drbd_err(device, "IO ERROR %d on bitmap page idx %u\n",
+ bio->bi_error, idx);
+ } else {
+ bm_clear_page_io_err(b->bm_pages[idx]);
+ dynamic_drbd_dbg(device, "bitmap page idx %u completed\n", idx);
+ }
+
+ bm_page_unlock_io(device, idx);
+
+ if (ctx->flags & BM_AIO_COPY_PAGES)
+ mempool_free(bio->bi_io_vec[0].bv_page, drbd_md_io_page_pool);
+
+ bio_put(bio);
+
+ if (atomic_dec_and_test(&ctx->in_flight)) {
+ ctx->done = 1;
+ wake_up(&device->misc_wait);
+ kref_put(&ctx->kref, &drbd_bm_aio_ctx_destroy);
+ }
+
+ BIO_ENDIO_FN_RETURN;
+}
+#else
static BIO_ENDIO_TYPE drbd_bm_endio BIO_ENDIO_ARGS(struct bio *bio, int error)
{
struct drbd_bm_aio_ctx *ctx = bio->bi_private;
@@ -1011,6 +1056,7 @@ static BIO_ENDIO_TYPE drbd_bm_endio BIO_ENDIO_ARGS(struct bio *bio, int error)
BIO_ENDIO_FN_RETURN;
}
+#endif
static void bm_page_io_async(struct drbd_bm_aio_ctx *ctx, int page_nr) __must_hold(local)
{
diff --git a/drbd/drbd_int.h b/drbd/drbd_int.h
index d1e2bc0..bed73cc 100644
--- a/drbd/drbd_int.h
+++ b/drbd/drbd_int.h
@@ -1563,6 +1563,7 @@ extern void do_submit(struct work_struct *ws);
extern void __drbd_make_request(struct drbd_device *, struct bio *, unsigned long);
extern MAKE_REQUEST_TYPE drbd_make_request(struct request_queue *q, struct bio *bio);
extern int drbd_read_remote(struct drbd_device *device, struct drbd_request *req);
+#ifndef NO_ERROR_BIO_END_IO
extern int drbd_merge_bvec(struct request_queue *q,
#ifdef HAVE_bvec_merge_data
struct bvec_merge_data *bvm,
@@ -1570,6 +1571,7 @@ extern int drbd_merge_bvec(struct request_queue *q,
struct bio *bvm,
#endif
struct bio_vec *bvec);
+#endif
extern int is_valid_ar_handle(struct drbd_request *, sector_t);
diff --git a/drbd/drbd_main.c b/drbd/drbd_main.c
index 31bf43f..6171714 100644
--- a/drbd/drbd_main.c
+++ b/drbd/drbd_main.c
@@ -2855,7 +2855,9 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig
This triggers a max_bio_size message upon first attach or connect */
blk_queue_max_hw_sectors(q, DRBD_MAX_BIO_SIZE_SAFE >> 8);
blk_queue_bounce_limit(q, BLK_BOUNCE_ANY);
+#ifndef NO_ERROR_BIO_END_IO
blk_queue_merge_bvec(q, drbd_merge_bvec);
+#endif
q->queue_lock = &resource->req_lock;
#ifdef blk_queue_plugged
/* plugging on a queue, that actually has no requests! */
diff --git a/drbd/drbd_req.c b/drbd/drbd_req.c
index 305fe71..e7b1b14 100644
--- a/drbd/drbd_req.c
+++ b/drbd/drbd_req.c
@@ -1573,6 +1573,7 @@ MAKE_REQUEST_TYPE drbd_make_request(struct request_queue *q, struct bio *bio)
* As long as the BIO is empty we have to allow at least one bvec,
* regardless of size and offset, so no need to ask lower levels.
*/
+#ifndef NO_ERROR_BIO_END_IO
#ifdef HAVE_bvec_merge_data
int drbd_merge_bvec(struct request_queue *q,
struct bvec_merge_data *bvm,
@@ -1604,7 +1605,7 @@ int drbd_merge_bvec(struct request_queue *q,
struct bio_vec *bvec)
{
struct drbd_device *device = (struct drbd_device *) q->queuedata;
- unsigned int bio_size = bvm->bi_size;
+ unsigned int bio_size = bvm->bi_iter.bi_size;
int limit = DRBD_MAX_BIO_SIZE;
int backing_limit;
@@ -1626,6 +1627,7 @@ int drbd_merge_bvec(struct request_queue *q,
return limit;
}
#endif
+#endif /* END NO_ERROR_BIO_END_IO*/
static bool net_timeout_reached(struct drbd_request *net_req,
struct drbd_connection *connection,
diff --git a/drbd/drbd_worker.c b/drbd/drbd_worker.c
index 2a15aeb..391237e 100644
--- a/drbd/drbd_worker.c
+++ b/drbd/drbd_worker.c
@@ -58,14 +58,22 @@ static int make_resync_request(struct drbd_device *, int);
/* used for synchronous meta data and bitmap IO
* submitted by drbd_md_sync_page_io()
*/
+#ifdef NO_ERROR_BIO_END_IO
+BIO_ENDIO_TYPE drbd_md_endio BIO_ENDIO_ARGS(struct bio *bio)
+#else
BIO_ENDIO_TYPE drbd_md_endio BIO_ENDIO_ARGS(struct bio *bio, int error)
+#endif
{
struct drbd_device *device;
BIO_ENDIO_FN_START;
device = bio->bi_private;
+#ifdef NO_ERROR_BIO_END_IO
+ device->md_io.error = bio->bi_error;
+#else
device->md_io.error = error;
+#endif
/* We grabbed an extra reference in _drbd_md_sync_page_io() to be able
* to timeout on the lower level device, and eventually detach from it.
@@ -194,6 +202,34 @@ void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __releases(l
/* writes on behalf of the partner, or resync writes,
* "submitted" by the receiver.
*/
+#ifdef NO_ERROR_BIO_END_IO
+BIO_ENDIO_TYPE drbd_peer_request_endio BIO_ENDIO_ARGS(struct bio *bio)
+{
+ struct drbd_peer_request *peer_req = bio->bi_private;
+ struct drbd_device *device = peer_req->peer_device->device;
+ int is_write = bio_data_dir(bio) == WRITE;
+ int is_discard = !!(bio->bi_rw & DRBD_REQ_DISCARD);
+
+ BIO_ENDIO_FN_START;
+ if (bio->bi_error && DRBD_ratelimit(5*HZ, 5))
+ drbd_warn(device, "%s: error=%d s=%llus\n",
+ is_write ? (is_discard ? "discard" : "write")
+ : "read", bio->bi_error,
+ (unsigned long long)peer_req->i.sector);
+
+ if (bio->bi_error)
+ set_bit(__EE_WAS_ERROR, &peer_req->flags);
+
+ bio_put(bio); /* no need for the bio anymore */
+ if (atomic_dec_and_test(&peer_req->pending_bios)) {
+ if (is_write)
+ drbd_endio_write_sec_final(peer_req);
+ else
+ drbd_endio_read_sec_final(peer_req);
+ }
+ BIO_ENDIO_FN_RETURN;
+}
+#else
BIO_ENDIO_TYPE drbd_peer_request_endio BIO_ENDIO_ARGS(struct bio *bio, int error)
{
struct drbd_peer_request *peer_req = bio->bi_private;
@@ -231,6 +267,7 @@ BIO_ENDIO_TYPE drbd_peer_request_endio BIO_ENDIO_ARGS(struct bio *bio, int error
}
BIO_ENDIO_FN_RETURN;
}
+#endif
void drbd_panic_after_delayed_completion_of_aborted_request(struct drbd_device *device)
{
@@ -240,6 +277,82 @@ void drbd_panic_after_delayed_completion_of_aborted_request(struct drbd_device *
/* read, readA or write requests on R_PRIMARY coming from drbd_make_request
*/
+#ifdef NO_ERROR_BIO_END_IO
+BIO_ENDIO_TYPE drbd_request_endio BIO_ENDIO_ARGS(struct bio *bio)
+{
+ unsigned long flags;
+ struct drbd_request *req = bio->bi_private;
+ struct drbd_device *device = req->device;
+ struct bio_and_error m;
+ enum drbd_req_event what;
+
+ BIO_ENDIO_FN_START;
+
+ /* If this request was aborted locally before,
+ * but now was completed "successfully",
+ * chances are that this caused arbitrary data corruption.
+ *
+ * "aborting" requests, or force-detaching the disk, is intended for
+ * completely blocked/hung local backing devices which do no longer
+ * complete requests at all, not even do error completions. In this
+ * situation, usually a hard-reset and failover is the only way out.
+ *
+ * By "aborting", basically faking a local error-completion,
+ * we allow for a more graceful swichover by cleanly migrating services.
+ * Still the affected node has to be rebooted "soon".
+ *
+ * By completing these requests, we allow the upper layers to re-use
+ * the associated data pages.
+ *
+ * If later the local backing device "recovers", and now DMAs some data
+ * from disk into the original request pages, in the best case it will
+ * just put random data into unused pages; but typically it will corrupt
+ * meanwhile completely unrelated data, causing all sorts of damage.
+ *
+ * Which means delayed successful completion,
+ * especially for READ requests,
+ * is a reason to panic().
+ *
+ * We assume that a delayed *error* completion is OK,
+ * though we still will complain noisily about it.
+ */
+ if (unlikely(req->rq_state & RQ_LOCAL_ABORTED)) {
+ if (DRBD_ratelimit(5*HZ, 5))
+ drbd_emerg(device, "delayed completion of aborted local request; disk-timeout may be too aggressive\n");
+
+ if (!bio->bi_error)
+ drbd_panic_after_delayed_completion_of_aborted_request(device);
+ }
+
+ /* to avoid recursion in __req_mod */
+ if (unlikely(bio->bi_error)) {
+ if (bio->bi_rw & DRBD_REQ_DISCARD)
+ what = (bio->bi_error == -EOPNOTSUPP)
+ ? DISCARD_COMPLETED_NOTSUPP
+ : DISCARD_COMPLETED_WITH_ERROR;
+ else
+ what = (bio_data_dir(bio) == WRITE)
+ ? WRITE_COMPLETED_WITH_ERROR
+ : (bio_rw(bio) == READ)
+ ? READ_COMPLETED_WITH_ERROR
+ : READ_AHEAD_COMPLETED_WITH_ERROR;
+ } else
+ what = COMPLETED_OK;
+
+ bio_put(req->private_bio);
+ req->private_bio = ERR_PTR(bio->bi_error);
+
+ /* not req_mod(), we need irqsave here! */
+ spin_lock_irqsave(&device->resource->req_lock, flags);
+ __req_mod(req, what, &m);
+ spin_unlock_irqrestore(&device->resource->req_lock, flags);
+ put_ldev(device);
+
+ if (m.bio)
+ complete_master_bio(device, &m);
+ BIO_ENDIO_FN_RETURN;
+}
+#else
BIO_ENDIO_TYPE drbd_request_endio BIO_ENDIO_ARGS(struct bio *bio, int error)
{
unsigned long flags;
@@ -324,6 +437,7 @@ BIO_ENDIO_TYPE drbd_request_endio BIO_ENDIO_ARGS(struct bio *bio, int error)
complete_master_bio(device, &m);
BIO_ENDIO_FN_RETURN;
}
+#endif
void drbd_csum_ee(struct crypto_hash *tfm, struct drbd_peer_request *peer_req, void *digest)
{
diff --git a/drbd/drbd_wrappers.h b/drbd/drbd_wrappers.h
index d7a4138..c9ccb93 100644
--- a/drbd/drbd_wrappers.h
+++ b/drbd/drbd_wrappers.h
@@ -195,16 +195,38 @@ static inline int drbd_blkdev_put(struct block_device *bdev, fmode_t mode)
#define BIO_ENDIO_FN_START if (bio->bi_size) return 1
#define BIO_ENDIO_FN_RETURN return 0
#else
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,3,0)
+ /* After Linux-4.3 a new bi_error field to store an errno value in struct bio.
+ See 4246a0b63bd8f56a1469b12eafeb875b1041a451 */
+ #define bio_endio(B,E) \
+ do { \
+ (B)->bi_error = (E); \
+ bio_endio(B); \
+ } while (0)
+ #define BIO_ENDIO_ARGS(b) (b)
+ #else
+ #define BIO_ENDIO_ARGS(b,e) (b,e)
+ #endif
#define BIO_ENDIO_TYPE void
-#define BIO_ENDIO_ARGS(b,e) (b,e)
#define BIO_ENDIO_FN_START do {} while (0)
#define BIO_ENDIO_FN_RETURN return
#endif
/* bi_end_io handlers */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,3,0)
+#undef NO_ERROR_BIO_END_IO
+#define NO_ERROR_BIO_END_IO 1
+#endif
+
+#ifdef NO_ERROR_BIO_END_IO
+extern BIO_ENDIO_TYPE drbd_md_endio BIO_ENDIO_ARGS(struct bio *bio);
+extern BIO_ENDIO_TYPE drbd_peer_request_endio BIO_ENDIO_ARGS(struct bio *bio);
+extern BIO_ENDIO_TYPE drbd_request_endio BIO_ENDIO_ARGS(struct bio *bio);
+#else
extern BIO_ENDIO_TYPE drbd_md_endio BIO_ENDIO_ARGS(struct bio *bio, int error);
extern BIO_ENDIO_TYPE drbd_peer_request_endio BIO_ENDIO_ARGS(struct bio *bio, int error);
extern BIO_ENDIO_TYPE drbd_request_endio BIO_ENDIO_ARGS(struct bio *bio, int error);
+#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
#define part_inc_in_flight(A, B) part_inc_in_flight(A)
@@ -222,6 +244,13 @@ extern BIO_ENDIO_TYPE drbd_request_endio BIO_ENDIO_ARGS(struct bio *bio, int err
# define HAVE_bvec_merge_data 1
#endif
+/* After 4.3.0 (with 8ae126660fddbeebb9251a174e6fa45b6ad8f932)
+ bvec_merge_data was killed. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,3,0)
+# undef HAVE_bvec_merge_data
+#endif
+
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
static inline void sg_set_page(struct scatterlist *sg, struct page *page,
unsigned int len, unsigned int offset)
--
2.1.4

View File

@ -1,3 +1,4 @@
Requires: kernel-%1
Requires: kernel-%1
Supplements: packageand(kernel-%1:%name)
Recommends: drbd
Recommends: drbd-utils

View File

@ -1,32 +0,0 @@
Index: drbd-8.4.6/drbd/drbd_bitmap.c
===================================================================
--- drbd-8.4.6.orig/drbd/drbd_bitmap.c
+++ drbd-8.4.6/drbd/drbd_bitmap.c
@@ -1084,7 +1084,11 @@ static void bm_page_io_async(struct drbd
bm_set_page_unchanged(b->bm_pages[page_nr]);
if (ctx->flags & BM_AIO_COPY_PAGES) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)
+ page = mempool_alloc(drbd_md_io_page_pool, __GFP_HIGHMEM|__GFP_RECLAIM);
+#else
page = mempool_alloc(drbd_md_io_page_pool, __GFP_HIGHMEM|__GFP_WAIT);
+#endif
copy_highpage(page, b->bm_pages[page_nr]);
bm_store_page_idx(page, page_nr);
} else
Index: drbd-8.4.6/drbd/drbd_receiver.c
===================================================================
--- drbd-8.4.6.orig/drbd/drbd_receiver.c
+++ drbd-8.4.6/drbd/drbd_receiver.c
@@ -421,7 +421,11 @@ drbd_alloc_peer_req(struct drbd_peer_dev
}
if (has_payload && data_size) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)
+ page = drbd_alloc_pages(peer_device, nr_pages, (gfp_mask & __GFP_RECLAIM));
+#else
page = drbd_alloc_pages(peer_device, nr_pages, (gfp_mask & __GFP_WAIT));
+#endif
if (!page)
goto fail;
}

File diff suppressed because it is too large Load Diff