nfs4_db_impl.h revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _NFS4_DB_IMPL_H
#define _NFS4_DB_IMPL_H
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* This is a private header file. Applications should not directly include
* this file.
*/
#ifdef __cplusplus
extern "C" {
#endif
#define SEARCH_DEBUG 0x0001
#define CREATE_DEBUG 0x0002
#define CACHED_DEBUG 0x0004
#define DESTROY_DEBUG 0x0008
#define REAP_DEBUG 0x0010
#define OTHER_DEBUG 0x0020
#define WALK_DEBUG 0x0040
/*
* A database is made up of a collection of tables.
* Tables are in turn made up of a collection of
* entries. Each table may haveone or more indices
* associtated with it.
*/
/* Private implementation */
typedef struct rfs4_link {
struct rfs4_link *next;
struct rfs4_link *prev;
rfs4_dbe_t *entry;
} rfs4_link;
struct rfs4_dbe {
kmutex_t lock[1]; /* Exclusive lock for entry */
uint32_t refcnt; /* # of references */
unsigned skipsearch:1; /* skip search */
unsigned invalid:1; /* invalid/"freed" entry */
unsigned reserved:31;
time_t time_rele; /* Time of last rele */
id_t id; /* unique identifier */
kcondvar_t cv[1];
rfs4_entry_t data;
rfs4_table_t *table;
rfs4_link indices[1]; /* Array of indices for entry */
};
typedef struct rfs4_bucket {
krwlock_t lock[1]; /* lock hash chain */
rfs4_link *head;
} rfs4_bucket;
struct rfs4_index {
uint32_t tblidx; /* which indice in entry */
bool_t createable; /* Can create entries */
rfs4_table_t *table; /* Pointer to table */
char *keyname; /* String rep of key */
rfs4_bucket *buckets; /* Hash buckets */
uint32_t (*hash)(void *key); /* Given key find bucket */
bool_t (*compare)(rfs4_entry_t, void *key); /* Key match entry? */
void *(*mkkey)(rfs4_entry_t); /* Given data generate a key */
struct rfs4_index *inext; /* next index on table */
};
struct rfs4_table {
rfs4_table_t *tnext; /* next table in db */
struct rfs4_database *dbp; /* db that holds this table */
krwlock_t t_lock[1]; /* lock table for resize */
kmutex_t lock[1]; /* mutex for count and cached */
char *name; /* Table name */
id_space_t *id_space; /* space for unique entry ids */
time_t min_cache_time; /* How long to cache entries */
time_t max_cache_time; /* How long to cache entries */
uint32_t usize; /* User entry size */
uint32_t maxentries; /* max # of entries in table */
uint32_t len; /* # of buckets in table */
uint32_t count; /* # of entries in table */
uint32_t idxcnt; /* # of indices in table */
uint32_t maxcnt; /* max # of indices */
uint32_t ccnt; /* # of creatable entries */
rfs4_index_t *indices; /* list of indices */
/* Given entry and data construct entry */
bool_t (*create)(rfs4_entry_t, void *data);
void (*destroy)(rfs4_entry_t); /* Destroy entry */
bool_t (*expiry)(rfs4_entry_t); /* Has this entry expired */
kmem_cache_t *mem_cache; /* Cache for table entries */
uint32_t debug; /* Debug Flags */
/* set of vars used for managing the reaper thread */
unsigned reaper_shutdown:1; /* table shutting down? */
kcondvar_t reaper_wait; /* reaper thread waits here */
kmutex_t reaper_cv_lock; /* lock used for cpr wait */
callb_cpr_t reaper_cpr_info; /* cpr the reaper thread */
};
struct rfs4_database {
kmutex_t lock[1];
uint32_t debug_flags; /* Table debug flags to set */
uint32_t shutdown_count; /* count to manage shutdown */
kcondvar_t shutdown_wait; /* where the shutdown waits */
rfs4_table_t *tables; /* list of tables in db */
};
#define RFS4_RECLAIM_PERCENT 10
#define RFS4_REAP_INTERVAL 300
#define HASH(idx, key) (idx->hash(key) % idx->table->len)
#define ENQUEUE(head, l) { \
(l)->prev = NULL; \
(l)->next = (head); \
if ((l)->next) \
(l)->next->prev = (l); \
(head) = (l); \
}
#define DEQUEUE(head, l) { \
if ((l)->prev) \
(l)->prev->next = (l)->next; \
else \
(head) = (l)->next; \
if ((l)->next) \
(l)->next->prev = (l)->prev; \
}
#define INVALIDATE_ADDR(a) ((a) = (void *)((unsigned long)(a) | 1L))
#define VALIDATE_ADDR(a) ((a) = (void *)((unsigned long)(a) & ~1L))
#define INVALID_ADDR(a) (((unsigned long)(a) & 1L))
#define INVALID_LINK(l) (INVALID_ADDR(l->entry))
#define ENQUEUE_IDX(bp, l) { \
rw_enter((bp)->lock, RW_WRITER); \
ENQUEUE((bp)->head, l); \
VALIDATE_ADDR((l)->entry); \
rw_exit((bp)->lock); \
}
#define DEQUEUE_IDX(bp, l) { \
rw_enter((bp)->lock, RW_WRITER); \
INVALIDATE_ADDR((l)->entry); \
DEQUEUE((bp)->head, l); \
rw_exit((bp)->lock); \
}
#ifdef __cplusplus
}
#endif
#endif /* _NFS4_DB_IMPL_H */