From 478715fb5fe6ee4aa62ffb082db6761ddb953c7f Mon Sep 17 00:00:00 2001
From: Dan McDonald <danmcd@joyent.com>
Date: Tue, 21 Jan 2020 21:31:35 -0500
Subject: [PATCH] Revert "NEX-20260 NFS hung in transitional state when RSF
 marks it maintenance"

This reverts commit 9bf6e5f740709f470ba350df64cd9f2c93f3f0a7.
---
 usr/src/uts/common/fs/nfs/nfs4_db.c    | 54 +++++++-------------------
 usr/src/uts/common/fs/nfs/nfs4_state.c |  1 +
 2 files changed, 14 insertions(+), 41 deletions(-)

diff --git a/usr/src/uts/common/fs/nfs/nfs4_db.c b/usr/src/uts/common/fs/nfs/nfs4_db.c
index 19d6c5ea13..b97567be70 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_db.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_db.c
@@ -24,7 +24,7 @@
  */
 
 /*
- * Copyright 2019 Nexenta Systems, Inc.
+ * Copyright 2018 Nexenta Systems, Inc.
  */
 
 #include <sys/systm.h>
@@ -32,6 +32,7 @@
 #include <sys/kmem.h>
 #include <sys/disp.h>
 #include <sys/id_space.h>
+#include <sys/atomic.h>
 #include <rpc/rpc.h>
 #include <nfs/nfs4.h>
 #include <nfs/nfs4_db_impl.h>
@@ -64,13 +65,7 @@ rfs4_dbe_getid(rfs4_dbe_t *entry)
 void
 rfs4_dbe_hold(rfs4_dbe_t *entry)
 {
-	if (!MUTEX_HELD(entry->dbe_lock)) {
-		mutex_enter(entry->dbe_lock);
-		entry->dbe_refcnt++;
-		mutex_exit(entry->dbe_lock);
-	} else {
-		entry->dbe_refcnt++;
-	}
+	atomic_inc_32(&entry->dbe_refcnt);
 }
 
 /*
@@ -79,14 +74,7 @@ rfs4_dbe_hold(rfs4_dbe_t *entry)
 void
 rfs4_dbe_rele_nolock(rfs4_dbe_t *entry)
 {
-	if (!MUTEX_HELD(entry->dbe_lock)) {
-		ASSERT(entry->dbe_refcnt > 0);
-		mutex_enter(entry->dbe_lock);
-		entry->dbe_refcnt--;
-		mutex_exit(entry->dbe_lock);
-	} else {
-		entry->dbe_refcnt--;
-	}
+	atomic_dec_32(&entry->dbe_refcnt);
 }
 
 
@@ -103,15 +91,8 @@ rfs4_dbe_refcnt(rfs4_dbe_t *entry)
 void
 rfs4_dbe_invalidate(rfs4_dbe_t *entry)
 {
-	if (!MUTEX_HELD(entry->dbe_lock)) {
-		mutex_enter(entry->dbe_lock);
-		entry->dbe_invalid = TRUE;
-		entry->dbe_skipsearch = TRUE;
-		mutex_exit(entry->dbe_lock);
-	} else {
-		entry->dbe_invalid = TRUE;
-		entry->dbe_skipsearch = TRUE;
-	}
+	entry->dbe_invalid = TRUE;
+	entry->dbe_skipsearch = TRUE;
 }
 
 /*
@@ -153,7 +134,7 @@ rfs4_dbe_rele(rfs4_dbe_t *entry)
 {
 	mutex_enter(entry->dbe_lock);
 	ASSERT(entry->dbe_refcnt > 1);
-	entry->dbe_refcnt--;
+	atomic_dec_32(&entry->dbe_refcnt);
 	entry->dbe_time_rele = gethrestime_sec();
 	mutex_exit(entry->dbe_lock);
 }
@@ -841,29 +822,25 @@ rfs4_dbe_reap(rfs4_table_t *table, time_t cache_time, uint32_t desired)
 
 	/* Walk the buckets looking for entries to release/destroy */
 	for (i = 0; i < table->dbt_len; i++) {
-		int retries = 0;
 		bp = &buckets[i];
 		do {
 			found = FALSE;
 			rw_enter(bp->dbk_lock, RW_READER);
 			for (l = bp->dbk_head; l; l = l->next) {
 				entry = l->entry;
-				mutex_enter(entry->dbe_lock);
-				ASSERT(entry->dbe_refcnt != 0);
 				/*
 				 * Examine an entry.  Ref count of 1 means
 				 * that the only reference is for the hash
 				 * table reference.
 				 */
-				if (entry->dbe_refcnt != 1) {
-					mutex_exit(entry->dbe_lock);
+				if (entry->dbe_refcnt != 1)
 					continue;
-				}
+				mutex_enter(entry->dbe_lock);
 				if ((entry->dbe_refcnt == 1) &&
 				    (table->dbt_reaper_shutdown ||
 				    table->dbt_expiry == NULL ||
 				    (*table->dbt_expiry)(entry->dbe_data))) {
-					rfs4_dbe_rele_nolock(entry);
+					entry->dbe_refcnt--;
 					count++;
 					found = TRUE;
 				}
@@ -880,16 +857,13 @@ rfs4_dbe_reap(rfs4_table_t *table, time_t cache_time, uint32_t desired)
 					t = l;
 					entry = t->entry;
 					l = l->next;
-					mutex_enter(entry->dbe_lock);
 					if (entry->dbe_refcnt == 0) {
 						DEQUEUE(bp->dbk_head, t);
-						mutex_exit(entry->dbe_lock);
 						t->next = NULL;
 						t->prev = NULL;
 						INVALIDATE_ADDR(t->entry);
 						rfs4_dbe_destroy(entry);
-					} else
-						mutex_exit(entry->dbe_lock);
+					}
 				}
 			}
 			rw_exit(bp->dbk_lock);
@@ -902,15 +876,13 @@ rfs4_dbe_reap(rfs4_table_t *table, time_t cache_time, uint32_t desired)
 			 * released.  This is only done in the
 			 * instance that the tables are being shut down.
 			 */
-			if (table->dbt_reaper_shutdown && bp->dbk_head != NULL) {
+			if (table->dbt_reaper_shutdown && bp->dbk_head != NULL)
 				delay(hz/100);
-				retries++;
-			}
 		/*
 		 * If this is a table shutdown, keep going until
 		 * everything is gone
 		 */
-		} while (table->dbt_reaper_shutdown && bp->dbk_head != NULL && retries < 5);
+		} while (table->dbt_reaper_shutdown && bp->dbk_head != NULL);
 
 		if (!table->dbt_reaper_shutdown && desired && count >= desired)
 			break;
diff --git a/usr/src/uts/common/fs/nfs/nfs4_state.c b/usr/src/uts/common/fs/nfs/nfs4_state.c
index 6af890191a..1f3724e7eb 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_state.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_state.c
@@ -1525,6 +1525,7 @@ rfs4_state_zone_fini()
 
 	/* First stop all of the reaper threads in the database */
 	rfs4_database_shutdown(dbp);
+
 	/*
 	 * WARNING: There may be consumers of the rfs4 database still
 	 * active as we destroy these.  IF that's the case, consider putting
-- 
2.23.0

