4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #ifndef _NFS4_DB_IMPL_H
27 #define _NFS4_DB_IMPL_H
30 * This is a private header file. Applications should not directly include
38 #define SEARCH_DEBUG 0x0001
39 #define CREATE_DEBUG 0x0002
40 #define CACHED_DEBUG 0x0004
41 #define DESTROY_DEBUG 0x0008
42 #define REAP_DEBUG 0x0010
43 #define OTHER_DEBUG 0x0020
44 #define WALK_DEBUG 0x0040
47 * A database is made up of a collection of tables.
48 * Tables are in turn made up of a collection of
49 * entries. Each table may haveone or more indices
50 * associtated with it.
53 /* Private implementation */
54 typedef struct rfs4_link
{
55 struct rfs4_link
*next
;
56 struct rfs4_link
*prev
;
61 kmutex_t dbe_lock
[1]; /* Exclusive lock for entry */
62 uint32_t dbe_refcnt
; /* # of references */
63 unsigned dbe_skipsearch
:1; /* skip search */
64 unsigned dbe_invalid
:1; /* invalid/"freed" entry */
65 unsigned dbe_reserved
:31;
66 time_t dbe_time_rele
; /* Time of last rele */
67 id_t dbe_id
; /* unique identifier */
69 rfs4_entry_t dbe_data
;
70 rfs4_table_t
*dbe_table
;
71 rfs4_link_t dbe_indices
[1]; /* Array of indices for entry */
74 typedef struct rfs4_bucket
{
75 krwlock_t dbk_lock
[1]; /* lock hash chain */
76 rfs4_link_t
*dbk_head
;
80 uint32_t dbi_tblidx
; /* which indice in entry */
81 bool_t dbi_createable
; /* Can create entries */
82 rfs4_table_t
*dbi_table
; /* Pointer to table */
83 char *dbi_keyname
; /* String rep of key */
84 rfs4_bucket_t
*dbi_buckets
; /* Hash buckets */
85 uint32_t (*dbi_hash
)(void *); /* Given key find bucket */
86 bool_t (*dbi_compare
)(rfs4_entry_t
, void *); /* Key match entry? */
87 void *(*dbi_mkkey
)(rfs4_entry_t
); /* Given data generate a key */
88 struct rfs4_index
*dbi_inext
; /* next index on table */
92 rfs4_table_t
*dbt_tnext
; /* next table in db */
93 struct rfs4_database
*dbt_db
; /* db that holds this table */
94 krwlock_t dbt_t_lock
[1]; /* lock table for resize */
95 kmutex_t dbt_lock
[1]; /* mutex for count and cached */
96 char *dbt_name
; /* Table name */
97 id_space_t
*dbt_id_space
; /* space for unique entry ids */
98 time_t dbt_min_cache_time
; /* How long to cache entries */
99 time_t dbt_max_cache_time
; /* How long to cache entries */
100 uint32_t dbt_usize
; /* User entry size */
101 uint32_t dbt_maxentries
; /* max # of entries in table */
102 uint32_t dbt_len
; /* # of buckets in table */
103 uint32_t dbt_count
; /* # of entries in table */
104 uint32_t dbt_idxcnt
; /* # of indices in table */
105 uint32_t dbt_maxcnt
; /* max # of indices */
106 uint32_t dbt_ccnt
; /* # of creatable entries */
107 uint32_t dbt_id_lwat
; /* lo wtrmrk; 50% ids in use */
108 uint32_t dbt_id_hwat
; /* hi wtrmrk; 75% ids in use */
109 time_t dbt_id_reap
; /* table's reap interval */
110 rfs4_index_t
*dbt_indices
; /* list of indices */
111 /* Given entry and data construct entry */
112 bool_t (*dbt_create
)(rfs4_entry_t
, void *data
);
113 void (*dbt_destroy
)(rfs4_entry_t
); /* Destroy entry */
114 bool_t (*dbt_expiry
)(rfs4_entry_t
); /* Has this entry expired */
115 kmem_cache_t
*dbt_mem_cache
; /* Cache for table entries */
116 uint32_t dbt_debug
; /* Debug Flags */
117 /* set of vars used for managing the reaper thread */
118 unsigned dbt_reaper_shutdown
:1; /* table shutting down? */
119 kcondvar_t dbt_reaper_wait
; /* reaper thread waits here */
120 kmutex_t dbt_reaper_cv_lock
; /* lock used for cpr wait */
121 callb_cpr_t dbt_reaper_cpr_info
; /* cpr the reaper thread */
124 struct rfs4_database
{
126 uint32_t db_debug_flags
; /* Table debug flags to set */
127 uint32_t db_shutdown_count
; /* count to manage shutdown */
128 kcondvar_t db_shutdown_wait
; /* where the shutdown waits */
129 rfs4_table_t
*db_tables
; /* list of tables in db */
132 #define RFS4_RECLAIM_PERCENT 10
133 #define RFS4_REAP_INTERVAL 300
135 #define HASH(idx, key) (idx->dbi_hash(key) % idx->dbi_table->dbt_len)
137 #define ENQUEUE(head, l) { \
139 (l)->next = (head); \
141 (l)->next->prev = (l); \
145 #define DEQUEUE(head, l) { \
147 (l)->prev->next = (l)->next; \
149 (head) = (l)->next; \
151 (l)->next->prev = (l)->prev; \
154 #define INVALIDATE_ADDR(a) ((a) = (void *)((unsigned long)(a) | 1L))
155 #define VALIDATE_ADDR(a) ((a) = (void *)((unsigned long)(a) & ~1L))
156 #define INVALID_ADDR(a) (((unsigned long)(a) & 1L))
157 #define INVALID_LINK(l) (INVALID_ADDR(l->entry))
159 #define ENQUEUE_IDX(bp, l) { \
160 rw_enter((bp)->dbk_lock, RW_WRITER); \
161 ENQUEUE((bp)->dbk_head, l); \
162 VALIDATE_ADDR((l)->entry); \
163 rw_exit((bp)->dbk_lock); \
166 #define DEQUEUE_IDX(bp, l) { \
167 rw_enter((bp)->dbk_lock, RW_WRITER); \
168 INVALIDATE_ADDR((l)->entry); \
169 DEQUEUE((bp)->dbk_head, l); \
170 rw_exit((bp)->dbk_lock); \
177 #endif /* _NFS4_DB_IMPL_H */