From f1688d61df13aacb0e512fd16504cc94f803d808 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 30 Aug 2004 20:19:40 +0000 Subject: [PATCH] r2112: Simplify the mangle hash code to use an in-memory tdb. Should be ready for the new directory code now... Jeremy. (This used to be commit c2eff8ef1b65570d2e590f62f026cc18f9142652) --- source3/Makefile.in | 2 +- source3/script/mkproto.awk | 2 +- source3/smbd/mangle_hash.c | 218 ++++++++++--------------------------- source3/smbd/statcache.c | 4 +- 4 files changed, 59 insertions(+), 167 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index dd9813de336..1ccf8099f42 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -397,7 +397,7 @@ SMBD_OBJ_BASE = $(PARAM_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \ $(LIBMSRPC_OBJ) \ $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(LIBADS_SERVER_OBJ) \ $(LIB_SMBD_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \ - $(UBIQX_OBJ) $(BUILDOPT_OBJ) $(SMBLDAP_OBJ) + $(BUILDOPT_OBJ) $(SMBLDAP_OBJ) PRINTING_OBJ = printing/pcap.o printing/print_svid.o \ printing/print_cups.o printing/print_generic.o \ diff --git a/source3/script/mkproto.awk b/source3/script/mkproto.awk index 4c9507dcf9b..4edc7abc63a 100644 --- a/source3/script/mkproto.awk +++ b/source3/script/mkproto.awk @@ -132,7 +132,7 @@ END { gotstart = 1; } - if( $0 ~ /^WINBINDD_PW|^WINBINDD_GR|^NT_PRINTER_INFO_LEVEL_2|^LOGIN_CACHE|^krb5_error_code|^LDAP/ ) { + if( $0 ~ /^WINBINDD_PW|^WINBINDD_GR|^NT_PRINTER_INFO_LEVEL_2|^LOGIN_CACHE|^krb5_error_code|^LDAP|^u32/ ) { gotstart = 1; } diff --git a/source3/smbd/mangle_hash.c b/source3/smbd/mangle_hash.c index 13ec99a917f..26ddf1b3a3d 100644 --- a/source3/smbd/mangle_hash.c +++ b/source3/smbd/mangle_hash.c @@ -85,23 +85,6 @@ * if that character is in the illegal characters set. * This is faster than using strchr_m(). * - * mangled_cache - Cache header used for storing mangled -> original - * reverse maps. - * - * mc_initialized - False until the mangled_cache structure has been - * initialized via a call to reset_mangled_cache(). - * - * MANGLED_CACHE_MAX_ENTRIES - Default maximum number of entries for the - * cache. A value of 0 indicates "infinite". - * - * MANGLED_CACHE_MAX_MEMORY - Default maximum amount of memory for the - * cache. When the cache was kept as an array of 256 - * byte strings, the default cache size was 50 entries. - * This required a fixed 12.5Kbytes of memory. The - * mangled stack parameter is no longer used (though - * this might change). We're now using a fixed 16Kbyte - * maximum cache size. This will probably be much more - * than 50 entries. */ char magic_char = '~'; @@ -118,10 +101,7 @@ static BOOL ct_initialized = False; #define isbasechar(C) ( (chartest[ ((C) & 0xff) ]) & BASECHAR_MASK ) #define isillegal(C) ( (chartest[ ((C) & 0xff) ]) & ILLEGAL_MASK ) -static ubi_cacheRoot mangled_cache[1] = { { { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0 } }; -static BOOL mc_initialized = False; -#define MANGLED_CACHE_MAX_ENTRIES 1024 -#define MANGLED_CACHE_MAX_MEMORY 0 +static TDB_CONTEXT *tdb_mangled_cache; /* -------------------------------------------------------------------- */ @@ -400,157 +380,69 @@ static BOOL is_mangled(const char *s) return( False ); } -/* ************************************************************************** ** - * Compare two cache keys and return a value indicating their ordinal - * relationship. - * - * Input: ItemPtr - Pointer to a comparison key. In this case, this will - * be a mangled name string. - * NodePtr - Pointer to a node in the cache. The node structure - * will be followed in memory by a mangled name string. - * - * Output: A signed integer, as follows: - * (x < 0) <==> Key1 less than Key2 - * (x == 0) <==> Key1 equals Key2 - * (x > 0) <==> Key1 greater than Key2 - * - * Notes: This is a ubiqx-style comparison routine. See ubi_BinTree for - * more info. - * - * ************************************************************************** ** - */ -static signed int cache_compare( ubi_btItemPtr ItemPtr, ubi_btNodePtr NodePtr ) -{ - char *Key1 = (char *)ItemPtr; - char *Key2 = (char *)(((ubi_cacheEntryPtr)NodePtr) + 1); - - return( StrCaseCmp( Key1, Key2 ) ); -} - -/* ************************************************************************** ** - * Free a cache entry. - * - * Input: WarrenZevon - Pointer to the entry that is to be returned to - * Nirvana. - * Output: none. - * - * Notes: This function gets around the possibility that the standard - * free() function may be implemented as a macro, or other evil - * subversions (oh, so much fun). - * - * ************************************************************************** ** - */ -static void cache_free_entry( ubi_trNodePtr WarrenZevon ) -{ - ZERO_STRUCTP(WarrenZevon); - SAFE_FREE( WarrenZevon ); -} - -/* ************************************************************************** ** - * Initializes or clears the mangled cache. - * - * Input: none. - * Output: none. - * - * Notes: There is a section below that is commented out. It shows how - * one might use lp_ calls to set the maximum memory and entry size - * of the cache. You might also want to remove the constants used - * in ubi_cacheInit() and replace them with lp_ calls. If so, then - * the calls to ubi_cacheSetMax*() would be moved into the else - * clause. Another option would be to pass in the max_entries and - * max_memory values as parameters. crh 09-Apr-1998. - * - * ************************************************************************** ** - */ +/*************************************************************************** + Initializes or clears the mangled cache. +***************************************************************************/ static void mangle_reset( void ) { - if( !mc_initialized ) { - (void)ubi_cacheInit( mangled_cache, - cache_compare, - cache_free_entry, - MANGLED_CACHE_MAX_ENTRIES, - MANGLED_CACHE_MAX_MEMORY ); - mc_initialized = True; - } else { - (void)ubi_cacheClear( mangled_cache ); - } - - /* - (void)ubi_cacheSetMaxEntries( mangled_cache, lp_mangled_cache_entries() ); - (void)ubi_cacheSetMaxMemory( mangled_cache, lp_mangled_cache_memory() ); - */ + /* We could close and re-open the tdb here... should we ? The old code did + the equivalent... JRA. */ } -/* ************************************************************************** ** - * Add a mangled name into the cache. - * - * Notes: If the mangled cache has not been initialized, then the - * function will simply fail. It could initialize the cache, - * but that's not the way it was done before I changed the - * cache mechanism, so I'm sticking with the old method. - * - * If the extension of the raw name maps directly to the - * extension of the mangled name, then we'll store both names - * *without* extensions. That way, we can provide consistent - * reverse mangling for all names that match. The test here is - * a bit more careful than the one done in earlier versions of - * mangle.c: - * - * - the extension must exist on the raw name, - * - it must be all lower case - * - it must match the mangled extension (to prove that no - * mangling occurred). - * - * crh 07-Apr-1998 - * - * ************************************************************************** ** - */ -static void cache_mangled_name( char *mangled_name, char *raw_name ) +/*************************************************************************** + Add a mangled name into the cache. + If the extension of the raw name maps directly to the + extension of the mangled name, then we'll store both names + *without* extensions. That way, we can provide consistent + reverse mangling for all names that match. The test here is + a bit more careful than the one done in earlier versions of + mangle.c: + + - the extension must exist on the raw name, + - it must be all lower case + - it must match the mangled extension (to prove that no + mangling occurred). + crh 07-Apr-1998 +**************************************************************************/ + +static void cache_mangled_name( const char mangled_name[13], char *raw_name ) { - ubi_cacheEntryPtr new_entry; - char *s1; - char *s2; - size_t mangled_len; - size_t raw_len; - size_t i; + TDB_DATA data_val; + char mangled_name_key[13]; + char *s1; + char *s2; /* If the cache isn't initialized, give up. */ - if( !mc_initialized ) + if( !tdb_mangled_cache ) return; /* Init the string lengths. */ - mangled_len = strlen( mangled_name ); - raw_len = strlen( raw_name ); + safe_strcpy(mangled_name_key, mangled_name, sizeof(mangled_name_key)-1); /* See if the extensions are unmangled. If so, store the entry * without the extension, thus creating a "group" reverse map. */ - s1 = strrchr( mangled_name, '.' ); + s1 = strrchr( mangled_name_key, '.' ); if( s1 && (s2 = strrchr( raw_name, '.' )) ) { - i = 1; + size_t i = 1; while( s1[i] && (tolower( s1[i] ) == s2[i]) ) i++; if( !s1[i] && !s2[i] ) { - mangled_len -= i; - raw_len -= i; + /* Truncate at the '.' */ + *s1 = '\0'; + *s2 = '\0'; } } /* Allocate a new cache entry. If the allocation fails, just return. */ - i = sizeof( ubi_cacheEntry ) + mangled_len + raw_len + 2; - new_entry = malloc( i ); - if( !new_entry ) - return; - - /* Fill the new cache entry, and add it to the cache. */ - s1 = (char *)(new_entry + 1); - s2 = (char *)&(s1[mangled_len + 1]); - memcpy( s1, mangled_name, mangled_len ); - s1[mangled_len] = '\0'; - memcpy( s2, raw_name, raw_len ); - s2[raw_len] = '\0'; - ubi_cachePut( mangled_cache, i, new_entry, s1 ); + data_val.dptr = raw_name; + data_val.dsize = strlen(raw_name)+1; + if (tdb_store_bystring(tdb_mangled_cache, mangled_name_key, data_val, TDB_REPLACE) != 0) { + DEBUG(0,("cache_mangled_name: Error storing entry %s -> %s\n", mangled_name_key, raw_name)); + } else { + DEBUG(5,("cache_mangled_name: Stored entry %s -> %s\n", mangled_name_key, raw_name)); + } } /* ************************************************************************** ** @@ -570,26 +462,25 @@ static void cache_mangled_name( char *mangled_name, char *raw_name ) static BOOL check_cache( char *s, size_t maxlen ) { - ubi_cacheEntryPtr FoundPtr; - char *ext_start = NULL; - char *found_name; - char *saved_ext = NULL; + TDB_DATA data_val; + char *ext_start = NULL; + char *saved_ext = NULL; /* If the cache isn't initialized, give up. */ - if( !mc_initialized ) + if( !tdb_mangled_cache ) return( False ); - FoundPtr = ubi_cacheGet( mangled_cache, (ubi_trItemPtr)s ); + data_val = tdb_fetch_bystring(tdb_mangled_cache, s); /* If we didn't find the name *with* the extension, try without. */ - if( !FoundPtr ) { + if(data_val.dptr == NULL || data_val.dsize == 0) { ext_start = strrchr( s, '.' ); if( ext_start ) { if((saved_ext = strdup(ext_start)) == NULL) return False; *ext_start = '\0'; - FoundPtr = ubi_cacheGet( mangled_cache, (ubi_trItemPtr)s ); + data_val = tdb_fetch_bystring(tdb_mangled_cache, s); /* * At this point s is the name without the * extension. We re-add the extension if saved_ext @@ -599,7 +490,7 @@ static BOOL check_cache( char *s, size_t maxlen ) } /* Okay, if we haven't found it we're done. */ - if( !FoundPtr ) { + if(data_val.dptr == NULL || data_val.dsize == 0) { if(saved_ext) { /* Replace the saved_ext as it was truncated. */ (void)safe_strcat( s, saved_ext, maxlen ); @@ -609,16 +500,13 @@ static BOOL check_cache( char *s, size_t maxlen ) } /* If we *did* find it, we need to copy it into the string buffer. */ - found_name = (char *)(FoundPtr + 1); - found_name += (strlen( found_name ) + 1); - - (void)safe_strcpy( s, found_name, maxlen ); + (void)safe_strcpy( s, data_val.dptr, maxlen ); if( saved_ext ) { /* Replace the saved_ext as it was truncated. */ (void)safe_strcat( s, saved_ext, maxlen ); SAFE_FREE(saved_ext); } - + SAFE_FREE(data_val.dptr); return( True ); } @@ -767,5 +655,9 @@ struct mangle_fns *mangle_hash_init(void) { mangle_reset(); + /* Create the in-memory tdb using our custom hash function. */ + tdb_mangled_cache = tdb_open_ex("mangled_cache", 1031, TDB_INTERNAL, + (O_RDWR|O_CREAT), 0644, NULL, fast_string_hash); + return &mangle_fns; } diff --git a/source3/smbd/statcache.c b/source3/smbd/statcache.c index dfc1a6ed959..03adf32e093 100644 --- a/source3/smbd/statcache.c +++ b/source3/smbd/statcache.c @@ -286,7 +286,7 @@ BOOL stat_cache_lookup(connection_struct *conn, pstring name, pstring dirpath, JRA. Use a djb-algorithm hash for speed. ***************************************************************/ -static u32 string_hash(TDB_DATA *key) +u32 fast_string_hash(TDB_DATA *key) { u32 n = 0; const char *p; @@ -311,7 +311,7 @@ BOOL reset_stat_cache( void ) /* Create the in-memory tdb using our custom hash function. */ tdb_stat_cache = tdb_open_ex("statcache", 0, TDB_INTERNAL, - (O_RDWR|O_CREAT), 0644, NULL, string_hash); + (O_RDWR|O_CREAT), 0644, NULL, fast_string_hash); if (!tdb_stat_cache) return False;