3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2015, Joyent, Inc.
24 * Copyright (c) 2017 by Delphix. All rights reserved.
25 */
26
27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29
30 /*
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
33 * All Rights Reserved
34 *
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
37 * contributors.
38 */
39
40 #include <sys/types.h>
41 #include <sys/systm.h>
42 #include <sys/param.h>
127
128 /*
129 * Hash table of name cache entries for fast lookup, dynamically
130 * allocated at startup.
131 */
132 nc_hash_t *nc_hash;
133
134 /*
135 * Rotors. Used to select entries on a round-robin basis.
136 */
137 static nc_hash_t *dnlc_purge_fs1_rotor;
138 static nc_hash_t *dnlc_free_rotor;
139
140 /*
141 * # of dnlc entries (uninitialized)
142 *
143 * the initial value was chosen as being
144 * a random string of bits, probably not
145 * normally chosen by a systems administrator
146 */
147 int ncsize = -1;
148 volatile uint32_t dnlc_nentries = 0; /* current num of name cache entries */
149 static int nc_hashsz; /* size of hash table */
150 static int nc_hashmask; /* size of hash table minus 1 */
151
152 /*
153 * The dnlc_reduce_cache() taskq queue is activated when there are
154 * ncsize name cache entries and if no parameter is provided, it reduces
155 * the size down to dnlc_nentries_low_water, which is by default one
156 * hundreth less (or 99%) of ncsize.
157 *
158 * If a parameter is provided to dnlc_reduce_cache(), then we reduce
159 * the size down based on ncsize_onepercent - where ncsize_onepercent
160 * is 1% of ncsize; however, we never let dnlc_reduce_cache() reduce
161 * the size below 3% of ncsize (ncsize_min_percent).
162 */
163 #define DNLC_LOW_WATER_DIVISOR_DEFAULT 100
164 uint_t dnlc_low_water_divisor = DNLC_LOW_WATER_DIVISOR_DEFAULT;
165 uint_t dnlc_nentries_low_water;
166 int dnlc_reduce_idle = 1; /* no locking needed */
167 uint_t ncsize_onepercent;
286 for (Xcp = (name + 1); (Xc = *Xcp) != 0; Xcp++) \
287 hash = (hash << 4) + hash + Xc; \
288 ASSERT((Xcp - (name)) <= ((1 << NBBY) - 1)); \
289 namelen = Xcp - (name); \
290 }
291
292 /* special dircache_t pointer to indicate error should be returned */
293 /*
294 * The anchor directory cache pointer can contain 3 types of values,
295 * 1) NULL: No directory cache
296 * 2) DC_RET_LOW_MEM (-1): There was a directory cache that found to be
297 * too big or a memory shortage occurred. This value remains in the
298 * pointer until a dnlc_dir_start() which returns the a DNOMEM error.
299 * This is kludgy but efficient and only visible in this source file.
300 * 3) A valid cache pointer.
301 */
302 #define DC_RET_LOW_MEM (dircache_t *)1
303 #define VALID_DIR_CACHE(dcp) ((dircache_t *)(dcp) > DC_RET_LOW_MEM)
304
305 /* Tunables */
306 uint_t dnlc_dir_enable = 1; /* disable caching directories by setting to 0 */
307 uint_t dnlc_dir_min_size = 40; /* min no of directory entries before caching */
308 uint_t dnlc_dir_max_size = UINT_MAX; /* ditto maximum */
309 uint_t dnlc_dir_hash_size_shift = 3; /* 8 entries per hash bucket */
310 uint_t dnlc_dir_min_reclaim = 350000; /* approx 1MB of dcentrys */
311 /*
312 * dnlc_dir_hash_resize_shift determines when the hash tables
313 * get re-adjusted due to growth or shrinkage
314 * - currently 2 indicating that there can be at most 4
315 * times or at least one quarter the number of entries
316 * before hash table readjustment. Note that with
317 * dnlc_dir_hash_size_shift above set at 3 this would
318 * mean readjustment would occur if the average number
319 * of entries went above 32 or below 2
320 */
321 uint_t dnlc_dir_hash_resize_shift = 2; /* readjust rate */
322
323 static kmem_cache_t *dnlc_dir_space_cache; /* free space entry cache */
324 static dchead_t dc_head; /* anchor of cached directories */
325
326 /* Prototypes */
327 static ncache_t *dnlc_get(uchar_t namlen);
328 static ncache_t *dnlc_search(vnode_t *dp, const char *name, uchar_t namlen,
|
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
24 * Copyright (c) 2015, Joyent, Inc.
25 * Copyright (c) 2017 by Delphix. All rights reserved.
26 */
27
28 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
29 /* All Rights Reserved */
30
31 /*
32 * University Copyright- Copyright (c) 1982, 1986, 1988
33 * The Regents of the University of California
34 * All Rights Reserved
35 *
36 * University Acknowledgment- Portions of this document are derived from
37 * software developed by the University of California, Berkeley, and its
38 * contributors.
39 */
40
41 #include <sys/types.h>
42 #include <sys/systm.h>
43 #include <sys/param.h>
128
129 /*
130 * Hash table of name cache entries for fast lookup, dynamically
131 * allocated at startup.
132 */
133 nc_hash_t *nc_hash;
134
135 /*
136 * Rotors. Used to select entries on a round-robin basis.
137 */
138 static nc_hash_t *dnlc_purge_fs1_rotor;
139 static nc_hash_t *dnlc_free_rotor;
140
141 /*
142 * # of dnlc entries (uninitialized)
143 *
144 * the initial value was chosen as being
145 * a random string of bits, probably not
146 * normally chosen by a systems administrator
147 */
148 volatile int ncsize = -1;
149 volatile uint32_t dnlc_nentries = 0; /* current num of name cache entries */
150 static int nc_hashsz; /* size of hash table */
151 static int nc_hashmask; /* size of hash table minus 1 */
152
153 /*
154 * The dnlc_reduce_cache() taskq queue is activated when there are
155 * ncsize name cache entries and if no parameter is provided, it reduces
156 * the size down to dnlc_nentries_low_water, which is by default one
157 * hundreth less (or 99%) of ncsize.
158 *
159 * If a parameter is provided to dnlc_reduce_cache(), then we reduce
160 * the size down based on ncsize_onepercent - where ncsize_onepercent
161 * is 1% of ncsize; however, we never let dnlc_reduce_cache() reduce
162 * the size below 3% of ncsize (ncsize_min_percent).
163 */
164 #define DNLC_LOW_WATER_DIVISOR_DEFAULT 100
165 uint_t dnlc_low_water_divisor = DNLC_LOW_WATER_DIVISOR_DEFAULT;
166 uint_t dnlc_nentries_low_water;
167 int dnlc_reduce_idle = 1; /* no locking needed */
168 uint_t ncsize_onepercent;
287 for (Xcp = (name + 1); (Xc = *Xcp) != 0; Xcp++) \
288 hash = (hash << 4) + hash + Xc; \
289 ASSERT((Xcp - (name)) <= ((1 << NBBY) - 1)); \
290 namelen = Xcp - (name); \
291 }
292
293 /* special dircache_t pointer to indicate error should be returned */
294 /*
295 * The anchor directory cache pointer can contain 3 types of values,
296 * 1) NULL: No directory cache
297 * 2) DC_RET_LOW_MEM (-1): There was a directory cache that found to be
298 * too big or a memory shortage occurred. This value remains in the
299 * pointer until a dnlc_dir_start() which returns the a DNOMEM error.
300 * This is kludgy but efficient and only visible in this source file.
301 * 3) A valid cache pointer.
302 */
303 #define DC_RET_LOW_MEM (dircache_t *)1
304 #define VALID_DIR_CACHE(dcp) ((dircache_t *)(dcp) > DC_RET_LOW_MEM)
305
306 /* Tunables */
307 volatile uint_t dnlc_dir_enable = 1; /* disable caching directories by */
308 /* setting to 0 */
309 volatile uint_t dnlc_dir_min_size = 40; /* min no of directory entries before */
310 /* caching */
311 volatile uint_t dnlc_dir_max_size = UINT_MAX; /* ditto maximum */
312 uint_t dnlc_dir_hash_size_shift = 3; /* 8 entries per hash bucket */
313 uint_t dnlc_dir_min_reclaim = 350000; /* approx 1MB of dcentrys */
314 /*
315 * dnlc_dir_hash_resize_shift determines when the hash tables
316 * get re-adjusted due to growth or shrinkage
317 * - currently 2 indicating that there can be at most 4
318 * times or at least one quarter the number of entries
319 * before hash table readjustment. Note that with
320 * dnlc_dir_hash_size_shift above set at 3 this would
321 * mean readjustment would occur if the average number
322 * of entries went above 32 or below 2
323 */
324 uint_t dnlc_dir_hash_resize_shift = 2; /* readjust rate */
325
326 static kmem_cache_t *dnlc_dir_space_cache; /* free space entry cache */
327 static dchead_t dc_head; /* anchor of cached directories */
328
329 /* Prototypes */
330 static ncache_t *dnlc_get(uchar_t namlen);
331 static ncache_t *dnlc_search(vnode_t *dp, const char *name, uchar_t namlen,
|