]>
Commit | Line | Data |
---|---|---|
f9d8a26d MW |
1 | Index: squid/src/cf.data.pre |
2 | diff -c squid/src/cf.data.pre:1.245.2.47 squid/src/cf.data.pre:1.245.2.48 | |
3 | *** squid/src/cf.data.pre:1.245.2.47 Tue Jul 1 14:42:41 2003 | |
4 | --- squid/src/cf.data.pre Wed Jul 23 15:00:33 2003 | |
5 | *************** | |
6 | *** 803,808 **** | |
7 | --- 803,818 ---- | |
8 | starts blocking. If this many messages are in the queues, | |
9 | Squid blocks until it recevies some replies. Default is 72 | |
10 | ||
11 | + The coss store type: | |
12 | + | |
13 | + block-size=n defines the "block size" for COSS cache_dir's. | |
14 | + Squid uses file numbers as block numbers. Since file numbers | |
15 | + are limited to 24 bits, the block size determines the maximum | |
16 | + size of the COSS partition. The default is 512 bytes, which | |
17 | + leads to a maximum cache_dir size of 512<<24, or 8 GB. Note | |
18 | + that you should not change the coss block size after Squid | |
19 | + has written some objects to the cache_dir. | |
20 | + | |
21 | Common options: | |
22 | ||
23 | read-only, this cache_dir is read only. | |
24 | *************** | |
25 | *** 812,817 **** | |
26 | --- 822,830 ---- | |
27 | Note: To make optimal use of the max-size limits you should order | |
28 | the cache_dir lines with the smallest max-size value first and the | |
29 | ones with no max-size specification last. | |
30 | + | |
31 | + Note that for coss, max-size must be less than COSS_MEMBUF_SZ | |
32 | + (hard coded at 1 MB). | |
33 | DOC_END | |
34 | ||
35 | ||
36 | Index: squid/src/fs/coss/async_io.c | |
37 | diff -c squid/src/fs/coss/async_io.c:1.7.2.1 squid/src/fs/coss/async_io.c:1.7.2.3 | |
38 | *** squid/src/fs/coss/async_io.c:1.7.2.1 Sat Jul 20 18:30:03 2002 | |
39 | --- squid/src/fs/coss/async_io.c Wed Jul 23 15:12:56 2003 | |
40 | *************** | |
41 | *** 94,100 **** | |
42 | ||
43 | /* Initiate aio */ | |
44 | if (aio_read(&qe->aq_e_aiocb) < 0) { | |
45 | ! fatalf("Aiee! aio_read() returned error (%d)!\n", errno); | |
46 | } | |
47 | } | |
48 | ||
49 | --- 94,100 ---- | |
50 | ||
51 | /* Initiate aio */ | |
52 | if (aio_read(&qe->aq_e_aiocb) < 0) { | |
53 | ! fatalf("Aiee! aio_read() returned error: %s\n", xstrerror()); | |
54 | } | |
55 | } | |
56 | ||
57 | *************** | |
58 | *** 140,146 **** | |
59 | ||
60 | /* Initiate aio */ | |
61 | if (aio_write(&qe->aq_e_aiocb) < 0) { | |
62 | ! fatalf("Aiee! aio_read() returned error (%d)!\n", errno); | |
63 | } | |
64 | } | |
65 | ||
66 | --- 140,146 ---- | |
67 | ||
68 | /* Initiate aio */ | |
69 | if (aio_write(&qe->aq_e_aiocb) < 0) { | |
70 | ! fatalf("Aiee! aio_write() returned error: %s\n", xstrerror()); | |
71 | } | |
72 | } | |
73 | ||
74 | Index: squid/src/fs/coss/coss-notes.txt | |
75 | diff -c squid/src/fs/coss/coss-notes.txt:1.1 squid/src/fs/coss/coss-notes.txt:1.1.2.1 | |
76 | *** squid/src/fs/coss/coss-notes.txt:1.1 Wed Sep 19 07:23:30 2001 | |
77 | --- squid/src/fs/coss/coss-notes.txt Wed Jul 23 15:00:33 2003 | |
78 | *************** | |
79 | *** 89,91 **** | |
80 | --- 89,123 ---- | |
81 | planned rewrite. This would also allow alternate replacement policies | |
82 | to be used. Oh, it'd cut down the storage requirements per | |
83 | StoreEntry by two pointers (8 bytes on the i386.) | |
84 | + | |
85 | + Notes by DW July 23, 2003 | |
86 | + ------------------------- | |
87 | + | |
88 | + Fixed up swap_filen -> offset implementation. Now user can use a | |
89 | + block-size setting to determine the maximum COSS cache_dir size. | |
90 | + | |
91 | + Fixed bug when cached response is larger than COSS stripe size. | |
92 | + Now require max-size to be less than COSS_MEMBUF_SZ. | |
93 | + | |
94 | + Fixed a lockcount bug. Some aborted requests for cache hits failed | |
95 | + to unlock the CossMemBuf because storeCossReadDone isn't called again. | |
96 | + Solution is to add locked_membuf pointer to CossState structure and | |
97 | + always unlock it if set. This is probably more reliable than | |
98 | + unlocking based on diskstart/diskend offsets. | |
99 | + | |
100 | + I'm worried that COSS is susceptible to a denial-of-service. If | |
101 | + the user can create N cache misses for responses about as large as | |
102 | + COSS_MEMBUF_SZ, then COSS probably allocates N membufs (stripes) | |
103 | + at the same time. For large enough values of N, this should cause | |
104 | + a malloc failure. Solution may be to refuse to allocate new stripes | |
105 | + (thus returning failure for cache misses and hits) after so many | |
106 | + have already been allocated. | |
107 | + | |
108 | + Adrian's code has this comment: | |
109 | + | |
110 | + /* Since we're not supporting NOTIFY anymore, lets fail */ | |
111 | + assert(which != COSS_ALLOC_NOTIFY); | |
112 | + | |
113 | + However, COSS_ALLOC_NOTIFY was still present in the store_dir_coss.c | |
114 | + rebuild routines. To avoid assertions during rebuild, I commented | |
115 | + out the storeCossAllocate(SD, e, COSS_ALLOC_NOTIFY) call. | |
116 | Index: squid/src/fs/coss/store_coss.h | |
117 | diff -c squid/src/fs/coss/store_coss.h:1.6 squid/src/fs/coss/store_coss.h:1.6.2.1 | |
118 | *** squid/src/fs/coss/store_coss.h:1.6 Sun Aug 12 04:20:41 2001 | |
119 | --- squid/src/fs/coss/store_coss.h Wed Jul 23 15:00:33 2003 | |
120 | *************** | |
121 | *** 5,18 **** | |
122 | #define COSS_MEMBUF_SZ 1048576 | |
123 | #endif | |
124 | ||
125 | - #ifndef COSS_BLOCK_SZ | |
126 | - #define COSS_BLOCK_SZ 512 | |
127 | - #endif | |
128 | - | |
129 | - /* Macros to help block<->offset transiting */ | |
130 | - #define COSS_OFS_TO_BLK(ofs) ((ofs) / COSS_BLOCK_SZ) | |
131 | - #define COSS_BLK_TO_OFS(ofs) ((ofs) * COSS_BLOCK_SZ) | |
132 | - | |
133 | /* Note that swap_filen in sio/e are actually disk offsets too! */ | |
134 | ||
135 | /* What we're doing in storeCossAllocate() */ | |
136 | --- 5,10 ---- | |
137 | *************** | |
138 | *** 46,51 **** | |
139 | --- 38,45 ---- | |
140 | int count; | |
141 | async_queue_t aq; | |
142 | dlink_node *walk_current; | |
143 | + unsigned int blksz_bits; | |
144 | + unsigned int blksz_mask; /* just 1<<blksz_bits - 1 */ | |
145 | }; | |
146 | ||
147 | struct _cossindex { | |
148 | *************** | |
149 | *** 67,72 **** | |
150 | --- 61,67 ---- | |
151 | unsigned int reading:1; | |
152 | unsigned int writing:1; | |
153 | } flags; | |
154 | + struct _cossmembuf *locked_membuf; | |
155 | }; | |
156 | ||
157 | typedef struct _cossmembuf CossMemBuf; | |
158 | *************** | |
159 | *** 91,97 **** | |
160 | extern STOBJUNLINK storeCossUnlink; | |
161 | extern STSYNC storeCossSync; | |
162 | ||
163 | - extern off_t storeCossAllocate(SwapDir * SD, const StoreEntry * e, int which); | |
164 | extern void storeCossAdd(SwapDir *, StoreEntry *); | |
165 | extern void storeCossRemove(SwapDir *, StoreEntry *); | |
166 | extern void storeCossStartMembuf(SwapDir * SD); | |
167 | --- 86,91 ---- | |
168 | Index: squid/src/fs/coss/store_dir_coss.c | |
169 | diff -c squid/src/fs/coss/store_dir_coss.c:1.30.2.5 squid/src/fs/coss/store_dir_coss.c:1.30.2.7 | |
170 | *** squid/src/fs/coss/store_dir_coss.c:1.30.2.5 Wed Jan 8 20:38:41 2003 | |
171 | --- squid/src/fs/coss/store_dir_coss.c Fri Jul 25 10:56:02 2003 | |
172 | *************** | |
173 | *** 89,98 **** | |
174 | --- 89,106 ---- | |
175 | static STFSRECONFIGURE storeCossDirReconfigure; | |
176 | static STDUMP storeCossDirDump; | |
177 | static STCALLBACK storeCossDirCallback; | |
178 | + static void storeCossDirParseBlkSize(SwapDir *, const char *, const char *, int); | |
179 | + static void storeCossDirDumpBlkSize(StoreEntry *, const char *, SwapDir *); | |
180 | ||
181 | /* The "only" externally visible function */ | |
182 | STSETUP storeFsSetup_coss; | |
183 | ||
184 | + static struct cache_dir_option options[] = | |
185 | + { | |
186 | + {"block-size", storeCossDirParseBlkSize, storeCossDirDumpBlkSize}, | |
187 | + {NULL, NULL} | |
188 | + }; | |
189 | + | |
190 | static char * | |
191 | storeCossDirSwapLogFile(SwapDir * sd, const char *ext) | |
192 | { | |
193 | *************** | |
194 | *** 161,170 **** | |
195 | cs->fd = file_open(sd->path, O_RDWR | O_CREAT); | |
196 | if (cs->fd < 0) { | |
197 | debug(79, 1) ("%s: %s\n", sd->path, xstrerror()); | |
198 | ! fatal("storeCossDirInit: Failed to open a COSS directory."); | |
199 | } | |
200 | n_coss_dirs++; | |
201 | ! (void) storeDirGetBlkSize(sd->path, &sd->fs.blksize); | |
202 | } | |
203 | ||
204 | void | |
205 | --- 169,184 ---- | |
206 | cs->fd = file_open(sd->path, O_RDWR | O_CREAT); | |
207 | if (cs->fd < 0) { | |
208 | debug(79, 1) ("%s: %s\n", sd->path, xstrerror()); | |
209 | ! fatal("storeCossDirInit: Failed to open a COSS file."); | |
210 | } | |
211 | n_coss_dirs++; | |
212 | ! /* | |
213 | ! * fs.blksize is normally determined by calling statvfs() etc, | |
214 | ! * but we just set it here. It is used in accounting the | |
215 | ! * total store size, and is reported in cachemgr 'storedir' | |
216 | ! * page. | |
217 | ! */ | |
218 | ! sd->fs.blksize = 1 << cs->blksz_bits; | |
219 | } | |
220 | ||
221 | void | |
222 | *************** | |
223 | *** 335,341 **** | |
224 | --- 349,358 ---- | |
225 | EBIT_CLR(e->flags, ENTRY_VALIDATED); | |
226 | storeHashInsert(e, key); /* do it after we clear KEY_PRIVATE */ | |
227 | storeCossAdd(SD, e); | |
228 | + #if USE_COSS_ALLOC_NOTIFY | |
229 | e->swap_filen = storeCossAllocate(SD, e, COSS_ALLOC_NOTIFY); | |
230 | + #endif | |
231 | + assert(e->swap_filen >= 0); | |
232 | return e; | |
233 | } | |
234 | ||
235 | *************** | |
236 | *** 742,747 **** | |
237 | --- 759,765 ---- | |
238 | unsigned int i; | |
239 | unsigned int size; | |
240 | CossInfo *cs; | |
241 | + off_t max_offset; | |
242 | ||
243 | i = GetInteger(); | |
244 | size = i << 10; /* Mbytes to Kbytes */ | |
245 | *************** | |
246 | *** 796,806 **** | |
247 | cs->current_membuf = NULL; | |
248 | cs->index.head = NULL; | |
249 | cs->index.tail = NULL; | |
250 | ||
251 | ! parse_cachedir_options(sd, NULL, 0); | |
252 | /* Enforce maxobjsize being set to something */ | |
253 | if (sd->max_objsize == -1) | |
254 | fatal("COSS requires max-size to be set to something other than -1!\n"); | |
255 | } | |
256 | ||
257 | ||
258 | --- 814,840 ---- | |
259 | cs->current_membuf = NULL; | |
260 | cs->index.head = NULL; | |
261 | cs->index.tail = NULL; | |
262 | + cs->blksz_bits = 9; /* default block size = 512 */ | |
263 | + cs->blksz_mask = (1 << cs->blksz_bits) - 1; | |
264 | ||
265 | ! parse_cachedir_options(sd, options, 0); | |
266 | /* Enforce maxobjsize being set to something */ | |
267 | if (sd->max_objsize == -1) | |
268 | fatal("COSS requires max-size to be set to something other than -1!\n"); | |
269 | + if (sd->max_objsize > COSS_MEMBUF_SZ) | |
270 | + fatalf("COSS max-size option must be less than COSS_MEMBUF_SZ (%d)\n", COSS_MEMBUF_SZ); | |
271 | + /* | |
272 | + * check that we won't overflow sfileno later. 0xFFFFFF is the | |
273 | + * largest possible sfileno, assuming sfileno is a 25-bit | |
274 | + * signed integer, as defined in structs.h. | |
275 | + */ | |
276 | + max_offset = (off_t) 0xFFFFFF << cs->blksz_bits; | |
277 | + if (sd->max_size > (max_offset >> 10)) { | |
278 | + debug(47, 0) ("COSS block-size = %d bytes\n", 1 << cs->blksz_bits); | |
279 | + debug(47, 0) ("COSS largest file offset = %lu KB\n", (unsigned long) max_offset >> 10); | |
280 | + debug(47, 0) ("COSS cache_dir size = %d KB\n", sd->max_size); | |
281 | + fatal("COSS cache_dir size exceeds largest offset\n"); | |
282 | + } | |
283 | } | |
284 | ||
285 | ||
286 | *************** | |
287 | *** 821,827 **** | |
288 | debug(3, 1) ("Cache COSS dir '%s' size changed to %d KB\n", path, size); | |
289 | sd->max_size = size; | |
290 | } | |
291 | ! parse_cachedir_options(sd, NULL, 1); | |
292 | /* Enforce maxobjsize being set to something */ | |
293 | if (sd->max_objsize == -1) | |
294 | fatal("COSS requires max-size to be set to something other than -1!\n"); | |
295 | --- 855,861 ---- | |
296 | debug(3, 1) ("Cache COSS dir '%s' size changed to %d KB\n", path, size); | |
297 | sd->max_size = size; | |
298 | } | |
299 | ! parse_cachedir_options(sd, options, 1); | |
300 | /* Enforce maxobjsize being set to something */ | |
301 | if (sd->max_objsize == -1) | |
302 | fatal("COSS requires max-size to be set to something other than -1!\n"); | |
303 | *************** | |
304 | *** 833,838 **** | |
305 | --- 867,908 ---- | |
306 | storeAppendPrintf(entry, " %d", | |
307 | s->max_size >> 20); | |
308 | dump_cachedir_options(entry, NULL, s); | |
309 | + } | |
310 | + | |
311 | + static void | |
312 | + storeCossDirParseBlkSize(SwapDir * sd, const char *name, const char *value, int reconfiguring) | |
313 | + { | |
314 | + CossInfo *cs = sd->fsdata; | |
315 | + int blksz = atoi(value); | |
316 | + int check; | |
317 | + int nbits; | |
318 | + if (blksz == (1 << cs->blksz_bits)) | |
319 | + /* no change */ | |
320 | + return; | |
321 | + if (reconfiguring) { | |
322 | + debug(47, 0) ("WARNING: cannot change COSS block-size while Squid is running\n"); | |
323 | + return; | |
324 | + } | |
325 | + nbits = 0; | |
326 | + check = blksz; | |
327 | + while (check > 1) { | |
328 | + nbits++; | |
329 | + check >>= 1; | |
330 | + } | |
331 | + check = 1 << nbits; | |
332 | + if (check != blksz) | |
333 | + fatal("COSS block-size must be a power of 2\n"); | |
334 | + if (nbits > 13) | |
335 | + fatal("COSS block-size must be 8192 or smaller\n"); | |
336 | + cs->blksz_bits = nbits; | |
337 | + cs->blksz_mask = (1 << cs->blksz_bits) - 1; | |
338 | + } | |
339 | + | |
340 | + static void | |
341 | + storeCossDirDumpBlkSize(StoreEntry * e, const char *option, SwapDir * sd) | |
342 | + { | |
343 | + CossInfo *cs = sd->fsdata; | |
344 | + storeAppendPrintf(e, " block-size=%d", 1 << cs->blksz_bits); | |
345 | } | |
346 | ||
347 | #if OLD_UNUSED_CODE | |
348 | Index: squid/src/fs/coss/store_io_coss.c | |
349 | diff -c squid/src/fs/coss/store_io_coss.c:1.13.2.4 squid/src/fs/coss/store_io_coss.c:1.13.2.6 | |
350 | *** squid/src/fs/coss/store_io_coss.c:1.13.2.4 Thu Aug 8 14:17:41 2002 | |
351 | --- squid/src/fs/coss/store_io_coss.c Wed Jul 23 15:12:56 2003 | |
352 | *************** | |
353 | *** 49,54 **** | |
354 | --- 49,59 ---- | |
355 | static CossMemBuf *storeCossCreateMemBuf(SwapDir * SD, size_t start, | |
356 | sfileno curfn, int *collision); | |
357 | static CBDUNL storeCossIOFreeEntry; | |
358 | + static off_t storeCossFilenoToDiskOffset(sfileno f, CossInfo *); | |
359 | + static sfileno storeCossDiskOffsetToFileno(off_t o, CossInfo *); | |
360 | + static void storeCossMaybeWriteMemBuf(SwapDir * SD, CossMemBuf * t); | |
361 | + | |
362 | + static void membuf_describe(CossMemBuf * t, int level, int line); | |
363 | ||
364 | CBDATA_TYPE(storeIOState); | |
365 | CBDATA_TYPE(CossMemBuf); | |
366 | *************** | |
367 | *** 62,68 **** | |
368 | * to work.. | |
369 | * -- Adrian | |
370 | */ | |
371 | ! off_t | |
372 | storeCossAllocate(SwapDir * SD, const StoreEntry * e, int which) | |
373 | { | |
374 | CossInfo *cs = (CossInfo *) SD->fsdata; | |
375 | --- 67,73 ---- | |
376 | * to work.. | |
377 | * -- Adrian | |
378 | */ | |
379 | ! static sfileno | |
380 | storeCossAllocate(SwapDir * SD, const StoreEntry * e, int which) | |
381 | { | |
382 | CossInfo *cs = (CossInfo *) SD->fsdata; | |
383 | *************** | |
384 | *** 78,85 **** | |
385 | else | |
386 | checkf = -1; | |
387 | ||
388 | - retofs = e->swap_filen; /* Just for defaults, or while rebuilding */ | |
389 | - | |
390 | if (e->swap_file_sz > 0) | |
391 | allocsize = e->swap_file_sz; | |
392 | else | |
393 | --- 83,88 ---- | |
394 | *************** | |
395 | *** 96,101 **** | |
396 | --- 99,105 ---- | |
397 | */ | |
398 | cs->current_membuf->flags.full = 1; | |
399 | cs->current_membuf->diskend = cs->current_offset - 1; | |
400 | + storeCossMaybeWriteMemBuf(SD, cs->current_membuf); | |
401 | cs->current_offset = 0; /* wrap back to beginning */ | |
402 | debug(79, 2) ("storeCossAllocate: wrap to 0\n"); | |
403 | ||
404 | *************** | |
405 | *** 109,114 **** | |
406 | --- 113,119 ---- | |
407 | */ | |
408 | cs->current_membuf->flags.full = 1; | |
409 | cs->current_offset = cs->current_membuf->diskend + 1; | |
410 | + storeCossMaybeWriteMemBuf(SD, cs->current_membuf); | |
411 | debug(79, 2) ("storeCossAllocate: New offset - %ld\n", | |
412 | (long int) cs->current_offset); | |
413 | newmb = storeCossCreateMemBuf(SD, cs->current_offset, checkf, &coll); | |
414 | *************** | |
415 | *** 118,124 **** | |
416 | if (coll == 0) { | |
417 | retofs = cs->current_offset; | |
418 | cs->current_offset = retofs + allocsize; | |
419 | ! return retofs; | |
420 | } else { | |
421 | debug(79, 3) ("storeCossAllocate: Collision\n"); | |
422 | return -1; | |
423 | --- 123,131 ---- | |
424 | if (coll == 0) { | |
425 | retofs = cs->current_offset; | |
426 | cs->current_offset = retofs + allocsize; | |
427 | ! /* round up to our blocksize */ | |
428 | ! cs->current_offset = ((cs->current_offset + cs->blksz_mask) >> cs->blksz_bits) << cs->blksz_bits; | |
429 | ! return storeCossDiskOffsetToFileno(retofs, cs); | |
430 | } else { | |
431 | debug(79, 3) ("storeCossAllocate: Collision\n"); | |
432 | return -1; | |
433 | *************** | |
434 | *** 159,165 **** | |
435 | sio->st_size = objectLen(e) + e->mem_obj->swap_hdr_sz; | |
436 | sio->swap_dirn = SD->index; | |
437 | sio->swap_filen = storeCossAllocate(SD, e, COSS_ALLOC_ALLOCATE); | |
438 | ! debug(79, 3) ("storeCossCreate: offset %d, size %ld, end %ld\n", sio->swap_filen, (long int) sio->st_size, (long int) (sio->swap_filen + sio->st_size)); | |
439 | ||
440 | sio->callback = callback; | |
441 | sio->file_callback = file_callback; | |
442 | --- 166,175 ---- | |
443 | sio->st_size = objectLen(e) + e->mem_obj->swap_hdr_sz; | |
444 | sio->swap_dirn = SD->index; | |
445 | sio->swap_filen = storeCossAllocate(SD, e, COSS_ALLOC_ALLOCATE); | |
446 | ! debug(79, 3) ("storeCossCreate: offset %ld, size %ld, end %ld\n", | |
447 | ! (long int) storeCossFilenoToDiskOffset(sio->swap_filen, SD->fsdata), | |
448 | ! (long int) sio->st_size, | |
449 | ! (long int) (sio->swap_filen + sio->st_size)); | |
450 | ||
451 | sio->callback = callback; | |
452 | sio->file_callback = file_callback; | |
453 | *************** | |
454 | *** 211,217 **** | |
455 | cstate->flags.reading = 0; | |
456 | cstate->readbuffer = NULL; | |
457 | cstate->reqdiskoffset = -1; | |
458 | ! p = storeCossMemPointerFromDiskOffset(SD, f, NULL); | |
459 | /* make local copy so we don't have to lock membuf */ | |
460 | if (p) { | |
461 | cstate->readbuffer = xmalloc(sio->st_size); | |
462 | --- 221,227 ---- | |
463 | cstate->flags.reading = 0; | |
464 | cstate->readbuffer = NULL; | |
465 | cstate->reqdiskoffset = -1; | |
466 | ! p = storeCossMemPointerFromDiskOffset(SD, storeCossFilenoToDiskOffset(f, cs), NULL); | |
467 | /* make local copy so we don't have to lock membuf */ | |
468 | if (p) { | |
469 | cstate->readbuffer = xmalloc(sio->st_size); | |
470 | *************** | |
471 | *** 227,234 **** | |
472 | * a place for the object here, and the file_read() reads the object | |
473 | * into the cossmembuf for later writing .. | |
474 | */ | |
475 | ! cstate->reqdiskoffset = sio->swap_filen; | |
476 | ! sio->swap_filen = -1; | |
477 | sio->swap_filen = storeCossAllocate(SD, e, COSS_ALLOC_REALLOC); | |
478 | if (sio->swap_filen == -1) { | |
479 | /* We have to clean up neatly .. */ | |
480 | --- 237,243 ---- | |
481 | * a place for the object here, and the file_read() reads the object | |
482 | * into the cossmembuf for later writing .. | |
483 | */ | |
484 | ! cstate->reqdiskoffset = storeCossFilenoToDiskOffset(sio->swap_filen, cs); | |
485 | sio->swap_filen = storeCossAllocate(SD, e, COSS_ALLOC_REALLOC); | |
486 | if (sio->swap_filen == -1) { | |
487 | /* We have to clean up neatly .. */ | |
488 | *************** | |
489 | *** 243,249 **** | |
490 | ||
491 | /* | |
492 | * lock the buffer so it doesn't get swapped out on us | |
493 | ! * this will get unlocked in storeCossReadDone | |
494 | */ | |
495 | storeCossMemBufLock(SD, sio); | |
496 | ||
497 | --- 252,258 ---- | |
498 | ||
499 | /* | |
500 | * lock the buffer so it doesn't get swapped out on us | |
501 | ! * this will get unlocked in storeCossClose | |
502 | */ | |
503 | storeCossMemBufLock(SD, sio); | |
504 | ||
505 | *************** | |
506 | *** 254,263 **** | |
507 | storeCossAdd(SD, e); | |
508 | ||
509 | /* | |
510 | ! * Since we've reallocated a spot for this object, we need to | |
511 | ! * write it to the cossmembuf *and* return it in the read .. | |
512 | */ | |
513 | - cstate->readbuffer = NULL; | |
514 | } | |
515 | return sio; | |
516 | } | |
517 | --- 263,272 ---- | |
518 | storeCossAdd(SD, e); | |
519 | ||
520 | /* | |
521 | ! * NOTE cstate->readbuffer is NULL. We'll actually read | |
522 | ! * the disk data into the MemBuf in storeCossRead() and | |
523 | ! * return that pointer back to the caller | |
524 | */ | |
525 | } | |
526 | return sio; | |
527 | } | |
528 | *************** | |
529 | *** 266,273 **** | |
530 | storeCossClose(SwapDir * SD, storeIOState * sio) | |
531 | { | |
532 | debug(79, 3) ("storeCossClose: offset %d\n", sio->swap_filen); | |
533 | ! if (FILE_MODE(sio->mode) == O_WRONLY) | |
534 | ! storeCossMemBufUnlock(SD, sio); | |
535 | storeCossIOCallback(sio, 0); | |
536 | } | |
537 | ||
538 | --- 275,281 ---- | |
539 | storeCossClose(SwapDir * SD, storeIOState * sio) | |
540 | { | |
541 | debug(79, 3) ("storeCossClose: offset %d\n", sio->swap_filen); | |
542 | ! storeCossMemBufUnlock(SD, sio); | |
543 | storeCossIOCallback(sio, 0); | |
544 | } | |
545 | ||
546 | *************** | |
547 | *** 291,297 **** | |
548 | cstate->requestbuf = buf; | |
549 | cstate->requestoffset = offset; | |
550 | if (cstate->readbuffer == NULL) { | |
551 | ! p = storeCossMemPointerFromDiskOffset(SD, sio->swap_filen, NULL); | |
552 | /* Remember we need to translate the block offset to a disk offset! */ | |
553 | a_file_read(&cs->aq, cs->fd, | |
554 | p, | |
555 | --- 299,305 ---- | |
556 | cstate->requestbuf = buf; | |
557 | cstate->requestoffset = offset; | |
558 | if (cstate->readbuffer == NULL) { | |
559 | ! p = storeCossMemPointerFromDiskOffset(SD, storeCossFilenoToDiskOffset(sio->swap_filen, cs), NULL); | |
560 | /* Remember we need to translate the block offset to a disk offset! */ | |
561 | a_file_read(&cs->aq, cs->fd, | |
562 | p, | |
563 | *************** | |
564 | *** 301,306 **** | |
565 | --- 309,317 ---- | |
566 | sio); | |
567 | cstate->reqdiskoffset = 0; /* XXX */ | |
568 | } else { | |
569 | + /* | |
570 | + * It was copied from memory in storeCossOpen() | |
571 | + */ | |
572 | storeCossReadDone(cs->fd, | |
573 | cstate->readbuffer, | |
574 | sio->st_size, | |
575 | *************** | |
576 | *** 323,329 **** | |
577 | assert(sio->e->mem_obj->object_sz != -1); | |
578 | ||
579 | debug(79, 3) ("storeCossWrite: offset %ld, len %lu\n", (long int) sio->offset, (unsigned long int) size); | |
580 | ! diskoffset = sio->swap_filen + sio->offset; | |
581 | dest = storeCossMemPointerFromDiskOffset(SD, diskoffset, &membuf); | |
582 | assert(dest != NULL); | |
583 | xmemcpy(dest, buf, size); | |
584 | --- 334,340 ---- | |
585 | assert(sio->e->mem_obj->object_sz != -1); | |
586 | ||
587 | debug(79, 3) ("storeCossWrite: offset %ld, len %lu\n", (long int) sio->offset, (unsigned long int) size); | |
588 | ! diskoffset = storeCossFilenoToDiskOffset(sio->swap_filen, SD->fsdata) + sio->offset; | |
589 | dest = storeCossMemPointerFromDiskOffset(SD, diskoffset, &membuf); | |
590 | assert(dest != NULL); | |
591 | xmemcpy(dest, buf, size); | |
592 | *************** | |
593 | *** 355,363 **** | |
594 | } else { | |
595 | if (cstate->readbuffer == NULL) { | |
596 | cstate->readbuffer = xmalloc(sio->st_size); | |
597 | ! p = storeCossMemPointerFromDiskOffset(SD, sio->swap_filen, NULL); | |
598 | xmemcpy(cstate->readbuffer, p, sio->st_size); | |
599 | - storeCossMemBufUnlock(SD, sio); | |
600 | } | |
601 | sio->offset += len; | |
602 | xmemcpy(cstate->requestbuf, &cstate->readbuffer[cstate->requestoffset], | |
603 | --- 366,375 ---- | |
604 | } else { | |
605 | if (cstate->readbuffer == NULL) { | |
606 | cstate->readbuffer = xmalloc(sio->st_size); | |
607 | ! p = storeCossMemPointerFromDiskOffset(SD, | |
608 | ! storeCossFilenoToDiskOffset(sio->swap_filen, SD->fsdata), | |
609 | ! NULL); | |
610 | xmemcpy(cstate->readbuffer, p, sio->st_size); | |
611 | } | |
612 | sio->offset += len; | |
613 | xmemcpy(cstate->requestbuf, &cstate->readbuffer[cstate->requestoffset], | |
614 | *************** | |
615 | *** 377,382 **** | |
616 | --- 389,395 ---- | |
617 | { | |
618 | CossState *cstate = (CossState *) sio->fsstate; | |
619 | debug(79, 3) ("storeCossIOCallback: errflag=%d\n", errflag); | |
620 | + assert(NULL == cstate->locked_membuf); | |
621 | xfree(cstate->readbuffer); | |
622 | if (cbdataValid(sio->callback_data)) | |
623 | sio->callback(sio->callback_data, errflag, sio); | |
624 | *************** | |
625 | *** 406,458 **** | |
626 | return NULL; | |
627 | } | |
628 | ||
629 | ! static void | |
630 | ! storeCossMemBufLock(SwapDir * SD, storeIOState * e) | |
631 | { | |
632 | ! CossMemBuf *t; | |
633 | dlink_node *m; | |
634 | CossInfo *cs = (CossInfo *) SD->fsdata; | |
635 | ! | |
636 | for (m = cs->membufs.head; m; m = m->next) { | |
637 | t = m->data; | |
638 | ! if ((e->swap_filen >= t->diskstart) && (e->swap_filen <= t->diskend)) { | |
639 | ! debug(79, 3) ("storeCossMemBufLock: locking %p, lockcount %d\n", t, t->lockcount); | |
640 | ! t->lockcount++; | |
641 | ! return; | |
642 | ! } | |
643 | } | |
644 | ! debug(79, 3) ("storeCossMemBufLock: FAILED to lock %p\n", e); | |
645 | } | |
646 | ||
647 | static void | |
648 | ! storeCossMemBufUnlock(SwapDir * SD, storeIOState * e) | |
649 | { | |
650 | ! CossMemBuf *t; | |
651 | ! dlink_node *m, *n; | |
652 | ! CossInfo *cs = (CossInfo *) SD->fsdata; | |
653 | ||
654 | ! for (m = cs->membufs.head; m; m = n) { | |
655 | ! /* | |
656 | ! * Note that storeCossWriteMemBuf() might call storeCossWriteMemBufDone | |
657 | ! * immediately (if the write finishes immediately, of course!) which | |
658 | ! * will make m = m->next kinda unworkable. So, get the next pointer. | |
659 | ! */ | |
660 | ! n = m->next; | |
661 | ! t = m->data; | |
662 | ! if ((e->swap_filen >= t->diskstart) && (e->swap_filen <= t->diskend)) { | |
663 | ! t->lockcount--; | |
664 | ! debug(79, 3) ("storeCossMemBufUnlock: unlocking %p, lockcount %d\n", t, t->lockcount); | |
665 | ! } | |
666 | ! if (t->flags.full && !t->flags.writing && !t->lockcount) | |
667 | ! storeCossWriteMemBuf(SD, t); | |
668 | ! } | |
669 | } | |
670 | ||
671 | void | |
672 | storeCossSync(SwapDir * SD) | |
673 | { | |
674 | CossInfo *cs = (CossInfo *) SD->fsdata; | |
675 | - CossMemBuf *t; | |
676 | dlink_node *m; | |
677 | int end; | |
678 | ||
679 | --- 419,483 ---- | |
680 | return NULL; | |
681 | } | |
682 | ||
683 | ! static CossMemBuf * | |
684 | ! storeCossFilenoToMembuf(SwapDir * SD, sfileno s) | |
685 | { | |
686 | ! CossMemBuf *t = NULL; | |
687 | dlink_node *m; | |
688 | CossInfo *cs = (CossInfo *) SD->fsdata; | |
689 | ! off_t o = storeCossFilenoToDiskOffset(s, cs); | |
690 | for (m = cs->membufs.head; m; m = m->next) { | |
691 | t = m->data; | |
692 | ! if ((o >= t->diskstart) && (o <= t->diskend)) | |
693 | ! break; | |
694 | } | |
695 | ! assert(t); | |
696 | ! return t; | |
697 | } | |
698 | ||
699 | static void | |
700 | ! storeCossMemBufLock(SwapDir * SD, storeIOState * sio) | |
701 | { | |
702 | ! CossMemBuf *t = storeCossFilenoToMembuf(SD, sio->swap_filen); | |
703 | ! CossState *cstate = (CossState *) sio->fsstate; | |
704 | ! debug(79, 3) ("storeCossMemBufLock: locking %p, lockcount %d\n", | |
705 | ! t, t->lockcount); | |
706 | ! cstate->locked_membuf = t; | |
707 | ! t->lockcount++; | |
708 | ! } | |
709 | ||
710 | ! static void | |
711 | ! storeCossMemBufUnlock(SwapDir * SD, storeIOState * sio) | |
712 | ! { | |
713 | ! CossState *cstate = (CossState *) sio->fsstate; | |
714 | ! CossMemBuf *t = cstate->locked_membuf; | |
715 | ! if (NULL == t) | |
716 | ! return; | |
717 | ! debug(79, 3) ("storeCossMemBufUnlock: unlocking %p, lockcount %d\n", | |
718 | ! t, t->lockcount); | |
719 | ! t->lockcount--; | |
720 | ! cstate->locked_membuf = NULL; | |
721 | ! storeCossMaybeWriteMemBuf(SD, t); | |
722 | ! } | |
723 | ! | |
724 | ! static void | |
725 | ! storeCossMaybeWriteMemBuf(SwapDir * SD, CossMemBuf * t) | |
726 | ! { | |
727 | ! membuf_describe(t, 3, __LINE__); | |
728 | ! if (!t->flags.full) | |
729 | ! debug(79, 3) ("membuf %p not full\n", t); | |
730 | ! else if (t->flags.writing) | |
731 | ! debug(79, 3) ("membuf %p writing\n", t); | |
732 | ! else if (t->lockcount) | |
733 | ! debug(79, 3) ("membuf %p lockcount=%d\n", t, t->lockcount); | |
734 | ! else | |
735 | ! storeCossWriteMemBuf(SD, t); | |
736 | } | |
737 | ||
738 | void | |
739 | storeCossSync(SwapDir * SD) | |
740 | { | |
741 | CossInfo *cs = (CossInfo *) SD->fsdata; | |
742 | dlink_node *m; | |
743 | int end; | |
744 | ||
745 | *************** | |
746 | *** 463,471 **** | |
747 | if (!cs->membufs.head) | |
748 | return; | |
749 | for (m = cs->membufs.head; m; m = m->next) { | |
750 | ! t = m->data; | |
751 | ! if (t->flags.writing) | |
752 | sleep(5); /* XXX EEEWWW! */ | |
753 | lseek(cs->fd, t->diskstart, SEEK_SET); | |
754 | end = (t == cs->current_membuf) ? cs->current_offset : t->diskend; | |
755 | FD_WRITE_METHOD(cs->fd, t->buffer, end - t->diskstart); | |
756 | --- 488,498 ---- | |
757 | if (!cs->membufs.head) | |
758 | return; | |
759 | for (m = cs->membufs.head; m; m = m->next) { | |
760 | ! CossMemBuf *t = m->data; | |
761 | ! if (t->flags.writing) { | |
762 | ! debug(79, 1) ("WARNING: sleeping for 5 seconds in storeCossSync()\n"); | |
763 | sleep(5); /* XXX EEEWWW! */ | |
764 | + } | |
765 | lseek(cs->fd, t->diskstart, SEEK_SET); | |
766 | end = (t == cs->current_membuf) ? cs->current_offset : t->diskend; | |
767 | FD_WRITE_METHOD(cs->fd, t->buffer, end - t->diskstart); | |
768 | *************** | |
769 | *** 523,543 **** | |
770 | dlinkAdd(newmb, &newmb->node, &cs->membufs); | |
771 | ||
772 | /* Print out the list of membufs */ | |
773 | for (m = cs->membufs.head; m; m = m->next) { | |
774 | t = m->data; | |
775 | ! debug(79, 3) ("storeCossCreateMemBuf: membuflist %ld lockcount %d\n", (long int) t->diskstart, t->lockcount); | |
776 | } | |
777 | ||
778 | /* | |
779 | * Kill objects from the tail to make space for a new chunk | |
780 | */ | |
781 | for (m = cs->index.tail; m; m = prev) { | |
782 | prev = m->prev; | |
783 | e = m->data; | |
784 | if (curfn == e->swap_filen) | |
785 | *collision = 1; /* Mark an object alloc collision */ | |
786 | ! if ((e->swap_filen >= newmb->diskstart) && | |
787 | ! (e->swap_filen <= newmb->diskend)) { | |
788 | storeRelease(e); | |
789 | numreleased++; | |
790 | } else | |
791 | --- 550,573 ---- | |
792 | dlinkAdd(newmb, &newmb->node, &cs->membufs); | |
793 | ||
794 | /* Print out the list of membufs */ | |
795 | + debug(79, 3) ("storeCossCreateMemBuf: membuflist:\n"); | |
796 | for (m = cs->membufs.head; m; m = m->next) { | |
797 | t = m->data; | |
798 | ! membuf_describe(t, 3, __LINE__); | |
799 | } | |
800 | ||
801 | /* | |
802 | * Kill objects from the tail to make space for a new chunk | |
803 | */ | |
804 | for (m = cs->index.tail; m; m = prev) { | |
805 | + off_t o; | |
806 | prev = m->prev; | |
807 | e = m->data; | |
808 | + o = storeCossFilenoToDiskOffset(e->swap_filen, cs); | |
809 | if (curfn == e->swap_filen) | |
810 | *collision = 1; /* Mark an object alloc collision */ | |
811 | ! if ((o >= newmb->diskstart) && | |
812 | ! (o <= newmb->diskend)) { | |
813 | storeRelease(e); | |
814 | numreleased++; | |
815 | } else | |
816 | *************** | |
817 | *** 567,570 **** | |
818 | --- 597,624 ---- | |
819 | storeCossIOFreeEntry(void *sio) | |
820 | { | |
821 | memPoolFree(coss_state_pool, ((storeIOState *) sio)->fsstate); | |
822 | + } | |
823 | + | |
824 | + static off_t | |
825 | + storeCossFilenoToDiskOffset(sfileno f, CossInfo * cs) | |
826 | + { | |
827 | + return (off_t) f << cs->blksz_bits; | |
828 | + } | |
829 | + | |
830 | + static sfileno | |
831 | + storeCossDiskOffsetToFileno(off_t o, CossInfo * cs) | |
832 | + { | |
833 | + assert(0 == (o & cs->blksz_mask)); | |
834 | + return o >> cs->blksz_bits; | |
835 | + } | |
836 | + | |
837 | + static void | |
838 | + membuf_describe(CossMemBuf * t, int level, int line) | |
839 | + { | |
840 | + debug(79, level) ("membuf %p, LC:%02d, ST:%010lu, FL:%c%c\n", | |
841 | + t, | |
842 | + t->lockcount, | |
843 | + (unsigned long) t->diskstart, | |
844 | + t->flags.full ? 'F' : '.', | |
845 | + t->flags.writing ? 'W' : '.'); | |
846 | } |