Print this page
Revert "NEX-20260 NFS hung in transitional state when RSF marks it maintenance"
This reverts commit 9bf6e5f740709f470ba350df64cd9f2c93f3f0a7.

*** 22,39 **** /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. */ /* ! * Copyright 2019 Nexenta Systems, Inc. */ #include <sys/systm.h> #include <sys/cmn_err.h> #include <sys/kmem.h> #include <sys/disp.h> #include <sys/id_space.h> #include <rpc/rpc.h> #include <nfs/nfs4.h> #include <nfs/nfs4_db_impl.h> #include <sys/sdt.h> --- 22,40 ---- /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. */ /* ! * Copyright 2018 Nexenta Systems, Inc. */ #include <sys/systm.h> #include <sys/cmn_err.h> #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> #include <sys/sdt.h>
*** 62,94 **** } 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++; ! } } /* * rfs4_dbe_rele_nolock only decrements the reference count of the 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--; ! } } uint32_t rfs4_dbe_refcnt(rfs4_dbe_t *entry) --- 63,82 ---- } void rfs4_dbe_hold(rfs4_dbe_t *entry) { ! atomic_inc_32(&entry->dbe_refcnt); } /* * rfs4_dbe_rele_nolock only decrements the reference count of the entry. */ void rfs4_dbe_rele_nolock(rfs4_dbe_t *entry) { ! atomic_dec_32(&entry->dbe_refcnt); } uint32_t rfs4_dbe_refcnt(rfs4_dbe_t *entry)
*** 101,119 **** * Caller does not want this entry to be found any longer */ 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; - } } /* * Is this entry invalid? */ --- 89,100 ----
*** 151,161 **** void rfs4_dbe_rele(rfs4_dbe_t *entry) { mutex_enter(entry->dbe_lock); ASSERT(entry->dbe_refcnt > 1); ! entry->dbe_refcnt--; entry->dbe_time_rele = gethrestime_sec(); mutex_exit(entry->dbe_lock); } void --- 132,142 ---- void rfs4_dbe_rele(rfs4_dbe_t *entry) { mutex_enter(entry->dbe_lock); ASSERT(entry->dbe_refcnt > 1); ! atomic_dec_32(&entry->dbe_refcnt); entry->dbe_time_rele = gethrestime_sec(); mutex_exit(entry->dbe_lock); } void
*** 839,871 **** (CE_NOTE, "Reaping %d entries older than %ld seconds in table %s", desired, cache_time, table->dbt_name)); /* 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); continue; ! } if ((entry->dbe_refcnt == 1) && (table->dbt_reaper_shutdown || table->dbt_expiry == NULL || (*table->dbt_expiry)(entry->dbe_data))) { ! rfs4_dbe_rele_nolock(entry); count++; found = TRUE; } mutex_exit(entry->dbe_lock); } --- 820,848 ---- (CE_NOTE, "Reaping %d entries older than %ld seconds in table %s", desired, cache_time, table->dbt_name)); /* Walk the buckets looking for entries to release/destroy */ for (i = 0; i < table->dbt_len; i++) { 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; /* * Examine an entry. Ref count of 1 means * that the only reference is for the hash * table reference. */ ! 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))) { ! entry->dbe_refcnt--; count++; found = TRUE; } mutex_exit(entry->dbe_lock); }
*** 878,899 **** l = bp->dbk_head; while (l) { 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); /* * delay slightly if there is more work to do * with the expectation that other reaper * threads are freeing data structures as well --- 855,873 ---- l = bp->dbk_head; while (l) { t = l; entry = t->entry; l = l->next; if (entry->dbe_refcnt == 0) { DEQUEUE(bp->dbk_head, t); t->next = NULL; t->prev = NULL; INVALIDATE_ADDR(t->entry); rfs4_dbe_destroy(entry); } } + } rw_exit(bp->dbk_lock); /* * delay slightly if there is more work to do * with the expectation that other reaper * threads are freeing data structures as well
*** 900,918 **** * and in turn will reduce ref counts on * entries in this table allowing them to be * released. This is only done in the * instance that the tables are being shut down. */ ! 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); if (!table->dbt_reaper_shutdown && desired && count >= desired) break; } --- 874,890 ---- * and in turn will reduce ref counts on * entries in this table allowing them to be * released. This is only done in the * instance that the tables are being shut down. */ ! if (table->dbt_reaper_shutdown && bp->dbk_head != NULL) delay(hz/100); /* * If this is a table shutdown, keep going until * everything is gone */ ! } while (table->dbt_reaper_shutdown && bp->dbk_head != NULL); if (!table->dbt_reaper_shutdown && desired && count >= desired) break; }