1/* $NetBSD: chfs_pool.c,v 1.5 2020/09/05 16:30:12 riastradh Exp $ */ 2 3/*- 4 * Copyright (c) 2010 Department of Software Engineering, 5 * University of Szeged, Hungary 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by the Department of Software Engineering, University of Szeged, Hungary 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 27 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33/* 34 * Pool allocator and convenience routines for chfs. 35 */ 36 37#include <sys/cdefs.h> 38 39#include <sys/param.h> 40#include <sys/pool.h> 41#include <sys/atomic.h> 42 43#include "chfs.h" 44 45/* --------------------------------------------------------------------- */ 46 47void * chfs_pool_page_alloc(struct pool *, int); 48void chfs_pool_page_free(struct pool *, void *); 49 50/* --------------------------------------------------------------------- */ 51 52struct pool_allocator chfs_pool_allocator = { 53 .pa_alloc = chfs_pool_page_alloc, 54 .pa_free = chfs_pool_page_free, 55}; 56 57/* --------------------------------------------------------------------- */ 58 59void 60chfs_pool_init(struct chfs_pool *chpp, size_t size, const char *what, 61 struct chfs_mount *chmp) 62{ 63 int cnt __diagused; 64 65 cnt = snprintf(chpp->chp_name, sizeof(chpp->chp_name), 66 "%s_chfs_%p", what, chmp); 67 KASSERT(cnt < sizeof(chpp->chp_name)); 68 69 pool_init(&chpp->chp_pool, size, 0, 0, 0, chpp->chp_name, 70 &chfs_pool_allocator, IPL_NONE); 71 chpp->chp_mount = chmp; 72} 73 74/* --------------------------------------------------------------------- */ 75 76void 77chfs_pool_destroy(struct chfs_pool *chpp) 78{ 79 pool_destroy((struct pool *)chpp); 80} 81 82/* --------------------------------------------------------------------- */ 83 84void * 85chfs_pool_page_alloc(struct pool *pp, int flags) 86{ 87 struct chfs_pool *chpp; 88 struct chfs_mount *chmp; 89 unsigned int pages; 90 void *page; 91 dbg("CHFS: pool_page_alloc()\n"); 92 93 chpp = (struct chfs_pool *)pp; 94 chmp = chpp->chp_mount; 95 96 pages = atomic_inc_uint_nv(&chmp->chm_pages_used); 97 if (pages >= CHFS_PAGES_MAX(chmp)) { 98 atomic_dec_uint(&chmp->chm_pages_used); 99 return NULL; 100 } 101 page = pool_get(pp, flags | PR_WAITOK); 102 if (page == NULL) { 103 atomic_dec_uint(&chmp->chm_pages_used); 104 } 105 106 return page; 107} 108 109/* --------------------------------------------------------------------- */ 110 111void 112chfs_pool_page_free(struct pool *pp, void *v) 113{ 114 struct chfs_pool *chpp; 115 struct chfs_mount *chmp; 116 dbg("CHFS: pool_page_free()\n"); 117 118 chpp = (struct chfs_pool *)pp; 119 chmp = chpp->chp_mount; 120 121 atomic_dec_uint(&chmp->chm_pages_used); 122 pool_put(pp,v); 123} 124 125/* --------------------------------------------------------------------- */ 126 127void 128chfs_str_pool_init(struct chfs_str_pool *chsp, struct chfs_mount *chmp) 129{ 130 dbg("CHFS: str_pool_init()\n"); 131 132 chfs_pool_init(&chsp->chsp_pool_16, 16, "str", chmp); 133 chfs_pool_init(&chsp->chsp_pool_32, 32, "str", chmp); 134 chfs_pool_init(&chsp->chsp_pool_64, 64, "str", chmp); 135 chfs_pool_init(&chsp->chsp_pool_128, 128, "str", chmp); 136 chfs_pool_init(&chsp->chsp_pool_256, 256, "str", chmp); 137 chfs_pool_init(&chsp->chsp_pool_512, 512, "str", chmp); 138 chfs_pool_init(&chsp->chsp_pool_1024, 1024, "str", chmp); 139} 140 141/* --------------------------------------------------------------------- */ 142 143void 144chfs_str_pool_destroy(struct chfs_str_pool *chsp) 145{ 146 dbg("CHFS: str_pool_destroy()\n"); 147 148 chfs_pool_destroy(&chsp->chsp_pool_16); 149 chfs_pool_destroy(&chsp->chsp_pool_32); 150 chfs_pool_destroy(&chsp->chsp_pool_64); 151 chfs_pool_destroy(&chsp->chsp_pool_128); 152 chfs_pool_destroy(&chsp->chsp_pool_256); 153 chfs_pool_destroy(&chsp->chsp_pool_512); 154 chfs_pool_destroy(&chsp->chsp_pool_1024); 155} 156 157/* --------------------------------------------------------------------- */ 158 159char * 160chfs_str_pool_get(struct chfs_str_pool *chsp, size_t len, int flags) 161{ 162 struct chfs_pool *p; 163 dbg("CHFS: str_pool_get()\n"); 164 165 KASSERT(len <= 1024); 166 167 if (len <= 16) p = &chsp->chsp_pool_16; 168 else if (len <= 32) p = &chsp->chsp_pool_32; 169 else if (len <= 64) p = &chsp->chsp_pool_64; 170 else if (len <= 128) p = &chsp->chsp_pool_128; 171 else if (len <= 256) p = &chsp->chsp_pool_256; 172 else if (len <= 512) p = &chsp->chsp_pool_512; 173 else if (len <= 1024) p = &chsp->chsp_pool_1024; 174 else { 175 KASSERT(0); 176 p = NULL; /* Silence compiler warnings */ 177 } 178 179 return (char *)CHFS_POOL_GET(p, flags); 180} 181 182/* --------------------------------------------------------------------- */ 183 184void 185chfs_str_pool_put(struct chfs_str_pool *chsp, char *str, size_t len) 186{ 187 struct chfs_pool *p; 188 dbg("CHFS: str_pool_put()\n"); 189 190 KASSERT(len <= 1024); 191 192 if (len <= 16) p = &chsp->chsp_pool_16; 193 else if (len <= 32) p = &chsp->chsp_pool_32; 194 else if (len <= 64) p = &chsp->chsp_pool_64; 195 else if (len <= 128) p = &chsp->chsp_pool_128; 196 else if (len <= 256) p = &chsp->chsp_pool_256; 197 else if (len <= 512) p = &chsp->chsp_pool_512; 198 else if (len <= 1024) p = &chsp->chsp_pool_1024; 199 else { 200 KASSERT(0); 201 p = NULL; /* Silence compiler warnings */ 202 } 203 204 CHFS_POOL_PUT(p, str); 205} 206