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