11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * JFFS2 -- Journalling Flash File System, Version 2. 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Copyright (C) 2001-2003 Red Hat, Inc. 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * Created by David Woodhouse <dwmw2@infradead.org> 71da177e4SLinus Torvalds * 81da177e4SLinus Torvalds * For licensing information, see the file 'LICENCE' in this directory. 91da177e4SLinus Torvalds * 10182ec4eeSThomas Gleixner * $Id: malloc.c,v 1.31 2005/11/07 11:14:40 gleixner Exp $ 111da177e4SLinus Torvalds * 121da177e4SLinus Torvalds */ 131da177e4SLinus Torvalds 141da177e4SLinus Torvalds #include <linux/kernel.h> 151da177e4SLinus Torvalds #include <linux/slab.h> 161da177e4SLinus Torvalds #include <linux/init.h> 171da177e4SLinus Torvalds #include <linux/jffs2.h> 181da177e4SLinus Torvalds #include "nodelist.h" 191da177e4SLinus Torvalds 201da177e4SLinus Torvalds /* These are initialised to NULL in the kernel startup code. 211da177e4SLinus Torvalds If you're porting to other operating systems, beware */ 221da177e4SLinus Torvalds static kmem_cache_t *full_dnode_slab; 231da177e4SLinus Torvalds static kmem_cache_t *raw_dirent_slab; 241da177e4SLinus Torvalds static kmem_cache_t *raw_inode_slab; 251da177e4SLinus Torvalds static kmem_cache_t *tmp_dnode_info_slab; 261da177e4SLinus Torvalds static kmem_cache_t *raw_node_ref_slab; 271da177e4SLinus Torvalds static kmem_cache_t *node_frag_slab; 281da177e4SLinus Torvalds static kmem_cache_t *inode_cache_slab; 29aa98d7cfSKaiGai Kohei #ifdef CONFIG_JFFS2_FS_XATTR 30aa98d7cfSKaiGai Kohei static kmem_cache_t *xattr_datum_cache; 31aa98d7cfSKaiGai Kohei static kmem_cache_t *xattr_ref_cache; 32aa98d7cfSKaiGai Kohei #endif 331da177e4SLinus Torvalds 341da177e4SLinus Torvalds int __init jffs2_create_slab_caches(void) 351da177e4SLinus Torvalds { 361da177e4SLinus Torvalds full_dnode_slab = kmem_cache_create("jffs2_full_dnode", 371da177e4SLinus Torvalds sizeof(struct jffs2_full_dnode), 38f538c96bSArtem B. Bityutskiy 0, 0, NULL, NULL); 391da177e4SLinus Torvalds if (!full_dnode_slab) 401da177e4SLinus Torvalds goto err; 411da177e4SLinus Torvalds 421da177e4SLinus Torvalds raw_dirent_slab = kmem_cache_create("jffs2_raw_dirent", 431da177e4SLinus Torvalds sizeof(struct jffs2_raw_dirent), 44f538c96bSArtem B. Bityutskiy 0, 0, NULL, NULL); 451da177e4SLinus Torvalds if (!raw_dirent_slab) 461da177e4SLinus Torvalds goto err; 471da177e4SLinus Torvalds 481da177e4SLinus Torvalds raw_inode_slab = kmem_cache_create("jffs2_raw_inode", 491da177e4SLinus Torvalds sizeof(struct jffs2_raw_inode), 50f538c96bSArtem B. Bityutskiy 0, 0, NULL, NULL); 511da177e4SLinus Torvalds if (!raw_inode_slab) 521da177e4SLinus Torvalds goto err; 531da177e4SLinus Torvalds 541da177e4SLinus Torvalds tmp_dnode_info_slab = kmem_cache_create("jffs2_tmp_dnode", 551da177e4SLinus Torvalds sizeof(struct jffs2_tmp_dnode_info), 56f538c96bSArtem B. Bityutskiy 0, 0, NULL, NULL); 571da177e4SLinus Torvalds if (!tmp_dnode_info_slab) 581da177e4SLinus Torvalds goto err; 591da177e4SLinus Torvalds 601da177e4SLinus Torvalds raw_node_ref_slab = kmem_cache_create("jffs2_raw_node_ref", 611da177e4SLinus Torvalds sizeof(struct jffs2_raw_node_ref), 62f538c96bSArtem B. Bityutskiy 0, 0, NULL, NULL); 631da177e4SLinus Torvalds if (!raw_node_ref_slab) 641da177e4SLinus Torvalds goto err; 651da177e4SLinus Torvalds 661da177e4SLinus Torvalds node_frag_slab = kmem_cache_create("jffs2_node_frag", 671da177e4SLinus Torvalds sizeof(struct jffs2_node_frag), 68f538c96bSArtem B. Bityutskiy 0, 0, NULL, NULL); 691da177e4SLinus Torvalds if (!node_frag_slab) 701da177e4SLinus Torvalds goto err; 711da177e4SLinus Torvalds 721da177e4SLinus Torvalds inode_cache_slab = kmem_cache_create("jffs2_inode_cache", 731da177e4SLinus Torvalds sizeof(struct jffs2_inode_cache), 74f538c96bSArtem B. Bityutskiy 0, 0, NULL, NULL); 75aa98d7cfSKaiGai Kohei if (!inode_cache_slab) 76aa98d7cfSKaiGai Kohei goto err; 77aa98d7cfSKaiGai Kohei 78aa98d7cfSKaiGai Kohei #ifdef CONFIG_JFFS2_FS_XATTR 79aa98d7cfSKaiGai Kohei xattr_datum_cache = kmem_cache_create("jffs2_xattr_datum", 80aa98d7cfSKaiGai Kohei sizeof(struct jffs2_xattr_datum), 81aa98d7cfSKaiGai Kohei 0, 0, NULL, NULL); 82aa98d7cfSKaiGai Kohei if (!xattr_datum_cache) 83aa98d7cfSKaiGai Kohei goto err; 84aa98d7cfSKaiGai Kohei 85aa98d7cfSKaiGai Kohei xattr_ref_cache = kmem_cache_create("jffs2_xattr_ref", 86aa98d7cfSKaiGai Kohei sizeof(struct jffs2_xattr_ref), 87aa98d7cfSKaiGai Kohei 0, 0, NULL, NULL); 88aa98d7cfSKaiGai Kohei if (!xattr_ref_cache) 89aa98d7cfSKaiGai Kohei goto err; 90aa98d7cfSKaiGai Kohei #endif 91aa98d7cfSKaiGai Kohei 921da177e4SLinus Torvalds return 0; 931da177e4SLinus Torvalds err: 941da177e4SLinus Torvalds jffs2_destroy_slab_caches(); 951da177e4SLinus Torvalds return -ENOMEM; 961da177e4SLinus Torvalds } 971da177e4SLinus Torvalds 981da177e4SLinus Torvalds void jffs2_destroy_slab_caches(void) 991da177e4SLinus Torvalds { 1001da177e4SLinus Torvalds if(full_dnode_slab) 1011da177e4SLinus Torvalds kmem_cache_destroy(full_dnode_slab); 1021da177e4SLinus Torvalds if(raw_dirent_slab) 1031da177e4SLinus Torvalds kmem_cache_destroy(raw_dirent_slab); 1041da177e4SLinus Torvalds if(raw_inode_slab) 1051da177e4SLinus Torvalds kmem_cache_destroy(raw_inode_slab); 1061da177e4SLinus Torvalds if(tmp_dnode_info_slab) 1071da177e4SLinus Torvalds kmem_cache_destroy(tmp_dnode_info_slab); 1081da177e4SLinus Torvalds if(raw_node_ref_slab) 1091da177e4SLinus Torvalds kmem_cache_destroy(raw_node_ref_slab); 1101da177e4SLinus Torvalds if(node_frag_slab) 1111da177e4SLinus Torvalds kmem_cache_destroy(node_frag_slab); 1121da177e4SLinus Torvalds if(inode_cache_slab) 1131da177e4SLinus Torvalds kmem_cache_destroy(inode_cache_slab); 114aa98d7cfSKaiGai Kohei #ifdef CONFIG_JFFS2_FS_XATTR 115aa98d7cfSKaiGai Kohei if (xattr_datum_cache) 116aa98d7cfSKaiGai Kohei kmem_cache_destroy(xattr_datum_cache); 117aa98d7cfSKaiGai Kohei if (xattr_ref_cache) 118aa98d7cfSKaiGai Kohei kmem_cache_destroy(xattr_ref_cache); 119aa98d7cfSKaiGai Kohei #endif 1201da177e4SLinus Torvalds } 1211da177e4SLinus Torvalds 1221da177e4SLinus Torvalds struct jffs2_full_dirent *jffs2_alloc_full_dirent(int namesize) 1231da177e4SLinus Torvalds { 124f538c96bSArtem B. Bityutskiy struct jffs2_full_dirent *ret; 125f538c96bSArtem B. Bityutskiy ret = kmalloc(sizeof(struct jffs2_full_dirent) + namesize, GFP_KERNEL); 126733802d9SArtem B. Bityutskiy dbg_memalloc("%p\n", ret); 127f538c96bSArtem B. Bityutskiy return ret; 1281da177e4SLinus Torvalds } 1291da177e4SLinus Torvalds 1301da177e4SLinus Torvalds void jffs2_free_full_dirent(struct jffs2_full_dirent *x) 1311da177e4SLinus Torvalds { 132733802d9SArtem B. Bityutskiy dbg_memalloc("%p\n", x); 1331da177e4SLinus Torvalds kfree(x); 1341da177e4SLinus Torvalds } 1351da177e4SLinus Torvalds 1361da177e4SLinus Torvalds struct jffs2_full_dnode *jffs2_alloc_full_dnode(void) 1371da177e4SLinus Torvalds { 138f538c96bSArtem B. Bityutskiy struct jffs2_full_dnode *ret; 139f538c96bSArtem B. Bityutskiy ret = kmem_cache_alloc(full_dnode_slab, GFP_KERNEL); 140733802d9SArtem B. Bityutskiy dbg_memalloc("%p\n", ret); 1411da177e4SLinus Torvalds return ret; 1421da177e4SLinus Torvalds } 1431da177e4SLinus Torvalds 1441da177e4SLinus Torvalds void jffs2_free_full_dnode(struct jffs2_full_dnode *x) 1451da177e4SLinus Torvalds { 146733802d9SArtem B. Bityutskiy dbg_memalloc("%p\n", x); 1471da177e4SLinus Torvalds kmem_cache_free(full_dnode_slab, x); 1481da177e4SLinus Torvalds } 1491da177e4SLinus Torvalds 1501da177e4SLinus Torvalds struct jffs2_raw_dirent *jffs2_alloc_raw_dirent(void) 1511da177e4SLinus Torvalds { 152f538c96bSArtem B. Bityutskiy struct jffs2_raw_dirent *ret; 153f538c96bSArtem B. Bityutskiy ret = kmem_cache_alloc(raw_dirent_slab, GFP_KERNEL); 154733802d9SArtem B. Bityutskiy dbg_memalloc("%p\n", ret); 1551da177e4SLinus Torvalds return ret; 1561da177e4SLinus Torvalds } 1571da177e4SLinus Torvalds 1581da177e4SLinus Torvalds void jffs2_free_raw_dirent(struct jffs2_raw_dirent *x) 1591da177e4SLinus Torvalds { 160733802d9SArtem B. Bityutskiy dbg_memalloc("%p\n", x); 1611da177e4SLinus Torvalds kmem_cache_free(raw_dirent_slab, x); 1621da177e4SLinus Torvalds } 1631da177e4SLinus Torvalds 1641da177e4SLinus Torvalds struct jffs2_raw_inode *jffs2_alloc_raw_inode(void) 1651da177e4SLinus Torvalds { 166f538c96bSArtem B. Bityutskiy struct jffs2_raw_inode *ret; 167f538c96bSArtem B. Bityutskiy ret = kmem_cache_alloc(raw_inode_slab, GFP_KERNEL); 168733802d9SArtem B. Bityutskiy dbg_memalloc("%p\n", ret); 1691da177e4SLinus Torvalds return ret; 1701da177e4SLinus Torvalds } 1711da177e4SLinus Torvalds 1721da177e4SLinus Torvalds void jffs2_free_raw_inode(struct jffs2_raw_inode *x) 1731da177e4SLinus Torvalds { 174733802d9SArtem B. Bityutskiy dbg_memalloc("%p\n", x); 1751da177e4SLinus Torvalds kmem_cache_free(raw_inode_slab, x); 1761da177e4SLinus Torvalds } 1771da177e4SLinus Torvalds 1781da177e4SLinus Torvalds struct jffs2_tmp_dnode_info *jffs2_alloc_tmp_dnode_info(void) 1791da177e4SLinus Torvalds { 180f538c96bSArtem B. Bityutskiy struct jffs2_tmp_dnode_info *ret; 181f538c96bSArtem B. Bityutskiy ret = kmem_cache_alloc(tmp_dnode_info_slab, GFP_KERNEL); 182733802d9SArtem B. Bityutskiy dbg_memalloc("%p\n", 183f538c96bSArtem B. Bityutskiy ret); 1841da177e4SLinus Torvalds return ret; 1851da177e4SLinus Torvalds } 1861da177e4SLinus Torvalds 1871da177e4SLinus Torvalds void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *x) 1881da177e4SLinus Torvalds { 189733802d9SArtem B. Bityutskiy dbg_memalloc("%p\n", x); 1901da177e4SLinus Torvalds kmem_cache_free(tmp_dnode_info_slab, x); 1911da177e4SLinus Torvalds } 1921da177e4SLinus Torvalds 1931da177e4SLinus Torvalds struct jffs2_raw_node_ref *jffs2_alloc_raw_node_ref(void) 1941da177e4SLinus Torvalds { 195f538c96bSArtem B. Bityutskiy struct jffs2_raw_node_ref *ret; 196f538c96bSArtem B. Bityutskiy ret = kmem_cache_alloc(raw_node_ref_slab, GFP_KERNEL); 197733802d9SArtem B. Bityutskiy dbg_memalloc("%p\n", ret); 1981da177e4SLinus Torvalds return ret; 1991da177e4SLinus Torvalds } 2001da177e4SLinus Torvalds 2011da177e4SLinus Torvalds void jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *x) 2021da177e4SLinus Torvalds { 203733802d9SArtem B. Bityutskiy dbg_memalloc("%p\n", x); 2041da177e4SLinus Torvalds kmem_cache_free(raw_node_ref_slab, x); 2051da177e4SLinus Torvalds } 2061da177e4SLinus Torvalds 2071da177e4SLinus Torvalds struct jffs2_node_frag *jffs2_alloc_node_frag(void) 2081da177e4SLinus Torvalds { 209f538c96bSArtem B. Bityutskiy struct jffs2_node_frag *ret; 210f538c96bSArtem B. Bityutskiy ret = kmem_cache_alloc(node_frag_slab, GFP_KERNEL); 211733802d9SArtem B. Bityutskiy dbg_memalloc("%p\n", ret); 2121da177e4SLinus Torvalds return ret; 2131da177e4SLinus Torvalds } 2141da177e4SLinus Torvalds 2151da177e4SLinus Torvalds void jffs2_free_node_frag(struct jffs2_node_frag *x) 2161da177e4SLinus Torvalds { 217733802d9SArtem B. Bityutskiy dbg_memalloc("%p\n", x); 2181da177e4SLinus Torvalds kmem_cache_free(node_frag_slab, x); 2191da177e4SLinus Torvalds } 2201da177e4SLinus Torvalds 2211da177e4SLinus Torvalds struct jffs2_inode_cache *jffs2_alloc_inode_cache(void) 2221da177e4SLinus Torvalds { 223f538c96bSArtem B. Bityutskiy struct jffs2_inode_cache *ret; 224f538c96bSArtem B. Bityutskiy ret = kmem_cache_alloc(inode_cache_slab, GFP_KERNEL); 225733802d9SArtem B. Bityutskiy dbg_memalloc("%p\n", ret); 2261da177e4SLinus Torvalds return ret; 2271da177e4SLinus Torvalds } 2281da177e4SLinus Torvalds 2291da177e4SLinus Torvalds void jffs2_free_inode_cache(struct jffs2_inode_cache *x) 2301da177e4SLinus Torvalds { 231733802d9SArtem B. Bityutskiy dbg_memalloc("%p\n", x); 2321da177e4SLinus Torvalds kmem_cache_free(inode_cache_slab, x); 2331da177e4SLinus Torvalds } 234aa98d7cfSKaiGai Kohei 235aa98d7cfSKaiGai Kohei #ifdef CONFIG_JFFS2_FS_XATTR 236aa98d7cfSKaiGai Kohei struct jffs2_xattr_datum *jffs2_alloc_xattr_datum(void) 237aa98d7cfSKaiGai Kohei { 238aa98d7cfSKaiGai Kohei struct jffs2_xattr_datum *xd; 239aa98d7cfSKaiGai Kohei xd = kmem_cache_alloc(xattr_datum_cache, GFP_KERNEL); 240aa98d7cfSKaiGai Kohei dbg_memalloc("%p\n", xd); 241aa98d7cfSKaiGai Kohei 242aa98d7cfSKaiGai Kohei memset(xd, 0, sizeof(struct jffs2_xattr_datum)); 243aa98d7cfSKaiGai Kohei xd->class = RAWNODE_CLASS_XATTR_DATUM; 244aa98d7cfSKaiGai Kohei INIT_LIST_HEAD(&xd->xindex); 245aa98d7cfSKaiGai Kohei return xd; 246aa98d7cfSKaiGai Kohei } 247aa98d7cfSKaiGai Kohei 248aa98d7cfSKaiGai Kohei void jffs2_free_xattr_datum(struct jffs2_xattr_datum *xd) 249aa98d7cfSKaiGai Kohei { 250aa98d7cfSKaiGai Kohei dbg_memalloc("%p\n", xd); 251aa98d7cfSKaiGai Kohei kmem_cache_free(xattr_datum_cache, xd); 252aa98d7cfSKaiGai Kohei } 253aa98d7cfSKaiGai Kohei 254aa98d7cfSKaiGai Kohei struct jffs2_xattr_ref *jffs2_alloc_xattr_ref(void) 255aa98d7cfSKaiGai Kohei { 256aa98d7cfSKaiGai Kohei struct jffs2_xattr_ref *ref; 257aa98d7cfSKaiGai Kohei ref = kmem_cache_alloc(xattr_ref_cache, GFP_KERNEL); 258aa98d7cfSKaiGai Kohei dbg_memalloc("%p\n", ref); 259aa98d7cfSKaiGai Kohei 260aa98d7cfSKaiGai Kohei memset(ref, 0, sizeof(struct jffs2_xattr_ref)); 261aa98d7cfSKaiGai Kohei ref->class = RAWNODE_CLASS_XATTR_REF; 262aa98d7cfSKaiGai Kohei INIT_LIST_HEAD(&ref->ilist); 263aa98d7cfSKaiGai Kohei return ref; 264aa98d7cfSKaiGai Kohei } 265aa98d7cfSKaiGai Kohei 266aa98d7cfSKaiGai Kohei void jffs2_free_xattr_ref(struct jffs2_xattr_ref *ref) 267aa98d7cfSKaiGai Kohei { 268aa98d7cfSKaiGai Kohei dbg_memalloc("%p\n", ref); 269aa98d7cfSKaiGai Kohei kmem_cache_free(xattr_ref_cache, ref); 270aa98d7cfSKaiGai Kohei } 271aa98d7cfSKaiGai Kohei #endif 272