malloc.c 6.8 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9
/*
 * JFFS2 -- Journalling Flash File System, Version 2.
 *
 * Copyright (C) 2001-2003 Red Hat, Inc.
 *
 * Created by David Woodhouse <dwmw2@infradead.org>
 *
 * For licensing information, see the file 'LICENCE' in this directory.
 *
10
 * $Id: malloc.c,v 1.31 2005/11/07 11:14:40 gleixner Exp $
L
Linus Torvalds 已提交
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
 *
 */

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/jffs2.h>
#include "nodelist.h"

/* These are initialised to NULL in the kernel startup code.
   If you're porting to other operating systems, beware */
static kmem_cache_t *full_dnode_slab;
static kmem_cache_t *raw_dirent_slab;
static kmem_cache_t *raw_inode_slab;
static kmem_cache_t *tmp_dnode_info_slab;
static kmem_cache_t *raw_node_ref_slab;
static kmem_cache_t *node_frag_slab;
static kmem_cache_t *inode_cache_slab;
29 30 31 32
#ifdef CONFIG_JFFS2_FS_XATTR
static kmem_cache_t *xattr_datum_cache;
static kmem_cache_t *xattr_ref_cache;
#endif
L
Linus Torvalds 已提交
33 34 35

int __init jffs2_create_slab_caches(void)
{
36
	full_dnode_slab = kmem_cache_create("jffs2_full_dnode",
L
Linus Torvalds 已提交
37
					    sizeof(struct jffs2_full_dnode),
38
					    0, 0, NULL, NULL);
L
Linus Torvalds 已提交
39 40 41 42 43
	if (!full_dnode_slab)
		goto err;

	raw_dirent_slab = kmem_cache_create("jffs2_raw_dirent",
					    sizeof(struct jffs2_raw_dirent),
44
					    0, 0, NULL, NULL);
L
Linus Torvalds 已提交
45 46 47 48 49
	if (!raw_dirent_slab)
		goto err;

	raw_inode_slab = kmem_cache_create("jffs2_raw_inode",
					   sizeof(struct jffs2_raw_inode),
50
					   0, 0, NULL, NULL);
L
Linus Torvalds 已提交
51 52 53 54 55
	if (!raw_inode_slab)
		goto err;

	tmp_dnode_info_slab = kmem_cache_create("jffs2_tmp_dnode",
						sizeof(struct jffs2_tmp_dnode_info),
56
						0, 0, NULL, NULL);
L
Linus Torvalds 已提交
57 58 59 60 61
	if (!tmp_dnode_info_slab)
		goto err;

	raw_node_ref_slab = kmem_cache_create("jffs2_raw_node_ref",
					      sizeof(struct jffs2_raw_node_ref),
62
					      0, 0, NULL, NULL);
L
Linus Torvalds 已提交
63 64 65 66 67
	if (!raw_node_ref_slab)
		goto err;

	node_frag_slab = kmem_cache_create("jffs2_node_frag",
					   sizeof(struct jffs2_node_frag),
68
					   0, 0, NULL, NULL);
L
Linus Torvalds 已提交
69 70 71 72 73
	if (!node_frag_slab)
		goto err;

	inode_cache_slab = kmem_cache_create("jffs2_inode_cache",
					     sizeof(struct jffs2_inode_cache),
74
					     0, 0, NULL, NULL);
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
	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),
					     0, 0, NULL, NULL);
	if (!xattr_datum_cache)
		goto err;

	xattr_ref_cache = kmem_cache_create("jffs2_xattr_ref",
					   sizeof(struct jffs2_xattr_ref),
					   0, 0, NULL, NULL);
	if (!xattr_ref_cache)
		goto err;
#endif

	return 0;
L
Linus Torvalds 已提交
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
 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);
114 115 116 117 118 119
#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
L
Linus Torvalds 已提交
120 121 122 123
}

struct jffs2_full_dirent *jffs2_alloc_full_dirent(int namesize)
{
124 125
	struct jffs2_full_dirent *ret;
	ret = kmalloc(sizeof(struct jffs2_full_dirent) + namesize, GFP_KERNEL);
126
	dbg_memalloc("%p\n", ret);
127
	return ret;
L
Linus Torvalds 已提交
128 129 130 131
}

void jffs2_free_full_dirent(struct jffs2_full_dirent *x)
{
132
	dbg_memalloc("%p\n", x);
L
Linus Torvalds 已提交
133 134 135 136 137
	kfree(x);
}

struct jffs2_full_dnode *jffs2_alloc_full_dnode(void)
{
138 139
	struct jffs2_full_dnode *ret;
	ret = kmem_cache_alloc(full_dnode_slab, GFP_KERNEL);
140
	dbg_memalloc("%p\n", ret);
L
Linus Torvalds 已提交
141 142 143 144 145
	return ret;
}

void jffs2_free_full_dnode(struct jffs2_full_dnode *x)
{
146
	dbg_memalloc("%p\n", x);
L
Linus Torvalds 已提交
147 148 149 150 151
	kmem_cache_free(full_dnode_slab, x);
}

struct jffs2_raw_dirent *jffs2_alloc_raw_dirent(void)
{
152 153
	struct jffs2_raw_dirent *ret;
	ret = kmem_cache_alloc(raw_dirent_slab, GFP_KERNEL);
154
	dbg_memalloc("%p\n", ret);
L
Linus Torvalds 已提交
155 156 157 158 159
	return ret;
}

