From cf3cb3f19763a1261c78c5615cac7791698526a6 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Mon, 12 Apr 2021 10:32:21 -0700 Subject: [PATCH] Wait for rhashtable to rehash on insert EBUSY The rhashtable can return EBUSY if you insert fast enough to trigger an expansion of the next table size that is waiting to be rehashed in an rcu callback. If we get EBUSY from rhasthable_insert we call synchronize_rcu to wait for the rehash to complete before trying again. This was hit in testing restores of a very large namespace and took a few hours to hit. Signed-off-by: Zach Brown --- kmod/src/block.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kmod/src/block.c b/kmod/src/block.c index 1d80a667..ef6a1cb3 100644 --- a/kmod/src/block.c +++ b/kmod/src/block.c @@ -286,10 +286,16 @@ static int block_insert(struct super_block *sb, struct block_private *bp) WARN_ON_ONCE(atomic_read(&bp->refcount) & BLOCK_REF_INSERTED); +retry: atomic_add(BLOCK_REF_INSERTED, &bp->refcount); ret = rhashtable_insert_fast(&binf->ht, &bp->ht_head, block_ht_params); if (ret < 0) { atomic_sub(BLOCK_REF_INSERTED, &bp->refcount); + if (ret == -EBUSY) { + /* wait for pending rebalance to finish */ + synchronize_rcu(); + goto retry; + } } else { atomic_inc(&binf->total_inserted); TRACE_BLOCK(insert, bp);