diff options
Diffstat (limited to 'source4/ntvfs/posix/pvfs_shortname.c')
-rw-r--r-- | source4/ntvfs/posix/pvfs_shortname.c | 46 |
1 files changed, 35 insertions, 11 deletions
diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index 9efd1cec85..98cd4a99f6 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -71,11 +71,6 @@ #define FLAG_POSSIBLE3 64 #define FLAG_POSSIBLE4 128 -/* by default have a max of 512 entries in the cache. */ -#ifndef MANGLE_CACHE_SIZE -#define MANGLE_CACHE_SIZE 512 -#endif - #define DEFAULT_MANGLE_PREFIX 4 #define MANGLE_BASECHARS "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" @@ -87,6 +82,31 @@ static const char *reserved_names[] = "LPT1", "LPT2", "LPT3", "NUL", "PRN", NULL }; +struct pvfs_mangle_context { + uint8_t char_flags[256]; + /* + this determines how many characters are used from the original + filename in the 8.3 mangled name. A larger value leads to a weaker + hash and more collisions. The largest possible value is 6. + */ + int mangle_prefix; + uint32_t mangle_modulus; + + /* we will use a very simple direct mapped prefix cache. The big + advantage of this cache structure is speed and low memory usage + + The cache is indexed by the low-order bits of the hash, and confirmed by + hashing the resulting cache entry to match the known hash + */ + uint32_t cache_size; + char **prefix_cache; + uint32_t *prefix_cache_hashes; + + /* this is used to reverse the base 36 mapping */ + unsigned char base_reverse[256]; +}; + + /* hash a string of the specified length. The string does not need to be null terminated @@ -105,7 +125,7 @@ static uint32_t mangle_hash(struct pvfs_mangle_context *ctx, static void cache_insert(struct pvfs_mangle_context *ctx, const char *prefix, int length, uint32_t hash) { - int i = hash % MANGLE_CACHE_SIZE; + int i = hash % ctx->cache_size; if (ctx->prefix_cache[i]) { talloc_free(ctx->prefix_cache[i]); @@ -120,7 +140,7 @@ static void cache_insert(struct pvfs_mangle_context *ctx, */ static const char *cache_lookup(struct pvfs_mangle_context *ctx, uint32_t hash) { - int i = hash % MANGLE_CACHE_SIZE; + int i = hash % ctx->cache_size; if (!ctx->prefix_cache[i] || hash != ctx->prefix_cache_hashes[i]) { @@ -592,17 +612,21 @@ NTSTATUS pvfs_mangle_init(struct pvfs_state *pvfs) if (ctx == NULL) { return NT_STATUS_NO_MEMORY; } - ctx->prefix_cache = talloc_array_p(ctx, char *, MANGLE_CACHE_SIZE); + + /* by default have a max of 512 entries in the cache. */ + ctx->cache_size = lp_parm_int(-1, "mangle", "cachesize", 512); + + ctx->prefix_cache = talloc_array(ctx, char *, ctx->cache_size); if (ctx->prefix_cache == NULL) { return NT_STATUS_NO_MEMORY; } - ctx->prefix_cache_hashes = talloc_array_p(ctx, uint32_t, MANGLE_CACHE_SIZE); + ctx->prefix_cache_hashes = talloc_array(ctx, uint32_t, ctx->cache_size); if (ctx->prefix_cache_hashes == NULL) { return NT_STATUS_NO_MEMORY; } - memset(ctx->prefix_cache, 0, sizeof(char *)*MANGLE_CACHE_SIZE); - memset(ctx->prefix_cache_hashes, 0, sizeof(uint32_t)*MANGLE_CACHE_SIZE); + memset(ctx->prefix_cache, 0, sizeof(char *) * ctx->cache_size); + memset(ctx->prefix_cache_hashes, 0, sizeof(uint32_t) * ctx->cache_size); ctx->mangle_prefix = lp_parm_int(-1, "mangle", "prefix", -1); if (ctx->mangle_prefix < 0 || ctx->mangle_prefix > 6) { |