Merge branch 'timothy'
[yaffs2.git] / yaffs_linux_allocator.c
1 /*
2  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
3  *
4  * Copyright (C) 2002-2010 Aleph One Ltd.
5  *   for Toby Churchill Ltd and Brightstar Engineering
6  *
7  * Created by Charles Manning <charles@aleph1.co.uk>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU Lesser General Public License version 2.1 as
11  * published by the Free Software Foundation.
12  *
13  * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
14  */
15
16 /*
17  * Note: Tis code is currently unused. Being checked in in case it becomes useful.
18  */
19
20
21 #include "yaffs_allocator.h"
22 #include "yaffs_guts.h"
23 #include "yaffs_trace.h"
24 #include "yportenv.h"
25 #include "yaffs_linux.h"
26 /*
27  * Start out with the same allocator as yaffs direct.
28  * Todo: Change to Linux slab allocator.
29  */
30
31
32
33 #define NAMELEN  20
34 struct yaffs_AllocatorStruct {
35         char tnode_name[NAMELEN+1];
36         char object_name[NAMELEN+1];
37         struct kmem_cache *tnode_cache;
38         struct kmem_cache *object_cache;
39 };
40
41 typedef struct yaffs_AllocatorStruct yaffs_Allocator;
42
43 int mount_id;
44
45 void yaffs_deinit_raw_tnodes_and_objs(yaffs_dev_t *dev)
46 {
47         yaffs_Allocator *allocator = (yaffs_Allocator *)dev->allocator;
48
49         T(YAFFS_TRACE_ALLOCATE,(TSTR("Deinitialising yaffs allocator\n")));
50
51         if(allocator){
52                 if(allocator->tnode_cache){
53                         kmem_cache_destroy(allocator->tnode_cache);
54                         allocator->tnode_cache = NULL;
55                 } else {
56                         T(YAFFS_TRACE_ALWAYS,
57                                 (TSTR("NULL tnode cache\n")));
58                         YBUG();
59                 }
60
61                 if(allocator->object_cache){
62                         kmem_cache_destroy(allocator->object_cache);
63                         allocator->object_cache = NULL;
64                 } else {
65                         T(YAFFS_TRACE_ALWAYS,
66                                 (TSTR("NULL object cache\n")));
67                         YBUG();
68                 }
69
70                 YFREE(allocator);
71
72         } else {
73                 T(YAFFS_TRACE_ALWAYS,
74                         (TSTR("Deinitialising NULL allocator\n")));
75                 YBUG();
76         }
77         dev->allocator = NULL;
78 }
79
80
81 static void fake_ctor0(void *data){data = data;}
82 static void fake_ctor1(void *data){data = data;}
83 static void fake_ctor2(void *data){data = data;}
84 static void fake_ctor3(void *data){data = data;}
85 static void fake_ctor4(void *data){data = data;}
86 static void fake_ctor5(void *data){data = data;}
87 static void fake_ctor6(void *data){data = data;}
88 static void fake_ctor7(void *data){data = data;}
89 static void fake_ctor8(void *data){data = data;}
90 static void fake_ctor9(void *data){data = data;}
91
92 static void (*fake_ctor_list[10]) (void *) = {
93         fake_ctor0,
94         fake_ctor1,
95         fake_ctor2,
96         fake_ctor3,
97         fake_ctor4,
98         fake_ctor5,
99         fake_ctor6,
100         fake_ctor7,
101         fake_ctor8,
102         fake_ctor9,
103 };
104
105 void yaffs_init_raw_tnodes_and_objs(yaffs_dev_t *dev)
106 {
107         yaffs_Allocator *allocator;
108         unsigned mount_id = yaffs_dev_to_lc(dev)->mount_id;
109
110         T(YAFFS_TRACE_ALLOCATE,(TSTR("Initialising yaffs allocator\n")));
111
112         if(dev->allocator)
113                 YBUG();
114         else if(mount_id >= 10){
115                 T(YAFFS_TRACE_ALWAYS,(TSTR("Bad mount_id %u\n"),mount_id));
116         } else {
117                  allocator = YMALLOC(sizeof(yaffs_Allocator));
118                  memset(allocator,0,sizeof(yaffs_Allocator));
119                  dev->allocator = allocator;
120
121                 if(!dev->allocator){
122                         T(YAFFS_TRACE_ALWAYS,
123                                 (TSTR("yaffs allocator creation failed\n")));
124                         YBUG();
125                         return;
126
127                 }
128
129                 sprintf(allocator->tnode_name,"yaffs_t_%u",mount_id);
130                 sprintf(allocator->object_name,"yaffs_o_%u",mount_id);
131
132                 allocator->tnode_cache =
133                         kmem_cache_create(allocator->tnode_name,
134                                 dev->tnode_size,
135                                 0, 0,
136                                 fake_ctor_list[mount_id]);
137                 if(allocator->tnode_cache)
138                         T(YAFFS_TRACE_ALLOCATE,
139                                 (TSTR("tnode cache \"%s\" %p\n"),
140                                 allocator->tnode_name,allocator->tnode_cache));
141                 else {
142                         T(YAFFS_TRACE_ALWAYS,
143                                 (TSTR("yaffs cache creation failed\n")));
144                         YBUG();
145                 }
146
147
148                 allocator->object_cache = 
149                         kmem_cache_create(allocator->object_name,
150                                 sizeof(yaffs_obj_t),
151                                 0, 0,
152                                 fake_ctor_list[mount_id]);
153
154                 if(allocator->object_cache)
155                         T(YAFFS_TRACE_ALLOCATE,
156                                 (TSTR("object cache \"%s\" %p\n"),
157                                 allocator->object_name,allocator->object_cache));
158
159                 else {
160                         T(YAFFS_TRACE_ALWAYS,
161                                 (TSTR("yaffs cache creation failed\n")));
162                         YBUG();
163                 }
164         } 
165 }
166
167
168 yaffs_tnode_t *yaffs_alloc_raw_tnode(yaffs_dev_t *dev)
169 {
170         yaffs_Allocator *allocator = dev->allocator;
171         if(!allocator || !allocator->tnode_cache){
172                 YBUG();
173                 return NULL;
174         }
175         return kmem_cache_alloc(allocator->tnode_cache, GFP_NOFS);
176 }
177
178 void yaffs_free_raw_tnode(yaffs_dev_t *dev, yaffs_tnode_t *tn)
179 {
180         yaffs_Allocator *allocator = dev->allocator;
181         kmem_cache_free(allocator->tnode_cache,tn);
182 }
183
184 yaffs_obj_t *yaffs_alloc_raw_obj(yaffs_dev_t *dev)
185 {
186         yaffs_Allocator *allocator = dev->allocator;
187         if(!allocator){
188                 YBUG();
189                 return NULL;
190         }
191         if(!allocator->object_cache){
192                 YBUG();
193                 return NULL;
194         }
195         return kmem_cache_alloc(allocator->object_cache, GFP_NOFS);
196 }
197
198 void yaffs_free_raw_obj(yaffs_dev_t *dev, yaffs_obj_t *obj)
199 {
200         yaffs_Allocator *allocator = dev->allocator;
201         kmem_cache_free(allocator->object_cache,obj);
202 }