diff --git a/src/rebuild/rebuild_internal.h b/src/rebuild/rebuild_internal.h index 7bffb8c61b9e..42c40f814301 100644 --- a/src/rebuild/rebuild_internal.h +++ b/src/rebuild/rebuild_internal.h @@ -1,5 +1,5 @@ /** - * (C) Copyright 2017-2023 Intel Corporation. + * (C) Copyright 2017-2024 Intel Corporation. * * SPDX-License-Identifier: BSD-2-Clause-Patent */ @@ -312,6 +312,7 @@ rebuild_tls_get() void rpt_get(struct rebuild_tgt_pool_tracker *rpt); void rpt_put(struct rebuild_tgt_pool_tracker *rpt); +void rpt_delete(struct rebuild_tgt_pool_tracker *rpt); struct rebuild_pool_tls * rebuild_pool_tls_lookup(uuid_t pool_uuid, unsigned int ver, uint32_t gen); diff --git a/src/rebuild/scan.c b/src/rebuild/scan.c index 8ddc4d7d905d..22d90eb025e1 100644 --- a/src/rebuild/scan.c +++ b/src/rebuild/scan.c @@ -1228,8 +1228,11 @@ rebuild_tgt_scan_handler(crt_rpc_t *rpc) if (tls && tls->rebuild_pool_status == 0 && rc != 0) tls->rebuild_pool_status = rc; - if (rpt) + if (rpt) { + if (rc) + rpt_delete(rpt); rpt_put(rpt); + } ro = crt_reply_get(rpc); ro->rso_status = rc; ro->rso_stable_epoch = d_hlc_get(); diff --git a/src/rebuild/srv.c b/src/rebuild/srv.c index 9db18b58e438..702404b81ac0 100644 --- a/src/rebuild/srv.c +++ b/src/rebuild/srv.c @@ -216,7 +216,7 @@ rpt_insert(struct rebuild_tgt_pool_tracker *rpt) ABT_rwlock_unlock(rebuild_gst.rg_ttl_rwlock); } -static void +void rpt_delete(struct rebuild_tgt_pool_tracker *rpt) { D_ASSERT(dss_get_module_info()->dmi_xs_id == 0); @@ -1065,10 +1065,20 @@ rpt_get(struct rebuild_tgt_pool_tracker *rpt) ABT_mutex_unlock(rpt->rt_lock); } +static int +rpt_put_destroy(void *data) +{ + struct rebuild_tgt_pool_tracker *rpt = data; + + rpt_destroy(rpt); + return 0; +} + void -rpt_put(struct rebuild_tgt_pool_tracker *rpt) +rpt_put(struct rebuild_tgt_pool_tracker *rpt) { bool zombie; + int rc; ABT_mutex_lock(rpt->rt_lock); rpt->rt_refcount--; @@ -1078,8 +1088,22 @@ rpt_put(struct rebuild_tgt_pool_tracker *rpt) ABT_cond_signal(rpt->rt_fini_cond); zombie = (rpt->rt_refcount == 0); ABT_mutex_unlock(rpt->rt_lock); - if (zombie) + if (!zombie) + return; + + if (dss_get_module_info()->dmi_xs_id == 0) { rpt_destroy(rpt); + } else { + /* Possibly triggered by VOS target XS by obj_inflight_io_check() -> + * ds_rebuild_running_query(), but rpt_destroy() -> ds_pool_put() can only + * be called in system XS. + * If dss_ult_execute failed that due to fatal system error (no memory + * or ABT failure), throw an ERR log. + */ + rc = dss_ult_execute(rpt_put_destroy, rpt, NULL, NULL, DSS_XS_SYS, 0, 0); + if (rc) + DL_ERROR(rc, "failed to destroy rpt %p.\n", rpt); + } } static void