]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 1 Aug 2023 06:27:59 +0000 (08:27 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 1 Aug 2023 06:27:59 +0000 (08:27 +0200)
added patches:
ceph-never-send-metrics-if-disable_send_metrics-is-set.patch
dm-cache-policy-smq-ensure-io-doesn-t-prevent-cleaner-policy-progress.patch
drm-i915-dpt-use-shmem-for-dpt-objects.patch
rbd-harden-get_lock_owner_info-a-bit.patch
rbd-make-get_lock_owner_info-return-a-single-locker-or-null.patch
rbd-retrieve-and-check-lock-owner-twice-before-blocklisting.patch

queue-6.1/ceph-never-send-metrics-if-disable_send_metrics-is-set.patch [new file with mode: 0644]
queue-6.1/dm-cache-policy-smq-ensure-io-doesn-t-prevent-cleaner-policy-progress.patch [new file with mode: 0644]
queue-6.1/drm-i915-dpt-use-shmem-for-dpt-objects.patch [new file with mode: 0644]
queue-6.1/rbd-harden-get_lock_owner_info-a-bit.patch [new file with mode: 0644]
queue-6.1/rbd-make-get_lock_owner_info-return-a-single-locker-or-null.patch [new file with mode: 0644]
queue-6.1/rbd-retrieve-and-check-lock-owner-twice-before-blocklisting.patch [new file with mode: 0644]
queue-6.1/series

diff --git a/queue-6.1/ceph-never-send-metrics-if-disable_send_metrics-is-set.patch b/queue-6.1/ceph-never-send-metrics-if-disable_send_metrics-is-set.patch
new file mode 100644 (file)
index 0000000..fec9d1f
--- /dev/null
@@ -0,0 +1,34 @@
+From 50164507f6b7b7ed85d8c3ac0266849fbd908db7 Mon Sep 17 00:00:00 2001
+From: Xiubo Li <xiubli@redhat.com>
+Date: Thu, 20 Jul 2023 11:33:55 +0800
+Subject: ceph: never send metrics if disable_send_metrics is set
+
+From: Xiubo Li <xiubli@redhat.com>
+
+commit 50164507f6b7b7ed85d8c3ac0266849fbd908db7 upstream.
+
+Even the 'disable_send_metrics' is true so when the session is
+being opened it will always trigger to send the metric for the
+first time.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Xiubo Li <xiubli@redhat.com>
+Reviewed-by: Venky Shankar <vshankar@redhat.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ceph/metric.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/ceph/metric.c
++++ b/fs/ceph/metric.c
+@@ -208,7 +208,7 @@ static void metric_delayed_work(struct w
+       struct ceph_mds_client *mdsc =
+               container_of(m, struct ceph_mds_client, metric);
+-      if (mdsc->stopping)
++      if (mdsc->stopping || disable_send_metrics)
+               return;
+       if (!m->session || !check_session_state(m->session)) {
diff --git a/queue-6.1/dm-cache-policy-smq-ensure-io-doesn-t-prevent-cleaner-policy-progress.patch b/queue-6.1/dm-cache-policy-smq-ensure-io-doesn-t-prevent-cleaner-policy-progress.patch
new file mode 100644 (file)
index 0000000..2164334
--- /dev/null
@@ -0,0 +1,106 @@
+From 1e4ab7b4c881cf26c1c72b3f56519e03475486fb Mon Sep 17 00:00:00 2001
+From: Joe Thornber <ejt@redhat.com>
+Date: Tue, 25 Jul 2023 11:44:41 -0400
+Subject: dm cache policy smq: ensure IO doesn't prevent cleaner policy progress
+
+From: Joe Thornber <ejt@redhat.com>
+
+commit 1e4ab7b4c881cf26c1c72b3f56519e03475486fb upstream.
+
+When using the cleaner policy to decommission the cache, there is
+never any writeback started from the cache as it is constantly delayed
+due to normal I/O keeping the device busy. Meaning @idle=false was
+always being passed to clean_target_met()
+
+Fix this by adding a specific 'cleaner' flag that is set when the
+cleaner policy is configured. This flag serves to always allow the
+cleaner's writeback work to be queued until the cache is
+decommissioned (even if the cache isn't idle).
+
+Reported-by: David Jeffery <djeffery@redhat.com>
+Fixes: b29d4986d0da ("dm cache: significant rework to leverage dm-bio-prison-v2")
+Cc: stable@vger.kernel.org
+Signed-off-by: Joe Thornber <ejt@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/md/dm-cache-policy-smq.c |   28 ++++++++++++++++++----------
+ 1 file changed, 18 insertions(+), 10 deletions(-)
+
+--- a/drivers/md/dm-cache-policy-smq.c
++++ b/drivers/md/dm-cache-policy-smq.c
+@@ -855,7 +855,13 @@ struct smq_policy {
+       struct background_tracker *bg_work;
+-      bool migrations_allowed;
++      bool migrations_allowed:1;
++
++      /*
++       * If this is set the policy will try and clean the whole cache
++       * even if the device is not idle.
++       */
++      bool cleaner:1;
+ };
+ /*----------------------------------------------------------------*/
+@@ -1136,7 +1142,7 @@ static bool clean_target_met(struct smq_
+        * Cache entries may not be populated.  So we cannot rely on the
+        * size of the clean queue.
+        */
+-      if (idle) {
++      if (idle || mq->cleaner) {
+               /*
+                * We'd like to clean everything.
+                */
+@@ -1719,11 +1725,9 @@ static void calc_hotspot_params(sector_t
+               *hotspot_block_size /= 2u;
+ }
+-static struct dm_cache_policy *__smq_create(dm_cblock_t cache_size,
+-                                          sector_t origin_size,
+-                                          sector_t cache_block_size,
+-                                          bool mimic_mq,
+-                                          bool migrations_allowed)
++static struct dm_cache_policy *
++__smq_create(dm_cblock_t cache_size, sector_t origin_size, sector_t cache_block_size,
++           bool mimic_mq, bool migrations_allowed, bool cleaner)
+ {
+       unsigned int i;
+       unsigned int nr_sentinels_per_queue = 2u * NR_CACHE_LEVELS;
+@@ -1810,6 +1814,7 @@ static struct dm_cache_policy *__smq_cre
+               goto bad_btracker;
+       mq->migrations_allowed = migrations_allowed;
++      mq->cleaner = cleaner;
+       return &mq->policy;
+@@ -1833,21 +1838,24 @@ static struct dm_cache_policy *smq_creat
+                                         sector_t origin_size,
+                                         sector_t cache_block_size)
+ {
+-      return __smq_create(cache_size, origin_size, cache_block_size, false, true);
++      return __smq_create(cache_size, origin_size, cache_block_size,
++                          false, true, false);
+ }
+ static struct dm_cache_policy *mq_create(dm_cblock_t cache_size,
+                                        sector_t origin_size,
+                                        sector_t cache_block_size)
+ {
+-      return __smq_create(cache_size, origin_size, cache_block_size, true, true);
++      return __smq_create(cache_size, origin_size, cache_block_size,
++                          true, true, false);
+ }
+ static struct dm_cache_policy *cleaner_create(dm_cblock_t cache_size,
+                                             sector_t origin_size,
+                                             sector_t cache_block_size)
+ {
+-      return __smq_create(cache_size, origin_size, cache_block_size, false, false);
++      return __smq_create(cache_size, origin_size, cache_block_size,
++                          false, false, true);
+ }
+ /*----------------------------------------------------------------*/
diff --git a/queue-6.1/drm-i915-dpt-use-shmem-for-dpt-objects.patch b/queue-6.1/drm-i915-dpt-use-shmem-for-dpt-objects.patch
new file mode 100644 (file)
index 0000000..e8cd39a
--- /dev/null
@@ -0,0 +1,58 @@
+From 3844ed5e78823eebb5f0f1edefc403310693d402 Mon Sep 17 00:00:00 2001
+From: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
+Date: Tue, 18 Jul 2023 15:51:18 -0700
+Subject: drm/i915/dpt: Use shmem for dpt objects
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
+
+commit 3844ed5e78823eebb5f0f1edefc403310693d402 upstream.
+
+Dpt objects that are created from internal get evicted when there is
+memory pressure and do not get restored when pinned during scanout. The
+pinned page table entries look corrupted and programming the display
+engine with the incorrect pte's result in DE throwing pipe faults.
+
+Create DPT objects from shmem and mark the object as dirty when pinning so
+that the object is restored when shrinker evicts an unpinned buffer object.
+
+v2: Unconditionally mark the dpt objects dirty during pinning(Chris).
+
+Fixes: 0dc987b699ce ("drm/i915/display: Add smem fallback allocation for dpt")
+Cc: <stable@vger.kernel.org> # v6.0+
+Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
+Suggested-by: Chris Wilson <chris.p.wilson@intel.com>
+Signed-off-by: Fei Yang <fei.yang@intel.com>
+Signed-off-by: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
+Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230718225118.2562132-1-radhakrishna.sripada@intel.com
+(cherry picked from commit e91a777a6e602ba0e3366e053e4e094a334a1244)
+Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i915/display/intel_dpt.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/i915/display/intel_dpt.c
++++ b/drivers/gpu/drm/i915/display/intel_dpt.c
+@@ -163,6 +163,8 @@ struct i915_vma *intel_dpt_pin(struct i9
+               i915_vma_get(vma);
+       }
++      dpt->obj->mm.dirty = true;
++
+       atomic_dec(&i915->gpu_error.pending_fb_pin);
+       intel_runtime_pm_put(&i915->runtime_pm, wakeref);
+@@ -258,7 +260,7 @@ intel_dpt_create(struct intel_framebuffe
+               dpt_obj = i915_gem_object_create_stolen(i915, size);
+       if (IS_ERR(dpt_obj) && !HAS_LMEM(i915)) {
+               drm_dbg_kms(&i915->drm, "Allocating dpt from smem\n");
+-              dpt_obj = i915_gem_object_create_internal(i915, size);
++              dpt_obj = i915_gem_object_create_shmem(i915, size);
+       }
+       if (IS_ERR(dpt_obj))
+               return ERR_CAST(dpt_obj);
diff --git a/queue-6.1/rbd-harden-get_lock_owner_info-a-bit.patch b/queue-6.1/rbd-harden-get_lock_owner_info-a-bit.patch
new file mode 100644 (file)
index 0000000..0c4d86a
--- /dev/null
@@ -0,0 +1,79 @@
+From 8ff2c64c9765446c3cef804fb99da04916603e27 Mon Sep 17 00:00:00 2001
+From: Ilya Dryomov <idryomov@gmail.com>
+Date: Sat, 8 Jul 2023 16:16:59 +0200
+Subject: rbd: harden get_lock_owner_info() a bit
+
+From: Ilya Dryomov <idryomov@gmail.com>
+
+commit 8ff2c64c9765446c3cef804fb99da04916603e27 upstream.
+
+- we want the exclusive lock type, so test for it directly
+- use sscanf() to actually parse the lock cookie and avoid admitting
+  invalid handles
+- bail if locker has a blank address
+
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/block/rbd.c  |   21 +++++++++++++++------
+ net/ceph/messenger.c |    1 +
+ 2 files changed, 16 insertions(+), 6 deletions(-)
+
+--- a/drivers/block/rbd.c
++++ b/drivers/block/rbd.c
+@@ -3863,10 +3863,9 @@ static struct ceph_locker *get_lock_owne
+       u32 num_lockers;
+       u8 lock_type;
+       char *lock_tag;
++      u64 handle;
+       int ret;
+-      dout("%s rbd_dev %p\n", __func__, rbd_dev);
+-
+       ret = ceph_cls_lock_info(osdc, &rbd_dev->header_oid,
+                                &rbd_dev->header_oloc, RBD_LOCK_NAME,
+                                &lock_type, &lock_tag, &lockers, &num_lockers);
+@@ -3887,18 +3886,28 @@ static struct ceph_locker *get_lock_owne
+               goto err_busy;
+       }
+-      if (lock_type == CEPH_CLS_LOCK_SHARED) {
+-              rbd_warn(rbd_dev, "shared lock type detected");
++      if (lock_type != CEPH_CLS_LOCK_EXCLUSIVE) {
++              rbd_warn(rbd_dev, "incompatible lock type detected");
+               goto err_busy;
+       }
+       WARN_ON(num_lockers != 1);
+-      if (strncmp(lockers[0].id.cookie, RBD_LOCK_COOKIE_PREFIX,
+-                  strlen(RBD_LOCK_COOKIE_PREFIX))) {
++      ret = sscanf(lockers[0].id.cookie, RBD_LOCK_COOKIE_PREFIX " %llu",
++                   &handle);
++      if (ret != 1) {
+               rbd_warn(rbd_dev, "locked by external mechanism, cookie %s",
+                        lockers[0].id.cookie);
+               goto err_busy;
+       }
++      if (ceph_addr_is_blank(&lockers[0].info.addr)) {
++              rbd_warn(rbd_dev, "locker has a blank address");
++              goto err_busy;
++      }
++
++      dout("%s rbd_dev %p got locker %s%llu@%pISpc/%u handle %llu\n",
++           __func__, rbd_dev, ENTITY_NAME(lockers[0].id.name),
++           &lockers[0].info.addr.in_addr,
++           le32_to_cpu(lockers[0].info.addr.nonce), handle);
+ out:
+       kfree(lock_tag);
+--- a/net/ceph/messenger.c
++++ b/net/ceph/messenger.c
+@@ -1118,6 +1118,7 @@ bool ceph_addr_is_blank(const struct cep
+               return true;
+       }
+ }
++EXPORT_SYMBOL(ceph_addr_is_blank);
+ int ceph_addr_port(const struct ceph_entity_addr *addr)
+ {
diff --git a/queue-6.1/rbd-make-get_lock_owner_info-return-a-single-locker-or-null.patch b/queue-6.1/rbd-make-get_lock_owner_info-return-a-single-locker-or-null.patch
new file mode 100644 (file)
index 0000000..71f1954
--- /dev/null
@@ -0,0 +1,176 @@
+From f38cb9d9c2045dad16eead4a2e1aedfddd94603b Mon Sep 17 00:00:00 2001
+From: Ilya Dryomov <idryomov@gmail.com>
+Date: Fri, 30 Jun 2023 13:52:13 +0200
+Subject: rbd: make get_lock_owner_info() return a single locker or NULL
+
+From: Ilya Dryomov <idryomov@gmail.com>
+
+commit f38cb9d9c2045dad16eead4a2e1aedfddd94603b upstream.
+
+Make the "num_lockers can be only 0 or 1" assumption explicit and
+simplify the API by getting rid of output parameters in preparation
+for calling get_lock_owner_info() twice before blocklisting.
+
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/block/rbd.c |   84 +++++++++++++++++++++++++++++++---------------------
+ 1 file changed, 51 insertions(+), 33 deletions(-)
+
+--- a/drivers/block/rbd.c
++++ b/drivers/block/rbd.c
+@@ -3850,10 +3850,17 @@ static void wake_lock_waiters(struct rbd
+       list_splice_tail_init(&rbd_dev->acquiring_list, &rbd_dev->running_list);
+ }
+-static int get_lock_owner_info(struct rbd_device *rbd_dev,
+-                             struct ceph_locker **lockers, u32 *num_lockers)
++static void free_locker(struct ceph_locker *locker)
++{
++      if (locker)
++              ceph_free_lockers(locker, 1);
++}
++
++static struct ceph_locker *get_lock_owner_info(struct rbd_device *rbd_dev)
+ {
+       struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc;
++      struct ceph_locker *lockers;
++      u32 num_lockers;
+       u8 lock_type;
+       char *lock_tag;
+       int ret;
+@@ -3862,39 +3869,45 @@ static int get_lock_owner_info(struct rb
+       ret = ceph_cls_lock_info(osdc, &rbd_dev->header_oid,
+                                &rbd_dev->header_oloc, RBD_LOCK_NAME,
+-                               &lock_type, &lock_tag, lockers, num_lockers);
+-      if (ret)
+-              return ret;
++                               &lock_type, &lock_tag, &lockers, &num_lockers);
++      if (ret) {
++              rbd_warn(rbd_dev, "failed to retrieve lockers: %d", ret);
++              return ERR_PTR(ret);
++      }
+-      if (*num_lockers == 0) {
++      if (num_lockers == 0) {
+               dout("%s rbd_dev %p no lockers detected\n", __func__, rbd_dev);
++              lockers = NULL;
+               goto out;
+       }
+       if (strcmp(lock_tag, RBD_LOCK_TAG)) {
+               rbd_warn(rbd_dev, "locked by external mechanism, tag %s",
+                        lock_tag);
+-              ret = -EBUSY;
+-              goto out;
++              goto err_busy;
+       }
+       if (lock_type == CEPH_CLS_LOCK_SHARED) {
+               rbd_warn(rbd_dev, "shared lock type detected");
+-              ret = -EBUSY;
+-              goto out;
++              goto err_busy;
+       }
+-      if (strncmp((*lockers)[0].id.cookie, RBD_LOCK_COOKIE_PREFIX,
++      WARN_ON(num_lockers != 1);
++      if (strncmp(lockers[0].id.cookie, RBD_LOCK_COOKIE_PREFIX,
+                   strlen(RBD_LOCK_COOKIE_PREFIX))) {
+               rbd_warn(rbd_dev, "locked by external mechanism, cookie %s",
+-                       (*lockers)[0].id.cookie);
+-              ret = -EBUSY;
+-              goto out;
++                       lockers[0].id.cookie);
++              goto err_busy;
+       }
+ out:
+       kfree(lock_tag);
+-      return ret;
++      return lockers;
++
++err_busy:
++      kfree(lock_tag);
++      ceph_free_lockers(lockers, num_lockers);
++      return ERR_PTR(-EBUSY);
+ }
+ static int find_watcher(struct rbd_device *rbd_dev,
+@@ -3948,51 +3961,56 @@ out:
+ static int rbd_try_lock(struct rbd_device *rbd_dev)
+ {
+       struct ceph_client *client = rbd_dev->rbd_client->client;
+-      struct ceph_locker *lockers;
+-      u32 num_lockers;
++      struct ceph_locker *locker;
+       int ret;
+       for (;;) {
++              locker = NULL;
++
+               ret = rbd_lock(rbd_dev);
+               if (ret != -EBUSY)
+-                      return ret;
++                      goto out;
+               /* determine if the current lock holder is still alive */
+-              ret = get_lock_owner_info(rbd_dev, &lockers, &num_lockers);
+-              if (ret)
+-                      return ret;
+-
+-              if (num_lockers == 0)
++              locker = get_lock_owner_info(rbd_dev);
++              if (IS_ERR(locker)) {
++                      ret = PTR_ERR(locker);
++                      locker = NULL;
++                      goto out;
++              }
++              if (!locker)
+                       goto again;
+-              ret = find_watcher(rbd_dev, lockers);
++              ret = find_watcher(rbd_dev, locker);
+               if (ret)
+                       goto out; /* request lock or error */
+               rbd_warn(rbd_dev, "breaking header lock owned by %s%llu",
+-                       ENTITY_NAME(lockers[0].id.name));
++                       ENTITY_NAME(locker->id.name));
+               ret = ceph_monc_blocklist_add(&client->monc,
+-                                            &lockers[0].info.addr);
++                                            &locker->info.addr);
+               if (ret) {
+-                      rbd_warn(rbd_dev, "blocklist of %s%llu failed: %d",
+-                               ENTITY_NAME(lockers[0].id.name), ret);
++                      rbd_warn(rbd_dev, "failed to blocklist %s%llu: %d",
++                               ENTITY_NAME(locker->id.name), ret);
+                       goto out;
+               }
+               ret = ceph_cls_break_lock(&client->osdc, &rbd_dev->header_oid,
+                                         &rbd_dev->header_oloc, RBD_LOCK_NAME,
+-                                        lockers[0].id.cookie,
+-                                        &lockers[0].id.name);
+-              if (ret && ret != -ENOENT)
++                                        locker->id.cookie, &locker->id.name);
++              if (ret && ret != -ENOENT) {
++                      rbd_warn(rbd_dev, "failed to break header lock: %d",
++                               ret);
+                       goto out;
++              }
+ again:
+-              ceph_free_lockers(lockers, num_lockers);
++              free_locker(locker);
+       }
+ out:
+-      ceph_free_lockers(lockers, num_lockers);
++      free_locker(locker);
+       return ret;
+ }
diff --git a/queue-6.1/rbd-retrieve-and-check-lock-owner-twice-before-blocklisting.patch b/queue-6.1/rbd-retrieve-and-check-lock-owner-twice-before-blocklisting.patch
new file mode 100644 (file)
index 0000000..a12d996
--- /dev/null
@@ -0,0 +1,99 @@
+From 588159009d5b7a09c3e5904cffddbe4a4e170301 Mon Sep 17 00:00:00 2001
+From: Ilya Dryomov <idryomov@gmail.com>
+Date: Sat, 22 Jul 2023 20:28:08 +0200
+Subject: rbd: retrieve and check lock owner twice before blocklisting
+
+From: Ilya Dryomov <idryomov@gmail.com>
+
+commit 588159009d5b7a09c3e5904cffddbe4a4e170301 upstream.
+
+An attempt to acquire exclusive lock can race with the current lock
+owner closing the image:
+
+1. lock is held by client123, rbd_lock() returns -EBUSY
+2. get_lock_owner_info() returns client123 instance details
+3. client123 closes the image, lock is released
+4. find_watcher() returns 0 as there is no matching watcher anymore
+5. client123 instance gets erroneously blocklisted
+
+Particularly impacted is mirror snapshot scheduler in snapshot-based
+mirroring since it happens to open and close images a lot (images are
+opened only for as long as it takes to take the next mirror snapshot,
+the same client instance is used for all images).
+
+To reduce the potential for erroneous blocklisting, retrieve the lock
+owner again after find_watcher() returns 0.  If it's still there, make
+sure it matches the previously detected lock owner.
+
+Cc: stable@vger.kernel.org # f38cb9d9c204: rbd: make get_lock_owner_info() return a single locker or NULL
+Cc: stable@vger.kernel.org # 8ff2c64c9765: rbd: harden get_lock_owner_info() a bit
+Cc: stable@vger.kernel.org
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/block/rbd.c |   25 +++++++++++++++++++++++--
+ 1 file changed, 23 insertions(+), 2 deletions(-)
+
+--- a/drivers/block/rbd.c
++++ b/drivers/block/rbd.c
+@@ -3850,6 +3850,15 @@ static void wake_lock_waiters(struct rbd
+       list_splice_tail_init(&rbd_dev->acquiring_list, &rbd_dev->running_list);
+ }
++static bool locker_equal(const struct ceph_locker *lhs,
++                       const struct ceph_locker *rhs)
++{
++      return lhs->id.name.type == rhs->id.name.type &&
++             lhs->id.name.num == rhs->id.name.num &&
++             !strcmp(lhs->id.cookie, rhs->id.cookie) &&
++             ceph_addr_equal_no_type(&lhs->info.addr, &rhs->info.addr);
++}
++
+ static void free_locker(struct ceph_locker *locker)
+ {
+       if (locker)
+@@ -3970,11 +3979,11 @@ out:
+ static int rbd_try_lock(struct rbd_device *rbd_dev)
+ {
+       struct ceph_client *client = rbd_dev->rbd_client->client;
+-      struct ceph_locker *locker;
++      struct ceph_locker *locker, *refreshed_locker;
+       int ret;
+       for (;;) {
+-              locker = NULL;
++              locker = refreshed_locker = NULL;
+               ret = rbd_lock(rbd_dev);
+               if (ret != -EBUSY)
+@@ -3994,6 +4003,16 @@ static int rbd_try_lock(struct rbd_devic
+               if (ret)
+                       goto out; /* request lock or error */
++              refreshed_locker = get_lock_owner_info(rbd_dev);
++              if (IS_ERR(refreshed_locker)) {
++                      ret = PTR_ERR(refreshed_locker);
++                      refreshed_locker = NULL;
++                      goto out;
++              }
++              if (!refreshed_locker ||
++                  !locker_equal(locker, refreshed_locker))
++                      goto again;
++
+               rbd_warn(rbd_dev, "breaking header lock owned by %s%llu",
+                        ENTITY_NAME(locker->id.name));
+@@ -4015,10 +4034,12 @@ static int rbd_try_lock(struct rbd_devic
+               }
+ again:
++              free_locker(refreshed_locker);
+               free_locker(locker);
+       }
+ out:
++      free_locker(refreshed_locker);
+       free_locker(locker);
+       return ret;
+ }
index e6b9c823bfb26f3f0e311faf0489a99fc3ac6c1f..b8caedb25db092a54f273716d4d96ae57ce17d0e 100644 (file)
@@ -208,3 +208,9 @@ s390-dasd-print-copy-pair-message-only-for-the-correct-error.patch
 asoc-wm8904-fill-the-cache-for-wm8904_adc_test_0-register.patch
 arm64-sme-set-new-vector-length-before-reallocating.patch
 pm-sleep-wakeirq-fix-wake-irq-arming.patch
+ceph-never-send-metrics-if-disable_send_metrics-is-set.patch
+drm-i915-dpt-use-shmem-for-dpt-objects.patch
+dm-cache-policy-smq-ensure-io-doesn-t-prevent-cleaner-policy-progress.patch
+rbd-make-get_lock_owner_info-return-a-single-locker-or-null.patch
+rbd-harden-get_lock_owner_info-a-bit.patch
+rbd-retrieve-and-check-lock-owner-twice-before-blocklisting.patch