yaffs Change file Linux vfs truncation to new mechanism
[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  * Note: Tis code is currently unused. Being checked in in case it becomes useful.
16  */
17
18
19 #include "yaffs_allocator.h"
20 #include "yaffs_guts.h"
21 #include "yaffs_trace.h"
22 #include "yportenv.h"
23 #include "yaffs_linux.h"
24 /*
25  * Start out with the same allocator as yaffs direct.
26  * Todo: Change to Linux slab allocator.
27  */
28
29
30
31 #define NAMELEN  20
32 struct yaffs_AllocatorStruct {
33         char tnode_name[NAMELEN+1];
34         char object_name[NAMELEN+1];
35         struct kmem_cache *tnode_cache;
36         struct kmem_cache *object_cache;
37 };
38
39 typedef struct yaffs_AllocatorStruct yaffs_Allocator;
40
41 int mount_id;
42
43 void yaffs_DeinitialiseRawTnodesAndObjects(yaffs_Device *dev)
44 {
45         yaffs_Allocator *allocator = (yaffs_Allocator *)dev->allocator;
46
47         T(YAFFS_TRACE_ALLOCATE,(TSTR("Deinitialising yaffs allocator\n")));
48
49         if(allocator){
50                 if(allocator->tnode_cache){
51                         kmem_cache_destroy(allocator->tnode_cache);
52                         allocator->tnode_cache = NULL;
53                 } else {
54                         T(YAFFS_TRACE_ALWAYS,
55                                 (TSTR("NULL tnode cache\n")));
56                         YBUG();
57                 }
58
59                 if(allocator->object_cache){
60                         kmem_cache_destroy(allocator->object_cache);
61                         allocator->object_cache = NULL;
62                 } else {
63                         T(YAFFS_TRACE_ALWAYS,
64                                 (TSTR("NULL object cache\n")));
65                         YBUG();
66                 }
67
68                 YFREE(allocator);
69
70         } else {
71                 T(YAFFS_TRACE_ALWAYS,
72                         (TSTR("Deinitialising NULL allocator\n")));
73                 YBUG();
74         }
75         dev->allocator = NULL;
76 }
77
78
79 static void fake_ctor0(void *data){data = data;}
80 static void fake_ctor1(void *data){data = data;}
81 static void fake_ctor2(void *data){data = data;}
82 static void fake_ctor3(void *data){data = data;}
83 static void fake_ctor4(void *data){data = data;}
84 static void fake_ctor5(void *data){data = data;}
85 static void fake_ctor6(void *data){data = data;}
86 static void fake_ctor7(void *data){data = data;}
87 static void fake_ctor8(void *data){data = data;}
88 static void fake_ctor9(void *data){data = data;}
89
90 static void (*fake_ctor_list[10]) (void *) = {
91         fake_ctor0,
92         fake_ctor1,
93         fake_ctor2,
94         fake_ctor3,
95         fake_ctor4,
96         fake_ctor5,
97         fake_ctor6,
98         fake_ctor7,
99         fake_ctor8,
100         fake_ctor9,
101 };
102
103 void yaffs_InitialiseRawTnodesAndObjects(yaffs_Device *dev)
104 {
105         yaffs_Allocator *allocator;
106         unsigned mount_id = yaffs_DeviceToLC(dev)->mount_id;
107
108         T(YAFFS_TRACE_ALLOCATE,(TSTR("Initialising yaffs allocator\n")));
109
110         if(dev->allocator)
111                 YBUG();
112         else if(mount_id >= 10){
113                 T(YAFFS_TRACE_ALWAYS,(TSTR("Bad mount_id %u\n"),mount_id));
114         } else {
115                  allocator = YMALLOC(sizeof(yaffs_Allocator));
116                  memset(allocator,0,sizeof(yaffs_Allocator));
117                  dev->allocator = allocator;
118
119                 if(!dev->allocator){
120                         T(YAFFS_TRACE_ALWAYS,
121                                 (TSTR("yaffs allocator creation failed\n")));
122                         YBUG();
123                         return;
124
125                 }
126
127                 sprintf(allocator->tnode_name,"yaffs_t_%u",mount_id);
128                 sprintf(allocator->object_name,"yaffs_o_%u",mount_id);
129
130                 allocator->tnode_cache =
131                         kmem_cache_create(allocator->tnode_name,
132                                 dev->tnodeSize,
133                                 0, 0,
134                                 fake_ctor_list[mount_id]);
135                 if(allocator->tnode_cache)
136                         T(YAFFS_TRACE_ALLOCATE,
137                                 (TSTR("tnode cache \"%s\" %p\n"),
138                                 allocator->tnode_name,allocator->tnode_cache));
139                 else {
140                         T(YAFFS_TRACE_ALWAYS,
141                                 (TSTR("yaffs cache creation failed\n")));
142                         YBUG();
143                 }
144
145
146                 allocator->object_cache = 
147                         kmem_cache_create(allocator->object_name,
148                                 sizeof(yaffs_Object),
149                                 0, 0,
150                                 fake_ctor_list[mount_id]);
151
152                 if(allocator->object_cache)
153                         T(YAFFS_TRACE_ALLOCATE,
154                                 (TSTR("object cache \"%s\" %p\n"),
155                                 allocator->object_name,allocator->object_cache));
156
157                 else {
158                         T(YAFFS_TRACE_ALWAYS,
159                                 (TSTR("yaffs cache creation failed\n")));
160                         YBUG();
161                 }
162         } 
163 }
164
165
166 yaffs_Tnode *yaffs_AllocateRawTnode(yaffs_Device *dev)
167 {
168         yaffs_Allocator *allocator = dev->allocator;
169         if(!allocator || !allocator->tnode_cache){
170                 YBUG();
171                 return NULL;
172         }
173         return kmem_cache_alloc(allocator->tnode_cache, GFP_NOFS);
174 }
175
176 void yaffs_FreeRawTnode(yaffs_Device *dev, yaffs_Tnode *tn)
177 {
178         yaffs_Allocator *allocator = dev->allocator;
179         kmem_cache_free(allocator->tnode_cache,tn);
180 }
181
182 yaffs_Object *yaffs_AllocateRawObject(yaffs_Device *dev)
183 {
184         yaffs_Allocator *allocator = dev->allocator;
185         if(!allocator){
186                 YBUG();
187                 return NULL;
188         }
189         if(!allocator->object_cache){
190                 YBUG();
191                 return NULL;
192         }
193         return kmem_cache_alloc(allocator->object_cache, GFP_NOFS);
194 }
195
196 void yaffs_FreeRawObject(yaffs_Device *dev, yaffs_Object *obj)
197 {
198         yaffs_Allocator *allocator = dev->allocator;
199         kmem_cache_free(allocator->object_cache,obj);
200 }