From 17404ae74dab88788f052e9950332c25cb62fab4 Mon Sep 17 00:00:00 2001 From: Patrick Donnelly Date: Wed, 5 Mar 2025 11:15:20 -0500 Subject: [PATCH] pybind/cephfs: increment ref before calling out to c++ At the time this construction seemed safe since the caller should have a reference but it could conveivably be the only ref. We don't want the ref count to reach 0. Additionally, catch errors so this callback is genuinely noexcept. Signed-off-by: Patrick Donnelly (cherry picked from commit 395263ceb2f351d540359f52694b48b2824e1291) --- src/pybind/cephfs/cephfs.pyx | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/pybind/cephfs/cephfs.pyx b/src/pybind/cephfs/cephfs.pyx index b6b810c7ca6..6599beb4c27 100644 --- a/src/pybind/cephfs/cephfs.pyx +++ b/src/pybind/cephfs/cephfs.pyx @@ -114,10 +114,14 @@ cdef extern from "Python.h": cdef void completion_callback(int rc, const void* out, size_t outlen, const void* outs, size_t outslen, void* ud) nogil: # This GIL awkwardness is due to incompatible types with function pointers defined with mds_command2: with gil: - pyout = (out)[:outlen] - pyouts = (outs)[:outslen] - (ud).complete(rc, pyout, pyouts) - ref.Py_DECREF(ud) + try: + pyout = (out)[:outlen] + pyouts = (outs)[:outslen] + (ud).complete(rc, pyout, pyouts) + except: + pass # we can't handle this in any useful way: e.g. which thread should get the exception? + finally: + ref.Py_DECREF(ud) class Error(Exception): def get_error_code(self): @@ -2316,6 +2320,7 @@ cdef class LibCephFS(object): try: + ref.Py_INCREF(result) with nogil: ret = ceph_mds_command2(self.cluster, _mds_spec, _cmd, _cmdlen, @@ -2323,9 +2328,8 @@ cdef class LibCephFS(object): _one_shot, completion_callback, result) - if ret == 0: - ref.Py_INCREF(result) - else: + if ret != 0: + ref.Py_DECREF(result) raise make_ex(ret, "error in mds_command2") finally: free(_cmd) -- 2.39.5