]> git.ipfire.org Git - thirdparty/squid.git/blob - src/store_dir.cc
dont need statvfs here
[thirdparty/squid.git] / src / store_dir.cc
1
2 /*
3 * $Id: store_dir.cc,v 1.90 1999/05/04 19:14:27 wessels Exp $
4 * $Id: store_dir.cc,v 1.90 1999/05/04 19:14:27 wessels Exp $
5 *
6 * DEBUG: section 47 Store Directory Routines
7 * AUTHOR: Duane Wessels
8 *
9 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
10 * ----------------------------------------------------------
11 *
12 * Squid is the result of efforts by numerous individuals from the
13 * Internet community. Development is led by Duane Wessels of the
14 * National Laboratory for Applied Network Research and funded by the
15 * National Science Foundation. Squid is Copyrighted (C) 1998 by
16 * Duane Wessels and the University of California San Diego. Please
17 * see the COPYRIGHT file for full details. Squid incorporates
18 * software developed and/or copyrighted by other sources. Please see
19 * the CREDITS file for full details.
20 *
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 2 of the License, or
24 * (at your option) any later version.
25 *
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
30 *
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
34 *
35 */
36
37 #include "squid.h"
38
39 void
40 storeDirInit(void)
41 {
42 storeUfsDirInit();
43 }
44
45 char *
46 storeSwapFullPath(sfileno f, char *buf)
47 {
48 return storeUfsFullPath(f, buf);
49 }
50
51 void
52 storeCreateSwapDirectories(void)
53 {
54 storeUfsCreateSwapDirectories();
55 }
56
57 /*
58 *Spread load across least 3/4 of the store directories
59 */
60 static int
61 storeDirSelectSwapDir(void)
62 {
63 double least_used = 1.0;
64 double high = (double) Config.Swap.highWaterMark / 100.0;
65 double u;
66 int dirn;
67 int i, j;
68 SwapDir *SD;
69 static int nleast = 0;
70 static int nconf = 0;
71 static int *dirq = NULL;
72 static double *diru = NULL;
73 /*
74 * Handle simplest case of a single swap directory immediately
75 */
76 if (Config.cacheSwap.n_configured == 1)
77 return 0;
78 /*
79 * Initialise dirq on the first call or on change of number of dirs
80 */
81 if (nconf != Config.cacheSwap.n_configured) {
82 nconf = Config.cacheSwap.n_configured;
83 nleast = (nconf * 3) / 4;
84 safe_free(dirq);
85 dirq = (int *) xmalloc(sizeof(int) * nleast);
86 safe_free(diru);
87 diru = (double *) xmalloc(sizeof(double) * nconf);
88 for (j = 0; j < nleast; j++)
89 dirq[j] = -1;
90 }
91 /*
92 * Scan for a non-negative dirn in the dirq array and return that one
93 */
94 dirn = -1;
95 for (j = 0; j < nleast; j++) {
96 dirn = dirq[j];
97 if (dirn < 0)
98 continue;
99 dirq[j] = -1;
100 break;
101 }
102 /*
103 * If we found a valid dirn return it
104 */
105 if (dirn >= 0)
106 return dirn;
107 /*
108 * Now for the real guts of the algorithm - building the dirq array
109 */
110 for (i = 0; i < nconf; i++) {
111 diru[i] = 1.1;
112 SD = &Config.cacheSwap.swapDirs[i];
113 SD->flags.selected = 0;
114 if (SD->flags.read_only)
115 continue;
116 u = (double) SD->cur_size / SD->max_size;
117 if (u > high)
118 continue;
119 diru[i] = u;
120 }
121 for (j = 0; j < nleast; j++) {
122 dirq[j] = -1;
123 least_used = 1.0;
124 dirn = -1;
125 for (i = 0; i < nconf; i++) {
126 if (diru[i] < least_used) {
127 least_used = diru[i];
128 dirn = i;
129 }
130 }
131 if (dirn < 0)
132 break;
133 dirq[j] = dirn;
134 diru[dirn] = 1.1;
135 /* set selected flag for debugging/cachemgr only */
136 Config.cacheSwap.swapDirs[dirn].flags.selected = 1;
137 }
138 /*
139 * Setup default return of 0 if no least found
140 */
141 if (dirq[0] < 0)
142 dirq[0] = 0;
143 dirn = dirq[0];
144 dirq[0] = -1;
145 return dirn;
146 }
147
148 int
149 storeDirValidFileno(int fn)
150 {
151 int dirn = fn >> SWAP_DIR_SHIFT;
152 int filn = fn & SWAP_FILE_MASK;
153 if (dirn > Config.cacheSwap.n_configured)
154 return 0;
155 if (dirn < 0)
156 return 0;
157 if (filn < 0)
158 return 0;
159 if (filn > Config.cacheSwap.swapDirs[dirn].map->max_n_files)
160 return 0;
161 return 1;
162 }
163
164 int
165 storeDirMapBitTest(int fn)
166 {
167 int dirn = fn >> SWAP_DIR_SHIFT;
168 int filn = fn & SWAP_FILE_MASK;
169 return file_map_bit_test(Config.cacheSwap.swapDirs[dirn].map, filn);
170 }
171
172 void
173 storeDirMapBitSet(int fn)
174 {
175 int dirn = fn >> SWAP_DIR_SHIFT;
176 int filn = fn & SWAP_FILE_MASK;
177 file_map_bit_set(Config.cacheSwap.swapDirs[dirn].map, filn);
178 }
179
180 void
181 storeDirMapBitReset(int fn)
182 {
183 int dirn = fn >> SWAP_DIR_SHIFT;
184 int filn = fn & SWAP_FILE_MASK;
185 file_map_bit_reset(Config.cacheSwap.swapDirs[dirn].map, filn);
186 }
187
188 int
189 storeDirMapAllocate(void)
190 {
191 int dirn = storeDirSelectSwapDir();
192 SwapDir *SD = &Config.cacheSwap.swapDirs[dirn];
193 int filn = file_map_allocate(SD->map, SD->suggest);
194 SD->suggest = filn + 1;
195 return (dirn << SWAP_DIR_SHIFT) | (filn & SWAP_FILE_MASK);
196 }
197
198 char *
199 storeSwapDir(int dirn)
200 {
201 assert(0 <= dirn && dirn < Config.cacheSwap.n_configured);
202 return Config.cacheSwap.swapDirs[dirn].path;
203 }
204
205 int
206 storeDirNumber(int swap_file_number)
207 {
208 return swap_file_number >> SWAP_DIR_SHIFT;
209 }
210
211 int
212 storeDirProperFileno(int dirn, int fn)
213 {
214 return (dirn << SWAP_DIR_SHIFT) | (fn & SWAP_FILE_MASK);
215 }
216
217 /*
218 * An entry written to the swap log MUST have the following
219 * properties.
220 * 1. It MUST be a public key. It does no good to log
221 * a public ADD, change the key, then log a private
222 * DEL. So we need to log a DEL before we change a
223 * key from public to private.
224 * 2. It MUST have a valid (> -1) swap_file_number.
225 */
226 void
227 storeDirSwapLog(const StoreEntry * e, int op)
228 {
229 int dirn = e->swap_file_number >> SWAP_DIR_SHIFT;
230 assert(dirn < Config.cacheSwap.n_configured);
231 assert(!EBIT_TEST(e->flags, KEY_PRIVATE));
232 assert(e->swap_file_number >= 0);
233 /*
234 * icons and such; don't write them to the swap log
235 */
236 if (EBIT_TEST(e->flags, ENTRY_SPECIAL))
237 return;
238 assert(op > SWAP_LOG_NOP && op < SWAP_LOG_MAX);
239 debug(20, 3) ("storeDirSwapLog: %s %s %08X\n",
240 swap_log_op_str[op],
241 storeKeyText(e->key),
242 e->swap_file_number);
243 storeUfsDirSwapLog(e, op);
244 }
245
246 char *
247 storeDirSwapLogFile(int dirn, const char *ext)
248 {
249 return storeUfsDirSwapLogFile(dirn, ext);
250 }
251
252 void
253 storeDirUpdateSwapSize(int fn, size_t size, int sign)
254 {
255 int dirn = (fn >> SWAP_DIR_SHIFT) % Config.cacheSwap.n_configured;
256 int k = ((size + 1023) >> 10) * sign;
257 Config.cacheSwap.swapDirs[dirn].cur_size += k;
258 store_swap_size += k;
259 if (sign > 0)
260 n_disk_objects++;
261 else if (sign < 0)
262 n_disk_objects--;
263 }
264
265 void
266 storeDirStats(StoreEntry * sentry)
267 {
268 storeAppendPrintf(sentry, "Store Directory Statistics:\n");
269 storeAppendPrintf(sentry, "Store Entries : %d\n",
270 memInUse(MEM_STOREENTRY));
271 storeAppendPrintf(sentry, "Maximum Swap Size : %8d KB\n",
272 Config.Swap.maxSize);
273 storeAppendPrintf(sentry, "Current Store Swap Size: %8d KB\n",
274 store_swap_size);
275 storeAppendPrintf(sentry, "Current Capacity : %d%% used, %d%% free\n",
276 percent((int) store_swap_size, (int) Config.Swap.maxSize),
277 percent((int) (Config.Swap.maxSize - store_swap_size), (int) Config.Swap.maxSize));
278 storeUfsDirStats(sentry);
279 }
280
281 int
282 storeDirMapBitsInUse(void)
283 {
284 int i;
285 int n = 0;
286 for (i = 0; i < Config.cacheSwap.n_configured; i++)
287 n += Config.cacheSwap.swapDirs[i].map->n_files_in_map;
288 return n;
289 }
290
291 /*
292 * storeDirWriteCleanLogs
293 *
294 * Writes a "clean" swap log file from in-memory metadata.
295 */
296 int
297 storeDirWriteCleanLogs(int reopen)
298 {
299 return storeUfsDirWriteCleanLogs(reopen);
300 }
301
302 void
303 storeDirConfigure(void)
304 {
305 SwapDir *SD;
306 int n;
307 int i;
308 fileMap *fm;
309 Config.Swap.maxSize = 0;
310 for (i = 0; i < Config.cacheSwap.n_configured; i++) {
311 SD = &Config.cacheSwap.swapDirs[i];;
312 Config.Swap.maxSize += SD->max_size;
313 n = 2 * SD->max_size / Config.Store.avgObjectSize;
314 if (NULL == SD->map) {
315 /* first time */
316 SD->map = file_map_create(n);
317 } else if (n > SD->map->max_n_files) {
318 /* it grew, need to expand */
319 fm = file_map_create(n);
320 filemapCopy(SD->map, fm);
321 filemapFreeMemory(SD->map);
322 SD->map = fm;
323 }
324 /* else it shrunk, and we leave the old one in place */
325 }
326 }
327
328 void
329 storeDirDiskFull(int fn)
330 {
331 int dirn = fn >> SWAP_DIR_SHIFT;
332 SwapDir *SD = &Config.cacheSwap.swapDirs[dirn];
333 assert(0 <= dirn && dirn < Config.cacheSwap.n_configured);
334 SD->max_size = SD->cur_size;
335 debug(20, 1) ("WARNING: Shrinking cache_dir #%d to %d KB\n",
336 dirn, SD->cur_size);
337 }
338
339 void
340 storeDirOpenSwapLogs(void)
341 {
342 return storeUfsDirOpenSwapLogs();
343 }
344
345 void
346 storeDirCloseSwapLogs(void)
347 {
348 return storeUfsDirCloseSwapLogs();
349 }
350
351 void
352 storeDirCloseTmpSwapLog(int dirn)
353 {
354 return storeUfsDirCloseTmpSwapLog(dirn);
355 }