X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=patches%2Fyaffs_linux_allocator.c;fp=patches%2Fyaffs_linux_allocator.c;h=d0837f8696e946150dff107a90e4238179190be7;hp=0000000000000000000000000000000000000000;hb=1d65367807dc6c75458c2926b17727ae0765a856;hpb=96eaf1d7ebcad5892d7600bf85419f70d332f8b2 diff --git a/patches/yaffs_linux_allocator.c b/patches/yaffs_linux_allocator.c new file mode 100644 index 0000000..d0837f8 --- /dev/null +++ b/patches/yaffs_linux_allocator.c @@ -0,0 +1,202 @@ +/* + * YAFFS: Yet another Flash File System . A NAND-flash specific file system. + * + * Copyright (C) 2002-2010 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + */ + +/* + * Note: Tis code is currently unused. Being checked in in case it becomes useful. + */ + + +#include "yaffs_allocator.h" +#include "yaffs_guts.h" +#include "yaffs_trace.h" +#include "yportenv.h" +#include "yaffs_linux.h" +/* + * Start out with the same allocator as yaffs direct. + * Todo: Change to Linux slab allocator. + */ + + + +#define NAMELEN 20 +struct yaffs_AllocatorStruct { + char tnode_name[NAMELEN+1]; + char object_name[NAMELEN+1]; + struct kmem_cache *tnode_cache; + struct kmem_cache *object_cache; +}; + +typedef struct yaffs_AllocatorStruct yaffs_Allocator; + +int mount_id; + +void yaffs_deinit_raw_tnodes_and_objs(yaffs_dev_t *dev) +{ + yaffs_Allocator *allocator = (yaffs_Allocator *)dev->allocator; + + T(YAFFS_TRACE_ALLOCATE,(TSTR("Deinitialising yaffs allocator\n"))); + + if(allocator){ + if(allocator->tnode_cache){ + kmem_cache_destroy(allocator->tnode_cache); + allocator->tnode_cache = NULL; + } else { + T(YAFFS_TRACE_ALWAYS, + (TSTR("NULL tnode cache\n"))); + YBUG(); + } + + if(allocator->object_cache){ + kmem_cache_destroy(allocator->object_cache); + allocator->object_cache = NULL; + } else { + T(YAFFS_TRACE_ALWAYS, + (TSTR("NULL object cache\n"))); + YBUG(); + } + + YFREE(allocator); + + } else { + T(YAFFS_TRACE_ALWAYS, + (TSTR("Deinitialising NULL allocator\n"))); + YBUG(); + } + dev->allocator = NULL; +} + + +static void fake_ctor0(void *data){data = data;} +static void fake_ctor1(void *data){data = data;} +static void fake_ctor2(void *data){data = data;} +static void fake_ctor3(void *data){data = data;} +static void fake_ctor4(void *data){data = data;} +static void fake_ctor5(void *data){data = data;} +static void fake_ctor6(void *data){data = data;} +static void fake_ctor7(void *data){data = data;} +static void fake_ctor8(void *data){data = data;} +static void fake_ctor9(void *data){data = data;} + +static void (*fake_ctor_list[10]) (void *) = { + fake_ctor0, + fake_ctor1, + fake_ctor2, + fake_ctor3, + fake_ctor4, + fake_ctor5, + fake_ctor6, + fake_ctor7, + fake_ctor8, + fake_ctor9, +}; + +void yaffs_init_raw_tnodes_and_objs(yaffs_dev_t *dev) +{ + yaffs_Allocator *allocator; + unsigned mount_id = yaffs_dev_to_lc(dev)->mount_id; + + T(YAFFS_TRACE_ALLOCATE,(TSTR("Initialising yaffs allocator\n"))); + + if(dev->allocator) + YBUG(); + else if(mount_id >= 10){ + T(YAFFS_TRACE_ALWAYS,(TSTR("Bad mount_id %u\n"),mount_id)); + } else { + allocator = YMALLOC(sizeof(yaffs_Allocator)); + memset(allocator,0,sizeof(yaffs_Allocator)); + dev->allocator = allocator; + + if(!dev->allocator){ + T(YAFFS_TRACE_ALWAYS, + (TSTR("yaffs allocator creation failed\n"))); + YBUG(); + return; + + } + + sprintf(allocator->tnode_name,"yaffs_t_%u",mount_id); + sprintf(allocator->object_name,"yaffs_o_%u",mount_id); + + allocator->tnode_cache = + kmem_cache_create(allocator->tnode_name, + dev->tnode_size, + 0, 0, + fake_ctor_list[mount_id]); + if(allocator->tnode_cache) + T(YAFFS_TRACE_ALLOCATE, + (TSTR("tnode cache \"%s\" %p\n"), + allocator->tnode_name,allocator->tnode_cache)); + else { + T(YAFFS_TRACE_ALWAYS, + (TSTR("yaffs cache creation failed\n"))); + YBUG(); + } + + + allocator->object_cache = + kmem_cache_create(allocator->object_name, + sizeof(yaffs_obj_t), + 0, 0, + fake_ctor_list[mount_id]); + + if(allocator->object_cache) + T(YAFFS_TRACE_ALLOCATE, + (TSTR("object cache \"%s\" %p\n"), + allocator->object_name,allocator->object_cache)); + + else { + T(YAFFS_TRACE_ALWAYS, + (TSTR("yaffs cache creation failed\n"))); + YBUG(); + } + } +} + + +yaffs_tnode_t *yaffs_alloc_raw_tnode(yaffs_dev_t *dev) +{ + yaffs_Allocator *allocator = dev->allocator; + if(!allocator || !allocator->tnode_cache){ + YBUG(); + return NULL; + } + return kmem_cache_alloc(allocator->tnode_cache, GFP_NOFS); +} + +void yaffs_free_raw_tnode(yaffs_dev_t *dev, yaffs_tnode_t *tn) +{ + yaffs_Allocator *allocator = dev->allocator; + kmem_cache_free(allocator->tnode_cache,tn); +} + +yaffs_obj_t *yaffs_alloc_raw_obj(yaffs_dev_t *dev) +{ + yaffs_Allocator *allocator = dev->allocator; + if(!allocator){ + YBUG(); + return NULL; + } + if(!allocator->object_cache){ + YBUG(); + return NULL; + } + return kmem_cache_alloc(allocator->object_cache, GFP_NOFS); +} + +void yaffs_free_raw_obj(yaffs_dev_t *dev, yaffs_obj_t *obj) +{ + yaffs_Allocator *allocator = dev->allocator; + kmem_cache_free(allocator->object_cache,obj); +}