]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd/cache/pwl: avoid stack overflow caused by nested shared_ptr destruction 42149/head
authorHualong Feng <hualong.feng@intel.com>
Fri, 2 Jul 2021 06:22:06 +0000 (14:22 +0800)
committerIlya Dryomov <idryomov@gmail.com>
Fri, 6 Aug 2021 19:43:43 +0000 (21:43 +0200)
Destruction of nested shared_ptr will cause stack overflow.
With the explicit assignment of nullptr, the deleted node
is completely disconnected from the current linked list

-------              *******               -------
|sync | <--earlier-- |sync | <--earlier-x- |sync |
|point| --later----> |point| --later----x> |point|
-------              *******               -------
   |                    |                     |
   V                    V                     V
-------              -------               -------
|log_ | ---next----> |log_ | ---next----x> |log_ |
|entry|              |entry|               |entry|
-------              -------               -------

earlier: earlier_sync_point
later:   later_sync_point
next:    next_sync_point_entry

Fixes: https://tracker.ceph.com/issues/51418
Signed-off-by: Feng Hualong <hualong.feng@intel.com>
src/librbd/cache/pwl/LogOperation.cc

index 701fe14b1a60289ded1a382d8a9ce77ba0dd5659..2c5a5ef78d638da9dff9b40d9b1a6117902043cd 100644 (file)
@@ -70,9 +70,10 @@ std::vector<Context*> SyncPointLogOperation::append_sync_point() {
 void SyncPointLogOperation::clear_earlier_sync_point() {
   std::lock_guard locker(m_lock);
   ceph_assert(sync_point->later_sync_point);
-  ceph_assert(sync_point->later_sync_point->earlier_sync_point ==
-              sync_point);
+  ceph_assert(sync_point->later_sync_point->earlier_sync_point == sync_point);
   sync_point->later_sync_point->earlier_sync_point = nullptr;
+  sync_point->later_sync_point = nullptr;
+  sync_point->log_entry->next_sync_point_entry = nullptr;
 }
 
 std::vector<Context*> SyncPointLogOperation::swap_on_sync_point_persisted() {