File 0544-erts-Fix-bugs-in-ets-rename.patch of Package erlang
From dbf48201728e9530090773cebc0733ed49ed9ee2 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Thu, 22 Sep 2022 00:13:02 +0200
Subject: [PATCH 4/5] erts: Fix bugs in ets:rename
Handle racing rename correct by retry.
Avoid all name-tab locks when table is not named.
---
erts/emulator/beam/erl_db.c | 26 ++++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c
index c71c951785..a32c9803e7 100644
--- a/erts/emulator/beam/erl_db.c
+++ b/erts/emulator/beam/erl_db.c
@@ -2178,13 +2178,13 @@ BIF_RETTYPE ets_rename_2(BIF_ALIST_2)
db_unlock(tb, LCK_READ);
BIF_ERROR(BIF_P, BADARG);
}
-
+retry:
(void) meta_name_tab_bucket(BIF_ARG_2, &lck1);
if (is_atom(BIF_ARG_1)) {
old_name = BIF_ARG_1;
named_tab:
- (void) meta_name_tab_bucket(old_name, &lck2);
+ (void)meta_name_tab_bucket(old_name, &lck2);
if (lck1 == lck2)
lck2 = NULL;
else if (lck1 > lck2) {
@@ -2198,15 +2198,17 @@ BIF_RETTYPE ets_rename_2(BIF_ALIST_2)
if (!tb)
BIF_ERROR(BIF_P, BADARG | EXF_HAS_EXT_INFO);
else {
+ old_name = tb->common.the_name;
if (is_table_named(tb)) {
- old_name = tb->common.the_name;
goto named_tab;
}
+ lck1 = NULL;
lck2 = NULL;
}
}
- erts_rwmtx_rwlock(lck1);
+ if (lck1)
+ erts_rwmtx_rwlock(lck1);
if (lck2)
erts_rwmtx_rwlock(lck2);
@@ -2215,6 +2217,16 @@ BIF_RETTYPE ets_rename_2(BIF_ALIST_2)
goto fail;
if (is_table_named(tb)) {
+ if (tb->common.the_name != old_name) {
+ /* Wow! Racing rename op. Unlock all and retry. */
+ ASSERT(is_not_atom(BIF_ARG_1));
+ if (lck1)
+ erts_rwmtx_rwunlock(lck1);
+ if (lck2)
+ erts_rwmtx_rwunlock(lck2);
+ db_unlock(tb, LCK_WRITE);
+ goto retry;
+ }
if (!insert_named_tab(BIF_ARG_2, tb, 1))
goto badarg;
@@ -2228,7 +2240,8 @@ BIF_RETTYPE ets_rename_2(BIF_ALIST_2)
tb->common.the_name = BIF_ARG_2;
db_unlock(tb, LCK_WRITE);
- erts_rwmtx_rwunlock(lck1);
+ if (lck1)
+ erts_rwmtx_rwunlock(lck1);
if (lck2)
erts_rwmtx_rwunlock(lck2);
BIF_RET(ret);
@@ -2239,7 +2252,8 @@ badarg:
fail:
if (tb)
db_unlock(tb, LCK_WRITE);
- erts_rwmtx_rwunlock(lck1);
+ if (lck1)
+ erts_rwmtx_rwunlock(lck1);
if (lck2)
erts_rwmtx_rwunlock(lck2);
--
2.35.3