Blame view
fs/jffs2/malloc.c
7.44 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 |
/* * JFFS2 -- Journalling Flash File System, Version 2. * |
c00c310ea [JFFS2] Tidy up l... |
4 |
* Copyright © 2001-2007 Red Hat, Inc. |
1da177e4c Linux-2.6.12-rc2 |
5 6 7 8 9 |
* * Created by David Woodhouse <dwmw2@infradead.org> * * For licensing information, see the file 'LICENCE' in this directory. * |
1da177e4c Linux-2.6.12-rc2 |
10 11 12 13 14 15 16 |
*/ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/init.h> #include <linux/jffs2.h> #include "nodelist.h" |
1da177e4c Linux-2.6.12-rc2 |
17 18 |
/* These are initialised to NULL in the kernel startup code. If you're porting to other operating systems, beware */ |
e18b890bb [PATCH] slab: rem... |
19 20 21 22 23 24 25 |
static struct kmem_cache *full_dnode_slab; static struct kmem_cache *raw_dirent_slab; static struct kmem_cache *raw_inode_slab; static struct kmem_cache *tmp_dnode_info_slab; static struct kmem_cache *raw_node_ref_slab; static struct kmem_cache *node_frag_slab; static struct kmem_cache *inode_cache_slab; |
aa98d7cf5 [JFFS2][XATTR] XA... |
26 |
#ifdef CONFIG_JFFS2_FS_XATTR |
e18b890bb [PATCH] slab: rem... |
27 28 |
static struct kmem_cache *xattr_datum_cache; static struct kmem_cache *xattr_ref_cache; |
aa98d7cf5 [JFFS2][XATTR] XA... |
29 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
30 31 32 |
int __init jffs2_create_slab_caches(void) { |
182ec4eee [JFFS2] Clean up ... |
33 |
full_dnode_slab = kmem_cache_create("jffs2_full_dnode", |
1da177e4c Linux-2.6.12-rc2 |
34 |
sizeof(struct jffs2_full_dnode), |
20c2df83d mm: Remove slab d... |
35 |
0, 0, NULL); |
1da177e4c Linux-2.6.12-rc2 |
36 37 38 39 40 |
if (!full_dnode_slab) goto err; raw_dirent_slab = kmem_cache_create("jffs2_raw_dirent", sizeof(struct jffs2_raw_dirent), |
dd799983e jffs2: Use SLAB_H... |
41 |
0, SLAB_HWCACHE_ALIGN, NULL); |
1da177e4c Linux-2.6.12-rc2 |
42 43 44 45 46 |
if (!raw_dirent_slab) goto err; raw_inode_slab = kmem_cache_create("jffs2_raw_inode", sizeof(struct jffs2_raw_inode), |
dd799983e jffs2: Use SLAB_H... |
47 |
0, SLAB_HWCACHE_ALIGN, NULL); |
1da177e4c Linux-2.6.12-rc2 |
48 49 50 51 52 |
if (!raw_inode_slab) goto err; tmp_dnode_info_slab = kmem_cache_create("jffs2_tmp_dnode", sizeof(struct jffs2_tmp_dnode_info), |
20c2df83d mm: Remove slab d... |
53 |
0, 0, NULL); |
1da177e4c Linux-2.6.12-rc2 |
54 55 |
if (!tmp_dnode_info_slab) goto err; |
9bfeb691e [JFFS2] Switch to... |
56 57 |
raw_node_ref_slab = kmem_cache_create("jffs2_refblock", sizeof(struct jffs2_raw_node_ref) * (REFS_PER_BLOCK + 1), |
20c2df83d mm: Remove slab d... |
58 |
0, 0, NULL); |
1da177e4c Linux-2.6.12-rc2 |
59 60 61 62 63 |
if (!raw_node_ref_slab) goto err; node_frag_slab = kmem_cache_create("jffs2_node_frag", sizeof(struct jffs2_node_frag), |
20c2df83d mm: Remove slab d... |
64 |
0, 0, NULL); |
1da177e4c Linux-2.6.12-rc2 |
65 66 67 68 69 |
if (!node_frag_slab) goto err; inode_cache_slab = kmem_cache_create("jffs2_inode_cache", sizeof(struct jffs2_inode_cache), |
20c2df83d mm: Remove slab d... |
70 |
0, 0, NULL); |
aa98d7cf5 [JFFS2][XATTR] XA... |
71 72 73 74 75 76 |
if (!inode_cache_slab) goto err; #ifdef CONFIG_JFFS2_FS_XATTR xattr_datum_cache = kmem_cache_create("jffs2_xattr_datum", sizeof(struct jffs2_xattr_datum), |
20c2df83d mm: Remove slab d... |
77 |
0, 0, NULL); |
aa98d7cf5 [JFFS2][XATTR] XA... |
78 79 80 81 82 |
if (!xattr_datum_cache) goto err; xattr_ref_cache = kmem_cache_create("jffs2_xattr_ref", sizeof(struct jffs2_xattr_ref), |
20c2df83d mm: Remove slab d... |
83 |
0, 0, NULL); |
aa98d7cf5 [JFFS2][XATTR] XA... |
84 85 86 87 88 |
if (!xattr_ref_cache) goto err; #endif return 0; |
1da177e4c Linux-2.6.12-rc2 |
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
err: jffs2_destroy_slab_caches(); return -ENOMEM; } void jffs2_destroy_slab_caches(void) { if(full_dnode_slab) kmem_cache_destroy(full_dnode_slab); if(raw_dirent_slab) kmem_cache_destroy(raw_dirent_slab); if(raw_inode_slab) kmem_cache_destroy(raw_inode_slab); if(tmp_dnode_info_slab) kmem_cache_destroy(tmp_dnode_info_slab); if(raw_node_ref_slab) kmem_cache_destroy(raw_node_ref_slab); if(node_frag_slab) kmem_cache_destroy(node_frag_slab); if(inode_cache_slab) kmem_cache_destroy(inode_cache_slab); |
aa98d7cf5 [JFFS2][XATTR] XA... |
110 111 112 113 114 115 |
#ifdef CONFIG_JFFS2_FS_XATTR if (xattr_datum_cache) kmem_cache_destroy(xattr_datum_cache); if (xattr_ref_cache) kmem_cache_destroy(xattr_ref_cache); #endif |
1da177e4c Linux-2.6.12-rc2 |
116 117 118 119 |
} struct jffs2_full_dirent *jffs2_alloc_full_dirent(int namesize) { |
f538c96ba [JFFS2] Debug cod... |
120 121 |
struct jffs2_full_dirent *ret; ret = kmalloc(sizeof(struct jffs2_full_dirent) + namesize, GFP_KERNEL); |
733802d97 [JFFS2] Debug cod... |
122 123 |
dbg_memalloc("%p ", ret); |
f538c96ba [JFFS2] Debug cod... |
124 |
return ret; |
1da177e4c Linux-2.6.12-rc2 |
125 126 127 128 |
} void jffs2_free_full_dirent(struct jffs2_full_dirent *x) { |
733802d97 [JFFS2] Debug cod... |
129 130 |
dbg_memalloc("%p ", x); |
1da177e4c Linux-2.6.12-rc2 |
131 132 133 134 135 |
kfree(x); } struct jffs2_full_dnode *jffs2_alloc_full_dnode(void) { |
f538c96ba [JFFS2] Debug cod... |
136 137 |
struct jffs2_full_dnode *ret; ret = kmem_cache_alloc(full_dnode_slab, GFP_KERNEL); |
733802d97 [JFFS2] Debug cod... |
138 139 |
dbg_memalloc("%p ", ret); |
1da177e4c Linux-2.6.12-rc2 |
140 141 142 143 144 |
return ret; } void jffs2_free_full_dnode(struct jffs2_full_dnode *x) { |
733802d97 [JFFS2] Debug cod... |
145 146 |
dbg_memalloc("%p ", x); |
1da177e4c Linux-2.6.12-rc2 |
147 148 149 150 151 |
kmem_cache_free(full_dnode_slab, x); } struct jffs2_raw_dirent *jffs2_alloc_raw_dirent(void) { |
f538c96ba [JFFS2] Debug cod... |
152 153 |
struct jffs2_raw_dirent *ret; ret = kmem_cache_alloc(raw_dirent_slab, GFP_KERNEL); |
733802d97 [JFFS2] Debug cod... |
154 155 |
dbg_memalloc("%p ", ret); |
1da177e4c Linux-2.6.12-rc2 |
156 157 158 159 160 |
return ret; } void jffs2_free_raw_dirent(struct jffs2_raw_dirent *x) { |
733802d97 [JFFS2] Debug cod... |
161 162 |
dbg_memalloc("%p ", x); |
1da177e4c Linux-2.6.12-rc2 |
163 164 165 166 167 |
kmem_cache_free(raw_dirent_slab, x); } struct jffs2_raw_inode *jffs2_alloc_raw_inode(void) { |
f538c96ba [JFFS2] Debug cod... |
168 169 |
struct jffs2_raw_inode *ret; ret = kmem_cache_alloc(raw_inode_slab, GFP_KERNEL); |
733802d97 [JFFS2] Debug cod... |
170 171 |
dbg_memalloc("%p ", ret); |
1da177e4c Linux-2.6.12-rc2 |
172 173 174 175 176 |
return ret; } void jffs2_free_raw_inode(struct jffs2_raw_inode *x) { |
733802d97 [JFFS2] Debug cod... |
177 178 |
dbg_memalloc("%p ", x); |
1da177e4c Linux-2.6.12-rc2 |
179 180 181 182 183 |
kmem_cache_free(raw_inode_slab, x); } struct jffs2_tmp_dnode_info *jffs2_alloc_tmp_dnode_info(void) { |
f538c96ba [JFFS2] Debug cod... |
184 185 |
struct jffs2_tmp_dnode_info *ret; ret = kmem_cache_alloc(tmp_dnode_info_slab, GFP_KERNEL); |
733802d97 [JFFS2] Debug cod... |
186 187 |
dbg_memalloc("%p ", |
f538c96ba [JFFS2] Debug cod... |
188 |
ret); |
1da177e4c Linux-2.6.12-rc2 |
189 190 191 192 193 |
return ret; } void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *x) { |
733802d97 [JFFS2] Debug cod... |
194 195 |
dbg_memalloc("%p ", x); |
1da177e4c Linux-2.6.12-rc2 |
196 197 |
kmem_cache_free(tmp_dnode_info_slab, x); } |
c05d52c74 fs/jffs2/: make 2... |
198 |
static struct jffs2_raw_node_ref *jffs2_alloc_refblock(void) |
9bfeb691e [JFFS2] Switch to... |
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
{ struct jffs2_raw_node_ref *ret; ret = kmem_cache_alloc(raw_node_ref_slab, GFP_KERNEL); if (ret) { int i = 0; for (i=0; i < REFS_PER_BLOCK; i++) { ret[i].flash_offset = REF_EMPTY_NODE; ret[i].next_in_ino = NULL; } ret[i].flash_offset = REF_LINK_NODE; ret[i].next_in_ino = NULL; } return ret; } |
046b8b980 [JFFS2] Add 'jeb'... |
214 215 |
int jffs2_prealloc_raw_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, int nr) |
2f785402f [JFFS2] Reduce vi... |
216 |
{ |
9bfeb691e [JFFS2] Switch to... |
217 218 |
struct jffs2_raw_node_ref **p, *ref; int i = nr; |
2f785402f [JFFS2] Reduce vi... |
219 220 221 |
dbg_memalloc("%d ", nr); |
9bfeb691e [JFFS2] Switch to... |
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
p = &jeb->last_node; ref = *p; dbg_memalloc("Reserving %d refs for block @0x%08x ", nr, jeb->offset); /* If jeb->last_node is really a valid node then skip over it */ if (ref && ref->flash_offset != REF_EMPTY_NODE) ref++; while (i) { if (!ref) { dbg_memalloc("Allocating new refblock linked from %p ", p); ref = *p = jffs2_alloc_refblock(); if (!ref) return -ENOMEM; } if (ref->flash_offset == REF_LINK_NODE) { p = &ref->next_in_ino; ref = *p; continue; } i--; ref++; |
2f785402f [JFFS2] Reduce vi... |
247 |
} |
9bfeb691e [JFFS2] Switch to... |
248 |
jeb->allocated_refs = nr; |
2f785402f [JFFS2] Reduce vi... |
249 |
|
9bfeb691e [JFFS2] Switch to... |
250 251 252 253 254 255 |
dbg_memalloc("Reserved %d refs for block @0x%08x, last_node is %p (%08x,%p) ", nr, jeb->offset, jeb->last_node, jeb->last_node->flash_offset, jeb->last_node->next_in_ino); return 0; |
1da177e4c Linux-2.6.12-rc2 |
256 |
} |
9bfeb691e [JFFS2] Switch to... |
257 |
void jffs2_free_refblock(struct jffs2_raw_node_ref *x) |
1da177e4c Linux-2.6.12-rc2 |
258 |
{ |
733802d97 [JFFS2] Debug cod... |
259 260 |
dbg_memalloc("%p ", x); |
1da177e4c Linux-2.6.12-rc2 |
261 262 263 264 265 |
kmem_cache_free(raw_node_ref_slab, x); } struct jffs2_node_frag *jffs2_alloc_node_frag(void) { |
f538c96ba [JFFS2] Debug cod... |
266 267 |
struct jffs2_node_frag *ret; ret = kmem_cache_alloc(node_frag_slab, GFP_KERNEL); |
733802d97 [JFFS2] Debug cod... |
268 269 |
dbg_memalloc("%p ", ret); |
1da177e4c Linux-2.6.12-rc2 |
270 271 272 273 274 |
return ret; } void jffs2_free_node_frag(struct jffs2_node_frag *x) { |
733802d97 [JFFS2] Debug cod... |
275 276 |
dbg_memalloc("%p ", x); |
1da177e4c Linux-2.6.12-rc2 |
277 278 279 280 281 |
kmem_cache_free(node_frag_slab, x); } struct jffs2_inode_cache *jffs2_alloc_inode_cache(void) { |
f538c96ba [JFFS2] Debug cod... |
282 283 |
struct jffs2_inode_cache *ret; ret = kmem_cache_alloc(inode_cache_slab, GFP_KERNEL); |
733802d97 [JFFS2] Debug cod... |
284 285 |
dbg_memalloc("%p ", ret); |
1da177e4c Linux-2.6.12-rc2 |
286 287 288 289 290 |
return ret; } void jffs2_free_inode_cache(struct jffs2_inode_cache *x) { |
733802d97 [JFFS2] Debug cod... |
291 292 |
dbg_memalloc("%p ", x); |
1da177e4c Linux-2.6.12-rc2 |
293 294 |
kmem_cache_free(inode_cache_slab, x); } |
aa98d7cf5 [JFFS2][XATTR] XA... |
295 296 297 298 299 |
#ifdef CONFIG_JFFS2_FS_XATTR struct jffs2_xattr_datum *jffs2_alloc_xattr_datum(void) { struct jffs2_xattr_datum *xd; |
c6d59cdd4 [JFFS2] kmem_cach... |
300 |
xd = kmem_cache_zalloc(xattr_datum_cache, GFP_KERNEL); |
aa98d7cf5 [JFFS2][XATTR] XA... |
301 302 |
dbg_memalloc("%p ", xd); |
aa98d7cf5 [JFFS2][XATTR] XA... |
303 |
xd->class = RAWNODE_CLASS_XATTR_DATUM; |
c9f700f84 [JFFS2][XATTR] us... |
304 |
xd->node = (void *)xd; |
aa98d7cf5 [JFFS2][XATTR] XA... |
305 306 307 308 309 310 311 312 313 314 315 316 317 318 |
INIT_LIST_HEAD(&xd->xindex); return xd; } void jffs2_free_xattr_datum(struct jffs2_xattr_datum *xd) { dbg_memalloc("%p ", xd); kmem_cache_free(xattr_datum_cache, xd); } struct jffs2_xattr_ref *jffs2_alloc_xattr_ref(void) { struct jffs2_xattr_ref *ref; |
c6d59cdd4 [JFFS2] kmem_cach... |
319 |
ref = kmem_cache_zalloc(xattr_ref_cache, GFP_KERNEL); |
aa98d7cf5 [JFFS2][XATTR] XA... |
320 321 |
dbg_memalloc("%p ", ref); |
aa98d7cf5 [JFFS2][XATTR] XA... |
322 |
ref->class = RAWNODE_CLASS_XATTR_REF; |
c9f700f84 [JFFS2][XATTR] us... |
323 |
ref->node = (void *)ref; |
aa98d7cf5 [JFFS2][XATTR] XA... |
324 325 326 327 328 329 330 331 332 333 |
return ref; } void jffs2_free_xattr_ref(struct jffs2_xattr_ref *ref) { dbg_memalloc("%p ", ref); kmem_cache_free(xattr_ref_cache, ref); } #endif |