SHA256
1
0
forked from pool/drbd
drbd/0032-drbd-open-do-not-delay-open-if-already-Primary.patch
heming zhao 6ee9ba5898 - Update DRBD version from 9.1.22 to 9.1.23 (boo#1234849)
* Changelog from Linbit:
    9.1.23 (api:genl2/proto:86-101,118-121/transport:18)
    --------
     * Fix a corner case that can happen when DRBD establishes multiple
       connections in parallel, which could lead one connection to end up in
       an inconsistent replication state of WFBitMapT/Established
     * Fix a corner case in which a reconciliation resync ends up in
       WFBitMapT/Established
     * Restrict protocol compatibility to the most recent 8.4 and 9.0 releases
     * Fix a corner case causing a module ref leak on drbd_transport_tcp;
       if it hits, you can not rmmod it
     * rate-limit resync progress while resync is paused
     * resync-target inherits history UUIDs when resync finishes,
       this can prevent unexpected "unrelared data" events later
     * Updated compatibility code for Linux 6.11 and 6.12
  * remove patches which already included in the new version:
     0001-drbd-properly-rate-limit-resync-progress-reports.patch
     0002-drbd-inherit-history-UUIDs-from-sync-source-when-res.patch
     0003-build-compat-fix-line-offset-in-annotation-pragmas-p.patch
     0004-drbd-fix-exposed_uuid-going-backward.patch
     0005-drbd-Proper-locking-around-new_current_uuid-on-a-dis.patch
     0006-build-CycloneDX-fix-bom-ref-add-purl.patch
     0007-build-Another-update-to-the-spdx-files.patch
     0008-build-generate-spdx.json-not-tag-value-format.patch
     0009-compat-fix-gen_patch_names-for-bdev_file_open_by_pat.patch
     0010-compat-fix-nla_nest_start_noflag-test.patch
     0011-compat-fix-blk_alloc_disk-rule.patch
     0012-drbd-remove-const-from-function-return-type.patch
     0013-drbd-don-t-set-max_write_zeroes_sectors-in-decide_on.patch
     0014-drbd-split-out-a-drbd_discard_supported-helper.patch
     0015-drbd-atomically-update-queue-limits-in-drbd_reconsid.patch
     0016-compat-test-and-patch-for-queue_limits_start_update.patch
     0017-compat-specify-which-essential-change-was-not-made.patch
     0018-gen_patch_names-reorder-blk_mode_t.patch
     0019-compat-fix-blk_queue_update_readahead-patch.patch
     0020-compat-test-and-patch-for-que_limits-max_hw_discard_.patch
     0021-compat-fixup-write_zeroes__no_capable.patch
     0022-compat-fixup-queue_flag_discard__yes_present.patch
     0023-drbd-move-flags-to-queue_limits.patch
     0024-compat-test-and-patch-for-queue_limits.features.patch
     0025-drbd-Annotate-struct-fifo_buffer-with-__counted_by.patch
     0026-compat-test-and-patch-for-__counted_by.patch
     0027-drbd-fix-function-cast-warnings-in-state-machine.patch
     0028-Add-missing-documentation-of-peer_device-parameter-t.patch
     0030-drbd-kref_put-path-when-kernel_accept-fails.patch
     0031-build-fix-typo-in-Makefile.spatch.patch
     0032-drbd-open-do-not-delay-open-if-already-Primary.patch
  * removed patch which is not needed anymore:
     boo1231290_fix_drbd_build_error_against_kernel_v6.11.0.patch
     boo1233222_fix_drbd_build_error_against_kernel_v6.11.6.patch
  * update:
     drbd_git_revision
     drbd.spec
  * add upstream patches to align commit d64ebe7eb7df:
     0001-drbd-Fix-memory-leak.patch

OBS-URL: https://build.opensuse.org/package/show/network:ha-clustering:Factory/drbd?expand=0&rev=155
2024-12-27 03:43:25 +00:00

91 lines
3.4 KiB
Diff

From 13ada1be201eb14ff8295a17194de8db5cdccd7f Mon Sep 17 00:00:00 2001
From: Lars Ellenberg <lars.ellenberg@linbit.com>
Date: Wed, 2 Oct 2024 14:34:02 +0200
Subject: [PATCH 32/32] drbd: open: do not delay open() if already Primary
Since 48376549f (drbd: When a remote state change is active to not touch the open_counts, 2017-10-30)
if a remote state change is pending when someone tries to open() a DRBD volume,
we wait, interruptible, for "auto-promote-timeout",
until that state change is finalized (committed or aborted),
or give up with EAGAIN if the auto-promote timeout is reached.
auto-promote-timeout by default is much smaller than twopc-timeout,
so we may get spurious open() failures.
This could be mitigated with auto-promote-timeout > twopc-timeout.
But we can just ignore the pending state change,
if changing the open_cnt won't make a difference:
if we are already Primary, or we already have openers anyways.
If
- we have some remote state change pending,
- and we are not Primary already,
- and we do not have any openers, or this is an open with write intent,
we reject NDELAY openers immediately.
Normal openers wait for the state change to be finalized
(or give up after auto-promote-timeout).
We do not need to wait if:
- there is no remote state change pending,
- or we are already Primary anyways,
- or we are Secondary, this is a read-only open, and we have openers already.
Note: we may still want to immediately reject NDELAY open if
there is a remote state change pending, even if we have an
open count != 0. These are typically short lived openers
triggered via udev. If they overlap (new open comes in
before previous close), these may still accumulate enough
time to mess with state changes.
For now, I decide to allow them.
---
drbd/drbd_main.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/drbd/drbd_main.c b/drbd/drbd_main.c
index a216b725e66c..258be3b9c10d 100644
--- a/drbd/drbd_main.c
+++ b/drbd/drbd_main.c
@@ -2583,10 +2583,21 @@ enum ioc_rv {
IOC_ABORT = 2,
};
+/* If we are in the middle of a cluster wide state change, we don't want
+ * to change (open_cnt == 0), as that then could cause a failure to commit
+ * some already promised peer auto-promote locally.
+ * So we wait until the pending remote_state_change is finalized,
+ * or give up when the timeout is reached.
+ *
+ * But we don't want to fail an open on a Primary just because it happens
+ * during some unrelated remote state change.
+ * If we are already Primary, or already have an open count != 0,
+ * we don't need to wait, it won't change anything.
+ */
static enum ioc_rv inc_open_count(struct drbd_device *device, blk_mode_t mode)
{
struct drbd_resource *resource = device->resource;
- enum ioc_rv r = mode & BLK_OPEN_NDELAY ? IOC_ABORT : IOC_SLEEP;
+ enum ioc_rv r;
if (test_bit(DOWN_IN_PROGRESS, &resource->flags))
return IOC_ABORT;
@@ -2594,7 +2605,14 @@ static enum ioc_rv inc_open_count(struct drbd_device *device, blk_mode_t mode)
read_lock_irq(&resource->state_rwlock);
if (test_bit(UNREGISTERED, &device->flags))
r = IOC_ABORT;
- else if (!resource->remote_state_change) {
+ else if (resource->remote_state_change &&
+ resource->role[NOW] != R_PRIMARY &&
+ (device->open_cnt == 0 || mode & BLK_OPEN_WRITE)) {
+ if (mode & BLK_OPEN_NDELAY)
+ r = IOC_ABORT;
+ else
+ r = IOC_SLEEP;
+ } else {
r = IOC_OK;
device->open_cnt++;
if (mode & BLK_OPEN_WRITE)
--
2.35.3