17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5d216dff5SRobert Mastors * Common Development and Distribution License (the "License"). 6d216dff5SRobert Mastors * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22d216dff5SRobert Mastors * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #ifndef _NFS4_DB_IMPL_H 277c478bd9Sstevel@tonic-gate #define _NFS4_DB_IMPL_H 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate /* 307c478bd9Sstevel@tonic-gate * This is a private header file. Applications should not directly include 317c478bd9Sstevel@tonic-gate * this file. 327c478bd9Sstevel@tonic-gate */ 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate #ifdef __cplusplus 357c478bd9Sstevel@tonic-gate extern "C" { 367c478bd9Sstevel@tonic-gate #endif 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate #define SEARCH_DEBUG 0x0001 397c478bd9Sstevel@tonic-gate #define CREATE_DEBUG 0x0002 407c478bd9Sstevel@tonic-gate #define CACHED_DEBUG 0x0004 417c478bd9Sstevel@tonic-gate #define DESTROY_DEBUG 0x0008 427c478bd9Sstevel@tonic-gate #define REAP_DEBUG 0x0010 437c478bd9Sstevel@tonic-gate #define OTHER_DEBUG 0x0020 447c478bd9Sstevel@tonic-gate #define WALK_DEBUG 0x0040 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate /* 477c478bd9Sstevel@tonic-gate * A database is made up of a collection of tables. 487c478bd9Sstevel@tonic-gate * Tables are in turn made up of a collection of 497c478bd9Sstevel@tonic-gate * entries. Each table may haveone or more indices 507c478bd9Sstevel@tonic-gate * associtated with it. 517c478bd9Sstevel@tonic-gate */ 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate /* Private implementation */ 547c478bd9Sstevel@tonic-gate typedef struct rfs4_link { 557c478bd9Sstevel@tonic-gate struct rfs4_link *next; 567c478bd9Sstevel@tonic-gate struct rfs4_link *prev; 577c478bd9Sstevel@tonic-gate rfs4_dbe_t *entry; 58d216dff5SRobert Mastors } rfs4_link_t; 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate struct rfs4_dbe { 61d216dff5SRobert Mastors kmutex_t dbe_lock[1]; /* Exclusive lock for entry */ 62d216dff5SRobert Mastors uint32_t dbe_refcnt; /* # of references */ 63d216dff5SRobert Mastors unsigned dbe_skipsearch:1; /* skip search */ 64d216dff5SRobert Mastors unsigned dbe_invalid:1; /* invalid/"freed" entry */ 65d216dff5SRobert Mastors unsigned dbe_reserved:31; 66d216dff5SRobert Mastors time_t dbe_time_rele; /* Time of last rele */ 67d216dff5SRobert Mastors id_t dbe_id; /* unique identifier */ 68d216dff5SRobert Mastors kcondvar_t dbe_cv[1]; 69d216dff5SRobert Mastors rfs4_entry_t dbe_data; 70d216dff5SRobert Mastors rfs4_table_t *dbe_table; 71d216dff5SRobert Mastors rfs4_link_t dbe_indices[1]; /* Array of indices for entry */ 727c478bd9Sstevel@tonic-gate }; 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate typedef struct rfs4_bucket { 75d216dff5SRobert Mastors krwlock_t dbk_lock[1]; /* lock hash chain */ 76d216dff5SRobert Mastors rfs4_link_t *dbk_head; 77d216dff5SRobert Mastors } rfs4_bucket_t; 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate struct rfs4_index { 80d216dff5SRobert Mastors uint32_t dbi_tblidx; /* which indice in entry */ 81d216dff5SRobert Mastors bool_t dbi_createable; /* Can create entries */ 82d216dff5SRobert Mastors rfs4_table_t *dbi_table; /* Pointer to table */ 83d216dff5SRobert Mastors char *dbi_keyname; /* String rep of key */ 84d216dff5SRobert Mastors rfs4_bucket_t *dbi_buckets; /* Hash buckets */ 85d216dff5SRobert Mastors uint32_t (*dbi_hash)(void *); /* Given key find bucket */ 86d216dff5SRobert Mastors bool_t (*dbi_compare)(rfs4_entry_t, void *); /* Key match entry? */ 87d216dff5SRobert Mastors void *(*dbi_mkkey)(rfs4_entry_t); /* Given data generate a key */ 88d216dff5SRobert Mastors struct rfs4_index *dbi_inext; /* next index on table */ 897c478bd9Sstevel@tonic-gate }; 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate struct rfs4_table { 92d216dff5SRobert Mastors rfs4_table_t *dbt_tnext; /* next table in db */ 93d216dff5SRobert Mastors struct rfs4_database *dbt_db; /* db that holds this table */ 94d216dff5SRobert Mastors krwlock_t dbt_t_lock[1]; /* lock table for resize */ 95d216dff5SRobert Mastors kmutex_t dbt_lock[1]; /* mutex for count and cached */ 96d216dff5SRobert Mastors char *dbt_name; /* Table name */ 97d216dff5SRobert Mastors id_space_t *dbt_id_space; /* space for unique entry ids */ 98d216dff5SRobert Mastors time_t dbt_min_cache_time; /* How long to cache entries */ 99d216dff5SRobert Mastors time_t dbt_max_cache_time; /* How long to cache entries */ 100d216dff5SRobert Mastors uint32_t dbt_usize; /* User entry size */ 101d216dff5SRobert Mastors uint32_t dbt_maxentries; /* max # of entries in table */ 102d216dff5SRobert Mastors uint32_t dbt_len; /* # of buckets in table */ 103d216dff5SRobert Mastors uint32_t dbt_count; /* # of entries in table */ 104d216dff5SRobert Mastors uint32_t dbt_idxcnt; /* # of indices in table */ 105d216dff5SRobert Mastors uint32_t dbt_maxcnt; /* max # of indices */ 106d216dff5SRobert Mastors uint32_t dbt_ccnt; /* # of creatable entries */ 107*f6cf9e50SRick Mesta uint32_t dbt_id_lwat; /* lo wtrmrk; 50% ids in use */ 108*f6cf9e50SRick Mesta uint32_t dbt_id_hwat; /* hi wtrmrk; 75% ids in use */ 109*f6cf9e50SRick Mesta time_t dbt_id_reap; /* table's reap interval */ 110d216dff5SRobert Mastors rfs4_index_t *dbt_indices; /* list of indices */ 1117c478bd9Sstevel@tonic-gate /* Given entry and data construct entry */ 112d216dff5SRobert Mastors bool_t (*dbt_create)(rfs4_entry_t, void *data); 113d216dff5SRobert Mastors void (*dbt_destroy)(rfs4_entry_t); /* Destroy entry */ 114d216dff5SRobert Mastors bool_t (*dbt_expiry)(rfs4_entry_t); /* Has this entry expired */ 115d216dff5SRobert Mastors kmem_cache_t *dbt_mem_cache; /* Cache for table entries */ 116d216dff5SRobert Mastors uint32_t dbt_debug; /* Debug Flags */ 1177c478bd9Sstevel@tonic-gate /* set of vars used for managing the reaper thread */ 118d216dff5SRobert Mastors unsigned dbt_reaper_shutdown:1; /* table shutting down? */ 119d216dff5SRobert Mastors kcondvar_t dbt_reaper_wait; /* reaper thread waits here */ 120d216dff5SRobert Mastors kmutex_t dbt_reaper_cv_lock; /* lock used for cpr wait */ 121d216dff5SRobert Mastors callb_cpr_t dbt_reaper_cpr_info; /* cpr the reaper thread */ 1227c478bd9Sstevel@tonic-gate }; 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate struct rfs4_database { 125d216dff5SRobert Mastors kmutex_t db_lock[1]; 126d216dff5SRobert Mastors uint32_t db_debug_flags; /* Table debug flags to set */ 127d216dff5SRobert Mastors uint32_t db_shutdown_count; /* count to manage shutdown */ 128d216dff5SRobert Mastors kcondvar_t db_shutdown_wait; /* where the shutdown waits */ 129d216dff5SRobert Mastors rfs4_table_t *db_tables; /* list of tables in db */ 1307c478bd9Sstevel@tonic-gate }; 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate #define RFS4_RECLAIM_PERCENT 10 1337c478bd9Sstevel@tonic-gate #define RFS4_REAP_INTERVAL 300 1347c478bd9Sstevel@tonic-gate 135d216dff5SRobert Mastors #define HASH(idx, key) (idx->dbi_hash(key) % idx->dbi_table->dbt_len) 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate #define ENQUEUE(head, l) { \ 1387c478bd9Sstevel@tonic-gate (l)->prev = NULL; \ 1397c478bd9Sstevel@tonic-gate (l)->next = (head); \ 1407c478bd9Sstevel@tonic-gate if ((l)->next) \ 1417c478bd9Sstevel@tonic-gate (l)->next->prev = (l); \ 1427c478bd9Sstevel@tonic-gate (head) = (l); \ 1437c478bd9Sstevel@tonic-gate } 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate #define DEQUEUE(head, l) { \ 1467c478bd9Sstevel@tonic-gate if ((l)->prev) \ 1477c478bd9Sstevel@tonic-gate (l)->prev->next = (l)->next; \ 1487c478bd9Sstevel@tonic-gate else \ 1497c478bd9Sstevel@tonic-gate (head) = (l)->next; \ 1507c478bd9Sstevel@tonic-gate if ((l)->next) \ 1517c478bd9Sstevel@tonic-gate (l)->next->prev = (l)->prev; \ 1527c478bd9Sstevel@tonic-gate } 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate #define INVALIDATE_ADDR(a) ((a) = (void *)((unsigned long)(a) | 1L)) 1557c478bd9Sstevel@tonic-gate #define VALIDATE_ADDR(a) ((a) = (void *)((unsigned long)(a) & ~1L)) 1567c478bd9Sstevel@tonic-gate #define INVALID_ADDR(a) (((unsigned long)(a) & 1L)) 1577c478bd9Sstevel@tonic-gate #define INVALID_LINK(l) (INVALID_ADDR(l->entry)) 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate #define ENQUEUE_IDX(bp, l) { \ 160d216dff5SRobert Mastors rw_enter((bp)->dbk_lock, RW_WRITER); \ 161d216dff5SRobert Mastors ENQUEUE((bp)->dbk_head, l); \ 1627c478bd9Sstevel@tonic-gate VALIDATE_ADDR((l)->entry); \ 163d216dff5SRobert Mastors rw_exit((bp)->dbk_lock); \ 1647c478bd9Sstevel@tonic-gate } 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate #define DEQUEUE_IDX(bp, l) { \ 167d216dff5SRobert Mastors rw_enter((bp)->dbk_lock, RW_WRITER); \ 1687c478bd9Sstevel@tonic-gate INVALIDATE_ADDR((l)->entry); \ 169d216dff5SRobert Mastors DEQUEUE((bp)->dbk_head, l); \ 170d216dff5SRobert Mastors rw_exit((bp)->dbk_lock); \ 1717c478bd9Sstevel@tonic-gate } 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate #ifdef __cplusplus 1747c478bd9Sstevel@tonic-gate } 1757c478bd9Sstevel@tonic-gate #endif 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate #endif /* _NFS4_DB_IMPL_H */ 178