void jffs2_free_raw_dirent(struct jffs2_raw_dirent *x)
{
160
	dbg_memalloc("%p\n", x);
L
Linus Torvalds 已提交
161 162 163 164 165
	kmem_cache_free(raw_dirent_slab, x);
}

struct jffs2_raw_inode *jffs2_alloc_raw_inode(void)
{
166 167
	struct jffs2_raw_inode *ret;
	ret = kmem_cache_alloc(raw_inode_slab, GFP_KERNEL);
168
	dbg_memalloc("%p\n", ret);
L
Linus Torvalds 已提交
169 170 171 172 173
	return ret;
}

void jffs2_free_raw_inode(struct jffs2_raw_inode *x)
{
174
	dbg_memalloc("%p\n", x);
L
Linus Torvalds 已提交
175 176 177 178 179
	kmem_cache_free(raw_inode_slab, x);
}

struct jffs2_tmp_dnode_info *jffs2_alloc_tmp_dnode_info(void)
{
180 181
	struct jffs2_tmp_dnode_info *ret;
	ret = kmem_cache_alloc(tmp_dnode_info_slab, GFP_KERNEL);
182
	dbg_memalloc("%p\n",
183
		ret);
L
Linus Torvalds 已提交
184 185 186 187 188
	return ret;
}

void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *x)
{
189
	dbg_memalloc("%p\n", x);
L
Linus Torvalds 已提交
190 191 192
	kmem_cache_free(tmp_dnode_info_slab, x);
}

193 194
int jffs2_prealloc_raw_node_refs(struct jffs2_sb_info *c,
				 struct jffs2_eraseblock *jeb, int nr)
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
{
	struct jffs2_raw_node_ref *p = c->refs;

	dbg_memalloc("%d\n", nr);

	while (nr && p) {
		p = p->next_in_ino;
		nr--;
	}
	while (nr) {
		p = __jffs2_alloc_raw_node_ref();
		if (!p)
			return -ENOMEM;
		p->next_in_ino = c->refs;
		c->refs = p;
		nr--;
	}
	c->reserved_refs = nr;
	return 0;
}

struct jffs2_raw_node_ref *__jffs2_alloc_raw_node_ref(void)
L
Linus Torvalds 已提交
217
{
218 219
	struct jffs2_raw_node_ref *ret;
	ret = kmem_cache_alloc(raw_node_ref_slab, GFP_KERNEL);
220
	dbg_memalloc("%p\n", ret);
L
Linus Torvalds 已提交
221 222 223
	return ret;
}

224
void __jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *x)
L
Linus Torvalds 已提交
225
{
226
	dbg_memalloc("%p\n", x);
L
Linus Torvalds 已提交
227 228 229 230 231
	kmem_cache_free(raw_node_ref_slab, x);
}

struct jffs2_node_frag *jffs2_alloc_node_frag(void)
{
232 233
	struct jffs2_node_frag *ret;
	ret = kmem_cache_alloc(node_frag_slab, GFP_KERNEL);
234
	dbg_memalloc("%p\n", ret);
L
Linus Torvalds 已提交
235 236 237 238 239
	return ret;
}

void jffs2_free_node_frag(struct jffs2_node_frag *x)
{
240
	dbg_memalloc("%p\n", x);
L
Linus Torvalds 已提交
241 242 243 244 245
	kmem_cache_free(node_frag_slab, x);
}

struct jffs2_inode_cache *jffs2_alloc_inode_cache(void)
{
246 247
	struct jffs2_inode_cache *ret;
	ret = kmem_cache_alloc(inode_cache_slab, GFP_KERNEL);
248
	dbg_memalloc("%p\n", ret);
L
Linus Torvalds 已提交
249 250 251 252 253
	return ret;
}

void jffs2_free_inode_cache(struct jffs2_inode_cache *x)
{
254
	dbg_memalloc("%p\n", x);
L
Linus Torvalds 已提交
255 256
	kmem_cache_free(inode_cache_slab, x);
}
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293

#ifdef CONFIG_JFFS2_FS_XATTR
struct jffs2_xattr_datum *jffs2_alloc_xattr_datum(void)
{
	struct jffs2_xattr_datum *xd;
	xd = kmem_cache_alloc(xattr_datum_cache, GFP_KERNEL);
	dbg_memalloc("%p\n", xd);

	memset(xd, 0, sizeof(struct jffs2_xattr_datum));
	xd->class = RAWNODE_CLASS_XATTR_DATUM;
	INIT_LIST_HEAD(&xd->xindex);
	return xd;
}

void jffs2_free_xattr_datum(struct jffs2_xattr_datum *xd)
{
	dbg_memalloc("%p\n", xd);
	kmem_cache_free(xattr_datum_cache, xd);
}

struct jffs2_xattr_ref *jffs2_alloc_xattr_ref(void)
{
	struct jffs2_xattr_ref *ref;
	ref = kmem_cache_alloc(xattr_ref_cache, GFP_KERNEL);
	dbg_memalloc("%p\n", ref);

	memset(ref, 0, sizeof(struct jffs2_xattr_ref));
	ref->class = RAWNODE_CLASS_XATTR_REF;
	return ref;
}

void jffs2_free_xattr_ref(struct jffs2_xattr_ref *ref)
{
	dbg_memalloc("%p\n", ref);
	kmem_cache_free(xattr_ref_cache, ref);
}
#endif