5 |
* |
* |
6 |
* Copyright (C) 2005-2007 NTT DATA CORPORATION |
* Copyright (C) 2005-2007 NTT DATA CORPORATION |
7 |
* |
* |
8 |
* Version: 1.3.2 2007/02/14 |
* Version: 1.5.0-pre 2007/08/06 |
9 |
* |
* |
10 |
* This file is applicable to both 2.4.30 and 2.6.11 and later. |
* This file is applicable to both 2.4.30 and 2.6.11 and later. |
11 |
* See README.ccs for ChangeLog. |
* See README.ccs for ChangeLog. |
237 |
} |
} |
238 |
|
|
239 |
/* Allocate memory for structures. The RAM is chunked, so NEVER try to kfree() the returned pointer. */ |
/* Allocate memory for structures. The RAM is chunked, so NEVER try to kfree() the returned pointer. */ |
240 |
char *alloc_element(const unsigned int size) |
void *alloc_element(const unsigned int size) |
241 |
{ |
{ |
242 |
static DECLARE_MUTEX(lock); |
static DECLARE_MUTEX(lock); |
243 |
static char *buf = NULL; |
static char *buf = NULL; |
283 |
|
|
284 |
#define MAX_HASH 256 |
#define MAX_HASH 256 |
285 |
|
|
286 |
typedef struct name_entry { |
struct name_entry { |
287 |
struct name_entry *next; /* Pointer to next record. NULL if none. */ |
struct name_entry *next; /* Pointer to next record. NULL if none. */ |
288 |
struct path_info entry; |
struct path_info entry; |
289 |
} NAME_ENTRY; |
}; |
290 |
|
|
291 |
typedef struct free_memory_block_list { |
struct free_memory_block_list { |
292 |
struct free_memory_block_list *next; /* Pointer to next record. NULL if none. */ |
struct free_memory_block_list *next; /* Pointer to next record. NULL if none. */ |
293 |
char *ptr; /* Pointer to a free area. */ |
char *ptr; /* Pointer to a free area. */ |
294 |
int len; /* Length of the area. */ |
int len; /* Length of the area. */ |
295 |
} FREE_MEMORY_BLOCK_LIST; |
}; |
296 |
|
|
297 |
/* Keep the given name on the RAM. The RAM is shared, so NEVER try to modify or kfree() the returned name. */ |
/* Keep the given name on the RAM. The RAM is shared, so NEVER try to modify or kfree() the returned name. */ |
298 |
const struct path_info *SaveName(const char *name) |
const struct path_info *SaveName(const char *name) |
299 |
{ |
{ |
300 |
static FREE_MEMORY_BLOCK_LIST fmb_list = { NULL, NULL, 0 }; |
static struct free_memory_block_list fmb_list = { NULL, NULL, 0 }; |
301 |
static NAME_ENTRY name_list[MAX_HASH]; /* The list of names. */ |
static struct name_entry name_list[MAX_HASH]; /* The list of names. */ |
302 |
static DECLARE_MUTEX(lock); |
static DECLARE_MUTEX(lock); |
303 |
NAME_ENTRY *ptr, *prev = NULL; |
struct name_entry *ptr, *prev = NULL; |
304 |
unsigned int hash; |
unsigned int hash; |
305 |
FREE_MEMORY_BLOCK_LIST *fmb = &fmb_list; |
struct free_memory_block_list *fmb = &fmb_list; |
306 |
int len; |
int len; |
307 |
static int first_call = 1; |
static int first_call = 1; |
308 |
if (!name) return NULL; |
if (!name) return NULL; |
333 |
fmb = fmb->next; |
fmb = fmb->next; |
334 |
} else { |
} else { |
335 |
char *cp; |
char *cp; |
336 |
if ((cp = kmalloc(PAGE_SIZE, GFP_KERNEL)) == NULL || (fmb->next = (FREE_MEMORY_BLOCK_LIST *) alloc_element(sizeof(FREE_MEMORY_BLOCK_LIST))) == NULL) { |
if ((cp = kmalloc(PAGE_SIZE, GFP_KERNEL)) == NULL || (fmb->next = alloc_element(sizeof(*fmb))) == NULL) { |
337 |
kfree(cp); |
kfree(cp); |
338 |
printk("ERROR: Out of memory for SaveName().\n"); |
printk("ERROR: Out of memory for SaveName().\n"); |
339 |
if (!sbin_init_started) panic("MAC Initialization failed.\n"); |
if (!sbin_init_started) panic("MAC Initialization failed.\n"); |
346 |
fmb->len = PAGE_SIZE; |
fmb->len = PAGE_SIZE; |
347 |
} |
} |
348 |
} |
} |
349 |
if ((ptr = (NAME_ENTRY *) alloc_element(sizeof(NAME_ENTRY))) == NULL) goto out; |
if ((ptr = alloc_element(sizeof(*ptr))) == NULL) goto out; |
350 |
ptr->entry.name = fmb->ptr; |
ptr->entry.name = fmb->ptr; |
351 |
memmove(fmb->ptr, name, len); |
memmove(fmb->ptr, name, len); |
352 |
fill_path_info(&ptr->entry); |
fill_path_info(&ptr->entry); |
354 |
fmb->len -= len; |
fmb->len -= len; |
355 |
prev->next = ptr; /* prev != NULL because name_list is not empty. */ |
prev->next = ptr; /* prev != NULL because name_list is not empty. */ |
356 |
if (fmb->len == 0) { |
if (fmb->len == 0) { |
357 |
FREE_MEMORY_BLOCK_LIST *ptr = &fmb_list; |
struct free_memory_block_list *ptr = &fmb_list; |
358 |
while (ptr->next != fmb) ptr = ptr->next; ptr->next = fmb->next; |
while (ptr->next != fmb) ptr = ptr->next; ptr->next = fmb->next; |
359 |
} |
} |
360 |
out: |
out: |
364 |
|
|
365 |
/***** Dynamic memory allocator. *****/ |
/***** Dynamic memory allocator. *****/ |
366 |
|
|
367 |
typedef struct cache_entry { |
struct cache_entry { |
368 |
struct list_head list; |
struct list_head list; |
369 |
void *ptr; |
void *ptr; |
370 |
int size; |
int size; |
371 |
} CACHE_ENTRY; |
}; |
372 |
|
|
373 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) |
374 |
static struct kmem_cache *ccs_cachep = NULL; |
static struct kmem_cache *ccs_cachep = NULL; |
378 |
|
|
379 |
void __init realpath_Init(void) |
void __init realpath_Init(void) |
380 |
{ |
{ |
381 |
ccs_cachep = kmem_cache_create("ccs_cache", sizeof(CACHE_ENTRY), 0, 0, NULL, NULL); |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) |
382 |
|
ccs_cachep = kmem_cache_create("ccs_cache", sizeof(struct cache_entry), 0, 0, NULL); |
383 |
|
#else |
384 |
|
ccs_cachep = kmem_cache_create("ccs_cache", sizeof(struct cache_entry), 0, 0, NULL, NULL); |
385 |
|
#endif |
386 |
if (!ccs_cachep) panic("Can't create cache.\n"); |
if (!ccs_cachep) panic("Can't create cache.\n"); |
387 |
} |
} |
388 |
|
|
395 |
return dynamic_memory_size; |
return dynamic_memory_size; |
396 |
} |
} |
397 |
|
|
398 |
char *ccs_alloc(const size_t size) |
void *ccs_alloc(const size_t size) |
399 |
{ |
{ |
400 |
void *ret = kmalloc(size, GFP_KERNEL); |
void *ret = kmalloc(size, GFP_KERNEL); |
401 |
if (ret) { |
if (ret) { |
402 |
CACHE_ENTRY *new_entry = kmem_cache_alloc(ccs_cachep, GFP_KERNEL); |
struct cache_entry *new_entry = kmem_cache_alloc(ccs_cachep, GFP_KERNEL); |
403 |
if (!new_entry) { |
if (!new_entry) { |
404 |
kfree(ret); ret = NULL; |
kfree(ret); ret = NULL; |
405 |
} else { |
} else { |
413 |
memset(ret, 0, size); |
memset(ret, 0, size); |
414 |
} |
} |
415 |
} |
} |
416 |
return (char *) ret; |
return ret; |
417 |
} |
} |
418 |
|
|
419 |
void ccs_free(const void *p) |
void ccs_free(const void *p) |
420 |
{ |
{ |
421 |
struct list_head *v; |
struct list_head *v; |
422 |
CACHE_ENTRY *entry = NULL; |
struct cache_entry *entry = NULL; |
423 |
if (!p) return; |
if (!p) return; |
424 |
spin_lock(&cache_list_lock); |
spin_lock(&cache_list_lock); |
425 |
list_for_each(v, &cache_list) { |
list_for_each(v, &cache_list) { |
426 |
entry = list_entry(v, CACHE_ENTRY, list); |
entry = list_entry(v, struct cache_entry, list); |
427 |
if (entry->ptr != p) { |
if (entry->ptr != p) { |
428 |
entry = NULL; continue; |
entry = NULL; continue; |
429 |
} |
} |