diff --git a/0001-drbd-allow-transports-to-take-additional-krefs-on-a-.patch b/0001-drbd-allow-transports-to-take-additional-krefs-on-a-.patch new file mode 100644 index 0000000..a0b8893 --- /dev/null +++ b/0001-drbd-allow-transports-to-take-additional-krefs-on-a-.patch @@ -0,0 +1,37 @@ +From 0dda200877d1b801fba948a5948f321bee1a75a9 Mon Sep 17 00:00:00 2001 +From: Philipp Reisner +Date: Fri, 1 Sep 2023 08:03:01 +0200 +Subject: [PATCH 01/20] drbd: allow transports to take additional krefs on a + listener + +by making the drbd_listener_destroy() available to the transports. + +heming.zhao@suse.com +- For compiling drbd, I modified this patch. please differ with upstream + to find changes. + +--- + drbd/drbd_transport.c | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +diff --git a/drbd/drbd_transport.c b/drbd/drbd_transport.c +index d1ec5724dec6..416a50499046 100644 +--- a/drbd/drbd_transport.c ++++ b/drbd/drbd_transport.c +@@ -223,7 +223,7 @@ int drbd_get_listener(struct drbd_transport *transport, struct drbd_path *path, + return err; + } + +-static void drbd_listener_destroy(struct kref *kref) ++void drbd_listener_destroy(struct kref *kref) + { + struct drbd_listener *listener = container_of(kref, struct drbd_listener, kref); + struct drbd_resource *resource = listener->resource; +@@ -331,3 +331,4 @@ EXPORT_SYMBOL_GPL(drbd_find_path_by_addr); + EXPORT_SYMBOL_GPL(drbd_stream_send_timed_out); + EXPORT_SYMBOL_GPL(drbd_should_abort_listening); + EXPORT_SYMBOL_GPL(drbd_path_event); ++EXPORT_SYMBOL_GPL(drbd_listener_destroy); +-- +2.35.3 + diff --git a/0002-drbd-improve-decision-about-marking-a-failed-disk-Ou.patch b/0002-drbd-improve-decision-about-marking-a-failed-disk-Ou.patch new file mode 100644 index 0000000..ab4595c --- /dev/null +++ b/0002-drbd-improve-decision-about-marking-a-failed-disk-Ou.patch @@ -0,0 +1,65 @@ +From f2cd05b8d60d27f43b07175b92ef4c2a69b8e3a2 Mon Sep 17 00:00:00 2001 +From: Joel Colledge +Date: Wed, 6 Sep 2023 15:49:44 +0200 +Subject: [PATCH 02/20] drbd: improve decision about marking a failed disk + Outdated + +Sometimes it is possible to update the metadata even after our disk has +failed. We were too eager to remove the MDF_WAS_UP_TO_DATE flag in this +case. + +Firstly, we used the "NOW" states, so would mark our metadata Outdated +if we were a Primary with UpToDate data and no peers, and our disk +failed. Use the "NEW" states instead. + +Secondly, do not consider peers that are disconnecting, because they +will not see that our disk state is Failed, and so will outdate +themselves. We do not want to outdate both nodes in this situation. +--- + drbd/drbd_state.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +diff --git a/drbd/drbd_state.c b/drbd/drbd_state.c +index 7e6e3477893d..8b60afeb097b 100644 +--- a/drbd/drbd_state.c ++++ b/drbd/drbd_state.c +@@ -2489,15 +2489,24 @@ static void initialize_resync(struct drbd_peer_device *peer_device) + /* Is there a primary with access to up to date data known */ + static bool primary_and_data_present(struct drbd_device *device) + { +- bool up_to_date_data = device->disk_state[NOW] == D_UP_TO_DATE; +- bool primary = device->resource->role[NOW] == R_PRIMARY; ++ bool up_to_date_data = device->disk_state[NEW] == D_UP_TO_DATE; ++ struct drbd_resource *resource = device->resource; ++ bool primary = resource->role[NEW] == R_PRIMARY; + struct drbd_peer_device *peer_device; + + for_each_peer_device(peer_device, device) { +- if (peer_device->connection->peer_role[NOW] == R_PRIMARY) ++ struct drbd_connection *connection = peer_device->connection; ++ ++ /* Do not consider the peer if we are disconnecting. */ ++ if (resource->remote_state_change && ++ drbd_twopc_between_peer_and_me(connection) && ++ resource->twopc_reply.is_disconnect) ++ continue; ++ ++ if (connection->peer_role[NEW] == R_PRIMARY) + primary = true; + +- if (peer_device->disk_state[NOW] == D_UP_TO_DATE) ++ if (peer_device->disk_state[NEW] == D_UP_TO_DATE) + up_to_date_data = true; + } + +@@ -4808,6 +4817,7 @@ change_cluster_wide_state(bool (*change)(struct change_context *, enum change_ph + } else if (context->mask.conn == conn_MASK && context->val.conn == C_DISCONNECTING) { + reply->target_reachable_nodes = NODE_MASK(context->target_node_id); + reply->reachable_nodes &= ~reply->target_reachable_nodes; ++ reply->is_disconnect = 1; + } else { + reply->target_reachable_nodes = reply->reachable_nodes; + } +-- +2.35.3 + diff --git a/0003-drbd-fix-error-path-in-drbd_get_listener.patch b/0003-drbd-fix-error-path-in-drbd_get_listener.patch new file mode 100644 index 0000000..cdfef55 --- /dev/null +++ b/0003-drbd-fix-error-path-in-drbd_get_listener.patch @@ -0,0 +1,32 @@ +From fbfb92d11e64daec167b24521c715ceab505b55d Mon Sep 17 00:00:00 2001 +From: Philipp Reisner +Date: Thu, 7 Sep 2023 10:36:29 +0200 +Subject: [PATCH 03/20] drbd: fix error path in drbd_get_listener() + +When initializing a listener fails do not access the fields of the +listener struct after giving up the reference. +--- + drbd/drbd_transport.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drbd/drbd_transport.c b/drbd/drbd_transport.c +index 416a50499046..2aefd71ee395 100644 +--- a/drbd/drbd_transport.c ++++ b/drbd/drbd_transport.c +@@ -207,11 +207,11 @@ int drbd_get_listener(struct drbd_transport *transport, struct drbd_path *path, + + if (needs_init) { + err = init_listener(transport, addr, &init_net, listener); ++ listener->err = err; ++ complete_all(&listener->ready); + if (err) + drbd_put_listener(path); + +- listener->err = err; +- complete_all(&listener->ready); + return err; + } + +-- +2.35.3 + diff --git a/0004-drbd-build-fix-spurious-re-build-attempt-of-compat.p.patch b/0004-drbd-build-fix-spurious-re-build-attempt-of-compat.p.patch new file mode 100644 index 0000000..84d3199 --- /dev/null +++ b/0004-drbd-build-fix-spurious-re-build-attempt-of-compat.p.patch @@ -0,0 +1,47 @@ +From 67ac093d6dc176fd6a3bf0c7f5a3ad046d48f558 Mon Sep 17 00:00:00 2001 +From: Lars Ellenberg +Date: Wed, 6 Sep 2023 14:38:32 +0200 +Subject: [PATCH 04/20] drbd: build: fix spurious re-build attempt of + compat.patch + +Patching changed the timestamp of the patched files, +which are pre-requisites for generating the patch. + +The second build after extracting the tarball +would try to regenerate the patch file. + +Exclude generated *.mod.c from "to-be-patched" files for spatch. +Reset timestamp of patched files to that of the patch file, instead of current time. +--- + drbd/Kbuild | 1 + + drbd/Makefile | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drbd/Kbuild b/drbd/Kbuild +index 1576dc19e1da..073469ae4191 100644 +--- a/drbd/Kbuild ++++ b/drbd/Kbuild +@@ -110,6 +110,7 @@ filechk_compat.h = cat $(obj)/compat.$(KERNELVERSION).h + $(src)/.compat_patches_applied: $(src)/drbd-kernel-compat/compat.patch + @$(kecho) ' PATCH' + @patch -d $(src) -p0 --batch --forward --reject-file=- < $(src)/drbd-kernel-compat/compat.patch ++ @cd $(src) && p=drbd-kernel-compat/compat.patch && sed -ne 's/^--- //p' < $$p | xargs -r -- touch -r $$p + @cp -d $(src)/drbd-kernel-compat/compat.patch $(src)/.compat_patches_applied + + $(src)/drbd-kernel-compat/compat.patch: $(obj)/compat.h +diff --git a/drbd/Makefile b/drbd/Makefile +index 09a1efbf7fe1..ecdff04b9808 100644 +--- a/drbd/Makefile ++++ b/drbd/Makefile +@@ -170,7 +170,7 @@ else + compat_headers := $(wildcard drbd-kernel-compat/cocci_cache/*/compat.h) + compat_patches := $(patsubst %.h,%.patch,$(compat_headers)) + +- sources := $(filter-out drbd_strings.c drbd_buildtag.c,$(wildcard *.c)) ++ sources := $(filter-out drbd_strings.c drbd_buildtag.c drbd%.mod.c,$(wildcard *.c)) + sources += $(wildcard drbd-headers/linux/*.h) + + $(compat_patches): $(sources) +-- +2.35.3 + diff --git a/0005-drbd-log-error-code-when-thread-fails-to-start.patch b/0005-drbd-log-error-code-when-thread-fails-to-start.patch new file mode 100644 index 0000000..fd971ec --- /dev/null +++ b/0005-drbd-log-error-code-when-thread-fails-to-start.patch @@ -0,0 +1,28 @@ +From a98c818bd33920fd5189cdd8f5d81850ad4a945b Mon Sep 17 00:00:00 2001 +From: Joel Colledge +Date: Thu, 7 Sep 2023 17:32:56 +0200 +Subject: [PATCH 05/20] drbd: log error code when thread fails to start + +--- + drbd/drbd_main.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drbd/drbd_main.c b/drbd/drbd_main.c +index 38f728f3da73..810df864f60b 100644 +--- a/drbd/drbd_main.c ++++ b/drbd/drbd_main.c +@@ -642,9 +642,9 @@ int drbd_thread_start(struct drbd_thread *thi) + + if (IS_ERR(nt)) { + if (connection) +- drbd_err(connection, "Couldn't start thread\n"); ++ drbd_err(connection, "Couldn't start thread: %ld\n", PTR_ERR(nt)); + else +- drbd_err(resource, "Couldn't start thread\n"); ++ drbd_err(resource, "Couldn't start thread: %ld\n", PTR_ERR(nt)); + + return false; + } +-- +2.35.3 + diff --git a/0006-drbd-log-numeric-value-of-drbd_state_rv-as-well-as-s.patch b/0006-drbd-log-numeric-value-of-drbd_state_rv-as-well-as-s.patch new file mode 100644 index 0000000..f340c97 --- /dev/null +++ b/0006-drbd-log-numeric-value-of-drbd_state_rv-as-well-as-s.patch @@ -0,0 +1,82 @@ +From 8c2c783a09d81f0a725e7a3ae48be4ceb2d79a63 Mon Sep 17 00:00:00 2001 +From: Joel Colledge +Date: Fri, 8 Sep 2023 11:26:01 +0200 +Subject: [PATCH 06/20] drbd: log numeric value of drbd_state_rv as well as + string form + +"Auto-promote failed: ?" was seen in a log. Logging the numeric value of +the state change return value gives us more information about what +happened in such a case. +--- + drbd/drbd_main.c | 8 ++++---- + drbd/drbd_receiver.c | 6 +++--- + drbd/drbd_state.c | 3 ++- + 3 files changed, 9 insertions(+), 8 deletions(-) + +diff --git a/drbd/drbd_main.c b/drbd/drbd_main.c +index 810df864f60b..e26cf7e2b008 100644 +--- a/drbd/drbd_main.c ++++ b/drbd/drbd_main.c +@@ -2698,8 +2698,8 @@ static int drbd_open(struct block_device *bdev, fmode_t mode) + if (resource->role[NOW] == R_SECONDARY) { + rv = try_to_promote(device, timeout, (mode & FMODE_NDELAY)); + if (rv < SS_SUCCESS) +- drbd_info(resource, "Auto-promote failed: %s\n", +- drbd_set_st_err_str(rv)); ++ drbd_info(resource, "Auto-promote failed: %s (%d)\n", ++ drbd_set_st_err_str(rv), rv); + } + } else if ((mode & FMODE_NDELAY) == 0) { + /* Double check peers +@@ -2856,8 +2856,8 @@ static void drbd_release(struct gendisk *gd, fmode_t mode) + !test_bit(EXPLICIT_PRIMARY, &resource->flags)) { + rv = drbd_set_role(resource, R_SECONDARY, false, NULL); + if (rv < SS_SUCCESS) +- drbd_warn(resource, "Auto-demote failed: %s\n", +- drbd_set_st_err_str(rv)); ++ drbd_warn(resource, "Auto-demote failed: %s (%d)\n", ++ drbd_set_st_err_str(rv), rv); + } + } + +diff --git a/drbd/drbd_receiver.c b/drbd/drbd_receiver.c +index 95cf7ac36762..2162d13cb25e 100644 +--- a/drbd/drbd_receiver.c ++++ b/drbd/drbd_receiver.c +@@ -983,8 +983,8 @@ static int connect_work(struct drbd_work *work, int cancel) + drbd_send_disconnect(connection); + apply_local_state_change(connection, OUTDATE_DISKS_AND_DISCONNECT, force_demote); + } else { +- drbd_info(connection, "Failure to connect %d %s; retrying\n", +- rv, drbd_set_st_err_str(rv)); ++ drbd_info(connection, "Failure to connect: %s (%d); retrying\n", ++ drbd_set_st_err_str(rv), rv); + change_cstate(connection, C_NETWORK_FAILURE, CS_HARD); + } + +@@ -6107,7 +6107,7 @@ out: + } + + if (rv < SS_SUCCESS) { +- drbd_err(resource, "State change failed: %s\n", drbd_set_st_err_str(rv)); ++ drbd_err(resource, "State change failed: %s (%d)\n", drbd_set_st_err_str(rv), rv); + if (rv == SS_PRIMARY_READER) + log_openers(resource); + } +diff --git a/drbd/drbd_state.c b/drbd/drbd_state.c +index 8b60afeb097b..23eab7f867aa 100644 +--- a/drbd/drbd_state.c ++++ b/drbd/drbd_state.c +@@ -791,7 +791,8 @@ static enum drbd_state_rv ___end_state_change(struct drbd_resource *resource, st + rv = try_state_change(resource); + if (rv < SS_SUCCESS) { + if (flags & CS_VERBOSE) { +- drbd_err(resource, "State change failed: %s\n", drbd_set_st_err_str(rv)); ++ drbd_err(resource, "State change failed: %s (%d)\n", ++ drbd_set_st_err_str(rv), rv); + print_state_change(resource, "Failed: "); + } + goto out; +-- +2.35.3 + diff --git a/0007-drbd-stop-defining-__KERNEL_SYSCALLS__.patch b/0007-drbd-stop-defining-__KERNEL_SYSCALLS__.patch new file mode 100644 index 0000000..a5a7b4f --- /dev/null +++ b/0007-drbd-stop-defining-__KERNEL_SYSCALLS__.patch @@ -0,0 +1,45 @@ +From 15cf257c277020e1ba76eff7aa99ed08d44f7d3c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Moritz=20=22WanzenBug=22=20Wanzenb=C3=B6ck?= + +Date: Fri, 8 Sep 2023 11:45:48 +0200 +Subject: [PATCH 07/20] drbd: stop defining __KERNEL_SYSCALLS__ + +See also upstream Linux kernel commit +d519df00938e ("drbd: stop defining __KERNEL_SYSCALLS__") + +Original message: + +__KERNEL_SYSCALLS__ hasn't been needed since Linux 2.6.19 so stop +defining it. +--- + drbd/drbd_main.c | 1 - + drbd/drbd_receiver.c | 1 - + 2 files changed, 2 deletions(-) + +diff --git a/drbd/drbd_main.c b/drbd/drbd_main.c +index e26cf7e2b008..ccf0f72829db 100644 +--- a/drbd/drbd_main.c ++++ b/drbd/drbd_main.c +@@ -36,7 +36,6 @@ + #include + #include + #include +-#define __KERNEL_SYSCALLS__ + #include + #include + #include +diff --git a/drbd/drbd_receiver.c b/drbd/drbd_receiver.c +index 2162d13cb25e..2e2ed4699a94 100644 +--- a/drbd/drbd_receiver.c ++++ b/drbd/drbd_receiver.c +@@ -26,7 +26,6 @@ + #include + #include + #include +-#define __KERNEL_SYSCALLS__ + #include + #include + #include +-- +2.35.3 + diff --git a/0008-compat-block-introduce-holder-ops.patch b/0008-compat-block-introduce-holder-ops.patch new file mode 100644 index 0000000..53fa4d9 --- /dev/null +++ b/0008-compat-block-introduce-holder-ops.patch @@ -0,0 +1,80 @@ +From c34a13c3df85352124e94456f81e3d4ba4f52440 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Moritz=20=22WanzenBug=22=20Wanzenb=C3=B6ck?= + +Date: Fri, 8 Sep 2023 12:20:10 +0200 +Subject: [PATCH 08/20] compat: block: introduce holder ops + +See also upstream Linux kernel commit +0718afd47f70 ("block: introduce holder ops") + +Original message: + +Add a new blk_holder_ops structure, which is passed to blkdev_get_by_* and +installed in the block_device for exclusive claims. It will be used to +allow the block layer to call back into the user of the block device for +thing like notification of a removed device or a device resize. +--- + .../cocci/blkdev_get_by_path__no_has_holder_ops.cocci | 6 ++++++ + drbd/drbd-kernel-compat/gen_patch_names.c | 3 +++ + .../tests/blkdev_get_by_path_has_holder_ops.c | 7 +++++++ + drbd/drbd_nl.c | 3 ++- + 4 files changed, 18 insertions(+), 1 deletion(-) + create mode 100644 drbd/drbd-kernel-compat/cocci/blkdev_get_by_path__no_has_holder_ops.cocci + create mode 100644 drbd/drbd-kernel-compat/tests/blkdev_get_by_path_has_holder_ops.c + +diff --git a/drbd/drbd-kernel-compat/cocci/blkdev_get_by_path__no_has_holder_ops.cocci b/drbd/drbd-kernel-compat/cocci/blkdev_get_by_path__no_has_holder_ops.cocci +new file mode 100644 +index 000000000000..050d89e6fe0d +--- /dev/null ++++ b/drbd/drbd-kernel-compat/cocci/blkdev_get_by_path__no_has_holder_ops.cocci +@@ -0,0 +1,6 @@ ++@@ ++expression path, mode, holder, ops; ++@@ ++ blkdev_get_by_path(path, mode, holder ++- , ops ++ ) +diff --git a/drbd/drbd-kernel-compat/gen_patch_names.c b/drbd/drbd-kernel-compat/gen_patch_names.c +index 959bbc351e1b..7071a0a4c5ec 100644 +--- a/drbd/drbd-kernel-compat/gen_patch_names.c ++++ b/drbd/drbd-kernel-compat/gen_patch_names.c +@@ -556,6 +556,9 @@ int main(int argc, char **argv) + patch(1, "__bio_add_page", true, false, + COMPAT_HAVE___BIO_ADD_PAGE, "present"); + ++ patch(1, "blkdev_get_by_path", true, false, ++ COMPAT_BLKDEV_GET_BY_PATH_HAS_HOLDER_OPS, "has_holder_ops"); ++ + /* #define BLKDEV_ISSUE_ZEROOUT_EXPORTED */ + /* #define BLKDEV_ZERO_NOUNMAP */ + +diff --git a/drbd/drbd-kernel-compat/tests/blkdev_get_by_path_has_holder_ops.c b/drbd/drbd-kernel-compat/tests/blkdev_get_by_path_has_holder_ops.c +new file mode 100644 +index 000000000000..02a560782f37 +--- /dev/null ++++ b/drbd/drbd-kernel-compat/tests/blkdev_get_by_path_has_holder_ops.c +@@ -0,0 +1,7 @@ ++/* { "version": "v6.5-rc1", "commit": "0718afd47f70cf46877c39c25d06b786e1a3f36c", "comment": "block: introduce holder ops", "author": "Christoph Hellwig ", "date": "Thu Jun 1 11:44:52 2023 +0200" } */ ++#include ++ ++struct block_device *foo(const char *bdev_path, struct blk_holder_ops *ops) ++{ ++ return blkdev_get_by_path(bdev_path, 0, NULL, ops); ++} +diff --git a/drbd/drbd_nl.c b/drbd/drbd_nl.c +index 0fc1d84a996f..0a67bfa4ca52 100644 +--- a/drbd/drbd_nl.c ++++ b/drbd/drbd_nl.c +@@ -2560,7 +2560,8 @@ static struct block_device *open_backing_dev(struct drbd_device *device, + const char *bdev_path, void *claim_ptr) + { + struct block_device *bdev = blkdev_get_by_path(bdev_path, +- FMODE_READ | FMODE_WRITE | FMODE_EXCL, claim_ptr); ++ FMODE_READ | FMODE_WRITE | FMODE_EXCL, ++ claim_ptr, NULL); + if (IS_ERR(bdev)) { + drbd_err(device, "open(\"%s\") failed with %ld\n", + bdev_path, PTR_ERR(bdev)); +-- +2.35.3 + diff --git a/0009-drbd-reduce-net_ee-not-empty-info-to-a-dynamic-debug.patch b/0009-drbd-reduce-net_ee-not-empty-info-to-a-dynamic-debug.patch new file mode 100644 index 0000000..4f59585 --- /dev/null +++ b/0009-drbd-reduce-net_ee-not-empty-info-to-a-dynamic-debug.patch @@ -0,0 +1,45 @@ +From fc7b1ad2c422e4148d6419f1eec56189a7a578ac Mon Sep 17 00:00:00 2001 +From: Joel Colledge +Date: Fri, 1 Sep 2023 11:04:49 +0200 +Subject: [PATCH 09/20] drbd: reduce "net_ee not empty" info to a dynamic debug + print + +This situation is known and harmless. No need to print a worrying +"killed N entries" message when it occurs. + +A similar comment explaining that this is harmless was introduced in +commit: +31e0f1250f17 on disconnect, just give up all references on pages from net_ee + +But the comment got lost in some refactoring: +0b220db6109e drbd: move {active,read,sync,done}_ee lists from device to connection + +Bring the comment back, slightly simplified. +--- + drbd/drbd_receiver.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drbd/drbd_receiver.c b/drbd/drbd_receiver.c +index 2e2ed4699a94..223353b1081c 100644 +--- a/drbd/drbd_receiver.c ++++ b/drbd/drbd_receiver.c +@@ -8664,9 +8664,15 @@ static void conn_disconnect(struct drbd_connection *connection) + i = drbd_free_peer_reqs(connection, &connection->sync_ee); + if (i) + drbd_info(connection, "sync_ee not empty, killed %u entries\n", i); ++ ++ /* ++ * tcp_close and release of sendpage pages can be deferred. We don't ++ * care for exactly when the network stack does its put_page(), but ++ * release our reference on these pages right here. ++ */ + i = drbd_free_peer_reqs(connection, &connection->net_ee); + if (i) +- drbd_info(connection, "net_ee not empty, killed %u entries\n", i); ++ dynamic_drbd_dbg(connection, "net_ee not empty, killed %u entries\n", i); + + cleanup_unacked_peer_requests(connection); + cleanup_peer_ack_list(connection); +-- +2.35.3 + diff --git a/0010-drbd-do-not-send-P_CURRENT_UUID-to-DRBD-8-peer-when-.patch b/0010-drbd-do-not-send-P_CURRENT_UUID-to-DRBD-8-peer-when-.patch new file mode 100644 index 0000000..20d3297 --- /dev/null +++ b/0010-drbd-do-not-send-P_CURRENT_UUID-to-DRBD-8-peer-when-.patch @@ -0,0 +1,37 @@ +From 1b94c10250c7d37423ba894457c40d9799025a93 Mon Sep 17 00:00:00 2001 +From: Joel Colledge +Date: Mon, 11 Sep 2023 09:20:24 +0200 +Subject: [PATCH 10/20] drbd: do not send P_CURRENT_UUID to DRBD 8 peer when + our disk fails + +DRBD 8 does not understand P_CURRENT_UUID. Skip the peer in +diskfull_peers_need_new_cur_uuid() to avoid sending such a packet. + +This is valid because the DRBD 8 peer generates a new UUID itself when +our disk fails. + +This prevents failures of the form: + +drbd res: Unexpected data packet Unknown (0x0044) +drbd res: peer( Primary -> Unknown ) conn( Connected -> ProtocolError ) pdsk( Failed -> DUnknown ) +--- + drbd/drbd_main.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drbd/drbd_main.c b/drbd/drbd_main.c +index ccf0f72829db..e6ed1185c710 100644 +--- a/drbd/drbd_main.c ++++ b/drbd/drbd_main.c +@@ -4614,6 +4614,9 @@ static bool diskfull_peers_need_new_cur_uuid(struct drbd_device *device) + + rcu_read_lock(); + for_each_peer_device_rcu(peer_device, device) { ++ if (peer_device->connection->agreed_pro_version < 110) ++ continue; ++ + /* Only an up-to-date peer persists a new current uuid! */ + if (peer_device->disk_state[NOW] < D_UP_TO_DATE) + continue; +-- +2.35.3 + diff --git a/0011-compat-block-pass-a-gendisk-to-open.patch b/0011-compat-block-pass-a-gendisk-to-open.patch new file mode 100644 index 0000000..a5b00ee --- /dev/null +++ b/0011-compat-block-pass-a-gendisk-to-open.patch @@ -0,0 +1,129 @@ +From b993152e80676f5b9ce583c9471b630cbd0675d7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Moritz=20=22WanzenBug=22=20Wanzenb=C3=B6ck?= + +Date: Fri, 8 Sep 2023 15:09:47 +0200 +Subject: [PATCH 11/20] compat: block: pass a gendisk to ->open + +See also upstream Linux kernel commit +d32e2bf83791 ("block: pass a gendisk to ->open") + +Original message: + +->open is only called on the whole device. Make that explicit by +passing a gendisk instead of the block_device. +--- + ...ice_operations_open__no_takes_gendisk.cocci | 18 ++++++++++++++++++ + drbd/drbd-kernel-compat/gen_patch_names.c | 3 +++ + ...lock_device_operations_open_takes_gendisk.c | 17 +++++++++++++++++ + drbd/drbd_main.c | 10 +++++----- + 4 files changed, 43 insertions(+), 5 deletions(-) + create mode 100644 drbd/drbd-kernel-compat/cocci/block_device_operations_open__no_takes_gendisk.cocci + create mode 100644 drbd/drbd-kernel-compat/tests/block_device_operations_open_takes_gendisk.c + +diff --git a/drbd/drbd-kernel-compat/cocci/block_device_operations_open__no_takes_gendisk.cocci b/drbd/drbd-kernel-compat/cocci/block_device_operations_open__no_takes_gendisk.cocci +new file mode 100644 +index 000000000000..2ba2856da9db +--- /dev/null ++++ b/drbd/drbd-kernel-compat/cocci/block_device_operations_open__no_takes_gendisk.cocci +@@ -0,0 +1,18 @@ ++@ drbd_open_arg @ ++identifier gd; ++fresh identifier bdev = "" ## "bdev"; ++@@ ++ drbd_open( ++- struct gendisk *gd, +++ struct block_device *bdev, ++ ... ) { ++<... ++( ++- gd->part0 +++ bdev ++| ++- gd +++ bdev->bd_disk ++) ++...> ++} +diff --git a/drbd/drbd-kernel-compat/gen_patch_names.c b/drbd/drbd-kernel-compat/gen_patch_names.c +index 7071a0a4c5ec..6e4f06d9a3a7 100644 +--- a/drbd/drbd-kernel-compat/gen_patch_names.c ++++ b/drbd/drbd-kernel-compat/gen_patch_names.c +@@ -559,6 +559,9 @@ int main(int argc, char **argv) + patch(1, "blkdev_get_by_path", true, false, + COMPAT_BLKDEV_GET_BY_PATH_HAS_HOLDER_OPS, "has_holder_ops"); + ++ patch(1, "block_device_operations_open", true, false, ++ COMPAT_BLOCK_DEVICE_OPERATIONS_OPEN_TAKES_GENDISK, "takes_gendisk"); ++ + /* #define BLKDEV_ISSUE_ZEROOUT_EXPORTED */ + /* #define BLKDEV_ZERO_NOUNMAP */ + +diff --git a/drbd/drbd-kernel-compat/tests/block_device_operations_open_takes_gendisk.c b/drbd/drbd-kernel-compat/tests/block_device_operations_open_takes_gendisk.c +new file mode 100644 +index 000000000000..d5f20fd569fb +--- /dev/null ++++ b/drbd/drbd-kernel-compat/tests/block_device_operations_open_takes_gendisk.c +@@ -0,0 +1,17 @@ ++/* { "version": "v6.5-rc1", "commit": "d32e2bf83791727a84ad5d3e3d713e82f9adbe30", "comment": "block: pass a gendisk to ->open", "author": "Christoph Hellwig ", "date": "Thu Jun 8 13:02:36 2023 +0200" } */ ++#include ++ ++#ifndef __same_type ++# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) ++#endif ++ ++int foo_open(struct gendisk *disk, unsigned int mode) ++{ ++ return 0; ++} ++ ++void foo(void) ++{ ++ struct block_device_operations ops; ++ BUILD_BUG_ON(!(__same_type(ops.open, &foo_open))); ++} +diff --git a/drbd/drbd_main.c b/drbd/drbd_main.c +index e6ed1185c710..53cb4c9e7db3 100644 +--- a/drbd/drbd_main.c ++++ b/drbd/drbd_main.c +@@ -52,7 +52,7 @@ + #include "drbd_meta_data.h" + #include "drbd_dax_pmem.h" + +-static int drbd_open(struct block_device *bdev, fmode_t mode); ++static int drbd_open(struct gendisk *gd, fmode_t mode); + static void drbd_release(struct gendisk *gd, fmode_t mode); + static void md_sync_timer_fn(struct timer_list *t); + static int w_bitmap_io(struct drbd_work *w, int unused); +@@ -2646,9 +2646,9 @@ out: + spin_unlock(&device->openers_lock); + } + +-static int drbd_open(struct block_device *bdev, fmode_t mode) ++static int drbd_open(struct gendisk *gd, fmode_t mode) + { +- struct drbd_device *device = bdev->bd_disk->private_data; ++ struct drbd_device *device = gd->private_data; + struct drbd_resource *resource = device->resource; + long timeout = resource->res_opts.auto_promote_timeout * HZ / 10; + enum ioc_rv r; +@@ -2664,7 +2664,7 @@ static int drbd_open(struct block_device *bdev, fmode_t mode) + + /* Fail read-write open early, + * in case someone explicitly set us read-only (blockdev --setro) */ +- if (bdev_read_only(bdev) && (mode & FMODE_WRITE)) ++ if (bdev_read_only(gd->part0) && (mode & FMODE_WRITE)) + return -EACCES; + + if (resource->fail_io[NOW]) +@@ -2740,7 +2740,7 @@ out: + + mutex_unlock(&resource->open_release); + if (err) { +- drbd_release(bdev->bd_disk, mode); ++ drbd_release(gd, mode); + if (err == -EAGAIN && !(mode & FMODE_NDELAY)) + err = -EMEDIUMTYPE; + } +-- +2.35.3 + diff --git a/0012-drbd-Restore-DATA_CORKED-and-CONTROL_CORKED-bits.patch b/0012-drbd-Restore-DATA_CORKED-and-CONTROL_CORKED-bits.patch new file mode 100644 index 0000000..343fbe5 --- /dev/null +++ b/0012-drbd-Restore-DATA_CORKED-and-CONTROL_CORKED-bits.patch @@ -0,0 +1,67 @@ +From 88bf7f95dc359f4901f08ac8fb8ffc7dfceca9c1 Mon Sep 17 00:00:00 2001 +From: Philipp Reisner +Date: Wed, 13 Sep 2023 17:50:37 +0200 +Subject: [PATCH 12/20] drbd: Restore DATA_CORKED and CONTROL_CORKED bits + +They were removed with 9072e1d1b6b3 in January 2022. + +Since then, the CONTROL_CORKED mapped onto C_UNREGISTERED. + +I think that had a negligible impact because C_UNREGISTERED indicates +if a connection was deleted before. It is no longer connected when it +is time to delete a connection. Therefore, the corking code can not +set that double-used bit. + +The other user of C_UNREGISTERED is when iterating over connections. A +wrongly set C_UNREGISTERED causes another iteration over the +connections list - no further harm. + +Still, I am fixing this by allocating dedicated bits for corking in +the flags word. +--- + drbd/drbd_debugfs.c | 2 ++ + drbd/drbd_int.h | 2 ++ + drbd/drbd_main.c | 1 + + 3 files changed, 5 insertions(+) + +diff --git a/drbd/drbd_debugfs.c b/drbd/drbd_debugfs.c +index 778a995018d7..b8e4f2cde426 100644 +--- a/drbd/drbd_debugfs.c ++++ b/drbd/drbd_debugfs.c +@@ -839,6 +839,8 @@ static int connection_debug_show(struct seq_file *m, void *ignored) + pretty_print_bit(CONN_DRY_RUN); + pretty_print_bit(DISCONNECT_EXPECTED); + pretty_print_bit(BARRIER_ACK_PENDING); ++ pretty_print_bit(DATA_CORKED); ++ pretty_print_bit(CONTROL_CORKED); + pretty_print_bit(C_UNREGISTERED); + pretty_print_bit(RECONNECT); + pretty_print_bit(CONN_DISCARD_MY_DATA); +diff --git a/drbd/drbd_int.h b/drbd/drbd_int.h +index 17be90e7d8fa..4f3228d5a4d1 100644 +--- a/drbd/drbd_int.h ++++ b/drbd/drbd_int.h +@@ -755,6 +755,8 @@ enum connection_flag { + DISCONNECT_EXPECTED, + BARRIER_ACK_PENDING, + CORKED, ++ DATA_CORKED = CORKED, /* used as computed value CORKED + DATA_STREAM */ ++ CONTROL_CORKED, /* used as computed value CORKED + CONTROL_STREAM */ + C_UNREGISTERED, + RECONNECT, + CONN_DISCARD_MY_DATA, +diff --git a/drbd/drbd_main.c b/drbd/drbd_main.c +index 53cb4c9e7db3..6bb618909aa0 100644 +--- a/drbd/drbd_main.c ++++ b/drbd/drbd_main.c +@@ -1039,6 +1039,7 @@ int __send_command(struct drbd_connection *connection, int vnr, + struct drbd_send_buffer *sbuf = &connection->send_buffer[drbd_stream]; + struct drbd_transport *transport = &connection->transport; + struct drbd_transport_ops *tr_ops = transport->ops; ++ /* CORKED + drbd_stream is either DATA_CORKED or CONTROL_CORKED */ + bool corked = test_bit(CORKED + drbd_stream, &connection->flags); + bool flush = stream_and_flags & SFLAG_FLUSH; + int err; +-- +2.35.3 + diff --git a/0013-drbd-remove-unused-extern-for-conn_try_outdate_peer.patch b/0013-drbd-remove-unused-extern-for-conn_try_outdate_peer.patch new file mode 100644 index 0000000..9d3a99b --- /dev/null +++ b/0013-drbd-remove-unused-extern-for-conn_try_outdate_peer.patch @@ -0,0 +1,38 @@ +From 9e087399533445e3df60a34f26a1e6a285b0504a Mon Sep 17 00:00:00 2001 +From: Joel Colledge +Date: Tue, 12 Sep 2023 16:36:43 +0200 +Subject: [PATCH 13/20] drbd: remove unused extern for conn_try_outdate_peer() + +--- + drbd/drbd_int.h | 1 - + drbd/drbd_nl.c | 2 +- + 2 files changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drbd/drbd_int.h b/drbd/drbd_int.h +index 4f3228d5a4d1..f6e7c3ac2629 100644 +--- a/drbd/drbd_int.h ++++ b/drbd/drbd_int.h +@@ -1932,7 +1932,6 @@ extern void drbd_reconsider_queue_parameters(struct drbd_device *device, + struct drbd_backing_dev *bdev); + extern bool barrier_pending(struct drbd_resource *resource); + extern enum drbd_state_rv drbd_set_role(struct drbd_resource *, enum drbd_role, bool, struct sk_buff *); +-extern bool conn_try_outdate_peer(struct drbd_connection *connection); + extern void conn_try_outdate_peer_async(struct drbd_connection *connection); + extern int drbd_maybe_khelper(struct drbd_device *, struct drbd_connection *, char *); + extern int drbd_create_peer_device_default_config(struct drbd_peer_device *peer_device); +diff --git a/drbd/drbd_nl.c b/drbd/drbd_nl.c +index 0a67bfa4ca52..cb5cdb184824 100644 +--- a/drbd/drbd_nl.c ++++ b/drbd/drbd_nl.c +@@ -768,7 +768,7 @@ static bool intentional_diskless(struct drbd_resource *resource) + return intentional_diskless; + } + +-bool conn_try_outdate_peer(struct drbd_connection *connection) ++static bool conn_try_outdate_peer(struct drbd_connection *connection) + { + struct drbd_resource *resource = connection->resource; + unsigned long last_reconnect_jif; +-- +2.35.3 + diff --git a/0014-drbd-include-source-of-state-change-in-log.patch b/0014-drbd-include-source-of-state-change-in-log.patch new file mode 100644 index 0000000..8d215ce --- /dev/null +++ b/0014-drbd-include-source-of-state-change-in-log.patch @@ -0,0 +1,1480 @@ +From d6bbb1b1635b9912d77d1a26aba3f380a2ed986d Mon Sep 17 00:00:00 2001 +From: Joel Colledge +Date: Mon, 11 Sep 2023 16:45:27 +0200 +Subject: [PATCH 14/20] drbd: include source of state change in log + +This is useful for understanding why a state change occurs. In +particular, whether it was triggered by userspace. +--- + drbd/drbd_int.h | 10 ++-- + drbd/drbd_main.c | 12 ++--- + drbd/drbd_nl.c | 103 ++++++++++++++++++++------------------ + drbd/drbd_receiver.c | 77 +++++++++++++++------------- + drbd/drbd_req.c | 6 +-- + drbd/drbd_sender.c | 25 ++++++---- + drbd/drbd_state.c | 116 ++++++++++++++++++++++++------------------- + drbd/drbd_state.h | 40 +++++++++++---- + 8 files changed, 224 insertions(+), 165 deletions(-) + +diff --git a/drbd/drbd_int.h b/drbd/drbd_int.h +index f6e7c3ac2629..b705f26e71a4 100644 +--- a/drbd/drbd_int.h ++++ b/drbd/drbd_int.h +@@ -1876,7 +1876,8 @@ extern void drbd_destroy_resource(struct kref *kref); + + extern void drbd_destroy_device(struct kref *kref); + +-extern int set_resource_options(struct drbd_resource *resource, struct res_opts *res_opts); ++extern int set_resource_options(struct drbd_resource *resource, struct res_opts *res_opts, ++ const char *tag); + extern struct drbd_connection *drbd_create_connection(struct drbd_resource *resource, + struct drbd_transport_class *tc); + extern void drbd_transport_shutdown(struct drbd_connection *connection, enum drbd_tr_free_op op); +@@ -1931,7 +1932,9 @@ extern void resync_after_online_grow(struct drbd_peer_device *); + extern void drbd_reconsider_queue_parameters(struct drbd_device *device, + struct drbd_backing_dev *bdev); + extern bool barrier_pending(struct drbd_resource *resource); +-extern enum drbd_state_rv drbd_set_role(struct drbd_resource *, enum drbd_role, bool, struct sk_buff *); ++extern enum drbd_state_rv ++drbd_set_role(struct drbd_resource *resource, enum drbd_role role, bool force, const char *tag, ++ struct sk_buff *reply_skb); + extern void conn_try_outdate_peer_async(struct drbd_connection *connection); + extern int drbd_maybe_khelper(struct drbd_device *, struct drbd_connection *, char *); + extern int drbd_create_peer_device_default_config(struct drbd_peer_device *peer_device); +@@ -1943,7 +1946,8 @@ extern int drbd_worker(struct drbd_thread *thi); + enum drbd_ret_code drbd_resync_after_valid(struct drbd_device *device, int o_minor); + void drbd_resync_after_changed(struct drbd_device *device); + extern bool drbd_stable_sync_source_present(struct drbd_peer_device *, enum which_state); +-extern void drbd_start_resync(struct drbd_peer_device *, enum drbd_repl_state); ++extern void drbd_start_resync(struct drbd_peer_device *peer_device, enum drbd_repl_state side, ++ const char *tag); + extern void resume_next_sg(struct drbd_device *device); + extern void suspend_other_sg(struct drbd_device *device); + extern void drbd_resync_finished(struct drbd_peer_device *, enum drbd_disk_state); +diff --git a/drbd/drbd_main.c b/drbd/drbd_main.c +index 6bb618909aa0..4b0b967c2c97 100644 +--- a/drbd/drbd_main.c ++++ b/drbd/drbd_main.c +@@ -2505,7 +2505,7 @@ static int try_to_promote(struct drbd_device *device, long timeout, bool ndelay) + unsigned long start = jiffies; + long t; + +- rv = drbd_set_role(resource, R_PRIMARY, false, NULL); ++ rv = drbd_set_role(resource, R_PRIMARY, false, "auto-promote", NULL); + timeout -= jiffies - start; + + if (ndelay || rv >= SS_SUCCESS || timeout <= 0) { +@@ -2854,7 +2854,7 @@ static void drbd_release(struct gendisk *gd, fmode_t mode) + open_rw_cnt == 0 && + resource->role[NOW] == R_PRIMARY && + !test_bit(EXPLICIT_PRIMARY, &resource->flags)) { +- rv = drbd_set_role(resource, R_SECONDARY, false, NULL); ++ rv = drbd_set_role(resource, R_SECONDARY, false, "auto-demote", NULL); + if (rv < SS_SUCCESS) + drbd_warn(resource, "Auto-demote failed: %s (%d)\n", + drbd_set_st_err_str(rv), rv); +@@ -2866,7 +2866,7 @@ static void drbd_release(struct gendisk *gd, fmode_t mode) + + begin_state_change(resource, &irq_flags, CS_VERBOSE); + resource->fail_io[NEW] = false; +- end_state_change(resource, &irq_flags); ++ end_state_change(resource, &irq_flags, "release"); + } + + /* if the open counts are 0, we free the whole list, otherwise we remove the specific pid */ +@@ -3349,7 +3349,7 @@ static void wake_all_device_misc(struct drbd_resource *resource) + rcu_read_unlock(); + } + +-int set_resource_options(struct drbd_resource *resource, struct res_opts *res_opts) ++int set_resource_options(struct drbd_resource *resource, struct res_opts *res_opts, const char *tag) + { + struct drbd_connection *connection; + cpumask_var_t new_cpu_mask; +@@ -3414,7 +3414,7 @@ int set_resource_options(struct drbd_resource *resource, struct res_opts *res_op + + if (force_state_recalc) { + begin_state_change(resource, &irq_flags, CS_VERBOSE | CS_FORCE_RECALC); +- end_state_change(resource, &irq_flags); ++ end_state_change(resource, &irq_flags, tag); + } + + if (wake_device_misc) +@@ -3491,7 +3491,7 @@ struct drbd_resource *drbd_create_resource(const char *name, + } + resource->pp_vacant = page_pool_count; + +- if (set_resource_options(resource, res_opts)) ++ if (set_resource_options(resource, res_opts, "create-resource")) + goto fail_free_pages; + + list_add_tail_rcu(&resource->resources, &drbd_resources); +diff --git a/drbd/drbd_nl.c b/drbd/drbd_nl.c +index cb5cdb184824..b7e9e43312f9 100644 +--- a/drbd/drbd_nl.c ++++ b/drbd/drbd_nl.c +@@ -768,7 +768,7 @@ static bool intentional_diskless(struct drbd_resource *resource) + return intentional_diskless; + } + +-static bool conn_try_outdate_peer(struct drbd_connection *connection) ++static bool conn_try_outdate_peer(struct drbd_connection *connection, const char *tag) + { + struct drbd_resource *resource = connection->resource; + unsigned long last_reconnect_jif; +@@ -792,7 +792,7 @@ static bool conn_try_outdate_peer(struct drbd_connection *connection) + !(disk_state == D_DISKLESS && intentional_diskless(resource))) { + begin_state_change_locked(resource, CS_VERBOSE | CS_HARD); + __change_io_susp_fencing(connection, false); +- end_state_change_locked(resource); ++ end_state_change_locked(resource, tag); + read_unlock_irq(&resource->state_rwlock); + return false; + } +@@ -862,7 +862,7 @@ static bool conn_try_outdate_peer(struct drbd_connection *connection) + goto abort; + } + +- end_state_change(resource, &irq_flags); ++ end_state_change(resource, &irq_flags, tag); + + goto out; + abort: +@@ -875,7 +875,7 @@ static int _try_outdate_peer_async(void *data) + { + struct drbd_connection *connection = (struct drbd_connection *)data; + +- conn_try_outdate_peer(connection); ++ conn_try_outdate_peer(connection, "outdate-async"); + + kref_debug_put(&connection->kref_debug, 4); + kref_put(&connection->kref, drbd_destroy_connection); +@@ -1014,7 +1014,8 @@ static bool wait_up_to_date(struct drbd_resource *resource) + } + + enum drbd_state_rv +-drbd_set_role(struct drbd_resource *resource, enum drbd_role role, bool force, struct sk_buff *reply_skb) ++drbd_set_role(struct drbd_resource *resource, enum drbd_role role, bool force, const char *tag, ++ struct sk_buff *reply_skb) + { + struct drbd_device *device; + int vnr, try = 0; +@@ -1042,7 +1043,7 @@ retry: + err_str = NULL; + } + rv = stable_state_change(resource, +- change_role(resource, role, flags, &err_str)); ++ change_role(resource, role, flags, tag, &err_str)); + + if (rv == SS_TIMEOUT || rv == SS_CONCURRENT_ST_CHG) { + long timeout = twopc_retry_timeout(resource, try); +@@ -1104,7 +1105,7 @@ retry: + if (device->disk_state[NOW] != D_CONSISTENT) + continue; + +- if (conn_try_outdate_peer(connection)) ++ if (conn_try_outdate_peer(connection, tag)) + fenced_peers = true; + else + any_fencing_failed = true; +@@ -1140,7 +1141,7 @@ retry: + + up(&resource->state_sem); /* Allow connect while fencing */ + for_each_connection_ref(connection, im, resource) { +- bool outdated_peer = conn_try_outdate_peer(connection); ++ bool outdated_peer = conn_try_outdate_peer(connection, tag); + if (!outdated_peer && force) { + drbd_warn(connection, "Forced into split brain situation!\n"); + flags |= CS_FP_LOCAL_UP_TO_DATE; +@@ -1331,7 +1332,9 @@ int drbd_adm_set_role(struct sk_buff *skb, struct genl_info *info) + new_role = info->genlhdr->cmd == DRBD_ADM_PRIMARY ? R_PRIMARY : R_SECONDARY; + rv = drbd_set_role(adm_ctx.resource, + new_role, +- parms.force, adm_ctx.reply_skb); ++ parms.force, ++ new_role == R_PRIMARY ? "primary" : "secondary", ++ adm_ctx.reply_skb); + + if (new_role == R_PRIMARY) { + if (rv >= SS_SUCCESS) +@@ -3093,7 +3096,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) + drbd_flush_workqueue(&resource->work); + + rv = stable_state_change(resource, +- change_disk_state(device, D_ATTACHING, CS_VERBOSE | CS_SERIALIZE, NULL)); ++ change_disk_state(device, D_ATTACHING, CS_VERBOSE | CS_SERIALIZE, "attach", NULL)); + retcode = (enum drbd_ret_code)rv; + if (rv >= SS_SUCCESS) + update_resource_dagtag(resource, nbc); +@@ -3353,8 +3356,8 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) + + /* change_disk_state uses disk_state_from_md(device); in case D_NEGOTIATING not + necessary, and falls back to a local state change */ +- rv = stable_state_change(resource, +- change_disk_state(device, D_NEGOTIATING, CS_VERBOSE | CS_SERIALIZE, NULL)); ++ rv = stable_state_change(resource, change_disk_state(device, ++ D_NEGOTIATING, CS_VERBOSE | CS_SERIALIZE, "attach", NULL)); + + if (rv < SS_SUCCESS) { + if (rv == SS_CW_FAILED_BY_PEER) +@@ -3385,7 +3388,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) + force_diskless_dec: + put_ldev(device); + force_diskless: +- change_disk_state(device, D_DISKLESS, CS_HARD, NULL); ++ change_disk_state(device, D_DISKLESS, CS_HARD, "attach", NULL); + fail: + mutex_unlock_cond(&resource->conf_update, &have_conf_update); + drbd_backing_dev_free(device, nbc); +@@ -3406,7 +3409,7 @@ static enum drbd_disk_state get_disk_state(struct drbd_device *device) + } + + static int adm_detach(struct drbd_device *device, bool force, bool intentional_diskless, +- struct sk_buff *reply_skb) ++ const char *tag, struct sk_buff *reply_skb) + { + const char *err_str = NULL; + int ret, retcode; +@@ -3414,7 +3417,7 @@ static int adm_detach(struct drbd_device *device, bool force, bool intentional_d + device->device_conf.intentional_diskless = intentional_diskless; + if (force) { + set_bit(FORCE_DETACH, &device->flags); +- change_disk_state(device, D_DETACHING, CS_HARD, NULL); ++ change_disk_state(device, D_DETACHING, CS_HARD, tag, NULL); + retcode = SS_SUCCESS; + goto out; + } +@@ -3422,7 +3425,7 @@ static int adm_detach(struct drbd_device *device, bool force, bool intentional_d + drbd_suspend_io(device, READ_AND_WRITE); /* so no-one is stuck in drbd_al_begin_io */ + retcode = stable_state_change(device->resource, + change_disk_state(device, D_DETACHING, +- CS_VERBOSE | CS_WAIT_COMPLETE | CS_SERIALIZE, &err_str)); ++ CS_VERBOSE | CS_WAIT_COMPLETE | CS_SERIALIZE, tag, &err_str)); + /* D_DETACHING will transition to DISKLESS. */ + drbd_resume_io(device); + ret = wait_event_interruptible(device->misc_wait, +@@ -3473,7 +3476,7 @@ int drbd_adm_detach(struct sk_buff *skb, struct genl_info *info) + + mutex_lock(&adm_ctx.resource->adm_mutex); + retcode = (enum drbd_ret_code)adm_detach(adm_ctx.device, parms.force_detach, +- parms.intentional_diskless_detach, adm_ctx.reply_skb); ++ parms.intentional_diskless_detach, "detach", adm_ctx.reply_skb); + mutex_unlock(&adm_ctx.resource->adm_mutex); + + out: +@@ -4385,7 +4388,7 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info) + drbd_md_mark_dirty(device); + } + +- rv = change_cstate(connection, C_UNCONNECTED, CS_VERBOSE); ++ rv = change_cstate_tag(connection, C_UNCONNECTED, CS_VERBOSE, "connect", NULL); + drbd_adm_finish(&adm_ctx, info, rv); + return 0; + out: +@@ -4535,7 +4538,7 @@ int drbd_open_ro_count(struct drbd_resource *resource) + } + + static enum drbd_state_rv conn_try_disconnect(struct drbd_connection *connection, bool force, +- struct sk_buff *reply_skb) ++ const char *tag, struct sk_buff *reply_skb) + { + struct drbd_resource *resource = connection->resource; + enum drbd_conn_state cstate; +@@ -4545,7 +4548,7 @@ static enum drbd_state_rv conn_try_disconnect(struct drbd_connection *connection + long t; + + repeat: +- rv = change_cstate_es(connection, C_DISCONNECTING, flags, &err_str); ++ rv = change_cstate_tag(connection, C_DISCONNECTING, flags, tag, &err_str); + switch (rv) { + case SS_CW_FAILED_BY_PEER: + case SS_NEED_CONNECTION: +@@ -4571,7 +4574,7 @@ static enum drbd_state_rv conn_try_disconnect(struct drbd_connection *connection + break; + case SS_IS_DISKLESS: + case SS_LOWER_THAN_OUTDATED: +- rv = change_cstate(connection, C_DISCONNECTING, CS_HARD); ++ rv = change_cstate_tag(connection, C_DISCONNECTING, CS_HARD, tag, NULL); + break; + case SS_NO_QUORUM: + if (!(flags & CS_VERBOSE)) { +@@ -4597,7 +4600,7 @@ static enum drbd_state_rv conn_try_disconnect(struct drbd_connection *connection + + /* this can only be called immediately after a successful + * peer_try_disconnect, within the same resource->adm_mutex */ +-static void del_connection(struct drbd_connection *connection) ++static void del_connection(struct drbd_connection *connection, const char *tag) + { + struct drbd_resource *resource = connection->resource; + struct drbd_peer_device *peer_device; +@@ -4619,7 +4622,7 @@ static void del_connection(struct drbd_connection *connection) + * after drbd_receiver() returned. Typically, we should be + * C_STANDALONE already, now, and this becomes a no-op. + */ +- rv2 = change_cstate(connection, C_STANDALONE, CS_VERBOSE | CS_HARD); ++ rv2 = change_cstate_tag(connection, C_STANDALONE, CS_VERBOSE | CS_HARD, tag, NULL); + if (rv2 < SS_SUCCESS) + drbd_err(connection, + "unexpected rv2=%d in del_connection()\n", +@@ -4654,6 +4657,7 @@ static int adm_disconnect(struct sk_buff *skb, struct genl_info *info, bool dest + struct drbd_connection *connection; + enum drbd_state_rv rv; + enum drbd_ret_code retcode; ++ const char *tag = destroy ? "del-peer" : "disconnect"; + + retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_CONNECTION); + if (!adm_ctx.reply_skb) +@@ -4671,10 +4675,10 @@ static int adm_disconnect(struct sk_buff *skb, struct genl_info *info, bool dest + + connection = adm_ctx.connection; + mutex_lock(&adm_ctx.resource->adm_mutex); +- rv = conn_try_disconnect(connection, parms.force_disconnect, adm_ctx.reply_skb); ++ rv = conn_try_disconnect(connection, parms.force_disconnect, tag, adm_ctx.reply_skb); + if (rv >= SS_SUCCESS && destroy) { + mutex_lock(&connection->resource->conf_update); +- del_connection(connection); ++ del_connection(connection, tag); + mutex_unlock(&connection->resource->conf_update); + } + if (rv < SS_SUCCESS) +@@ -4721,10 +4725,10 @@ void resync_after_online_grow(struct drbd_peer_device *peer_device) + + if (!sync_source && connection->agreed_pro_version < 110) { + stable_change_repl_state(peer_device, L_WF_SYNC_UUID, +- CS_VERBOSE | CS_SERIALIZE); ++ CS_VERBOSE | CS_SERIALIZE, "online-grow"); + return; + } +- drbd_start_resync(peer_device, sync_source ? L_SYNC_SOURCE : L_SYNC_TARGET); ++ drbd_start_resync(peer_device, sync_source ? L_SYNC_SOURCE : L_SYNC_TARGET, "online-grow"); + } + + sector_t drbd_local_max_size(struct drbd_device *device) __must_hold(local) +@@ -4956,7 +4960,7 @@ int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info) + goto fail; + } + +- err = set_resource_options(adm_ctx.resource, &res_opts); ++ err = set_resource_options(adm_ctx.resource, &res_opts, "resource-options"); + if (err) { + retcode = ERR_INVALID_REQUEST; + if (err == -ENOMEM) +@@ -4976,11 +4980,11 @@ static enum drbd_state_rv invalidate_resync(struct drbd_peer_device *peer_device + + drbd_flush_workqueue(&peer_device->connection->sender_work); + +- rv = change_repl_state(peer_device, L_STARTING_SYNC_T, CS_SERIALIZE); ++ rv = change_repl_state(peer_device, L_STARTING_SYNC_T, CS_SERIALIZE, "invalidate"); + + if (rv < SS_SUCCESS && rv != SS_NEED_CONNECTION) + rv = stable_change_repl_state(peer_device, L_STARTING_SYNC_T, +- CS_VERBOSE | CS_SERIALIZE); ++ CS_VERBOSE | CS_SERIALIZE, "invalidate"); + + wait_event_interruptible(resource->state_wait, + peer_device->repl_state[NOW] != L_STARTING_SYNC_T); +@@ -5005,7 +5009,7 @@ static enum drbd_state_rv invalidate_no_resync(struct drbd_device *device) __mus + } + } + __change_disk_state(device, D_INCONSISTENT); +- rv = end_state_change(resource, &irq_flags); ++ rv = end_state_change(resource, &irq_flags, "invalidate"); + + if (rv >= SS_SUCCESS) { + drbd_bitmap_io(device, &drbd_bmio_set_all_n_write, +@@ -5080,7 +5084,8 @@ int drbd_adm_invalidate(struct sk_buff *skb, struct genl_info *info) + retcode = invalidate_resync(sync_from_peer_device); + } else { + retcode = change_repl_state(sync_from_peer_device, L_WF_BITMAP_T, +- CS_VERBOSE | CS_CLUSTER_WIDE | CS_WAIT_COMPLETE | CS_SERIALIZE); ++ CS_VERBOSE | CS_CLUSTER_WIDE | CS_WAIT_COMPLETE | ++ CS_SERIALIZE, "invalidate"); + } + } else { + int retry = 3; +@@ -5103,7 +5108,8 @@ int drbd_adm_invalidate(struct sk_buff *skb, struct genl_info *info) + } + retcode = change_repl_state(peer_device, L_WF_BITMAP_T, + CS_VERBOSE | CS_CLUSTER_WIDE | +- CS_WAIT_COMPLETE | CS_SERIALIZE); ++ CS_WAIT_COMPLETE | CS_SERIALIZE, ++ "invalidate"); + } + if (retcode >= SS_SUCCESS) + goto out; +@@ -5140,13 +5146,15 @@ static int full_sync_from_peer(struct drbd_peer_device *peer_device) + struct drbd_resource *resource = device->resource; + int retcode; /* enum drbd_ret_code rsp. enum drbd_state_rv */ + +- retcode = stable_change_repl_state(peer_device, L_STARTING_SYNC_S, CS_SERIALIZE); ++ retcode = stable_change_repl_state(peer_device, L_STARTING_SYNC_S, CS_SERIALIZE, ++ "invalidate-remote"); + if (retcode < SS_SUCCESS) { + if (retcode == SS_NEED_CONNECTION && resource->role[NOW] == R_PRIMARY) { + /* The peer will get a resync upon connect anyways. + * Just make that into a full resync. */ + retcode = change_peer_disk_state(peer_device, D_INCONSISTENT, +- CS_VERBOSE | CS_WAIT_COMPLETE | CS_SERIALIZE); ++ CS_VERBOSE | CS_WAIT_COMPLETE | CS_SERIALIZE, ++ "invalidate-remote"); + if (retcode >= SS_SUCCESS) { + if (drbd_bitmap_io(device, &drbd_bmio_set_susp_al, + "set_n_write from invalidate_peer", +@@ -5155,7 +5163,7 @@ static int full_sync_from_peer(struct drbd_peer_device *peer_device) + } + } else { + retcode = stable_change_repl_state(peer_device, L_STARTING_SYNC_S, +- CS_VERBOSE | CS_SERIALIZE); ++ CS_VERBOSE | CS_SERIALIZE, "invalidate-remote"); + } + } + +@@ -5214,7 +5222,8 @@ int drbd_adm_invalidate_peer(struct sk_buff *skb, struct genl_info *info) + retcode = full_sync_from_peer(peer_device); + } else { + retcode = change_repl_state(peer_device, L_WF_BITMAP_S, +- CS_VERBOSE | CS_CLUSTER_WIDE | CS_WAIT_COMPLETE | CS_SERIALIZE); ++ CS_VERBOSE | CS_CLUSTER_WIDE | CS_WAIT_COMPLETE | CS_SERIALIZE, ++ "invalidate-remote"); + } + drbd_resume_io(device); + +@@ -5329,7 +5338,7 @@ int drbd_adm_resume_io(struct sk_buff *skb, struct genl_info *info) + __change_io_susp_fencing(connection, false); + + __change_io_susp_quorum(resource, false); +- retcode = end_state_change(resource, &irq_flags); ++ retcode = end_state_change(resource, &irq_flags, "resume-io"); + drbd_resume_io(device); + mutex_unlock(&adm_ctx.resource->adm_mutex); + drbd_adm_finish(&adm_ctx, info, retcode); +@@ -5348,7 +5357,7 @@ int drbd_adm_outdate(struct sk_buff *skb, struct genl_info *info) + + retcode = stable_state_change(adm_ctx.device->resource, + change_disk_state(adm_ctx.device, D_OUTDATED, +- CS_VERBOSE | CS_WAIT_COMPLETE | CS_SERIALIZE, NULL)); ++ CS_VERBOSE | CS_WAIT_COMPLETE | CS_SERIALIZE, "outdate", NULL)); + + mutex_unlock(&adm_ctx.resource->adm_mutex); + drbd_adm_finish(&adm_ctx, info, retcode); +@@ -6010,7 +6019,7 @@ int drbd_adm_start_ov(struct sk_buff *skb, struct genl_info *info) + drbd_suspend_io(device, READ_AND_WRITE); + wait_event(device->misc_wait, !atomic_read(&device->pending_bitmap_work.n)); + rv = stable_change_repl_state(peer_device, +- L_VERIFY_S, CS_VERBOSE | CS_WAIT_COMPLETE | CS_SERIALIZE); ++ L_VERIFY_S, CS_VERBOSE | CS_WAIT_COMPLETE | CS_SERIALIZE, "verify"); + drbd_resume_io(device); + + mutex_unlock(&adm_ctx.resource->adm_mutex); +@@ -6082,7 +6091,7 @@ int drbd_adm_new_c_uuid(struct sk_buff *skb, struct genl_info *info) + unsigned long irq_flags; + begin_state_change(device->resource, &irq_flags, CS_VERBOSE); + __change_disk_state(device, D_UP_TO_DATE); +- end_state_change(device->resource, &irq_flags); ++ end_state_change(device->resource, &irq_flags, "new-c-uuid"); + + for_each_peer_device(peer_device, device) { + if (NODE_MASK(peer_device->node_id) & nodes) { +@@ -6122,7 +6131,7 @@ int drbd_adm_new_c_uuid(struct sk_buff *skb, struct genl_info *info) + if (NODE_MASK(peer_device->node_id) & diskful) + __change_peer_disk_state(peer_device, D_UP_TO_DATE); + } +- end_state_change(device->resource, &irq_flags); ++ end_state_change(device->resource, &irq_flags, "new-c-uuid"); + } + + drbd_md_sync_if_dirty(device); +@@ -6353,7 +6362,7 @@ static enum drbd_ret_code adm_del_minor(struct drbd_device *device) + + for_each_peer_device_ref(peer_device, im, device) + stable_change_repl_state(peer_device, L_OFF, +- CS_VERBOSE | CS_WAIT_COMPLETE); ++ CS_VERBOSE | CS_WAIT_COMPLETE, "del-minor"); + + /* If drbd_ldev_destroy() is pending, wait for it to run before + * unregistering the device. */ +@@ -6465,7 +6474,7 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) + mutex_lock(&resource->adm_mutex); + set_bit(DOWN_IN_PROGRESS, &resource->flags); + /* demote */ +- retcode = drbd_set_role(resource, R_SECONDARY, false, adm_ctx.reply_skb); ++ retcode = drbd_set_role(resource, R_SECONDARY, false, "down", adm_ctx.reply_skb); + if (retcode < SS_SUCCESS) { + opener_info(adm_ctx.resource, adm_ctx.reply_skb, retcode); + goto out; +@@ -6474,10 +6483,10 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) + for_each_connection_ref(connection, im, resource) { + retcode = SS_SUCCESS; + if (connection->cstate[NOW] > C_STANDALONE) +- retcode = conn_try_disconnect(connection, 0, adm_ctx.reply_skb); ++ retcode = conn_try_disconnect(connection, 0, "down", adm_ctx.reply_skb); + if (retcode >= SS_SUCCESS) { + mutex_lock(&resource->conf_update); +- del_connection(connection); ++ del_connection(connection, "down"); + mutex_unlock(&resource->conf_update); + } else { + kref_debug_put(&connection->kref_debug, 13); +@@ -6491,7 +6500,7 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) + idr_for_each_entry(&resource->devices, device, i) { + kref_get(&device->kref); + rcu_read_unlock(); +- retcode = adm_detach(device, 0, 0, adm_ctx.reply_skb); ++ retcode = adm_detach(device, 0, 0, "down", adm_ctx.reply_skb); + mutex_lock(&resource->conf_update); + ret = adm_del_minor(device); + mutex_unlock(&resource->conf_update); +diff --git a/drbd/drbd_receiver.c b/drbd/drbd_receiver.c +index 223353b1081c..0c3ab0fd486c 100644 +--- a/drbd/drbd_receiver.c ++++ b/drbd/drbd_receiver.c +@@ -920,7 +920,7 @@ static void apply_local_state_change(struct drbd_connection *connection, enum ao + resource->role[NEW] = R_SECONDARY; + } + } +- end_state_change(resource, &irq_flags); ++ end_state_change(resource, &irq_flags, "connect-failed"); + } + + static int connect_work(struct drbd_work *work, int cancel) +@@ -945,8 +945,9 @@ static int connect_work(struct drbd_work *work, int cancel) + rv = SS_CONCURRENT_ST_CHG; + break; + } +- rv = change_cstate(connection, C_CONNECTED, CS_SERIALIZE | +- CS_ALREADY_SERIALIZED | CS_VERBOSE | CS_DONT_RETRY); ++ rv = change_cstate_tag(connection, C_CONNECTED, CS_SERIALIZE | ++ CS_ALREADY_SERIALIZED | CS_VERBOSE | CS_DONT_RETRY, ++ "connected", NULL); + up(&resource->state_sem); + if (rv != SS_PRIMARY_READER) + break; +@@ -1011,7 +1012,8 @@ static bool conn_connect(struct drbd_connection *connection) + start: + have_mutex = false; + clear_bit(DISCONNECT_EXPECTED, &connection->flags); +- if (change_cstate(connection, C_CONNECTING, CS_VERBOSE) < SS_SUCCESS) { ++ if (change_cstate_tag(connection, C_CONNECTING, CS_VERBOSE, "connecting", NULL) ++ < SS_SUCCESS) { + /* We do not have a network config. */ + return false; + } +@@ -3697,7 +3699,8 @@ static enum sync_strategy drbd_asb_recover_1p(struct drbd_peer_device *peer_devi + /* drbd_change_state() does not sleep while in SS_IN_TRANSIENT_STATE, + * we might be here in L_OFF which is transient. + * we do not need to wait for the after state change work either. */ +- rv2 = change_role(resource, R_SECONDARY, CS_VERBOSE, NULL); ++ rv2 = change_role(resource, R_SECONDARY, CS_VERBOSE, ++ "after-sb-1pri", NULL); + if (rv2 != SS_SUCCESS) { + drbd_maybe_khelper(device, connection, "pri-lost-after-sb"); + } else { +@@ -3750,7 +3753,8 @@ static enum sync_strategy drbd_asb_recover_2p(struct drbd_peer_device *peer_devi + /* drbd_change_state() does not sleep while in SS_IN_TRANSIENT_STATE, + * we might be here in L_OFF which is transient. + * we do not need to wait for the after state change work either. */ +- rv2 = change_role(device->resource, R_SECONDARY, CS_VERBOSE, NULL); ++ rv2 = change_role(device->resource, R_SECONDARY, CS_VERBOSE, ++ "after-sb-2pri", NULL); + if (rv2 != SS_SUCCESS) { + drbd_maybe_khelper(device, connection, "pri-lost-after-sb"); + } else { +@@ -5500,6 +5504,7 @@ static void drbd_resync(struct drbd_peer_device *peer_device, + enum sync_rule rule; + int peer_node_id; + enum drbd_state_rv rv; ++ const char *tag = reason == AFTER_UNSTABLE ? "after-unstable" : "diskless-primary"; + + strategy = drbd_handshake(peer_device, &rule, &peer_node_id, reason == DISKLESS_PRIMARY); + if (strategy == SPLIT_BRAIN_AUTO_RECOVER && reason == AFTER_UNSTABLE) +@@ -5529,11 +5534,11 @@ static void drbd_resync(struct drbd_peer_device *peer_device, + as well. */ + drbd_info(peer_device, "Upgrading local disk to %s after unstable/weak (and no resync).\n", + drbd_disk_str(peer_disk_state)); +- change_disk_state(peer_device->device, peer_disk_state, CS_VERBOSE, NULL); ++ change_disk_state(peer_device->device, peer_disk_state, CS_VERBOSE, tag, NULL); + return; + } + +- rv = change_repl_state(peer_device, new_repl_state, CS_VERBOSE); ++ rv = change_repl_state(peer_device, new_repl_state, CS_VERBOSE, tag); + if ((rv == SS_NOTHING_TO_DO || rv == SS_RESYNC_RUNNING) && + (new_repl_state == L_WF_BITMAP_S || new_repl_state == L_WF_BITMAP_T)) { + /* Those events might happen very quickly. In case we are still processing +@@ -5633,7 +5638,7 @@ static int __receive_uuids(struct drbd_peer_device *peer_device, u64 node_mask) + begin_state_change(device->resource, &irq_flags, CS_VERBOSE); + __change_disk_state(device, D_UP_TO_DATE); + __change_peer_disk_state(peer_device, D_UP_TO_DATE); +- end_state_change(device->resource, &irq_flags); ++ end_state_change(device->resource, &irq_flags, "skip-initial-sync"); + updated_uuids = 1; + propagate_skip_initial_to_diskless(device); + } +@@ -5668,7 +5673,7 @@ static int __receive_uuids(struct drbd_peer_device *peer_device, u64 node_mask) + if (device->disk_state[NOW] == D_DISKLESS && uuid_match && + peer_device->disk_state[NOW] == D_CONSISTENT) { + drbd_info(peer_device, "Peer is on same UUID now\n"); +- change_peer_disk_state(peer_device, D_UP_TO_DATE, CS_VERBOSE); ++ change_peer_disk_state(peer_device, D_UP_TO_DATE, CS_VERBOSE, "receive-uuids"); + } + + if (updated_uuids) +@@ -5855,7 +5860,7 @@ static void check_resync_source(struct drbd_device *device, u64 weak_nodes) + return; + abort: + drbd_info(peer_device, "My sync source became a weak node, aborting resync!\n"); +- change_repl_state(peer_device, L_ESTABLISHED, CS_VERBOSE); ++ change_repl_state(peer_device, L_ESTABLISHED, CS_VERBOSE, "abort-resync"); + drbd_flush_workqueue(&device->resource->work); + + wait_event_interruptible(device->misc_wait, +@@ -6091,7 +6096,7 @@ retry: + + if (is_connect && connection->agreed_pro_version >= 117) + apply_connect(connection, (flags & CS_PREPARED) && !abort); +- rv = end_state_change(resource, &irq_flags); ++ rv = end_state_change(resource, &irq_flags, "remote"); + out: + + if ((rv == SS_NO_UP_TO_DATE_DISK && resource->role[NOW] != R_PRIMARY) || +@@ -6144,7 +6149,7 @@ change_peer_device_state(struct drbd_peer_device *peer_device, + rv = __change_connection_state(connection, mask, val, flags); + if (rv < SS_SUCCESS) + goto fail; +- rv = end_state_change(connection->resource, &irq_flags); ++ rv = end_state_change(connection->resource, &irq_flags, "remote"); + out: + return rv; + fail: +@@ -6375,7 +6380,7 @@ far_away_change(struct drbd_connection *connection, + } + + /* even if no outdate happens, CS_FORCE_RECALC might be set here */ +- return end_state_change(resource, &irq_flags); ++ return end_state_change(resource, &irq_flags, "far-away"); + } + + static void handle_neighbor_demotion(struct drbd_connection *connection, +@@ -6630,17 +6635,18 @@ cont: + /* peer is secondary */ + resync = L_SYNC_SOURCE; + } +- drbd_start_resync(peer_device, resync); ++ drbd_start_resync(peer_device, resync, "resize"); + } else { + if (tr->diskful_primary_nodes & NODE_MASK(peer_device->node_id)) +- drbd_start_resync(peer_device, L_SYNC_TARGET); ++ drbd_start_resync(peer_device, L_SYNC_TARGET, ++ "resize"); + /* else no resync */ + } + } else { + if (resource->twopc_parent_nodes & NODE_MASK(peer_device->node_id)) +- drbd_start_resync(peer_device, L_SYNC_TARGET); ++ drbd_start_resync(peer_device, L_SYNC_TARGET, "resize"); + else if (nodes_to_reach & NODE_MASK(peer_device->node_id)) +- drbd_start_resync(peer_device, L_SYNC_SOURCE); ++ drbd_start_resync(peer_device, L_SYNC_SOURCE, "resize"); + /* else no resync */ + } + } +@@ -7101,7 +7107,7 @@ void drbd_try_to_get_resynced(struct drbd_device *device) + peer_device = best_peer_device; + + if (best_strategy == NO_SYNC) { +- change_disk_state(device, D_UP_TO_DATE, CS_VERBOSE, NULL); ++ change_disk_state(device, D_UP_TO_DATE, CS_VERBOSE, "get-resync", NULL); + } else if (peer_device) { + drbd_resync(peer_device, DISKLESS_PRIMARY); + drbd_send_uuids(peer_device, UUID_FLAG_RESYNC | UUID_FLAG_DISKLESS_PRIMARY, 0); +@@ -7225,7 +7231,7 @@ static void diskless_with_peers_different_current_uuids(struct drbd_peer_device + CS_VERBOSE | CS_HARD | CS_FS_IGN_OPENERS); + resource->role[NEW] = R_SECONDARY; + /* resource->fail_io[NEW] gets set via CS_FS_IGN_OPENERS */ +- end_state_change(resource, &irq_flags); ++ end_state_change(resource, &irq_flags, "peer-state"); + } + set_bit(CONN_HANDSHAKE_RETRY, &connection->flags); + } else if (data_successor && resource->role[NOW] == R_SECONDARY) { +@@ -7278,7 +7284,7 @@ static int receive_state(struct drbd_connection *connection, struct packet_info + if (peer_state.role == R_SECONDARY) { + begin_state_change(resource, &irq_flags, CS_HARD | CS_VERBOSE); + __change_peer_role(connection, R_SECONDARY); +- rv = end_state_change(resource, &irq_flags); ++ rv = end_state_change(resource, &irq_flags, "peer-state"); + if (rv < SS_SUCCESS) + goto fail; + } +@@ -7374,7 +7380,7 @@ static int receive_state(struct drbd_connection *connection, struct packet_info + /* Start resync after AHEAD/BEHIND */ + if (connection->agreed_pro_version >= 110 && + peer_state.conn == L_SYNC_SOURCE && old_peer_state.conn == L_BEHIND) { +- drbd_start_resync(peer_device, L_SYNC_TARGET); ++ drbd_start_resync(peer_device, L_SYNC_TARGET, "resync-after-behind"); + return 0; + } + +@@ -7519,7 +7525,7 @@ static int receive_state(struct drbd_connection *connection, struct packet_info + begin_state_change(resource, &irq_flags, CS_HARD); + __change_cstate(connection, C_PROTOCOL_ERROR); + __change_io_susp_user(resource, false); +- end_state_change(resource, &irq_flags); ++ end_state_change(resource, &irq_flags, "abort-connect"); + return -EIO; + } + +@@ -7581,7 +7587,7 @@ static int receive_state(struct drbd_connection *connection, struct packet_info + if (repl_state[OLD] < L_ESTABLISHED && repl_state[NEW] >= L_ESTABLISHED) + resource->state_change_flags |= CS_HARD; + +- rv = end_state_change(resource, &irq_flags); ++ rv = end_state_change(resource, &irq_flags, "peer-state"); + new_repl_state = peer_device->repl_state[NOW]; + + if (rv < SS_SUCCESS) +@@ -7635,7 +7641,7 @@ static int receive_sync_uuid(struct drbd_connection *connection, struct packet_i + _drbd_uuid_set_bitmap(peer_device, 0UL); + + drbd_print_uuids(peer_device, "updated sync uuid"); +- drbd_start_resync(peer_device, L_SYNC_TARGET); ++ drbd_start_resync(peer_device, L_SYNC_TARGET, "peer-sync-uuid"); + + put_ldev(device); + } else +@@ -7935,17 +7941,18 @@ static int receive_bitmap(struct drbd_connection *connection, struct packet_info + /* We have entered drbd_start_resync() since starting the bitmap exchange. */ + drbd_warn(peer_device, "Received bitmap more than once; ignoring\n"); + } else if (repl_state == L_WF_BITMAP_S) { +- drbd_start_resync(peer_device, L_SYNC_SOURCE); ++ drbd_start_resync(peer_device, L_SYNC_SOURCE, "receive-bitmap"); + } else if (repl_state == L_WF_BITMAP_T) { + if (connection->agreed_pro_version < 110) { + enum drbd_state_rv rv; + + /* Omit CS_WAIT_COMPLETE and CS_SERIALIZE with this state + * transition to avoid deadlocks. */ +- rv = stable_change_repl_state(peer_device, L_WF_SYNC_UUID, CS_VERBOSE); ++ rv = stable_change_repl_state(peer_device, L_WF_SYNC_UUID, CS_VERBOSE, ++ "receive-bitmap"); + D_ASSERT(device, rv == SS_SUCCESS); + } else { +- drbd_start_resync(peer_device, L_SYNC_TARGET); ++ drbd_start_resync(peer_device, L_SYNC_TARGET, "receive-bitmap"); + } + } else { + /* admin may have requested C_DISCONNECTING, +@@ -8139,7 +8146,7 @@ static int receive_peer_dagtag(struct drbd_connection *connection, struct packet + __change_repl_state(peer_device, new_repl_state); + set_bit(RECONCILIATION_RESYNC, &peer_device->flags); + } +- rv = end_state_change(resource, &irq_flags); ++ rv = end_state_change(resource, &irq_flags, "receive-peer-dagtag"); + if (rv == SS_SUCCESS) + drbd_info(connection, "Reconciliation resync because \'%s\' disappeared. (o=%d)\n", + lost_peer->transport.net_conf->name, (int)dagtag_offset); +@@ -8248,7 +8255,8 @@ static int receive_current_uuid(struct drbd_connection *connection, struct packe + if (resource->remote_state_change) + set_bit(OUTDATE_ON_2PC_COMMIT, &device->flags); + else +- change_disk_state(device, D_OUTDATED, CS_VERBOSE, NULL); ++ change_disk_state(device, D_OUTDATED, CS_VERBOSE, ++ "receive-current-uuid", NULL); + } + put_ldev(device); + } else if (device->disk_state[NOW] == D_DISKLESS && resource->role[NOW] == R_PRIMARY) { +@@ -8328,7 +8336,7 @@ static int receive_rs_deallocated(struct drbd_connection *connection, struct pac + + static int receive_disconnect(struct drbd_connection *connection, struct packet_info *pi) + { +- change_cstate(connection, C_DISCONNECTING, CS_HARD); ++ change_cstate_tag(connection, C_DISCONNECTING, CS_HARD, "receive-disconnect", NULL); + return 0; + } + +@@ -8594,7 +8602,7 @@ static void conn_disconnect(struct drbd_connection *connection) + * Usually we should be in some network failure state already, + * but just in case we are not, we fix it up here. + */ +- change_cstate(connection, C_NETWORK_FAILURE, CS_HARD); ++ change_cstate_tag(connection, C_NETWORK_FAILURE, CS_HARD, "disconnected", NULL); + + del_connect_timer(connection); + +@@ -8707,10 +8715,11 @@ static void conn_disconnect(struct drbd_connection *connection) + /* drbd_receiver() has to be restarted after it returns */ + drbd_thread_restart_nowait(&connection->receiver); + } +- end_state_change(resource, &irq_flags); ++ end_state_change(resource, &irq_flags, "disconnected"); + + if (oc == C_DISCONNECTING) +- change_cstate(connection, C_STANDALONE, CS_VERBOSE | CS_HARD | CS_LOCAL_ONLY); ++ change_cstate_tag(connection, C_STANDALONE, CS_VERBOSE | CS_HARD | CS_LOCAL_ONLY, ++ "disconnected", NULL); + } + + /* +diff --git a/drbd/drbd_req.c b/drbd/drbd_req.c +index af2ae66f51b5..41950e46ec27 100644 +--- a/drbd/drbd_req.c ++++ b/drbd/drbd_req.c +@@ -2688,7 +2688,7 @@ void request_timer_fn(struct timer_list *t) + continue; + begin_state_change(resource, &irq_flags, CS_VERBOSE | CS_HARD); + __change_cstate(connection, C_TIMEOUT); +- end_state_change(resource, &irq_flags); ++ end_state_change(resource, &irq_flags, "timeout"); + kref_put(&connection->kref, drbd_destroy_connection); + } + +@@ -2723,7 +2723,7 @@ void drbd_handle_io_error_(struct drbd_device *device, + if (device->disk_state[NOW] > D_INCONSISTENT) { + begin_state_change_locked(device->resource, CS_HARD); + __change_disk_state(device, D_INCONSISTENT); +- end_state_change_locked(device->resource); ++ end_state_change_locked(device->resource, "local-io-error"); + } + break; + } +@@ -2740,7 +2740,7 @@ void drbd_handle_io_error_(struct drbd_device *device, + if (device->disk_state[NOW] > D_FAILED) { + begin_state_change_locked(device->resource, CS_HARD); + __change_disk_state(device, D_FAILED); +- end_state_change_locked(device->resource); ++ end_state_change_locked(device->resource, "local-io-error"); + drbd_err(device, + "Local IO failed in %s. Detaching...\n", where); + } +diff --git a/drbd/drbd_sender.c b/drbd/drbd_sender.c +index 93a460dae190..0beeb5f3cb54 100644 +--- a/drbd/drbd_sender.c ++++ b/drbd/drbd_sender.c +@@ -472,7 +472,7 @@ int w_resync_timer(struct drbd_work *w, int cancel) + unsigned long irq_flags; + begin_state_change(resource, &irq_flags, 0); + peer_device->resync_active[NEW] = false; +- end_state_change(resource, &irq_flags); ++ end_state_change(resource, &irq_flags, "resync-inactive"); + } + break; + } +@@ -1155,7 +1155,7 @@ static void resync_again(struct drbd_device *device, u64 source_m, u64 target_m) + peer_device->resync_again--; + begin_state_change_locked(device->resource, CS_VERBOSE); + __change_repl_state(peer_device, new_repl_state); +- end_state_change_locked(device->resource); ++ end_state_change_locked(device->resource, "resync-again"); + } + } + } +@@ -1225,7 +1225,7 @@ found: + } + + drbd_send_uuids(peer_device, 0, 0); +- drbd_start_resync(peer_device, L_SYNC_TARGET); ++ drbd_start_resync(peer_device, L_SYNC_TARGET, "resync-from-primary"); + } + + static void queue_resync_finished(struct drbd_peer_device *peer_device, enum drbd_disk_state new_peer_disk_state) +@@ -1428,7 +1428,7 @@ void drbd_resync_finished(struct drbd_peer_device *peer_device, + } + + out_unlock: +- end_state_change_locked(device->resource); ++ end_state_change_locked(device->resource, "resync-finished"); + + put_ldev(device); + +@@ -1920,7 +1920,8 @@ static bool drbd_pause_after(struct drbd_device *device) + if (!__drbd_may_sync_now(other_peer_device)) + __change_resync_susp_dependency(other_peer_device, true); + } +- if (end_state_change_locked(other_device->resource) != SS_NOTHING_TO_DO) ++ if (end_state_change_locked(other_device->resource, "resync-after") != ++ SS_NOTHING_TO_DO) + changed = true; + } + rcu_read_unlock(); +@@ -1957,7 +1958,8 @@ static bool drbd_resume_next(struct drbd_device *device) + __drbd_may_sync_now(other_peer_device)) + __change_resync_susp_dependency(other_peer_device, false); + } +- if (end_state_change_locked(other_device->resource) != SS_NOTHING_TO_DO) ++ if (end_state_change_locked(other_device->resource, "resync-after") != ++ SS_NOTHING_TO_DO) + changed = true; + } + rcu_read_unlock(); +@@ -2125,7 +2127,7 @@ static void do_start_resync(struct drbd_peer_device *peer_device) + return; + } + +- drbd_start_resync(peer_device, peer_device->start_resync_side); ++ drbd_start_resync(peer_device, peer_device->start_resync_side, "postponed-resync"); + clear_bit(AHEAD_TO_SYNC_SOURCE, &peer_device->flags); + } + +@@ -2149,7 +2151,7 @@ static void handle_congestion(struct drbd_peer_device *peer_device) + else if (on_congestion == OC_DISCONNECT) + __change_cstate(peer_device->connection, C_DISCONNECTING); + } +- end_state_change(resource, &irq_flags); ++ end_state_change(resource, &irq_flags, "congestion"); + } + rcu_read_unlock(); + +@@ -2163,7 +2165,8 @@ static void handle_congestion(struct drbd_peer_device *peer_device) + * This function might bring you directly into one of the + * C_PAUSED_SYNC_* states. + */ +-void drbd_start_resync(struct drbd_peer_device *peer_device, enum drbd_repl_state side) ++void drbd_start_resync(struct drbd_peer_device *peer_device, enum drbd_repl_state side, ++ const char *tag) + { + struct drbd_device *device = peer_device->device; + struct drbd_connection *connection = peer_device->connection; +@@ -2258,7 +2261,7 @@ skip_helper: + init_resync_stable_bits(peer_device); + finished_resync_pdsk = peer_device->resync_finished_pdsk; + peer_device->resync_finished_pdsk = D_UNKNOWN; +- r = end_state_change_locked(device->resource); ++ r = end_state_change_locked(device->resource, tag); + repl_state = peer_device->repl_state[NOW]; + + if (repl_state < L_ESTABLISHED) +@@ -2339,7 +2342,7 @@ static void go_diskless(struct drbd_device *device) + } + + drbd_md_sync_if_dirty(device); +- change_disk_state(device, D_DISKLESS, CS_HARD, NULL); ++ change_disk_state(device, D_DISKLESS, CS_HARD, "go-diskless", NULL); + } + + static int do_md_sync(struct drbd_device *device) +diff --git a/drbd/drbd_state.c b/drbd/drbd_state.c +index 23eab7f867aa..22cd134be962 100644 +--- a/drbd/drbd_state.c ++++ b/drbd/drbd_state.c +@@ -74,8 +74,8 @@ struct change_disk_state_context { + static bool lost_contact_to_peer_data(enum drbd_disk_state *peer_disk_state); + static bool peer_returns_diskless(struct drbd_peer_device *peer_device, + enum drbd_disk_state os, enum drbd_disk_state ns); +-static void print_state_change(struct drbd_resource *resource, const char *prefix); +-static void finish_state_change(struct drbd_resource *); ++static void print_state_change(struct drbd_resource *resource, const char *prefix, const char *tag); ++static void finish_state_change(struct drbd_resource *, const char *tag); + static int w_after_state_change(struct drbd_work *w, int unused); + static enum drbd_state_rv is_valid_soft_transition(struct drbd_resource *); + static enum drbd_state_rv is_valid_transition(struct drbd_resource *resource); +@@ -774,7 +774,7 @@ static void queue_after_state_change_work(struct drbd_resource *resource, + } + + static enum drbd_state_rv ___end_state_change(struct drbd_resource *resource, struct completion *done, +- enum drbd_state_rv rv) ++ enum drbd_state_rv rv, const char *tag) + { + enum chg_state_flags flags = resource->state_change_flags; + struct drbd_connection *connection; +@@ -793,14 +793,14 @@ static enum drbd_state_rv ___end_state_change(struct drbd_resource *resource, st + if (flags & CS_VERBOSE) { + drbd_err(resource, "State change failed: %s (%d)\n", + drbd_set_st_err_str(rv), rv); +- print_state_change(resource, "Failed: "); ++ print_state_change(resource, "Failed: ", tag); + } + goto out; + } + if (flags & CS_PREPARE) + goto out; + +- finish_state_change(resource); ++ finish_state_change(resource, tag); + update_members(resource); + + /* Check whether we are establishing a connection before applying the change. */ +@@ -939,9 +939,9 @@ void begin_state_change_locked(struct drbd_resource *resource, enum chg_state_fl + __begin_state_change(resource); + } + +-enum drbd_state_rv end_state_change_locked(struct drbd_resource *resource) ++enum drbd_state_rv end_state_change_locked(struct drbd_resource *resource, const char *tag) + { +- return ___end_state_change(resource, NULL, SS_SUCCESS); ++ return ___end_state_change(resource, NULL, SS_SUCCESS, tag); + } + + void begin_state_change(struct drbd_resource *resource, unsigned long *irq_flags, enum chg_state_flags flags) +@@ -952,7 +952,8 @@ void begin_state_change(struct drbd_resource *resource, unsigned long *irq_flags + + static enum drbd_state_rv __end_state_change(struct drbd_resource *resource, + unsigned long *irq_flags, +- enum drbd_state_rv rv) ++ enum drbd_state_rv rv, ++ const char *tag) + { + enum chg_state_flags flags = resource->state_change_flags; + struct completion __done, *done = NULL; +@@ -961,26 +962,27 @@ static enum drbd_state_rv __end_state_change(struct drbd_resource *resource, + done = &__done; + init_completion(done); + } +- rv = ___end_state_change(resource, done, rv); ++ rv = ___end_state_change(resource, done, rv, tag); + __state_change_unlock(resource, irq_flags, rv >= SS_SUCCESS ? done : NULL); + return rv; + } + +-enum drbd_state_rv end_state_change(struct drbd_resource *resource, unsigned long *irq_flags) ++enum drbd_state_rv end_state_change(struct drbd_resource *resource, unsigned long *irq_flags, ++ const char *tag) + { +- return __end_state_change(resource, irq_flags, SS_SUCCESS); ++ return __end_state_change(resource, irq_flags, SS_SUCCESS, tag); + } + + void abort_state_change(struct drbd_resource *resource, unsigned long *irq_flags) + { + resource->state_change_flags &= ~CS_VERBOSE; +- __end_state_change(resource, irq_flags, SS_UNKNOWN_ERROR); ++ __end_state_change(resource, irq_flags, SS_UNKNOWN_ERROR, NULL); + } + + void abort_state_change_locked(struct drbd_resource *resource) + { + resource->state_change_flags &= ~CS_VERBOSE; +- ___end_state_change(resource, NULL, SS_UNKNOWN_ERROR); ++ ___end_state_change(resource, NULL, SS_UNKNOWN_ERROR, NULL); + } + + static void begin_remote_state_change(struct drbd_resource *resource, unsigned long *irq_flags) +@@ -1159,15 +1161,19 @@ static int scnprintf_io_suspend_flags(char *buffer, size_t size, + return b - buffer; + } + +-static void print_state_change(struct drbd_resource *resource, const char *prefix) ++static void print_state_change(struct drbd_resource *resource, const char *prefix, const char *tag) + { + char buffer[150], *b, *end = buffer + sizeof(buffer); ++ char tag_buffer[30] = ""; + struct drbd_connection *connection; + struct drbd_device *device; + enum drbd_role *role = resource->role; + bool *fail_io = resource->fail_io; + int vnr; + ++ if (tag) ++ scnprintf(tag_buffer, 30, " [%s]", tag); ++ + b = buffer; + if (role[OLD] != role[NEW]) + b += scnprintf(b, end - b, "role( %s -> %s ) ", +@@ -1186,7 +1192,7 @@ static void print_state_change(struct drbd_resource *resource, const char *prefi + fail_io[NEW] ? "yes" : "no"); + if (b != buffer) { + *(b-1) = 0; +- drbd_info(resource, "%s%s\n", prefix, buffer); ++ drbd_info(resource, "%s%s%s\n", prefix, buffer, tag_buffer); + } + + for_each_connection(connection, resource) { +@@ -1205,7 +1211,7 @@ static void print_state_change(struct drbd_resource *resource, const char *prefi + + if (b != buffer) { + *(b-1) = 0; +- drbd_info(connection, "%s%s\n", prefix, buffer); ++ drbd_info(connection, "%s%s%s\n", prefix, buffer, tag_buffer); + } + } + +@@ -1225,7 +1231,7 @@ static void print_state_change(struct drbd_resource *resource, const char *prefi + have_quorum[NEW] ? "yes" : "no"); + if (b != buffer) { + *(b-1) = 0; +- drbd_info(device, "%s%s\n", prefix, buffer); ++ drbd_info(device, "%s%s%s\n", prefix, buffer, tag_buffer); + } + + for_each_peer_device(peer_device, device) { +@@ -1253,7 +1259,7 @@ static void print_state_change(struct drbd_resource *resource, const char *prefi + + if (b != buffer) { + *(b-1) = 0; +- drbd_info(peer_device, "%s%s\n", prefix, buffer); ++ drbd_info(peer_device, "%s%s%s\n", prefix, buffer, tag_buffer); + } + } + } +@@ -2543,7 +2549,7 @@ static bool should_try_become_up_to_date(struct drbd_device *device, enum drbd_d + /** + * finish_state_change - carry out actions triggered by a state change + */ +-static void finish_state_change(struct drbd_resource *resource) ++static void finish_state_change(struct drbd_resource *resource, const char *tag) + { + enum drbd_role *role = resource->role; + struct drbd_device *device; +@@ -2557,7 +2563,7 @@ static void finish_state_change(struct drbd_resource *resource) + bool unfreeze_io = false; + int vnr; + +- print_state_change(resource, ""); ++ print_state_change(resource, "", tag); + + resource_suspended[OLD] = resource_is_suspended(resource, OLD); + resource_suspended[NEW] = resource_is_suspended(resource, NEW); +@@ -3025,7 +3031,7 @@ static void abw_start_sync(struct drbd_device *device, + + if (rv) { + drbd_err(device, "Writing the bitmap failed not starting resync.\n"); +- stable_change_repl_state(peer_device, L_ESTABLISHED, CS_VERBOSE); ++ stable_change_repl_state(peer_device, L_ESTABLISHED, CS_VERBOSE, "start-sync"); + return; + } + +@@ -3039,12 +3045,13 @@ static void abw_start_sync(struct drbd_device *device, + rcu_read_unlock(); + + if (peer_device->connection->agreed_pro_version < 110) +- stable_change_repl_state(peer_device, L_WF_SYNC_UUID, CS_VERBOSE); ++ stable_change_repl_state(peer_device, L_WF_SYNC_UUID, CS_VERBOSE, ++ "start-sync"); + else +- drbd_start_resync(peer_device, L_SYNC_TARGET); ++ drbd_start_resync(peer_device, L_SYNC_TARGET, "start-sync"); + break; + case L_STARTING_SYNC_S: +- drbd_start_resync(peer_device, L_SYNC_SOURCE); ++ drbd_start_resync(peer_device, L_SYNC_SOURCE, "start-sync"); + break; + default: + break; +@@ -3531,7 +3538,7 @@ static void check_may_resume_io_after_fencing(struct drbd_state_change *state_ch + rcu_read_unlock(); + begin_state_change(resource, &irq_flags, CS_VERBOSE); + __change_io_susp_fencing(connection, false); +- end_state_change(resource, &irq_flags); ++ end_state_change(resource, &irq_flags, "after-fencing"); + } + /* case2: The connection was established again: */ + if (all_peer_disks_connected) { +@@ -3543,7 +3550,7 @@ static void check_may_resume_io_after_fencing(struct drbd_state_change *state_ch + rcu_read_unlock(); + begin_state_change(resource, &irq_flags, CS_VERBOSE); + __change_io_susp_fencing(connection, false); +- end_state_change(resource, &irq_flags); ++ end_state_change(resource, &irq_flags, "after-fencing"); + } + } + +@@ -4191,7 +4198,7 @@ static int w_after_state_change(struct drbd_work *w, int unused) + + begin_state_change(resource, &irq_flags, CS_VERBOSE); + resource->susp_uuid[NEW] = false; +- end_state_change(resource, &irq_flags); ++ end_state_change(resource, &irq_flags, "susp-uuid"); + } + + if (try_become_up_to_date) +@@ -4673,7 +4680,7 @@ static void twopc_phase2(struct drbd_resource *resource, + */ + static enum drbd_state_rv + change_cluster_wide_state(bool (*change)(struct change_context *, enum change_phase), +- struct change_context *context) ++ struct change_context *context, const char *tag) + { + struct drbd_resource *resource = context->resource; + unsigned long irq_flags; +@@ -4692,11 +4699,11 @@ change_cluster_wide_state(bool (*change)(struct change_context *, enum change_ph + if (local_state_change(context->flags)) { + /* Not a cluster-wide state change. */ + change(context, PH_LOCAL_COMMIT); +- return end_state_change(resource, &irq_flags); ++ return end_state_change(resource, &irq_flags, tag); + } else { + if (!change(context, PH_PREPARE)) { + /* Not a cluster-wide state change. */ +- return end_state_change(resource, &irq_flags); ++ return end_state_change(resource, &irq_flags, tag); + } + rv = try_state_change(resource); + if (rv != SS_SUCCESS) { +@@ -4704,7 +4711,7 @@ change_cluster_wide_state(bool (*change)(struct change_context *, enum change_ph + /* abort_state_change(resource, &irq_flags); */ + if (rv == SS_NOTHING_TO_DO) + resource->state_change_flags &= ~CS_VERBOSE; +- return __end_state_change(resource, &irq_flags, rv); ++ return __end_state_change(resource, &irq_flags, rv, tag); + } + /* Really a cluster-wide state change. */ + } +@@ -4720,12 +4727,12 @@ change_cluster_wide_state(bool (*change)(struct change_context *, enum change_ph + } + if (rv >= SS_SUCCESS) + change(context, PH_84_COMMIT); +- return __end_state_change(resource, &irq_flags, rv); ++ return __end_state_change(resource, &irq_flags, rv, tag); + } + + if (!expect(resource, context->flags & CS_SERIALIZE)) { + rv = SS_CW_FAILED_BY_PEER; +- return __end_state_change(resource, &irq_flags, rv); ++ return __end_state_change(resource, &irq_flags, rv, tag); + } + + rcu_read_lock(); +@@ -4740,7 +4747,7 @@ change_cluster_wide_state(bool (*change)(struct change_context *, enum change_ph + + retry: + if (current == resource->worker.task && resource->remote_state_change) +- return __end_state_change(resource, &irq_flags, SS_CONCURRENT_ST_CHG); ++ return __end_state_change(resource, &irq_flags, SS_CONCURRENT_ST_CHG, tag); + + complete_remote_state_change(resource, &irq_flags); + start_time = jiffies; +@@ -4756,7 +4763,7 @@ change_cluster_wide_state(bool (*change)(struct change_context *, enum change_ph + connection = drbd_get_connection_by_node_id(resource, context->target_node_id); + if (!connection) { + rv = SS_NEED_CONNECTION; +- return __end_state_change(resource, &irq_flags, rv); ++ return __end_state_change(resource, &irq_flags, rv, tag); + } + kref_debug_get(&connection->kref_debug, 8); + +@@ -4768,7 +4775,7 @@ change_cluster_wide_state(bool (*change)(struct change_context *, enum change_ph + + kref_debug_put(&connection->kref_debug, 8); + kref_put(&connection->kref, drbd_destroy_connection); +- return __end_state_change(resource, &irq_flags, rv); ++ return __end_state_change(resource, &irq_flags, rv, tag); + } + target_connection = connection; + +@@ -4959,7 +4966,7 @@ change_cluster_wide_state(bool (*change)(struct change_context *, enum change_ph + clear_bit(TWOPC_STATE_CHANGE_PENDING, &resource->flags); + if (rv >= SS_SUCCESS) { + change(context, PH_COMMIT); +- rv = end_state_change(resource, &irq_flags); ++ rv = end_state_change(resource, &irq_flags, tag); + if (rv < SS_SUCCESS) + drbd_err(resource, "FATAL: Local commit of already committed %u failed! \n", + request.tid); +@@ -5276,6 +5283,7 @@ static bool do_change_role(struct change_context *context, enum change_phase pha + enum drbd_state_rv change_role(struct drbd_resource *resource, + enum drbd_role role, + enum chg_state_flags flags, ++ const char *tag, + const char **err_str) + { + struct change_context role_context = { +@@ -5310,7 +5318,7 @@ enum drbd_state_rv change_role(struct drbd_resource *resource, + } + role_context.change_local_state_last = true; + } +- rv = change_cluster_wide_state(do_change_role, &role_context); ++ rv = change_cluster_wide_state(do_change_role, &role_context, tag); + out: + if (got_state_sem) + up(&resource->state_sem); +@@ -5330,7 +5338,7 @@ enum drbd_state_rv change_io_susp_user(struct drbd_resource *resource, + + begin_state_change(resource, &irq_flags, flags); + __change_io_susp_user(resource, value); +- return end_state_change(resource, &irq_flags); ++ return end_state_change(resource, &irq_flags, value ? "suspend-io" : "resume-io"); + } + + void __change_io_susp_no_data(struct drbd_resource *resource, bool value) +@@ -5465,7 +5473,7 @@ enum drbd_state_rv twopc_after_lost_peer(struct drbd_resource *resource, + /* The other nodes get the request for an empty state change. I.e. they + will agree to this change request. At commit time we know where to + go from the D_CONSISTENT, since we got the primary mask. */ +- return change_cluster_wide_state(do_twopc_after_lost_peer, &context); ++ return change_cluster_wide_state(do_twopc_after_lost_peer, &context, "lost-peer"); + } + + static bool do_change_disk_state(struct change_context *context, enum change_phase phase) +@@ -5496,6 +5504,7 @@ static bool do_change_disk_state(struct change_context *context, enum change_pha + enum drbd_state_rv change_disk_state(struct drbd_device *device, + enum drbd_disk_state disk_state, + enum chg_state_flags flags, ++ const char *tag, + const char **err_str) + { + struct change_disk_state_context disk_state_context = { +@@ -5513,7 +5522,7 @@ enum drbd_state_rv change_disk_state(struct drbd_device *device, + }; + + return change_cluster_wide_state(do_change_disk_state, +- &disk_state_context.context); ++ &disk_state_context.context, tag); + } + + void __change_cstate(struct drbd_connection *connection, enum drbd_conn_state cstate) +@@ -5683,11 +5692,11 @@ static bool do_change_cstate(struct change_context *context, enum change_phase p + * peer disks depending on the fencing policy. This cannot easily be split + * into two state changes. + */ +-enum drbd_state_rv change_cstate_es(struct drbd_connection *connection, ++enum drbd_state_rv change_cstate_tag(struct drbd_connection *connection, + enum drbd_conn_state cstate, + enum chg_state_flags flags, +- const char **err_str +- ) ++ const char *tag, ++ const char **err_str) + { + struct change_cstate_context cstate_context = { + .context = { +@@ -5717,7 +5726,7 @@ enum drbd_state_rv change_cstate_es(struct drbd_connection *connection, + if (!(flags & CS_HARD)) + cstate_context.context.flags |= CS_SERIALIZE; + +- return change_cluster_wide_state(do_change_cstate, &cstate_context.context); ++ return change_cluster_wide_state(do_change_cstate, &cstate_context.context, tag); + } + + void __change_peer_role(struct drbd_connection *connection, enum drbd_role peer_role) +@@ -5759,7 +5768,8 @@ static bool do_change_repl_state(struct change_context *context, enum change_pha + + enum drbd_state_rv change_repl_state(struct drbd_peer_device *peer_device, + enum drbd_repl_state new_repl_state, +- enum chg_state_flags flags) ++ enum chg_state_flags flags, ++ const char *tag) + { + struct change_repl_context repl_context = { + .context = { +@@ -5776,15 +5786,16 @@ enum drbd_state_rv change_repl_state(struct drbd_peer_device *peer_device, + if (new_repl_state == L_WF_BITMAP_S || new_repl_state == L_VERIFY_S) + repl_context.context.change_local_state_last = true; + +- return change_cluster_wide_state(do_change_repl_state, &repl_context.context); ++ return change_cluster_wide_state(do_change_repl_state, &repl_context.context, tag); + } + + enum drbd_state_rv stable_change_repl_state(struct drbd_peer_device *peer_device, + enum drbd_repl_state repl_state, +- enum chg_state_flags flags) ++ enum chg_state_flags flags, ++ const char *tag) + { + return stable_state_change(peer_device->device->resource, +- change_repl_state(peer_device, repl_state, flags)); ++ change_repl_state(peer_device, repl_state, flags, tag)); + } + + void __change_peer_disk_state(struct drbd_peer_device *peer_device, enum drbd_disk_state disk_state) +@@ -5807,14 +5818,15 @@ void __downgrade_peer_disk_states(struct drbd_connection *connection, enum drbd_ + + enum drbd_state_rv change_peer_disk_state(struct drbd_peer_device *peer_device, + enum drbd_disk_state disk_state, +- enum chg_state_flags flags) ++ enum chg_state_flags flags, ++ const char *tag) + { + struct drbd_resource *resource = peer_device->device->resource; + unsigned long irq_flags; + + begin_state_change(resource, &irq_flags, flags); + __change_peer_disk_state(peer_device, disk_state); +- return end_state_change(resource, &irq_flags); ++ return end_state_change(resource, &irq_flags, tag); + } + + void __change_resync_susp_user(struct drbd_peer_device *peer_device, +@@ -5832,7 +5844,7 @@ enum drbd_state_rv change_resync_susp_user(struct drbd_peer_device *peer_device, + + begin_state_change(resource, &irq_flags, flags); + __change_resync_susp_user(peer_device, value); +- return end_state_change(resource, &irq_flags); ++ return end_state_change(resource, &irq_flags, value ? "pause-sync" : "resume-sync"); + } + + void __change_resync_susp_peer(struct drbd_peer_device *peer_device, +diff --git a/drbd/drbd_state.h b/drbd/drbd_state.h +index 6942f85123dd..952dea156697 100644 +--- a/drbd/drbd_state.h ++++ b/drbd/drbd_state.h +@@ -56,12 +56,13 @@ extern void state_change_lock(struct drbd_resource *, unsigned long *, enum chg_ + extern void state_change_unlock(struct drbd_resource *, unsigned long *); + + extern void begin_state_change(struct drbd_resource *, unsigned long *, enum chg_state_flags); +-extern enum drbd_state_rv end_state_change(struct drbd_resource *, unsigned long *); ++extern enum drbd_state_rv end_state_change(struct drbd_resource *resource, unsigned long *irq_flags, ++ const char *tag); + extern void abort_state_change(struct drbd_resource *, unsigned long *); + extern void abort_state_change_locked(struct drbd_resource *resource); + + extern void begin_state_change_locked(struct drbd_resource *, enum chg_state_flags); +-extern enum drbd_state_rv end_state_change_locked(struct drbd_resource *); ++extern enum drbd_state_rv end_state_change_locked(struct drbd_resource *resource, const char *tag); + + extern void clear_remote_state_change(struct drbd_resource *resource); + extern void __clear_remote_state_change(struct drbd_resource *resource); +@@ -89,7 +90,11 @@ extern enum drbd_state_rv nested_twopc_request(struct drbd_resource *res, struct + extern bool drbd_twopc_between_peer_and_me(struct drbd_connection *connection); + extern bool cluster_wide_reply_ready(struct drbd_resource *); + +-extern enum drbd_state_rv change_role(struct drbd_resource *, enum drbd_role, enum chg_state_flags, const char **); ++extern enum drbd_state_rv change_role(struct drbd_resource *resource, ++ enum drbd_role role, ++ enum chg_state_flags flags, ++ const char *tag, ++ const char **err_str); + + extern void __change_io_susp_user(struct drbd_resource *, bool); + extern enum drbd_state_rv change_io_susp_user(struct drbd_resource *, bool, enum chg_state_flags); +@@ -99,27 +104,44 @@ extern void __change_io_susp_quorum(struct drbd_resource *, bool); + + extern void __change_disk_state(struct drbd_device *, enum drbd_disk_state); + extern void __downgrade_disk_states(struct drbd_resource *, enum drbd_disk_state); +-extern enum drbd_state_rv change_disk_state(struct drbd_device *, enum drbd_disk_state, enum chg_state_flags, const char **); ++extern enum drbd_state_rv change_disk_state(struct drbd_device *device, ++ enum drbd_disk_state disk_state, ++ enum chg_state_flags flags, ++ const char *tag, ++ const char **err_str); + + extern void __change_cstate(struct drbd_connection *, enum drbd_conn_state); +-extern enum drbd_state_rv change_cstate_es(struct drbd_connection *, enum drbd_conn_state, enum chg_state_flags, const char **); ++extern enum drbd_state_rv change_cstate_tag(struct drbd_connection *connection, ++ enum drbd_conn_state cstate, ++ enum chg_state_flags flags, ++ const char *tag, ++ const char **err_str); + static inline enum drbd_state_rv change_cstate(struct drbd_connection *connection, + enum drbd_conn_state cstate, + enum chg_state_flags flags) + { +- return change_cstate_es(connection, cstate, flags, NULL); ++ return change_cstate_tag(connection, cstate, flags, NULL, NULL); + } + + extern void __change_peer_role(struct drbd_connection *, enum drbd_role); + + extern void __change_repl_state(struct drbd_peer_device *, enum drbd_repl_state); +-extern enum drbd_state_rv change_repl_state(struct drbd_peer_device *, enum drbd_repl_state, enum chg_state_flags); +-extern enum drbd_state_rv stable_change_repl_state(struct drbd_peer_device *, enum drbd_repl_state, enum chg_state_flags); ++extern enum drbd_state_rv change_repl_state(struct drbd_peer_device *peer_device, ++ enum drbd_repl_state new_repl_state, ++ enum chg_state_flags flags, ++ const char *tag); ++extern enum drbd_state_rv stable_change_repl_state(struct drbd_peer_device *peer_device, ++ enum drbd_repl_state repl_state, ++ enum chg_state_flags flags, ++ const char *tag); + + extern void __change_peer_disk_state(struct drbd_peer_device *, enum drbd_disk_state); + extern void __downgrade_peer_disk_states(struct drbd_connection *, enum drbd_disk_state); + extern void __outdate_myself(struct drbd_resource *resource); +-extern enum drbd_state_rv change_peer_disk_state(struct drbd_peer_device *, enum drbd_disk_state, enum chg_state_flags); ++extern enum drbd_state_rv change_peer_disk_state(struct drbd_peer_device *peer_device, ++ enum drbd_disk_state disk_state, ++ enum chg_state_flags flags, ++ const char *tag); + + enum drbd_state_rv twopc_after_lost_peer(struct drbd_resource *resource, enum chg_state_flags); + +-- +2.35.3 + diff --git a/0015-compat-block-use-the-holder-as-indication-for-exclus.patch b/0015-compat-block-use-the-holder-as-indication-for-exclus.patch new file mode 100644 index 0000000..83881d6 --- /dev/null +++ b/0015-compat-block-use-the-holder-as-indication-for-exclus.patch @@ -0,0 +1,202 @@ +From 3b9fcc2cfaa32766724f371cc2054e057adbc425 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Moritz=20=22WanzenBug=22=20Wanzenb=C3=B6ck?= + +Date: Mon, 11 Sep 2023 13:36:07 +0200 +Subject: [PATCH 15/20] compat: block: use the holder as indication for + exclusive opens + +See also upstream Linux kernel commit +2736e8eeb0cc ("block: use the holder as indication for exclusive opens") +Original message: + +The current interface for exclusive opens is rather confusing as it +requires both the FMODE_EXCL flag and a holder. Remove the need to pass +FMODE_EXCL and just key off the exclusive open off a non-NULL holder. + +For blkdev_put this requires adding the holder argument, which provides +better debug checking that only the holder actually releases the hold, +but at the same time allows removing the now superfluous mode argument. +--- + .../cocci/blkdev_put__no_has_holder.cocci | 38 +++++++++++++++++++ + drbd/drbd-kernel-compat/gen_patch_names.c | 3 ++ + .../tests/blkdev_put_has_holder.c | 17 +++++++++ + drbd/drbd_nl.c | 28 ++++++++------ + 4 files changed, 75 insertions(+), 11 deletions(-) + create mode 100644 drbd/drbd-kernel-compat/cocci/blkdev_put__no_has_holder.cocci + create mode 100644 drbd/drbd-kernel-compat/tests/blkdev_put_has_holder.c + +diff --git a/drbd/drbd-kernel-compat/cocci/blkdev_put__no_has_holder.cocci b/drbd/drbd-kernel-compat/cocci/blkdev_put__no_has_holder.cocci +new file mode 100644 +index 000000000000..c903bc2d529c +--- /dev/null ++++ b/drbd/drbd-kernel-compat/cocci/blkdev_put__no_has_holder.cocci +@@ -0,0 +1,38 @@ ++@@ ++expression path, mode; ++@@ ++ blkdev_get_by_path( ++ path, ++- mode, +++ mode | FMODE_EXCL, ++ ... ++ ) ++ ++@@ ++expression bdev, holder; ++@@ ++ blkdev_put( ++ bdev, ++- holder +++ FMODE_READ | FMODE_WRITE | FMODE_EXCL ++ ) ++ ++@@ ++identifier device, bdev, holder, do_bd_unlink; ++@@ ++ void close_backing_dev( ++ struct drbd_device *device, ++ struct block_device *bdev, ++- void *holder, ++ bool do_bd_unlink ++ ) { ... } ++ ++@@ ++expression device, bdev, holder, do_bd_unlink; ++@@ ++ close_backing_dev( ++ device, ++ bdev, ++- holder, ++ do_bd_unlink ++ ) +diff --git a/drbd/drbd-kernel-compat/gen_patch_names.c b/drbd/drbd-kernel-compat/gen_patch_names.c +index 6e4f06d9a3a7..4761c1ef7d0c 100644 +--- a/drbd/drbd-kernel-compat/gen_patch_names.c ++++ b/drbd/drbd-kernel-compat/gen_patch_names.c +@@ -562,6 +562,9 @@ int main(int argc, char **argv) + patch(1, "block_device_operations_open", true, false, + COMPAT_BLOCK_DEVICE_OPERATIONS_OPEN_TAKES_GENDISK, "takes_gendisk"); + ++ patch(1, "blkdev_put", true, false, ++ COMPAT_BLKDEV_PUT_HAS_HOLDER, "has_holder"); ++ + /* #define BLKDEV_ISSUE_ZEROOUT_EXPORTED */ + /* #define BLKDEV_ZERO_NOUNMAP */ + +diff --git a/drbd/drbd-kernel-compat/tests/blkdev_put_has_holder.c b/drbd/drbd-kernel-compat/tests/blkdev_put_has_holder.c +new file mode 100644 +index 000000000000..d5f0c5dd0355 +--- /dev/null ++++ b/drbd/drbd-kernel-compat/tests/blkdev_put_has_holder.c +@@ -0,0 +1,17 @@ ++/* { "version": "v6.5-rc1", "commit": "ae220766d87cd6799dbf918fea10613ae14c0654", "comment": "block: remove the unused mode argument to ->release", "author": "Christoph Hellwig ", "date": "Thu Jun 8 13:02:37 2023 +0200" } */ ++#include ++ ++#ifndef __same_type ++# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) ++#endif ++ ++void foo_blkdev_put(struct block_device *bdev, void *holder) ++{ ++} ++ ++ ++void foo(void) ++{ ++ BUILD_BUG_ON(!(__same_type(&blkdev_put, &foo_blkdev_put))); ++} ++ +diff --git a/drbd/drbd_nl.c b/drbd/drbd_nl.c +index b7e9e43312f9..8c968cf252ca 100644 +--- a/drbd/drbd_nl.c ++++ b/drbd/drbd_nl.c +@@ -2536,13 +2536,13 @@ bool want_bitmap(struct drbd_peer_device *peer_device) + } + + static void close_backing_dev(struct drbd_device *device, struct block_device *bdev, +- bool do_bd_unlink) ++ void *holder, bool do_bd_unlink) + { + if (!bdev) + return; + if (do_bd_unlink) + bd_unlink_disk_holder(bdev, device->vdisk); +- blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL); ++ blkdev_put(bdev, holder); + } + + void drbd_backing_dev_free(struct drbd_device *device, struct drbd_backing_dev *ldev) +@@ -2552,8 +2552,11 @@ void drbd_backing_dev_free(struct drbd_device *device, struct drbd_backing_dev * + + drbd_dax_close(ldev); + +- close_backing_dev(device, ldev->md_bdev, ldev->md_bdev != ldev->backing_bdev); +- close_backing_dev(device, ldev->backing_bdev, true); ++ close_backing_dev(device, ++ ldev->md_bdev, ++ ldev->md.meta_dev_idx < 0 ? (void *)device : (void *)drbd_m_holder, ++ ldev->md_bdev != ldev->backing_bdev); ++ close_backing_dev(device, ldev->backing_bdev, device, true); + + kfree(ldev->disk_conf); + kfree(ldev); +@@ -2563,7 +2566,7 @@ static struct block_device *open_backing_dev(struct drbd_device *device, + const char *bdev_path, void *claim_ptr) + { + struct block_device *bdev = blkdev_get_by_path(bdev_path, +- FMODE_READ | FMODE_WRITE | FMODE_EXCL, ++ FMODE_READ | FMODE_WRITE, + claim_ptr, NULL); + if (IS_ERR(bdev)) { + drbd_err(device, "open(\"%s\") failed with %ld\n", +@@ -2588,6 +2591,7 @@ static int open_backing_devices(struct drbd_device *device, + struct drbd_backing_dev *nbc) + { + struct block_device *bdev; ++ void *meta_claim_ptr; + int err; + + bdev = open_backing_dev(device, new_disk_conf->backing_dev, device); +@@ -2597,12 +2601,17 @@ static int open_backing_devices(struct drbd_device *device, + err = link_backing_dev(device, new_disk_conf->backing_dev, bdev); + if (err) { + /* close without unlinking; otherwise error path will try to unlink */ +- close_backing_dev(device, bdev, false); ++ close_backing_dev(device, bdev, device, false); + return ERR_OPEN_DISK; + } + + nbc->backing_bdev = bdev; + ++ /* meta_claim_ptr: device, if claimed exclusively; shared drbd_m_holder, ++ * if potentially shared with other drbd minors ++ */ ++ meta_claim_ptr = (new_disk_conf->meta_dev_idx < 0) ? ++ (void *)device : (void *)drbd_m_holder; + /* + * meta_dev_idx >= 0: external fixed size, possibly multiple + * drbd sharing one meta device. TODO in that case, paranoia +@@ -2611,10 +2620,7 @@ static int open_backing_devices(struct drbd_device *device, + * should check it for you already; but if you don't, or + * someone fooled it, we need to double check here) + */ +- bdev = open_backing_dev(device, new_disk_conf->meta_dev, +- /* claim ptr: device, if claimed exclusively; shared drbd_m_holder, +- * if potentially shared with other drbd minors */ +- (new_disk_conf->meta_dev_idx < 0) ? (void*)device : (void*)drbd_m_holder); ++ bdev = open_backing_dev(device, new_disk_conf->meta_dev, meta_claim_ptr); + if (IS_ERR(bdev)) + return ERR_OPEN_MD_DISK; + +@@ -2624,7 +2630,7 @@ static int open_backing_devices(struct drbd_device *device, + err = link_backing_dev(device, new_disk_conf->meta_dev, bdev); + if (err) { + /* close without unlinking; otherwise error path will try to unlink */ +- close_backing_dev(device, bdev, false); ++ close_backing_dev(device, bdev, meta_claim_ptr, false); + return ERR_OPEN_MD_DISK; + } + } +-- +2.35.3 + diff --git a/0016-drbd-Fix-net-options-set-defaults-to-not-clear-the-t.patch b/0016-drbd-Fix-net-options-set-defaults-to-not-clear-the-t.patch new file mode 100644 index 0000000..8ba4ee9 --- /dev/null +++ b/0016-drbd-Fix-net-options-set-defaults-to-not-clear-the-t.patch @@ -0,0 +1,33 @@ +From 69d9286628b730870665cd2c6f05dd9f1813c65e Mon Sep 17 00:00:00 2001 +From: Philipp Reisner +Date: Sun, 17 Sep 2023 22:21:11 +0800 +Subject: [PATCH 16/20] drbd: Fix `net-options --set-defaults` to not clear the + transport + +So far, `drbdsetup net-options --set-defaults` cleared the +transport_name. That is a stupid bug that caused `drbdadm adjust` to +do a disconnect/connect cycle. This affected `lb-tcp` and `rdma`. As +`tcp` is the default, it was not affected by this. +--- + drbd/drbd_nl.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drbd/drbd_nl.c b/drbd/drbd_nl.c +index 8c968cf252ca..b0a1e6fa46f1 100644 +--- a/drbd/drbd_nl.c ++++ b/drbd/drbd_nl.c +@@ -3729,6 +3729,11 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info) + if (should_set_defaults(info)) + set_net_conf_defaults(new_net_conf); + ++ /* The transport_name is immutable taking precedence over set_net_conf_defaults() */ ++ memcpy(new_net_conf->transport_name, old_net_conf->transport_name, ++ old_net_conf->transport_name_len); ++ new_net_conf->transport_name_len = old_net_conf->transport_name_len; ++ + err = net_conf_from_attrs_for_change(new_net_conf, info); + if (err && err != -ENOMSG) { + retcode = ERR_MANDATORY_TAG; +-- +2.35.3 + diff --git a/0017-drbd-propagate-exposed-UUIDs-only-into-established-c.patch b/0017-drbd-propagate-exposed-UUIDs-only-into-established-c.patch new file mode 100644 index 0000000..33d6744 --- /dev/null +++ b/0017-drbd-propagate-exposed-UUIDs-only-into-established-c.patch @@ -0,0 +1,35 @@ +From 0666bc5b014049b6aa184b5a8fdb60481b9c8717 Mon Sep 17 00:00:00 2001 +From: Philipp Reisner +Date: Fri, 22 Sep 2023 15:09:07 +0200 +Subject: [PATCH 17/20] drbd: propagate exposed UUIDs only into established + connections + +Sending into connections in C_CONNECTING state while we exchange the +feature and auth packets might interfere with exchanging those. I also +witnessed that it might block unexpectedly long (2 - 6 seconds), +holding the `connection->mutex[DATA_STREAM]` mutex and again causing +troubles with establishing connections. + +This is a fix for commit 772e5b21d from April 2023 +"drbd: Consider outdating a disk when more recent data is behind a diskless" +Released with of 9.1.15 and 9.2.4. +--- + drbd/drbd_receiver.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drbd/drbd_receiver.c b/drbd/drbd_receiver.c +index 0c3ab0fd486c..bfd265b86b43 100644 +--- a/drbd/drbd_receiver.c ++++ b/drbd/drbd_receiver.c +@@ -7206,7 +7206,7 @@ static void propagate_exposed_uuid(struct drbd_device *device) + u64 im; + + for_each_peer_device_ref(peer_device, im, device) { +- if (peer_device->connection->cstate[NOW] < C_CONNECTING) ++ if (!test_bit(INITIAL_STATE_SENT, &peer_device->flags)) + continue; + drbd_send_current_uuid(peer_device, device->exposed_data_uuid, 0); + } +-- +2.35.3 + diff --git a/0018-drbd-rework-autopromote.patch b/0018-drbd-rework-autopromote.patch new file mode 100644 index 0000000..dab770a --- /dev/null +++ b/0018-drbd-rework-autopromote.patch @@ -0,0 +1,185 @@ +From e3ef0e229a6ae88346164d1507697ae1b397cdf9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Moritz=20=22WanzenBug=22=20Wanzenb=C3=B6ck?= + +Date: Tue, 12 Sep 2023 10:17:08 +0200 +Subject: [PATCH 18/20] drbd: rework autopromote + +With upstream commit ae220766d87c we lost the ability to keep separate +counts for RW and RO openers. Instead, we keep track of openers using a +single count, and a flag indicating if the device was opened RW once. + +Once a device was opened RW, it will stay "writable" for DRBD, until all +openers are gone. This should offer a good compromise between keeping +the old auto-promote behaviour, and the changed device interface. +--- + drbd/drbd_int.h | 3 ++- + drbd/drbd_main.c | 38 +++++++++++++++++++++----------------- + drbd/drbd_nl.c | 9 +++++---- + drbd/drbd_state.c | 7 ++++--- + 4 files changed, 32 insertions(+), 25 deletions(-) + +diff --git a/drbd/drbd_int.h b/drbd/drbd_int.h +index b705f26e71a4..cf593c09cda1 100644 +--- a/drbd/drbd_int.h ++++ b/drbd/drbd_int.h +@@ -1399,7 +1399,8 @@ struct drbd_device { + + struct drbd_bitmap *bitmap; + +- int open_rw_cnt, open_ro_cnt; ++ int open_cnt; ++ bool writable; + /* FIXME clean comments, restructure so it is more obvious which + * members are protected by what */ + +diff --git a/drbd/drbd_main.c b/drbd/drbd_main.c +index 4b0b967c2c97..bb05b2215dfb 100644 +--- a/drbd/drbd_main.c ++++ b/drbd/drbd_main.c +@@ -2579,10 +2579,9 @@ static enum ioc_rv inc_open_count(struct drbd_device *device, fmode_t mode) + r = IOC_ABORT; + else if (!resource->remote_state_change) { + r = IOC_OK; ++ device->open_cnt++; + if (mode & FMODE_WRITE) +- device->open_rw_cnt++; +- else +- device->open_ro_cnt++; ++ device->writable = true; + } + read_unlock_irq(&resource->state_rwlock); + +@@ -2756,8 +2755,10 @@ void drbd_open_counts(struct drbd_resource *resource, int *rw_count_ptr, int *ro + + rcu_read_lock(); + idr_for_each_entry(&resource->devices, device, vnr) { +- rw_count += device->open_rw_cnt; +- ro_count += device->open_ro_cnt; ++ if (device->writable) ++ rw_count += device->open_cnt; ++ else ++ ro_count += device->open_cnt; + } + rcu_read_unlock(); + *rw_count_ptr = rw_count; +@@ -2825,33 +2826,35 @@ static void drbd_release(struct gendisk *gd, fmode_t mode) + { + struct drbd_device *device = gd->private_data; + struct drbd_resource *resource = device->resource; ++ bool was_writable = device->writable; + int open_rw_cnt, open_ro_cnt; + + mutex_lock(&resource->open_release); +- if (mode & FMODE_WRITE) +- device->open_rw_cnt--; +- else +- device->open_ro_cnt--; ++ device->open_cnt--; + + drbd_open_counts(resource, &open_rw_cnt, &open_ro_cnt); + +- /* last one to close will be responsible for write-out of all dirty pages */ +- if (mode & FMODE_WRITE && device->open_rw_cnt == 0) ++ /* last one to close will be responsible for write-out of all dirty pages. ++ * We also reset the writable flag for this device here: later code may ++ * check if the device is still opened for writes to determine things ++ * like auto-demote. ++ */ ++ if (was_writable && device->open_cnt == 0) { + drbd_fsync_device(device); ++ device->writable = false; ++ } + + if (open_ro_cnt == 0) + wake_up_all(&resource->state_wait); + +- if (test_bit(UNREGISTERED, &device->flags) && +- device->open_rw_cnt == 0 && device->open_ro_cnt == 0 && ++ if (test_bit(UNREGISTERED, &device->flags) && device->open_cnt == 0 && + !test_and_set_bit(DESTROYING_DEV, &device->flags)) + call_rcu(&device->rcu, drbd_reclaim_device); + + if (resource->res_opts.auto_promote) { + enum drbd_state_rv rv; + +- if (mode & FMODE_WRITE && +- open_rw_cnt == 0 && ++ if (was_writable && open_rw_cnt == 0 && + resource->role[NOW] == R_PRIMARY && + !test_bit(EXPLICIT_PRIMARY, &resource->flags)) { + rv = drbd_set_role(resource, R_SECONDARY, false, "auto-demote", NULL); +@@ -2869,9 +2872,10 @@ static void drbd_release(struct gendisk *gd, fmode_t mode) + end_state_change(resource, &irq_flags, "release"); + } + +- /* if the open counts are 0, we free the whole list, otherwise we remove the specific pid */ ++ /* if the open count is 0, we free the whole list, otherwise we remove the specific pid */ + prune_or_free_openers(device, +- (open_ro_cnt == 0 && open_rw_cnt == 0) ? 0 : task_pid_nr(current)); ++ (open_ro_cnt == 0 && open_rw_cnt == 0) ? ++ 0 : task_pid_nr(current)); + + mutex_unlock(&resource->open_release); + +diff --git a/drbd/drbd_nl.c b/drbd/drbd_nl.c +index b0a1e6fa46f1..71ed4272614e 100644 +--- a/drbd/drbd_nl.c ++++ b/drbd/drbd_nl.c +@@ -4541,8 +4541,10 @@ int drbd_open_ro_count(struct drbd_resource *resource) + int vnr, open_ro_cnt = 0; + + read_lock_irq(&resource->state_rwlock); +- idr_for_each_entry(&resource->devices, device, vnr) +- open_ro_cnt += device->open_ro_cnt; ++ idr_for_each_entry(&resource->devices, device, vnr) { ++ if (!device->writable) ++ open_ro_cnt += device->open_cnt; ++ } + read_unlock_irq(&resource->state_rwlock); + + return open_ro_cnt; +@@ -6394,8 +6396,7 @@ static enum drbd_ret_code adm_del_minor(struct drbd_device *device) + notify_device_state(NULL, 0, device, NULL, NOTIFY_DESTROY); + mutex_unlock(¬ification_mutex); + +- if (device->open_ro_cnt == 0 && device->open_rw_cnt == 0 && +- !test_and_set_bit(DESTROYING_DEV, &device->flags)) ++ if (device->open_cnt == 0 && !test_and_set_bit(DESTROYING_DEV, &device->flags)) + call_rcu(&device->rcu, drbd_reclaim_device); + + return ret; +diff --git a/drbd/drbd_state.c b/drbd/drbd_state.c +index 22cd134be962..fa70507df425 100644 +--- a/drbd/drbd_state.c ++++ b/drbd/drbd_state.c +@@ -1634,7 +1634,7 @@ handshake_found: + return SS_TWO_PRIMARIES; + if (!fail_io[NEW]) { + idr_for_each_entry(&resource->devices, device, vnr) { +- if (device->open_ro_cnt) ++ if (!device->writable && device->open_cnt) + return SS_PRIMARY_READER; + /* + * One might be tempted to add "|| open_rw_cont" here. +@@ -1661,7 +1661,7 @@ handshake_found: + (disk_state[OLD] > D_DETACHING && disk_state[NEW] == D_DETACHING))) + return SS_IN_TRANSIENT_STATE; + +- if (role[OLD] == R_PRIMARY && role[NEW] == R_SECONDARY && device->open_rw_cnt && ++ if (role[OLD] == R_PRIMARY && role[NEW] == R_SECONDARY && device->writable && + !(resource->state_change_flags & CS_FS_IGN_OPENERS)) + return SS_DEVICE_IN_USE; + +@@ -1693,7 +1693,8 @@ handshake_found: + return SS_NO_UP_TO_DATE_DISK; + + /* Prevent detach or disconnect while held open read only */ +- if (device->open_ro_cnt && any_disk_up_to_date[OLD] && !any_disk_up_to_date[NEW]) ++ if (!device->writable && device->open_cnt && ++ any_disk_up_to_date[OLD] && !any_disk_up_to_date[NEW]) + return SS_NO_UP_TO_DATE_DISK; + + if (disk_state[NEW] == D_NEGOTIATING) +-- +2.35.3 + diff --git a/0019-compat-block-remove-the-unused-mode-argument-to-rele.patch b/0019-compat-block-remove-the-unused-mode-argument-to-rele.patch new file mode 100644 index 0000000..9f40f7c --- /dev/null +++ b/0019-compat-block-remove-the-unused-mode-argument-to-rele.patch @@ -0,0 +1,107 @@ +From bf287c15359c4495a706ca270e7dcab4c2d6ebcc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Moritz=20=22WanzenBug=22=20Wanzenb=C3=B6ck?= + +Date: Tue, 12 Sep 2023 15:27:01 +0200 +Subject: [PATCH 19/20] compat: block: remove the unused mode argument to + ->release + +See also upstream Linux kernel commit +ae220766d87c ("block: remove the unused mode argument to ->release") + +Original message: + +The mode argument to the ->release block_device_operation is never used, +so remove it. +--- + ...ions_release__no_takes_single_argument.cocci | 17 +++++++++++++++++ + drbd/drbd-kernel-compat/gen_patch_names.c | 3 +++ + ...e_operations_release_takes_single_argument.c | 7 +++++++ + drbd/drbd_main.c | 6 +++--- + 4 files changed, 30 insertions(+), 3 deletions(-) + create mode 100644 drbd/drbd-kernel-compat/cocci/block_device_operations_release__no_takes_single_argument.cocci + create mode 100644 drbd/drbd-kernel-compat/tests/block_device_operations_release_takes_single_argument.c + +diff --git a/drbd/drbd-kernel-compat/cocci/block_device_operations_release__no_takes_single_argument.cocci b/drbd/drbd-kernel-compat/cocci/block_device_operations_release__no_takes_single_argument.cocci +new file mode 100644 +index 000000000000..b0a0ee9eef39 +--- /dev/null ++++ b/drbd/drbd-kernel-compat/cocci/block_device_operations_release__no_takes_single_argument.cocci +@@ -0,0 +1,17 @@ ++@@ ++identifier gd; ++fresh identifier mode = "" ## "mode"; ++@@ ++ drbd_release( ++ struct gendisk *gd +++ , fmode_t mode ++ ) { ... } ++ ++@@ ++symbol drbd_release; ++expression gd; ++@@ ++ drbd_release( ++ gd +++ , 0 ++ ) +diff --git a/drbd/drbd-kernel-compat/gen_patch_names.c b/drbd/drbd-kernel-compat/gen_patch_names.c +index 4761c1ef7d0c..608be8b4f099 100644 +--- a/drbd/drbd-kernel-compat/gen_patch_names.c ++++ b/drbd/drbd-kernel-compat/gen_patch_names.c +@@ -565,6 +565,9 @@ int main(int argc, char **argv) + patch(1, "blkdev_put", true, false, + COMPAT_BLKDEV_PUT_HAS_HOLDER, "has_holder"); + ++ patch(1, "block_device_operations_release", true, false, ++ COMPAT_BLOCK_DEVICE_OPERATIONS_RELEASE_TAKES_SINGLE_ARGUMENT, "takes_single_argument"); ++ + /* #define BLKDEV_ISSUE_ZEROOUT_EXPORTED */ + /* #define BLKDEV_ZERO_NOUNMAP */ + +diff --git a/drbd/drbd-kernel-compat/tests/block_device_operations_release_takes_single_argument.c b/drbd/drbd-kernel-compat/tests/block_device_operations_release_takes_single_argument.c +new file mode 100644 +index 000000000000..d51c863e359a +--- /dev/null ++++ b/drbd/drbd-kernel-compat/tests/block_device_operations_release_takes_single_argument.c +@@ -0,0 +1,7 @@ ++/* { "version": "v6.5-rc1", "commit": "ae220766d87cd6799dbf918fea10613ae14c0654", "comment": "block: remove the unused mode argument to ->release", "author": "Christoph Hellwig ", "date": "Thu Jun 8 13:02:37 2023 +0200" } */ ++#include ++ ++void foo(struct block_device_operations *ops, struct gendisk *gd) ++{ ++ ops->release(gd); ++} +diff --git a/drbd/drbd_main.c b/drbd/drbd_main.c +index bb05b2215dfb..1864861db21d 100644 +--- a/drbd/drbd_main.c ++++ b/drbd/drbd_main.c +@@ -53,7 +53,7 @@ + #include "drbd_dax_pmem.h" + + static int drbd_open(struct gendisk *gd, fmode_t mode); +-static void drbd_release(struct gendisk *gd, fmode_t mode); ++static void drbd_release(struct gendisk *gd); + static void md_sync_timer_fn(struct timer_list *t); + static int w_bitmap_io(struct drbd_work *w, int unused); + static int flush_send_buffer(struct drbd_connection *connection, enum drbd_stream drbd_stream); +@@ -2740,7 +2740,7 @@ out: + + mutex_unlock(&resource->open_release); + if (err) { +- drbd_release(gd, mode); ++ drbd_release(gd); + if (err == -EAGAIN && !(mode & FMODE_NDELAY)) + err = -EMEDIUMTYPE; + } +@@ -2822,7 +2822,7 @@ void drbd_fsync_device(struct drbd_device *device) + drbd_flush_peer_acks(resource); + } + +-static void drbd_release(struct gendisk *gd, fmode_t mode) ++static void drbd_release(struct gendisk *gd) + { + struct drbd_device *device = gd->private_data; + struct drbd_resource *resource = device->resource; +-- +2.35.3 + diff --git a/0020-drbd-do-not-allow-auto-demote-to-be-interrupted-by-s.patch b/0020-drbd-do-not-allow-auto-demote-to-be-interrupted-by-s.patch new file mode 100644 index 0000000..f95b989 --- /dev/null +++ b/0020-drbd-do-not-allow-auto-demote-to-be-interrupted-by-s.patch @@ -0,0 +1,66 @@ +From c8e2a3c4355b4794267cd6e58a074802b4607cb9 Mon Sep 17 00:00:00 2001 +From: Joel Colledge +Date: Fri, 22 Sep 2023 16:57:24 +0200 +Subject: [PATCH 20/20] drbd: do not allow auto-demote to be interrupted by + signal + +Pending signals can mess up auto-demote: + +drbd res: Preparing cluster-wide state change 671410162 (0->-1 3/2) +drbd res: Aborting cluster-wide state change 671410162 (6ms) rv = -21 +drbd res: Auto-demote failed: Interrupted state change + +After this state change failure no process has the DRBD device open, but +DRBD remains Primary. +--- + drbd/drbd_main.c | 33 +++++++++++++++++++++++---------- + 1 file changed, 23 insertions(+), 10 deletions(-) + +diff --git a/drbd/drbd_main.c b/drbd/drbd_main.c +index 1864861db21d..0719229f210e 100644 +--- a/drbd/drbd_main.c ++++ b/drbd/drbd_main.c +@@ -2851,17 +2851,30 @@ static void drbd_release(struct gendisk *gd) + !test_and_set_bit(DESTROYING_DEV, &device->flags)) + call_rcu(&device->rcu, drbd_reclaim_device); + +- if (resource->res_opts.auto_promote) { +- enum drbd_state_rv rv; ++ if (resource->res_opts.auto_promote && ++ open_rw_cnt == 0 && ++ resource->role[NOW] == R_PRIMARY && ++ !test_bit(EXPLICIT_PRIMARY, &resource->flags)) { ++ sigset_t mask, oldmask; ++ int rv; ++ ++ /* ++ * Auto-demote is triggered by the last opener releasing the ++ * DRBD device. However, it is an implicit action, so it should ++ * not be affected by the state of the process. In particular, ++ * it should ignore any pending signals. It may be the case ++ * that the process is releasing DRBD because it is being ++ * terminated using a signal. ++ */ ++ sigfillset(&mask); ++ sigprocmask(SIG_BLOCK, &mask, &oldmask); + +- if (was_writable && open_rw_cnt == 0 && +- resource->role[NOW] == R_PRIMARY && +- !test_bit(EXPLICIT_PRIMARY, &resource->flags)) { +- rv = drbd_set_role(resource, R_SECONDARY, false, "auto-demote", NULL); +- if (rv < SS_SUCCESS) +- drbd_warn(resource, "Auto-demote failed: %s (%d)\n", +- drbd_set_st_err_str(rv), rv); +- } ++ rv = drbd_set_role(resource, R_SECONDARY, false, "auto-demote", NULL); ++ if (rv < SS_SUCCESS) ++ drbd_warn(resource, "Auto-demote failed: %s (%d)\n", ++ drbd_set_st_err_str(rv), rv); ++ ++ sigprocmask(SIG_SETMASK, &oldmask, NULL); + } + + if (open_ro_cnt == 0 && open_rw_cnt == 0 && resource->fail_io[NOW]) { +-- +2.35.3 + diff --git a/bsc-1215699_fix-build-error-against-kernel-v6.5.4.patch b/bsc-1215699_fix-build-error-against-kernel-v6.5.4.patch new file mode 100644 index 0000000..3fd25e5 --- /dev/null +++ b/bsc-1215699_fix-build-error-against-kernel-v6.5.4.patch @@ -0,0 +1,86 @@ +Author: Heming Zhao +Date: Thu Sep 28 11:12:00 2023 +0800 +Subject: drbd: fix build error against kernel v6.5.4 + +Below two upstream commits broken drbd v9.1 building + +(belonging to v6.5-rc1) +``` +commit dc97391e661009eab46783030d2404c9b6e6f2e7 +Author: David Howells +Date: Fri Jun 23 23:55:12 2023 +0100 + + sock: Remove ->sendpage*() in favour of sendmsg(MSG_SPLICE_PAGES) + + +commit 0733ad8002916b9dbbbcfe6e92ad44d2657de1c1 +Author: Christoph Hellwig +Date: Thu Jun 8 13:02:58 2023 +0200 + + fs: remove the now unused FMODE_* flags +``` + +This patch fix the build error. + +--- + +diff -Nupr a/drbd/drbd_main.c b/drbd/drbd_main.c +--- a/drbd/drbd_main.c 2023-09-26 11:08:57.142974614 +0800 ++++ b/drbd/drbd_main.c 2023-09-26 11:07:53.646071680 +0800 +@@ -2569,7 +2569,7 @@ enum ioc_rv { + static enum ioc_rv inc_open_count(struct drbd_device *device, fmode_t mode) + { + struct drbd_resource *resource = device->resource; +- enum ioc_rv r = mode & FMODE_NDELAY ? IOC_ABORT : IOC_SLEEP; ++ enum ioc_rv r = mode & BLK_OPEN_NDELAY ? IOC_ABORT : IOC_SLEEP; + + if (test_bit(DOWN_IN_PROGRESS, &resource->flags)) + return IOC_ABORT; +@@ -2695,12 +2695,12 @@ static int drbd_open(struct gendisk *gd, + + if (mode & FMODE_WRITE) { + if (resource->role[NOW] == R_SECONDARY) { +- rv = try_to_promote(device, timeout, (mode & FMODE_NDELAY)); ++ rv = try_to_promote(device, timeout, (mode & BLK_OPEN_NDELAY)); + if (rv < SS_SUCCESS) + drbd_info(resource, "Auto-promote failed: %s (%d)\n", + drbd_set_st_err_str(rv), rv); + } +- } else if ((mode & FMODE_NDELAY) == 0) { ++ } else if ((mode & BLK_OPEN_NDELAY) == 0) { + /* Double check peers + * + * Some services may try to first open ro, and only if that +@@ -2741,7 +2741,7 @@ out: + mutex_unlock(&resource->open_release); + if (err) { + drbd_release(gd); +- if (err == -EAGAIN && !(mode & FMODE_NDELAY)) ++ if (err == -EAGAIN && !(mode & BLK_OPEN_NDELAY)) + err = -EMEDIUMTYPE; + } + +diff -Nupr a/drbd/drbd_transport_tcp.c b/drbd/drbd_transport_tcp.c +--- a/drbd/drbd_transport_tcp.c 2023-09-26 11:09:04.016333505 +0800 ++++ b/drbd/drbd_transport_tcp.c 2023-09-26 11:07:59.132758771 +0800 +@@ -1193,6 +1193,8 @@ static int dtt_send_page(struct drbd_tra + struct drbd_tcp_transport *tcp_transport = + container_of(transport, struct drbd_tcp_transport, transport); + struct socket *socket = tcp_transport->stream[stream]; ++ struct msghdr msghdr = { .msg_flags = MSG_SPLICE_PAGES|msg_flags, }; ++ struct bio_vec bvec; + int len = size; + int err = -EIO; + +@@ -1204,7 +1206,10 @@ static int dtt_send_page(struct drbd_tra + do { + int sent; + +- sent = socket->ops->sendpage(socket, page, offset, len, msg_flags); ++ //sent = socket->ops->sendpage(socket, page, offset, len, msg_flags); ++ bvec_set_page(&bvec, page, offset, len); ++ iov_iter_bvec(&msghdr.msg_iter, ITER_SOURCE, &bvec, 1, len); ++ sent = sock_sendmsg(socket, &msghdr); + if (sent <= 0) { + if (sent == -EAGAIN) { + if (drbd_stream_send_timed_out(transport, stream)) diff --git a/drbd.changes b/drbd.changes index aee12fb..70dd531 100644 --- a/drbd.changes +++ b/drbd.changes @@ -1,3 +1,31 @@ +------------------------------------------------------------------ +Tue Sep 26 03:35:00 UTC 2023 - Heming Zhao + +- drbd: fix build error against kernel v6.5.4 (boo#1215699) + * add upstream patch + + 0001-drbd-allow-transports-to-take-additional-krefs-on-a-.patch + + 0002-drbd-improve-decision-about-marking-a-failed-disk-Ou.patch + + 0003-drbd-fix-error-path-in-drbd_get_listener.patch + + 0004-drbd-build-fix-spurious-re-build-attempt-of-compat.p.patch + + 0005-drbd-log-error-code-when-thread-fails-to-start.patch + + 0006-drbd-log-numeric-value-of-drbd_state_rv-as-well-as-s.patch + + 0007-drbd-stop-defining-__KERNEL_SYSCALLS__.patch + + 0008-compat-block-introduce-holder-ops.patch + + 0009-drbd-reduce-net_ee-not-empty-info-to-a-dynamic-debug.patch + + 0010-drbd-do-not-send-P_CURRENT_UUID-to-DRBD-8-peer-when-.patch + + 0011-compat-block-pass-a-gendisk-to-open.patch + + 0012-drbd-Restore-DATA_CORKED-and-CONTROL_CORKED-bits.patch + + 0013-drbd-remove-unused-extern-for-conn_try_outdate_peer.patch + + 0014-drbd-include-source-of-state-change-in-log.patch + + 0015-compat-block-use-the-holder-as-indication-for-exclus.patch + + 0016-drbd-Fix-net-options-set-defaults-to-not-clear-the-t.patch + + 0017-drbd-propagate-exposed-UUIDs-only-into-established-c.patch + + 0018-drbd-rework-autopromote.patch + + 0019-compat-block-remove-the-unused-mode-argument-to-rele.patch + + 0020-drbd-do-not-allow-auto-demote-to-be-interrupted-by-s.patch + * add suse special patch + + bsc-1215699_fix-build-error-against-kernel-v6.5.4.patch + ------------------------------------------------------------------ Mon Sep 04 11:35:00 UTC 2023 - Heming Zhao diff --git a/drbd.spec b/drbd.spec index f478bc2..72cddd3 100644 --- a/drbd.spec +++ b/drbd.spec @@ -34,8 +34,33 @@ Source1: preamble Source2: Module.supported Source3: drbd_git_revision -Patch1: bsc-1025089_fix-resync-finished-with-syncs-have-bits-set.patch -Patch99: suse-coccinelle.patch +######################## +# upstream patch +Patch0001: 0001-drbd-allow-transports-to-take-additional-krefs-on-a-.patch +Patch0002: 0002-drbd-improve-decision-about-marking-a-failed-disk-Ou.patch +Patch0003: 0003-drbd-fix-error-path-in-drbd_get_listener.patch +Patch0004: 0004-drbd-build-fix-spurious-re-build-attempt-of-compat.p.patch +Patch0005: 0005-drbd-log-error-code-when-thread-fails-to-start.patch +Patch0006: 0006-drbd-log-numeric-value-of-drbd_state_rv-as-well-as-s.patch +Patch0007: 0007-drbd-stop-defining-__KERNEL_SYSCALLS__.patch +Patch0008: 0008-compat-block-introduce-holder-ops.patch +Patch0009: 0009-drbd-reduce-net_ee-not-empty-info-to-a-dynamic-debug.patch +Patch0010: 0010-drbd-do-not-send-P_CURRENT_UUID-to-DRBD-8-peer-when-.patch +Patch0011: 0011-compat-block-pass-a-gendisk-to-open.patch +Patch0012: 0012-drbd-Restore-DATA_CORKED-and-CONTROL_CORKED-bits.patch +Patch0013: 0013-drbd-remove-unused-extern-for-conn_try_outdate_peer.patch +Patch0014: 0014-drbd-include-source-of-state-change-in-log.patch +Patch0015: 0015-compat-block-use-the-holder-as-indication-for-exclus.patch +Patch0016: 0016-drbd-Fix-net-options-set-defaults-to-not-clear-the-t.patch +Patch0017: 0017-drbd-propagate-exposed-UUIDs-only-into-established-c.patch +Patch0018: 0018-drbd-rework-autopromote.patch +Patch0019: 0019-compat-block-remove-the-unused-mode-argument-to-rele.patch +Patch0020: 0020-drbd-do-not-allow-auto-demote-to-be-interrupted-by-s.patch +# suse special patch +Patch1001: bsc-1025089_fix-resync-finished-with-syncs-have-bits-set.patch +Patch1002: suse-coccinelle.patch +Patch1003: bsc-1215699_fix-build-error-against-kernel-v6.5.4.patch +######################## #https://github.com/openSUSE/rpmlint-checks/blob/master/KMPPolicyCheck.py BuildRequires: coccinelle >= 1.0.8 @@ -70,8 +95,29 @@ installed kernel. %prep %setup -q -n drbd-%{version} -%patch1 -p1 -%patch99 -p1 +%patch0001 -p1 +%patch0002 -p1 +%patch0003 -p1 +%patch0004 -p1 +%patch0005 -p1 +%patch0006 -p1 +%patch0007 -p1 +%patch0008 -p1 +%patch0009 -p1 +%patch0010 -p1 +%patch0011 -p1 +%patch0012 -p1 +%patch0013 -p1 +%patch0014 -p1 +%patch0015 -p1 +%patch0016 -p1 +%patch0017 -p1 +%patch0018 -p1 +%patch0019 -p1 +%patch0020 -p1 +%patch1001 -p1 +%patch1002 -p1 +%patch1003 -p1 mkdir source cp -a drbd/. source/. || :