]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commit
os/bluestore: avoid premature onode release. 44724/head
authorIgor Fedotov <ifed@suse.com>
Tue, 2 Nov 2021 12:03:39 +0000 (15:03 +0300)
committerCory Snyder <csnyder@iland.com>
Fri, 21 Jan 2022 17:44:31 +0000 (12:44 -0500)
commit36f8377f93cb18ef2775e293697b16d4cd97afa7
tree587955c1838434557648b72831e5b9ec4b017f1c
parent6d0261fcb9458c90b6f509c036c9df47e35eb281
os/bluestore: avoid premature onode release.

This was observed when onode's removal is followed by reading
and the latter causes object release before the removal is finalized.
The root cause is an improper 'pinned' state assessment in Onode::get

More detailed overview is:
At some point Onode::get() might face the case when nref == 2 and pinned = true
which means parallel incomplete put is running on the onode - ref count is
decremented but pinned state is still unmodified (and even lock hasn't been
acquired yet).
This might finally result in two puts racing over the same onode with nref == 2
which finally results in a premature onode release:
  // nref =3, pinned = 1
  // Thread 1                   Thread 2
  //   o->put()                   o->get()
  //   --nref(n = 2, pinned=1)
  //                              nref++ (n=3, pinned = 1)
  //                              return
  //                              ...
  //                              o->put()
  //                              --nref(n = 2)
  //                              pinned = 0,
  //                              --nref(n = 1)
  //                              ocs->_unpin_and_rm(o) -> o->put()
  //                                ...
  //                                --nref(n = 0)
  //                                release o
  //  o->c->get_onode_cache()
  //  FAULT!
  //
The suggested fix is to introduce additional atomic counter tracking
running put() functions. And permit onode release when both regular
nref and put_nref are both equal to zero.

Fixes: https://tracker.ceph.com/issues/53002
Signed-off-by: Igor Fedotov <igor.fedotov@croit.io>
(cherry picked from commit 96f0efe6d5307a55bea32f7216ef9511da0c5a47)
src/os/bluestore/BlueStore.cc
src/os/bluestore/BlueStore.h